1/* 2 * Copyright (c) 2012 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24// #define COMMON_RSA_FUNCTIONS 25#include "CommonRSACryptor.h" 26#include "CommonDigest.h" 27#include "CommonDigestSPI.h" 28#include "CommonDigestPriv.h" 29 30#include "CommonRandomSPI.h" 31#include <corecrypto/ccrsa.h> 32#include <corecrypto/ccrsa_priv.h> 33#include <corecrypto/ccasn1.h> 34 35#if 0 36#include "asn1Types.h" 37#include "DER_Keys.h" 38#include "DER_Encode.h" 39#endif 40 41 42#include "ccErrors.h" 43#include "ccMemory.h" 44#include "ccdebug.h" 45#include <AssertMacros.h> 46 47#pragma mark internal 48 49#define kCCMaximumRSAKeyBits 4096 50#define kCCMaximumRSAKeyBytes ccn_sizeof(kCCMaximumRSAKeyBits) 51#define kCCRSAKeyContextSize ccrsa_full_ctx_size(kCCMaximumRSAKeyBytes) 52#define RSA_PKCS1_PAD_ENCRYPT 0x02 53 54 55typedef struct _CCRSACryptor { 56 ccrsa_full_ctx_decl(kCCMaximumRSAKeyBits, fk); 57 size_t keySize; 58 CCRSAKeyType keyType; 59} CCRSACryptor; 60 61static CCRSACryptor * 62ccMallocRSACryptor(size_t nbits, CCRSAKeyType keyType) 63{ 64 CCRSACryptor *retval; 65 cc_size n = ccn_nof(nbits); 66 if((retval = CC_XMALLOC(sizeof(CCRSACryptor))) == NULL) return NULL; 67 retval->keySize = nbits; 68 ccrsa_ctx_n(retval->fk) = n; 69 return retval; 70} 71 72static void 73ccRSACryptorClear(CCRSACryptorRef theKey) 74{ 75 CCRSACryptor *key = (CCRSACryptor *) theKey; 76 if(!key) return; 77 CC_XZEROMEM(key, sizeof(CCRSACryptor)); 78 CC_XFREE(key, sizeof(CCRSACryptor)); 79} 80 81static inline size_t 82ccRSAkeysize(CCRSACryptor *cryptor) { 83 return ccn_bitlen(ccrsa_ctx_n(cryptor->fk), ccrsa_ctx_m(cryptor->fk)); 84} 85 86/* 87 88 This is done for FIPS. Basically we make sure that the two keys will work to encrypt/decrypt 89 each other's data. This will test up to 4K bit keys. 90 91*/ 92 93#define MAXKEYTEST 512 94 95static bool 96ccRSApairwiseConsistencyCheck(CCRSACryptorRef privateKey, CCRSACryptorRef publicKey) 97{ 98 CCCryptorStatus status = kCCSuccess; 99 size_t theDataLen = MAXKEYTEST, resultLen, recoveryLen; 100 uint8_t theData[MAXKEYTEST]; 101 uint8_t theResult[MAXKEYTEST]; 102 uint8_t theRecovered[MAXKEYTEST]; 103 104 /* 105 106 the RSA keysize had better be equal - we convert keysizes to bytes since we need to 107 work with the appropriate size data buffers for tests. 108 109 */ 110 111 theDataLen = CCRSAGetKeySize(privateKey) / 8; 112 if(theDataLen > MAXKEYTEST || theDataLen != (size_t) (CCRSAGetKeySize(publicKey) / 8)) { 113 return false; 114 } 115 116 /* Fill the input buffer for the test */ 117 118 CC_XMEMSET(theData, 0x0a, theDataLen); 119 120 /* Encrypt the buffer with the private key then be sure the output isn't the same as the input */ 121 resultLen = theDataLen; 122 status = CCRSACryptorCrypt(privateKey, theData, theDataLen, theResult, &resultLen); 123 124 if (kCCSuccess != status) { 125 return false; 126 } 127 128 if(CC_XMEMCMP(theData, theResult, theDataLen) == 0) { 129 return false; 130 } 131 132 /* Decrypt the buffer with the public key and be sure the output matches the original input */ 133 134 recoveryLen = theDataLen; 135 status = CCRSACryptorCrypt(publicKey, theResult, resultLen, theRecovered, &recoveryLen); 136 137 if (kCCSuccess != status) { 138 return false; 139 } 140 141 if(recoveryLen != theDataLen) { 142 return false; 143 } 144 145 if(CC_XMEMCMP(theData, theRecovered, theDataLen) != 0) { 146 return false; 147 } 148 149 /* Cleanup and leave */ 150 151 CC_XZEROMEM(theData, MAXKEYTEST); 152 CC_XZEROMEM(theResult, MAXKEYTEST); 153 CC_XZEROMEM(theRecovered, MAXKEYTEST); 154 155 return true; 156} 157 158 159#pragma mark APIDone 160 161CCCryptorStatus 162CCRSACryptorGeneratePair(size_t keysize, uint32_t e, CCRSACryptorRef *publicKey, CCRSACryptorRef *privateKey) 163{ 164 CCCryptorStatus retval; 165 CCRSACryptor *privateCryptor = NULL; 166 CCRSACryptor *publicCryptor = NULL; 167 struct ccrng_state *theRng1 = ccDRBGGetRngState(); 168 struct ccrng_state *theRng2 = ccDevRandomGetRngState(); 169 170 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 171 // ccrsa_generate_key() requires the exponent as length / pointer to bytes 172 cc_unit cc_unit_e = (cc_unit) e; 173 174 size_t eSize = ccn_write_int_size(1, &cc_unit_e); 175 uint8_t eBytes[eSize]; 176 ccn_write_int(1, &cc_unit_e, eSize, eBytes); 177 178 *publicKey = *privateKey = NULL; 179 180 __Require_Action((privateCryptor = ccMallocRSACryptor(keysize, ccRSAKeyPrivate)) != NULL, errOut, retval = kCCMemoryFailure); 181 182 // __Require_Action((ccrsa_generate_key(keysize, privateCryptor->rsaKey.full, sizeof(e), &e, theRng) == 0), errOut, retval = kCCDecodeError); 183 __Require_Action((ccrsa_generate_931_key(keysize, privateCryptor->fk, eSize, eBytes, theRng1, theRng2) == 0), errOut, retval = kCCDecodeError); 184 185 privateCryptor->keyType = ccRSAKeyPrivate; 186 187 __Require_Action((publicCryptor = CCRSACryptorGetPublicKeyFromPrivateKey(privateCryptor)) != NULL, errOut, retval = kCCMemoryFailure); 188 189 *publicKey = publicCryptor; 190 *privateKey = privateCryptor; 191 192 __Require_Action(ccRSApairwiseConsistencyCheck(*privateKey, *publicKey) == true, errOut, retval = kCCDecodeError); 193 194 return kCCSuccess; 195 196errOut: 197 if(privateCryptor) ccRSACryptorClear(privateCryptor); 198 if(publicCryptor) ccRSACryptorClear(publicCryptor); 199 *publicKey = *privateKey = NULL; 200 return retval; 201} 202 203CCRSACryptorRef CCRSACryptorGetPublicKeyFromPrivateKey(CCRSACryptorRef privateCryptorRef) 204{ 205 CCRSACryptor *publicCryptor = NULL, *privateCryptor = privateCryptorRef; 206 207 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 208 if((publicCryptor = ccMallocRSACryptor(privateCryptor->keySize, ccRSAKeyPublic)) == NULL) return NULL; 209 ccrsa_init_pub(ccrsa_ctx_public(publicCryptor->fk), ccrsa_ctx_m(privateCryptor->fk), ccrsa_ctx_e(privateCryptor->fk)); 210 publicCryptor->keyType = ccRSAKeyPublic; 211 return publicCryptor; 212} 213 214CCRSAKeyType CCRSAGetKeyType(CCRSACryptorRef key) 215{ 216 CCRSACryptor *cryptor = key; 217 CCRSAKeyType retval; 218 219 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 220 if(key == NULL) return ccRSABadKey; 221 retval = cryptor->keyType; 222 if(retval != ccRSAKeyPublic && retval != ccRSAKeyPrivate) return ccRSABadKey; 223 return retval; 224} 225 226int CCRSAGetKeySize(CCRSACryptorRef key) 227{ 228 CCRSACryptor *cryptor = key; 229 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 230 if(key == NULL) return kCCParamError; 231 232 return (int) cryptor->keySize; 233} 234 235void 236CCRSACryptorRelease(CCRSACryptorRef key) 237{ 238 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 239 ccRSACryptorClear(key); 240} 241 242 243CCCryptorStatus CCRSACryptorImport(const void *keyPackage, size_t keyPackageLen, CCRSACryptorRef *key) 244{ 245 CCRSACryptor *cryptor = NULL; 246 CCCryptorStatus retval; 247 CCRSAKeyType keyToMake; 248 cc_size keyN; 249 250 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 251 if(!keyPackage || !key) return kCCParamError; 252 if((keyN = ccrsa_import_priv_n(keyPackageLen, keyPackage)) != 0) keyToMake = ccRSAKeyPrivate; 253 else if((keyN = ccrsa_import_pub_n(keyPackageLen, keyPackage)) != 0) keyToMake = ccRSAKeyPublic; 254 else return kCCDecodeError; 255 256 __Require_Action((cryptor = ccMallocRSACryptor(kCCMaximumRSAKeyBits, keyToMake)) != NULL, errOut, retval = kCCMemoryFailure); 257 258 switch(keyToMake) { 259 case ccRSAKeyPublic: 260 ccrsa_ctx_n(ccrsa_ctx_public(cryptor->fk)) = keyN; 261 if(ccrsa_import_pub(ccrsa_ctx_public(cryptor->fk), keyPackageLen, keyPackage)) { 262 ccRSACryptorClear(cryptor); 263 return kCCDecodeError; 264 } 265 break; 266 case ccRSAKeyPrivate: 267 ccrsa_ctx_n(cryptor->fk) = keyN; 268 if(ccrsa_import_priv(cryptor->fk, keyPackageLen, keyPackage)) { 269 ccRSACryptorClear(cryptor); 270 return kCCDecodeError; 271 } 272 break; 273 } 274 cryptor->keyType = keyToMake; 275 *key = cryptor; 276 cryptor->keySize = ccRSAkeysize(cryptor); 277 278 return kCCSuccess; 279 280errOut: 281 if(cryptor) ccRSACryptorClear(cryptor); 282 *key = NULL; 283 return retval; 284} 285 286 287CCCryptorStatus CCRSACryptorExport(CCRSACryptorRef cryptor, void *out, size_t *outLen) 288{ 289 CCCryptorStatus retval = kCCSuccess; 290 size_t bufsiz; 291 292 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 293 if(!cryptor || !out) return kCCParamError; 294 switch(cryptor->keyType) { 295 case ccRSAKeyPublic: 296 bufsiz = ccrsa_export_pub_size(ccrsa_ctx_public(cryptor->fk)); 297 if(*outLen <= bufsiz) { 298 *outLen = bufsiz; 299 return kCCBufferTooSmall; 300 } 301 *outLen = bufsiz; 302 if(ccrsa_export_pub(ccrsa_ctx_public(cryptor->fk), bufsiz, out)) 303 return kCCDecodeError; 304 break; 305 case ccRSAKeyPrivate: 306 bufsiz = ccrsa_export_priv_size(cryptor->fk); 307 if(*outLen < bufsiz) { 308 *outLen = bufsiz; 309 return kCCBufferTooSmall; 310 } 311 *outLen = bufsiz; 312 if(ccrsa_export_priv(cryptor->fk, bufsiz, out)) 313 return kCCDecodeError; 314 break; 315 default: 316 retval = kCCParamError; 317 } 318 return retval; 319} 320 321 322 323 324 325 326 327CCCryptorStatus 328CCRSACryptorEncrypt(CCRSACryptorRef publicKey, CCAsymmetricPadding padding, const void *plainText, size_t plainTextLen, void *cipherText, size_t *cipherTextLen, 329 const void *tagData, size_t tagDataLen, CCDigestAlgorithm digestType) 330{ 331 CCCryptorStatus retval = kCCSuccess; 332 333 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 334 if(!publicKey || !cipherText || !plainText || !cipherTextLen) return kCCParamError; 335 336 switch(padding) { 337 case ccPKCS1Padding: 338 if(ccrsa_encrypt_eme_pkcs1v15(ccrsa_ctx_public(publicKey->fk), ccDRBGGetRngState(), cipherTextLen, cipherText, plainTextLen, (uint8_t *) plainText) != 0) 339 retval = kCCDecodeError; 340 break; 341 case ccOAEPPadding: 342 if(ccrsa_encrypt_oaep(ccrsa_ctx_public(publicKey->fk), CCDigestGetDigestInfo(digestType), ccDRBGGetRngState(), cipherTextLen, cipherText, plainTextLen, (uint8_t *) plainText, tagDataLen, tagData) != 0) 343 retval = kCCDecodeError; 344 break; 345 default: 346 retval = kCCParamError; 347 goto errOut; 348 349 } 350 351errOut: 352 return retval; 353} 354 355 356 357CCCryptorStatus 358CCRSACryptorDecrypt(CCRSACryptorRef privateKey, CCAsymmetricPadding padding, const void *cipherText, size_t cipherTextLen, 359 void *plainText, size_t *plainTextLen, const void *tagData, size_t tagDataLen, CCDigestAlgorithm digestType) 360{ 361 CCCryptorStatus retval = kCCSuccess; 362 363 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 364 if(!privateKey || !cipherText || !plainText || !plainTextLen) return kCCParamError; 365 366 switch (padding) { 367 case ccPKCS1Padding: 368 if(ccrsa_decrypt_eme_pkcs1v15(privateKey->fk, plainTextLen, plainText, cipherTextLen, (uint8_t *) cipherText) != 0) 369 retval = kCCDecodeError; 370 break; 371 case ccOAEPPadding: 372 if(ccrsa_decrypt_oaep(privateKey->fk, CCDigestGetDigestInfo(digestType), plainTextLen, plainText, cipherTextLen, (uint8_t *) cipherText, 373 tagDataLen, tagData) != 0) 374 retval = kCCDecodeError; 375 break; 376 default: 377 goto errOut; 378 } 379 380errOut: 381 382 return retval; 383} 384 385CCCryptorStatus 386CCRSACryptorCrypt(CCRSACryptorRef rsaKey, const void *in, size_t inLen, void *out, size_t *outLen) 387{ 388 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 389 if(!rsaKey || !in || !out || !outLen) return kCCParamError; 390 391 size_t keysizeBytes = (rsaKey->keySize+7)/8; 392 393 if(inLen != keysizeBytes || *outLen < keysizeBytes) return kCCMemoryFailure; 394 395 cc_size n = ccrsa_ctx_n(rsaKey->fk); 396 cc_unit buf[n]; 397 ccn_read_uint(n, buf, inLen, in); 398 399 switch(rsaKey->keyType) { 400 case ccRSAKeyPublic: 401 ccrsa_pub_crypt(ccrsa_ctx_public(rsaKey->fk), buf, buf); 402 break; 403 case ccRSAKeyPrivate: 404 ccrsa_priv_crypt(ccrsa_ctx_private(rsaKey->fk), buf, buf); 405 break; 406 default: 407 return kCCParamError; 408 } 409 410 *outLen = keysizeBytes; 411 ccn_write_uint_padded(n, buf, *outLen, out); 412 return kCCSuccess; 413} 414 415 416#if 0 417static inline int cczp_read_uint(cczp_t r, size_t data_size, const uint8_t *data) 418{ 419 if(ccn_read_uint(ccn_nof_size(data_size), CCZP_PRIME(r), data_size, data) != 0) return -1; 420 CCZP_N(r) = ccn_nof_size(data_size); 421 cczp_init(r); 422 return 0; 423} 424#endif 425 426static inline 427CCCryptorStatus ccn_write_arg(size_t n, const cc_unit *source, uint8_t *dest, size_t *destLen) 428{ 429 size_t len; 430 if((len = ccn_write_uint_size(n, source)) > *destLen) { 431 return kCCMemoryFailure; 432 } 433 *destLen = len; 434 ccn_write_uint(n, source, *destLen, dest); 435 return kCCSuccess; 436} 437 438 439CCCryptorStatus 440CCRSACryptorCreatePairFromData(uint32_t e, 441 uint8_t *xp1, size_t xp1Length, 442 uint8_t *xp2, size_t xp2Length, 443 uint8_t *xp, size_t xpLength, 444 uint8_t *xq1, size_t xq1Length, 445 uint8_t *xq2, size_t xq2Length, 446 uint8_t *xq, size_t xqLength, 447 CCRSACryptorRef *publicKey, CCRSACryptorRef *privateKey, 448 uint8_t *retp, size_t *retpLength, 449 uint8_t *retq, size_t *retqLength, 450 uint8_t *retm, size_t *retmLength, 451 uint8_t *retd, size_t *retdLength) 452{ 453 CCCryptorStatus retval; 454 CCRSACryptor *privateCryptor = NULL; 455 CCRSACryptor *publicCryptor = NULL; 456 cc_unit x_p1[ccn_nof_size(xp1Length)]; 457 cc_unit x_p2[ccn_nof_size(xp2Length)]; 458 cc_unit x_p[ccn_nof_size(xpLength)]; 459 cc_unit x_q1[ccn_nof_size(xq1Length)]; 460 cc_unit x_q2[ccn_nof_size(xq2Length)]; 461 cc_unit x_q[ccn_nof_size(xqLength)]; 462 cc_unit e_value[1]; 463 size_t nbits = xpLength * 8 + xqLength * 8; // or we'll add this as a parameter. This appears to be correct for FIPS 464 cc_size n = ccn_nof(nbits); 465 cc_unit p[n], q[n], m[n], d[n]; 466 cc_size np, nq, nm, nd; 467 468 np = nq = nm = nd = n; 469 470 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 471 e_value[0] = (cc_unit) e; 472 473 __Require_Action((privateCryptor = ccMallocRSACryptor(nbits, ccRSAKeyPrivate)) != NULL, errOut, retval = kCCMemoryFailure); 474 475 __Require_Action(ccn_read_uint(ccn_nof_size(xp1Length), x_p1, xp1Length, xp1) == 0, errOut, retval = kCCParamError); 476 __Require_Action(ccn_read_uint(ccn_nof_size(xp2Length), x_p2, xp2Length, xp2)== 0, errOut, retval = kCCParamError); 477 __Require_Action(ccn_read_uint(ccn_nof_size(xpLength), x_p, xpLength, xp) == 0, errOut, retval = kCCParamError); 478 __Require_Action(ccn_read_uint(ccn_nof_size(xq1Length), x_q1, xq1Length, xq1) == 0, errOut, retval = kCCParamError); 479 __Require_Action(ccn_read_uint(ccn_nof_size(xq2Length), x_q2, xq2Length, xq2) == 0, errOut, retval = kCCParamError); 480 __Require_Action(ccn_read_uint(ccn_nof_size(xqLength), x_q, xqLength, xq) == 0, errOut, retval = kCCParamError); 481 482 __Require_Action(ccrsa_make_931_key(nbits, 1, e_value, 483 ccn_nof_size(xp1Length), x_p1, ccn_nof_size(xp2Length), x_p2, ccn_nof_size(xpLength), x_p, 484 ccn_nof_size(xq1Length), x_q1, ccn_nof_size(xq2Length), x_q2, ccn_nof_size(xqLength), x_q, 485 privateCryptor->fk, 486 &np, p, 487 &nq, q, 488 &nm, m, 489 &nd, d) == 0, errOut, retval = kCCDecodeError); 490 491 privateCryptor->keyType = ccRSAKeyPrivate; 492 493 __Require_Action((publicCryptor = CCRSACryptorGetPublicKeyFromPrivateKey(privateCryptor)) != NULL, errOut, retval = kCCMemoryFailure); 494 495 *publicKey = publicCryptor; 496 *privateKey = privateCryptor; 497 ccn_write_arg(np, p, retp, retpLength); 498 ccn_write_arg(nq, q, retq, retqLength); 499 ccn_write_arg(nm, m, retm, retmLength); 500 ccn_write_arg(nd, d, retd, retdLength); 501 502 return kCCSuccess; 503 504errOut: 505 if(privateCryptor) ccRSACryptorClear(privateCryptor); 506 if(publicCryptor) ccRSACryptorClear(publicCryptor); 507 // CLEAR the bits 508 *publicKey = *privateKey = NULL; 509 return retval; 510 511} 512 513 514 515CCCryptorStatus 516CCRSACryptorCreateFromData( CCRSAKeyType keyType, uint8_t *modulus, size_t modulusLength, 517 uint8_t *exponent, size_t exponentLength, 518 uint8_t *p, size_t pLength, uint8_t *q, size_t qLength, 519 CCRSACryptorRef *ref) 520{ 521 CCCryptorStatus retval = kCCSuccess; 522 CCRSACryptor *rsaKey = NULL; 523 size_t n = ccn_nof_size(modulusLength); 524 cc_unit m[n]; 525 526 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 527 __Require_Action(ccn_read_uint(n, m, modulusLength, modulus) == 0, errOut, retval = kCCParamError); 528 size_t nbits = ccn_bitlen(n, m); 529 530 __Require_Action((rsaKey = ccMallocRSACryptor(nbits, keyType)) != NULL, errOut, retval = kCCMemoryFailure); 531 532 __Require_Action(ccn_read_uint(n, ccrsa_ctx_m(rsaKey->fk), modulusLength, modulus) == 0, errOut, retval = kCCParamError); 533 __Require_Action(ccn_read_uint(n, ccrsa_ctx_e(rsaKey->fk), exponentLength, exponent) == 0, errOut, retval = kCCParamError); 534 cczp_init(ccrsa_ctx_zm(rsaKey->fk)); 535 rsaKey->keySize = ccn_bitlen(n, ccrsa_ctx_m(rsaKey->fk)); 536 537 switch(keyType) { 538 case ccRSAKeyPublic: 539 rsaKey->keyType = ccRSAKeyPublic; 540 break; 541 542 case ccRSAKeyPrivate: { 543 ccrsa_priv_ctx_t privk = ccrsa_ctx_private(rsaKey->fk); 544 size_t psize = ccn_nof_size(pLength); 545 size_t qsize = ccn_nof_size(qLength); 546 547 548 CCZP_N(ccrsa_ctx_private_zp(privk)) = psize; 549 __Require_Action(ccn_read_uint(psize, CCZP_PRIME(ccrsa_ctx_private_zp(privk)), pLength, p) == 0, errOut, retval = kCCParamError); 550 CCZP_N(ccrsa_ctx_private_zq(privk)) = qsize; 551 __Require_Action(ccn_read_uint(qsize, CCZP_PRIME(ccrsa_ctx_private_zq(privk)), qLength, q) == 0, errOut, retval = kCCParamError); 552 553 ccrsa_crt_makekey(ccrsa_ctx_zm(rsaKey->fk), ccrsa_ctx_e(rsaKey->fk), ccrsa_ctx_d(rsaKey->fk), 554 ccrsa_ctx_private_zp(privk), 555 ccrsa_ctx_private_dp(privk), ccrsa_ctx_private_qinv(privk), 556 ccrsa_ctx_private_zq(privk), ccrsa_ctx_private_dq(privk)); 557 558 rsaKey->keyType = ccRSAKeyPrivate; 559 560 break; 561 } 562 563 default: 564 retval = kCCParamError; 565 goto errOut; 566 } 567 *ref = rsaKey; 568 return kCCSuccess; 569 570errOut: 571 if(rsaKey) ccRSACryptorClear(rsaKey); 572 return retval; 573} 574 575 576 577 578CCCryptorStatus 579CCRSAGetKeyComponents(CCRSACryptorRef rsaKey, uint8_t *modulus, size_t *modulusLength, uint8_t *exponent, size_t *exponentLength, 580 uint8_t *p, size_t *pLength, uint8_t *q, size_t *qLength) 581{ 582 CCRSACryptor *rsa = rsaKey; 583 584 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 585 switch(rsa->keyType) { 586 case ccRSAKeyPublic: { 587 if(ccrsa_get_pubkey_components(ccrsa_ctx_public(rsaKey->fk), modulus, modulusLength, exponent, exponentLength)) return kCCParamError; 588 break; 589 } 590 591 case ccRSAKeyPrivate: { 592 if(ccrsa_get_fullkey_components(rsaKey->fk, modulus, modulusLength, exponent, exponentLength, 593 p, pLength, q, qLength)) return kCCParamError; 594 break; 595 } 596 597 default: 598 return kCCParamError; 599 } 600 601 return kCCSuccess; 602} 603 604 605CCCryptorStatus 606CCRSACryptorSign(CCRSACryptorRef privateKey, CCAsymmetricPadding padding, 607 const void *hashToSign, size_t hashSignLen, 608 CCDigestAlgorithm digestType, size_t saltLen, 609 void *signedData, size_t *signedDataLen) 610{ 611 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 612 if(!privateKey || !hashToSign || !signedData) return kCCParamError; 613 614 switch(padding) { 615 case ccPKCS1Padding: 616 if(ccrsa_sign_pkcs1v15(privateKey->fk, CCDigestGetDigestInfo(digestType)->oid, 617 hashSignLen, hashToSign, signedDataLen, signedData) != 0) 618 return kCCDecodeError; 619 break; 620 621 case ccOAEPPadding: 622 if(ccrsa_sign_oaep(privateKey->fk, CCDigestGetDigestInfo(digestType), 623 ccDRBGGetRngState(), hashSignLen, hashToSign, 624 signedDataLen, signedData) != 0) 625 return kCCDecodeError; 626 break; 627 case ccX931Padding: 628 case ccPKCS1PaddingRaw: 629 case ccPaddingNone: 630 default: 631 return kCCParamError; 632 break; 633 } 634 return kCCSuccess; 635} 636 637 638 639CCCryptorStatus 640CCRSACryptorVerify(CCRSACryptorRef publicKey, CCAsymmetricPadding padding, 641 const void *hash, size_t hashLen, 642 CCDigestAlgorithm digestType, size_t saltLen, 643 const void *signedData, size_t signedDataLen) 644{ 645 bool valid; 646 647 CC_DEBUG_LOG(ASL_LEVEL_ERR, "Entering\n"); 648 if(!publicKey || !hash || !signedData) return kCCParamError; 649 650 switch(padding) { 651 case ccPKCS1Padding: 652 if(ccrsa_verify_pkcs1v15(ccrsa_ctx_public(publicKey->fk), CCDigestGetDigestInfo(digestType)->oid, 653 hashLen, hash, signedDataLen, signedData, &valid) != 0) 654 return kCCDecodeError; 655 if(!valid) return kCCDecodeError; 656 break; 657 658 case ccOAEPPadding: 659 if(ccrsa_verify_oaep(ccrsa_ctx_public(publicKey->fk), CCDigestGetDigestInfo(digestType), 660 hashLen, hash, signedDataLen, signedData, &valid) != 0) 661 return kCCDecodeError; 662 if(!valid) return kCCDecodeError; 663 break; 664 case ccX931Padding: 665 case ccPKCS1PaddingRaw: 666 case ccPaddingNone: 667 default: 668 return kCCParamError; 669 break; 670 } 671 return kCCSuccess; 672} 673 674#pragma mark APINotDone 675#ifdef NEVER 676 677// This was only here for FIPS. If we move FIPS to the corecrypto layer it will need to be there. 678 679CCCryptorStatus 680CCRSACryptorDecodePayloadPKCS1( 681 CCRSACryptorRef publicKey, 682 const void *cipherText, 683 size_t cipherTextLen, 684 void *plainText, 685 size_t *plainTextLen) 686{ 687 int tcReturn; 688 int stat = 0; 689 CCRSACryptor *publicCryptor = publicKey; 690 uint8_t *message; 691 unsigned long messageLen, modulusLen; 692 CCCryptorStatus retval = kCCSuccess; 693 694 modulusLen = CCRSAGetKeySize(publicKey); 695 messageLen = modulusLen / 8; 696 697 if((message = CC_XMALLOC(messageLen)) == NULL) return kCCMemoryFailure; 698 699 tcReturn = rsa_exptmod(cipherText, cipherTextLen, message, messageLen, publicCryptor->keyType, &publicCryptor->key); 700 if(tcReturn) { 701 retval = kCCDecodeError; 702 goto out; 703 } 704 tcReturn = pkcs_1_v1_5_decode(message, messageLen, LTC_PKCS_1_EME, modulusLen, plainText, plainTextLen, &stat); 705 if(tcReturn) { 706 retval = kCCDecodeError; 707 goto out; 708 } 709 if(!stat) { 710 retval = kCCDecodeError; 711 goto out; 712 } 713 714out: 715 CC_XZEROMEM(message, messageLen); 716 CC_XFREE(message, messageLen); 717 return retval; 718} 719 720#endif 721 722 723 724