2  * Copyright (c) 2006-2010,2012-2015 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  * SecRSAKey.c - CoreFoundation based rsa key object 
  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. */ 
  38 #include <sys/types.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> 
  48 #include <corecrypto/ccn.h> 
  49 #include <corecrypto/ccrsa.h> 
  50 #include <corecrypto/ccsha1.h> 
  52 #include <libDER/asn1Types.h> 
  53 #include <libDER/DER_Keys.h> 
  54 #include <libDER/DER_Encode.h> 
  56 #include <CommonCrypto/CommonDigest.h> 
  58 #include <corecrypto/ccrsa_priv.h> 
  63 #define kMaximumRSAKeyBits (1024 * 8) 
  65 #define RSA_PKCS1_PAD_SIGN              0x01 
  66 #define RSA_PKCS1_PAD_ENCRYPT   0x02 
  68 static void ccn_c_dump(cc_size count
, const cc_unit 
*s
) 
  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)); 
  82 static void ccn_cprint(cc_size count
, char* prefix
, const cc_unit 
*s
) 
  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
)); 
  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
))); 
 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
)); 
 130 /* Public key static functions. */ 
 131 static void SecRSAPublicKeyDestroy(SecKeyRef key
) { 
 132     /* Zero out the public 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
); 
 142 #define cc_skip_zeros(size, ptr) { while (size > 0 && *ptr == 0) { ++ptr; --size; } } 
 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. 
 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
) 
 152     cc_skip_zeros(m_size
, m
); 
 154     cc_size nm 
= ccn_nof_size(m_size
); 
 155     if (nm 
> ccrsa_ctx_n(pubkey
)) 
 158     ccrsa_ctx_n(pubkey
) = nm
; 
 160     ccn_read_uint(nm
, ccrsa_ctx_m(pubkey
), m_size
, m
); 
 161     cczp_init(ccrsa_ctx_zm(pubkey
)); 
 163     return ccn_read_uint(nm
, ccrsa_ctx_e(pubkey
), e_size
, e
); 
 167 static OSStatus 
ccrsa_pub_decode_apple(ccrsa_pub_ctx_t pubkey
, size_t pkcs1_size
, const uint8_t* pkcs1
) 
 169     OSStatus result 
= errSecParam
; 
 171         DERItem keyItem 
= {(DERByte 
*)pkcs1
, pkcs1_size
}; 
 172     DERRSAPubKeyApple decodedKey
; 
 174         require_noerr_action(DERParseSequence(&keyItem
, 
 175                                           DERNumRSAPubKeyAppleItemSpecs
, DERRSAPubKeyAppleItemSpecs
, 
 176                                           &decodedKey
, sizeof(decodedKey
)), 
 177                          errOut
, result 
= errSecDecode
); 
 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. 
 182     require_noerr(ccrsa_pub_init(pubkey
, 
 183                                  decodedKey
.modulus
.length
, decodedKey
.modulus
.data
, 
 184                                  decodedKey
.pubExponent
.length
, decodedKey
.pubExponent
.data
), 
 187     result 
= errSecSuccess
; 
 194 static void ccasn_encode_int(cc_size n
, const cc_unit
*s
, size_t s_size
, uint8_t **buffer
) 
 196     **buffer 
= ASN1_INTEGER
; 
 199     DERSize itemLength 
= 4; 
 200     DEREncodeLength(s_size
, *buffer
, &itemLength
); 
 201     *buffer 
+= itemLength
; 
 203     ccn_write_int(n
, s
, s_size
, *buffer
); 
 209 static OSStatus 
SecRSAPublicKeyInit(SecKeyRef key
, 
 210                                     const uint8_t *keyData
, CFIndex keyDataLength
, SecKeyEncoding encoding
) { 
 212     OSStatus result 
= errSecParam
; 
 213     ccrsa_pub_ctx_t pubkey
; 
 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
); 
 224             key
->key 
= calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n
))); 
 225             require_action(key
->key
, errOut
, result 
= errSecAllocate
); 
 227             pubkey
.pub 
= key
->key
; 
 228             ccrsa_ctx_n(pubkey
) = size_n
; 
 230             require_noerr(ccrsa_import_pub(pubkey
, keyDataLength
, keyData
), errOut
); 
 232             result 
= errSecSuccess
; 
 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
); 
 240             key
->key 
= calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n
))); 
 241             require_action(key
->key
, errOut
, result 
= errSecAllocate
); 
 243             pubkey
.pub 
= key
->key
; 
 244             ccrsa_ctx_n(pubkey
) = size_n
; 
 246             result 
= ccrsa_pub_decode_apple(pubkey
, keyDataLength
, keyData
); 
 248         case kSecKeyEncodingRSAPublicParams
: 
 250             SecRSAPublicKeyParams 
*params 
= (SecRSAPublicKeyParams 
*)keyData
; 
 252             size_n 
= ccn_nof_size(params
->modulusLength
); 
 254             key
->key 
= calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n
))); 
 255             require_action(key
->key
, errOut
, result 
= errSecAllocate
); 
 257             pubkey
.pub 
= key
->key
; 
 258             ccrsa_ctx_n(pubkey
) = size_n
; 
 260             require_noerr(ccrsa_pub_init(pubkey
, 
 261                                          params
->modulusLength
, params
->modulus
, 
 262                                          params
->exponentLength
, params
->exponent
), errOut
); 
 264             result 
= errSecSuccess
; 
 267         case kSecExtractPublicFromPrivate
: 
 269             ccrsa_full_ctx_t fullKey
; 
 270             fullKey
.full 
= (ccrsa_full_ctx
*) keyData
; 
 272             size_n 
= ccrsa_ctx_n(fullKey
); 
 274             key
->key 
= calloc(1, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n
))); 
 275             require_action(key
->key
, errOut
, result 
= errSecAllocate
); 
 277             pubkey
.pub 
= key
->key
; 
 278             ccrsa_ctx_n(pubkey
) = size_n
; 
 280             memcpy(pubkey
.pub
, ccrsa_ctx_public(fullKey
).pub
, ccrsa_pub_ctx_size(ccn_sizeof_n(size_n
))); 
 281             result 
= errSecSuccess
; 
 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
; 
 297     ccrsa_pub_ctx_t pubkey
; 
 298     pubkey
.pub 
= key
->key
; 
 300     cc_unit s
[ccrsa_ctx_n(pubkey
)]; 
 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
); 
 306     const uint8_t* sBytes 
= (uint8_t*) s
; 
 307     const uint8_t* sEnd 
= (uint8_t*) (s 
+ ccrsa_ctx_n(pubkey
)); 
 310         case kSecPaddingNone
: 
 311             // Skip leading zeros as long as s is bigger than signedData. 
 312             while (((ptrdiff_t)signedDataLen 
< (sEnd 
- sBytes
)) && (*sBytes 
== 0)) 
 316         case kSecPaddingPKCS1
: 
 318             // Verify and skip PKCS1 padding: 
 320             // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData 
 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
; 
 325             while (prefix_zeros
--) 
 326                 require_quiet(*sBytes
++ == 0x00, errOut
); 
 328             require_quiet(*sBytes
++ == 0x00, errOut
); 
 329             require_quiet(*sBytes
++ == RSA_PKCS1_PAD_SIGN
, errOut
); 
 331             while (*sBytes 
== 0xFF) { 
 332                 require_quiet(++sBytes 
< sEnd
, errOut
); 
 334             // Required to have at least 8 0xFFs 
 335             require_quiet((sBytes 
- (uint8_t*)s
) - 2 >= 8, errOut
); 
 337             require_quiet(*sBytes 
== 0x00, errOut
); 
 338             require_quiet(++sBytes 
< sEnd
, errOut
); 
 341         case kSecPaddingOAEP
: 
 342             result 
= errSecParam
; 
 346             result 
= errSecUnimplemented
; 
 351     require_quiet((sEnd 
- sBytes
) == (ptrdiff_t)signedDataLen
, errOut
); 
 352     require_quiet(memcmp(sBytes
, signedData
, signedDataLen
) == 0, errOut
); 
 354     result 
= errSecSuccess
; 
 357     cc_clear(ccrsa_ctx_n(pubkey
), s
); 
 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
; 
 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
)); 
 372     require(cipherTextLen
, errOut
); 
 373     require(*cipherTextLen 
>= m_size
, errOut
); 
 375     uint8_t* sBytes 
= (uint8_t*) s
; 
 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
); 
 385         case kSecPaddingPKCS1
: 
 387             // Create PKCS1 padding: 
 389             // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData 
 391             const int kMinimumPadding 
= 1 + 1 + 8 + 1; 
 393             require_quiet(plainTextLen 
<= m_size 
- kMinimumPadding
, errOut
); 
 395             size_t prefix_zeros 
= ccn_sizeof_n(ccrsa_ctx_n(pubkey
)) - m_size
; 
 397             while (prefix_zeros
--) 
 400             size_t pad_size 
= m_size 
- plainTextLen
; 
 403             *sBytes
++ = RSA_PKCS1_PAD_ENCRYPT
; 
 405             ccrng_generate(ccrng_seckey
, pad_size 
- 3, sBytes
); 
 406             // Remove zeroes from the random pad 
 408             const uint8_t* sEndOfPad 
= sBytes 
+ (pad_size 
- 3); 
 409             while (sBytes 
< sEndOfPad
) 
 412                     *sBytes 
= 0xFF; // Michael said 0xFF was good enough. 
 419             memcpy(sBytes
, plainText
, plainTextLen
); 
 421             ccn_swap(ccrsa_ctx_n(pubkey
), s
); 
 424         case kSecPaddingOAEP
: 
 426             const struct ccdigest_info
* di 
= ccsha1_di(); 
 428             const size_t encodingOverhead 
= 2 + 2 * di
->output_size
; 
 430             require_action(m_size 
> encodingOverhead
, errOut
, result 
= errSecParam
); 
 431             require_action_quiet(plainTextLen 
<= m_size 
- encodingOverhead
, errOut
, result 
= errSecParam
); 
 433             require_noerr_action(ccrsa_oaep_encode(di
, 
 436                                                    plainTextLen
, plainText
), errOut
, result 
= errSecInternal
); 
 444     ccrsa_pub_crypt(pubkey
, s
, s
); 
 446     ccn_write_uint_padded(ccrsa_ctx_n(pubkey
), s
, m_size
, cipherText
); 
 447     *cipherTextLen 
= m_size
; 
 449     result 
= errSecSuccess
; 
 452     ccn_zero(ccrsa_ctx_n(pubkey
), s
); 
 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
; 
 460     ccrsa_pub_ctx_t pubkey
; 
 461     pubkey
.pub 
= key
->key
; 
 463     cc_unit s
[ccrsa_ctx_n(pubkey
)]; 
 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
); 
 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
); 
 473     const uint8_t* sBytes 
= (uint8_t*) s
; 
 474     const uint8_t* sEnd 
= (uint8_t*) (s 
+ ccrsa_ctx_n(pubkey
)); 
 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) 
 485         case kSecPaddingPKCS1
: 
 487             // Verify and skip PKCS1 padding: 
 489             // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData 
 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
; 
 494             while (prefix_zeros
--) 
 495                 require_quiet(*sBytes
++ == 0x00, errOut
); 
 497             require_quiet(*sBytes
++ == 0x00, errOut
); 
 498             require_quiet(*sBytes
++ == RSA_PKCS1_PAD_ENCRYPT
, errOut
); 
 500             while (*sBytes 
!= 0x00) { 
 501                 require_quiet(++sBytes 
< sEnd
, errOut
); 
 503             // Required to have at least 8 0xFFs 
 504             require_quiet((sBytes 
- (uint8_t*)s
) - 2 >= 8, errOut
); 
 506             require_quiet(*sBytes 
== 0x00, errOut
); 
 507             require_quiet(++sBytes 
< sEnd
, errOut
); 
 511         case kSecPaddingOAEP
: 
 512             result 
= errSecParam
; 
 518     require_action((sEnd 
- sBytes
) <= (ptrdiff_t)*plainTextLen
, errOut
, result 
= errSecParam
); 
 520     *plainTextLen 
= sEnd 
- sBytes
; 
 521     memcpy(plainText
, sBytes
, *plainTextLen
); 
 523     result 
= errSecSuccess
; 
 526     ccn_zero(ccrsa_ctx_n(pubkey
), s
); 
 531 static size_t SecRSAPublicKeyBlockSize(SecKeyRef key
) { 
 532     ccrsa_pub_ctx_t pubkey
; 
 533     pubkey
.pub 
= key
->key
; 
 535     return ccn_write_uint_size(ccrsa_ctx_n(pubkey
), ccrsa_ctx_m(pubkey
)); 
 539 static CFDataRef 
SecRSAPublicKeyCreatePKCS1(CFAllocatorRef allocator
, ccrsa_pub_ctx_t pubkey
) 
 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
)); 
 544     const size_t seq_size 
= DERLengthOfItem(ASN1_INTEGER
, m_size
) + 
 545     DERLengthOfItem(ASN1_INTEGER
, e_size
); 
 547     const size_t result_size 
= DERLengthOfItem(ASN1_SEQUENCE
, seq_size
); 
 549         CFMutableDataRef pkcs1 
= CFDataCreateMutable(allocator
, result_size
); 
 554         CFDataSetLength(pkcs1
, result_size
); 
 556     uint8_t *bytes 
= CFDataGetMutableBytePtr(pkcs1
); 
 558     *bytes
++ = ASN1_CONSTR_SEQUENCE
; 
 560     DERSize itemLength 
= 4; 
 561     DEREncodeLength(seq_size
, bytes
, &itemLength
); 
 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
); 
 570 static OSStatus 
SecRSAPublicKeyCopyPublicSerialization(SecKeyRef key
, CFDataRef
* serialized
) 
 572     ccrsa_pub_ctx_t pubkey
; 
 573     pubkey
.pub 
= key
->key
; 
 575         CFAllocatorRef allocator 
= CFGetAllocator(key
); 
 576     *serialized 
= SecRSAPublicKeyCreatePKCS1(allocator
, pubkey
); 
 578     if (NULL 
== *serialized
) 
 581         return errSecSuccess
; 
 584 static CFDictionaryRef 
SecRSAPublicKeyCopyAttributeDictionary(SecKeyRef key
) { 
 585     return SecKeyGeneratePublicAttributeDictionary(key
, kSecAttrKeyTypeRSA
); 
 588 static CFStringRef 
SecRSAPublicKeyCopyDescription(SecKeyRef key
) { 
 590     CFStringRef keyDescription 
= NULL
; 
 591     CFDataRef modRef 
= SecKeyCopyModulus(key
); 
 593     ccrsa_pub_ctx_t pubkey
; 
 594     pubkey
.pub 
= key
->key
; 
 596     CFStringRef modulusString 
= CFDataCopyHexString(modRef
); 
 597     require( modulusString
, fail
); 
 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
); 
 602     CFReleaseSafe(modRef
); 
 603     CFReleaseSafe(modulusString
); 
 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
); 
 607         return keyDescription
; 
 610 SecKeyDescriptor kSecRSAPublicKeyDescriptor 
= { 
 611     kSecKeyDescriptorVersion
, 
 615     SecRSAPublicKeyDestroy
, 
 616     NULL
, /* SecKeyRawSignMethod */ 
 617     SecRSAPublicKeyRawVerify
, 
 618     SecRSAPublicKeyRawEncrypt
, 
 619     SecRSAPublicKeyRawDecrypt
, 
 620     NULL
, /* SecKeyComputeMethod */ 
 621     SecRSAPublicKeyBlockSize
, 
 622         SecRSAPublicKeyCopyAttributeDictionary
, 
 623     SecRSAPublicKeyCopyDescription
, 
 625     SecRSAPublicKeyCopyPublicSerialization
, 
 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
); 
 638 CFDataRef 
