2 * Copyright (c) 1999-2001,2005-2014 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 "sslContext.h"
30 #include "sslCipherSpecs.h"
32 #include "sslMemory.h"
36 #include <tls_handshake.h>
40 #include <Security/SecBase.h>
42 #include <TargetConditionals.h>
45 /* SecureTransport needs it's own copy of KnownCipherSuites for now, there is a copy in coreTLS,
46 that is exported, but it actually should only included the "default" not the supported */
49 #define ENABLE_AES_GCM 1
51 #define ENABLE_CHACHA20_POLY1305 1
52 #define ENABLE_AES_CCM 0
55 static const uint16_t STKnownCipherSuites
[] = {
57 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
,
58 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
,
60 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
,
61 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
,
62 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
,
63 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
,
64 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
,
66 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
,
67 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
,
69 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
,
70 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
,
71 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
,
72 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
,
73 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
,
76 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
,
77 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
,
79 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
,
80 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
,
81 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
,
82 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
,
83 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
,
85 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
,
86 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
,
88 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
,
89 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
,
90 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
,
91 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
,
92 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
,
96 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
,
97 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
,
98 #endif // ENABLE_AES_GCM
99 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
,
100 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
,
101 TLS_DHE_RSA_WITH_AES_256_CBC_SHA
,
102 TLS_DHE_RSA_WITH_AES_128_CBC_SHA
,
103 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
,
106 TLS_RSA_WITH_AES_256_GCM_SHA384
,
107 TLS_RSA_WITH_AES_128_GCM_SHA256
,
109 TLS_RSA_WITH_AES_256_CBC_SHA256
,
110 TLS_RSA_WITH_AES_128_CBC_SHA256
,
111 TLS_RSA_WITH_AES_256_CBC_SHA
,
112 TLS_RSA_WITH_AES_128_CBC_SHA
,
113 SSL_RSA_WITH_3DES_EDE_CBC_SHA
,
116 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
,
117 TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
118 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
,
119 TLS_ECDH_RSA_WITH_RC4_128_SHA
,
120 SSL_RSA_WITH_RC4_128_SHA
,
121 SSL_RSA_WITH_RC4_128_MD5
,
124 /* TLS 1.3 ciphersuites */
126 TLS_AES_128_GCM_SHA256
,
127 TLS_AES_256_GCM_SHA384
,
129 #if ENABLE_CHACHA20_POLY1305
130 TLS_CHACHA20_POLY1305_SHA256
,
133 TLS_AES_128_CCM_SHA256
,
134 TLS_AES_128_CCM_8_SHA256
,
137 /* Unsafe ciphersuites */
140 TLS_DH_anon_WITH_AES_256_GCM_SHA384
,
141 TLS_DH_anon_WITH_AES_128_GCM_SHA256
,
143 TLS_DH_anon_WITH_AES_128_CBC_SHA256
,
144 TLS_DH_anon_WITH_AES_256_CBC_SHA256
,
145 TLS_DH_anon_WITH_AES_128_CBC_SHA
,
146 TLS_DH_anon_WITH_AES_256_CBC_SHA
,
147 SSL_DH_anon_WITH_RC4_128_MD5
,
148 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
,
150 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
151 TLS_ECDHE_RSA_WITH_NULL_SHA
,
153 TLS_ECDH_ECDSA_WITH_NULL_SHA
,
154 TLS_ECDH_RSA_WITH_NULL_SHA
,
158 TLS_PSK_WITH_AES_256_CBC_SHA384
,
159 TLS_PSK_WITH_AES_128_CBC_SHA256
,
160 TLS_PSK_WITH_AES_256_CBC_SHA
,
161 TLS_PSK_WITH_AES_128_CBC_SHA
,
162 TLS_PSK_WITH_RC4_128_SHA
,
163 TLS_PSK_WITH_3DES_EDE_CBC_SHA
,
164 TLS_PSK_WITH_NULL_SHA384
,
165 TLS_PSK_WITH_NULL_SHA256
,
166 TLS_PSK_WITH_NULL_SHA
,
169 TLS_RSA_WITH_NULL_SHA256
,
170 SSL_RSA_WITH_NULL_SHA
,
171 SSL_RSA_WITH_NULL_MD5
175 static const unsigned STCipherSuiteCount
= sizeof(STKnownCipherSuites
)/sizeof(STKnownCipherSuites
[0]);
179 * Convert an array of uint16_t
180 * to an array of SSLCipherSuites.
183 cipherSuitesToCipherSuites(
184 size_t numCipherSuites
,
185 const uint16_t *cipherSuites
,
186 SSLCipherSuite
*ciphers
, /* RETURNED */
187 size_t *numCiphers
) /* IN/OUT */
190 if(*numCiphers
< numCipherSuites
) {
191 return errSSLBufferOverflow
;
194 /* NOTE: this is required to go from uint16_t to SSLCipherSuite
195 which is either 32 or 16 bits, depending on the platform */
196 for(i
=0;i
<numCipherSuites
; i
++) {
197 ciphers
[i
]=cipherSuites
[i
];
199 *numCiphers
= numCipherSuites
;
200 return errSecSuccess
;
204 *** Publically exported functions declared in SecureTransport.h
208 * Determine number and values of all of the SSLCipherSuites we support.
209 * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
210 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
214 SSLGetNumberSupportedCiphers (SSLContextRef ctx
,
217 if((ctx
== NULL
) || (numCiphers
== NULL
)) {
220 *numCiphers
= STCipherSuiteCount
;
221 return errSecSuccess
;
225 SSLGetSupportedCiphers (SSLContextRef ctx
,
226 SSLCipherSuite
*ciphers
, /* RETURNED */
227 size_t *numCiphers
) /* IN/OUT */
229 if((ctx
== NULL
) || (ciphers
== NULL
) || (numCiphers
== NULL
)) {
232 return cipherSuitesToCipherSuites(STCipherSuiteCount
,
239 * Specify a (typically) restricted set of SSLCipherSuites to be enabled by
240 * the current SSLContext. Can only be called when no session is active. Default
241 * set of enabled SSLCipherSuites is NOT the same as the complete set of supported
242 * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
245 SSLSetEnabledCiphers (SSLContextRef ctx
,
246 const SSLCipherSuite
*ciphers
,
251 if((ctx
== NULL
) || (ciphers
== NULL
) || (numCiphers
== 0)) {
255 if(sslIsSessionActive(ctx
)) {
256 /* can't do this with an active session */
261 for(int i
=0; i
<numCiphers
; i
++) {
262 for (int j
=0; j
< STCipherSuiteCount
; j
++) {
263 if (STKnownCipherSuites
[j
] == ciphers
[i
]) {
270 // If the caller specified no ciphersuites that we actually support, return an error code.
271 if (matchCount
== 0) {
275 cs
= (uint16_t *)sslMalloc(matchCount
* sizeof(uint16_t));
277 return errSecAllocate
;
281 for(int i
=0; i
<numCiphers
; i
++) {
282 for (int j
=0; j
< STCipherSuiteCount
; j
++) {
283 if (STKnownCipherSuites
[j
] == ciphers
[i
]) {
284 cs
[matchCount
++] = ciphers
[i
];
291 OSStatus result
= tls_handshake_set_ciphersuites(ctx
->hdsk
, cs
, (unsigned) matchCount
);
299 * Determine number and values of all of the SSLCipherSuites currently enabled.
300 * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
301 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
305 SSLGetNumberEnabledCiphers (SSLContextRef ctx
,
308 if((ctx
== NULL
) || (numCiphers
== NULL
)) {
313 const uint16_t *ciphersuites
;
316 err
= tls_handshake_get_ciphersuites(ctx
->hdsk
, &ciphersuites
, &n
);
322 return errSecSuccess
;
327 SSLGetEnabledCiphers (SSLContextRef ctx
,
328 SSLCipherSuite
*ciphers
, /* RETURNED */
329 size_t *numCiphers
) /* IN/OUT */
331 if((ctx
== NULL
) || (ciphers
== NULL
) || (numCiphers
== NULL
)) {
336 const uint16_t *ciphersuites
;
339 err
= tls_handshake_get_ciphersuites(ctx
->hdsk
, &ciphersuites
, &n
);
344 return cipherSuitesToCipherSuites(n
,
352 SSLSetSessionTicketsEnabled (SSLContextRef context
,
355 if (context
== NULL
) {
359 return tls_handshake_set_session_ticket_enabled(context
->hdsk
, enabled
);