lowpbe.c (55518B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "plarena.h" 6 7 #include "seccomon.h" 8 #include "secitem.h" 9 #include "secport.h" 10 #include "hasht.h" 11 #include "pkcs11t.h" 12 #include "blapi.h" 13 #include "hasht.h" 14 #include "secasn1.h" 15 #include "secder.h" 16 #include "lowpbe.h" 17 #include "secoid.h" 18 #include "alghmac.h" 19 #include "softoken.h" 20 #include "secerr.h" 21 #include "pkcs11i.h" 22 23 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) 24 25 /* how much a crypto encrypt/decryption may expand a buffer */ 26 #define MAX_CRYPTO_EXPANSION 64 27 28 /* template for PKCS 5 PBE Parameter. This template has been expanded 29 * based upon the additions in PKCS 12. This should eventually be moved 30 * if RSA updates PKCS 5. 31 */ 32 static const SEC_ASN1Template NSSPKCS5PBEParameterTemplate[] = { 33 { SEC_ASN1_SEQUENCE, 34 0, NULL, sizeof(NSSPKCS5PBEParameter) }, 35 { SEC_ASN1_OCTET_STRING, 36 offsetof(NSSPKCS5PBEParameter, salt) }, 37 { SEC_ASN1_INTEGER, 38 offsetof(NSSPKCS5PBEParameter, iteration) }, 39 { 0 } 40 }; 41 42 static const SEC_ASN1Template NSSPKCS5PKCS12V2PBEParameterTemplate[] = { 43 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) }, 44 { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) }, 45 { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) }, 46 { 0 } 47 }; 48 49 /* PKCS5 v2 */ 50 51 struct nsspkcs5V2PBEParameterStr { 52 SECAlgorithmID keyParams; /* parameters of the key generation */ 53 SECAlgorithmID algParams; /* parameters for the encryption or mac op */ 54 }; 55 56 typedef struct nsspkcs5V2PBEParameterStr nsspkcs5V2PBEParameter; 57 58 static const SEC_ASN1Template NSSPKCS5V2PBES2ParameterTemplate[] = { 59 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(nsspkcs5V2PBEParameter) }, 60 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 61 offsetof(nsspkcs5V2PBEParameter, keyParams), 62 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 63 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 64 offsetof(nsspkcs5V2PBEParameter, algParams), 65 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 66 { 0 } 67 }; 68 69 static const SEC_ASN1Template NSSPKCS5V2PBEParameterTemplate[] = { 70 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) }, 71 /* this is really a choice, but since we don't understand any other 72 * choice, just inline it. */ 73 { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) }, 74 { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) }, 75 { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, keyLength) }, 76 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 77 offsetof(NSSPKCS5PBEParameter, prfAlg), 78 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 79 { 0 } 80 }; 81 82 SECStatus 83 nsspkcs5_HashBuf(const SECHashObject *hashObj, unsigned char *dest, 84 unsigned char *src, int len) 85 { 86 void *ctx; 87 unsigned int retLen; 88 89 ctx = hashObj->create(); 90 if (ctx == NULL) { 91 return SECFailure; 92 } 93 hashObj->begin(ctx); 94 hashObj->update(ctx, src, len); 95 hashObj->end(ctx, dest, &retLen, hashObj->length); 96 hashObj->destroy(ctx, PR_TRUE); 97 return SECSuccess; 98 } 99 100 /* generate bits using any hash 101 */ 102 static SECItem * 103 nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd, 104 int iter, PRBool faulty3DES) 105 { 106 SECItem *hash = NULL, *pre_hash = NULL; 107 SECStatus rv = SECFailure; 108 109 if ((salt == NULL) || (pwd == NULL) || (iter < 0)) { 110 return NULL; 111 } 112 113 hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); 114 pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); 115 116 if ((hash != NULL) && (pre_hash != NULL)) { 117 int i, ph_len; 118 119 ph_len = hashObj->length; 120 if ((salt->len + pwd->len) > hashObj->length) { 121 ph_len = salt->len + pwd->len; 122 } 123 124 rv = SECFailure; 125 126 /* allocate buffers */ 127 hash->len = hashObj->length; 128 hash->data = (unsigned char *)PORT_ZAlloc(hash->len); 129 pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len); 130 131 /* in pbeSHA1TripleDESCBC there was an allocation error that made 132 * it into the caller. We do not want to propagate those errors 133 * further, so we are doing it correctly, but reading the old method. 134 */ 135 if (faulty3DES) { 136 pre_hash->len = ph_len; 137 } else { 138 pre_hash->len = salt->len + pwd->len; 139 } 140 141 /* preform hash */ 142 if ((hash->data != NULL) && (pre_hash->data != NULL)) { 143 rv = SECSuccess; 144 /* check for 0 length password */ 145 if (pwd->len > 0) { 146 PORT_Memcpy(pre_hash->data, pwd->data, pwd->len); 147 } 148 if (salt->len > 0) { 149 PORT_Memcpy((pre_hash->data + pwd->len), salt->data, salt->len); 150 } 151 for (i = 0; ((i < iter) && (rv == SECSuccess)); i++) { 152 rv = nsspkcs5_HashBuf(hashObj, hash->data, 153 pre_hash->data, pre_hash->len); 154 if (rv != SECFailure) { 155 pre_hash->len = hashObj->length; 156 PORT_Memcpy(pre_hash->data, hash->data, hashObj->length); 157 } 158 } 159 } 160 } 161 162 if (pre_hash != NULL) { 163 SECITEM_ZfreeItem(pre_hash, PR_TRUE); 164 } 165 166 if ((rv != SECSuccess) && (hash != NULL)) { 167 SECITEM_ZfreeItem(hash, PR_TRUE); 168 hash = NULL; 169 } 170 171 return hash; 172 } 173 174 /* this bit generation routine is described in PKCS 12 and the proposed 175 * extensions to PKCS 5. an initial hash is generated following the 176 * instructions laid out in PKCS 5. If the number of bits generated is 177 * insufficient, then the method discussed in the proposed extensions to 178 * PKCS 5 in PKCS 12 are used. This extension makes use of the HMAC 179 * function. And the P_Hash function from the TLS standard. 180 */ 181 static SECItem * 182 nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param, 183 SECItem *init_hash, unsigned int bytes_needed) 184 { 185 SECItem *ret_bits = NULL; 186 int hash_size = 0; 187 unsigned int i; 188 unsigned int hash_iter; 189 unsigned int dig_len; 190 SECStatus rv = SECFailure; 191 unsigned char *state = NULL; 192 unsigned int state_len; 193 HMACContext *cx = NULL; 194 195 hash_size = hashObj->length; 196 hash_iter = (bytes_needed + (unsigned int)hash_size - 1) / hash_size; 197 198 /* allocate return buffer */ 199 ret_bits = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); 200 if (ret_bits == NULL) 201 return NULL; 202 ret_bits->data = (unsigned char *)PORT_ZAlloc((hash_iter * hash_size) + 1); 203 ret_bits->len = (hash_iter * hash_size); 204 if (ret_bits->data == NULL) { 205 PORT_Free(ret_bits); 206 return NULL; 207 } 208 209 /* allocate intermediate hash buffer. 8 is for the 8 bytes of 210 * data which are added based on iteration number 211 */ 212 213 if ((unsigned int)hash_size > pbe_param->salt.len) { 214 state_len = hash_size; 215 } else { 216 state_len = pbe_param->salt.len; 217 } 218 state = (unsigned char *)PORT_ZAlloc(state_len); 219 if (state == NULL) { 220 rv = SECFailure; 221 goto loser; 222 } 223 if (pbe_param->salt.len > 0) { 224 PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len); 225 } 226 227 cx = HMAC_Create(hashObj, init_hash->data, init_hash->len, PR_TRUE); 228 if (cx == NULL) { 229 rv = SECFailure; 230 goto loser; 231 } 232 233 for (i = 0; i < hash_iter; i++) { 234 235 /* generate output bits */ 236 HMAC_Begin(cx); 237 HMAC_Update(cx, state, state_len); 238 HMAC_Update(cx, pbe_param->salt.data, pbe_param->salt.len); 239 rv = HMAC_Finish(cx, ret_bits->data + (i * hash_size), 240 &dig_len, hash_size); 241 if (rv != SECSuccess) 242 goto loser; 243 PORT_Assert((unsigned int)hash_size == dig_len); 244 245 /* generate new state */ 246 HMAC_Begin(cx); 247 HMAC_Update(cx, state, state_len); 248 rv = HMAC_Finish(cx, state, &state_len, state_len); 249 if (rv != SECSuccess) 250 goto loser; 251 PORT_Assert(state_len == dig_len); 252 } 253 254 loser: 255 if (state != NULL) 256 PORT_ZFree(state, state_len); 257 HMAC_Destroy(cx, PR_TRUE); 258 259 if (rv != SECSuccess) { 260 SECITEM_ZfreeItem(ret_bits, PR_TRUE); 261 ret_bits = NULL; 262 } 263 264 return ret_bits; 265 } 266 267 /* generate bits for the key and iv determination. if enough bits 268 * are not generated using PKCS 5, then we need to generate more bits 269 * based on the extension proposed in PKCS 12 270 */ 271 static SECItem * 272 nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj, 273 NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PRBool faulty3DES) 274 { 275 SECItem *hash = NULL; 276 SECItem *newHash = NULL; 277 int bytes_needed; 278 int bytes_available; 279 280 bytes_needed = pbe_param->ivLen + pbe_param->keyLen; 281 bytes_available = hashObj->length; 282 283 hash = nsspkcs5_PBKDF1(hashObj, &pbe_param->salt, pwitem, 284 pbe_param->iter, faulty3DES); 285 286 if (hash == NULL) { 287 return NULL; 288 } 289 290 if (bytes_needed <= bytes_available) { 291 return hash; 292 } 293 294 newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed); 295 if (hash != newHash) 296 SECITEM_ZfreeItem(hash, PR_TRUE); 297 return newHash; 298 } 299 300 /* 301 * PBDKDF2 is PKCS #5 v2.0 it's currently not used by NSS 302 */ 303 static void 304 do_xor(unsigned char *dest, unsigned char *src, int len) 305 { 306 /* use byt xor, not all platforms are happy about inaligned 307 * integer fetches */ 308 while (len--) { 309 *dest = *dest ^ *src; 310 dest++; 311 src++; 312 } 313 } 314 315 static SECStatus 316 nsspkcs5_PBKDF2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt, 317 int iterations, unsigned int i, unsigned char *T) 318 { 319 int j; 320 HMACContext *cx = NULL; 321 unsigned int hLen = hashobj->length; 322 SECStatus rv = SECFailure; 323 unsigned char *last = NULL; 324 unsigned int lastLength = salt->len + 4; 325 unsigned int lastBufLength; 326 327 cx = HMAC_Create(hashobj, pwitem->data, pwitem->len, PR_FALSE); 328 if (cx == NULL) { 329 goto loser; 330 } 331 PORT_Memset(T, 0, hLen); 332 lastBufLength = PR_MAX(lastLength, hLen); 333 last = PORT_Alloc(lastBufLength); 334 if (last == NULL) { 335 goto loser; 336 } 337 PORT_Memcpy(last, salt->data, salt->len); 338 last[salt->len] = (i >> 24) & 0xff; 339 last[salt->len + 1] = (i >> 16) & 0xff; 340 last[salt->len + 2] = (i >> 8) & 0xff; 341 last[salt->len + 3] = i & 0xff; 342 343 /* NOTE: we need at least one iteration to return success! */ 344 for (j = 0; j < iterations; j++) { 345 HMAC_Begin(cx); 346 HMAC_Update(cx, last, lastLength); 347 rv = HMAC_Finish(cx, last, &lastLength, hLen); 348 if (rv != SECSuccess) { 349 break; 350 } 351 do_xor(T, last, hLen); 352 } 353 loser: 354 if (cx) { 355 HMAC_Destroy(cx, PR_TRUE); 356 } 357 if (last) { 358 PORT_ZFree(last, lastBufLength); 359 } 360 return rv; 361 } 362 363 static SECItem * 364 nsspkcs5_PBKDF2(const SECHashObject *hashobj, NSSPKCS5PBEParameter *pbe_param, 365 SECItem *pwitem) 366 { 367 int iterations = pbe_param->iter; 368 int bytesNeeded = pbe_param->keyLen; 369 unsigned int dkLen = bytesNeeded; 370 unsigned int hLen = hashobj->length; 371 unsigned int nblocks = (dkLen + hLen - 1) / hLen; 372 unsigned int i; 373 unsigned char *rp; 374 unsigned char *T = NULL; 375 SECItem *result = NULL; 376 SECItem *salt = &pbe_param->salt; 377 SECStatus rv = SECFailure; 378 379 result = SECITEM_AllocItem(NULL, NULL, nblocks * hLen); 380 if (result == NULL) { 381 return NULL; 382 } 383 384 T = PORT_Alloc(hLen); 385 if (T == NULL) { 386 goto loser; 387 } 388 389 for (i = 1, rp = result->data; i <= nblocks; i++, rp += hLen) { 390 rv = nsspkcs5_PBKDF2_F(hashobj, pwitem, salt, iterations, i, T); 391 if (rv != SECSuccess) { 392 break; 393 } 394 PORT_Memcpy(rp, T, hLen); 395 } 396 397 loser: 398 if (T) { 399 PORT_ZFree(T, hLen); 400 } 401 if (rv != SECSuccess) { 402 SECITEM_ZfreeItem(result, PR_TRUE); 403 result = NULL; 404 } else { 405 result->len = dkLen; 406 } 407 408 return result; 409 } 410 411 #define NSSPBE_ROUNDUP(x, y) ((((x) + ((y)-1)) / (y)) * (y)) 412 #define NSSPBE_MIN(x, y) ((x) < (y) ? (x) : (y)) 413 /* 414 * This is the extended PBE function defined by the final PKCS #12 spec. 415 */ 416 static SECItem * 417 nsspkcs5_PKCS12PBE(const SECHashObject *hashObject, 418 NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, 419 PBEBitGenID bitGenPurpose, unsigned int bytesNeeded) 420 { 421 PLArenaPool *arena = NULL; 422 unsigned int SLen, PLen; 423 unsigned int hashLength = hashObject->length; 424 unsigned char *S, *P; 425 SECItem *A = NULL, B, D, I; 426 SECItem *salt = &pbe_param->salt; 427 unsigned int c, i = 0; 428 unsigned int hashLen; 429 int iter; 430 unsigned char *iterBuf; 431 void *hash = NULL; 432 unsigned int bufferLength; 433 434 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 435 if (!arena) { 436 return NULL; 437 } 438 439 /* how many hash object lengths are needed */ 440 c = (bytesNeeded + (hashLength - 1)) / hashLength; 441 442 /* 64 if 0 < hashLength <= 32, 128 if 32 < hashLength <= 64 */ 443 bufferLength = NSSPBE_ROUNDUP(hashLength * 2, 64); 444 445 /* initialize our buffers */ 446 D.len = bufferLength; 447 /* B and D are the same length, use one alloc go get both */ 448 D.data = (unsigned char *)PORT_ArenaZAlloc(arena, D.len * 2); 449 B.len = D.len; 450 B.data = D.data + D.len; 451 452 /* if all goes well, A will be returned, so don't use our temp arena */ 453 A = SECITEM_AllocItem(NULL, NULL, c * hashLength); 454 if (A == NULL) { 455 goto loser; 456 } 457 458 SLen = NSSPBE_ROUNDUP(salt->len, bufferLength); 459 PLen = NSSPBE_ROUNDUP(pwitem->len, bufferLength); 460 I.len = SLen + PLen; 461 I.data = (unsigned char *)PORT_ArenaZAlloc(arena, I.len); 462 if (I.data == NULL) { 463 goto loser; 464 } 465 466 /* S & P are only used to initialize I */ 467 S = I.data; 468 P = S + SLen; 469 470 PORT_Memset(D.data, (char)bitGenPurpose, D.len); 471 if (SLen) { 472 for (i = 0; i < SLen; i += salt->len) { 473 PORT_Memcpy(S + i, salt->data, NSSPBE_MIN(SLen - i, salt->len)); 474 } 475 } 476 if (PLen) { 477 for (i = 0; i < PLen; i += pwitem->len) { 478 PORT_Memcpy(P + i, pwitem->data, NSSPBE_MIN(PLen - i, pwitem->len)); 479 } 480 } 481 482 iterBuf = (unsigned char *)PORT_ArenaZAlloc(arena, hashLength); 483 if (iterBuf == NULL) { 484 goto loser; 485 } 486 487 hash = hashObject->create(); 488 if (!hash) { 489 goto loser; 490 } 491 /* calculate the PBE now */ 492 for (i = 0; i < c; i++) { 493 int Bidx; /* must be signed or the for loop won't terminate */ 494 unsigned int k, j; 495 unsigned char *Ai = A->data + i * hashLength; 496 497 for (iter = 0; iter < pbe_param->iter; iter++) { 498 hashObject->begin(hash); 499 500 if (iter) { 501 hashObject->update(hash, iterBuf, hashLen); 502 } else { 503 hashObject->update(hash, D.data, D.len); 504 hashObject->update(hash, I.data, I.len); 505 } 506 507 hashObject->end(hash, iterBuf, &hashLen, hashObject->length); 508 if (hashLen != hashObject->length) { 509 break; 510 } 511 } 512 513 PORT_Memcpy(Ai, iterBuf, hashLength); 514 for (Bidx = 0; Bidx < (int)B.len; Bidx += hashLength) { 515 PORT_Memcpy(B.data + Bidx, iterBuf, NSSPBE_MIN(B.len - Bidx, hashLength)); 516 } 517 518 k = I.len / B.len; 519 for (j = 0; j < k; j++) { 520 unsigned int q, carryBit; 521 unsigned char *Ij = I.data + j * B.len; 522 523 /* (Ij = Ij+B+1) */ 524 for (Bidx = (B.len - 1), q = 1, carryBit = 0; Bidx >= 0; Bidx--, q = 0) { 525 q += (unsigned int)Ij[Bidx]; 526 q += (unsigned int)B.data[Bidx]; 527 q += carryBit; 528 529 carryBit = (q > 0xff); 530 Ij[Bidx] = (unsigned char)(q & 0xff); 531 } 532 } 533 } 534 loser: 535 if (hash) { 536 hashObject->destroy(hash, PR_TRUE); 537 } 538 if (arena) { 539 PORT_FreeArena(arena, PR_TRUE); 540 } 541 542 if (A) { 543 /* if i != c, then we didn't complete the loop above and must of failed 544 * somwhere along the way */ 545 if (i != c) { 546 SECITEM_ZfreeItem(A, PR_TRUE); 547 A = NULL; 548 } else { 549 A->len = bytesNeeded; 550 } 551 } 552 553 return A; 554 } 555 556 struct KDFCacheItemStr { 557 SECItem *hash; 558 SECItem *salt; 559 SECItem *pwItem; 560 HASH_HashType hashType; 561 int iterations; 562 int keyLen; 563 }; 564 typedef struct KDFCacheItemStr KDFCacheItem; 565 566 /* Bug 1606992 - Cache the hash result for the common case that we're 567 * asked to repeatedly compute the key for the same password item, 568 * hash, iterations and salt. */ 569 #define KDF2_CACHE_COUNT 150 570 static struct { 571 PZLock *lock; 572 struct { 573 KDFCacheItem common; 574 int ivLen; 575 PRBool faulty3DES; 576 } cacheKDF1; 577 struct { 578 KDFCacheItem common[KDF2_CACHE_COUNT]; 579 int next; 580 } cacheKDF2; 581 } PBECache; 582 583 void 584 sftk_PBELockInit(void) 585 { 586 if (!PBECache.lock) { 587 PBECache.lock = PZ_NewLock(nssIPBECacheLock); 588 } 589 } 590 591 static void 592 sftk_clearPBECommonCacheItemsLocked(KDFCacheItem *item) 593 { 594 if (item->hash) { 595 SECITEM_ZfreeItem(item->hash, PR_TRUE); 596 item->hash = NULL; 597 } 598 if (item->salt) { 599 SECITEM_ZfreeItem(item->salt, PR_TRUE); 600 item->salt = NULL; 601 } 602 if (item->pwItem) { 603 SECITEM_ZfreeItem(item->pwItem, PR_TRUE); 604 item->pwItem = NULL; 605 } 606 } 607 608 static void 609 sftk_setPBECommonCacheItemsKDFLocked(KDFCacheItem *cacheItem, 610 const SECItem *hash, 611 const NSSPKCS5PBEParameter *pbe_param, 612 const SECItem *pwItem) 613 { 614 cacheItem->hash = SECITEM_DupItem(hash); 615 cacheItem->hashType = pbe_param->hashType; 616 cacheItem->iterations = pbe_param->iter; 617 cacheItem->keyLen = pbe_param->keyLen; 618 cacheItem->salt = SECITEM_DupItem(&pbe_param->salt); 619 cacheItem->pwItem = SECITEM_DupItem(pwItem); 620 } 621 622 static void 623 sftk_setPBECacheKDF2(const SECItem *hash, 624 const NSSPKCS5PBEParameter *pbe_param, 625 const SECItem *pwItem) 626 { 627 PZ_Lock(PBECache.lock); 628 KDFCacheItem *next = &PBECache.cacheKDF2.common[PBECache.cacheKDF2.next]; 629 630 sftk_clearPBECommonCacheItemsLocked(next); 631 632 sftk_setPBECommonCacheItemsKDFLocked(next, hash, pbe_param, pwItem); 633 PBECache.cacheKDF2.next++; 634 if (PBECache.cacheKDF2.next >= KDF2_CACHE_COUNT) { 635 PBECache.cacheKDF2.next = 0; 636 } 637 638 PZ_Unlock(PBECache.lock); 639 } 640 641 static void 642 sftk_setPBECacheKDF1(const SECItem *hash, 643 const NSSPKCS5PBEParameter *pbe_param, 644 const SECItem *pwItem, 645 PRBool faulty3DES) 646 { 647 PZ_Lock(PBECache.lock); 648 649 sftk_clearPBECommonCacheItemsLocked(&PBECache.cacheKDF1.common); 650 651 sftk_setPBECommonCacheItemsKDFLocked(&PBECache.cacheKDF1.common, 652 hash, pbe_param, pwItem); 653 PBECache.cacheKDF1.faulty3DES = faulty3DES; 654 PBECache.cacheKDF1.ivLen = pbe_param->ivLen; 655 656 PZ_Unlock(PBECache.lock); 657 } 658 659 static PRBool 660 sftk_comparePBECommonCacheItemLocked(const KDFCacheItem *cacheItem, 661 const NSSPKCS5PBEParameter *pbe_param, 662 const SECItem *pwItem) 663 { 664 return (cacheItem->hash && 665 cacheItem->salt && 666 cacheItem->pwItem && 667 pbe_param->hashType == cacheItem->hashType && 668 pbe_param->iter == cacheItem->iterations && 669 pbe_param->keyLen == cacheItem->keyLen && 670 SECITEM_ItemsAreEqual(&pbe_param->salt, cacheItem->salt) && 671 SECITEM_ItemsAreEqual(pwItem, cacheItem->pwItem)); 672 } 673 674 static SECItem * 675 sftk_getPBECacheKDF2(const NSSPKCS5PBEParameter *pbe_param, 676 const SECItem *pwItem) 677 { 678 SECItem *result = NULL; 679 int i; 680 681 PZ_Lock(PBECache.lock); 682 for (i = 0; i < KDF2_CACHE_COUNT; i++) { 683 const KDFCacheItem *cacheItem = &PBECache.cacheKDF2.common[i]; 684 if (sftk_comparePBECommonCacheItemLocked(cacheItem, 685 pbe_param, pwItem)) { 686 result = SECITEM_DupItem(cacheItem->hash); 687 break; 688 } 689 } 690 PZ_Unlock(PBECache.lock); 691 692 return result; 693 } 694 695 static SECItem * 696 sftk_getPBECacheKDF1(const NSSPKCS5PBEParameter *pbe_param, 697 const SECItem *pwItem, 698 PRBool faulty3DES) 699 { 700 SECItem *result = NULL; 701 const KDFCacheItem *cacheItem = &PBECache.cacheKDF1.common; 702 703 PZ_Lock(PBECache.lock); 704 if (sftk_comparePBECommonCacheItemLocked(cacheItem, pbe_param, pwItem) && 705 PBECache.cacheKDF1.faulty3DES == faulty3DES && 706 PBECache.cacheKDF1.ivLen == pbe_param->ivLen) { 707 result = SECITEM_DupItem(cacheItem->hash); 708 } 709 PZ_Unlock(PBECache.lock); 710 711 return result; 712 } 713 714 void 715 sftk_PBELockShutdown(void) 716 { 717 int i; 718 if (PBECache.lock) { 719 PZ_DestroyLock(PBECache.lock); 720 PBECache.lock = 0; 721 } 722 sftk_clearPBECommonCacheItemsLocked(&PBECache.cacheKDF1.common); 723 for (i = 0; i < KDF2_CACHE_COUNT; i++) { 724 sftk_clearPBECommonCacheItemsLocked(&PBECache.cacheKDF2.common[i]); 725 } 726 PBECache.cacheKDF2.next = 0; 727 } 728 729 /* 730 * generate key as per PKCS 5 731 */ 732 SECItem * 733 nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, 734 SECItem *iv, PRBool faulty3DES) 735 { 736 SECItem *hash = NULL, *key = NULL; 737 const SECHashObject *hashObj; 738 PRBool getIV = PR_FALSE; 739 740 if ((pbe_param == NULL) || (pwitem == NULL)) { 741 return NULL; 742 } 743 744 key = SECITEM_AllocItem(NULL, NULL, pbe_param->keyLen); 745 if (key == NULL) { 746 return NULL; 747 } 748 749 if (iv && (pbe_param->ivLen) && (iv->data == NULL)) { 750 getIV = PR_TRUE; 751 iv->data = (unsigned char *)PORT_Alloc(pbe_param->ivLen); 752 if (iv->data == NULL) { 753 goto loser; 754 } 755 iv->len = pbe_param->ivLen; 756 } 757 758 hashObj = HASH_GetRawHashObject(pbe_param->hashType); 759 switch (pbe_param->pbeType) { 760 case NSSPKCS5_PBKDF1: 761 hash = sftk_getPBECacheKDF1(pbe_param, pwitem, faulty3DES); 762 if (!hash) { 763 hash = nsspkcs5_PBKDF1Extended(hashObj, pbe_param, pwitem, faulty3DES); 764 sftk_setPBECacheKDF1(hash, pbe_param, pwitem, faulty3DES); 765 } 766 if (hash == NULL) { 767 goto loser; 768 } 769 PORT_Assert(hash->len >= key->len + (getIV ? iv->len : 0)); 770 if (getIV) { 771 PORT_Memcpy(iv->data, hash->data + (hash->len - iv->len), iv->len); 772 } 773 774 break; 775 case NSSPKCS5_PBKDF2: 776 hash = sftk_getPBECacheKDF2(pbe_param, pwitem); 777 if (!hash) { 778 hash = nsspkcs5_PBKDF2(hashObj, pbe_param, pwitem); 779 sftk_setPBECacheKDF2(hash, pbe_param, pwitem); 780 } 781 if (getIV) { 782 PORT_Memcpy(iv->data, pbe_param->ivData, iv->len); 783 } 784 break; 785 case NSSPKCS5_PKCS12_V2: 786 if (getIV) { 787 hash = nsspkcs5_PKCS12PBE(hashObj, pbe_param, pwitem, 788 pbeBitGenCipherIV, iv->len); 789 if (hash == NULL) { 790 goto loser; 791 } 792 PORT_Memcpy(iv->data, hash->data, iv->len); 793 SECITEM_ZfreeItem(hash, PR_TRUE); 794 hash = NULL; 795 } 796 hash = nsspkcs5_PKCS12PBE(hashObj, pbe_param, pwitem, 797 pbe_param->keyID, key->len); 798 default: 799 break; 800 } 801 802 if (hash == NULL) { 803 goto loser; 804 } 805 806 PORT_Memcpy(key->data, hash->data, key->len); 807 808 SECITEM_ZfreeItem(hash, PR_TRUE); 809 return key; 810 811 loser: 812 if (getIV && iv->data) { 813 PORT_ZFree(iv->data, iv->len); 814 iv->data = NULL; 815 } 816 817 SECITEM_ZfreeItem(key, PR_TRUE); 818 return NULL; 819 } 820 821 #define MAX_IV_LENGTH 64 822 /* get a random IV into the parameters */ 823 static SECStatus 824 nsspkcs5_SetIVParam(NSSPKCS5PBEParameter *pbe_param, int ivLen) 825 { 826 SECStatus rv; 827 SECItem derIV; 828 SECItem iv; 829 SECItem *dummy = NULL; 830 unsigned char ivData[MAX_IV_LENGTH]; 831 832 PORT_Assert(ivLen <= MAX_IV_LENGTH); 833 834 /* Because of a bug in the decode section, the IV's not are expected 835 * to be der encoded, but still need to parse as if they were der data. 836 * because we want to be compatible with existing versions of nss that 837 * have that bug, create an IV that looks like der data. That still 838 * leaves 14 bytes of entropy in the IV */ 839 rv = RNG_GenerateGlobalRandomBytes(ivData, ivLen - 2); 840 if (rv != SECSuccess) { 841 return SECFailure; 842 } 843 derIV.data = NULL; 844 derIV.len = 0; 845 iv.data = ivData; 846 iv.len = ivLen - 2; 847 dummy = SEC_ASN1EncodeItem(pbe_param->poolp, &derIV, &iv, 848 SEC_ASN1_GET(SEC_OctetStringTemplate)); 849 if (dummy == NULL) { 850 return SECFailure; 851 } 852 pbe_param->ivData = derIV.data; 853 pbe_param->ivLen = derIV.len; 854 PORT_Assert(pbe_param->ivLen == ivLen); 855 return SECSuccess; 856 } 857 858 static SECStatus 859 nsspkcs5_FillInParam(SECOidTag algorithm, HASH_HashType hashType, 860 NSSPKCS5PBEParameter *pbe_param) 861 { 862 PRBool skipType = PR_FALSE; 863 SECStatus rv; 864 865 pbe_param->keyLen = 5; 866 pbe_param->ivLen = 8; 867 pbe_param->hashType = hashType; 868 pbe_param->pbeType = NSSPKCS5_PBKDF1; 869 pbe_param->encAlg = SEC_OID_RC2_CBC; 870 pbe_param->is2KeyDES = PR_FALSE; 871 switch (algorithm) { 872 /* DES3 Algorithms */ 873 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: 874 pbe_param->is2KeyDES = PR_TRUE; 875 pbe_param->pbeType = NSSPKCS5_PKCS12_V2; 876 pbe_param->keyLen = 16; 877 pbe_param->encAlg = SEC_OID_DES_EDE3_CBC; 878 break; 879 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: 880 pbe_param->pbeType = NSSPKCS5_PKCS12_V2; 881 pbe_param->keyLen = 24; 882 pbe_param->encAlg = SEC_OID_DES_EDE3_CBC; 883 break; 884 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: 885 pbe_param->keyLen = 24; 886 pbe_param->encAlg = SEC_OID_DES_EDE3_CBC; 887 break; 888 889 /* DES Algorithms */ 890 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: 891 pbe_param->hashType = HASH_AlgMD2; 892 goto finish_des; 893 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: 894 pbe_param->hashType = HASH_AlgMD5; 895 /* fall through */ 896 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: 897 finish_des: 898 pbe_param->keyLen = 8; 899 pbe_param->encAlg = SEC_OID_DES_CBC; 900 break; 901 902 #ifndef NSS_DISABLE_DEPRECATED_RC2 903 /* RC2 Algorithms */ 904 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 905 pbe_param->keyLen = 16; 906 /* fall through */ 907 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 908 pbe_param->pbeType = NSSPKCS5_PKCS12_V2; 909 break; 910 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 911 pbe_param->keyLen = 16; 912 /* fall through */ 913 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 914 break; 915 #endif 916 917 /* RC4 algorithms */ 918 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: 919 skipType = PR_TRUE; 920 /* fall through */ 921 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: 922 pbe_param->keyLen = 16; 923 /* fall through */ 924 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: 925 if (!skipType) { 926 pbe_param->pbeType = NSSPKCS5_PKCS12_V2; 927 } 928 /* fall through */ 929 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: 930 pbe_param->ivLen = 0; 931 pbe_param->encAlg = SEC_OID_RC4; 932 break; 933 934 case SEC_OID_PKCS5_PBKDF2: 935 case SEC_OID_PKCS5_PBES2: 936 case SEC_OID_PKCS5_PBMAC1: 937 /* everything else will be filled in by the template */ 938 pbe_param->ivLen = 0; 939 pbe_param->pbeType = NSSPKCS5_PBKDF2; 940 pbe_param->encAlg = SEC_OID_PKCS5_PBKDF2; 941 pbe_param->keyLen = 0; /* needs to be set by caller after return */ 942 break; 943 /* AES uses PBKDF2 */ 944 case SEC_OID_AES_128_CBC: 945 rv = nsspkcs5_SetIVParam(pbe_param, 16); 946 if (rv != SECSuccess) { 947 return rv; 948 } 949 pbe_param->ivLen = 16; 950 pbe_param->pbeType = NSSPKCS5_PBKDF2; 951 pbe_param->encAlg = algorithm; 952 pbe_param->keyLen = 128 / 8; 953 break; 954 case SEC_OID_AES_192_CBC: 955 rv = nsspkcs5_SetIVParam(pbe_param, 16); 956 if (rv != SECSuccess) { 957 return rv; 958 } 959 pbe_param->pbeType = NSSPKCS5_PBKDF2; 960 pbe_param->encAlg = algorithm; 961 pbe_param->keyLen = 192 / 8; 962 break; 963 case SEC_OID_AES_256_CBC: 964 rv = nsspkcs5_SetIVParam(pbe_param, 16); 965 if (rv != SECSuccess) { 966 return rv; 967 } 968 pbe_param->pbeType = NSSPKCS5_PBKDF2; 969 pbe_param->encAlg = algorithm; 970 pbe_param->keyLen = 256 / 8; 971 break; 972 case SEC_OID_AES_128_KEY_WRAP: 973 pbe_param->ivLen = 0; 974 pbe_param->pbeType = NSSPKCS5_PBKDF2; 975 pbe_param->encAlg = algorithm; 976 pbe_param->keyLen = 128 / 8; 977 break; 978 case SEC_OID_AES_192_KEY_WRAP: 979 pbe_param->ivLen = 0; 980 pbe_param->pbeType = NSSPKCS5_PBKDF2; 981 pbe_param->encAlg = algorithm; 982 pbe_param->keyLen = 192 / 8; 983 break; 984 case SEC_OID_AES_256_KEY_WRAP: 985 pbe_param->ivLen = 0; 986 pbe_param->pbeType = NSSPKCS5_PBKDF2; 987 pbe_param->encAlg = algorithm; 988 pbe_param->keyLen = 256 / 8; 989 break; 990 991 default: 992 return SECFailure; 993 } 994 if (pbe_param->pbeType == NSSPKCS5_PBKDF2) { 995 SECOidTag prfAlg = HASH_HMACOidFromHash(pbe_param->hashType); 996 if (prfAlg == SEC_OID_UNKNOWN) { 997 return SECFailure; 998 } 999 rv = SECOID_SetAlgorithmID(pbe_param->poolp, &pbe_param->prfAlg, 1000 prfAlg, NULL); 1001 if (rv != SECSuccess) { 1002 return rv; 1003 } 1004 } 1005 return SECSuccess; 1006 } 1007 1008 /* decode the algid and generate a PKCS 5 parameter from it 1009 */ 1010 NSSPKCS5PBEParameter * 1011 nsspkcs5_NewParam(SECOidTag alg, HASH_HashType hashType, SECItem *salt, 1012 int iterationCount) 1013 { 1014 PLArenaPool *arena = NULL; 1015 NSSPKCS5PBEParameter *pbe_param = NULL; 1016 SECStatus rv = SECFailure; 1017 1018 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 1019 if (arena == NULL) 1020 return NULL; 1021 1022 /* allocate memory for the parameter */ 1023 pbe_param = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena, 1024 sizeof(NSSPKCS5PBEParameter)); 1025 1026 if (pbe_param == NULL) { 1027 goto loser; 1028 } 1029 1030 pbe_param->poolp = arena; 1031 1032 rv = nsspkcs5_FillInParam(alg, hashType, pbe_param); 1033 if (rv != SECSuccess) { 1034 goto loser; 1035 } 1036 1037 pbe_param->iter = iterationCount; 1038 if (salt) { 1039 rv = SECITEM_CopyItem(arena, &pbe_param->salt, salt); 1040 } 1041 1042 /* default key gen */ 1043 pbe_param->keyID = pbeBitGenCipherKey; 1044 1045 loser: 1046 if (rv != SECSuccess) { 1047 PORT_FreeArena(arena, PR_TRUE); 1048 pbe_param = NULL; 1049 } 1050 1051 return pbe_param; 1052 } 1053 1054 /* 1055 * find the hash type needed to implement a specific HMAC. 1056 * OID definitions are from pkcs 5 v2.0 and 2.1 1057 */ 1058 HASH_HashType 1059 HASH_FromHMACOid(SECOidTag hmac) 1060 { 1061 switch (hmac) { 1062 case SEC_OID_HMAC_SHA1: 1063 return HASH_AlgSHA1; 1064 case SEC_OID_HMAC_SHA256: 1065 return HASH_AlgSHA256; 1066 case SEC_OID_HMAC_SHA384: 1067 return HASH_AlgSHA384; 1068 case SEC_OID_HMAC_SHA512: 1069 return HASH_AlgSHA512; 1070 case SEC_OID_HMAC_SHA224: 1071 default: 1072 break; 1073 } 1074 return HASH_AlgNULL; 1075 } 1076 1077 SECOidTag 1078 HASH_HMACOidFromHash(HASH_HashType hashType) 1079 { 1080 switch (hashType) { 1081 case HASH_AlgSHA1: 1082 return SEC_OID_HMAC_SHA1; 1083 case HASH_AlgSHA256: 1084 return SEC_OID_HMAC_SHA256; 1085 case HASH_AlgSHA384: 1086 return SEC_OID_HMAC_SHA384; 1087 case HASH_AlgSHA512: 1088 return SEC_OID_HMAC_SHA512; 1089 case HASH_AlgSHA224: 1090 return SEC_OID_HMAC_SHA224; 1091 case HASH_AlgMD2: 1092 case HASH_AlgMD5: 1093 case HASH_AlgTOTAL: 1094 default: 1095 break; 1096 } 1097 return SEC_OID_UNKNOWN; 1098 } 1099 1100 /* decode the algid and generate a PKCS 5 parameter from it 1101 */ 1102 NSSPKCS5PBEParameter * 1103 nsspkcs5_AlgidToParam(SECAlgorithmID *algid) 1104 { 1105 NSSPKCS5PBEParameter *pbe_param = NULL; 1106 nsspkcs5V2PBEParameter pbev2_param; 1107 SECOidTag algorithm; 1108 SECStatus rv = SECFailure; 1109 1110 if (algid == NULL) { 1111 return NULL; 1112 } 1113 1114 algorithm = SECOID_GetAlgorithmTag(algid); 1115 if (algorithm == SEC_OID_UNKNOWN) { 1116 goto loser; 1117 } 1118 1119 pbe_param = nsspkcs5_NewParam(algorithm, HASH_AlgSHA1, NULL, 1); 1120 if (pbe_param == NULL) { 1121 goto loser; 1122 } 1123 1124 /* decode parameter */ 1125 rv = SECFailure; 1126 switch (pbe_param->pbeType) { 1127 case NSSPKCS5_PBKDF1: 1128 rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, 1129 NSSPKCS5PBEParameterTemplate, &algid->parameters); 1130 break; 1131 case NSSPKCS5_PKCS12_V2: 1132 rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, 1133 NSSPKCS5PKCS12V2PBEParameterTemplate, &algid->parameters); 1134 break; 1135 case NSSPKCS5_PBKDF2: 1136 PORT_Memset(&pbev2_param, 0, sizeof(pbev2_param)); 1137 /* just the PBE */ 1138 if (algorithm == SEC_OID_PKCS5_PBKDF2) { 1139 rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, 1140 NSSPKCS5V2PBEParameterTemplate, &algid->parameters); 1141 } else { 1142 /* PBE data an others */ 1143 rv = SEC_ASN1DecodeItem(pbe_param->poolp, &pbev2_param, 1144 NSSPKCS5V2PBES2ParameterTemplate, &algid->parameters); 1145 if (rv != SECSuccess) { 1146 break; 1147 } 1148 pbe_param->encAlg = SECOID_GetAlgorithmTag(&pbev2_param.algParams); 1149 rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param, 1150 NSSPKCS5V2PBEParameterTemplate, 1151 &pbev2_param.keyParams.parameters); 1152 if (rv != SECSuccess) { 1153 break; 1154 } 1155 pbe_param->keyLen = DER_GetInteger(&pbe_param->keyLength); 1156 } 1157 /* we we are encrypting, save any iv's */ 1158 if (algorithm == SEC_OID_PKCS5_PBES2) { 1159 pbe_param->ivLen = pbev2_param.algParams.parameters.len; 1160 pbe_param->ivData = pbev2_param.algParams.parameters.data; 1161 } 1162 pbe_param->hashType = 1163 HASH_FromHMACOid(SECOID_GetAlgorithmTag(&pbe_param->prfAlg)); 1164 if (pbe_param->hashType == HASH_AlgNULL) { 1165 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1166 rv = SECFailure; 1167 } 1168 break; 1169 } 1170 1171 loser: 1172 PORT_Memset(&pbev2_param, 0, sizeof(pbev2_param)); 1173 if (rv == SECSuccess) { 1174 pbe_param->iter = DER_GetInteger(&pbe_param->iteration); 1175 } else { 1176 nsspkcs5_DestroyPBEParameter(pbe_param); 1177 pbe_param = NULL; 1178 } 1179 1180 return pbe_param; 1181 } 1182 1183 /* destroy a pbe parameter. it assumes that the parameter was 1184 * generated using the appropriate create function and therefor 1185 * contains an arena pool. 1186 */ 1187 void 1188 nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param) 1189 { 1190 if (pbe_param != NULL) { 1191 PORT_FreeArena(pbe_param->poolp, PR_TRUE); 1192 } 1193 } 1194 1195 /* crypto routines */ 1196 /* perform DES encryption and decryption. these routines are called 1197 * by nsspkcs5_CipherData. In the case of an error, NULL is returned. 1198 */ 1199 static SECItem * 1200 sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des, 1201 PRBool encrypt) 1202 { 1203 SECItem *dest; 1204 SECItem *dup_src; 1205 CK_RV crv = CKR_DEVICE_ERROR; 1206 int error; 1207 SECStatus rv = SECFailure; 1208 DESContext *ctxt; 1209 unsigned int pad; 1210 1211 if ((src == NULL) || (key == NULL) || (iv == NULL)) { 1212 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1213 return NULL; 1214 } 1215 1216 dup_src = SECITEM_DupItem(src); 1217 if (dup_src == NULL) { 1218 return NULL; 1219 } 1220 1221 if (encrypt != PR_FALSE) { 1222 void *dummy; 1223 1224 dummy = CBC_PadBuffer(NULL, dup_src->data, 1225 dup_src->len, &dup_src->len, DES_BLOCK_SIZE); 1226 if (dummy == NULL) { 1227 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1228 return NULL; 1229 } 1230 dup_src->data = (unsigned char *)dummy; 1231 } 1232 1233 dest = SECITEM_AllocItem(NULL, NULL, dup_src->len + MAX_CRYPTO_EXPANSION); 1234 if (dest == NULL) { 1235 goto loser; 1236 } 1237 ctxt = DES_CreateContext(key->data, iv->data, 1238 (triple_des ? NSS_DES_EDE3_CBC : NSS_DES_CBC), 1239 encrypt); 1240 if (ctxt == NULL) { 1241 goto loser; 1242 } 1243 rv = (encrypt ? DES_Encrypt : DES_Decrypt)( 1244 ctxt, dest->data, &dest->len, 1245 dest->len, dup_src->data, dup_src->len); 1246 1247 crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; 1248 error = PORT_GetError(); 1249 1250 /* remove padding */ 1251 if ((encrypt == PR_FALSE) && (rv == SECSuccess)) { 1252 crv = sftk_CheckCBCPadding(dest->data, dest->len, DES_BLOCK_SIZE, &pad); 1253 dest->len = PORT_CT_SEL(sftk_CKRVToMask(crv), dest->len - pad, dest->len); 1254 PORT_SetError(PORT_CT_SEL(sftk_CKRVToMask(crv), error, SEC_ERROR_BAD_PASSWORD)); 1255 } 1256 DES_DestroyContext(ctxt, PR_TRUE); 1257 1258 loser: 1259 if (crv != CKR_OK) { 1260 if (dest != NULL) { 1261 SECITEM_ZfreeItem(dest, PR_TRUE); 1262 } 1263 dest = NULL; 1264 } 1265 1266 if (dup_src != NULL) { 1267 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1268 } 1269 1270 return dest; 1271 } 1272 1273 /* perform aes encryption/decryption if an error occurs, NULL is returned 1274 */ 1275 static SECItem * 1276 sec_pkcs5_aes(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des, 1277 PRBool encrypt) 1278 { 1279 SECItem *dest; 1280 SECItem *dup_src; 1281 CK_RV crv = CKR_DEVICE_ERROR; 1282 int error; 1283 SECStatus rv = SECFailure; 1284 AESContext *ctxt; 1285 unsigned int pad; 1286 1287 if ((src == NULL) || (key == NULL) || (iv == NULL)) { 1288 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1289 return NULL; 1290 } 1291 1292 dup_src = SECITEM_DupItem(src); 1293 if (dup_src == NULL) { 1294 return NULL; 1295 } 1296 1297 if (encrypt != PR_FALSE) { 1298 void *dummy; 1299 1300 dummy = CBC_PadBuffer(NULL, dup_src->data, 1301 dup_src->len, &dup_src->len, AES_BLOCK_SIZE); 1302 if (dummy == NULL) { 1303 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1304 return NULL; 1305 } 1306 dup_src->data = (unsigned char *)dummy; 1307 } 1308 1309 dest = SECITEM_AllocItem(NULL, NULL, dup_src->len + MAX_CRYPTO_EXPANSION); 1310 if (dest == NULL) { 1311 goto loser; 1312 } 1313 ctxt = AES_CreateContext(key->data, iv->data, NSS_AES_CBC, 1314 encrypt, key->len, AES_BLOCK_SIZE); 1315 if (ctxt == NULL) { 1316 goto loser; 1317 } 1318 rv = (encrypt ? AES_Encrypt : AES_Decrypt)( 1319 ctxt, dest->data, &dest->len, 1320 dest->len, dup_src->data, dup_src->len); 1321 1322 crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; 1323 error = PORT_GetError(); 1324 1325 /* remove padding */ 1326 if ((encrypt == PR_FALSE) && (rv == SECSuccess)) { 1327 crv = sftk_CheckCBCPadding(dest->data, dest->len, AES_BLOCK_SIZE, &pad); 1328 dest->len = PORT_CT_SEL(sftk_CKRVToMask(crv), dest->len - pad, dest->len); 1329 PORT_SetError(PORT_CT_SEL(sftk_CKRVToMask(crv), error, SEC_ERROR_BAD_PASSWORD)); 1330 } 1331 AES_DestroyContext(ctxt, PR_TRUE); 1332 1333 loser: 1334 if (crv != CKR_OK) { 1335 if (dest != NULL) { 1336 SECITEM_ZfreeItem(dest, PR_TRUE); 1337 } 1338 dest = NULL; 1339 } 1340 1341 if (dup_src != NULL) { 1342 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1343 } 1344 1345 return dest; 1346 } 1347 1348 /* perform aes encryption/decryption if an error occurs, NULL is returned 1349 */ 1350 static SECItem * 1351 sec_pkcs5_aes_key_wrap(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des, 1352 PRBool encrypt) 1353 { 1354 SECItem *dest; 1355 SECItem *dup_src; 1356 CK_RV crv = CKR_DEVICE_ERROR; 1357 int error; 1358 SECStatus rv = SECFailure; 1359 AESKeyWrapContext *ctxt; 1360 unsigned int pad; 1361 1362 if ((src == NULL) || (key == NULL) || (iv == NULL)) { 1363 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1364 return NULL; 1365 } 1366 1367 dup_src = SECITEM_DupItem(src); 1368 if (dup_src == NULL) { 1369 return NULL; 1370 } 1371 1372 if (encrypt != PR_FALSE) { 1373 void *dummy; 1374 1375 dummy = CBC_PadBuffer(NULL, dup_src->data, 1376 dup_src->len, &dup_src->len, AES_BLOCK_SIZE); 1377 if (dummy == NULL) { 1378 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1379 return NULL; 1380 } 1381 dup_src->data = (unsigned char *)dummy; 1382 } 1383 1384 dest = SECITEM_AllocItem(NULL, NULL, dup_src->len + MAX_CRYPTO_EXPANSION); 1385 if (dest == NULL) { 1386 goto loser; 1387 } 1388 ctxt = AESKeyWrap_CreateContext(key->data, iv->data, encrypt, 1389 key->len); 1390 1391 if (ctxt == NULL) { 1392 goto loser; 1393 } 1394 rv = (encrypt ? AESKeyWrap_Encrypt : AESKeyWrap_Decrypt)( 1395 ctxt, dest->data, &dest->len, 1396 dest->len, dup_src->data, dup_src->len); 1397 1398 crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; 1399 error = PORT_GetError(); 1400 1401 /* remove padding */ 1402 if ((encrypt == PR_FALSE) && (rv == SECSuccess)) { 1403 crv = sftk_CheckCBCPadding(dest->data, dest->len, AES_BLOCK_SIZE, &pad); 1404 dest->len = PORT_CT_SEL(sftk_CKRVToMask(crv), dest->len - pad, dest->len); 1405 PORT_SetError(PORT_CT_SEL(sftk_CKRVToMask(crv), error, SEC_ERROR_BAD_PASSWORD)); 1406 } 1407 AESKeyWrap_DestroyContext(ctxt, PR_TRUE); 1408 1409 loser: 1410 if (crv != CKR_OK) { 1411 if (dest != NULL) { 1412 SECITEM_ZfreeItem(dest, PR_TRUE); 1413 } 1414 dest = NULL; 1415 } 1416 1417 if (dup_src != NULL) { 1418 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1419 } 1420 1421 return dest; 1422 } 1423 1424 #ifndef NSS_DISABLE_DEPRECATED_RC2 1425 /* perform rc2 encryption/decryption if an error occurs, NULL is returned 1426 */ 1427 static SECItem * 1428 sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy, 1429 PRBool encrypt) 1430 { 1431 SECItem *dest; 1432 SECItem *dup_src; 1433 SECStatus rv = SECFailure; 1434 int pad; 1435 1436 if ((src == NULL) || (key == NULL) || (iv == NULL)) { 1437 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1438 return NULL; 1439 } 1440 1441 dup_src = SECITEM_DupItem(src); 1442 if (dup_src == NULL) { 1443 return NULL; 1444 } 1445 1446 if (encrypt != PR_FALSE) { 1447 void *v; 1448 1449 v = CBC_PadBuffer(NULL, dup_src->data, 1450 dup_src->len, &dup_src->len, 8 /* RC2_BLOCK_SIZE */); 1451 if (v == NULL) { 1452 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1453 return NULL; 1454 } 1455 dup_src->data = (unsigned char *)v; 1456 } 1457 1458 dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); 1459 if (dest != NULL) { 1460 dest->data = (unsigned char *)PORT_ZAlloc(dup_src->len + 64); 1461 if (dest->data != NULL) { 1462 RC2Context *ctxt; 1463 1464 ctxt = RC2_CreateContext(key->data, key->len, iv->data, 1465 NSS_RC2_CBC, key->len); 1466 1467 if (ctxt != NULL) { 1468 rv = (encrypt ? RC2_Encrypt : RC2_Decrypt)( 1469 ctxt, dest->data, &dest->len, 1470 dup_src->len + 64, dup_src->data, dup_src->len); 1471 1472 /* assumes 8 byte blocks -- remove padding */ 1473 if ((rv == SECSuccess) && (encrypt != PR_TRUE)) { 1474 pad = dest->data[dest->len - 1]; 1475 if ((pad > 0) && (pad <= 8)) { 1476 if (dest->data[dest->len - pad] != pad) { 1477 PORT_SetError(SEC_ERROR_BAD_PASSWORD); 1478 rv = SECFailure; 1479 } else { 1480 dest->len -= pad; 1481 } 1482 } else { 1483 PORT_SetError(SEC_ERROR_BAD_PASSWORD); 1484 rv = SECFailure; 1485 } 1486 } 1487 } 1488 } 1489 } 1490 1491 if ((rv != SECSuccess) && (dest != NULL)) { 1492 SECITEM_ZfreeItem(dest, PR_TRUE); 1493 dest = NULL; 1494 } 1495 1496 if (dup_src != NULL) { 1497 SECITEM_ZfreeItem(dup_src, PR_TRUE); 1498 } 1499 1500 return dest; 1501 } 1502 #endif /* NSS_DISABLE_DEPRECATED_RC2 */ 1503 1504 /* perform rc4 encryption and decryption */ 1505 static SECItem * 1506 sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op, 1507 PRBool encrypt) 1508 { 1509 SECItem *dest; 1510 SECStatus rv = SECFailure; 1511 1512 if ((src == NULL) || (key == NULL) || (iv == NULL)) { 1513 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1514 return NULL; 1515 } 1516 1517 dest = (SECItem *)PORT_ZAlloc(sizeof(SECItem)); 1518 if (dest != NULL) { 1519 dest->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) * 1520 (src->len + 64)); 1521 if (dest->data != NULL) { 1522 RC4Context *ctxt; 1523 1524 ctxt = RC4_CreateContext(key->data, key->len); 1525 if (ctxt) { 1526 rv = (encrypt ? RC4_Encrypt : RC4_Decrypt)( 1527 ctxt, dest->data, &dest->len, 1528 src->len + 64, src->data, src->len); 1529 RC4_DestroyContext(ctxt, PR_TRUE); 1530 } 1531 } 1532 } 1533 1534 if ((rv != SECSuccess) && (dest)) { 1535 SECITEM_ZfreeItem(dest, PR_TRUE); 1536 dest = NULL; 1537 } 1538 1539 return dest; 1540 } 1541 /* function pointer template for crypto functions */ 1542 typedef SECItem *(*pkcs5_crypto_func)(SECItem *key, SECItem *iv, 1543 SECItem *src, PRBool op1, PRBool op2); 1544 1545 /* performs the cipher operation on the src and returns the result. 1546 * if an error occurs, NULL is returned. 1547 * 1548 * a null length password is allowed. this corresponds to encrypting 1549 * the data with ust the salt. 1550 */ 1551 /* change this to use PKCS 11? */ 1552 SECItem * 1553 nsspkcs5_CipherData(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, 1554 SECItem *src, PRBool encrypt, PRBool *update) 1555 { 1556 SECItem *key = NULL, iv; 1557 SECItem *dest = NULL; 1558 PRBool tripleDES = PR_TRUE; 1559 pkcs5_crypto_func cryptof; 1560 1561 iv.data = NULL; 1562 1563 if (update) { 1564 *update = PR_FALSE; 1565 } 1566 1567 if ((pwitem == NULL) || (src == NULL)) { 1568 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1569 return NULL; 1570 } 1571 1572 /* get key, and iv */ 1573 key = nsspkcs5_ComputeKeyAndIV(pbe_param, pwitem, &iv, PR_FALSE); 1574 if (key == NULL) { 1575 return NULL; 1576 } 1577 1578 switch (pbe_param->encAlg) { 1579 /* PKCS 5 v2 only */ 1580 case SEC_OID_AES_128_KEY_WRAP: 1581 case SEC_OID_AES_192_KEY_WRAP: 1582 case SEC_OID_AES_256_KEY_WRAP: 1583 cryptof = sec_pkcs5_aes_key_wrap; 1584 break; 1585 case SEC_OID_AES_128_CBC: 1586 case SEC_OID_AES_192_CBC: 1587 case SEC_OID_AES_256_CBC: 1588 cryptof = sec_pkcs5_aes; 1589 break; 1590 case SEC_OID_DES_EDE3_CBC: 1591 cryptof = sec_pkcs5_des; 1592 tripleDES = PR_TRUE; 1593 break; 1594 case SEC_OID_DES_CBC: 1595 cryptof = sec_pkcs5_des; 1596 tripleDES = PR_FALSE; 1597 break; 1598 #ifndef NSS_DISABLE_DEPRECATED_RC2 1599 case SEC_OID_RC2_CBC: 1600 cryptof = sec_pkcs5_rc2; 1601 break; 1602 #endif 1603 case SEC_OID_RC4: 1604 cryptof = sec_pkcs5_rc4; 1605 break; 1606 default: 1607 cryptof = NULL; 1608 break; 1609 } 1610 1611 if (cryptof == NULL) { 1612 goto loser; 1613 } 1614 1615 dest = (*cryptof)(key, &iv, src, tripleDES, encrypt); 1616 /* 1617 * it's possible for some keys and keydb's to claim to 1618 * be triple des when they're really des. In this case 1619 * we simply try des. If des works we set the update flag 1620 * so the key db knows it needs to update all it's entries. 1621 * The case can only happen on decrypted of a 1622 * SEC_OID_DES_EDE3_CBD. 1623 */ 1624 if ((pbe_param->encAlg == SEC_OID_DES_EDE3_CBC) && 1625 (dest == NULL) && (encrypt == PR_FALSE)) { 1626 dest = (*cryptof)(key, &iv, src, PR_FALSE, encrypt); 1627 if (update && (dest != NULL)) 1628 *update = PR_TRUE; 1629 } 1630 1631 loser: 1632 if (key != NULL) { 1633 SECITEM_ZfreeItem(key, PR_TRUE); 1634 } 1635 if (iv.data != NULL) { 1636 SECITEM_ZfreeItem(&iv, PR_FALSE); 1637 } 1638 1639 return dest; 1640 } 1641 1642 /* creates a algorithm ID containing the PBE algorithm and appropriate 1643 * parameters. the required parameter is the algorithm. if salt is 1644 * not specified, it is generated randomly. if IV is specified, it overrides 1645 * the PKCS 5 generation of the IV. 1646 * 1647 * the returned SECAlgorithmID should be destroyed using 1648 * SECOID_DestroyAlgorithmID 1649 */ 1650 SECAlgorithmID * 1651 nsspkcs5_CreateAlgorithmID(PLArenaPool *arena, SECOidTag algorithm, 1652 NSSPKCS5PBEParameter *pbe_param) 1653 { 1654 SECAlgorithmID *algid, *ret_algid = NULL; 1655 SECItem der_param; 1656 nsspkcs5V2PBEParameter pkcs5v2_param; 1657 1658 SECStatus rv = SECFailure; 1659 void *dummy = NULL; 1660 1661 if (arena == NULL) { 1662 return NULL; 1663 } 1664 1665 der_param.data = NULL; 1666 der_param.len = 0; 1667 1668 /* generate the algorithm id */ 1669 algid = (SECAlgorithmID *)PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID)); 1670 if (algid == NULL) { 1671 goto loser; 1672 } 1673 1674 if (pbe_param->iteration.data == NULL) { 1675 dummy = SEC_ASN1EncodeInteger(pbe_param->poolp, &pbe_param->iteration, 1676 pbe_param->iter); 1677 if (dummy == NULL) { 1678 goto loser; 1679 } 1680 } 1681 switch (pbe_param->pbeType) { 1682 case NSSPKCS5_PBKDF1: 1683 dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param, 1684 NSSPKCS5PBEParameterTemplate); 1685 break; 1686 case NSSPKCS5_PKCS12_V2: 1687 dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param, 1688 NSSPKCS5PKCS12V2PBEParameterTemplate); 1689 break; 1690 case NSSPKCS5_PBKDF2: 1691 if (pbe_param->keyLength.data == NULL) { 1692 dummy = SEC_ASN1EncodeInteger(pbe_param->poolp, 1693 &pbe_param->keyLength, pbe_param->keyLen); 1694 if (dummy == NULL) { 1695 goto loser; 1696 } 1697 } 1698 PORT_Memset(&pkcs5v2_param, 0, sizeof(pkcs5v2_param)); 1699 dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param, 1700 NSSPKCS5V2PBEParameterTemplate); 1701 if (dummy == NULL) { 1702 break; 1703 } 1704 dummy = NULL; 1705 rv = SECOID_SetAlgorithmID(arena, &pkcs5v2_param.keyParams, 1706 SEC_OID_PKCS5_PBKDF2, &der_param); 1707 if (rv != SECSuccess) { 1708 break; 1709 } 1710 der_param.data = pbe_param->ivData; 1711 der_param.len = pbe_param->ivLen; 1712 rv = SECOID_SetAlgorithmID(arena, &pkcs5v2_param.algParams, 1713 pbe_param->encAlg, pbe_param->ivLen ? &der_param : NULL); 1714 if (rv != SECSuccess) { 1715 dummy = NULL; 1716 break; 1717 } 1718 der_param.data = NULL; 1719 der_param.len = 0; 1720 dummy = SEC_ASN1EncodeItem(arena, &der_param, &pkcs5v2_param, 1721 NSSPKCS5V2PBES2ParameterTemplate); 1722 /* If the algorithm was set to some encryption oid, set it 1723 * to PBES2 */ 1724 if ((algorithm != SEC_OID_PKCS5_PBKDF2) && 1725 (algorithm != SEC_OID_PKCS5_PBMAC1)) { 1726 algorithm = SEC_OID_PKCS5_PBES2; 1727 } 1728 break; 1729 default: 1730 break; 1731 } 1732 1733 if (dummy == NULL) { 1734 goto loser; 1735 } 1736 1737 rv = SECOID_SetAlgorithmID(arena, algid, algorithm, &der_param); 1738 if (rv != SECSuccess) { 1739 goto loser; 1740 } 1741 1742 ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID)); 1743 if (ret_algid == NULL) { 1744 goto loser; 1745 } 1746 1747 rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid); 1748 if (rv != SECSuccess) { 1749 SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE); 1750 ret_algid = NULL; 1751 } 1752 1753 loser: 1754 1755 return ret_algid; 1756 } 1757 1758 #define TEST_KEY "pbkdf test key" 1759 SECStatus 1760 sftk_fips_pbkdf_PowerUpSelfTests(void) 1761 { 1762 SECItem *result; 1763 SECItem inKey; 1764 NSSPKCS5PBEParameter pbe_params; 1765 unsigned char iteration_count = 5; 1766 unsigned char keyLen = 64; 1767 char *inKeyData = TEST_KEY; 1768 static const unsigned char saltData[] = { 1769 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 1770 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 1771 }; 1772 1773 static const unsigned char pbkdf_known_answer[] = { 1774 0x73, 0x8c, 0xfa, 0x02, 0xe8, 0xdb, 0x43, 0xe4, 1775 0x99, 0xc5, 0xfd, 0xd9, 0x4d, 0x8e, 0x3e, 0x7b, 1776 0xc4, 0xda, 0x22, 0x1b, 0xe1, 0xae, 0x23, 0x7a, 1777 0x21, 0x27, 0xbd, 0xcc, 0x78, 0xc4, 0xe6, 0xc5, 1778 0x33, 0x38, 0x35, 0xe0, 0x68, 0x1a, 0x1e, 0x06, 1779 0xad, 0xaf, 0x7f, 0xd7, 0x3f, 0x0e, 0xc0, 0x90, 1780 0x17, 0x97, 0x73, 0x75, 0x7b, 0x88, 0x49, 0xd8, 1781 0x6f, 0x78, 0x5a, 0xde, 0x50, 0x20, 0x55, 0x33 1782 }; 1783 1784 sftk_PBELockInit(); 1785 1786 inKey.data = (unsigned char *)inKeyData; 1787 inKey.len = sizeof(TEST_KEY) - 1; 1788 1789 pbe_params.salt.data = (unsigned char *)saltData; 1790 pbe_params.salt.len = sizeof(saltData); 1791 /* the interation and keyLength are used as intermediate 1792 * values when decoding the Algorithm ID, set them for completeness, 1793 * but they are not used */ 1794 pbe_params.iteration.data = &iteration_count; 1795 pbe_params.iteration.len = 1; 1796 pbe_params.keyLength.data = &keyLen; 1797 pbe_params.keyLength.len = 1; 1798 /* pkcs5v2 stores the key in the AlgorithmID, so we don't need to 1799 * generate it here */ 1800 pbe_params.ivLen = 0; 1801 pbe_params.ivData = NULL; 1802 /* keyID is only used by pkcs12 extensions to pkcs5v1 */ 1803 pbe_params.keyID = pbeBitGenCipherKey; 1804 /* Algorithm is used by the decryption code after get get our key */ 1805 pbe_params.encAlg = SEC_OID_AES_256_CBC; 1806 /* these are the fields actually used in nsspkcs5_ComputeKeyAndIV 1807 * for NSSPKCS5_PBKDF2 */ 1808 pbe_params.iter = iteration_count; 1809 pbe_params.keyLen = keyLen; 1810 pbe_params.hashType = HASH_AlgSHA256; 1811 pbe_params.pbeType = NSSPKCS5_PBKDF2; 1812 pbe_params.is2KeyDES = PR_FALSE; 1813 1814 result = nsspkcs5_ComputeKeyAndIV(&pbe_params, &inKey, NULL, PR_FALSE); 1815 if ((result == NULL) || (result->len != sizeof(pbkdf_known_answer)) || 1816 (PORT_Memcmp(result->data, pbkdf_known_answer, sizeof(pbkdf_known_answer)) != 0)) { 1817 SECITEM_FreeItem(result, PR_TRUE); 1818 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1819 return SECFailure; 1820 } 1821 SECITEM_FreeItem(result, PR_TRUE); 1822 return SECSuccess; 1823 }