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