]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/lib/symCipher.c
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_ssl / lib / symCipher.c
1 /*
2 * Copyright (c) 1999-2001,2005-2008,2010-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * symCipher.c - CommonCrypto-based symmetric cipher module
26 */
27
28 /* THIS FILE CONTAINS KERNEL CODE */
29
30 #include "sslBuildFlags.h"
31 #include "sslDebug.h"
32 #include "sslMemory.h"
33 #include "symCipher.h"
34 #include "cipherSpecs.h"
35 #include "SSLRecordInternal.h"
36
37 #ifdef KERNEL
38
39 #include <corecrypto/ccaes.h>
40 #include <corecrypto/ccdes.h>
41 #include <corecrypto/ccmode.h>
42
43 #include <AssertMacros.h>
44
45 struct SymCipherContext {
46 const struct ccmode_cbc *cbc;
47 cccbc_ctx u[]; /* this will have the key and iv */
48 };
49
50 /* Macros for accessing the content of a SymCipherContext */
51
52 /*
53 SymCipherContext looks like this in memory:
54
55 {
56 const struct ccmode_cbc *cbc;
57 cccbc_ctx key[n];
58 cccbc_iv iv[m];
59 }
60
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
64 contexts.
65 The size of the context depends on the actual cbc implementation used.
66 */
67
68
69 /* CTX_SIZE: Total size of the SymCipherContext struct for a cbc implementation */
70 static inline
71 size_t CTX_SIZE(const struct ccmode_cbc *cbc)
72 {
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))));
75 #else
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);
78 #endif
79 }
80
81 /* CTX_KEY: Address of the key context in the SymCipherContext struct */
82 static inline
83 cccbc_ctx *CTX_KEY(struct SymCipherContext *ctx)
84 {
85 return &ctx->u[0];
86 }
87
88
89 /* CTX_IV: Address of the iv context in the SymCipherContext struct */
90 #ifdef __CC_HAS_FIX_FOR_11468135__
91 static inline
92 cccbc_iv *CTX_IV(struct SymCipherContext *ctx)
93 {
94 return (cccbc_iv *)&ctx->u[cc_ctx_n(cccbc_ctx, ctx->cbc->size)];
95 }
96 #endif
97
98 static
99 const void *ccmode(SSL_CipherAlgorithm alg, int enc)
100 {
101 switch(alg) {
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 */
111 default:
112 check(0);
113 return NULL; /* This will cause CCCryptorCreate to return an error */
114 }
115 }
116
117 static
118 int CCSymmInit(
119 const SSLSymmetricCipherParams *params,
120 int encrypting,
121 uint8_t *key,
122 uint8_t* iv,
123 SymCipherContext *cipherCtx)
124 {
125 check(cipherCtx!=NULL);
126 check(params);
127 SymCipherContext ctx = *cipherCtx;
128
129 /*
130 * Cook up a cccbx_ctx object. Assumes:
131 * cipherCtx->symCipher.keyAlg
132 * cipherCtx->encrypting
133 * key (raw key bytes)
134 * iv (raw bytes)
135 * On successful exit:
136 * Resulting ccmode --> cipherCtx
137 */
138
139 /* FIXME: this should not be needed as long as CCSymFinish is called */
140 if(ctx) {
141 sslFree(ctx);
142 ctx = NULL;
143 }
144
145 const struct ccmode_cbc *cbc = ccmode(params->keyAlg, encrypting);
146
147 ctx = sslMalloc(CTX_SIZE(cbc));
148
149 if(ctx==NULL) {
150 sslErrorLog("CCSymmInit: Can't allocate context\n");
151 return errSSLRecordInternal;
152 }
153
154 ctx->cbc = cbc;
155
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);
159 #else
160 cccbc_init(cbc, CTX_KEY(ctx), params->keySize, key, iv);
161 #endif
162
163 *cipherCtx = ctx;
164 return 0;
165 }
166
167 /* same for en/decrypt */
168 static
169 int CCSymmEncryptDecrypt(
170 const uint8_t *src,
171 uint8_t *dest,
172 size_t len,
173 SymCipherContext cipherCtx)
174 {
175
176 ASSERT(cipherCtx != NULL);
177 ASSERT(cipherCtx->cbc != NULL);
178
179 if(cipherCtx == NULL || cipherCtx->cbc == NULL) {
180 sslErrorLog("CCSymmEncryptDecrypt: NULL cipherCtx\n");
181 return errSSLRecordInternal;
182 }
183
184 ASSERT((len%cipherCtx->cbc->block_size)==0);
185
186 if(len%cipherCtx->cbc->block_size) {
187 sslErrorLog("CCSymmEncryptDecrypt: Invalid size\n");
188 return errSSLRecordInternal;
189 }
190
191 unsigned long nblocks = len/cipherCtx->cbc->block_size;
192
193 #ifdef __CC_HAS_FIX_FOR_11468135__
194 cccbc_update(cipherCtx->cbc, CTX_KEY(cipherCtx), CTX_IV(cipherCtx), nblocks, src, dest);
195 #else
196 cipherCtx->cbc->cbc(CTX_KEY(cipherCtx), nblocks, src, dest);
197 #endif
198 return 0;
199 }
200
201 static
202 int CCSymmFinish(
203 SymCipherContext cipherCtx)
204 {
205 if(cipherCtx) {
206 sslFree(cipherCtx);
207 }
208 return 0;
209 }
210
211
212 #else
213
214 #define ENABLE_RC4 1
215 #define ENABLE_3DES 1
216 #define ENABLE_AES 1
217 #define ENABLE_AES256 1
218
219 /*
220 * CommonCrypto-based symmetric cipher callouts
221 */
222 #include <CommonCrypto/CommonCryptor.h>
223 #include <CommonCrypto/CommonCryptorSPI.h>
224 #include <assert.h>
225
226 static
227 CCAlgorithm CCAlg(SSL_CipherAlgorithm alg)
228 {
229 switch(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;
243 default:
244 assert(0);
245 return (CCAlgorithm)(-1); /* This will cause CCCryptorCreate to return an error */
246 }
247 }
248
249 static CCOptions CCOpt(CipherType cipherType)
250 {
251 #if 0
252 if(cipherType==aeadCipherType) return kCCModeGCM;
253 #endif
254 return 0;
255 }
256
257 static
258 int CCSymmInit(
259 const SSLSymmetricCipherParams *params,
260 int encrypting,
261 uint8_t *key,
262 uint8_t* iv,
263 SymCipherContext *cipherCtx)
264 {
265 assert(cipherCtx!=NULL);
266
267 /*
268 * Cook up a CCCryptorRef. Assumes:
269 * cipherCtx->symCipher.keyAlg
270 * cipherCtx->encrypting
271 * key (raw key bytes)
272 * iv (raw bytes)
273 * On successful exit:
274 * Resulting CCCryptorRef --> cipherCtx->cryptorRef
275 */
276 CCCryptorStatus ccrtn;
277 CCOperation op = encrypting ? kCCEncrypt : kCCDecrypt;
278 CCCryptorRef cryptorRef = (CCCryptorRef)*cipherCtx;
279
280 /* FIXME: this should not be needed as long as CCSymFinish is called */
281 if(cryptorRef) {
282 CCCryptorRelease(cryptorRef);
283 cryptorRef = NULL;
284 }
285
286 ccrtn = CCCryptorCreate(op, CCAlg(params->keyAlg),
287 /* options - gcm or no padding, default CBC */
288 CCOpt(params->cipherType),
289 key, params->keySize,
290 iv,
291 &cryptorRef);
292 if(ccrtn) {
293 sslErrorLog("CCCryptorCreate returned %d\n", (int)ccrtn);
294 return errSSLRecordInternal;
295 }
296 *cipherCtx = (SymCipherContext)cryptorRef;
297 return 0;
298 }
299
300 /* same for en/decrypt */
301 static
302 int CCSymmEncryptDecrypt(
303 const uint8_t *src,
304 uint8_t *dest,
305 size_t len,
306 SymCipherContext cipherCtx)
307 {
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;
314 }
315 size_t data_moved;
316 ccrtn = CCCryptorUpdate(cryptorRef, src, len,
317 dest, len, &data_moved);
318 assert(data_moved == len);
319 #if SSL_DEBUG
320 if(ccrtn) {
321 sslErrorLog("CCSymmEncryptDecrypt: returned %d\n", (int)ccrtn);
322 return errSSLRecordInternal;
323 }
324 #endif
325 return 0;
326 }
327
328 #if ENABLE_AES_GCM
329
330 /* same for en/decrypt */
331 static
332 int CCSymmAEADSetIV(
333 const uint8_t *iv,
334 size_t len,
335 SymCipherContext cipherCtx)
336 {
337 CCCryptorStatus ccrtn;
338 CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
339
340 ASSERT(cryptorRef != NULL);
341 if(cryptorRef == NULL) {
342 sslErrorLog("CCSymmAEADAddIV: NULL cryptorRef\n");
343 return errSecInternalComponent;
344 }
345 ccrtn = CCCryptorGCMAddIV(cryptorRef, iv, len);
346 #if SSL_DEBUG
347 if(ccrtn) {
348 sslErrorLog("CCSymmAEADAddIV: returned %d\n", (int)ccrtn);
349 return errSSLRecordInternal;
350 }
351 #endif
352 return 0;
353 }
354
355 /* same for en/decrypt */
356 static
357 int CCSymmAddADD(
358 const uint8_t *src,
359 size_t len,
360 SymCipherContext cipherCtx)
361 {
362 CCCryptorStatus ccrtn;
363 CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
364
365 ASSERT(cryptorRef != NULL);
366 if(cryptorRef == NULL) {
367 sslErrorLog("CCSymmAddADD: NULL cryptorRef\n");
368 return errSSLRecordInternal;
369 }
370 ccrtn = CCCryptorGCMAddADD(cryptorRef, src, len);
371 #if SSL_DEBUG
372 if(ccrtn) {
373 sslErrorLog("CCSymmAddADD: returned %d\n", (int)ccrtn);
374 return errSSLRecordInternal;
375 }
376 #endif
377 return 0;
378 }
379
380 static
381 int CCSymmAEADEncrypt(
382 const uint8_t *src,
383 uint8_t *dest,
384 size_t len,
385 SymCipherContext cipherCtx)
386 {
387 CCCryptorStatus ccrtn;
388 CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
389
390 ASSERT(cryptorRef != NULL);
391 if(cryptorRef == NULL) {
392 sslErrorLog("CCSymmAEADEncrypt: NULL cryptorRef\n");
393 return errSSLRecordInternal;
394 }
395 ccrtn = CCCryptorGCMEncrypt(cryptorRef, src, len, dest);
396 #if SSL_DEBUG
397 if(ccrtn) {
398 sslErrorLog("CCSymmAEADEncrypt: returned %d\n", (int)ccrtn);
399 return errSSLRecordInternal;
400 }
401 #endif
402 return 0;
403 }
404
405
406 static
407 int CCSymmAEADDecrypt(
408 const uint8_t *src,
409 uint8_t *dest,
410 size_t len,
411 SymCipherContext cipherCtx)
412 {
413 CCCryptorStatus ccrtn;
414 CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
415
416 ASSERT(cipherCtx != NULL);
417 ASSERT(cipherCtx->cryptorRef != NULL);
418 if(cipherCtx->cryptorRef == NULL) {
419 sslErrorLog("CCSymmAEADDecrypt: NULL cryptorRef\n");
420 return errSSLRecordInternal;
421 }
422 ccrtn = CCCryptorGCMDecrypt(cryptorRef, src, len, dest);
423 #if SSL_DEBUG
424 if(ccrtn) {
425 sslErrorLog("CCSymmAEADDecrypt: returned %d\n", (int)ccrtn);
426 return errSSLRecordInternal;
427 }
428 #endif
429 return 0;
430 }
431
432
433 static
434 int CCSymmAEADDone(
435 uint8_t *mac,
436 size_t *macLen,
437 SymCipherContext cipherCtx)
438 {
439 CCCryptorStatus ccrtn;
440 CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
441
442 ASSERT(cipherCtx != NULL);
443 ASSERT(cipherCtx->cryptorRef != NULL);
444 if(cipherCtx->cryptorRef == NULL) {
445 sslErrorLog("CCSymmAEADDone: NULL cryptorRef\n");
446 return errSSLRecordInternal;
447 }
448 ccrtn = CCCryptorGCMFinal(cipherCtx->cryptorRef, mac, macLen);
449 CCCryptorStatus ccrtn2 = CCCryptorGCMReset(cipherCtx->cryptorRef);
450 if (ccrtn == kCCSuccess)
451 ccrtn = ccrtn2;
452 #if SSL_DEBUG
453 if(ccrtn) {
454 sslErrorLog("CCSymmAEADDone: returned %d\n", (int)ccrtn);
455 return errSSLRecordInternal;
456 }
457 #endif
458 return 0;
459 }
460 #endif
461
462 static
463 int CCSymmFinish(
464 SymCipherContext cipherCtx)
465 {
466 CCCryptorRef cryptorRef = (CCCryptorRef)cipherCtx;
467
468 if(cryptorRef) {
469 CCCryptorRelease(cryptorRef);
470 }
471 return 0;
472 }
473
474 #endif /* KERNEL */
475
476 #if ENABLE_DES
477 const SSLSymmetricCipher SSLCipherDES_CBC = {
478 .params = &SSLCipherDES_CBCParams,
479 .c.cipher = {
480 .initialize = CCSymmInit,
481 .encrypt = CCSymmEncryptDecrypt,
482 .decrypt = CCSymmEncryptDecrypt
483 },
484 .finish = CCSymmFinish
485 };
486 #endif /* ENABLE_DES */
487
488 #if ENABLE_3DES
489 const SSLSymmetricCipher SSLCipher3DES_CBC = {
490 .params = &SSLCipher3DES_CBCParams,
491 .c.cipher = {
492 .initialize = CCSymmInit,
493 .encrypt = CCSymmEncryptDecrypt,
494 .decrypt = CCSymmEncryptDecrypt
495 },
496 .finish = CCSymmFinish
497 };
498 #endif /* ENABLE_3DES */
499
500 #if ENABLE_RC4
501 const SSLSymmetricCipher SSLCipherRC4_128 = {
502 .params = &SSLCipherRC4_128Params,
503 .c.cipher = {
504 .initialize = CCSymmInit,
505 .encrypt = CCSymmEncryptDecrypt,
506 .decrypt = CCSymmEncryptDecrypt
507 },
508 .finish = CCSymmFinish
509 };
510 #endif /* ENABLE_RC4 */
511
512 #if ENABLE_RC2
513 const SSLSymmetricCipher SSLCipherRC2_128 = {
514 .params = &SSLCipherRC2_128Params,
515 .c.cipher = {
516 .initialize = CCSymmInit,
517 .encrypt = CCSymmEncryptDecrypt,
518 .decrypt = CCSymmEncryptDecrypt
519 },
520 .finish = CCSymmFinish
521 };
522 #endif /* ENABLE_RC2*/
523
524 #if ENABLE_AES
525 const SSLSymmetricCipher SSLCipherAES_128_CBC = {
526 .params = &SSLCipherAES_128_CBCParams,
527 .c.cipher = {
528 .initialize = CCSymmInit,
529 .encrypt = CCSymmEncryptDecrypt,
530 .decrypt = CCSymmEncryptDecrypt
531 },
532 .finish = CCSymmFinish
533 };
534 #endif /* ENABLE_AES */
535
536 #if ENABLE_AES256
537 const SSLSymmetricCipher SSLCipherAES_256_CBC = {
538 .params = &SSLCipherAES_256_CBCParams,
539 .c.cipher = {
540 .initialize = CCSymmInit,
541 .encrypt = CCSymmEncryptDecrypt,
542 .decrypt = CCSymmEncryptDecrypt
543 },
544 .finish = CCSymmFinish
545 };
546 #endif /* ENABLE_AES256 */
547
548 #if ENABLE_AES_GCM
549 const SSLSymmetricCipher SSLCipherAES_128_GCM = {
550 .params = &SSLCipherAES_128_GCMParams,
551 .c.aead = {
552 .initialize = CCSymmInit,
553 .setIV = CCSymmAEADSetIV,
554 .update = CCSymmAddADD,
555 .encrypt = CCSymmAEADEncrypt,
556 .decrypt = CCSymmAEADDecrypt,
557 .done = CCSymmAEADDone
558 },
559 .finish = CCSymmFinish
560 };
561
562 const SSLSymmetricCipher SSLCipherAES_256_GCM = {
563 .params = &SSLCipherAES_256_GCMParams,
564 .c.aead = {
565 .initialize = CCSymmInit,
566 .setIV = CCSymmAEADSetIV,
567 .update = CCSymmAddADD,
568 .encrypt = CCSymmAEADEncrypt,
569 .decrypt = CCSymmAEADDecrypt,
570 .done = CCSymmAEADDone
571 },
572 .finish = CCSymmFinish
573 };
574 #endif /* ENABLE_AES_GCM */