]> git.saurik.com Git - apple/security.git/blob - SecureTransport/cipherSpecs.cpp
Security-179.tar.gz
[apple/security.git] / SecureTransport / cipherSpecs.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 File: cipherSpecs.cpp
21
22 Contains: SSLCipherSpec declarations
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "sslContext.h"
31 #include "cryptType.h"
32 #include "symCipher.h"
33 #include "cipherSpecs.h"
34 #include "sslDebug.h"
35 #include "sslMemory.h"
36 #include "sslDebug.h"
37 #include "sslUtils.h"
38 #include "sslPriv.h"
39 #include "appleCdsa.h"
40 #include <string.h>
41 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
42
43 #define ENABLE_3DES 1 /* normally enabled */
44 #define ENABLE_RC4 1 /* normally enabled, our first preference */
45 #define ENABLE_DES 1 /* normally enabled */
46 #define ENABLE_RC2 1 /* normally enabled */
47
48 #define ENABLE_RSA_DES_SHA_NONEXPORT ENABLE_DES
49 #define ENABLE_RSA_DES_MD5_NONEXPORT ENABLE_DES
50 #define ENABLE_RSA_DES_SHA_EXPORT ENABLE_DES
51 #define ENABLE_RSA_RC4_MD5_EXPORT ENABLE_RC4 /* the most common one */
52 #define ENABLE_RSA_RC4_MD5_NONEXPORT ENABLE_RC4
53 #define ENABLE_RSA_RC4_SHA_NONEXPORT ENABLE_RC4
54 #define ENABLE_RSA_RC2_MD5_EXPORT ENABLE_RC2
55 #define ENABLE_RSA_RC2_MD5_NONEXPORT ENABLE_RC2
56 #define ENABLE_RSA_3DES_SHA ENABLE_3DES
57 #define ENABLE_RSA_3DES_MD5 ENABLE_3DES
58
59 #if APPLE_DH
60 #define ENABLE_DH_ANON 1
61 #define ENABLE_DH_EPHEM_RSA 1
62 #define ENABLE_DH_EPHEM_DSA 1
63 #else
64 #define ENABLE_DH_ANON 0
65 #define ENABLE_DH_EPHEM_RSA 0
66 #define ENABLE_DH_EPHEM_DSA 0
67 #endif /* APPLE_DH */
68
69 extern "C" {
70 extern const SSLSymmetricCipher SSLCipherNull; /* in sslNullCipher.cpp */
71 }
72
73 /*
74 * The symmetric ciphers currently supported (in addition to the
75 * NULL cipher in nullciph.c).
76 */
77 #if ENABLE_DES
78 static const SSLSymmetricCipher SSLCipherDES_CBC = {
79 8, /* Key size in bytes */
80 8, /* Secret key size = 64 bits */
81 8, /* IV size */
82 8, /* Block size */
83 CSSM_ALGID_DES,
84 CSSM_ALGID_DES,
85 /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
86 * for us */
87 CSSM_ALGMODE_CBC_IV8,
88 CSSM_PADDING_NONE,
89 CDSASymmInit,
90 CDSASymmEncrypt,
91 CDSASymmDecrypt,
92 CDSASymmFinish
93 };
94
95 static const SSLSymmetricCipher SSLCipherDES40_CBC = {
96 8, /* Key size in bytes */
97 5, /* Secret key size = 40 bits */
98 8, /* IV size */
99 8, /* Block size */
100 CSSM_ALGID_DES,
101 CSSM_ALGID_DES,
102 CSSM_ALGMODE_CBC_IV8,
103 CSSM_PADDING_NONE,
104 CDSASymmInit,
105 CDSASymmEncrypt,
106 CDSASymmDecrypt,
107 CDSASymmFinish
108 };
109 #endif /* ENABLE_DES */
110
111 #if ENABLE_3DES
112 static const SSLSymmetricCipher SSLCipher3DES_CBC = {
113 24, /* Key size in bytes */
114 24, /* Secret key size = 192 bits */
115 8, /* IV size */
116 8, /* Block size */
117 CSSM_ALGID_3DES_3KEY, // key gen
118 CSSM_ALGID_3DES_3KEY_EDE, // encryption
119 /* Note we don't want CSSM_ALGMODE_CBCPadIV8; our clients do that
120 * for us */
121 CSSM_ALGMODE_CBC_IV8,
122 CSSM_PADDING_NONE,
123 CDSASymmInit,
124 CDSASymmEncrypt,
125 CDSASymmDecrypt,
126 CDSASymmFinish
127 };
128 #endif /* ENABLE_3DES */
129
130 #if ENABLE_RC4
131 static const SSLSymmetricCipher SSLCipherRC4_40 = {
132 16, /* Key size in bytes */
133 5, /* Secret key size = 40 bits */
134 0, /* IV size */
135 0, /* Block size */
136 CSSM_ALGID_RC4,
137 CSSM_ALGID_RC4,
138 CSSM_ALGMODE_NONE,
139 CSSM_PADDING_NONE,
140 CDSASymmInit,
141 CDSASymmEncrypt,
142 CDSASymmDecrypt,
143 CDSASymmFinish
144 };
145
146 static const SSLSymmetricCipher SSLCipherRC4_128 = {
147 16, /* Key size in bytes */
148 16, /* Secret key size = 128 bits */
149 0, /* IV size */
150 0, /* Block size */
151 CSSM_ALGID_RC4,
152 CSSM_ALGID_RC4,
153 CSSM_ALGMODE_NONE,
154 CSSM_PADDING_NONE,
155 CDSASymmInit,
156 CDSASymmEncrypt,
157 CDSASymmDecrypt,
158 CDSASymmFinish
159 };
160 #endif /* ENABLE_RC4 */
161
162 #if ENABLE_RC2
163 static const SSLSymmetricCipher SSLCipherRC2_40 = {
164 16, /* Key size in bytes */
165 5, /* Secret key size = 40 bits */
166 8, /* IV size */
167 8, /* Block size */
168 CSSM_ALGID_RC2,
169 CSSM_ALGID_RC2,
170 CSSM_ALGMODE_CBC_IV8,
171 CSSM_PADDING_NONE,
172 CDSASymmInit,
173 CDSASymmEncrypt,
174 CDSASymmDecrypt,
175 CDSASymmFinish
176 };
177
178 static const SSLSymmetricCipher SSLCipherRC2_128 = {
179 16, /* Key size in bytes */
180 16, /* Secret key size = 40 bits */
181 8, /* IV size */
182 8, /* Block size */
183 CSSM_ALGID_RC2,
184 CSSM_ALGID_RC2,
185 CSSM_ALGMODE_CBC_IV8,
186 CSSM_PADDING_NONE,
187 CDSASymmInit,
188 CDSASymmEncrypt,
189 CDSASymmDecrypt,
190 CDSASymmFinish
191 };
192
193 #endif /* ENABLE_RC2*/
194
195
196 /* Even if we don't support NULL_WITH_NULL_NULL for transport,
197 * we need a reference for startup */
198 const SSLCipherSpec SSL_NULL_WITH_NULL_NULL_CipherSpec =
199 { SSL_NULL_WITH_NULL_NULL,
200 Exportable,
201 SSL_NULL_auth,
202 &HashHmacNull,
203 &SSLCipherNull
204 };
205
206 /*
207 * List of all CipherSpecs we implement. Depending on a context's
208 * exportable flag, not all of these might be available for use.
209 *
210 * FIXME - I'm not sure the distinction between e.g. SSL_RSA and SSL_RSA_EXPORT
211 * makes any sense here. See comments for the definition of
212 * KeyExchangeMethod in cryptType.h.
213 */
214 /* Order by preference, domestic first */
215 static const SSLCipherSpec KnownCipherSpecs[] =
216 {
217 /*** domestic only ***/
218 #if ENABLE_RSA_RC4_SHA_NONEXPORT
219 {
220 SSL_RSA_WITH_RC4_128_SHA,
221 NotExportable,
222 SSL_RSA,
223 &HashHmacSHA1,
224 &SSLCipherRC4_128
225 },
226 #endif
227 #if ENABLE_RSA_RC4_MD5_NONEXPORT
228 {
229 SSL_RSA_WITH_RC4_128_MD5,
230 NotExportable,
231 SSL_RSA,
232 &HashHmacMD5,
233 &SSLCipherRC4_128
234 },
235 #endif
236 #if ENABLE_RSA_3DES_SHA
237 {
238 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
239 NotExportable,
240 SSL_RSA,
241 &HashHmacSHA1,
242 &SSLCipher3DES_CBC
243 },
244 #endif
245 #if ENABLE_RSA_3DES_MD5
246 {
247 SSL_RSA_WITH_3DES_EDE_CBC_MD5,
248 NotExportable,
249 SSL_RSA,
250 &HashHmacMD5,
251 &SSLCipher3DES_CBC
252 },
253 #endif
254 #if ENABLE_RSA_DES_SHA_NONEXPORT
255 {
256 SSL_RSA_WITH_DES_CBC_SHA,
257 NotExportable,
258 SSL_RSA,
259 &HashHmacSHA1,
260 &SSLCipherDES_CBC
261 },
262 #endif
263 #if ENABLE_RSA_DES_MD5_NONEXPORT
264 {
265 SSL_RSA_WITH_DES_CBC_MD5,
266 NotExportable,
267 SSL_RSA,
268 &HashHmacMD5,
269 &SSLCipherDES_CBC
270 },
271 #endif
272 /*** exportable ***/
273 #if ENABLE_RSA_RC4_MD5_EXPORT
274 {
275 SSL_RSA_EXPORT_WITH_RC4_40_MD5,
276 Exportable,
277 SSL_RSA_EXPORT,
278 &HashHmacMD5,
279 &SSLCipherRC4_40
280 },
281 #endif
282 #if ENABLE_RSA_DES_SHA_EXPORT
283 {
284 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
285 Exportable,
286 SSL_RSA_EXPORT,
287 &HashHmacSHA1,
288 &SSLCipherDES40_CBC
289 },
290 #endif
291
292 #if ENABLE_RSA_RC2_MD5_EXPORT
293 {
294 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
295 Exportable,
296 SSL_RSA_EXPORT,
297 &HashHmacMD5,
298 &SSLCipherRC2_40
299 },
300 #endif
301 #if ENABLE_RSA_RC2_MD5_NONEXPORT
302 {
303 SSL_RSA_WITH_RC2_CBC_MD5,
304 NotExportable,
305 SSL_RSA,
306 &HashHmacMD5,
307 &SSLCipherRC2_128
308 },
309 #endif
310 {
311 SSL_RSA_WITH_NULL_MD5,
312 Exportable,
313 SSL_RSA,
314 &HashHmacMD5,
315 &SSLCipherNull
316 },
317 #if ENABLE_DH_EPHEM_RSA
318 {
319 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
320 NotExportable,
321 SSL_DHE_RSA,
322 &HashHmacSHA1,
323 &SSLCipher3DES_CBC
324 },
325 {
326 SSL_DHE_RSA_WITH_DES_CBC_SHA,
327 NotExportable,
328 SSL_DHE_RSA,
329 &HashHmacSHA1,
330 &SSLCipherDES_CBC
331 },
332 {
333 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
334 Exportable,
335 SSL_DHE_RSA,
336 &HashHmacSHA1,
337 &SSLCipherDES40_CBC
338 },
339
340 #endif /* ENABLE_DH_EPHEM_RSA */
341 #if ENABLE_DH_EPHEM_DSA
342 {
343 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
344 NotExportable,
345 SSL_DHE_DSS,
346 &HashHmacSHA1,
347 &SSLCipher3DES_CBC
348 },
349 {
350 SSL_DHE_DSS_WITH_DES_CBC_SHA,
351 NotExportable,
352 SSL_DHE_DSS,
353 &HashHmacSHA1,
354 &SSLCipherDES_CBC
355 },
356 {
357 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
358 Exportable,
359 SSL_DHE_DSS,
360 &HashHmacSHA1,
361 &SSLCipherDES40_CBC
362 },
363
364 #endif /* ENABLE_DH_EPHEM_DSA */
365 #if ENABLE_DH_ANON
366 {
367 SSL_DH_anon_WITH_RC4_128_MD5,
368 NotExportable,
369 SSL_DH_anon,
370 &HashHmacMD5,
371 &SSLCipherRC4_128
372 },
373 {
374 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
375 NotExportable,
376 SSL_DH_anon,
377 &HashHmacSHA1,
378 &SSLCipher3DES_CBC
379 },
380 {
381 SSL_DH_anon_WITH_DES_CBC_SHA,
382 NotExportable,
383 SSL_DH_anon,
384 &HashHmacSHA1,
385 &SSLCipherDES_CBC
386 },
387 {
388 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
389 Exportable,
390 SSL_DH_anon,
391 &HashHmacMD5,
392 &SSLCipherRC4_40
393 },
394 {
395 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
396 Exportable,
397 SSL_DH_anon,
398 &HashHmacSHA1,
399 &SSLCipherDES40_CBC
400 },
401 #endif /* APPLE_DH */
402 };
403
404 static const unsigned CipherSpecCount = sizeof(KnownCipherSpecs) / sizeof(SSLCipherSpec);
405
406 /*
407 * Build ctx->validCipherSpecs as a copy of KnownCipherSpecs, assuming that
408 * validCipherSpecs is currently not valid (i.e., SSLSetEnabledCiphers() has
409 * not been called).
410 */
411 OSStatus sslBuildCipherSpecArray(SSLContext *ctx)
412 {
413 unsigned size;
414
415 assert(ctx != NULL);
416 assert(ctx->validCipherSpecs == NULL);
417
418 ctx->numValidCipherSpecs = CipherSpecCount;
419 size = CipherSpecCount * sizeof(SSLCipherSpec);
420 ctx->validCipherSpecs = (SSLCipherSpec *)sslMalloc(size);
421 if(ctx->validCipherSpecs == NULL) {
422 ctx->numValidCipherSpecs = 0;
423 return memFullErr;
424 }
425 memmove(ctx->validCipherSpecs, KnownCipherSpecs, size);
426 return noErr;
427 }
428
429 /*
430 * Convert an array of SSLCipherSpecs (which is either KnownCipherSpecs or
431 * ctx->validCipherSpecs) to an array of SSLCipherSuites.
432 */
433 static OSStatus
434 cipherSpecsToCipherSuites(
435 UInt32 numCipherSpecs, /* size of cipherSpecs */
436 const SSLCipherSpec *cipherSpecs,
437 SSLCipherSuite *ciphers, /* RETURNED */
438 UInt32 *numCiphers) /* IN/OUT */
439 {
440 unsigned dex;
441
442 if(*numCiphers < numCipherSpecs) {
443 return errSSLBufferOverflow;
444 }
445 for(dex=0; dex<numCipherSpecs; dex++) {
446 ciphers[dex] = cipherSpecs[dex].cipherSpec;
447 }
448 *numCiphers = numCipherSpecs;
449 return noErr;
450 }
451
452 /***
453 *** Publically exported functions declared in SecureTransport.h
454 ***/
455
456 /*
457 * Determine number and values of all of the SSLCipherSuites we support.
458 * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in
459 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
460 * will be returned.
461 */
462 OSStatus
463 SSLGetNumberSupportedCiphers (SSLContextRef ctx,
464 UInt32 *numCiphers)
465 {
466 if((ctx == NULL) || (numCiphers == NULL)) {
467 return paramErr;
468 }
469 *numCiphers = CipherSpecCount;
470 return noErr;
471 }
472
473 OSStatus
474 SSLGetSupportedCiphers (SSLContextRef ctx,
475 SSLCipherSuite *ciphers, /* RETURNED */
476 UInt32 *numCiphers) /* IN/OUT */
477 {
478 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
479 return paramErr;
480 }
481 return cipherSpecsToCipherSuites(CipherSpecCount,
482 KnownCipherSpecs,
483 ciphers,
484 numCiphers);
485 }
486
487 /*
488 * Specify a (typically) restricted set of SSLCipherSuites to be enabled by
489 * the current SSLContext. Can only be called when no session is active. Default
490 * set of enabled SSLCipherSuites is the same as the complete set of supported
491 * SSLCipherSuites as obtained by SSLGetSupportedCiphers().
492 */
493 OSStatus
494 SSLSetEnabledCiphers (SSLContextRef ctx,
495 const SSLCipherSuite *ciphers,
496 UInt32 numCiphers)
497 {
498 unsigned size;
499 unsigned callerDex;
500 unsigned tableDex;
501
502 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == 0)) {
503 return paramErr;
504 }
505 if(sslIsSessionActive(ctx)) {
506 /* can't do this with an active session */
507 return badReqErr;
508 }
509 size = numCiphers * sizeof(SSLCipherSpec);
510 ctx->validCipherSpecs = (SSLCipherSpec *)sslMalloc(size);
511 if(ctx->validCipherSpecs == NULL) {
512 ctx->numValidCipherSpecs = 0;
513 return memFullErr;
514 }
515
516 /*
517 * Run thru caller's specs, finding a matching SSLCipherSpec for each one.
518 * If caller specifies one we don't know about, abort.
519 */
520 for(callerDex=0; callerDex<numCiphers; callerDex++) {
521 /* find matching CipherSpec in our known table */
522 int foundOne = 0;
523 for(tableDex=0; tableDex<CipherSpecCount; tableDex++) {
524 if(ciphers[callerDex] == KnownCipherSpecs[tableDex].cipherSpec) {
525 ctx->validCipherSpecs[callerDex] = KnownCipherSpecs[tableDex];
526 foundOne = 1;
527 break;
528 }
529 }
530 if(!foundOne) {
531 /* caller specified one we don't implement */
532 sslFree(ctx->validCipherSpecs);
533 ctx->validCipherSpecs = NULL;
534 return errSSLBadCipherSuite;
535 }
536 }
537
538 /* success */
539 ctx->numValidCipherSpecs = numCiphers;
540 return noErr;
541 }
542
543 /*
544 * Determine number and values of all of the SSLCipherSuites currently enabled.
545 * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in
546 * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow
547 * will be returned.
548 */
549 OSStatus
550 SSLGetNumberEnabledCiphers (SSLContextRef ctx,
551 UInt32 *numCiphers)
552 {
553 if((ctx == NULL) || (numCiphers == NULL)) {
554 return paramErr;
555 }
556 if(ctx->validCipherSpecs == NULL) {
557 /* hasn't been set; use default */
558 *numCiphers = CipherSpecCount;
559 }
560 else {
561 /* caller set via SSLSetEnabledCiphers */
562 *numCiphers = ctx->numValidCipherSpecs;
563 }
564 return noErr;
565 }
566
567 OSStatus
568 SSLGetEnabledCiphers (SSLContextRef ctx,
569 SSLCipherSuite *ciphers, /* RETURNED */
570 UInt32 *numCiphers) /* IN/OUT */
571 {
572 if((ctx == NULL) || (ciphers == NULL) || (numCiphers == NULL)) {
573 return paramErr;
574 }
575 if(ctx->validCipherSpecs == NULL) {
576 /* hasn't been set; use default */
577 return cipherSpecsToCipherSuites(CipherSpecCount,
578 KnownCipherSpecs,
579 ciphers,
580 numCiphers);
581 }
582 else {
583 /* use the ones specified in SSLSetEnabledCiphers() */
584 return cipherSpecsToCipherSuites(ctx->numValidCipherSpecs,
585 ctx->validCipherSpecs,
586 ciphers,
587 numCiphers);
588 }
589 }
590
591 /***
592 *** End of publically exported functions declared in SecureTransport.h
593 ***/
594
595 /*
596 * Given a valid ctx->selectedCipher and ctx->validCipherSpecs, set
597 * ctx->selectedCipherSpec as appropriate.
598 */
599 OSStatus
600 FindCipherSpec(SSLContext *ctx)
601 {
602
603 unsigned i;
604
605 assert(ctx != NULL);
606 assert(ctx->validCipherSpecs != NULL);
607
608 ctx->selectedCipherSpec = NULL;
609 for (i=0; i<ctx->numValidCipherSpecs; i++)
610 { if (ctx->validCipherSpecs[i].cipherSpec == ctx->selectedCipher) {
611 ctx->selectedCipherSpec = &ctx->validCipherSpecs[i];
612 break;
613 }
614 }
615 if (ctx->selectedCipherSpec == NULL) /* Not found */
616 return errSSLNegotiation;
617
618 /* make sure we're configured to handle this one */
619 return sslVerifyNegotiatedCipher(ctx);
620 }
621