SecKeyCopyModulus(SecKeyRef key
) { 
 639     ccrsa_pub_ctx_t pubkey
; 
 640     pubkey
.pub 
= key
->key
; 
 642     size_t m_size 
= ccn_write_uint_size(ccrsa_ctx_n(pubkey
), ccrsa_ctx_m(pubkey
)); 
 644         CFAllocatorRef allocator 
= CFGetAllocator(key
); 
 645         CFMutableDataRef modulusData 
= CFDataCreateMutable(allocator
, m_size
); 
 647     if (modulusData 
== NULL
) 
 650         CFDataSetLength(modulusData
, m_size
); 
 652     ccn_write_uint(ccrsa_ctx_n(pubkey
), ccrsa_ctx_m(pubkey
), m_size
, CFDataGetMutableBytePtr(modulusData
)); 
 657 CFDataRef 
SecKeyCopyExponent(SecKeyRef key
) { 
 658     ccrsa_pub_ctx_t pubkey
; 
 659     pubkey
.pub 
= key
->key
; 
 661     size_t e_size 
= ccn_write_uint_size(ccrsa_ctx_n(pubkey
), ccrsa_ctx_e(pubkey
)); 
 663         CFAllocatorRef allocator 
= CFGetAllocator(key
); 
 664         CFMutableDataRef exponentData 
= CFDataCreateMutable(allocator
, e_size
); 
 666     if (exponentData 
== NULL
) 
 669         CFDataSetLength(exponentData
, e_size
); 
 671     ccn_write_uint(ccrsa_ctx_n(pubkey
), ccrsa_ctx_e(pubkey
), e_size
, CFDataGetMutableBytePtr(exponentData
)); 
 683 /* Private key static functions. */ 
 684 static void SecRSAPrivateKeyDestroy(SecKeyRef key
) { 
 685     /* Zero out the public 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
); 
 695 static OSStatus 
SecRSAPrivateKeyInit(SecKeyRef key
, const uint8_t *keyData
, CFIndex keyDataLength
, SecKeyEncoding encoding
) { 
 696     OSStatus result 
= errSecParam
; 
 697     ccrsa_full_ctx_t fullkey
; 
 701         case kSecKeyEncodingBytes
: // Octets is PKCS1 
 702         case kSecKeyEncodingPkcs1
: 
 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
); 
 709             key
->key 
= calloc(1, ccrsa_full_ctx_size(ccn_sizeof_n(size_n
))); 
 710             require_action(key
->key
, errOut
, result 
= errSecAllocate
); 
 712             fullkey
.full 
= key
->key
; 
 713             ccrsa_ctx_n(fullkey
) = size_n
; 
 715             require(ccder_decode_rsa_priv(fullkey
, keyData
, der_end
), errOut
); 
 717             result 
= errSecSuccess
; 
 720         case kSecGenerateKey
: 
 722             CFDictionaryRef parameters 
= (CFDictionaryRef
) keyData
; 
 724             CFTypeRef ksize 
= CFDictionaryGetValue(parameters
, kSecAttrKeySizeInBits
); 
 725             CFIndex keyLengthInBits 
= getIntValue(ksize
); 
 727             if (keyLengthInBits 
< 512 || keyLengthInBits 
> kMaximumRSAKeyBits
) { 
 728                 secwarning("Invalid or missing key size in: %@", parameters
); 
 729                 result 
= errSecKeySizeNotAllowed
; 
 733             size_n 
= ccn_nof(keyLengthInBits
); 
 735             key
->key 
= calloc(1, ccrsa_full_ctx_size(ccn_sizeof_n(size_n
))); 
 736             require_action(key
->key
, errOut
, result 
= errSecAllocate
); 
 738             fullkey
.full 
= key
->key
; 
 739             ccrsa_ctx_n(fullkey
) = size_n
; 
 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
; 
 754 static OSStatus 
SecRSAPrivateKeyRawSign(SecKeyRef key
, SecPadding padding
, 
 755                                         const uint8_t *dataToSign
, size_t dataToSignLen
, 
 756                                         uint8_t *sig
, size_t *sigLen
) { 
 758     OSStatus result 
= errSecParam
; 
 760     ccrsa_full_ctx_t fullkey
; 
 761     fullkey
.full 
= key
->key
; 
 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
)]; 
 766     uint8_t* sBytes 
= (uint8_t*) s
; 
 768     require(sigLen
, errOut
); 
 769     require(*sigLen 
>= m_size
, errOut
); 
 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
); 
 779         case kSecPaddingPKCS1
: 
 781             // Create PKCS1 padding: 
 783             // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData 
 785             const int kMinimumPadding 
= 1 + 1 + 8 + 1; 
 787             require_quiet(dataToSignLen 
<= m_size 
- kMinimumPadding
, errOut
); 
 789             size_t prefix_zeros 
= ccn_sizeof_n(ccrsa_ctx_n(fullkey
)) - m_size
; 
 791             while (prefix_zeros
--) 
 794             size_t pad_size 
= m_size 
- dataToSignLen
; 
 797             *sBytes
++ = RSA_PKCS1_PAD_SIGN
; 
 800             for(ff_size 
= pad_size 
- 3; ff_size 
> 0; --ff_size
) 
 805             // Get the user data into s looking like a ccn. 
 806             memcpy(sBytes
, dataToSign
, dataToSignLen
); 
 807             ccn_swap(ccrsa_ctx_n(fullkey
), s
); 
 811         case kSecPaddingOAEP
: 
 812             result 
= errSecParam
; 
 817     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey
), s
, s
); 
 819     // Pad with leading zeros to fit in modulus size 
 820     ccn_write_uint_padded(ccrsa_ctx_n(fullkey
), s
, m_size
, sig
); 
 823     result 
= errSecSuccess
; 
 826     ccn_zero(ccrsa_ctx_n(fullkey
), s
); 
 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
; 
 835     ccrsa_full_ctx_t fullkey
; 
 836     fullkey
.full 
= key
->key
; 
 838     size_t m_size 
= ccn_write_uint_size(ccrsa_ctx_n(fullkey
), ccrsa_ctx_m(fullkey
)); 
 840     cc_unit s
[ccrsa_ctx_n(fullkey
)]; 
 841     uint8_t recoveredData
[ccn_sizeof_n(ccrsa_ctx_n(fullkey
))]; 
 843     ccn_read_uint(ccrsa_ctx_n(fullkey
), s
, cipherTextLen
, cipherText
); 
 844     ccrsa_priv_crypt(ccrsa_ctx_private(fullkey
), s
, s
); 
 846     const uint8_t* sBytes 
= (uint8_t*) s
; 
 847     const uint8_t* sEnd 
= (uint8_t*) (s 
+ ccrsa_ctx_n(fullkey
)); 
 849     require(plainTextLen
, errOut
); 
 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) 
 859         case kSecPaddingPKCS1
: 
 861             ccn_swap(ccrsa_ctx_n(fullkey
), s
); 
 862             // Verify and skip PKCS1 padding: 
 864             // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData 
 867             size_t prefix_zeros 
= ccn_sizeof_n(ccrsa_ctx_n(fullkey
)) - m_size
; 
 869             while (prefix_zeros
--) 
 870                 require_quiet(*sBytes
++ == 0x00, errOut
); 
 872             require_quiet(*sBytes
++ == 0x00, errOut
); 
 873             require_quiet(*sBytes
++ == RSA_PKCS1_PAD_ENCRYPT
, errOut
); 
 875             while (*sBytes 
!= 0x00) { 
 876                 require_quiet(++sBytes 
< sEnd
, errOut
); 
 878             // Required to have at least 8 non-zeros 
 879             require_quiet((sBytes 
- (uint8_t*)s
) - 2 >= 8, errOut
); 
 881             require_quiet(*sBytes 
== 0x00, errOut
); 
 882             require_quiet(++sBytes 
< sEnd
, errOut
); 
 885         case kSecPaddingOAEP
: 
 887             size_t length 
= sizeof(recoveredData
); 
 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
 
 894             sBytes 
= recoveredData
; 
 895             sEnd 
= recoveredData 
+ length
; 
 902     require((sEnd 
- sBytes
) <= (ptrdiff_t)*plainTextLen
, errOut
); 
 903     *plainTextLen 
= sEnd 
- sBytes
; 
 904     memcpy(plainText
, sBytes
, *plainTextLen
); 
 906     result 
= errSecSuccess
; 
 909     bzero(recoveredData
, sizeof(recoveredData
)); 
 910     ccn_zero(ccrsa_ctx_n(fullkey
), s
); 
 915 static size_t SecRSAPrivateKeyBlockSize(SecKeyRef key
) { 
 916     ccrsa_full_ctx_t fullkey
; 
 917     fullkey
.full 
= key
->key
; 
 919     return ccn_write_uint_size(ccrsa_ctx_n(fullkey
), ccrsa_ctx_m(fullkey
)); 
 922 static CFDataRef 
SecRSAPrivateKeyCreatePKCS1(CFAllocatorRef allocator
, ccrsa_full_ctx_t fullkey
) 
 924     ccrsa_priv_ctx_t privkey 
= ccrsa_ctx_private(fullkey
); 
 926     const cc_size np 
= cczp_n(ccrsa_ctx_private_zp(privkey
)); 
 927     const cc_size nq 
= cczp_n(ccrsa_ctx_private_zq(privkey
)); 
 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
)); 
 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
))); 
 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
)); 
 939     size_t qinv_size 
= ccn_write_int_size(np
, ccrsa_ctx_private_qinv(privkey
)); 
 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
); 
 951     const size_t result_size 
= DERLengthOfItem(ASN1_SEQUENCE
, seq_size
); 
 953         CFMutableDataRef pkcs1 
= CFDataCreateMutable(allocator
, result_size
); 
 958         CFDataSetLength(pkcs1
, result_size
); 
 960     uint8_t *bytes 
= CFDataGetMutableBytePtr(pkcs1
); 
 962     *bytes
++ = ASN1_CONSTR_SEQUENCE
; 
 964     DERSize itemLength 
= 4; 
 965     DEREncodeLength(seq_size
, bytes
, &itemLength
); 
 968     *bytes
++ = ASN1_INTEGER
; 
 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
); 
 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
); 
 985 static CFDataRef 
SecRSAPrivateKeyCopyPKCS1(SecKeyRef key
) 
 987     ccrsa_full_ctx_t fullkey
; 
 988     fullkey
.full 
= key
->key
; 
 990         CFAllocatorRef allocator 
= CFGetAllocator(key
); 
 991     return SecRSAPrivateKeyCreatePKCS1(allocator
, fullkey
); 
 994 static OSStatus 
SecRSAPrivateKeyCopyPublicSerialization(SecKeyRef key
, CFDataRef
* serialized
) 
 996     ccrsa_full_ctx_t fullkey
; 
 997     fullkey
.full 
= key
->key
; 
 999         CFAllocatorRef allocator 
= CFGetAllocator(key
); 
1000     *serialized 
= SecRSAPublicKeyCreatePKCS1(allocator
, fullkey
); 
1002     if (NULL 
== *serialized
) 
1003         return errSecDecode
; 
1005         return errSecSuccess
; 
1009 static CFDictionaryRef 
SecRSAPrivateKeyCopyAttributeDictionary(SecKeyRef key
) { 
1010         CFDictionaryRef dict 
= NULL
; 
1011         CFDataRef fullKeyBlob 
= NULL
; 
1013         /* PKCS1 encode the key pair. */ 
1014         fullKeyBlob 
= SecRSAPrivateKeyCopyPKCS1(key
); 
1015     require(fullKeyBlob
, errOut
); 
1017         dict 
= SecKeyGeneratePrivateAttributeDictionary(key
, kSecAttrKeyTypeRSA
, fullKeyBlob
); 
1020         CFReleaseSafe(fullKeyBlob
); 
1025 static CFStringRef 
SecRSAPrivateKeyCopyDescription(SecKeyRef key
){ 
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
); 
1030 SecKeyDescriptor kSecRSAPrivateKeyDescriptor 
= { 
1031     kSecKeyDescriptorVersion
, 
1034     SecRSAPrivateKeyInit
, 
1035     SecRSAPrivateKeyDestroy
, 
1036     SecRSAPrivateKeyRawSign
, 
1037     NULL
, /* SecKeyRawVerifyMethod */ 
1038     NULL
, /* SecKeyEncryptMethod */ 
1039     SecRSAPrivateKeyRawDecrypt
, 
1040     NULL
, /* SecKeyComputeMethod */ 
1041     SecRSAPrivateKeyBlockSize
, 
1042         SecRSAPrivateKeyCopyAttributeDictionary
, 
1043     SecRSAPrivateKeyCopyDescription
, 
1045     SecRSAPrivateKeyCopyPublicSerialization
, 
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
); 
1059 OSStatus 
SecRSAKeyGeneratePair(CFDictionaryRef parameters
, 
1060                                SecKeyRef 
*rsaPublicKey
, SecKeyRef 
*rsaPrivateKey
) { 
1061     OSStatus status 
= errSecParam
; 
1063     CFAllocatorRef allocator 
= NULL
; /* @@@ get from parameters. */ 
1065     SecKeyRef pubKey 
= NULL
; 
1066     SecKeyRef privKey 
= SecKeyCreate(allocator
, &kSecRSAPrivateKeyDescriptor
, 
1067                                      (const void*) parameters
, 0, kSecGenerateKey
); 
1069     require(privKey
, errOut
); 
1071         /* Create SecKeyRef's from the pkcs1 encoded keys. */ 
1072     pubKey 
= SecKeyCreate(allocator
, &kSecRSAPublicKeyDescriptor
, 
1073                           privKey
->key
, 0, kSecExtractPublicFromPrivate
); 
1075     require(pubKey
, errOut
); 
1078         *rsaPublicKey 
= pubKey
; 
1081     if (rsaPrivateKey
) { 
1082         *rsaPrivateKey 
= privKey
; 
1086     status 
= errSecSuccess
; 
1089     CFReleaseSafe(pubKey
); 
1090     CFReleaseSafe(privKey
);