/ protocol / SecProtocolHelper.m
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  }