pk11pbe.c (51632B)
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 "blapit.h" 8 #include "seccomon.h" 9 #include "secitem.h" 10 #include "secport.h" 11 #include "hasht.h" 12 #include "pkcs11t.h" 13 #include "sechash.h" 14 #include "secasn1.h" 15 #include "secder.h" 16 #include "secoid.h" 17 #include "secerr.h" 18 #include "secmod.h" 19 #include "pk11func.h" 20 #include "secpkcs5.h" 21 #include "secmodi.h" 22 #include "secmodti.h" 23 #include "pkcs11.h" 24 #include "pk11func.h" 25 #include "secitem.h" 26 #include "keyhi.h" 27 28 typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter; 29 struct SEC_PKCS5PBEParameterStr { 30 PLArenaPool *poolp; 31 SECItem salt; /* octet string */ 32 SECItem iteration; /* integer */ 33 SECItem keyLength; /* PKCS5v2 only */ 34 SECAlgorithmID *pPrfAlgId; /* PKCS5v2 only */ 35 SECAlgorithmID prfAlgId; /* PKCS5v2 only */ 36 }; 37 38 /* PKCS5 V2 has an algorithm ID for the encryption and for 39 * the key generation. This is valid for SEC_OID_PKCS5_PBES2 40 * and SEC_OID_PKCS5_PBMAC1 41 */ 42 struct sec_pkcs5V2ParameterStr { 43 PLArenaPool *poolp; 44 SECAlgorithmID pbeAlgId; /* real pbe algorithms */ 45 SECAlgorithmID cipherAlgId; /* encryption/mac */ 46 }; 47 48 typedef struct sec_pkcs5V2ParameterStr sec_pkcs5V2Parameter; 49 50 /* template for PKCS 5 PBE Parameter. This template has been expanded 51 * based upon the additions in PKCS 12. This should eventually be moved 52 * if RSA updates PKCS 5. 53 */ 54 const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] = { 55 { SEC_ASN1_SEQUENCE, 56 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, 57 { SEC_ASN1_OCTET_STRING, 58 offsetof(SEC_PKCS5PBEParameter, salt) }, 59 { SEC_ASN1_INTEGER, 60 offsetof(SEC_PKCS5PBEParameter, iteration) }, 61 { 0 } 62 }; 63 64 const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] = { 65 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, 66 { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) }, 67 { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) }, 68 { 0 } 69 }; 70 71 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) 72 73 /* SECOID_PKCS5_PBKDF2 */ 74 const SEC_ASN1Template SEC_PKCS5V2PBEParameterTemplate[] = { 75 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, 76 /* This is really a choice, but since we only understand this 77 * choice, just inline it */ 78 { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) }, 79 { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) }, 80 { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, 81 offsetof(SEC_PKCS5PBEParameter, keyLength) }, 82 { SEC_ASN1_POINTER | SEC_ASN1_XTRN | SEC_ASN1_OPTIONAL, 83 offsetof(SEC_PKCS5PBEParameter, pPrfAlgId), 84 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 85 { 0 } 86 }; 87 88 /* SEC_OID_PKCS5_PBES2, SEC_OID_PKCS5_PBMAC1 */ 89 const SEC_ASN1Template SEC_PKCS5V2ParameterTemplate[] = { 90 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) }, 91 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(sec_pkcs5V2Parameter, pbeAlgId), 92 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 93 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, 94 offsetof(sec_pkcs5V2Parameter, cipherAlgId), 95 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, 96 { 0 } 97 }; 98 99 /* 100 * maps a PBE algorithm to a crypto algorithm. for PKCS12 and PKCS5v1 101 * for PKCS5v2 it returns SEC_OID_PKCS5_PBKDF2. 102 */ 103 SECOidTag 104 sec_pkcs5GetCryptoFromAlgTag(SECOidTag algorithm) 105 { 106 switch (algorithm) { 107 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: 108 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: 109 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: 110 return SEC_OID_DES_EDE3_CBC; 111 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: 112 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: 113 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: 114 return SEC_OID_DES_CBC; 115 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 116 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 117 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 118 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 119 return SEC_OID_RC2_CBC; 120 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: 121 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: 122 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: 123 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: 124 return SEC_OID_RC4; 125 case SEC_OID_PKCS5_PBKDF2: 126 case SEC_OID_PKCS5_PBES2: 127 case SEC_OID_PKCS5_PBMAC1: 128 return SEC_OID_PKCS5_PBKDF2; 129 default: 130 break; 131 } 132 133 return SEC_OID_UNKNOWN; 134 } 135 136 /* 137 * only gets the tag from PKCS5v1 or PKCS12pbe. 138 * PKCS5v2 requires the algid to get the full thing 139 */ 140 SECOidTag 141 SEC_PKCS5GetHashFromAlgTag(SECOidTag algtag) 142 { 143 switch (algtag) { 144 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: 145 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: 146 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: 147 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: 148 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 149 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 150 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 151 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 152 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: 153 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: 154 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: 155 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: 156 return SEC_OID_SHA1; 157 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: 158 return SEC_OID_MD5; 159 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: 160 return SEC_OID_MD2; 161 default: 162 break; 163 } 164 return SEC_OID_UNKNOWN; 165 } 166 167 /* 168 * get a new PKCS5 V2 Parameter from the algorithm id. 169 * if arena is passed in, use it, otherwise create a new arena. 170 */ 171 sec_pkcs5V2Parameter * 172 sec_pkcs5_v2_get_v2_param(PLArenaPool *arena, SECAlgorithmID *algid) 173 { 174 PLArenaPool *localArena = NULL; 175 sec_pkcs5V2Parameter *pbeV2_param; 176 SECStatus rv; 177 178 if (arena == NULL) { 179 localArena = arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 180 if (arena == NULL) { 181 return NULL; 182 } 183 } 184 pbeV2_param = PORT_ArenaZNew(arena, sec_pkcs5V2Parameter); 185 if (pbeV2_param == NULL) { 186 goto loser; 187 } 188 189 rv = SEC_ASN1DecodeItem(arena, pbeV2_param, 190 SEC_PKCS5V2ParameterTemplate, &algid->parameters); 191 if (rv == SECFailure) { 192 goto loser; 193 } 194 195 pbeV2_param->poolp = arena; 196 return pbeV2_param; 197 loser: 198 if (localArena) { 199 PORT_FreeArena(arena, PR_FALSE); 200 } 201 return NULL; 202 } 203 204 void 205 sec_pkcs5_v2_destroy_v2_param(sec_pkcs5V2Parameter *param) 206 { 207 if (param && param->poolp) { 208 PORT_FreeArena(param->poolp, PR_TRUE); 209 } 210 } 211 212 /* maps crypto algorithm from PBE algorithm. 213 */ 214 SECOidTag 215 SEC_PKCS5GetHashAlgorithm(SECAlgorithmID *algid) 216 { 217 218 SECOidTag pbeAlg; 219 SECOidTag hashAlg = SEC_OID_UNKNOWN; 220 PLArenaPool *arena = NULL; 221 222 if (algid == NULL) 223 return SEC_OID_UNKNOWN; 224 225 pbeAlg = SECOID_GetAlgorithmTag(algid); 226 /* if we are using a PKCS 5v2 algorithm, get the hash from the parameters */ 227 if ((pbeAlg == SEC_OID_PKCS5_PBES2) || 228 (pbeAlg == SEC_OID_PKCS5_PBMAC1)) { 229 SEC_PKCS5PBEParameter p5_param; 230 sec_pkcs5V2Parameter *pbeV2_param; 231 SECOidTag kdfAlg; 232 SECStatus rv; 233 234 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 235 if (arena == NULL) { 236 goto loser; 237 } 238 239 pbeV2_param = sec_pkcs5_v2_get_v2_param(arena, algid); 240 if (pbeV2_param == NULL) { 241 goto loser; 242 } 243 244 kdfAlg = SECOID_GetAlgorithmTag(&pbeV2_param->pbeAlgId); 245 /* sanity check, they should all be PBKDF2 here */ 246 if (kdfAlg != SEC_OID_PKCS5_PBKDF2) { 247 goto loser; 248 } 249 250 PORT_Memset(&p5_param, 0, sizeof(p5_param)); 251 rv = SEC_ASN1DecodeItem(arena, &p5_param, 252 SEC_PKCS5V2PBEParameterTemplate, 253 &pbeV2_param->pbeAlgId.parameters); 254 if (rv != SECSuccess) { 255 goto loser; 256 } 257 /* if the prf does not exist, it defaults to SHA1 */ 258 hashAlg = SEC_OID_SHA1; 259 if (p5_param.pPrfAlgId && 260 p5_param.pPrfAlgId->algorithm.data != 0) { 261 hashAlg = HASH_GetHashOidTagByHMACOidTag( 262 SECOID_GetAlgorithmTag(p5_param.pPrfAlgId)); 263 } 264 } else { 265 return SEC_PKCS5GetHashFromAlgTag(pbeAlg); 266 } 267 loser: 268 if (arena != NULL) { 269 PORT_FreeArena(arena, PR_FALSE); 270 } 271 272 return hashAlg; 273 } 274 275 /* maps crypto algorithm from PBE algorithm. 276 */ 277 SECOidTag 278 SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid) 279 { 280 281 SECOidTag pbeAlg; 282 SECOidTag cipherAlg; 283 284 if (algid == NULL) 285 return SEC_OID_UNKNOWN; 286 287 pbeAlg = SECOID_GetAlgorithmTag(algid); 288 cipherAlg = sec_pkcs5GetCryptoFromAlgTag(pbeAlg); 289 if ((cipherAlg == SEC_OID_PKCS5_PBKDF2) && 290 (pbeAlg != SEC_OID_PKCS5_PBKDF2)) { 291 sec_pkcs5V2Parameter *pbeV2_param; 292 cipherAlg = SEC_OID_UNKNOWN; 293 294 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); 295 if (pbeV2_param != NULL) { 296 cipherAlg = SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId); 297 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); 298 } 299 } 300 301 return cipherAlg; 302 } 303 304 /* 305 * only gets the tag from PKCS5v1 or PKCS12pbe. 306 * PKCS5v2 requires the algid to get the full thing 307 */ 308 SECOidTag 309 SEC_PKCS5GetCryptoFromAlgTag(SECOidTag algtag) 310 { 311 SECOidTag cipherAlg; 312 cipherAlg = sec_pkcs5GetCryptoFromAlgTag(algtag); 313 if (cipherAlg == SEC_OID_PKCS5_PBKDF2) { 314 return SEC_OID_UNKNOWN; 315 } 316 return cipherAlg; 317 } 318 319 /* check to see if an oid is a pbe algorithm 320 */ 321 PRBool 322 SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid) 323 { 324 return (PRBool)(SEC_PKCS5GetCryptoAlgorithm(algid) != SEC_OID_UNKNOWN); 325 } 326 327 PRBool 328 SEC_PKCS5IsAlgorithmPBEAlgTag(SECOidTag algtag) 329 { 330 return (PRBool)(sec_pkcs5GetCryptoFromAlgTag(algtag) != SEC_OID_UNKNOWN); 331 } 332 333 /* 334 * find the most appropriate PKCS5v2 overall oid tag from a regular 335 * cipher/hash algorithm tag. 336 */ 337 static SECOidTag 338 sec_pkcs5v2_get_pbe(SECOidTag algTag) 339 { 340 /* if it's a valid hash oid... */ 341 if (HASH_GetHashOidTagByHMACOidTag(algTag) != SEC_OID_UNKNOWN) { 342 /* use the MAC tag */ 343 return SEC_OID_PKCS5_PBMAC1; 344 } 345 if (HASH_GetHashTypeByOidTag(algTag) != HASH_AlgNULL) { 346 /* eliminate Hash algorithms */ 347 return SEC_OID_UNKNOWN; 348 } 349 if (PK11_AlgtagToMechanism(algTag) != CKM_INVALID_MECHANISM) { 350 /* it's not a hash, if it has a PKCS #11 mechanism associated 351 * with it, assume it's a cipher. (NOTE this will generate 352 * some false positives). */ 353 return SEC_OID_PKCS5_PBES2; 354 } 355 return SEC_OID_UNKNOWN; 356 } 357 358 /* 359 * maps PBE algorithm from crypto algorithm, assumes SHA1 hashing. 360 * input keyLen in bits. 361 */ 362 SECOidTag 363 SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen) 364 { 365 switch (algTag) { 366 case SEC_OID_DES_EDE3_CBC: 367 switch (keyLen) { 368 case 168: 369 case 192: 370 case 0: 371 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC; 372 case 128: 373 case 92: 374 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC; 375 default: 376 break; 377 } 378 break; 379 case SEC_OID_DES_CBC: 380 return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC; 381 case SEC_OID_RC2_CBC: 382 switch (keyLen) { 383 case 40: 384 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC; 385 case 128: 386 case 0: 387 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC; 388 default: 389 break; 390 } 391 break; 392 case SEC_OID_RC4: 393 switch (keyLen) { 394 case 40: 395 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4; 396 case 128: 397 case 0: 398 return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4; 399 default: 400 break; 401 } 402 break; 403 default: 404 return sec_pkcs5v2_get_pbe(algTag); 405 } 406 407 return SEC_OID_UNKNOWN; 408 } 409 410 /* 411 * Some oids encode the key size in the oid, while the actual PKCS 412 * PKCS #11 mechanism does not. In those cases we can't use 413 * the PKCS #11 automated key length code to select the key size. 414 */ 415 static int 416 sec_pkcs5v2_key_length_by_oid(SECOidTag algorithm) 417 { 418 switch (algorithm) { 419 case SEC_OID_AES_128_CBC: 420 case SEC_OID_CAMELLIA_128_CBC: 421 return AES_128_KEY_LENGTH; 422 case SEC_OID_AES_192_CBC: 423 case SEC_OID_CAMELLIA_192_CBC: 424 return AES_192_KEY_LENGTH; 425 case SEC_OID_AES_256_CBC: 426 case SEC_OID_CAMELLIA_256_CBC: 427 return AES_256_KEY_LENGTH; 428 default: 429 break; 430 } 431 return -1; 432 } 433 434 /* find the keylength from the algorithm id */ 435 static int 436 sec_pkcs5v2_default_key_length(SECOidTag algorithm) 437 { 438 CK_MECHANISM_TYPE cryptoMech; 439 int key_length = sec_pkcs5v2_key_length_by_oid(algorithm); 440 if (key_length != -1) { 441 return key_length; 442 } 443 cryptoMech = PK11_AlgtagToMechanism(algorithm); 444 if (cryptoMech == CKM_INVALID_MECHANISM) { 445 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 446 return -1; 447 } 448 return PK11_GetMaxKeyLength(cryptoMech); 449 } 450 451 /* 452 * get the key length in bytes from a PKCS5 PBE 453 */ 454 static int 455 sec_pkcs5v2_key_length(SECAlgorithmID *algid, SECAlgorithmID *cipherAlgId) 456 { 457 SECOidTag algorithm; 458 PLArenaPool *arena = NULL; 459 SEC_PKCS5PBEParameter p5_param; 460 SECStatus rv; 461 int length = -1; 462 SECOidTag cipherAlg = SEC_OID_UNKNOWN; 463 464 algorithm = SECOID_GetAlgorithmTag(algid); 465 /* sanity check, they should all be PBKDF2 here */ 466 if (algorithm != SEC_OID_PKCS5_PBKDF2) { 467 return -1; 468 } 469 470 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 471 if (arena == NULL) { 472 goto loser; 473 } 474 PORT_Memset(&p5_param, 0, sizeof(p5_param)); 475 rv = SEC_ASN1DecodeItem(arena, &p5_param, 476 SEC_PKCS5V2PBEParameterTemplate, &algid->parameters); 477 if (rv != SECSuccess) { 478 goto loser; 479 } 480 481 if (cipherAlgId) 482 cipherAlg = SECOID_GetAlgorithmTag(cipherAlgId); 483 484 if (p5_param.keyLength.data != NULL) { 485 /* if the length is given, accept that length. This 486 * will allow us to decode old NSS encrypted data 487 * where we used the MAX keysize for the algorithm, 488 * but put an incorrect header for a different keysize. 489 */ 490 length = DER_GetInteger(&p5_param.keyLength); 491 } else { 492 /* if the keylength was not specified, figure it 493 * out from the oid */ 494 length = sec_pkcs5v2_default_key_length(cipherAlg); 495 } 496 497 loser: 498 if (arena) { 499 PORT_FreeArena(arena, PR_FALSE); 500 } 501 return length; 502 } 503 504 /* 505 * get the key length in bytes needed for the PBE algorithm 506 */ 507 int 508 SEC_PKCS5GetKeyLength(SECAlgorithmID *algid) 509 { 510 511 SECOidTag algorithm; 512 513 if (algid == NULL) 514 return SEC_OID_UNKNOWN; 515 516 algorithm = SECOID_GetAlgorithmTag(algid); 517 518 switch (algorithm) { 519 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: 520 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC: 521 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: 522 return 24; 523 case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC: 524 case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC: 525 case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC: 526 return 8; 527 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 528 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4: 529 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: 530 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 531 return 5; 532 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 533 case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4: 534 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 535 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: 536 return 16; 537 case SEC_OID_PKCS5_PBKDF2: 538 return sec_pkcs5v2_key_length(algid, NULL); 539 case SEC_OID_PKCS5_PBES2: 540 case SEC_OID_PKCS5_PBMAC1: { 541 sec_pkcs5V2Parameter *pbeV2_param; 542 int length = -1; 543 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); 544 if (pbeV2_param != NULL) { 545 length = sec_pkcs5v2_key_length(&pbeV2_param->pbeAlgId, 546 &pbeV2_param->cipherAlgId); 547 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); 548 } 549 return length; 550 } 551 552 default: 553 break; 554 } 555 return -1; 556 } 557 558 /* the PKCS12 V2 algorithms only encode the salt, there is no iteration 559 * count so we need a check for V2 algorithm parameters. 560 */ 561 static PRBool 562 sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm) 563 { 564 switch (algorithm) { 565 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4: 566 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4: 567 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC: 568 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC: 569 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC: 570 case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC: 571 return PR_TRUE; 572 default: 573 break; 574 } 575 576 return PR_FALSE; 577 } 578 579 static PRBool 580 sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(SECOidTag algorithm) 581 { 582 switch (algorithm) { 583 case SEC_OID_PKCS5_PBES2: 584 case SEC_OID_PKCS5_PBMAC1: 585 case SEC_OID_PKCS5_PBKDF2: 586 return PR_TRUE; 587 default: 588 break; 589 } 590 591 return PR_FALSE; 592 } 593 594 /* destroy a pbe parameter. it assumes that the parameter was 595 * generated using the appropriate create function and therefor 596 * contains an arena pool. 597 */ 598 static void 599 sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param) 600 { 601 if (pbe_param != NULL) 602 PORT_FreeArena(pbe_param->poolp, PR_TRUE); 603 } 604 605 /* creates a PBE parameter based on the PBE algorithm. the only required 606 * parameters are algorithm and interation. the return is a PBE parameter 607 * which conforms to PKCS 5 parameter unless an extended parameter is needed. 608 * this is primarily if keyLength and a variable key length algorithm are 609 * specified. 610 * salt - if null, a salt will be generated from random bytes. 611 * iteration - number of iterations to perform hashing. 612 * keyLength - only used in variable key length algorithms. if specified, 613 * should be in bytes. 614 * once a parameter is allocated, it should be destroyed calling 615 * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter. 616 */ 617 #define DEFAULT_SALT_LENGTH 16 618 static SEC_PKCS5PBEParameter * 619 sec_pkcs5_create_pbe_parameter(SECOidTag algorithm, 620 SECItem *salt, 621 int iteration, 622 int keyLength, 623 SECOidTag prfAlg) 624 { 625 PLArenaPool *poolp = NULL; 626 SEC_PKCS5PBEParameter *pbe_param = NULL; 627 SECStatus rv = SECSuccess; 628 void *dummy = NULL; 629 630 if (iteration < 0) { 631 return NULL; 632 } 633 634 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 635 if (poolp == NULL) 636 return NULL; 637 638 pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp, 639 sizeof(SEC_PKCS5PBEParameter)); 640 if (!pbe_param) { 641 PORT_FreeArena(poolp, PR_TRUE); 642 return NULL; 643 } 644 645 pbe_param->poolp = poolp; 646 647 rv = SECFailure; 648 if (salt && salt->data) { 649 rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt); 650 } else { 651 /* sigh, the old interface generated salt on the fly, so we have to 652 * preserve the semantics */ 653 pbe_param->salt.len = DEFAULT_SALT_LENGTH; 654 pbe_param->salt.data = PORT_ArenaZAlloc(poolp, DEFAULT_SALT_LENGTH); 655 if (pbe_param->salt.data) { 656 rv = PK11_GenerateRandom(pbe_param->salt.data, DEFAULT_SALT_LENGTH); 657 } 658 } 659 660 if (rv != SECSuccess) { 661 PORT_FreeArena(poolp, PR_TRUE); 662 return NULL; 663 } 664 665 /* encode the integer */ 666 dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration, 667 iteration); 668 rv = (dummy) ? SECSuccess : SECFailure; 669 670 if (rv != SECSuccess) { 671 PORT_FreeArena(poolp, PR_FALSE); 672 return NULL; 673 } 674 675 /* 676 * for PKCS5 v2 Add the keylength and the prf 677 */ 678 if (algorithm == SEC_OID_PKCS5_PBKDF2) { 679 dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->keyLength, 680 keyLength); 681 rv = (dummy) ? SECSuccess : SECFailure; 682 if (rv != SECSuccess) { 683 PORT_FreeArena(poolp, PR_FALSE); 684 return NULL; 685 } 686 rv = SECOID_SetAlgorithmID(poolp, &pbe_param->prfAlgId, prfAlg, NULL); 687 if (rv != SECSuccess) { 688 PORT_FreeArena(poolp, PR_FALSE); 689 return NULL; 690 } 691 pbe_param->pPrfAlgId = &pbe_param->prfAlgId; 692 } 693 694 return pbe_param; 695 } 696 697 /* creates a algorithm ID containing the PBE algorithm and appropriate 698 * parameters. the required parameter is the algorithm. if salt is 699 * not specified, it is generated randomly. 700 * 701 * the returned SECAlgorithmID should be destroyed using 702 * SECOID_DestroyAlgorithmID 703 */ 704 SECAlgorithmID * 705 sec_pkcs5CreateAlgorithmID(SECOidTag algorithm, 706 SECOidTag cipherAlgorithm, 707 SECOidTag prfAlg, 708 SECOidTag *pPbeAlgorithm, 709 int keyLength, 710 SECItem *salt, 711 int iteration) 712 { 713 PLArenaPool *poolp = NULL; 714 SECAlgorithmID *algid, *ret_algid = NULL; 715 SECOidTag pbeAlgorithm = algorithm; 716 SECItem der_param; 717 void *dummy; 718 SECStatus rv = SECFailure; 719 SEC_PKCS5PBEParameter *pbe_param = NULL; 720 sec_pkcs5V2Parameter pbeV2_param; 721 722 if (iteration <= 0) { 723 return NULL; 724 } 725 726 poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 727 if (!poolp) { 728 goto loser; 729 } 730 731 if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm) || 732 sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { 733 /* use PKCS 5 v2 */ 734 SECItem *cipherParams; 735 736 /* 737 * if we ask for pkcs5 Algorithms directly, then the 738 * application needs to supply the cipher algorithm, 739 * otherwise we are implicitly using pkcs5 v2 and the 740 * passed in algorithm is the encryption algorithm. 741 */ 742 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { 743 if (cipherAlgorithm == SEC_OID_UNKNOWN) { 744 goto loser; 745 } 746 } else { 747 cipherAlgorithm = algorithm; 748 /* force algorithm to be chosen below */ 749 algorithm = SEC_OID_PKCS5_PBKDF2; 750 } 751 752 pbeAlgorithm = SEC_OID_PKCS5_PBKDF2; 753 /* 754 * 'algorithm' is the overall algorithm oid tag used to wrap the 755 * entire algorithm ID block. For PKCS5v1 and PKCS12, this 756 * algorithm OID has encoded in it both the PBE KDF function 757 * and the encryption algorithm. For PKCS 5v2, PBE KDF and 758 * encryption/macing oids are encoded as parameters in 759 * the algorithm ID block. 760 * 761 * Thus in PKCS5 v1 and PKCS12, this algorithm maps to a pkcs #11 762 * mechanism, where as in PKCS 5v2, this algorithm tag does not map 763 * directly to a PKCS #11 mechanim, instead the 2 oids in the 764 * algorithm ID block map the the actual PKCS #11 mechanism. 765 * algorithm is). We use choose this algorithm oid based on the 766 * cipherAlgorithm to determine what this should be (MAC1 or PBES2). 767 */ 768 if (algorithm == SEC_OID_PKCS5_PBKDF2) { 769 /* choose mac or pbes */ 770 algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm); 771 } 772 773 SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm); 774 775 /* set the PKCS5v2 specific parameters */ 776 if (keyLength == 0) { 777 if (hashAlg != SEC_OID_UNKNOWN) { 778 keyLength = HASH_ResultLenByOidTag(hashAlg); 779 } else { 780 keyLength = sec_pkcs5v2_default_key_length(cipherAlgorithm); 781 } 782 if (keyLength <= 0) { 783 goto loser; 784 } 785 } 786 /* currently SEC_OID_HMAC_SHA1 is the default */ 787 if (prfAlg == SEC_OID_UNKNOWN) { 788 prfAlg = SEC_OID_HMAC_SHA1; 789 } 790 791 /* build the PKCS5v2 cipher algorithm id, if cipher 792 * is an HMAC, the cipherParams should be NULL */ 793 if (hashAlg == SEC_OID_UNKNOWN) { 794 cipherParams = pk11_GenerateNewParamWithKeyLen( 795 PK11_AlgtagToMechanism(cipherAlgorithm), keyLength); 796 if (!cipherParams) { 797 goto loser; 798 } 799 } else { 800 cipherParams = NULL; 801 } 802 803 PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param)); 804 805 rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams, 806 poolp, &pbeV2_param.cipherAlgId); 807 if (cipherParams) { 808 SECITEM_FreeItem(cipherParams, PR_TRUE); 809 } 810 if (rv != SECSuccess) { 811 goto loser; 812 } 813 } 814 815 /* generate the parameter */ 816 pbe_param = sec_pkcs5_create_pbe_parameter(pbeAlgorithm, salt, iteration, 817 keyLength, prfAlg); 818 if (!pbe_param) { 819 goto loser; 820 } 821 822 /* generate the algorithm id */ 823 algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID)); 824 if (algid == NULL) { 825 goto loser; 826 } 827 828 der_param.data = NULL; 829 der_param.len = 0; 830 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(algorithm)) { 831 /* first encode the PBE algorithm ID */ 832 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, 833 SEC_PKCS5V2PBEParameterTemplate); 834 if (dummy == NULL) { 835 goto loser; 836 } 837 rv = SECOID_SetAlgorithmID(poolp, &pbeV2_param.pbeAlgId, 838 pbeAlgorithm, &der_param); 839 if (rv != SECSuccess) { 840 goto loser; 841 } 842 843 /* now encode the Full PKCS 5 parameter */ 844 der_param.data = NULL; 845 der_param.len = 0; 846 dummy = SEC_ASN1EncodeItem(poolp, &der_param, &pbeV2_param, 847 SEC_PKCS5V2ParameterTemplate); 848 } else if (!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { 849 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, 850 SEC_PKCS5PBEParameterTemplate); 851 } else { 852 dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param, 853 SEC_V2PKCS12PBEParameterTemplate); 854 } 855 if (dummy == NULL) { 856 goto loser; 857 } 858 859 rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param); 860 if (rv != SECSuccess) { 861 goto loser; 862 } 863 864 ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID)); 865 if (ret_algid == NULL) { 866 goto loser; 867 } 868 869 rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid); 870 if (rv != SECSuccess) { 871 SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE); 872 ret_algid = NULL; 873 } else if (pPbeAlgorithm) { 874 *pPbeAlgorithm = pbeAlgorithm; 875 } 876 877 loser: 878 if (poolp != NULL) { 879 PORT_FreeArena(poolp, PR_TRUE); 880 algid = NULL; 881 } 882 883 if (pbe_param) { 884 sec_pkcs5_destroy_pbe_param(pbe_param); 885 } 886 887 return ret_algid; 888 } 889 890 SECStatus 891 pbe_PK11AlgidToParam(SECAlgorithmID *algid, SECItem *mech) 892 { 893 SEC_PKCS5PBEParameter p5_param; 894 SECItem *salt = NULL; 895 SECOidTag algorithm = SECOID_GetAlgorithmTag(algid); 896 PLArenaPool *arena = NULL; 897 SECStatus rv = SECFailure; 898 unsigned char *paramData = NULL; 899 unsigned char *pSalt = NULL; 900 CK_ULONG iterations; 901 int paramLen = 0; 902 int iv_len = -1; 903 904 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 905 if (arena == NULL) { 906 goto loser; 907 } 908 909 /* 910 * decode the algid based on the pbe type 911 */ 912 PORT_Memset(&p5_param, 0, sizeof(p5_param)); 913 if (sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) { 914 iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm)); 915 rv = SEC_ASN1DecodeItem(arena, &p5_param, 916 SEC_V2PKCS12PBEParameterTemplate, &algid->parameters); 917 } else if (algorithm == SEC_OID_PKCS5_PBKDF2) { 918 iv_len = 0; 919 rv = SEC_ASN1DecodeItem(arena, &p5_param, 920 SEC_PKCS5V2PBEParameterTemplate, &algid->parameters); 921 } else { 922 iv_len = PK11_GetIVLength(PK11_AlgtagToMechanism(algorithm)); 923 rv = SEC_ASN1DecodeItem(arena, &p5_param, SEC_PKCS5PBEParameterTemplate, 924 &algid->parameters); 925 } 926 927 if (iv_len < 0) { 928 goto loser; 929 } 930 931 if (rv != SECSuccess) { 932 goto loser; 933 } 934 935 /* get salt */ 936 salt = &p5_param.salt; 937 iterations = (CK_ULONG)DER_GetInteger(&p5_param.iteration); 938 939 /* allocate and fill in the PKCS #11 parameters 940 * based on the algorithm. */ 941 if (algorithm == SEC_OID_PKCS5_PBKDF2) { 942 SECOidTag prfAlgTag; 943 CK_PKCS5_PBKD2_PARAMS2 *pbeV2_params = 944 (CK_PKCS5_PBKD2_PARAMS2 *)PORT_ZAlloc( 945 PR_MAX(sizeof(CK_PKCS5_PBKD2_PARAMS2), sizeof(CK_PKCS5_PBKD2_PARAMS)) + salt->len); 946 947 if (pbeV2_params == NULL) { 948 goto loser; 949 } 950 paramData = (unsigned char *)pbeV2_params; 951 paramLen = PR_MAX(sizeof(CK_PKCS5_PBKD2_PARAMS2), sizeof(CK_PKCS5_PBKD2_PARAMS)); 952 953 /* set the prf */ 954 prfAlgTag = SEC_OID_HMAC_SHA1; 955 if (p5_param.pPrfAlgId && 956 p5_param.pPrfAlgId->algorithm.data != 0) { 957 prfAlgTag = SECOID_GetAlgorithmTag(p5_param.pPrfAlgId); 958 } 959 switch (prfAlgTag) { 960 case SEC_OID_HMAC_SHA1: 961 pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA1; 962 break; 963 case SEC_OID_HMAC_SHA224: 964 pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA224; 965 break; 966 case SEC_OID_HMAC_SHA256: 967 pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA256; 968 break; 969 case SEC_OID_HMAC_SHA384: 970 pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA384; 971 break; 972 case SEC_OID_HMAC_SHA512: 973 pbeV2_params->prf = CKP_PKCS5_PBKD2_HMAC_SHA512; 974 break; 975 default: 976 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 977 goto loser; 978 } 979 980 /* probably should fetch these from the prfAlgid */ 981 pbeV2_params->pPrfData = NULL; 982 pbeV2_params->ulPrfDataLen = 0; 983 pbeV2_params->saltSource = CKZ_SALT_SPECIFIED; 984 pSalt = ((CK_CHAR_PTR)pbeV2_params) + PR_MAX(sizeof(CK_PKCS5_PBKD2_PARAMS2), sizeof(CK_PKCS5_PBKD2_PARAMS)); 985 if (salt->data) { 986 PORT_Memcpy(pSalt, salt->data, salt->len); 987 } 988 pbeV2_params->pSaltSourceData = pSalt; 989 pbeV2_params->ulSaltSourceDataLen = salt->len; 990 pbeV2_params->iterations = iterations; 991 } else { 992 CK_PBE_PARAMS *pbe_params = NULL; 993 pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS) + 994 salt->len + iv_len); 995 if (pbe_params == NULL) { 996 goto loser; 997 } 998 paramData = (unsigned char *)pbe_params; 999 paramLen = sizeof(CK_PBE_PARAMS); 1000 1001 pSalt = ((CK_CHAR_PTR)pbe_params) + sizeof(CK_PBE_PARAMS); 1002 pbe_params->pSalt = pSalt; 1003 if (salt->data) { 1004 PORT_Memcpy(pSalt, salt->data, salt->len); 1005 } 1006 pbe_params->ulSaltLen = salt->len; 1007 if (iv_len) { 1008 pbe_params->pInitVector = 1009 ((CK_CHAR_PTR)pbe_params) + sizeof(CK_PBE_PARAMS) + salt->len; 1010 } 1011 pbe_params->ulIteration = iterations; 1012 } 1013 1014 /* copy into the mechanism sec item */ 1015 mech->data = paramData; 1016 mech->len = paramLen; 1017 if (arena) { 1018 PORT_FreeArena(arena, PR_TRUE); 1019 } 1020 return SECSuccess; 1021 1022 loser: 1023 if (paramData) { 1024 PORT_Free(paramData); 1025 } 1026 if (arena) { 1027 PORT_FreeArena(arena, PR_TRUE); 1028 } 1029 return SECFailure; 1030 } 1031 1032 /* 1033 * public, deprecated, not valid for pkcs5 v2 1034 * 1035 * use PK11_CreatePBEV2AlgorithmID or PK11_CreatePBEAlgorithmID to create 1036 * PBE algorithmID's directly. 1037 */ 1038 SECStatus 1039 PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PLArenaPool *arena, 1040 SECAlgorithmID *algId) 1041 { 1042 CK_PBE_PARAMS *pbe_param; 1043 SECItem pbeSalt; 1044 SECAlgorithmID *pbeAlgID = NULL; 1045 SECStatus rv; 1046 1047 if (!param || !algId) { 1048 return SECFailure; 1049 } 1050 1051 pbe_param = (CK_PBE_PARAMS *)param->data; 1052 pbeSalt.data = (unsigned char *)pbe_param->pSalt; 1053 pbeSalt.len = pbe_param->ulSaltLen; 1054 pbeAlgID = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN, 1055 SEC_OID_UNKNOWN, NULL, 0, 1056 &pbeSalt, (int)pbe_param->ulIteration); 1057 if (!pbeAlgID) { 1058 return SECFailure; 1059 } 1060 1061 rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID); 1062 SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE); 1063 return rv; 1064 } 1065 1066 /* 1067 * public, Deprecated, This function is only for binary compatibility with 1068 * older applications. Does not support PKCS5v2. 1069 * 1070 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for 1071 * iv values rather than generating PBE bits directly. 1072 */ 1073 PBEBitGenContext * 1074 PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose, 1075 SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded, 1076 unsigned int iterations) 1077 { 1078 SECItem *context = NULL; 1079 SECItem mechItem; 1080 CK_PBE_PARAMS pbe_params; 1081 CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM; 1082 PK11SlotInfo *slot; 1083 PK11SymKey *symKey = NULL; 1084 unsigned char ivData[8]; 1085 1086 /* use the purpose to select the low level keygen algorithm */ 1087 switch (bitGenPurpose) { 1088 case pbeBitGenIntegrityKey: 1089 switch (hashAlgorithm) { 1090 case SEC_OID_SHA1: 1091 mechanism = CKM_PBA_SHA1_WITH_SHA1_HMAC; 1092 break; 1093 case SEC_OID_MD2: 1094 mechanism = CKM_NSS_PBE_MD2_HMAC_KEY_GEN; 1095 break; 1096 case SEC_OID_MD5: 1097 mechanism = CKM_NSS_PBE_MD5_HMAC_KEY_GEN; 1098 break; 1099 default: 1100 break; 1101 } 1102 break; 1103 case pbeBitGenCipherIV: 1104 if (bitsNeeded > 64) { 1105 break; 1106 } 1107 if (hashAlgorithm != SEC_OID_SHA1) { 1108 break; 1109 } 1110 mechanism = CKM_PBE_SHA1_DES3_EDE_CBC; 1111 break; 1112 case pbeBitGenCipherKey: 1113 if (hashAlgorithm != SEC_OID_SHA1) { 1114 break; 1115 } 1116 switch (bitsNeeded) { 1117 case 40: 1118 mechanism = CKM_PBE_SHA1_RC4_40; 1119 break; 1120 case 128: 1121 mechanism = CKM_PBE_SHA1_RC4_128; 1122 break; 1123 default: 1124 break; 1125 } 1126 case pbeBitGenIDNull: 1127 break; 1128 } 1129 1130 if (mechanism == CKM_INVALID_MECHANISM) { 1131 /* we should set an error, but this is a deprecated function, and 1132 * we are keeping bug for bug compatibility;)... */ 1133 return NULL; 1134 } 1135 1136 pbe_params.pInitVector = ivData; 1137 pbe_params.pPassword = pwitem->data; 1138 pbe_params.ulPasswordLen = pwitem->len; 1139 pbe_params.pSalt = salt->data; 1140 pbe_params.ulSaltLen = salt->len; 1141 pbe_params.ulIteration = iterations; 1142 mechItem.data = (unsigned char *)&pbe_params; 1143 mechItem.len = sizeof(pbe_params); 1144 1145 slot = PK11_GetInternalSlot(); 1146 symKey = PK11_RawPBEKeyGen(slot, mechanism, 1147 &mechItem, pwitem, PR_FALSE, NULL); 1148 PK11_FreeSlot(slot); 1149 if (symKey != NULL) { 1150 if (bitGenPurpose == pbeBitGenCipherIV) { 1151 /* NOTE: this assumes that bitsNeeded is a multiple of 8! */ 1152 SECItem ivItem; 1153 1154 ivItem.data = ivData; 1155 ivItem.len = bitsNeeded / 8; 1156 context = SECITEM_DupItem(&ivItem); 1157 } else { 1158 SECItem *keyData; 1159 PK11_ExtractKeyValue(symKey); 1160 keyData = PK11_GetKeyData(symKey); 1161 1162 /* assert bitsNeeded with length? */ 1163 if (keyData) { 1164 context = SECITEM_DupItem(keyData); 1165 } 1166 } 1167 PK11_FreeSymKey(symKey); 1168 } 1169 1170 return (PBEBitGenContext *)context; 1171 } 1172 1173 /* 1174 * public, Deprecated, This function is only for binary compatibility with 1175 * older applications. Does not support PKCS5v2. 1176 * 1177 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetIV() for 1178 * iv values rather than generating PBE bits directly. 1179 */ 1180 SECItem * 1181 PBE_GenerateBits(PBEBitGenContext *context) 1182 { 1183 return (SECItem *)context; 1184 } 1185 1186 /* 1187 * public, Deprecated, This function is only for binary compatibility with 1188 * older applications. Does not support PKCS5v2. 1189 * 1190 * Applications should use PK11_PBEKeyGen() for keys and PK11_GetPBEIV() for 1191 * iv values rather than generating PBE bits directly. 1192 */ 1193 void 1194 PBE_DestroyContext(PBEBitGenContext *context) 1195 { 1196 SECITEM_FreeItem((SECItem *)context, PR_TRUE); 1197 } 1198 1199 /* 1200 * public, deprecated. Replaced with PK11_GetPBEIV(). 1201 */ 1202 SECItem * 1203 SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES) 1204 { 1205 /* pbe stuff */ 1206 CK_MECHANISM_TYPE type; 1207 SECItem *param = NULL; 1208 SECItem *iv = NULL; 1209 SECItem src; 1210 int iv_len = 0; 1211 PK11SymKey *symKey; 1212 PK11SlotInfo *slot; 1213 CK_PBE_PARAMS_PTR pPBEparams; 1214 SECOidTag pbeAlg; 1215 1216 pbeAlg = SECOID_GetAlgorithmTag(algid); 1217 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) { 1218 unsigned char *ivData; 1219 sec_pkcs5V2Parameter *pbeV2_param = NULL; 1220 1221 /* can only return the IV if the crypto Algorithm exists */ 1222 if (pbeAlg == SEC_OID_PKCS5_PBKDF2) { 1223 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1224 goto loser; 1225 } 1226 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); 1227 if (pbeV2_param == NULL) { 1228 goto loser; 1229 } 1230 /* extract the IV from the cipher algid portion of our pkcs 5 v2 1231 * algorithm id */ 1232 type = PK11_AlgtagToMechanism( 1233 SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId)); 1234 param = PK11_ParamFromAlgid(&pbeV2_param->cipherAlgId); 1235 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); 1236 if (!param) { 1237 goto loser; 1238 } 1239 /* NOTE: NULL is a permissible return here */ 1240 ivData = PK11_IVFromParam(type, param, &iv_len); 1241 src.data = ivData; 1242 src.len = iv_len; 1243 goto done; 1244 } 1245 1246 type = PK11_AlgtagToMechanism(pbeAlg); 1247 param = PK11_ParamFromAlgid(algid); 1248 if (param == NULL) { 1249 goto done; 1250 } 1251 slot = PK11_GetInternalSlot(); 1252 symKey = PK11_RawPBEKeyGen(slot, type, param, pwitem, faulty3DES, NULL); 1253 PK11_FreeSlot(slot); 1254 if (symKey == NULL) { 1255 goto loser; 1256 } 1257 PK11_FreeSymKey(symKey); 1258 pPBEparams = (CK_PBE_PARAMS_PTR)param->data; 1259 iv_len = PK11_GetIVLength(type); 1260 1261 src.data = (unsigned char *)pPBEparams->pInitVector; 1262 src.len = iv_len; 1263 1264 done: 1265 iv = SECITEM_DupItem(&src); 1266 1267 loser: 1268 if (param) { 1269 SECITEM_ZfreeItem(param, PR_TRUE); 1270 } 1271 return iv; 1272 } 1273 1274 /* 1275 * Subs from nss 3.x that are deprecated 1276 */ 1277 PBEBitGenContext * 1278 __PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose, 1279 SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded, 1280 unsigned int iterations) 1281 { 1282 PORT_Assert("__PBE_CreateContext is Deprecated" == NULL); 1283 return NULL; 1284 } 1285 1286 SECItem * 1287 __PBE_GenerateBits(PBEBitGenContext *context) 1288 { 1289 PORT_Assert("__PBE_GenerateBits is Deprecated" == NULL); 1290 return NULL; 1291 } 1292 1293 void 1294 __PBE_DestroyContext(PBEBitGenContext *context) 1295 { 1296 PORT_Assert("__PBE_DestroyContext is Deprecated" == NULL); 1297 } 1298 1299 SECStatus 1300 RSA_FormatBlock(SECItem *result, unsigned modulusLen, 1301 int blockType, SECItem *data) 1302 { 1303 PORT_Assert("RSA_FormatBlock is Deprecated" == NULL); 1304 return SECFailure; 1305 } 1306 1307 /**************************************************************************** 1308 * 1309 * Now Do The PBE Functions Here... 1310 * 1311 ****************************************************************************/ 1312 1313 static void 1314 pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params) 1315 { 1316 if (pbe_params) { 1317 if (pbe_params->pPassword) 1318 PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen); 1319 if (pbe_params->pSalt) 1320 PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen); 1321 PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS)); 1322 } 1323 } 1324 1325 /* 1326 * public, deprecated. use PK11_CreatePBEAlgorithmID or 1327 * PK11_CreatePBEV2AlgorithmID instead. If you needthe pkcs #11 parameters, 1328 * use PK11_ParamFromAlgid from the algorithm id you created using 1329 * PK11_CreatePBEAlgorithmID or PK11_CreatePBEV2AlgorithmID. 1330 */ 1331 SECItem * 1332 PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations) 1333 { 1334 CK_PBE_PARAMS *pbe_params = NULL; 1335 SECItem *paramRV = NULL; 1336 1337 paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); 1338 if (!paramRV) { 1339 goto loser; 1340 } 1341 /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */ 1342 PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS)); 1343 1344 pbe_params = (CK_PBE_PARAMS *)paramRV->data; 1345 pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len); 1346 if (!pbe_params->pPassword) { 1347 goto loser; 1348 } 1349 if (pwd->data) { 1350 PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); 1351 } 1352 pbe_params->ulPasswordLen = pwd->len; 1353 1354 pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len); 1355 if (!pbe_params->pSalt) { 1356 goto loser; 1357 } 1358 PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); 1359 pbe_params->ulSaltLen = salt->len; 1360 1361 pbe_params->ulIteration = (CK_ULONG)iterations; 1362 return paramRV; 1363 1364 loser: 1365 if (pbe_params) 1366 pk11_destroy_ck_pbe_params(pbe_params); 1367 if (paramRV) 1368 PORT_ZFree(paramRV, sizeof(SECItem)); 1369 return NULL; 1370 } 1371 1372 /* 1373 * public, deprecated. 1374 */ 1375 void 1376 PK11_DestroyPBEParams(SECItem *pItem) 1377 { 1378 if (pItem) { 1379 CK_PBE_PARAMS *params = (CK_PBE_PARAMS *)(pItem->data); 1380 if (params) 1381 pk11_destroy_ck_pbe_params(params); 1382 PORT_ZFree(pItem, sizeof(SECItem)); 1383 } 1384 } 1385 1386 /* 1387 * public, Partially supports PKCS5 V2 (some parameters are not controllable 1388 * through this interface). Use PK11_CreatePBEV2AlgorithmID() if you need 1389 * finer control these. 1390 */ 1391 SECAlgorithmID * 1392 PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt) 1393 { 1394 SECAlgorithmID *algid = NULL; 1395 algid = sec_pkcs5CreateAlgorithmID(algorithm, 1396 SEC_OID_UNKNOWN, SEC_OID_UNKNOWN, NULL, 1397 0, salt, iteration); 1398 return algid; 1399 } 1400 1401 /* 1402 * public, fully support pkcs5v2. 1403 */ 1404 SECAlgorithmID * 1405 PK11_CreatePBEV2AlgorithmID(SECOidTag pbeAlgTag, SECOidTag cipherAlgTag, 1406 SECOidTag prfAlgTag, int keyLength, int iteration, 1407 SECItem *salt) 1408 { 1409 SECAlgorithmID *algid = NULL; 1410 algid = sec_pkcs5CreateAlgorithmID(pbeAlgTag, cipherAlgTag, prfAlgTag, 1411 NULL, keyLength, salt, iteration); 1412 return algid; 1413 } 1414 1415 /* 1416 * private. 1417 */ 1418 PK11SymKey * 1419 pk11_RawPBEKeyGenWithKeyType(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, 1420 SECItem *params, CK_KEY_TYPE keyType, int keyLen, 1421 SECItem *pwitem, void *wincx) 1422 { 1423 #ifndef NSS_USE_PKCS5_PBKD2_PARAMS2_ONLY 1424 SECItem _params = { 0, NULL, 0 }; 1425 CK_PKCS5_PBKD2_PARAMS pbev2_1_params; 1426 CK_ULONG pwLen; 1427 #endif 1428 #ifdef UNSAFE_FUZZER_MODE 1429 PK11SymKey *zeroKey = NULL; 1430 unsigned char zeroBuff[32] = { 0 }; 1431 SECItem zeroItem = { siBuffer, zeroBuff, sizeof zeroBuff }; 1432 1433 zeroKey = PK11_ImportSymKeyWithFlags(slot, type, PK11_OriginUnwrap, 1434 CKA_FLAGS_ONLY, &zeroItem, 1435 CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT | 1436 CKF_UNWRAP | CKF_WRAP, 1437 PR_FALSE, wincx); 1438 return zeroKey; 1439 #else /* UNSAFE_FUZZER_MODE */ 1440 1441 /* do some sanity checks */ 1442 if ((params == NULL) || (params->data == NULL)) { 1443 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1444 return NULL; 1445 } 1446 1447 if (type == CKM_INVALID_MECHANISM) { 1448 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1449 return NULL; 1450 } 1451 1452 /* set the password pointer in the parameters... */ 1453 if (type == CKM_PKCS5_PBKD2) { 1454 CK_PKCS5_PBKD2_PARAMS2 *pbev2_params; 1455 1456 if (params->len < PR_MIN(sizeof(CK_PKCS5_PBKD2_PARAMS2), sizeof(CK_PKCS5_PBKD2_PARAMS))) { 1457 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1458 return NULL; 1459 } 1460 pbev2_params = (CK_PKCS5_PBKD2_PARAMS2 *)params->data; 1461 pbev2_params->pPassword = pwitem->data; 1462 pbev2_params->ulPasswordLen = pwitem->len; 1463 params->len = sizeof(CK_PKCS5_PBKD2_PARAMS2); 1464 1465 #ifndef NSS_USE_PKCS5_PBKD2_PARAMS2_ONLY 1466 if (PK11_CheckPKCS11Version(slot, 2, 40, PR_FALSE) < 0) { 1467 /* CK_PKCS5_PBKD2_PARAMS */ 1468 _params.type = params->type; 1469 _params.data = (CK_CHAR_PTR)&pbev2_1_params; 1470 _params.len = sizeof(CK_PKCS5_PBKD2_PARAMS); 1471 memcpy(&pbev2_1_params, pbev2_params, 1472 PR_MIN(sizeof(CK_PKCS5_PBKD2_PARAMS2), 1473 sizeof(CK_PKCS5_PBKD2_PARAMS))); 1474 1475 pwLen = pwitem->len; 1476 pbev2_1_params.ulPasswordLen = &pwLen; 1477 params = &_params; 1478 } 1479 #endif 1480 1481 } else { 1482 CK_PBE_PARAMS *pbe_params; 1483 if (params->len < sizeof(CK_PBE_PARAMS)) { 1484 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1485 return NULL; 1486 } 1487 pbe_params = (CK_PBE_PARAMS *)params->data; 1488 pbe_params->pPassword = pwitem->data; 1489 pbe_params->ulPasswordLen = pwitem->len; 1490 } 1491 1492 /* generate the key (and sometimes the IV as a side effect...) */ 1493 return pk11_TokenKeyGenWithFlagsAndKeyType(slot, type, params, keyType, keyLen, NULL, 1494 CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT | CKF_UNWRAP | CKF_WRAP, 1495 0, wincx); 1496 #endif /* UNSAFE_FUZZER_MODE */ 1497 } 1498 1499 /* 1500 * public, deprecated. use PK11_PBEKeyGen instead. 1501 */ 1502 PK11SymKey * 1503 PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, 1504 SECItem *pwitem, PRBool faulty3DES, void *wincx) 1505 { 1506 if (faulty3DES && (type == CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC)) { 1507 type = CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC; 1508 } 1509 return pk11_RawPBEKeyGenWithKeyType(slot, type, mech, -1, 0, pwitem, wincx); 1510 } 1511 1512 /* 1513 * pubic, supports pkcs5 v2. 1514 * 1515 * Create symkey from a PBE key. The algid can be created with 1516 * PK11_CreatePBEV2AlgorithmID and PK11_CreatePBEAlgorithmID, or by 1517 * extraction of der data. 1518 */ 1519 PK11SymKey * 1520 PK11_PBEKeyGen(PK11SlotInfo *slot, SECAlgorithmID *algid, SECItem *pwitem, 1521 PRBool faulty3DES, void *wincx) 1522 { 1523 CK_MECHANISM_TYPE type; 1524 SECItem *param = NULL; 1525 PK11SymKey *symKey = NULL; 1526 SECOidTag pbeAlg; 1527 CK_KEY_TYPE keyType = -1; 1528 int keyLen = 0; 1529 1530 pbeAlg = SECOID_GetAlgorithmTag(algid); 1531 /* if we're using PKCS5v2, extract the additional information we need 1532 * (key length, key type, and pbeAlg). */ 1533 if (sec_pkcs5_is_algorithm_v2_pkcs5_algorithm(pbeAlg)) { 1534 CK_MECHANISM_TYPE cipherMech; 1535 sec_pkcs5V2Parameter *pbeV2_param; 1536 1537 pbeV2_param = sec_pkcs5_v2_get_v2_param(NULL, algid); 1538 if (pbeV2_param == NULL) { 1539 return NULL; 1540 } 1541 cipherMech = PK11_AlgtagToMechanism( 1542 SECOID_GetAlgorithmTag(&pbeV2_param->cipherAlgId)); 1543 pbeAlg = SECOID_GetAlgorithmTag(&pbeV2_param->pbeAlgId); 1544 param = PK11_ParamFromAlgid(&pbeV2_param->pbeAlgId); 1545 sec_pkcs5_v2_destroy_v2_param(pbeV2_param); 1546 keyLen = SEC_PKCS5GetKeyLength(algid); 1547 if (keyLen == -1) { 1548 keyLen = 0; 1549 } 1550 keyType = PK11_GetKeyType(cipherMech, keyLen); 1551 } else { 1552 param = PK11_ParamFromAlgid(algid); 1553 } 1554 1555 if (param == NULL) { 1556 goto loser; 1557 } 1558 1559 type = PK11_AlgtagToMechanism(pbeAlg); 1560 if (type == CKM_INVALID_MECHANISM) { 1561 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1562 goto loser; 1563 } 1564 if (faulty3DES && (type == CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC)) { 1565 type = CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC; 1566 } 1567 symKey = pk11_RawPBEKeyGenWithKeyType(slot, type, param, keyType, keyLen, 1568 pwitem, wincx); 1569 1570 loser: 1571 if (param) { 1572 SECITEM_ZfreeItem(param, PR_TRUE); 1573 } 1574 return symKey; 1575 } 1576 1577 /* 1578 * public, supports pkcs5v2 1579 */ 1580 SECItem * 1581 PK11_GetPBEIV(SECAlgorithmID *algid, SECItem *pwitem) 1582 { 1583 return SEC_PKCS5GetIV(algid, pwitem, PR_FALSE); 1584 } 1585 1586 CK_MECHANISM_TYPE 1587 pk11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param, 1588 SECItem *pbe_pwd, PRBool faulty3DES) 1589 { 1590 int keyLen = 0; 1591 SECOidTag algTag = SEC_PKCS5GetCryptoAlgorithm(algid); 1592 CK_MECHANISM_TYPE mech = PK11_AlgtagToMechanism(algTag); 1593 CK_MECHANISM_TYPE returnedMechanism = CKM_INVALID_MECHANISM; 1594 SECItem *iv = NULL; 1595 1596 if (mech == CKM_INVALID_MECHANISM) { 1597 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1598 goto loser; 1599 } 1600 if (PK11_GetIVLength(mech)) { 1601 iv = SEC_PKCS5GetIV(algid, pbe_pwd, faulty3DES); 1602 if (iv == NULL) { 1603 goto loser; 1604 } 1605 } 1606 1607 keyLen = SEC_PKCS5GetKeyLength(algid); 1608 1609 *param = pk11_ParamFromIVWithLen(mech, iv, keyLen); 1610 if (*param == NULL) { 1611 goto loser; 1612 } 1613 returnedMechanism = mech; 1614 1615 loser: 1616 if (iv) { 1617 SECITEM_FreeItem(iv, PR_TRUE); 1618 } 1619 return returnedMechanism; 1620 } 1621 1622 /* 1623 * Public, supports pkcs5 v2 1624 * 1625 * Get the crypto mechanism directly from the pbe algorithmid. 1626 * 1627 * It's important to go directly from the algorithm id so that we can 1628 * handle both the PKCS #5 v1, PKCS #12, and PKCS #5 v2 cases. 1629 * 1630 * This function returns both the mechanism and the parameter for the mechanism. 1631 * The caller is responsible for freeing the parameter. 1632 */ 1633 CK_MECHANISM_TYPE 1634 PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **param, 1635 SECItem *pbe_pwd) 1636 { 1637 return pk11_GetPBECryptoMechanism(algid, param, pbe_pwd, PR_FALSE); 1638 }