2 * Copyright (c) 1999-2001,2005-2008,2010-2012 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 * symCipher.c - CommonCrypto-based symmetric cipher module
28 /* THIS FILE CONTAINS KERNEL CODE */
30 #include "sslBuildFlags.h"
32 #include "sslMemory.h"
33 #include "symCipher.h"
34 #include "cipherSpecs.h"
35 #include "SSLRecordInternal.h"
39 #include <corecrypto/ccaes.h>
40 #include <corecrypto/ccdes.h>
41 #include <corecrypto/ccmode.h>
43 #include <AssertMacros.h>
45 struct SymCipherContext
{
46 const struct ccmode_cbc
*cbc
;
47 cccbc_ctx u
[]; /* this will have the key and iv */
50 /* Macros for accessing the content of a SymCipherContext */
53 SymCipherContext looks like this in memory:
56 const struct ccmode_cbc *cbc;
61 cccbc_ctx and cccbc_iv are typedef-ined as aligned opaque struct, the actual contexts are arrays
62 of those types normally declared with a cc_ctx_decl macro.
63 The cc_ctx_n macros gives the number of elements in those arrays that are needed to store the
65 The size of the context depends on the actual cbc implementation used.
69 /* CTX_SIZE: Total size of the SymCipherContext struct for a cbc implementation */
71 size_t CTX_SIZE(const struct ccmode_cbc
*cbc
)
73 #ifdef __CC_HAS_FIX_FOR_11468135__
74 return (sizeof(SymCipherContext
) + (sizeof(cccbc_ctx
) * (cc_ctx_n(cccbc_ctx
, cbc
->size
) + cc_ctx_n(cccbc_iv
, cbc
->block_size
))));
76 /* This is approximate, but will work in that case, this code will go away after we transition */
77 return (sizeof(SymCipherContext
) + sizeof(cccbc_ctx
) + cbc
->size
);
81 /* CTX_KEY: Address of the key context in the SymCipherContext struct */
83 cccbc_ctx
*CTX_KEY(struct SymCipherContext
*ctx
)
89 /* CTX_IV: Address of the iv context in the SymCipherContext struct */
90 #ifdef __CC_HAS_FIX_FOR_11468135__
92 cccbc_iv
*CTX_IV(struct SymCipherContext
*ctx
)
94 return (cccbc_iv
*)&ctx
->u
[cc_ctx_n(cccbc_ctx
, ctx
->cbc
->size
)];
99 const void *ccmode(SSL_CipherAlgorithm alg
, int enc
)
102 case SSL_CipherAlgorithmAES_128_CBC
:
103 case SSL_CipherAlgorithmAES_256_CBC
:
104 return enc
?ccaes_cbc_encrypt_mode():ccaes_cbc_decrypt_mode();
105 case SSL_CipherAlgorithm3DES_CBC
:
106 return enc
?ccdes3_cbc_encrypt_mode():ccdes3_cbc_decrypt_mode();
107 case SSL_CipherAlgorithmAES_128_GCM
:
108 case SSL_CipherAlgorithmAES_256_GCM
:
109 case SSL_CipherAlgorithmRC4_128
:
110 /* TODO: we should do RC4 for TLS, but we dont need it for DTLS */
113 return NULL
; /* This will cause CCCryptorCreate to return an error */
119 const SSLSymmetricCipherParams
*params
,
123 SymCipherContext
*cipherCtx
)
125 check(cipherCtx
!=NULL
);
127 SymCipherContext ctx
= *cipherCtx
;
130 * Cook up a cccbx_ctx object. Assumes:
131 * cipherCtx->symCipher.keyAlg
132 * cipherCtx->encrypting
133 * key (raw key bytes)
135 * On successful exit:
136 * Resulting ccmode --> cipherCtx
139 /* FIXME: this should not be needed as long as CCSymFinish is called */
145 const struct ccmode_cbc
*cbc
= ccmode(params
->keyAlg
, encrypting
);
147 ctx
= sslMalloc(CTX_SIZE(cbc
));
150 sslErrorLog("CCSymmInit: Can't allocate context\n");
151 return errSSLRecordInternal
;
156 #ifdef __CC_HAS_FIX_FOR_11468135__
157 cccbc_init(cbc
, CTX_KEY(ctx
), params
->keySize
, key
);
158 cccbc_set_iv(cbc
, CTX_IV(ctx
), iv
);
160 cccbc_init(cbc
, CTX_KEY(ctx
), params
->keySize
, key
, iv
);
167 /* same for en/decrypt */
169 int CCSymmEncryptDecrypt(
173 SymCipherContext cipherCtx
)
176 ASSERT(cipherCtx
!= NULL
);
177 ASSERT(cipherCtx
->cbc
!= NULL
);
179 if(cipherCtx
== NULL
|| cipherCtx
->cbc
== NULL
) {
180 sslErrorLog("CCSymmEncryptDecrypt: NULL cipherCtx\n");
181 return errSSLRecordInternal
;
184 ASSERT((len%cipherCtx
->cbc
->block_size
)==0);
186 if(len%cipherCtx
->cbc
->block_size
) {
187 sslErrorLog("CCSymmEncryptDecrypt: Invalid size\n");
188 return errSSLRecordInternal
;
191 unsigned long nblocks
= len
/cipherCtx
->cbc
->block_size
;
193 #ifdef __CC_HAS_FIX_FOR_11468135__
194 cccbc_update(cipherCtx
->cbc
, CTX_KEY(cipherCtx
), CTX_IV(cipherCtx
), nblocks
, src
, dest
);
196 cipherCtx
->cbc
->cbc(CTX_KEY(cipherCtx
), nblocks
, src
, dest
);
203 SymCipherContext cipherCtx
)
215 #define ENABLE_3DES 1
217 #define ENABLE_AES256 1
220 * CommonCrypto-based symmetric cipher callouts
222 #include <CommonCrypto/CommonCryptor.h>
223 #include <CommonCrypto/CommonCryptorSPI.h>
227 CCAlgorithm
CCAlg(SSL_CipherAlgorithm alg
)
230 case SSL_CipherAlgorithmAES_128_CBC
:
231 case SSL_CipherAlgorithmAES_256_CBC
:
232 case SSL_CipherAlgorithmAES_128_GCM
:
233 case SSL_CipherAlgorithmAES_256_GCM
:
234 return kCCAlgorithmAES128
; /* AES128 here means 128bit block size, not key size */
235 case SSL_CipherAlgorithm3DES_CBC
:
236 return kCCAlgorithm3DES
;
237 case SSL_CipherAlgorithmDES_CBC
:
238 return kCCAlgorithmDES
;
239 case SSL_CipherAlgorithmRC4_128
:
240 return kCCAlgorithmRC4
;
241 case SSL_CipherAlgorithmRC2_128
:
242 return kCCAlgorithmRC2
;
245 return (CCAlgorithm
)(-1); /* This will cause CCCryptorCreate to return an error */
249 static CCOptions
CCOpt(CipherType cipherType
)
252 if(cipherType
==aeadCipherType
) return kCCModeGCM
;
259 const SSLSymmetricCipherParams
*params
,
263 SymCipherContext
*cipherCtx
)
265 assert(cipherCtx
!=NULL
);
268 * Cook up a CCCryptorRef. Assumes:
269 * cipherCtx->symCipher.keyAlg
270 * cipherCtx->encrypting
271 * key (raw key bytes)
273 * On successful exit:
274 * Resulting CCCryptorRef --> cipherCtx->cryptorRef
276 CCCryptorStatus ccrtn
;
277 CCOperation op
= encrypting
? kCCEncrypt
: kCCDecrypt
;
278 CCCryptorRef cryptorRef
= (CCCryptorRef
)*cipherCtx
;
280 /* FIXME: this should not be needed as long as CCSymFinish is called */
282 CCCryptorRelease(cryptorRef
);
286 ccrtn
= CCCryptorCreate(op
, CCAlg(params
->keyAlg
),
287 /* options - gcm or no padding, default CBC */
288 CCOpt(params
->cipherType
),
289 key
, params
->keySize
,
293 sslErrorLog("CCCryptorCreate returned %d\n", (int)ccrtn
);
294 return errSSLRecordInternal
;
296 *cipherCtx
= (SymCipherContext
)cryptorRef
;
300 /* same for en/decrypt */
302 int CCSymmEncryptDecrypt(
306 SymCipherContext cipherCtx
)
308 CCCryptorStatus ccrtn
;
309 CCCryptorRef cryptorRef
= (CCCryptorRef
)cipherCtx
;
310 ASSERT(cryptorRef
!= NULL
);
311 if(cryptorRef
== NULL
) {
312 sslErrorLog("CCSymmEncryptDecrypt: NULL cryptorRef\n");
313 return errSSLRecordInternal
;
316 ccrtn
= CCCryptorUpdate(cryptorRef
, src
, len
,
317 dest
, len
, &data_moved
);
318 assert(data_moved
== len
);
321 sslErrorLog("CCSymmEncryptDecrypt: returned %d\n", (int)ccrtn
);
322 return errSSLRecordInternal
;
330 /* same for en/decrypt */
335 SymCipherContext cipherCtx
)
337 CCCryptorStatus ccrtn
;
338 CCCryptorRef cryptorRef
= (CCCryptorRef
)cipherCtx
;
340 ASSERT(cryptorRef
!= NULL
);
341 if(cryptorRef
== NULL
) {
342 sslErrorLog("CCSymmAEADAddIV: NULL cryptorRef\n");
343 return errSecInternalComponent
;
345 ccrtn
= CCCryptorGCMAddIV(cryptorRef
, iv
, len
);
348 sslErrorLog("CCSymmAEADAddIV: returned %d\n", (int)ccrtn
);
349 return errSSLRecordInternal
;
355 /* same for en/decrypt */
360 SymCipherContext cipherCtx
)
362 CCCryptorStatus ccrtn
;
363 CCCryptorRef cryptorRef
= (CCCryptorRef
)cipherCtx
;
365 ASSERT(cryptorRef
!= NULL
);
366 if(cryptorRef
== NULL
) {
367 sslErrorLog("CCSymmAddADD: NULL cryptorRef\n");
368 return errSSLRecordInternal
;
370 ccrtn
= CCCryptorGCMAddADD(cryptorRef
, src
, len
);
373 sslErrorLog("CCSymmAddADD: returned %d\n", (int)ccrtn
);
374 return errSSLRecordInternal
;
381 int CCSymmAEADEncrypt(
385 SymCipherContext cipherCtx
)
387 CCCryptorStatus ccrtn
;
388 CCCryptorRef cryptorRef
= (CCCryptorRef
)cipherCtx
;
390 ASSERT(cryptorRef
!= NULL
);
391 if(cryptorRef
== NULL
) {
392 sslErrorLog("CCSymmAEADEncrypt: NULL cryptorRef\n");
393 return errSSLRecordInternal
;
395 ccrtn
= CCCryptorGCMEncrypt(cryptorRef
, src
, len
, dest
);
398 sslErrorLog("CCSymmAEADEncrypt: returned %d\n", (int)ccrtn
);
399 return errSSLRecordInternal
;
407 int CCSymmAEADDecrypt(
411 SymCipherContext cipherCtx
)
413 CCCryptorStatus ccrtn
;
414 CCCryptorRef cryptorRef
= (CCCryptorRef
)cipherCtx
;
416 ASSERT(cipherCtx
!= NULL
);
417 ASSERT(cipherCtx
->cryptorRef
!= NULL
);
418 if(cipherCtx
->cryptorRef
== NULL
) {
419 sslErrorLog("CCSymmAEADDecrypt: NULL cryptorRef\n");
420 return errSSLRecordInternal
;
422 ccrtn
= CCCryptorGCMDecrypt(cryptorRef
, src
, len
, dest
);
425 sslErrorLog("CCSymmAEADDecrypt: returned %d\n", (int)ccrtn
);
426 return errSSLRecordInternal
;
437 SymCipherContext cipherCtx
)
439 CCCryptorStatus ccrtn
;
440 CCCryptorRef cryptorRef
= (CCCryptorRef
)cipherCtx
;
442 ASSERT(cipherCtx
!= NULL
);
443 ASSERT(cipherCtx
->cryptorRef
!= NULL
);
444 if(cipherCtx
->cryptorRef
== NULL
) {
445 sslErrorLog("CCSymmAEADDone: NULL cryptorRef\n");
446 return errSSLRecordInternal
;
448 ccrtn
= CCCryptorGCMFinal(cipherCtx
->cryptorRef
, mac
, macLen
);
449 CCCryptorStatus ccrtn2
= CCCryptorGCMReset(cipherCtx
->cryptorRef
);
450 if (ccrtn
== kCCSuccess
)
454 sslErrorLog("CCSymmAEADDone: returned %d\n", (int)ccrtn
);
455 return errSSLRecordInternal
;
464 SymCipherContext cipherCtx
)
466 CCCryptorRef cryptorRef
= (CCCryptorRef
)cipherCtx
;
469 CCCryptorRelease(cryptorRef
);
477 const SSLSymmetricCipher SSLCipherDES_CBC
= {
478 .params
= &SSLCipherDES_CBCParams
,
480 .initialize
= CCSymmInit
,
481 .encrypt
= CCSymmEncryptDecrypt
,
482 .decrypt
= CCSymmEncryptDecrypt
484 .finish
= CCSymmFinish
486 #endif /* ENABLE_DES */
489 const SSLSymmetricCipher SSLCipher3DES_CBC
= {
490 .params
= &SSLCipher3DES_CBCParams
,
492 .initialize
= CCSymmInit
,
493 .encrypt
= CCSymmEncryptDecrypt
,
494 .decrypt
= CCSymmEncryptDecrypt
496 .finish
= CCSymmFinish
498 #endif /* ENABLE_3DES */
501 const SSLSymmetricCipher SSLCipherRC4_128
= {
502 .params
= &SSLCipherRC4_128Params
,
504 .initialize
= CCSymmInit
,
505 .encrypt
= CCSymmEncryptDecrypt
,
506 .decrypt
= CCSymmEncryptDecrypt
508 .finish
= CCSymmFinish
510 #endif /* ENABLE_RC4 */
513 const SSLSymmetricCipher SSLCipherRC2_128
= {
514 .params
= &SSLCipherRC2_128Params
,
516 .initialize
= CCSymmInit
,
517 .encrypt
= CCSymmEncryptDecrypt
,
518 .decrypt
= CCSymmEncryptDecrypt
520 .finish
= CCSymmFinish
522 #endif /* ENABLE_RC2*/
525 const SSLSymmetricCipher SSLCipherAES_128_CBC
= {
526 .params
= &SSLCipherAES_128_CBCParams
,
528 .initialize
= CCSymmInit
,
529 .encrypt
= CCSymmEncryptDecrypt
,
530 .decrypt
= CCSymmEncryptDecrypt
532 .finish
= CCSymmFinish
534 #endif /* ENABLE_AES */
537 const SSLSymmetricCipher SSLCipherAES_256_CBC
= {
538 .params
= &SSLCipherAES_256_CBCParams
,
540 .initialize
= CCSymmInit
,
541 .encrypt
= CCSymmEncryptDecrypt
,
542 .decrypt
= CCSymmEncryptDecrypt
544 .finish
= CCSymmFinish
546 #endif /* ENABLE_AES256 */
549 const SSLSymmetricCipher SSLCipherAES_128_GCM
= {
550 .params
= &SSLCipherAES_128_GCMParams
,
552 .initialize
= CCSymmInit
,
553 .setIV
= CCSymmAEADSetIV
,
554 .update
= CCSymmAddADD
,
555 .encrypt
= CCSymmAEADEncrypt
,
556 .decrypt
= CCSymmAEADDecrypt
,
557 .done
= CCSymmAEADDone
559 .finish
= CCSymmFinish
562 const SSLSymmetricCipher SSLCipherAES_256_GCM
= {
563 .params
= &SSLCipherAES_256_GCMParams
,
565 .initialize
= CCSymmInit
,
566 .setIV
= CCSymmAEADSetIV
,
567 .update
= CCSymmAddADD
,
568 .encrypt
= CCSymmAEADEncrypt
,
569 .decrypt
= CCSymmAEADDecrypt
,
570 .done
= CCSymmAEADDone
572 .finish
= CCSymmFinish
574 #endif /* ENABLE_AES_GCM */