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