]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecRSAKey.c
Security-57337.50.23.tar.gz
[apple/security.git] / OSX / sec / Security / SecRSAKey.c
1 /*
2 * Copyright (c) 2006-2010,2012-2015 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 * SecRSAKey.c - CoreFoundation based rsa key object
26 */
27
28
29 #include "SecRSAKey.h"
30 #include "SecRSAKeyPriv.h"
31 #include <Security/SecKeyInternal.h>
32 #include <Security/SecItem.h>
33 #include <Security/SecBasePriv.h>
34 #include <AssertMacros.h>
35 #include <Security/SecureTransport.h> /* For error codes. */
36 #include <CoreFoundation/CFData.h> /* For error codes. */
37 #include <fcntl.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <CoreFoundation/CFNumber.h>
41 #include <Security/SecFramework.h>
42 #include <Security/SecRandom.h>
43 #include <utilities/debugging.h>
44 #include <utilities/SecCFWrappers.h>
45 #include "SecItemPriv.h"
46 #include <Security/SecInternal.h>
47
48 #include <corecrypto/ccn.h>
49 #include <corecrypto/ccrsa.h>
50 #include <corecrypto/ccsha1.h>
51
52 #include <libDER/asn1Types.h>
53 #include <libDER/DER_Keys.h>
54 #include <libDER/DER_Encode.h>
55
56 #include <CommonCrypto/CommonDigest.h>
57
58 #include <corecrypto/ccrsa_priv.h>
59
60 #include <stdint.h>
61 #include <string.h>
62
63 #define kMaximumRSAKeyBits (1024 * 8)
64
65 #define RSA_PKCS1_PAD_SIGN 0x01
66 #define RSA_PKCS1_PAD_ENCRYPT 0x02
67
68 static void ccn_c_dump(cc_size count, const cc_unit *s)
69 {
70 printf("{ ");
71 cc_size ix;
72 for (ix = count; ix--;) {
73 printf("0x%.02x, 0x%.02x, 0x%.02x, 0x%.02x, ",
74 (int) ((s[ix] >> 24) & 0xFF),
75 (int) ((s[ix] >> 16) & 0xFF),
76 (int) ((s[ix] >> 8 ) & 0xFF),
77 (int) ((s[ix] >> 0 ) & 0xFF));
78 }
79 printf("};");
80 }
81
82 static void ccn_cprint(cc_size count, char* prefix, const cc_unit *s)
83 {
84 printf("%s", prefix);
85 ccn_c_dump(count, s);
86 printf("\n");
87 }
88
89 void ccrsa_dump_full_key(ccrsa_full_ctx_t key); // Suppress warnings
90 void ccrsa_dump_full_key(ccrsa_full_ctx_t key) {
91 ccn_cprint(ccrsa_ctx_n(key), "uint8_t m[] = ", ccrsa_ctx_m(key));
92 ccn_cprint(ccrsa_ctx_n(key) + 1, "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
93 ccn_cprint(ccrsa_ctx_n(key), "uint8_t e[] = ", ccrsa_ctx_e(key));
94 ccn_cprint(ccrsa_ctx_n(key), "uint8_t d[] = ", ccrsa_ctx_d(key));
95
96 printf("cc_size np = %lu;\n", cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
97 ccn_cprint(cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))), "uint8_t p[] = ",
98 cczp_prime(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
99 ccn_cprint(cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))) + 1, "uint8_t rp[] = ",
100 cczp_recip(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))));
101 printf("cc_size nq = %lu;\n", cczp_n(ccrsa_ctx_private_zq(ccrsa_ctx_private(key))));
102 ccn_cprint(cczp_n(ccrsa_ctx_private_zq(ccrsa_ctx_private(key))), "uint8_t q[] = ",
103 cczp_prime(ccrsa_ctx_private_zq(ccrsa_ctx_private(key))));
104 ccn_cprint(cczp_n(ccrsa_ctx_private_zq(ccrsa_ctx_private(key))) + 1, "uint8_t rq[] = ",
105 cczp_recip(ccrsa_ctx_private_zq(ccrsa_ctx_private(key))));
106 ccn_cprint(cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))), "uint8_t dp[] = ",
107 ccrsa_ctx_private_dp(ccrsa_ctx_private(key)));
108 ccn_cprint(cczp_n(ccrsa_ctx_private_zq(ccrsa_ctx_private(key))), "uint8_t dq[] = ",
109 ccrsa_ctx_private_dq(ccrsa_ctx_private(key)));
110 ccn_cprint(cczp_n(ccrsa_ctx_private_zp(ccrsa_ctx_private(key))), "uint8_t qinv[] = ",
111 ccrsa_ctx_private_qinv(ccrsa_ctx_private(key)));
112 printf("--\n");
113 }
114
115 void ccrsa_dump_public_key(ccrsa_pub_ctx_t key); // Suppress warning.
116 void ccrsa_dump_public_key(ccrsa_pub_ctx_t key) {
117 ccn_cprint(ccrsa_ctx_n(key), "uint8_t m[] = ", ccrsa_ctx_m(key));
118 ccn_cprint(ccrsa_ctx_n(key) + 1, "uint8_t rm[] = ", cczp_recip(ccrsa_ctx_zm(key)));
119 ccn_cprint(ccrsa_ctx_n(key), "uint8_t e[] = ", ccrsa_ctx_e(key));
120
121 printf("--\n");
122 }
123
124 /*
125 *
126 * Public Key
127 *
128 */
129
130 /* Public key static functions. */
131 static void SecRSAPublicKeyDestroy(SecKeyRef key) {
132 /* Zero out the public key */
133 if (key->key) {
134 ccrsa_pub_ctx_t pubkey;
135 pubkey.pub = key->key;
136 cc_clear(ccrsa_pub_ctx_size(ccn_sizeof_n(ccrsa_ctx_n(pubkey))), pubkey.pub);
137 free(key->key);
138 key->key = NULL;
139 }
140 }
141
142 #define cc_skip_zeros(size, ptr) { while (size > 0 && *ptr == 0) { ++ptr; --size; } }
143
144 //
145 // pubkey is initilaized with an n which is the maximum it can hold
146 // We set the n to its correct value given m.
147 //
148 static int ccrsa_pub_init(ccrsa_pub_ctx_t pubkey,
149 size_t m_size, const uint8_t* m,
150 size_t e_size, const uint8_t* e)
151 {
152 cc_skip_zeros(m_size, m);
153
154 cc_size nm = ccn_nof_size(m_size);
155 if (nm > ccrsa_ctx_n(pubkey))
156 return -1;
157
158 ccrsa_ctx_n(pubkey) = nm;
159
160 ccn_read_uint(nm, ccrsa_ctx_m(pubkey), m_size, m);
161 cczp_init(ccrsa_ctx_zm(pubkey));
162
163 return ccn_read_uint(nm, ccrsa_ctx_e(pubkey), e_size, e);
164 }
165
166
167 static OSStatus ccrsa_pub_decode_apple(ccrsa_pub_ctx_t pubkey, size_t pkcs1_size, const uint8_t* pkcs1)
168 {
169 OSStatus result = errSecParam;
170
171 DERItem keyItem = {(DERByte *)pkcs1, pkcs1_size};
172 DERRSAPubKeyApple decodedKey;
173
174 require_noerr_action(DERParseSequence(&keyItem,
175 DERNumRSAPubKeyAppleItemSpecs, DERRSAPubKeyAppleItemSpecs,
176 &decodedKey, sizeof(decodedKey)),
177 errOut, result = errSecDecode);
178
179 // We could honor the recipricol, but we don't think this is used enough to care.
180 // Don't bother exploding the below function to try to handle this case, it computes.
181
182 require_noerr(ccrsa_pub_init(pubkey,
183 decodedKey.modulus.length, decodedKey.modulus.data,
184 decodedKey.pubExponent.length, decodedKey.pubExponent.data),
185 errOut);
186
187 result = errSecSuccess;
188
189 errOut:
190 return result;
191 }
192
193
194 static void ccasn_encode_int(cc_size n, const cc_unit*s, size_t s_size, uint8_t **buffer)
195 {
196 **buffer = ASN1_INTEGER;
197 *buffer += 1;
198
199 DERSize itemLength = 4;
200 DEREncodeLength(s_size, *buffer, &itemLength);
201 *buffer += itemLength;
202
203 ccn_write_int(n, s, s_size, *buffer);
204
205 *buffer += s_size;
206 }
207
208
209 static OSStatus SecRSAPublicKeyInit(SecKeyRef key,
210 const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
211
212 OSStatus result = errSecParam;
213 ccrsa_pub_ctx_t pubkey;
214 size_t size_n = 0;
215
216 switch (encoding) {
217 case kSecKeyEncodingBytes: // Octets is PKCS1
218 case kSecKeyEncodingPkcs1: {
219 const uint8_t *der_end = keyData + keyDataLength;
220 size_n = ccder_decode_rsa_pub_n(keyData, der_end);
221 require(size_n != 0, errOut);
222 require(size_n <= ccn_nof(kMaximumRSAKeyBits), errOut);
223
224 key->key = calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n)));
225 require_action(key->key, errOut, result = errSecAllocate);
226
227 pubkey.pub = key->key;
228 ccrsa_ctx_n(pubkey) = size_n;
229
230 require_noerr(ccrsa_import_pub(pubkey, keyDataLength, keyData), errOut);
231
232 result = errSecSuccess;
233
234 break;
235 }
236 case kSecKeyEncodingApplePkcs1:
237 /* for the few uses (I can't find any) that uses kSecKeyEncodingApplePkcs1, force largest keys */
238 size_n = ccn_nof(kMaximumRSAKeyBits);
239
240 key->key = calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n)));
241 require_action(key->key, errOut, result = errSecAllocate);
242
243 pubkey.pub = key->key;
244 ccrsa_ctx_n(pubkey) = size_n;
245
246 result = ccrsa_pub_decode_apple(pubkey, keyDataLength, keyData);
247 break;
248 case kSecKeyEncodingRSAPublicParams:
249 {
250 SecRSAPublicKeyParams *params = (SecRSAPublicKeyParams *)keyData;
251
252 size_n = ccn_nof_size(params->modulusLength);
253
254 key->key = calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n)));
255 require_action(key->key, errOut, result = errSecAllocate);
256
257 pubkey.pub = key->key;
258 ccrsa_ctx_n(pubkey) = size_n;
259
260 require_noerr(ccrsa_pub_init(pubkey,
261 params->modulusLength, params->modulus,
262 params->exponentLength, params->exponent), errOut);
263
264 result = errSecSuccess;
265 break;
266 }
267 case kSecExtractPublicFromPrivate:
268 {
269 ccrsa_full_ctx_t fullKey;
270 fullKey.full = (ccrsa_full_ctx*) keyData;
271
272 size_n = ccrsa_ctx_n(fullKey);
273
274 key->key = calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n)));
275 require_action(key->key, errOut, result = errSecAllocate);
276
277 pubkey.pub = key->key;
278 ccrsa_ctx_n(pubkey) = size_n;
279
280 memcpy(pubkey.pub, ccrsa_ctx_public(fullKey).pub, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n)));
281 result = errSecSuccess;
282 break;
283 }
284 default:
285 break;
286 }
287
288 errOut:
289 return result;
290 }
291
292 static OSStatus SecRSAPublicKeyRawVerify(SecKeyRef key, SecPadding padding,
293 const uint8_t *signedData, size_t signedDataLen,
294 const uint8_t *sig, size_t sigLen) {
295 OSStatus result = errSSLCrypto;
296
297 ccrsa_pub_ctx_t pubkey;
298 pubkey.pub = key->key;
299
300 cc_unit s[ccrsa_ctx_n(pubkey)];
301
302 ccn_read_uint(ccrsa_ctx_n(pubkey), s, sigLen, sig);
303 ccrsa_pub_crypt(pubkey, s, s);
304 ccn_swap(ccrsa_ctx_n(pubkey), s);
305
306 const uint8_t* sBytes = (uint8_t*) s;
307 const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
308
309 switch (padding) {
310 case kSecPaddingNone:
311 // Skip leading zeros as long as s is bigger than signedData.
312 while (((ptrdiff_t)signedDataLen < (sEnd - sBytes)) && (*sBytes == 0))
313 ++sBytes;
314 break;
315
316 case kSecPaddingPKCS1:
317 {
318 // Verify and skip PKCS1 padding:
319 //
320 // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData
321 //
322 size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
323 size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(pubkey)) - m_size;
324
325 while (prefix_zeros--)
326 require_quiet(*sBytes++ == 0x00, errOut);
327
328 require_quiet(*sBytes++ == 0x00, errOut);
329 require_quiet(*sBytes++ == RSA_PKCS1_PAD_SIGN, errOut);
330
331 while (*sBytes == 0xFF) {
332 require_quiet(++sBytes < sEnd, errOut);
333 }
334 // Required to have at least 8 0xFFs
335 require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
336
337 require_quiet(*sBytes == 0x00, errOut);
338 require_quiet(++sBytes < sEnd, errOut);
339 break;
340 }
341 case kSecPaddingOAEP:
342 result = errSecParam;
343 goto errOut;
344
345 default:
346 result = errSecUnimplemented;
347 goto errOut;
348 }
349
350 // Compare the rest.
351 require_quiet((sEnd - sBytes) == (ptrdiff_t)signedDataLen, errOut);
352 require_quiet(memcmp(sBytes, signedData, signedDataLen) == 0, errOut);
353
354 result = errSecSuccess;
355
356 errOut:
357 cc_clear(ccrsa_ctx_n(pubkey), s);
358
359 return result;
360 }
361
362 static OSStatus SecRSAPublicKeyRawEncrypt(SecKeyRef key, SecPadding padding,
363 const uint8_t *plainText, size_t plainTextLen,
364 uint8_t *cipherText, size_t *cipherTextLen) {
365 OSStatus result = errSecParam;
366 ccrsa_pub_ctx_t pubkey;
367 pubkey.pub = key->key;
368
369 cc_unit s[ccrsa_ctx_n(pubkey)];
370 const size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
371
372 require(cipherTextLen, errOut);
373 require(*cipherTextLen >= m_size, errOut);
374
375 uint8_t* sBytes = (uint8_t*) s;
376
377 switch (padding) {
378 case kSecPaddingNone:
379 // We'll allow modulus size assuming input is smaller than modulus
380 require_quiet(plainTextLen <= m_size, errOut);
381 require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(pubkey), s, plainTextLen, plainText), errOut);
382 require_quiet(ccn_cmp(ccrsa_ctx_n(pubkey), s, ccrsa_ctx_m(pubkey)) < 0, errOut);
383 break;
384
385 case kSecPaddingPKCS1:
386 {
387 // Create PKCS1 padding:
388 //
389 // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData
390 //
391 const int kMinimumPadding = 1 + 1 + 8 + 1;
392
393 require_quiet(plainTextLen <= m_size - kMinimumPadding, errOut);
394
395 size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(pubkey)) - m_size;
396
397 while (prefix_zeros--)
398 *sBytes++ = 0x00;
399
400 size_t pad_size = m_size - plainTextLen;
401
402 *sBytes++ = 0x00;
403 *sBytes++ = RSA_PKCS1_PAD_ENCRYPT;
404
405 ccrng_generate(ccrng_seckey, pad_size - 3, sBytes);
406 // Remove zeroes from the random pad
407
408 const uint8_t* sEndOfPad = sBytes + (pad_size - 3);
409 while (sBytes < sEndOfPad)
410 {
411 if (*sBytes == 0x00)
412 *sBytes = 0xFF; // Michael said 0xFF was good enough.
413
414 ++sBytes;
415 }
416
417 *sBytes++ = 0x00;
418
419 memcpy(sBytes, plainText, plainTextLen);
420
421 ccn_swap(ccrsa_ctx_n(pubkey), s);
422 break;
423 }
424 case kSecPaddingOAEP:
425 {
426 const struct ccdigest_info* di = ccsha1_di();
427
428 const size_t encodingOverhead = 2 + 2 * di->output_size;
429
430 require_action(m_size > encodingOverhead, errOut, result = errSecParam);
431 require_action_quiet(plainTextLen <= m_size - encodingOverhead, errOut, result = errSecParam);
432
433 require_noerr_action(ccrsa_oaep_encode(di,
434 ccrng_seckey,
435 m_size, s,
436 plainTextLen, plainText), errOut, result = errSecInternal);
437 break;
438 }
439 default:
440 goto errOut;
441 }
442
443
444 ccrsa_pub_crypt(pubkey, s, s);
445
446 ccn_write_uint_padded(ccrsa_ctx_n(pubkey), s, m_size, cipherText);
447 *cipherTextLen = m_size;
448
449 result = errSecSuccess;
450
451 errOut:
452 ccn_zero(ccrsa_ctx_n(pubkey), s);
453 return result;
454 }
455
456 static OSStatus SecRSAPublicKeyRawDecrypt(SecKeyRef key, SecPadding padding,
457 const uint8_t *cipherText, size_t cipherTextLen, uint8_t *plainText, size_t *plainTextLen) {
458 OSStatus result = errSSLCrypto;
459
460 ccrsa_pub_ctx_t pubkey;
461 pubkey.pub = key->key;
462
463 cc_unit s[ccrsa_ctx_n(pubkey)];
464
465 require_action_quiet(cipherText != NULL, errOut, result = errSecParam);
466 require_action_quiet(plainText != NULL, errOut, result = errSecParam);
467 require_action_quiet(plainTextLen != NULL, errOut, result = errSecParam);
468
469 ccn_read_uint(ccrsa_ctx_n(pubkey), s, cipherTextLen, cipherText);
470 ccrsa_pub_crypt(pubkey, s, s);
471 ccn_swap(ccrsa_ctx_n(pubkey), s);
472
473 const uint8_t* sBytes = (uint8_t*) s;
474 const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(pubkey));
475
476 switch (padding) {
477 case kSecPaddingNone:
478 // Skip leading zeros
479 // We return the bytes for a number and
480 // trim leading zeroes
481 while (sBytes < sEnd && *sBytes == 0x00)
482 ++sBytes;
483 break;
484
485 case kSecPaddingPKCS1:
486 {
487 // Verify and skip PKCS1 padding:
488 //
489 // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData
490 //
491 size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
492 size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(pubkey)) - m_size;
493
494 while (prefix_zeros--)
495 require_quiet(*sBytes++ == 0x00, errOut);
496
497 require_quiet(*sBytes++ == 0x00, errOut);
498 require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
499
500 while (*sBytes != 0x00) {
501 require_quiet(++sBytes < sEnd, errOut);
502 }
503 // Required to have at least 8 0xFFs
504 require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
505
506 require_quiet(*sBytes == 0x00, errOut);
507 require_quiet(++sBytes < sEnd, errOut);
508
509 break;
510 }
511 case kSecPaddingOAEP:
512 result = errSecParam;
513 default:
514 goto errOut;
515 }
516
517 // Return the rest.
518 require_action((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut, result = errSecParam);
519
520 *plainTextLen = sEnd - sBytes;
521 memcpy(plainText, sBytes, *plainTextLen);
522
523 result = errSecSuccess;
524
525 errOut:
526 ccn_zero(ccrsa_ctx_n(pubkey), s);
527
528 return result;
529 }
530
531 static size_t SecRSAPublicKeyBlockSize(SecKeyRef key) {
532 ccrsa_pub_ctx_t pubkey;
533 pubkey.pub = key->key;
534
535 return ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
536 }
537
538
539 static CFDataRef SecRSAPublicKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_pub_ctx_t pubkey)
540 {
541 size_t m_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
542 size_t e_size = ccn_write_int_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
543
544 const size_t seq_size = DERLengthOfItem(ASN1_INTEGER, m_size) +
545 DERLengthOfItem(ASN1_INTEGER, e_size);
546
547 const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
548
549 CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
550
551 if (pkcs1 == NULL)
552 return NULL;
553
554 CFDataSetLength(pkcs1, result_size);
555
556 uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
557
558 *bytes++ = ASN1_CONSTR_SEQUENCE;
559
560 DERSize itemLength = 4;
561 DEREncodeLength(seq_size, bytes, &itemLength);
562 bytes += itemLength;
563
564 ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, &bytes);
565 ccasn_encode_int(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey), e_size, &bytes);
566
567 return pkcs1;
568 }
569
570 static OSStatus SecRSAPublicKeyCopyPublicSerialization(SecKeyRef key, CFDataRef* serialized)
571 {
572 ccrsa_pub_ctx_t pubkey;
573 pubkey.pub = key->key;
574
575 CFAllocatorRef allocator = CFGetAllocator(key);
576 *serialized = SecRSAPublicKeyCreatePKCS1(allocator, pubkey);
577
578 if (NULL == *serialized)
579 return errSecDecode;
580 else
581 return errSecSuccess;
582 }
583
584 static CFDictionaryRef SecRSAPublicKeyCopyAttributeDictionary(SecKeyRef key) {
585 return SecKeyGeneratePublicAttributeDictionary(key, kSecAttrKeyTypeRSA);
586 }
587
588 static CFStringRef SecRSAPublicKeyCopyDescription(SecKeyRef key) {
589
590 CFStringRef keyDescription = NULL;
591 CFDataRef modRef = SecKeyCopyModulus(key);
592
593 ccrsa_pub_ctx_t pubkey;
594 pubkey.pub = key->key;
595
596 CFStringRef modulusString = CFDataCopyHexString(modRef);
597 require( modulusString, fail);
598
599 keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, exponent: {hex: %llx, decimal: %lld}, modulus: %@, addr: %p>"), SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), (long long)*ccrsa_ctx_e(pubkey), (long long)*ccrsa_ctx_e(pubkey), modulusString, key);
600
601 fail:
602 CFReleaseSafe(modRef);
603 CFReleaseSafe(modulusString);
604 if(!keyDescription)
605 keyDescription = CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR("<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), (long)SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
606
607 return keyDescription;
608 }
609
610 SecKeyDescriptor kSecRSAPublicKeyDescriptor = {
611 kSecKeyDescriptorVersion,
612 "RSAPublicKey",
613 0, /* extraBytes */
614 SecRSAPublicKeyInit,
615 SecRSAPublicKeyDestroy,
616 NULL, /* SecKeyRawSignMethod */
617 SecRSAPublicKeyRawVerify,
618 SecRSAPublicKeyRawEncrypt,
619 SecRSAPublicKeyRawDecrypt,
620 NULL, /* SecKeyComputeMethod */
621 SecRSAPublicKeyBlockSize,
622 SecRSAPublicKeyCopyAttributeDictionary,
623 SecRSAPublicKeyCopyDescription,
624 NULL,
625 SecRSAPublicKeyCopyPublicSerialization,
626 NULL,
627 NULL
628 };
629
630 /* Public Key API functions. */
631 SecKeyRef SecKeyCreateRSAPublicKey(CFAllocatorRef allocator,
632 const uint8_t *keyData, CFIndex keyDataLength,
633 SecKeyEncoding encoding) {
634 return SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor, keyData,
635 keyDataLength, encoding);
636 }
637
638 CFDataRef SecKeyCopyModulus(SecKeyRef key) {
639 ccrsa_pub_ctx_t pubkey;
640 pubkey.pub = key->key;
641
642 size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey));
643
644 CFAllocatorRef allocator = CFGetAllocator(key);
645 CFMutableDataRef modulusData = CFDataCreateMutable(allocator, m_size);
646
647 if (modulusData == NULL)
648 return NULL;
649
650 CFDataSetLength(modulusData, m_size);
651
652 ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey), m_size, CFDataGetMutableBytePtr(modulusData));
653
654 return modulusData;
655 }
656
657 CFDataRef SecKeyCopyExponent(SecKeyRef key) {
658 ccrsa_pub_ctx_t pubkey;
659 pubkey.pub = key->key;
660
661 size_t e_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey));
662
663 CFAllocatorRef allocator = CFGetAllocator(key);
664 CFMutableDataRef exponentData = CFDataCreateMutable(allocator, e_size);
665
666 if (exponentData == NULL)
667 return NULL;
668
669 CFDataSetLength(exponentData, e_size);
670
671 ccn_write_uint(ccrsa_ctx_n(pubkey), ccrsa_ctx_e(pubkey), e_size, CFDataGetMutableBytePtr(exponentData));
672
673 return exponentData;
674 }
675
676
677 /*
678 *
679 * Private Key
680 *
681 */
682
683 /* Private key static functions. */
684 static void SecRSAPrivateKeyDestroy(SecKeyRef key) {
685 /* Zero out the public key */
686 if (key->key) {
687 ccrsa_full_ctx_t fullkey;
688 fullkey.full = key->key;
689 cc_clear(ccrsa_full_ctx_size(ccn_sizeof_n(ccrsa_ctx_n(fullkey))), fullkey.full);
690 free(key->key);
691 key->key = NULL;
692 }
693 }
694
695 static OSStatus SecRSAPrivateKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) {
696 OSStatus result = errSecParam;
697 ccrsa_full_ctx_t fullkey;
698 cc_size size_n = 0;
699
700 switch (encoding) {
701 case kSecKeyEncodingBytes: // Octets is PKCS1
702 case kSecKeyEncodingPkcs1:
703 {
704 const uint8_t *der_end = keyData + keyDataLength;
705 size_n = ccder_decode_rsa_priv_n(keyData, der_end);
706 require(size_n != 0, errOut);
707 require(size_n <= ccn_nof(kMaximumRSAKeyBits), errOut);
708
709 key->key = calloc(1, ccrsa_full_ctx_size(ccn_sizeof_n(size_n)));
710 require_action(key->key, errOut, result = errSecAllocate);
711
712 fullkey.full = key->key;
713 ccrsa_ctx_n(fullkey) = size_n;
714
715 require(ccder_decode_rsa_priv(fullkey, keyData, der_end), errOut);
716
717 result = errSecSuccess;
718 break;
719 }
720 case kSecGenerateKey:
721 {
722 CFDictionaryRef parameters = (CFDictionaryRef) keyData;
723
724 CFTypeRef ksize = CFDictionaryGetValue(parameters, kSecAttrKeySizeInBits);
725 CFIndex keyLengthInBits = getIntValue(ksize);
726
727 if (keyLengthInBits < 512 || keyLengthInBits > kMaximumRSAKeyBits) {
728 secwarning("Invalid or missing key size in: %@", parameters);
729 result = errSecKeySizeNotAllowed;
730 goto errOut;
731 }
732
733 size_n = ccn_nof(keyLengthInBits);
734
735 key->key = calloc(1, ccrsa_full_ctx_size(ccn_sizeof_n(size_n)));
736 require_action(key->key, errOut, result = errSecAllocate);
737
738 fullkey.full = key->key;
739 ccrsa_ctx_n(fullkey) = size_n;
740
741 /* TODO: Add support for kSecPublicExponent parameter. */
742 static uint8_t e[] = { 0x01, 0x00, 0x01 }; // Default is 65537
743 if (!ccrsa_generate_key(keyLengthInBits, fullkey.full, sizeof(e), e, ccrng_seckey))
744 result = errSecSuccess;
745 break;
746 }
747 default:
748 break;
749 }
750 errOut:
751 return result;
752 }
753
754 static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding,
755 const uint8_t *dataToSign, size_t dataToSignLen,
756 uint8_t *sig, size_t *sigLen) {
757
758 OSStatus result = errSecParam;
759
760 ccrsa_full_ctx_t fullkey;
761 fullkey.full = key->key;
762
763 size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
764 cc_unit s[ccrsa_ctx_n(fullkey)];
765
766 uint8_t* sBytes = (uint8_t*) s;
767
768 require(sigLen, errOut);
769 require(*sigLen >= m_size, errOut);
770
771 switch (padding) {
772 case kSecPaddingNone:
773 // We'll allow modulus size assuming input is smaller than modulus
774 require_quiet(dataToSignLen <= m_size, errOut);
775 require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(fullkey), s, dataToSignLen, dataToSign), errOut);
776 require_quiet(ccn_cmp(ccrsa_ctx_n(fullkey), s, ccrsa_ctx_m(fullkey)) < 0, errOut);
777 break;
778
779 case kSecPaddingPKCS1:
780 {
781 // Create PKCS1 padding:
782 //
783 // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData
784 //
785 const int kMinimumPadding = 1 + 1 + 8 + 1;
786
787 require_quiet(dataToSignLen <= m_size - kMinimumPadding, errOut);
788
789 size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(fullkey)) - m_size;
790
791 while (prefix_zeros--)
792 *sBytes++ = 0x00;
793
794 size_t pad_size = m_size - dataToSignLen;
795
796 *sBytes++ = 0x00;
797 *sBytes++ = RSA_PKCS1_PAD_SIGN;
798
799 size_t ff_size;
800 for(ff_size = pad_size - 3; ff_size > 0; --ff_size)
801 *sBytes++ = 0xFF;
802
803 *sBytes++ = 0x00;
804
805 // Get the user data into s looking like a ccn.
806 memcpy(sBytes, dataToSign, dataToSignLen);
807 ccn_swap(ccrsa_ctx_n(fullkey), s);
808
809 break;
810 }
811 case kSecPaddingOAEP:
812 result = errSecParam;
813 default:
814 goto errOut;
815 }
816
817 ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
818
819 // Pad with leading zeros to fit in modulus size
820 ccn_write_uint_padded(ccrsa_ctx_n(fullkey), s, m_size, sig);
821 *sigLen = m_size;
822
823 result = errSecSuccess;
824
825 errOut:
826 ccn_zero(ccrsa_ctx_n(fullkey), s);
827 return result;
828 }
829
830 static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding,
831 const uint8_t *cipherText, size_t cipherTextLen,
832 uint8_t *plainText, size_t *plainTextLen) {
833 OSStatus result = errSSLCrypto;
834
835 ccrsa_full_ctx_t fullkey;
836 fullkey.full = key->key;
837
838 size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
839
840 cc_unit s[ccrsa_ctx_n(fullkey)];
841 uint8_t recoveredData[ccn_sizeof_n(ccrsa_ctx_n(fullkey))];
842
843 ccn_read_uint(ccrsa_ctx_n(fullkey), s, cipherTextLen, cipherText);
844 ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s);
845
846 const uint8_t* sBytes = (uint8_t*) s;
847 const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(fullkey));
848
849 require(plainTextLen, errOut);
850
851 switch (padding) {
852 case kSecPaddingNone:
853 ccn_swap(ccrsa_ctx_n(fullkey), s);
854 // Skip Zeros since our contract is to do so.
855 while (sBytes < sEnd && *sBytes == 0x00)
856 ++sBytes;
857 break;
858
859 case kSecPaddingPKCS1:
860 {
861 ccn_swap(ccrsa_ctx_n(fullkey), s);
862 // Verify and skip PKCS1 padding:
863 //
864 // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData
865 //
866
867 size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(fullkey)) - m_size;
868
869 while (prefix_zeros--)
870 require_quiet(*sBytes++ == 0x00, errOut);
871
872 require_quiet(*sBytes++ == 0x00, errOut);
873 require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut);
874
875 while (*sBytes != 0x00) {
876 require_quiet(++sBytes < sEnd, errOut);
877 }
878 // Required to have at least 8 non-zeros
879 require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut);
880
881 require_quiet(*sBytes == 0x00, errOut);
882 require_quiet(++sBytes < sEnd, errOut);
883 break;
884 }
885 case kSecPaddingOAEP:
886 {
887 size_t length = sizeof(recoveredData);
888
889 require_noerr_quiet(ccrsa_oaep_decode(ccsha1_di(),
890 &length, recoveredData,
891 ccn_write_uint_size(ccrsa_ctx_n(fullkey),ccrsa_ctx_m(fullkey)), s
892 ), errOut);
893
894 sBytes = recoveredData;
895 sEnd = recoveredData + length;
896 break;
897 }
898 default:
899 goto errOut;
900 }
901
902 require((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut);
903 *plainTextLen = sEnd - sBytes;
904 memcpy(plainText, sBytes, *plainTextLen);
905
906 result = errSecSuccess;
907
908 errOut:
909 bzero(recoveredData, sizeof(recoveredData));
910 ccn_zero(ccrsa_ctx_n(fullkey), s);
911
912 return result;
913 }
914
915 static size_t SecRSAPrivateKeyBlockSize(SecKeyRef key) {
916 ccrsa_full_ctx_t fullkey;
917 fullkey.full = key->key;
918
919 return ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
920 }
921
922 static CFDataRef SecRSAPrivateKeyCreatePKCS1(CFAllocatorRef allocator, ccrsa_full_ctx_t fullkey)
923 {
924 ccrsa_priv_ctx_t privkey = ccrsa_ctx_private(fullkey);
925
926 const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey));
927 const cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey));
928
929 size_t m_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey));
930 size_t e_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey));
931 size_t d_size = ccn_write_int_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey));
932
933 size_t p_size = ccn_write_int_size(np, cczp_prime(ccrsa_ctx_private_zp(privkey)));
934 size_t q_size = ccn_write_int_size(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)));
935
936 size_t dp_size = ccn_write_int_size(np, ccrsa_ctx_private_dp(privkey));
937 size_t dq_size = ccn_write_int_size(nq, ccrsa_ctx_private_dq(privkey));
938
939 size_t qinv_size = ccn_write_int_size(np, ccrsa_ctx_private_qinv(privkey));
940
941 const size_t seq_size = 3 +
942 DERLengthOfItem(ASN1_INTEGER, m_size) +
943 DERLengthOfItem(ASN1_INTEGER, e_size) +
944 DERLengthOfItem(ASN1_INTEGER, d_size) +
945 DERLengthOfItem(ASN1_INTEGER, p_size) +
946 DERLengthOfItem(ASN1_INTEGER, q_size) +
947 DERLengthOfItem(ASN1_INTEGER, dp_size) +
948 DERLengthOfItem(ASN1_INTEGER, dq_size) +
949 DERLengthOfItem(ASN1_INTEGER, qinv_size);
950
951 const size_t result_size = DERLengthOfItem(ASN1_SEQUENCE, seq_size);
952
953 CFMutableDataRef pkcs1 = CFDataCreateMutable(allocator, result_size);
954
955 if (pkcs1 == NULL)
956 return NULL;
957
958 CFDataSetLength(pkcs1, result_size);
959
960 uint8_t *bytes = CFDataGetMutableBytePtr(pkcs1);
961
962 *bytes++ = ASN1_CONSTR_SEQUENCE;
963
964 DERSize itemLength = 4;
965 DEREncodeLength(seq_size, bytes, &itemLength);
966 bytes += itemLength;
967
968 *bytes++ = ASN1_INTEGER;
969 *bytes++ = 0x01;
970 *bytes++ = 0x00;
971
972 ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey), m_size, &bytes);
973 ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_e(fullkey), e_size, &bytes);
974 ccasn_encode_int(ccrsa_ctx_n(fullkey), ccrsa_ctx_d(fullkey), d_size, &bytes);
975
976 ccasn_encode_int(np, cczp_prime(ccrsa_ctx_private_zp(privkey)), p_size, &bytes);
977 ccasn_encode_int(nq, cczp_prime(ccrsa_ctx_private_zq(privkey)), q_size, &bytes);
978 ccasn_encode_int(np, ccrsa_ctx_private_dp(privkey), dp_size, &bytes);
979 ccasn_encode_int(nq, ccrsa_ctx_private_dq(privkey), dq_size, &bytes);
980 ccasn_encode_int(np, ccrsa_ctx_private_qinv(privkey), qinv_size, &bytes);
981
982 return pkcs1;
983 }
984
985 static CFDataRef SecRSAPrivateKeyCopyPKCS1(SecKeyRef key)
986 {
987 ccrsa_full_ctx_t fullkey;
988 fullkey.full = key->key;
989
990 CFAllocatorRef allocator = CFGetAllocator(key);
991 return SecRSAPrivateKeyCreatePKCS1(allocator, fullkey);
992 }
993
994 static OSStatus SecRSAPrivateKeyCopyPublicSerialization(SecKeyRef key, CFDataRef* serialized)
995 {
996 ccrsa_full_ctx_t fullkey;
997 fullkey.full = key->key;
998
999 CFAllocatorRef allocator = CFGetAllocator(key);
1000 *serialized = SecRSAPublicKeyCreatePKCS1(allocator, fullkey);
1001
1002 if (NULL == *serialized)
1003 return errSecDecode;
1004 else
1005 return errSecSuccess;
1006 }
1007
1008
1009 static CFDictionaryRef SecRSAPrivateKeyCopyAttributeDictionary(SecKeyRef key) {
1010 CFDictionaryRef dict = NULL;
1011 CFDataRef fullKeyBlob = NULL;
1012
1013 /* PKCS1 encode the key pair. */
1014 fullKeyBlob = SecRSAPrivateKeyCopyPKCS1(key);
1015 require(fullKeyBlob, errOut);
1016
1017 dict = SecKeyGeneratePrivateAttributeDictionary(key, kSecAttrKeyTypeRSA, fullKeyBlob);
1018
1019 errOut:
1020 CFReleaseSafe(fullKeyBlob);
1021
1022 return dict;
1023 }
1024
1025 static CFStringRef SecRSAPrivateKeyCopyDescription(SecKeyRef key){
1026
1027 return CFStringCreateWithFormat(kCFAllocatorDefault,NULL,CFSTR( "<SecKeyRef algorithm id: %lu, key type: %s, version: %d, block size: %zu bits, addr: %p>"), SecKeyGetAlgorithmId(key), key->key_class->name, key->key_class->version, (8*SecKeyGetBlockSize(key)), key);
1028
1029 }
1030 SecKeyDescriptor kSecRSAPrivateKeyDescriptor = {
1031 kSecKeyDescriptorVersion,
1032 "RSAPrivateKey",
1033 0, /* extraBytes */
1034 SecRSAPrivateKeyInit,
1035 SecRSAPrivateKeyDestroy,
1036 SecRSAPrivateKeyRawSign,
1037 NULL, /* SecKeyRawVerifyMethod */
1038 NULL, /* SecKeyEncryptMethod */
1039 SecRSAPrivateKeyRawDecrypt,
1040 NULL, /* SecKeyComputeMethod */
1041 SecRSAPrivateKeyBlockSize,
1042 SecRSAPrivateKeyCopyAttributeDictionary,
1043 SecRSAPrivateKeyCopyDescription,
1044 NULL,
1045 SecRSAPrivateKeyCopyPublicSerialization,
1046 NULL,
1047 NULL
1048 };
1049
1050 /* Private Key API functions. */
1051 SecKeyRef SecKeyCreateRSAPrivateKey(CFAllocatorRef allocator,
1052 const uint8_t *keyData, CFIndex keyDataLength,
1053 SecKeyEncoding encoding) {
1054 return SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor, keyData,
1055 keyDataLength, encoding);
1056 }
1057
1058
1059 OSStatus SecRSAKeyGeneratePair(CFDictionaryRef parameters,
1060 SecKeyRef *rsaPublicKey, SecKeyRef *rsaPrivateKey) {
1061 OSStatus status = errSecParam;
1062
1063 CFAllocatorRef allocator = NULL; /* @@@ get from parameters. */
1064
1065 SecKeyRef pubKey = NULL;
1066 SecKeyRef privKey = SecKeyCreate(allocator, &kSecRSAPrivateKeyDescriptor,
1067 (const void*) parameters, 0, kSecGenerateKey);
1068
1069 require(privKey, errOut);
1070
1071 /* Create SecKeyRef's from the pkcs1 encoded keys. */
1072 pubKey = SecKeyCreate(allocator, &kSecRSAPublicKeyDescriptor,
1073 privKey->key, 0, kSecExtractPublicFromPrivate);
1074
1075 require(pubKey, errOut);
1076
1077 if (rsaPublicKey) {
1078 *rsaPublicKey = pubKey;
1079 pubKey = NULL;
1080 }
1081 if (rsaPrivateKey) {
1082 *rsaPrivateKey = privKey;
1083 privKey = NULL;
1084 }
1085
1086 status = errSecSuccess;
1087
1088 errOut:
1089 CFReleaseSafe(pubKey);
1090 CFReleaseSafe(privKey);
1091
1092 return status;
1093 }