]> git.saurik.com Git - apple/security.git/blob - protocol/SecProtocolHelper.m
Security-59754.80.3.tar.gz
[apple/security.git] / protocol / SecProtocolHelper.m
1 //
2 // SecProtocolHelper.m
3 // Security_ios
4 //
5 //
6
7 #import "SecProtocolInternal.h"
8
9 #define DefineTLSCiphersuiteGroupList(XXX, ...) \
10 static const tls_ciphersuite_t List##XXX[] = { \
11 __VA_ARGS__ \
12 };
13
14 DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_default,
15 CiphersuitesTLS13,
16 CiphersuitesPFS);
17 DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_compatibility,
18 CiphersuitesNonPFS,
19 CiphersuitesTLS10,
20 CiphersuitesTLS10_3DES);
21 DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_legacy,
22 CiphersuitesDHE);
23 DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_ats,
24 CiphersuitesTLS13,
25 CiphersuitesPFS);
26 DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_ats_compatibility,
27 CiphersuitesNonPFS);
28
29 typedef struct tls_ciphersuite_definition {
30 tls_ciphersuite_t ciphersuite;
31 tls_protocol_version_t min_version;
32 tls_protocol_version_t max_version;
33 char ciphersuite_name[64];
34 } *tls_ciphersuite_definition_t;
35
36 #define DefineTLSCiphersuiteDefinition(XXX, MIN_VERSION, MAX_VERSION) \
37 { \
38 .ciphersuite = XXX, \
39 .ciphersuite_name = "##XXX", \
40 .min_version = MIN_VERSION, \
41 .max_version = MAX_VERSION, \
42 }
43
44 static const struct tls_ciphersuite_definition tls_ciphersuite_definitions[] = {
45 // TLS 1.3 ciphersuites
46 DefineTLSCiphersuiteDefinition(TLS_AES_128_GCM_SHA256, tls_protocol_version_TLSv13, tls_protocol_version_TLSv13),
47 DefineTLSCiphersuiteDefinition(TLS_AES_256_GCM_SHA384, tls_protocol_version_TLSv13, tls_protocol_version_TLSv13),
48 DefineTLSCiphersuiteDefinition(TLS_CHACHA20_POLY1305_SHA256, tls_protocol_version_TLSv13, tls_protocol_version_TLSv13),
49
50 // RFC 7905: ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS)
51 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
52 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
53
54 // RFC 5289: TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM)
55 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
56 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
57 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
58 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
59 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
60 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
61 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
62 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
63
64 // RFC 5288: AES Galois Counter Mode (GCM) Cipher Suites for TLS
65 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_GCM_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
66 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
67 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
68 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
69
70 // RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2
71 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
72 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
73 DefineTLSCiphersuiteDefinition(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
74 DefineTLSCiphersuiteDefinition(SSL_RSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
75 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
76 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12),
77
78 // RFC 4492: Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)
79 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
80 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
81 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
82 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
83 DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
84 DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
85
86 // RFC 3268: Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS)
87 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
88 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
89 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
90 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
91 DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
92 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
93 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
94 DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11),
95 };
96
97 // Size of the definition list
98 static const size_t tls_ciphersuite_definitions_length = \
99 sizeof(tls_ciphersuite_definitions) / sizeof(struct tls_ciphersuite_definition);
100
101 const tls_ciphersuite_t *
102 sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(tls_ciphersuite_group_t group, size_t *list_count)
103 {
104 if (list_count == NULL) {
105 return NULL;
106 }
107
108 const tls_ciphersuite_t *ciphersuites = NULL;
109 size_t count = 0;
110
111 #define CASE_CONFIG(GROUPNAME) \
112 case GROUPNAME: \
113 ciphersuites = List##GROUPNAME; \
114 count = sizeof(List##GROUPNAME) / sizeof(tls_ciphersuite_t); \
115 break;
116
117 switch (group) {
118 CASE_CONFIG(tls_ciphersuite_group_default);
119 CASE_CONFIG(tls_ciphersuite_group_compatibility);
120 CASE_CONFIG(tls_ciphersuite_group_legacy);
121 CASE_CONFIG(tls_ciphersuite_group_ats);
122 CASE_CONFIG(tls_ciphersuite_group_ats_compatibility);
123 }
124
125 #undef CASE_CONFIG
126
127 if (ciphersuites != NULL) {
128 *list_count = count;
129 return ciphersuites;
130 }
131
132 *list_count = 0;
133 return NULL;
134 }
135
136 bool
137 sec_protocol_helper_ciphersuite_group_contains_ciphersuite(tls_ciphersuite_group_t group, tls_ciphersuite_t suite)
138 {
139 size_t list_size = 0;
140 const tls_ciphersuite_t *list = sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(group, &list_size);
141 if (list == NULL) {
142 return false;
143 }
144
145 for (size_t i = 0; i < list_size; i++) {
146 tls_ciphersuite_t other = list[i];
147 if (other == suite) {
148 return true;
149 }
150 }
151
152 return false;
153 }
154
155 tls_protocol_version_t
156 sec_protocol_helper_ciphersuite_minimum_TLS_version(tls_ciphersuite_t ciphersuite)
157 {
158 for (size_t i = 0; i < tls_ciphersuite_definitions_length; i++) {
159 if (tls_ciphersuite_definitions[i].ciphersuite == ciphersuite) {
160 return tls_ciphersuite_definitions[i].min_version;
161 }
162 }
163 return 0;
164 }
165
166 tls_protocol_version_t
167 sec_protocol_helper_ciphersuite_maximum_TLS_version(tls_ciphersuite_t ciphersuite)
168 {
169 for (size_t i = 0; i < tls_ciphersuite_definitions_length; i++) {
170 if (tls_ciphersuite_definitions[i].ciphersuite == ciphersuite) {
171 return tls_ciphersuite_definitions[i].max_version;
172 }
173 }
174 return 0;
175 }
176
177 const char *
178 sec_protocol_helper_get_ciphersuite_name(tls_ciphersuite_t ciphersuite)
179 {
180 #define CIPHERSUITE_TO_NAME(ciphersuite) \
181 case ciphersuite: { \
182 return #ciphersuite; \
183 }
184
185 switch (ciphersuite) {
186 CIPHERSUITE_TO_NAME(TLS_AES_128_GCM_SHA256);
187 CIPHERSUITE_TO_NAME(TLS_AES_256_GCM_SHA384);
188 CIPHERSUITE_TO_NAME(TLS_CHACHA20_POLY1305_SHA256);
189 CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_256_GCM_SHA384);
190 CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_128_GCM_SHA256);
191 CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_256_CBC_SHA256);
192 CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_128_CBC_SHA256);
193 CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_256_CBC_SHA);
194 CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_128_CBC_SHA);
195 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
196 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
197 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
198 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
199 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA);
200 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA);
201 CIPHERSUITE_TO_NAME(SSL_RSA_WITH_3DES_EDE_CBC_SHA);
202 CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384);
203 CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256);
204 CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256);
205 CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256);
206 CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_256_CBC_SHA);
207 CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
208 CIPHERSUITE_TO_NAME(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA);
209 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384);
210 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
211 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
212 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
213 CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256);
214 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384);
215 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
216 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384);
217 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256);
218 CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256);
219 }
220
221 #undef CIPHERSUITE_TO_NAME
222 return NULL;
223 }
224
225 #define KeyExchangeGroupsDefault \
226 tls_key_exchange_group_X25519, \
227 tls_key_exchange_group_X448
228 #define KeyExchangeGroupsCompatibility \
229 tls_key_exchange_group_Secp256r1, \
230 tls_key_exchange_group_Secp384r1, \
231 tls_key_exchange_group_Secp521r1
232 #define KeyExchangeGroupsLegacy \
233 tls_key_exchange_group_FFDHE2048, \
234 tls_key_exchange_group_FFDHE3072, \
235 tls_key_exchange_group_FFDHE4096, \
236 tls_key_exchange_group_FFDHE6144, \
237 tls_key_exchange_group_FFDHE8192
238
239 #define DefineTLSKeyExchangeGroupList(XXX, ...) \
240 static const tls_key_exchange_group_t List##XXX[] = { \
241 __VA_ARGS__ \
242 };
243
244 DefineTLSKeyExchangeGroupList(tls_key_exchange_group_set_default,
245 KeyExchangeGroupsDefault);
246 DefineTLSKeyExchangeGroupList(tls_key_exchange_group_set_compatibility,
247 KeyExchangeGroupsCompatibility);
248 DefineTLSKeyExchangeGroupList(tls_key_exchange_group_set_legacy,
249 KeyExchangeGroupsLegacy);
250
251 const tls_key_exchange_group_t *
252 sec_protocol_helper_tls_key_exchange_group_set_to_key_exchange_group_list(tls_key_exchange_group_set_t set, size_t *listSize)
253 {
254 if (listSize == NULL) {
255 return NULL;
256 }
257
258 const tls_key_exchange_group_t *groups = NULL;
259 size_t count = 0;
260
261 #define CASE_CONFIG(SETNAME) \
262 case SETNAME: \
263 groups = List##SETNAME; \
264 count = sizeof(List##SETNAME) / sizeof(SSLKeyExchangeGroup); \
265 break;
266
267 switch (set) {
268 CASE_CONFIG(tls_key_exchange_group_set_default);
269 CASE_CONFIG(tls_key_exchange_group_set_compatibility);
270 CASE_CONFIG(tls_key_exchange_group_set_legacy);
271 }
272
273 #undef CASE_CONFIG
274
275 if (groups != NULL) {
276 *listSize = count;
277 return groups;
278 }
279
280 *listSize = 0;
281 return NULL;
282 }
283
284 #undef DefineTLSKeyExchangeGroupList
285 #undef KeyExchangeGroupsDefault
286 #undef KeyExchangeGroupsCompatibility
287 #undef KeyExchangeGroupsLegacy
288
289 bool
290 sec_protocol_helper_dispatch_data_equal(dispatch_data_t left, dispatch_data_t right)
291 {
292 if (!left || !right || left == right) {
293 return left == right;
294 }
295 if (dispatch_data_get_size(left) != dispatch_data_get_size(right)) {
296 return false;
297 }
298 __block bool is_equal = true;
299 dispatch_data_apply(left,
300 ^bool(__unused dispatch_data_t _Nonnull lregion, size_t loffset, const void *_Nonnull lbuffer, size_t lsize) {
301 dispatch_data_apply(right,
302 ^bool(__unused dispatch_data_t _Nonnull rregion, size_t roffset, const void *_Nonnull rbuffer,
303 size_t rsize) {
304 // There is some overlap
305 const size_t start = MAX(loffset, roffset);
306 const size_t end = MIN(loffset + lsize, roffset + rsize);
307 if (start < end) {
308 is_equal = memcmp(&((const uint8_t *)rbuffer)[start - roffset],
309 &((const uint8_t *)lbuffer)[start - loffset], end - start) == 0;
310 } else {
311 if (roffset > loffset + lsize) {
312 // Iteration of right has gone past where we're at on left, bail out of inner apply
313 // left |---|
314 // right |---|
315 return false;
316 } else if (roffset + rsize < loffset) {
317 // Iteration of right has not yet reached where we're at on left, keep going
318 // left |---|
319 // right |--|
320 return true;
321 }
322 }
323
324 return is_equal;
325 });
326 return is_equal;
327 });
328 return is_equal;
329 }