cmscipher.c
1 /* 2 * The contents of this file are subject to the Mozilla Public 3 * License Version 1.1 (the "License"); you may not use this file 4 * except in compliance with the License. You may obtain a copy of 5 * the License at http://www.mozilla.org/MPL/ 6 * 7 * Software distributed under the License is distributed on an "AS 8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 9 * implied. See the License for the specific language governing 10 * rights and limitations under the License. 11 * 12 * The Original Code is the Netscape security libraries. 13 * 14 * The Initial Developer of the Original Code is Netscape 15 * Communications Corporation. Portions created by Netscape are 16 * Copyright (C) 1994-2000 Netscape Communications Corporation. All 17 * Rights Reserved. 18 * 19 * Contributor(s): 20 * 21 * Alternatively, the contents of this file may be used under the 22 * terms of the GNU General Public License Version 2 or later (the 23 * "GPL"), in which case the provisions of the GPL are applicable 24 * instead of those above. If you wish to allow use of your 25 * version of this file only under the terms of the GPL and not to 26 * allow others to use your version of this file under the MPL, 27 * indicate your decision by deleting the provisions above and 28 * replace them with the notice and other provisions required by 29 * the GPL. If you do not delete the provisions above, a recipient 30 * may use your version of this file under either the MPL or the 31 * GPL. 32 */ 33 34 /* 35 * Encryption/decryption routines for CMS implementation, none of which are exported. 36 * 37 */ 38 #include <limits.h> 39 40 #include "cmslocal.h" 41 42 #include "secoid.h" 43 #include <security_asn1/secerr.h> 44 #include <security_asn1/secasn1.h> 45 #include <security_asn1/secport.h> 46 47 #include <Security/SecAsn1Templates.h> 48 #if USE_CDSA_CRYPTO 49 #include <Security/cssmapi.h> 50 #include <Security/cssmapple.h> 51 #include <Security/SecKeyPriv.h> 52 #else 53 #include <Security/SecRandom.h> 54 #include <CommonCrypto/CommonCryptor.h> 55 #endif 56 57 /* 58 * ------------------------------------------------------------------- 59 * Cipher stuff. 60 */ 61 62 #if 0 63 typedef OSStatus (*nss_cms_cipher_function) (void *, unsigned char *, unsigned int *, 64 unsigned int, const unsigned char *, unsigned int); 65 typedef OSStatus (*nss_cms_cipher_destroy) (void *, Boolean); 66 #endif 67 68 #define BLOCK_SIZE 4096 69 70 struct SecCmsCipherContextStr { 71 #if 1 72 void * cc; /* CSP CONTEXT */ 73 Boolean encrypt; /* encrypt / decrypt switch */ 74 int block_size; /* block & pad sizes for cipher */ 75 #else 76 void * cx; /* PK11 cipher context */ 77 nss_cms_cipher_function doit; 78 nss_cms_cipher_destroy destroy; 79 Boolean encrypt; /* encrypt / decrypt switch */ 80 int pad_size; 81 int pending_count; /* pending data (not yet en/decrypted */ 82 unsigned char pending_buf[BLOCK_SIZE];/* because of blocking */ 83 #endif 84 }; 85 86 typedef struct sec_rc2cbcParameterStr { 87 SecAsn1Item rc2ParameterVersion; 88 SecAsn1Item iv; 89 } sec_rc2cbcParameter; 90 91 __unused static const SecAsn1Template sec_rc2cbc_parameter_template[] = { 92 { SEC_ASN1_SEQUENCE, 93 0, NULL, sizeof(sec_rc2cbcParameter) }, 94 { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT, 95 offsetof(sec_rc2cbcParameter,rc2ParameterVersion) }, 96 { SEC_ASN1_OCTET_STRING, 97 offsetof(sec_rc2cbcParameter,iv) }, 98 { 0 } 99 }; 100 101 // TODO: get rid of this? 102 #if USE_CDSA_CRYPTO 103 /* 104 ** Convert a der encoded *signed* integer into a machine integral value. 105 ** If an underflow/overflow occurs, sets error code and returns min/max. 106 */ 107 static long 108 DER_GetInteger(SecAsn1Item *it) 109 { 110 long ival = 0; 111 unsigned len = it->Length; 112 unsigned char *cp = it->Data; 113 unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1); 114 unsigned long ofloinit; 115 116 if (*cp & 0x80) 117 ival = -1L; 118 ofloinit = ival & overflow; 119 120 while (len) { 121 if ((ival & overflow) != ofloinit) { 122 PORT_SetError(SEC_ERROR_BAD_DER); 123 if (ival < 0) { 124 return LONG_MIN; 125 } 126 return LONG_MAX; 127 } 128 ival = ival << 8; 129 ival |= *cp++; 130 --len; 131 } 132 return ival; 133 } 134 135 /* S/MIME picked id values to represent differnt keysizes */ 136 /* I do have a formula, but it ain't pretty, and it only works because you 137 * can always match three points to a parabola:) */ 138 static unsigned char rc2_map(SecAsn1Item *version) 139 { 140 long x; 141 142 x = DER_GetInteger(version); 143 144 switch (x) { 145 case 58: return 128; 146 case 120: return 64; 147 case 160: return 40; 148 } 149 return 128; 150 } 151 152 static unsigned long rc2_unmap(unsigned long x) 153 { 154 switch (x) { 155 case 128: return 58; 156 case 64: return 120; 157 case 40: return 160; 158 } 159 return 58; 160 } 161 #endif /* USE_CDSA_CRYPTO */ 162 163 /* default IV size in bytes */ 164 #define DEFAULT_IV_SIZE 8 165 /* IV/block size for AES */ 166 #define AES_BLOCK_SIZE 16 167 /* max IV size in bytes */ 168 #define MAX_IV_SIZE AES_BLOCK_SIZE 169 170 #if !USE_CDSA_CRYPTO 171 #ifndef kCCKeySizeMaxRC2 172 #define kCCKeySizeMaxRC2 16 173 #endif 174 #ifndef kCCBlockSizeRC2 175 #define kCCBlockSizeRC2 8 176 #endif 177 #endif 178 179 static SecCmsCipherContextRef 180 SecCmsCipherContextStart(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorithmID *algid, Boolean encrypt) 181 { 182 SecCmsCipherContextRef cc; 183 SECOidData *oidData; 184 SECOidTag algtag; 185 OSStatus rv; 186 uint8_t ivbuf[MAX_IV_SIZE]; 187 SecAsn1Item initVector = { DEFAULT_IV_SIZE, ivbuf }; 188 #if USE_CDSA_CRYPTO 189 CSSM_CC_HANDLE ciphercc = 0; 190 CSSM_ALGORITHMS algorithm; 191 CSSM_PADDING padding = CSSM_PADDING_PKCS7; 192 CSSM_ENCRYPT_MODE mode; 193 CSSM_CSP_HANDLE cspHandle; 194 const CSSM_KEY *cssmKey; 195 //CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_ALG_PARAMS, sizeof(SecAsn1Item *) }; 196 #else 197 CCCryptorRef ciphercc = NULL; 198 CCOptions cipheroptions = kCCOptionPKCS7Padding; 199 int cipher_blocksize = 0; 200 #endif 201 202 #if USE_CDSA_CRYPTO 203 rv = SecKeyGetCSPHandle(key, &cspHandle); 204 if (rv) 205 goto loser; 206 rv = SecKeyGetCSSMKey(key, &cssmKey); 207 if (rv) 208 goto loser; 209 #endif 210 211 // @@@ Add support for PBE based stuff 212 213 oidData = SECOID_FindOID(&algid->algorithm); 214 if (!oidData) 215 goto loser; 216 algtag = oidData->offset; 217 #if USE_CDSA_CRYPTO 218 algorithm = oidData->cssmAlgorithm; 219 if (!algorithm) 220 goto loser; 221 222 switch (algtag) 223 { 224 case SEC_OID_RC2_CBC: 225 case SEC_OID_RC4: 226 case SEC_OID_DES_EDE3_CBC: 227 case SEC_OID_DES_EDE: 228 case SEC_OID_DES_CBC: 229 case SEC_OID_RC5_CBC_PAD: 230 case SEC_OID_FORTEZZA_SKIPJACK: 231 mode = CSSM_ALGMODE_CBCPadIV8; 232 break; 233 234 /* RFC 3565 says that these sizes refer to key size, NOT block size */ 235 case SEC_OID_AES_128_CBC: 236 case SEC_OID_AES_192_CBC: 237 case SEC_OID_AES_256_CBC: 238 initVector.Length = AES_BLOCK_SIZE; 239 mode = CSSM_ALGMODE_CBCPadIV8; 240 break; 241 242 case SEC_OID_DES_ECB: 243 case SEC_OID_AES_128_ECB: 244 case SEC_OID_AES_192_ECB: 245 case SEC_OID_AES_256_ECB: 246 mode = CSSM_ALGMODE_ECBPad; 247 break; 248 249 case SEC_OID_DES_OFB: 250 mode = CSSM_ALGMODE_OFBPadIV8; 251 break; 252 253 case SEC_OID_DES_CFB: 254 mode = CSSM_ALGMODE_CFBPadIV8; 255 break; 256 257 default: 258 goto loser; 259 } 260 #else 261 CCAlgorithm alg = -1; 262 switch (algtag) { 263 case SEC_OID_DES_CBC: 264 alg = kCCAlgorithmDES; 265 cipher_blocksize = kCCBlockSizeDES; 266 break; 267 case SEC_OID_DES_EDE3_CBC: 268 alg = kCCAlgorithm3DES; 269 cipher_blocksize = kCCBlockSize3DES; 270 break; 271 case SEC_OID_RC2_CBC: 272 alg = kCCAlgorithmRC2; 273 cipher_blocksize = kCCBlockSizeRC2; 274 break; 275 case SEC_OID_AES_128_CBC: 276 case SEC_OID_AES_192_CBC: 277 case SEC_OID_AES_256_CBC: 278 alg = kCCAlgorithmAES128; 279 cipher_blocksize = kCCBlockSizeAES128; 280 initVector.Length = AES_BLOCK_SIZE; 281 break; 282 default: 283 goto loser; 284 } 285 #endif 286 287 if (encrypt) 288 { 289 #if USE_CDSA_CRYPTO 290 CSSM_CC_HANDLE randomcc; 291 //SecAsn1Item *parameters; 292 293 // Generate random initVector 294 if (CSSM_CSP_CreateRandomGenContext(cspHandle, 295 CSSM_ALGID_APPLE_YARROW, 296 NULL, /* seed*/ 297 initVector.Length, 298 &randomcc)) 299 goto loser; 300 301 if (CSSM_GenerateRandom(randomcc, &initVector)) 302 goto loser; 303 CSSM_DeleteContext(randomcc); 304 #else 305 if (SecRandomCopyBytes(kSecRandomDefault, 306 initVector.Length, initVector.Data)) 307 goto loser; 308 #endif 309 310 // Put IV into algid.parameters 311 switch (algtag) 312 { 313 case SEC_OID_RC4: 314 case SEC_OID_DES_EDE3_CBC: 315 case SEC_OID_DES_EDE: 316 case SEC_OID_DES_CBC: 317 case SEC_OID_AES_128_CBC: 318 case SEC_OID_AES_192_CBC: 319 case SEC_OID_AES_256_CBC: 320 case SEC_OID_FORTEZZA_SKIPJACK: 321 case SEC_OID_DES_ECB: 322 case SEC_OID_AES_128_ECB: 323 case SEC_OID_AES_192_ECB: 324 case SEC_OID_AES_256_ECB: 325 case SEC_OID_DES_OFB: 326 case SEC_OID_DES_CFB: 327 /* Just encode the initVector as an octet string. */ 328 if (!SEC_ASN1EncodeItem(poolp, &algid->parameters, 329 &initVector, kSecAsn1OctetStringTemplate)) 330 goto loser; 331 break; 332 case SEC_OID_RC2_CBC: 333 #if USE_CDSA_CRYPTO 334 { 335 sec_rc2cbcParameter rc2 = {}; 336 unsigned long rc2version; 337 SecAsn1Item *newParams; 338 339 rc2.iv = initVector; 340 rc2version = rc2_unmap(cssmKey->KeyHeader.LogicalKeySizeInBits); 341 if (!SEC_ASN1EncodeUnsignedInteger (NULL, &(rc2.rc2ParameterVersion), 342 rc2version)) 343 goto loser; 344 newParams = SEC_ASN1EncodeItem (poolp, &algid->parameters, &rc2, 345 sec_rc2cbc_parameter_template); 346 PORT_Free(rc2.rc2ParameterVersion.Data); 347 if (newParams == NULL) 348 goto loser; 349 break; 350 } 351 #endif 352 case SEC_OID_RC5_CBC_PAD: 353 default: 354 // @@@ Implement rc5 params stuff. 355 goto loser; 356 } 357 } 358 else 359 { 360 // Extract IV from algid.parameters 361 // Put IV into algid.parameters 362 switch (algtag) 363 { 364 case SEC_OID_RC4: 365 case SEC_OID_DES_EDE3_CBC: 366 case SEC_OID_DES_EDE: 367 case SEC_OID_DES_CBC: 368 case SEC_OID_AES_128_CBC: 369 case SEC_OID_AES_192_CBC: 370 case SEC_OID_AES_256_CBC: 371 case SEC_OID_FORTEZZA_SKIPJACK: 372 case SEC_OID_DES_ECB: 373 case SEC_OID_AES_128_ECB: 374 case SEC_OID_AES_192_ECB: 375 case SEC_OID_AES_256_ECB: 376 case SEC_OID_DES_OFB: 377 case SEC_OID_DES_CFB: 378 { 379 SecAsn1Item iv = {}; 380 /* Just decode the initVector from an octet string. */ 381 rv = SEC_ASN1DecodeItem(NULL, &iv, kSecAsn1OctetStringTemplate, &(algid->parameters)); 382 if (rv) 383 goto loser; 384 if (initVector.Length != iv.Length) { 385 PORT_Free(iv.Data); 386 goto loser; 387 } 388 memcpy(initVector.Data, iv.Data, initVector.Length); 389 PORT_Free(iv.Data); 390 break; 391 } 392 case SEC_OID_RC2_CBC: 393 #if USE_CDSA_CRYPTO 394 { 395 sec_rc2cbcParameter rc2 = {}; 396 unsigned long ulEffectiveBits; 397 398 rv = SEC_ASN1DecodeItem(NULL, &rc2 ,sec_rc2cbc_parameter_template, 399 &(algid->parameters)); 400 if (rv) 401 goto loser; 402 403 if (initVector.Length != rc2.iv.Length) { 404 PORT_Free(rc2.iv.Data); 405 PORT_Free(rc2.rc2ParameterVersion.Data); 406 goto loser; 407 } 408 memcpy(initVector.Data, rc2.iv.Data, initVector.Length); 409 PORT_Free(rc2.iv.Data); 410 411 ulEffectiveBits = rc2_map(&rc2.rc2ParameterVersion); 412 PORT_Free(rc2.rc2ParameterVersion.Data); 413 if (ulEffectiveBits != cssmKey->KeyHeader.LogicalKeySizeInBits) 414 goto loser; 415 break; 416 } 417 #endif 418 case SEC_OID_RC5_CBC_PAD: 419 default: 420 // @@@ Implement rc5 params stuff. 421 goto loser; 422 } 423 } 424 425 #if USE_CDSA_CRYPTO 426 if (CSSM_CSP_CreateSymmetricContext(cspHandle, 427 algorithm, 428 mode, 429 NULL, /* accessCred */ 430 cssmKey, 431 &initVector, 432 padding, 433 NULL, /* reserved */ 434 &ciphercc)) 435 goto loser; 436 437 if (encrypt) 438 rv = CSSM_EncryptDataInit(ciphercc); 439 else 440 rv = CSSM_DecryptDataInit(ciphercc); 441 if (rv) 442 goto loser; 443 #else 444 if (CCCryptorCreate(encrypt ? kCCEncrypt : kCCDecrypt, 445 alg, cipheroptions, CFDataGetBytePtr(key), CFDataGetLength(key), 446 initVector.Data, &ciphercc)) 447 goto loser; 448 #endif 449 450 cc = (SecCmsCipherContextRef)PORT_ZAlloc(sizeof(SecCmsCipherContext)); 451 if (cc == NULL) 452 goto loser; 453 454 cc->cc = ciphercc; 455 cc->encrypt = encrypt; 456 #if !USE_CDSA_CRYPTO 457 cc->block_size =cipher_blocksize; 458 #endif 459 return cc; 460 loser: 461 if (ciphercc) 462 #if USE_CDSA_CRYPTO 463 CSSM_DeleteContext(ciphercc); 464 #else 465 CCCryptorRelease(ciphercc); 466 #endif 467 468 return NULL; 469 } 470 471 /* 472 * SecCmsCipherContextStartDecrypt - create a cipher context to do decryption 473 * based on the given bulk * encryption key and algorithm identifier (which may include an iv). 474 * 475 * XXX Once both are working, it might be nice to combine this and the 476 * function below (for starting up encryption) into one routine, and just 477 * have two simple cover functions which call it. 478 */ 479 SecCmsCipherContextRef 480 SecCmsCipherContextStartDecrypt(SecSymmetricKeyRef key, SECAlgorithmID *algid) 481 { 482 return SecCmsCipherContextStart(NULL, key, algid, PR_FALSE); 483 #if 0 484 SecCmsCipherContextRef cc; 485 void *ciphercx; 486 CK_MECHANISM_TYPE mechanism; 487 SecAsn1Item * param; 488 PK11SlotInfo *slot; 489 SECOidTag algtag; 490 491 algtag = SECOID_GetAlgorithmTag(algid); 492 493 /* set param and mechanism */ 494 if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { 495 CK_MECHANISM pbeMech, cryptoMech; 496 SecAsn1Item * pbeParams; 497 SEC_PKCS5KeyAndPassword *keyPwd; 498 499 PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); 500 PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); 501 502 /* HACK ALERT! 503 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword * 504 */ 505 keyPwd = (SEC_PKCS5KeyAndPassword *)key; 506 key = keyPwd->key; 507 508 /* find correct PK11 mechanism and parameters to initialize pbeMech */ 509 pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); 510 pbeParams = PK11_ParamFromAlgid(algid); 511 if (!pbeParams) 512 return NULL; 513 pbeMech.pParameter = pbeParams->Data; 514 pbeMech.ulParameterLen = pbeParams->Length; 515 516 /* now map pbeMech to cryptoMech */ 517 if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, keyPwd->pwitem, 518 PR_FALSE) != CKR_OK) { 519 SECITEM_ZfreeItem(pbeParams, PR_TRUE); 520 return NULL; 521 } 522 SECITEM_ZfreeItem(pbeParams, PR_TRUE); 523 524 /* and use it to initialize param & mechanism */ 525 if ((param = (SecAsn1Item *)PORT_ZAlloc(sizeof(SecAsn1Item))) == NULL) 526 return NULL; 527 528 param->Data = (unsigned char *)cryptoMech.pParameter; 529 param->Length = cryptoMech.ulParameterLen; 530 mechanism = cryptoMech.mechanism; 531 } else { 532 mechanism = PK11_AlgtagToMechanism(algtag); 533 if ((param = PK11_ParamFromAlgid(algid)) == NULL) 534 return NULL; 535 } 536 537 cc = (SecCmsCipherContextRef)PORT_ZAlloc(sizeof(SecCmsCipherContext)); 538 if (cc == NULL) { 539 SECITEM_FreeItem(param,PR_TRUE); 540 return NULL; 541 } 542 543 /* figure out pad and block sizes */ 544 cc->pad_size = PK11_GetBlockSize(mechanism, param); 545 slot = PK11_GetSlotFromKey(key); 546 cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; 547 PK11_FreeSlot(slot); 548 549 /* create PK11 cipher context */ 550 ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_DECRYPT, key, param); 551 SECITEM_FreeItem(param, PR_TRUE); 552 if (ciphercx == NULL) { 553 PORT_Free (cc); 554 return NULL; 555 } 556 557 cc->cx = ciphercx; 558 cc->doit = (nss_cms_cipher_function) PK11_CipherOp; 559 cc->destroy = (nss_cms_cipher_destroy) PK11_DestroyContext; 560 cc->encrypt = PR_FALSE; 561 cc->pending_count = 0; 562 563 return cc; 564 #endif 565 } 566 567 /* 568 * SecCmsCipherContextStartEncrypt - create a cipher object to do encryption, 569 * based on the given bulk encryption key and algorithm tag. Fill in the algorithm 570 * identifier (which may include an iv) appropriately. 571 * 572 * XXX Once both are working, it might be nice to combine this and the 573 * function above (for starting up decryption) into one routine, and just 574 * have two simple cover functions which call it. 575 */ 576 SecCmsCipherContextRef 577 SecCmsCipherContextStartEncrypt(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorithmID *algid) 578 { 579 return SecCmsCipherContextStart(poolp, key, algid, PR_TRUE); 580 #if 0 581 SecCmsCipherContextRef cc; 582 void *ciphercx; 583 SecAsn1Item * param; 584 OSStatus rv; 585 CK_MECHANISM_TYPE mechanism; 586 PK11SlotInfo *slot; 587 Boolean needToEncodeAlgid = PR_FALSE; 588 SECOidTag algtag = SECOID_GetAlgorithmTag(algid); 589 590 /* set param and mechanism */ 591 if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { 592 CK_MECHANISM pbeMech, cryptoMech; 593 SecAsn1Item * pbeParams; 594 SEC_PKCS5KeyAndPassword *keyPwd; 595 596 PORT_Memset(&pbeMech, 0, sizeof(CK_MECHANISM)); 597 PORT_Memset(&cryptoMech, 0, sizeof(CK_MECHANISM)); 598 599 /* HACK ALERT! 600 * in this case, key is not actually a SecSymmetricKeyRef, but a SEC_PKCS5KeyAndPassword * 601 */ 602 keyPwd = (SEC_PKCS5KeyAndPassword *)key; 603 key = keyPwd->key; 604 605 /* find correct PK11 mechanism and parameters to initialize pbeMech */ 606 pbeMech.mechanism = PK11_AlgtagToMechanism(algtag); 607 pbeParams = PK11_ParamFromAlgid(algid); 608 if (!pbeParams) 609 return NULL; 610 pbeMech.pParameter = pbeParams->Data; 611 pbeMech.ulParameterLen = pbeParams->Length; 612 613 /* now map pbeMech to cryptoMech */ 614 if (PK11_MapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, keyPwd->pwitem, 615 PR_FALSE) != CKR_OK) { 616 SECITEM_ZfreeItem(pbeParams, PR_TRUE); 617 return NULL; 618 } 619 SECITEM_ZfreeItem(pbeParams, PR_TRUE); 620 621 /* and use it to initialize param & mechanism */ 622 if ((param = (SecAsn1Item *)PORT_ZAlloc(sizeof(SecAsn1Item))) == NULL) 623 return NULL; 624 625 param->Data = (unsigned char *)cryptoMech.pParameter; 626 param->Length = cryptoMech.ulParameterLen; 627 mechanism = cryptoMech.mechanism; 628 } else { 629 mechanism = PK11_AlgtagToMechanism(algtag); 630 if ((param = PK11_GenerateNewParam(mechanism, key)) == NULL) 631 return NULL; 632 needToEncodeAlgid = PR_TRUE; 633 } 634 635 cc = (SecCmsCipherContextRef)PORT_ZAlloc(sizeof(SecCmsCipherContext)); 636 if (cc == NULL) 637 return NULL; 638 639 /* now find pad and block sizes for our mechanism */ 640 cc->pad_size = PK11_GetBlockSize(mechanism,param); 641 slot = PK11_GetSlotFromKey(key); 642 cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size; 643 PK11_FreeSlot(slot); 644 645 /* and here we go, creating a PK11 cipher context */ 646 ciphercx = PK11_CreateContextBySymKey(mechanism, CKA_ENCRYPT, key, param); 647 if (ciphercx == NULL) { 648 PORT_Free(cc); 649 cc = NULL; 650 goto loser; 651 } 652 653 /* 654 * These are placed after the CreateContextBySymKey() because some 655 * mechanisms have to generate their IVs from their card (i.e. FORTEZZA). 656 * Don't move it from here. 657 * XXX is that right? the purpose of this is to get the correct algid 658 * containing the IVs etc. for encoding. this means we need to set this up 659 * BEFORE encoding the algid in the contentInfo, right? 660 */ 661 if (needToEncodeAlgid) { 662 rv = PK11_ParamToAlgid(algtag, param, poolp, algid); 663 if(rv != SECSuccess) { 664 PORT_Free(cc); 665 cc = NULL; 666 goto loser; 667 } 668 } 669 670 cc->cx = ciphercx; 671 cc->doit = (nss_cms_cipher_function)PK11_CipherOp; 672 cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext; 673 cc->encrypt = PR_TRUE; 674 cc->pending_count = 0; 675 676 loser: 677 SECITEM_FreeItem(param, PR_TRUE); 678 679 return cc; 680 #endif 681 } 682 683 void 684 SecCmsCipherContextDestroy(SecCmsCipherContextRef cc) 685 { 686 PORT_Assert(cc != NULL); 687 if (cc == NULL) 688 return; 689 #if USE_CDSA_CRYPTO 690 CSSM_DeleteContext(cc->cc); 691 #else 692 CCCryptorRelease(cc->cc); 693 #endif 694 PORT_Free(cc); 695 } 696 697 static unsigned int 698 SecCmsCipherContextLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final, Boolean encrypt) 699 { 700 #if USE_CDSA_CRYPTO 701 CSSM_QUERY_SIZE_DATA dataBlockSize[2] = { { input_len, 0 }, { input_len, 0 } }; 702 /* Hack CDSA treats the last block as the final one. So unless we are being asked to report the final size we ask for 2 block and ignore the second (final) one. */ 703 OSStatus rv = CSSM_QuerySize(cc->cc, cc->encrypt, final ? 1 : 2, dataBlockSize); 704 if (rv) 705 { 706 PORT_SetError(rv); 707 return 0; 708 } 709 710 return dataBlockSize[0].SizeOutputBlock; 711 #else 712 return ((input_len + cc->block_size - 1) / cc->block_size * cc->block_size) + (final ? cc->block_size : 0); 713 #endif 714 } 715 716 /* 717 * SecCmsCipherContextDecryptLength - find the output length of the next call to decrypt. 718 * 719 * cc - the cipher context 720 * input_len - number of bytes used as input 721 * final - true if this is the final chunk of data 722 * 723 * Result can be used to perform memory allocations. Note that the amount 724 * is exactly accurate only when not doing a block cipher or when final 725 * is false, otherwise it is an upper bound on the amount because until 726 * we see the data we do not know how many padding bytes there are 727 * (always between 1 and bsize). 728 * 729 * Note that this can return zero, which does not mean that the decrypt 730 * operation can be skipped! (It simply means that there are not enough 731 * bytes to make up an entire block; the bytes will be reserved until 732 * there are enough to encrypt/decrypt at least one block.) However, 733 * if zero is returned it *does* mean that no output buffer need be 734 * passed in to the subsequent decrypt operation, as no output bytes 735 * will be stored. 736 */ 737 unsigned int 738 SecCmsCipherContextDecryptLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final) 739 { 740 #if 1 741 return SecCmsCipherContextLength(cc, input_len, final, PR_FALSE); 742 #else 743 int blocks, block_size; 744 745 PORT_Assert (! cc->encrypt); 746 747 block_size = cc->block_size; 748 749 /* 750 * If this is not a block cipher, then we always have the same 751 * number of output bytes as we had input bytes. 752 */ 753 if (block_size == 0) 754 return input_len; 755 756 /* 757 * On the final call, we will always use up all of the pending 758 * bytes plus all of the input bytes, *but*, there will be padding 759 * at the end and we cannot predict how many bytes of padding we 760 * will end up removing. The amount given here is actually known 761 * to be at least 1 byte too long (because we know we will have 762 * at least 1 byte of padding), but seemed clearer/better to me. 763 */ 764 if (final) 765 return cc->pending_count + input_len; 766 767 /* 768 * Okay, this amount is exactly what we will output on the 769 * next cipher operation. We will always hang onto the last 770 * 1 - block_size bytes for non-final operations. That is, 771 * we will do as many complete blocks as we can *except* the 772 * last block (complete or partial). (This is because until 773 * we know we are at the end, we cannot know when to interpret 774 * and removing the padding byte(s), which are guaranteed to 775 * be there.) 776 */ 777 blocks = (cc->pending_count + input_len - 1) / block_size; 778 return blocks * block_size; 779 #endif 780 } 781 782 /* 783 * SecCmsCipherContextEncryptLength - find the output length of the next call to encrypt. 784 * 785 * cc - the cipher context 786 * input_len - number of bytes used as input 787 * final - true if this is the final chunk of data 788 * 789 * Result can be used to perform memory allocations. 790 * 791 * Note that this can return zero, which does not mean that the encrypt 792 * operation can be skipped! (It simply means that there are not enough 793 * bytes to make up an entire block; the bytes will be reserved until 794 * there are enough to encrypt/decrypt at least one block.) However, 795 * if zero is returned it *does* mean that no output buffer need be 796 * passed in to the subsequent encrypt operation, as no output bytes 797 * will be stored. 798 */ 799 unsigned int 800 SecCmsCipherContextEncryptLength(SecCmsCipherContextRef cc, unsigned int input_len, Boolean final) 801 { 802 #if 1 803 return SecCmsCipherContextLength(cc, input_len, final, PR_TRUE); 804 #else 805 int blocks, block_size; 806 int pad_size; 807 808 PORT_Assert (cc->encrypt); 809 810 block_size = cc->block_size; 811 pad_size = cc->pad_size; 812 813 /* 814 * If this is not a block cipher, then we always have the same 815 * number of output bytes as we had input bytes. 816 */ 817 if (block_size == 0) 818 return input_len; 819 820 /* 821 * On the final call, we only send out what we need for 822 * remaining bytes plus the padding. (There is always padding, 823 * so even if we have an exact number of blocks as input, we 824 * will add another full block that is just padding.) 825 */ 826 if (final) { 827 if (pad_size == 0) { 828 return cc->pending_count + input_len; 829 } else { 830 blocks = (cc->pending_count + input_len) / pad_size; 831 blocks++; 832 return blocks*pad_size; 833 } 834 } 835 836 /* 837 * Now, count the number of complete blocks of data we have. 838 */ 839 blocks = (cc->pending_count + input_len) / block_size; 840 841 842 return blocks * block_size; 843 #endif 844 } 845 846 847 static OSStatus 848 SecCmsCipherContextCrypt(SecCmsCipherContextRef cc, unsigned char *output, 849 unsigned int *output_len_p, unsigned int max_output_len, 850 const unsigned char *input, unsigned int input_len, 851 Boolean final, Boolean encrypt) 852 { 853 size_t bytes_output = 0; 854 OSStatus rv = 0; 855 856 if (input_len) 857 { 858 859 #if USE_CDSA_CRYPTO 860 SecAsn1Item inputBuf = { input_len, (uint8_t *)input }; 861 SecAsn1Item outputBuf = { max_output_len, output }; 862 if (encrypt) 863 rv = CSSM_EncryptDataUpdate(cc->cc, &inputBuf, 1, &outputBuf, 1, &bytes_output); 864 else 865 rv = CSSM_DecryptDataUpdate(cc->cc, &inputBuf, 1, &outputBuf, 1, &bytes_output); 866 #else 867 rv = CCCryptorUpdate(cc->cc, input, input_len, output, max_output_len, &bytes_output); 868 #endif 869 } 870 871 if (!rv && final) 872 { 873 #if USE_CDSA_CRYPTO 874 SecAsn1Item remainderBuf = { max_output_len - bytes_output, output + bytes_output }; 875 if (encrypt) 876 rv = CSSM_EncryptDataFinal(cc->cc, &remainderBuf); 877 else 878 rv = CSSM_DecryptDataFinal(cc->cc, &remainderBuf); 879 bytes_output += remainderBuf.Length; 880 #else 881 size_t bytes_output_final = 0; 882 rv = CCCryptorFinal(cc->cc, output+bytes_output, max_output_len-bytes_output, &bytes_output_final); 883 bytes_output += bytes_output_final; 884 #endif 885 } 886 if (rv) 887 PORT_SetError(SEC_ERROR_BAD_DATA); 888 else if (output_len_p) 889 *output_len_p = (unsigned int)bytes_output; /* This cast is safe since bytes_output can't be bigger than max_output_len */ 890 891 return rv; 892 } 893 894 /* 895 * SecCmsCipherContextDecrypt - do the decryption 896 * 897 * cc - the cipher context 898 * output - buffer for decrypted result bytes 899 * output_len_p - number of bytes in output 900 * max_output_len - upper bound on bytes to put into output 901 * input - pointer to input bytes 902 * input_len - number of input bytes 903 * final - true if this is the final chunk of data 904 * 905 * Decrypts a given length of input buffer (starting at "input" and 906 * containing "input_len" bytes), placing the decrypted bytes in 907 * "output" and storing the output length in "*output_len_p". 908 * "cc" is the return value from SecCmsCipherStartDecrypt. 909 * When "final" is true, this is the last of the data to be decrypted. 910 * 911 * This is much more complicated than it sounds when the cipher is 912 * a block-type, meaning that the decryption function will only 913 * operate on whole blocks. But our caller is operating stream-wise, 914 * and can pass in any number of bytes. So we need to keep track 915 * of block boundaries. We save excess bytes between calls in "cc". 916 * We also need to determine which bytes are padding, and remove 917 * them from the output. We can only do this step when we know we 918 * have the final block of data. PKCS #7 specifies that the padding 919 * used for a block cipher is a string of bytes, each of whose value is 920 * the same as the length of the padding, and that all data is padded. 921 * (Even data that starts out with an exact multiple of blocks gets 922 * added to it another block, all of which is padding.) 923 */ 924 OSStatus 925 SecCmsCipherContextDecrypt(SecCmsCipherContextRef cc, unsigned char *output, 926 unsigned int *output_len_p, unsigned int max_output_len, 927 const unsigned char *input, unsigned int input_len, 928 Boolean final) 929 { 930 #if 1 931 return SecCmsCipherContextCrypt(cc, output, 932 output_len_p, max_output_len, 933 input, input_len, 934 final, PR_FALSE); 935 #else 936 int blocks, bsize, pcount, padsize; 937 unsigned int max_needed, ifraglen, ofraglen, output_len; 938 unsigned char *pbuf; 939 OSStatus rv; 940 941 PORT_Assert (! cc->encrypt); 942 943 /* 944 * Check that we have enough room for the output. Our caller should 945 * already handle this; failure is really an internal error (i.e. bug). 946 */ 947 max_needed = SecCmsCipherContextDecryptLength(cc, input_len, final); 948 PORT_Assert (max_output_len >= max_needed); 949 if (max_output_len < max_needed) { 950 /* PORT_SetError (XXX); */ 951 return SECFailure; 952 } 953 954 /* 955 * hardware encryption does not like small decryption sizes here, so we 956 * allow both blocking and padding. 957 */ 958 bsize = cc->block_size; 959 padsize = cc->pad_size; 960 961 /* 962 * When no blocking or padding work to do, we can simply call the 963 * cipher function and we are done. 964 */ 965 if (bsize == 0) { 966 return (* cc->doit) (cc->cx, output, output_len_p, max_output_len, 967 input, input_len); 968 } 969 970 pcount = cc->pending_count; 971 pbuf = cc->pending_buf; 972 973 output_len = 0; 974 975 if (pcount) { 976 /* 977 * Try to fill in an entire block, starting with the bytes 978 * we already have saved away. 979 */ 980 while (input_len && pcount < bsize) { 981 pbuf[pcount++] = *input++; 982 input_len--; 983 } 984 /* 985 * If we have at most a whole block and this is not our last call, 986 * then we are done for now. (We do not try to decrypt a lone 987 * single block because we cannot interpret the padding bytes 988 * until we know we are handling the very last block of all input.) 989 */ 990 if (input_len == 0 && !final) { 991 cc->pending_count = pcount; 992 if (output_len_p) 993 *output_len_p = 0; 994 return SECSuccess; 995 } 996 /* 997 * Given the logic above, we expect to have a full block by now. 998 * If we do not, there is something wrong, either with our own 999 * logic or with (length of) the data given to us. 1000 */ 1001 if ((padsize != 0) && (pcount % padsize) != 0) { 1002 PORT_Assert (final); 1003 PORT_SetError (SEC_ERROR_BAD_DATA); 1004 return SECFailure; 1005 } 1006 /* 1007 * Decrypt the block. 1008 */ 1009 rv = (*cc->doit)(cc->cx, output, &ofraglen, max_output_len, 1010 pbuf, pcount); 1011 if (rv != SECSuccess) 1012 return rv; 1013 1014 /* 1015 * For now anyway, all of our ciphers have the same number of 1016 * bytes of output as they do input. If this ever becomes untrue, 1017 * then SecCmsCipherContextDecryptLength needs to be made smarter! 1018 */ 1019 PORT_Assert(ofraglen == pcount); 1020 1021 /* 1022 * Account for the bytes now in output. 1023 */ 1024 max_output_len -= ofraglen; 1025 output_len += ofraglen; 1026 output += ofraglen; 1027 } 1028 1029 /* 1030 * If this is our last call, we expect to have an exact number of 1031 * blocks left to be decrypted; we will decrypt them all. 1032 * 1033 * If not our last call, we always save between 1 and bsize bytes 1034 * until next time. (We must do this because we cannot be sure 1035 * that none of the decrypted bytes are padding bytes until we 1036 * have at least another whole block of data. You cannot tell by 1037 * looking -- the data could be anything -- you can only tell by 1038 * context, knowing you are looking at the last block.) We could 1039 * decrypt a whole block now but it is easier if we just treat it 1040 * the same way we treat partial block bytes. 1041 */ 1042 if (final) { 1043 if (padsize) { 1044 blocks = input_len / padsize; 1045 ifraglen = blocks * padsize; 1046 } else ifraglen = input_len; 1047 PORT_Assert (ifraglen == input_len); 1048 1049 if (ifraglen != input_len) { 1050 PORT_SetError(SEC_ERROR_BAD_DATA); 1051 return SECFailure; 1052 } 1053 } else { 1054 blocks = (input_len - 1) / bsize; 1055 ifraglen = blocks * bsize; 1056 PORT_Assert (ifraglen < input_len); 1057 1058 pcount = input_len - ifraglen; 1059 PORT_Memcpy (pbuf, input + ifraglen, pcount); 1060 cc->pending_count = pcount; 1061 } 1062 1063 if (ifraglen) { 1064 rv = (* cc->doit)(cc->cx, output, &ofraglen, max_output_len, 1065 input, ifraglen); 1066 if (rv != SECSuccess) 1067 return rv; 1068 1069 /* 1070 * For now anyway, all of our ciphers have the same number of 1071 * bytes of output as they do input. If this ever becomes untrue, 1072 * then sec_PKCS7DecryptLength needs to be made smarter! 1073 */ 1074 PORT_Assert (ifraglen == ofraglen); 1075 if (ifraglen != ofraglen) { 1076 PORT_SetError(SEC_ERROR_BAD_DATA); 1077 return SECFailure; 1078 } 1079 1080 output_len += ofraglen; 1081 } else { 1082 ofraglen = 0; 1083 } 1084 1085 /* 1086 * If we just did our very last block, "remove" the padding by 1087 * adjusting the output length. 1088 */ 1089 if (final && (padsize != 0)) { 1090 unsigned int padlen = *(output + ofraglen - 1); 1091 1092 if (padlen == 0 || padlen > padsize) { 1093 PORT_SetError(SEC_ERROR_BAD_DATA); 1094 return SECFailure; 1095 } 1096 output_len -= padlen; 1097 } 1098 1099 PORT_Assert (output_len_p != NULL || output_len == 0); 1100 if (output_len_p != NULL) 1101 *output_len_p = output_len; 1102 1103 return SECSuccess; 1104 #endif 1105 } 1106 1107 /* 1108 * SecCmsCipherContextEncrypt - do the encryption 1109 * 1110 * cc - the cipher context 1111 * output - buffer for decrypted result bytes 1112 * output_len_p - number of bytes in output 1113 * max_output_len - upper bound on bytes to put into output 1114 * input - pointer to input bytes 1115 * input_len - number of input bytes 1116 * final - true if this is the final chunk of data 1117 * 1118 * Encrypts a given length of input buffer (starting at "input" and 1119 * containing "input_len" bytes), placing the encrypted bytes in 1120 * "output" and storing the output length in "*output_len_p". 1121 * "cc" is the return value from SecCmsCipherStartEncrypt. 1122 * When "final" is true, this is the last of the data to be encrypted. 1123 * 1124 * This is much more complicated than it sounds when the cipher is 1125 * a block-type, meaning that the encryption function will only 1126 * operate on whole blocks. But our caller is operating stream-wise, 1127 * and can pass in any number of bytes. So we need to keep track 1128 * of block boundaries. We save excess bytes between calls in "cc". 1129 * We also need to add padding bytes at the end. PKCS #7 specifies 1130 * that the padding used for a block cipher is a string of bytes, 1131 * each of whose value is the same as the length of the padding, 1132 * and that all data is padded. (Even data that starts out with 1133 * an exact multiple of blocks gets added to it another block, 1134 * all of which is padding.) 1135 * 1136 * XXX I would kind of like to combine this with the function above 1137 * which does decryption, since they have a lot in common. But the 1138 * tricky parts about padding and filling blocks would be much 1139 * harder to read that way, so I left them separate. At least for 1140 * now until it is clear that they are right. 1141 */ 1142 OSStatus 1143 SecCmsCipherContextEncrypt(SecCmsCipherContextRef cc, unsigned char *output, 1144 unsigned int *output_len_p, unsigned int max_output_len, 1145 const unsigned char *input, unsigned int input_len, 1146 Boolean final) 1147 { 1148 #if 1 1149 return SecCmsCipherContextCrypt(cc, output, 1150 output_len_p, max_output_len, 1151 input, input_len, 1152 final, PR_TRUE); 1153 #else 1154 int blocks, bsize, padlen, pcount, padsize; 1155 unsigned int max_needed, ifraglen, ofraglen, output_len; 1156 unsigned char *pbuf; 1157 OSStatus rv; 1158 1159 PORT_Assert (cc->encrypt); 1160 1161 /* 1162 * Check that we have enough room for the output. Our caller should 1163 * already handle this; failure is really an internal error (i.e. bug). 1164 */ 1165 max_needed = SecCmsCipherContextEncryptLength (cc, input_len, final); 1166 PORT_Assert (max_output_len >= max_needed); 1167 if (max_output_len < max_needed) { 1168 /* PORT_SetError (XXX); */ 1169 return SECFailure; 1170 } 1171 1172 bsize = cc->block_size; 1173 padsize = cc->pad_size; 1174 1175 /* 1176 * When no blocking and padding work to do, we can simply call the 1177 * cipher function and we are done. 1178 */ 1179 if (bsize == 0) { 1180 return (*cc->doit)(cc->cx, output, output_len_p, max_output_len, 1181 input, input_len); 1182 } 1183 1184 pcount = cc->pending_count; 1185 pbuf = cc->pending_buf; 1186 1187 output_len = 0; 1188 1189 if (pcount) { 1190 /* 1191 * Try to fill in an entire block, starting with the bytes 1192 * we already have saved away. 1193 */ 1194 while (input_len && pcount < bsize) { 1195 pbuf[pcount++] = *input++; 1196 input_len--; 1197 } 1198 /* 1199 * If we do not have a full block and we know we will be 1200 * called again, then we are done for now. 1201 */ 1202 if (pcount < bsize && !final) { 1203 cc->pending_count = pcount; 1204 if (output_len_p != NULL) 1205 *output_len_p = 0; 1206 return SECSuccess; 1207 } 1208 /* 1209 * If we have a whole block available, encrypt it. 1210 */ 1211 if ((padsize == 0) || (pcount % padsize) == 0) { 1212 rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len, 1213 pbuf, pcount); 1214 if (rv != SECSuccess) 1215 return rv; 1216 1217 /* 1218 * For now anyway, all of our ciphers have the same number of 1219 * bytes of output as they do input. If this ever becomes untrue, 1220 * then sec_PKCS7EncryptLength needs to be made smarter! 1221 */ 1222 PORT_Assert (ofraglen == pcount); 1223 1224 /* 1225 * Account for the bytes now in output. 1226 */ 1227 max_output_len -= ofraglen; 1228 output_len += ofraglen; 1229 output += ofraglen; 1230 1231 pcount = 0; 1232 } 1233 } 1234 1235 if (input_len) { 1236 PORT_Assert (pcount == 0); 1237 1238 blocks = input_len / bsize; 1239 ifraglen = blocks * bsize; 1240 1241 if (ifraglen) { 1242 rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len, 1243 input, ifraglen); 1244 if (rv != SECSuccess) 1245 return rv; 1246 1247 /* 1248 * For now anyway, all of our ciphers have the same number of 1249 * bytes of output as they do input. If this ever becomes untrue, 1250 * then sec_PKCS7EncryptLength needs to be made smarter! 1251 */ 1252 PORT_Assert (ifraglen == ofraglen); 1253 1254 max_output_len -= ofraglen; 1255 output_len += ofraglen; 1256 output += ofraglen; 1257 } 1258 1259 pcount = input_len - ifraglen; 1260 PORT_Assert (pcount < bsize); 1261 if (pcount) 1262 PORT_Memcpy (pbuf, input + ifraglen, pcount); 1263 } 1264 1265 if (final) { 1266 padlen = padsize - (pcount % padsize); 1267 PORT_Memset (pbuf + pcount, padlen, padlen); 1268 rv = (* cc->doit) (cc->cx, output, &ofraglen, max_output_len, 1269 pbuf, pcount+padlen); 1270 if (rv != SECSuccess) 1271 return rv; 1272 1273 /* 1274 * For now anyway, all of our ciphers have the same number of 1275 * bytes of output as they do input. If this ever becomes untrue, 1276 * then sec_PKCS7EncryptLength needs to be made smarter! 1277 */ 1278 PORT_Assert (ofraglen == (pcount+padlen)); 1279 output_len += ofraglen; 1280 } else { 1281 cc->pending_count = pcount; 1282 } 1283 1284 PORT_Assert (output_len_p != NULL || output_len == 0); 1285 if (output_len_p != NULL) 1286 *output_len_p = output_len; 1287 1288 return SECSuccess; 1289 #endif 1290 }