2 * Copyright (c) 1999-2001,2005-2011 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * cipherSpecs.c - SSLCipherSpec declarations
28 #include "sslBuildFlags.h"
29 #include "CipherSuite.h"
30 #include "sslContext.h"
31 #include "sslCipherSpecs.h"
33 #include "sslMemory.h"
37 #include "sslCrypto.h"
41 #include <Security/SecBase.h>
42 #include <utilities/array_size.h>
44 #include <TargetConditionals.h>
47 #define ENABLE_RSA_DES_SHA_NONEXPORT ENABLE_DES
48 #define ENABLE_RSA_DES_MD5_NONEXPORT ENABLE_DES
49 #define ENABLE_RSA_DES_SHA_EXPORT ENABLE_DES
50 #define ENABLE_RSA_RC4_MD5_EXPORT ENABLE_RC4 /* the most common one */
51 #define ENABLE_RSA_RC4_MD5_NONEXPORT ENABLE_RC4
52 #define ENABLE_RSA_RC4_SHA_NONEXPORT ENABLE_RC4
53 #define ENABLE_RSA_RC2_MD5_EXPORT ENABLE_RC2
54 #define ENABLE_RSA_RC2_MD5_NONEXPORT ENABLE_RC2
55 #define ENABLE_RSA_3DES_SHA ENABLE_3DES
56 #define ENABLE_RSA_3DES_MD5 ENABLE_3DES
59 #define ENABLE_AES_GCM 0
64 #define ENABLE_DH_ANON 1
65 #define ENABLE_DH_EPHEM_RSA 1
67 #define ENABLE_DH_EPHEM_DSA 1
69 #define ENABLE_DH_EPHEM_DSA 0
72 #define ENABLE_DH_ANON 0
73 #define ENABLE_DH_EPHEM_RSA 0
74 #define ENABLE_DH_EPHEM_DSA 0
78 * List of all CipherSpecs we implement. Depending on a context's
79 * exportable flag, not all of these might be available for use.
81 /* Order by preference, domestic first */
82 static const SSLCipherSuite KnownCipherSuites
[] = {
84 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
,
85 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
,
87 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
,
88 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
,
89 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
,
90 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
,
91 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
92 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
,
94 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
,
95 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
97 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
,
98 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
,
99 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
,
100 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
,
101 TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
102 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
105 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
,
106 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
,
108 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
,
109 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
,
111 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
,
112 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
,
114 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
,
115 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
,
116 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
,
117 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
,
118 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
,
119 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
,
120 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
,
121 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
,
122 TLS_ECDH_RSA_WITH_RC4_128_SHA
,
123 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
,
126 TLS_RSA_WITH_AES_256_GCM_SHA384
,
127 TLS_RSA_WITH_AES_128_GCM_SHA256
,
129 TLS_RSA_WITH_AES_256_CBC_SHA256
,
130 TLS_RSA_WITH_AES_128_CBC_SHA256
,
131 TLS_RSA_WITH_AES_128_CBC_SHA
,
132 SSL_RSA_WITH_RC4_128_SHA
,
133 SSL_RSA_WITH_RC4_128_MD5
,
134 TLS_RSA_WITH_AES_256_CBC_SHA
,
135 SSL_RSA_WITH_3DES_EDE_CBC_SHA
,
137 SSL_RSA_WITH_3DES_EDE_CBC_MD5
,
140 SSL_RSA_WITH_DES_CBC_SHA
,
143 SSL_RSA_WITH_DES_CBC_MD5
,
146 SSL_RSA_WITH_RC2_CBC_MD5
,
149 # if ENABLE_DH_EPHEM_DSA
150 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
,
151 # endif // ENABLE_DH_EPHEM_DSA
152 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
,
153 # if ENABLE_DH_EPHEM_DSA
154 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
,
155 # endif // ENABLE_DH_EPHEM_DSA
156 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
,
157 #endif // ENABLE_AES_GCM
158 #if ENABLE_DH_EPHEM_DSA
159 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
,
161 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
,
162 #if ENABLE_DH_EPHEM_DSA
163 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
,
165 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
,
166 #if ENABLE_DH_EPHEM_DSA
167 TLS_DHE_DSS_WITH_AES_128_CBC_SHA
,
169 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
,
170 #if ENABLE_DH_EPHEM_DSA
171 TLS_DHE_DSS_WITH_AES_256_CBC_SHA
,
173 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
,
174 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
,
176 SSL_DHE_RSA_WITH_DES_CBC_SHA
,
178 #if ENABLE_DH_EPHEM_DSA
179 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
,
181 SSL_DHE_DSS_WITH_DES_CBC_SHA
,
185 TLS_DH_anon_WITH_AES_256_GCM_SHA384
,
186 TLS_DH_anon_WITH_AES_128_GCM_SHA256
,
188 TLS_DH_anon_WITH_AES_128_CBC_SHA256
,
189 TLS_DH_anon_WITH_AES_256_CBC_SHA256
,
190 TLS_DH_anon_WITH_AES_128_CBC_SHA
,
191 TLS_DH_anon_WITH_AES_256_CBC_SHA
,
192 SSL_DH_anon_WITH_RC4_128_MD5
,
193 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
,
195 SSL_DH_anon_WITH_DES_CBC_SHA
,
197 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
198 TLS_ECDHE_RSA_WITH_NULL_SHA
,
200 TLS_ECDH_ECDSA_WITH_NULL_SHA
,
201 TLS_ECDH_RSA_WITH_NULL_SHA
,
205 TLS_PSK_WITH_AES_256_CBC_SHA384
,
206 TLS_PSK_WITH_AES_128_CBC_SHA256
,
207 TLS_PSK_WITH_AES_256_CBC_SHA
,
208 TLS_PSK_WITH_AES_128_CBC_SHA
,
209 TLS_PSK_WITH_RC4_128_SHA
,
210 TLS_PSK_WITH_3DES_EDE_CBC_SHA
,
211 TLS_PSK_WITH_NULL_SHA384
,
212 TLS_PSK_WITH_NULL_SHA256
,
213 TLS_PSK_WITH_NULL_SHA
,
216 TLS_RSA_WITH_NULL_SHA256
,
217 SSL_RSA_WITH_NULL_SHA
,
218 SSL_RSA_WITH_NULL_MD5
221 /* We don't support these yet. */
222 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
,
223 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
,
224 TLS_RSA_WITH_RC4_128_SHA
,
225 TLS_RSA_WITH_3DES_EDE_CBC_SHA
,
226 TLS_RSA_WITH_RC4_128_MD5
,
227 TLS_DH_DSS_WITH_AES_256_GCM_SHA384
,
228 TLS_DH_DSS_WITH_AES_128_GCM_SHA256
,
229 TLS_DH_RSA_WITH_AES_256_GCM_SHA384
,
230 TLS_DH_RSA_WITH_AES_128_GCM_SHA256
,
231 TLS_DH_DSS_WITH_AES_256_CBC_SHA256
,
232 TLS_DH_RSA_WITH_AES_256_CBC_SHA256
,
233 TLS_DH_DSS_WITH_AES_128_CBC_SHA256
,
234 TLS_DH_RSA_WITH_AES_128_CBC_SHA256
,
235 TLS_DH_DSS_WITH_AES_256_CBC_SHA
,
236 TLS_DH_RSA_WITH_AES_256_CBC_SHA
,
237 TLS_DH_DSS_WITH_AES_128_CBC_SHA
,
238 TLS_DH_RSA_WITH_AES_128_CBC_SHA
,
239 TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
,
240 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
,
241 TLS_ECDH_anon_WITH_AES_256_CBC_SHA
,
242 TLS_ECDH_anon_WITH_AES_128_CBC_SHA
,
243 TLS_ECDH_anon_WITH_RC4_128_SHA
,
244 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
,
245 TLS_ECDH_anon_WITH_NULL_SHA
,
249 static const unsigned CipherSuiteCount
= array_size(KnownCipherSuites
);
253 * Given a valid ctx->validCipherSpecs array, calculate how many of those
254 * cipherSpecs are *not* SSLv2 only, storing result in
255 * ctx->numValidNonSSLv2Specs. ClientHello routines need this to set
256 * up outgoing cipherSpecs arrays correctly.
258 * Also determines if any ECDSA/ECDH ciphers are enabled; we need to know
259 * that when creating a hello message.
261 static void sslAnalyzeCipherSpecs(SSLContext
*ctx
)
264 const SSLCipherSuite
*cipherSuite
;
267 ctx
->numValidNonSSLv2Suites
= 0;
269 cipherSuite
= &ctx
->validCipherSuites
[0];
270 ctx
->ecdsaEnable
= false;
271 for(dex
=0; dex
<ctx
->numValidCipherSuites
; dex
++, cipherSuite
++) {
273 if(!CIPHER_SPEC_IS_SSLv2(*cipherSuite
)) {
274 ctx
->numValidNonSSLv2Suites
++;
277 switch(sslCipherSuiteGetKeyExchangeMethod(*cipherSuite
)) {
279 case SSL_ECDHE_ECDSA
:
283 ctx
->ecdsaEnable
= true;
292 * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
293 * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
296 OSStatus
sslBuildCipherSuiteArray(SSLContext
*ctx
)
302 assert(ctx
->validCipherSuites
== NULL
);
304 ctx
->numValidCipherSuites
= CipherSuiteCount
;
305 size
= CipherSuiteCount
* sizeof(SSLCipherSuite
);
306 ctx
->validCipherSuites
= (SSLCipherSuite
*)sslMalloc(size
);
307 if(ctx
->validCipherSuites
== NULL
) {
308 ctx
->numValidCipherSuites
= 0;
309 return errSecAllocate
;
313 * Trim out inappropriate ciphers:
314 * -- trim anonymous ciphers if !ctx->anonCipherEnable
315 * -- trim ECDSA ciphers for server side if appropriate
316 * -- trim ECDSA ciphers if TLSv1 disable or SSLv2 enabled (since
317 * we MUST do the Client Hello extensions to make these ciphers
319 * -- trim Stream ciphers if DTLSv1 enable
321 SSLCipherSuite
*dst
= ctx
->validCipherSuites
;
322 const SSLCipherSuite
*src
= KnownCipherSuites
;
324 bool trimECDSA
= false;
325 if((ctx
->protocolSide
== kSSLServerSide
) && !SSL_ECDSA_SERVER
) {
328 if(ctx
->minProtocolVersion
== SSL_Version_2_0
329 || ctx
->maxProtocolVersion
== SSL_Version_3_0
) {
330 /* We trim ECDSA cipher suites if SSL2 is enabled or
331 The maximum allowed protocol is SSL3. Note that this
332 won't trim ECDSA cipherspecs for DTLS which should be
333 the right thing to do here. */
337 /* trim Stream Ciphers for DTLS */
338 bool trimRC4
= ctx
->isDTLS
;
340 bool trimDHE
= (ctx
->protocolSide
== kSSLServerSide
) &&
341 !ctx
->dhParamsEncoded
.length
;
343 for(dex
=0; dex
<CipherSuiteCount
; dex
++) {
344 KeyExchangeMethod kem
= sslCipherSuiteGetKeyExchangeMethod(*src
);
345 uint8_t keySize
= sslCipherSuiteGetSymmetricCipherKeySize(*src
);
346 HMAC_Algs mac
= sslCipherSuiteGetMacAlgorithm(*src
);
347 SSL_CipherAlgorithm cipher
= sslCipherSuiteGetSymmetricCipherAlgorithm(*src
);
348 /* First skip ECDSA ciphers as appropriate */
351 case SSL_ECDHE_ECDSA
:
357 ctx
->numValidCipherSuites
--;
367 if(!ctx
->anonCipherEnable
) {
368 /* trim out the anonymous (and null-auth-cipher) ciphers */
371 ctx
->numValidCipherSuites
--;
377 case SSL_DH_anon_EXPORT
:
380 ctx
->numValidCipherSuites
--;
387 if(ctx
->falseStartEnabled
) {
389 case SSL_ECDHE_ECDSA
:
393 /* Ok for false start */
397 ctx
->numValidCipherSuites
--;
402 case SSL_CipherAlgorithmAES_128_CBC
:
403 case SSL_CipherAlgorithmAES_128_GCM
:
404 case SSL_CipherAlgorithmAES_256_CBC
:
405 case SSL_CipherAlgorithmAES_256_GCM
:
406 case SSL_CipherAlgorithmRC4_128
:
407 /* Ok for false start */
411 ctx
->numValidCipherSuites
--;
417 /* This will skip the simple DES cipher suites, but not the NULL cipher ones */
421 ctx
->numValidCipherSuites
--;
426 /* Trim PSK ciphersuites, they need to be enabled explicitely */
428 ctx
->numValidCipherSuites
--;
436 case SSL_DHE_DSS_EXPORT
:
438 case SSL_DHE_RSA_EXPORT
:
440 ctx
->numValidCipherSuites
--;
448 if (trimRC4
&& (cipher
==SSL_CipherAlgorithmRC4_128
)) {
449 ctx
->numValidCipherSuites
--;
454 if(cipher
==SSL_CipherAlgorithmNull
) {
455 ctx
->numValidCipherSuites
--;
460 /* This one is good to go */
463 sslAnalyzeCipherSpecs(ctx
);
464 return errSecSuccess
;
468 * Convert an array of SSLCipherSuites (which is always KnownCipherSpecs)
469 * to an array of SSLCipherSuites.
472 cipherSuitesToCipherSuites(
473 size_t numCipherSuites
,
474 const SSLCipherSuite
*cipherSuites
,
475 SSLCipherSuite
*ciphers
, /* RETURNED */
476 size_t *numCiphers
) /* IN/OUT */
478 if(*numCiphers
< numCipherSuites
) {
479 return errSSLBufferOverflow
;
481 memcpy(ciphers
, cipherSuites
, numCipherSuites
* sizeof(SSLCipherSuite
));
482 *numCiphers
= numCipherSuites
;
483 return errSecSuccess
;
487 *** Publically exported functions declared in SecureTransport.h
491 * Determine number and values of all of the SSLCipherSuites we support.
492 * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
493 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
497 SSLGetNumberSupportedCiphers (SSLContextRef ctx
,
500 if((ctx
== NULL
) || (numCiphers
== NULL
)) {
503 *numCiphers
= CipherSuiteCount
;
504 return errSecSuccess
;
508 SSLGetSupportedCiphers (SSLContextRef ctx
,
509 SSLCipherSuite
*ciphers
, /* RETURNED */
510 size_t *numCiphers
) /* IN/OUT */
512 if((ctx
== NULL
) || (ciphers
== NULL
) || (numCiphers
== NULL
)) {
515 return cipherSuitesToCipherSuites(CipherSuiteCount
,
522 * Specify a (typically) restricted set of SSLCipherSuites to be enabled by
523 * the current SSLContext. Can only be called when no session is active. Default
524 * set of enabled SSLCipherSuites is NOT the same as the complete set of supported
525 * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
528 SSLSetEnabledCiphers (SSLContextRef ctx
,
529 const SSLCipherSuite
*ciphers
,
533 size_t foundCiphers
=0;
537 if((ctx
== NULL
) || (ciphers
== NULL
) || (numCiphers
== 0)) {
540 if(sslIsSessionActive(ctx
)) {
541 /* can't do this with an active session */
544 size
= numCiphers
* sizeof(SSLCipherSuite
);
545 ctx
->validCipherSuites
= (SSLCipherSuite
*)sslMalloc(size
);
546 if(ctx
->validCipherSuites
== NULL
) {
547 ctx
->numValidCipherSuites
= 0;
548 return errSecAllocate
;
552 * Run thru caller's specs, keep only the supported ones.
554 for(callerDex
=0; callerDex
<numCiphers
; callerDex
++) {
555 /* find matching CipherSpec in our known table */
556 for(tableDex
=0; tableDex
<CipherSuiteCount
; tableDex
++) {
557 if(ciphers
[callerDex
] == KnownCipherSuites
[tableDex
]) {
558 ctx
->validCipherSuites
[foundCiphers
] = KnownCipherSuites
[tableDex
];
565 if(foundCiphers
==0) {
566 /* caller specified only unsupported ciphersuites */
567 sslFree(ctx
->validCipherSuites
);
568 ctx
->validCipherSuites
= NULL
;
569 return errSSLBadCipherSuite
;
573 ctx
->numValidCipherSuites
= foundCiphers
;
574 sslAnalyzeCipherSpecs(ctx
);
575 return errSecSuccess
;
579 * Determine number and values of all of the SSLCipherSuites currently enabled.
580 * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
581 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
585 SSLGetNumberEnabledCiphers (SSLContextRef ctx
,
588 if((ctx
== NULL
) || (numCiphers
== NULL
)) {
591 if(ctx
->validCipherSuites
== NULL
) {
592 /* hasn't been set; use default */
593 *numCiphers
= CipherSuiteCount
;
596 /* caller set via SSLSetEnabledCiphers */
597 *numCiphers
= ctx
->numValidCipherSuites
;
599 return errSecSuccess
;
603 SSLGetEnabledCiphers (SSLContextRef ctx
,
604 SSLCipherSuite
*ciphers
, /* RETURNED */
605 size_t *numCiphers
) /* IN/OUT */
607 if((ctx
== NULL
) || (ciphers
== NULL
) || (numCiphers
== NULL
)) {
610 if(ctx
->validCipherSuites
== NULL
) {
611 /* hasn't been set; use default */
612 return cipherSuitesToCipherSuites(CipherSuiteCount
,
618 /* use the ones specified in SSLSetEnabledCiphers() */
619 return cipherSuitesToCipherSuites(ctx
->numValidCipherSuites
,
620 ctx
->validCipherSuites
,
627 *** End of publically exported functions declared in SecureTransport.h
630 void InitCipherSpecParams(SSLContext
*ctx
)
632 SSLCipherSpecParams
*dst
= &ctx
->selectedCipherSpecParams
;
633 dst
->cipherSpec
= ctx
->selectedCipher
;
634 dst
->macSize
= sslCipherSuiteGetMacSize(ctx
->selectedCipher
);
635 dst
->macAlg
= sslCipherSuiteGetMacAlgorithm(ctx
->selectedCipher
);
636 dst
->keySize
= sslCipherSuiteGetSymmetricCipherKeySize(ctx
->selectedCipher
);
637 dst
->blockSize
= sslCipherSuiteGetSymmetricCipherBlockIvSize(ctx
->selectedCipher
);
638 dst
->ivSize
= dst
->blockSize
;
639 dst
->keyExchangeMethod
= sslCipherSuiteGetKeyExchangeMethod(ctx
->selectedCipher
);
644 FindCipherSpec(SSLContext
*ctx
)
649 assert(ctx
->validCipherSuites
!= NULL
);
651 for (i
=0; i
<ctx
->numValidCipherSuites
; i
++)
653 if (ctx
->validCipherSuites
[i
] == ctx
->selectedCipher
) {
654 InitCipherSpecParams(ctx
);
655 /* Make sure we're configured to handle this cipherSuite. */
656 return sslVerifySelectedCipher(ctx
);
660 return errSSLNegotiation
;