pkcs11c.c (365580B)
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 * This file implements PKCS 11 on top of our existing security modules 6 * 7 * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. 8 * This implementation has two slots: 9 * slot 1 is our generic crypto support. It does not require login. 10 * It supports Public Key ops, and all they bulk ciphers and hashes. 11 * It can also support Private Key ops for imported Private keys. It does 12 * not have any token storage. 13 * slot 2 is our private key support. It requires a login before use. It 14 * can store Private Keys and Certs as token objects. Currently only private 15 * keys and their associated Certificates are saved on the token. 16 * 17 * In this implementation, session objects are only visible to the session 18 * that created or generated them. 19 */ 20 21 #include <limits.h> /* for UINT_MAX and ULONG_MAX */ 22 23 #include "lowkeyti.h" 24 #include "seccomon.h" 25 #include "secitem.h" 26 #include "secport.h" 27 #include "blapi.h" 28 /* we need to use the deprecated mechanisms values for backward compatibility */ 29 #include "pkcs11.h" 30 #include "pkcs11i.h" 31 #include "pkcs1sig.h" 32 #include "lowkeyi.h" 33 #include "secder.h" 34 #include "secdig.h" 35 #include "lowpbe.h" /* We do PBE below */ 36 #include "pkcs11t.h" 37 #include "secoid.h" 38 #include "cmac.h" 39 #include "alghmac.h" 40 #include "softoken.h" 41 #include "secasn1.h" 42 #include "secerr.h" 43 #include "kem.h" 44 #include "kyber.h" 45 46 #include "prprf.h" 47 #include "prenv.h" 48 #include "prerror.h" 49 50 #define __PASTE(x, y) x##y 51 #define BAD_PARAM_CAST(pMech, typeSize) (!pMech->pParameter || pMech->ulParameterLen < typeSize) 52 /* 53 * we renamed all our internal functions, get the correct 54 * definitions for them... 55 */ 56 #undef CK_PKCS11_FUNCTION_INFO 57 #undef CK_NEED_ARG_LIST 58 59 #define CK_PKCS11_3_0 1 60 61 #define CK_EXTERN extern 62 #define CK_PKCS11_FUNCTION_INFO(func) \ 63 CK_RV __PASTE(NS, func) 64 #define CK_NEED_ARG_LIST 1 65 66 #include "pkcs11f.h" 67 68 /* create a definition of SHA1 that's consistent 69 * with the rest of the CKM_SHAxxx hashes*/ 70 #define CKM_SHA1 CKM_SHA_1 71 #define CKM_SHA1_HMAC CKM_SHA_1_HMAC 72 #define CKM_SHA1_HMAC_GENERAL CKM_SHA_1_HMAC_GENERAL 73 74 typedef struct { 75 PRUint8 client_version[2]; 76 PRUint8 random[46]; 77 } SSL3RSAPreMasterSecret; 78 79 static void 80 sftk_Null(void *data, PRBool freeit) 81 { 82 return; 83 } 84 85 /* fake hash end, the hashed data is already in the signature context, 86 * return a NULL hash, which will be passed to the sign final and ignored */ 87 void 88 sftk_NullHashEnd(void *info, unsigned char *data, unsigned int *lenp, 89 unsigned int maxlen) 90 { 91 *lenp = 0; 92 } 93 94 #ifdef EC_DEBUG 95 #define SEC_PRINT(str1, str2, num, sitem) \ 96 printf("pkcs11c.c:%s:%s (keytype=%d) [len=%d]\n", \ 97 str1, str2, num, sitem->len); \ 98 for (i = 0; i < sitem->len; i++) { \ 99 printf("%02x:", sitem->data[i]); \ 100 } \ 101 printf("\n") 102 #else 103 #undef EC_DEBUG 104 #define SEC_PRINT(a, b, c, d) 105 #endif 106 107 /* Wrappers to avoid undefined behavior calling functions through a pointer of incorrect type. */ 108 #define SFTKHashWrap(ctxtype, mmm) \ 109 static void \ 110 SFTKHash_##mmm##_Update(void *vctx, const unsigned char *input, unsigned int len) \ 111 { \ 112 ctxtype *ctx = vctx; \ 113 mmm##_Update(ctx, input, len); \ 114 } \ 115 static void \ 116 SFTKHash_##mmm##_End(void *vctx, unsigned char *digest, \ 117 unsigned int *len, unsigned int maxLen) \ 118 { \ 119 ctxtype *ctx = vctx; \ 120 mmm##_End(ctx, digest, len, maxLen); \ 121 } \ 122 static void \ 123 SFTKHash_##mmm##_DestroyContext(void *vctx, PRBool freeit) \ 124 { \ 125 ctxtype *ctx = vctx; \ 126 mmm##_DestroyContext(ctx, freeit); \ 127 } 128 129 SFTKHashWrap(MD2Context, MD2); 130 SFTKHashWrap(MD5Context, MD5); 131 SFTKHashWrap(SHA1Context, SHA1); 132 SFTKHashWrap(SHA224Context, SHA224); 133 SFTKHashWrap(SHA256Context, SHA256); 134 SFTKHashWrap(SHA384Context, SHA384); 135 SFTKHashWrap(SHA512Context, SHA512); 136 SFTKHashWrap(SHA3_224Context, SHA3_224); 137 SFTKHashWrap(SHA3_256Context, SHA3_256); 138 SFTKHashWrap(SHA3_384Context, SHA3_384); 139 SFTKHashWrap(SHA3_512Context, SHA3_512); 140 SFTKHashWrap(sftk_MACCtx, sftk_MAC); 141 142 static void 143 SFTKHash_SHA1_Begin(void *vctx) 144 { 145 SHA1Context *ctx = vctx; 146 SHA1_Begin(ctx); 147 } 148 149 static void 150 SFTKHash_MD5_Begin(void *vctx) 151 { 152 MD5Context *ctx = vctx; 153 MD5_Begin(ctx); 154 } 155 156 #define SFTKCipherWrap(ctxtype, mmm) \ 157 static SECStatus \ 158 SFTKCipher_##mmm(void *vctx, unsigned char *output, \ 159 unsigned int *outputLen, unsigned int maxOutputLen, \ 160 const unsigned char *input, unsigned int inputLen) \ 161 { \ 162 ctxtype *ctx = vctx; \ 163 return mmm(ctx, output, outputLen, maxOutputLen, \ 164 input, inputLen); \ 165 } 166 167 SFTKCipherWrap(AESKeyWrapContext, AESKeyWrap_EncryptKWP); 168 SFTKCipherWrap(AESKeyWrapContext, AESKeyWrap_DecryptKWP); 169 170 #define SFTKCipherWrap2(ctxtype, mmm) \ 171 SFTKCipherWrap(ctxtype, mmm##_Encrypt); \ 172 SFTKCipherWrap(ctxtype, mmm##_Decrypt); \ 173 static void SFTKCipher_##mmm##_DestroyContext(void *vctx, PRBool freeit) \ 174 { \ 175 ctxtype *ctx = vctx; \ 176 mmm##_DestroyContext(ctx, freeit); \ 177 } 178 179 #ifndef NSS_DISABLE_DEPRECATED_RC2 180 SFTKCipherWrap2(RC2Context, RC2); 181 #endif 182 SFTKCipherWrap2(RC4Context, RC4); 183 SFTKCipherWrap2(DESContext, DES); 184 #ifndef NSS_DISABLE_DEPRECATED_SEED 185 SFTKCipherWrap2(SEEDContext, SEED); 186 #endif 187 SFTKCipherWrap2(CamelliaContext, Camellia); 188 SFTKCipherWrap2(AESContext, AES); 189 SFTKCipherWrap2(AESKeyWrapContext, AESKeyWrap); 190 191 #if NSS_SOFTOKEN_DOES_RC5 192 SFTKCipherWrap2(RC5Context, RC5); 193 #endif 194 195 /* 196 * free routines.... Free local type allocated data, and convert 197 * other free routines to the destroy signature. 198 */ 199 static void 200 sftk_FreePrivKey(void *vkey, PRBool freeit) 201 { 202 NSSLOWKEYPrivateKey *key = vkey; 203 nsslowkey_DestroyPrivateKey(key); 204 } 205 206 static void 207 sftk_Space(void *data, PRBool freeit) 208 { 209 PORT_Free(data); 210 } 211 212 static void 213 sftk_ZSpace(void *data, PRBool freeit) 214 { 215 size_t len = *(size_t *)data; 216 PORT_ZFree(data, len); 217 } 218 219 /* 220 * turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by 221 * Deprecating a full des key to 40 bit key strenth. 222 */ 223 static CK_RV 224 sftk_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey) 225 { 226 unsigned char key1[8] = { 0xc4, 0x08, 0xb0, 0x54, 0x0b, 0xa1, 0xe0, 0xae }; 227 unsigned char key2[8] = { 0xef, 0x2c, 0x04, 0x1c, 0xe6, 0x38, 0x2f, 0xe6 }; 228 unsigned char enc_src[8]; 229 unsigned char enc_dest[8]; 230 unsigned int leng, i; 231 DESContext *descx; 232 SECStatus rv; 233 CK_RV crv = CKR_OK; 234 235 /* zero the parity bits */ 236 for (i = 0; i < 8; i++) { 237 enc_src[i] = cdmfkey[i] & 0xfe; 238 } 239 240 /* encrypt with key 1 */ 241 descx = DES_CreateContext(key1, NULL, NSS_DES, PR_TRUE); 242 if (descx == NULL) { 243 crv = CKR_HOST_MEMORY; 244 goto done; 245 } 246 rv = DES_Encrypt(descx, enc_dest, &leng, 8, enc_src, 8); 247 DES_DestroyContext(descx, PR_TRUE); 248 if (rv != SECSuccess) { 249 crv = sftk_MapCryptError(PORT_GetError()); 250 goto done; 251 } 252 253 /* xor source with des, zero the parity bits and deprecate the key*/ 254 for (i = 0; i < 8; i++) { 255 if (i & 1) { 256 enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0xfe; 257 } else { 258 enc_src[i] = (enc_src[i] ^ enc_dest[i]) & 0x0e; 259 } 260 } 261 262 /* encrypt with key 2 */ 263 descx = DES_CreateContext(key2, NULL, NSS_DES, PR_TRUE); 264 if (descx == NULL) { 265 crv = CKR_HOST_MEMORY; 266 goto done; 267 } 268 rv = DES_Encrypt(descx, deskey, &leng, 8, enc_src, 8); 269 DES_DestroyContext(descx, PR_TRUE); 270 if (rv != SECSuccess) { 271 crv = sftk_MapCryptError(PORT_GetError()); 272 goto done; 273 } 274 275 /* set the corret parity on our new des key */ 276 sftk_FormatDESKey(deskey, 8); 277 done: 278 PORT_Memset(enc_src, 0, sizeof enc_src); 279 PORT_Memset(enc_dest, 0, sizeof enc_dest); 280 return crv; 281 } 282 283 /* NSC_DestroyObject destroys an object. */ 284 CK_RV 285 NSC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) 286 { 287 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); 288 SFTKSession *session; 289 SFTKObject *object; 290 SFTKFreeStatus status; 291 292 CHECK_FORK(); 293 294 if (slot == NULL) { 295 return CKR_SESSION_HANDLE_INVALID; 296 } 297 /* 298 * This whole block just makes sure we really can destroy the 299 * requested object. 300 */ 301 session = sftk_SessionFromHandle(hSession); 302 if (session == NULL) { 303 return CKR_SESSION_HANDLE_INVALID; 304 } 305 306 object = sftk_ObjectFromHandle(hObject, session); 307 if (object == NULL) { 308 sftk_FreeSession(session); 309 return CKR_OBJECT_HANDLE_INVALID; 310 } 311 312 /* don't destroy a private object if we aren't logged in */ 313 if ((!slot->isLoggedIn) && (slot->needLogin) && 314 (sftk_isTrue(object, CKA_PRIVATE))) { 315 sftk_FreeSession(session); 316 sftk_FreeObject(object); 317 return CKR_USER_NOT_LOGGED_IN; 318 } 319 320 /* don't destroy a token object if we aren't in a rw session */ 321 322 if (((session->info.flags & CKF_RW_SESSION) == 0) && 323 (sftk_isTrue(object, CKA_TOKEN))) { 324 sftk_FreeSession(session); 325 sftk_FreeObject(object); 326 return CKR_SESSION_READ_ONLY; 327 } 328 329 sftk_DeleteObject(session, object); 330 331 sftk_FreeSession(session); 332 333 /* 334 * get some indication if the object is destroyed. Note: this is not 335 * 100%. Someone may have an object reference outstanding (though that 336 * should not be the case by here. Also note that the object is "half" 337 * destroyed. Our internal representation is destroyed, but it may still 338 * be in the data base. 339 */ 340 status = sftk_FreeObject(object); 341 342 return (status != SFTK_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR; 343 } 344 345 /* 346 * Returns true if "params" contains a valid set of PSS parameters 347 */ 348 static PRBool 349 sftk_ValidatePssParams(const CK_RSA_PKCS_PSS_PARAMS *params) 350 { 351 if (!params) { 352 return PR_FALSE; 353 } 354 if (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL || 355 sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) { 356 return PR_FALSE; 357 } 358 return PR_TRUE; 359 } 360 361 /* 362 * Returns true if "params" contains a valid set of OAEP parameters 363 */ 364 static PRBool 365 sftk_ValidateOaepParams(const CK_RSA_PKCS_OAEP_PARAMS *params) 366 { 367 if (!params) { 368 return PR_FALSE; 369 } 370 /* The requirements of ulSourceLen/pSourceData come from PKCS #11, which 371 * state: 372 * If the parameter is empty, pSourceData must be NULL and 373 * ulSourceDataLen must be zero. 374 */ 375 if (params->source != CKZ_DATA_SPECIFIED || 376 (sftk_GetHashTypeFromMechanism(params->hashAlg) == HASH_AlgNULL) || 377 (sftk_GetHashTypeFromMechanism(params->mgf) == HASH_AlgNULL) || 378 (params->ulSourceDataLen == 0 && params->pSourceData != NULL) || 379 (params->ulSourceDataLen != 0 && params->pSourceData == NULL)) { 380 return PR_FALSE; 381 } 382 return PR_TRUE; 383 } 384 385 /* 386 * return a context based on the SFTKContext type. 387 */ 388 SFTKSessionContext * 389 sftk_ReturnContextByType(SFTKSession *session, SFTKContextType type) 390 { 391 switch (type) { 392 case SFTK_ENCRYPT: 393 case SFTK_DECRYPT: 394 case SFTK_MESSAGE_ENCRYPT: 395 case SFTK_MESSAGE_DECRYPT: 396 return session->enc_context; 397 case SFTK_HASH: 398 return session->hash_context; 399 case SFTK_SIGN: 400 case SFTK_SIGN_RECOVER: 401 case SFTK_VERIFY: 402 case SFTK_VERIFY_RECOVER: 403 case SFTK_MESSAGE_SIGN: 404 case SFTK_MESSAGE_VERIFY: 405 return session->hash_context; 406 } 407 return NULL; 408 } 409 410 /* 411 * change a context based on the SFTKContext type. 412 */ 413 void 414 sftk_SetContextByType(SFTKSession *session, SFTKContextType type, 415 SFTKSessionContext *context) 416 { 417 switch (type) { 418 case SFTK_ENCRYPT: 419 case SFTK_DECRYPT: 420 case SFTK_MESSAGE_ENCRYPT: 421 case SFTK_MESSAGE_DECRYPT: 422 session->enc_context = context; 423 break; 424 case SFTK_HASH: 425 session->hash_context = context; 426 break; 427 case SFTK_SIGN: 428 case SFTK_SIGN_RECOVER: 429 case SFTK_VERIFY: 430 case SFTK_VERIFY_RECOVER: 431 case SFTK_MESSAGE_SIGN: 432 case SFTK_MESSAGE_VERIFY: 433 session->hash_context = context; 434 break; 435 } 436 return; 437 } 438 439 /* 440 * code to grab the context. Needed by every C_XXXUpdate, C_XXXFinal, 441 * and C_XXX function. The function takes a session handle, the context type, 442 * and wether or not the session needs to be multipart. It returns the context, 443 * and optionally returns the session pointer (if sessionPtr != NULL) if session 444 * pointer is returned, the caller is responsible for freeing it. 445 */ 446 CK_RV 447 sftk_GetContext(CK_SESSION_HANDLE handle, SFTKSessionContext **contextPtr, 448 SFTKContextType type, PRBool needMulti, SFTKSession **sessionPtr) 449 { 450 SFTKSession *session; 451 SFTKSessionContext *context; 452 453 session = sftk_SessionFromHandle(handle); 454 if (session == NULL) 455 return CKR_SESSION_HANDLE_INVALID; 456 context = sftk_ReturnContextByType(session, type); 457 /* make sure the context is valid */ 458 if ((context == NULL) || (context->type != type) || (needMulti && !(context->multi))) { 459 sftk_FreeSession(session); 460 return CKR_OPERATION_NOT_INITIALIZED; 461 } 462 *contextPtr = context; 463 if (sessionPtr != NULL) { 464 *sessionPtr = session; 465 } else { 466 sftk_FreeSession(session); 467 } 468 return CKR_OK; 469 } 470 471 /** Terminate operation (in the PKCS#11 spec sense). 472 * Intuitive name for FreeContext/SetNullContext pair. 473 */ 474 void 475 sftk_TerminateOp(SFTKSession *session, SFTKContextType ctype, 476 SFTKSessionContext *context) 477 { 478 session->lastOpWasFIPS = context->isFIPS; 479 sftk_FreeContext(context); 480 sftk_SetContextByType(session, ctype, NULL); 481 } 482 483 /* 484 ************** Crypto Functions: Encrypt ************************ 485 */ 486 487 /* 488 * All the NSC_InitXXX functions have a set of common checks and processing they 489 * all need to do at the beginning. This is done here. 490 */ 491 CK_RV 492 sftk_InitGeneric(SFTKSession *session, CK_MECHANISM *pMechanism, 493 SFTKSessionContext **contextPtr, 494 SFTKContextType ctype, SFTKObject **keyPtr, 495 CK_OBJECT_HANDLE hKey, CK_KEY_TYPE *keyTypePtr, 496 CK_OBJECT_CLASS pubKeyType, CK_ATTRIBUTE_TYPE operation) 497 { 498 SFTKObject *key = NULL; 499 SFTKAttribute *att; 500 SFTKSessionContext *context; 501 502 /* We can only init if there is not current context active */ 503 if (sftk_ReturnContextByType(session, ctype) != NULL) { 504 return CKR_OPERATION_ACTIVE; 505 } 506 507 /* find the key */ 508 if (keyPtr) { 509 key = sftk_ObjectFromHandle(hKey, session); 510 if (key == NULL) { 511 return CKR_KEY_HANDLE_INVALID; 512 } 513 514 /* make sure it's a valid key for this operation */ 515 if (((key->objclass != CKO_SECRET_KEY) && 516 (key->objclass != pubKeyType)) || 517 !sftk_isTrue(key, operation)) { 518 sftk_FreeObject(key); 519 return CKR_KEY_TYPE_INCONSISTENT; 520 } 521 /* get the key type */ 522 att = sftk_FindAttribute(key, CKA_KEY_TYPE); 523 if (att == NULL) { 524 sftk_FreeObject(key); 525 return CKR_KEY_TYPE_INCONSISTENT; 526 } 527 PORT_Assert(att->attrib.ulValueLen == sizeof(CK_KEY_TYPE)); 528 if (att->attrib.ulValueLen != sizeof(CK_KEY_TYPE)) { 529 sftk_FreeAttribute(att); 530 sftk_FreeObject(key); 531 return CKR_ATTRIBUTE_VALUE_INVALID; 532 } 533 PORT_Memcpy(keyTypePtr, att->attrib.pValue, sizeof(CK_KEY_TYPE)); 534 sftk_FreeAttribute(att); 535 *keyPtr = key; 536 } 537 538 /* allocate the context structure */ 539 context = (SFTKSessionContext *)PORT_Alloc(sizeof(SFTKSessionContext)); 540 if (context == NULL) { 541 if (key) 542 sftk_FreeObject(key); 543 return CKR_HOST_MEMORY; 544 } 545 context->type = ctype; 546 context->multi = PR_TRUE; 547 context->rsa = PR_FALSE; 548 context->cipherInfo = NULL; 549 context->hashInfo = NULL; 550 context->doPad = PR_FALSE; 551 context->padDataLength = 0; 552 context->key = key; 553 context->blockSize = 0; 554 context->maxLen = 0; 555 context->signature = NULL; 556 context->isFIPS = sftk_operationIsFIPS(session->slot, pMechanism, 557 operation, key); 558 *contextPtr = context; 559 return CKR_OK; 560 } 561 562 static int 563 sftk_aes_mode(CK_MECHANISM_TYPE mechanism) 564 { 565 switch (mechanism) { 566 case CKM_AES_CBC_PAD: 567 case CKM_AES_CBC: 568 return NSS_AES_CBC; 569 case CKM_AES_ECB: 570 return NSS_AES; 571 case CKM_AES_CTS: 572 return NSS_AES_CTS; 573 case CKM_AES_CTR: 574 return NSS_AES_CTR; 575 case CKM_AES_GCM: 576 return NSS_AES_GCM; 577 } 578 return -1; 579 } 580 581 static SECStatus 582 sftk_RSAEncryptRaw(void *ctx, unsigned char *output, 583 unsigned int *outputLen, unsigned int maxLen, 584 const unsigned char *input, unsigned int inputLen) 585 { 586 NSSLOWKEYPublicKey *key = ctx; 587 SECStatus rv = SECFailure; 588 589 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 590 if (key->keyType != NSSLOWKEYRSAKey) { 591 PORT_SetError(SEC_ERROR_INVALID_KEY); 592 return SECFailure; 593 } 594 595 rv = RSA_EncryptRaw(&key->u.rsa, output, outputLen, maxLen, input, 596 inputLen); 597 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 598 sftk_fatalError = PR_TRUE; 599 } 600 601 return rv; 602 } 603 604 static SECStatus 605 sftk_RSADecryptRaw(void *ctx, unsigned char *output, 606 unsigned int *outputLen, unsigned int maxLen, 607 const unsigned char *input, unsigned int inputLen) 608 { 609 NSSLOWKEYPrivateKey *key = ctx; 610 SECStatus rv = SECFailure; 611 612 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 613 if (key->keyType != NSSLOWKEYRSAKey) { 614 PORT_SetError(SEC_ERROR_INVALID_KEY); 615 return SECFailure; 616 } 617 618 rv = RSA_DecryptRaw(&key->u.rsa, output, outputLen, maxLen, input, 619 inputLen); 620 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 621 sftk_fatalError = PR_TRUE; 622 } 623 624 return rv; 625 } 626 627 static SECStatus 628 sftk_RSAEncrypt(void *ctx, unsigned char *output, 629 unsigned int *outputLen, unsigned int maxLen, 630 const unsigned char *input, unsigned int inputLen) 631 { 632 NSSLOWKEYPublicKey *key = ctx; 633 SECStatus rv = SECFailure; 634 635 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 636 if (key->keyType != NSSLOWKEYRSAKey) { 637 PORT_SetError(SEC_ERROR_INVALID_KEY); 638 return SECFailure; 639 } 640 641 rv = RSA_EncryptBlock(&key->u.rsa, output, outputLen, maxLen, input, 642 inputLen); 643 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 644 sftk_fatalError = PR_TRUE; 645 } 646 647 return rv; 648 } 649 650 static SECStatus 651 sftk_RSADecrypt(void *ctx, unsigned char *output, 652 unsigned int *outputLen, unsigned int maxLen, 653 const unsigned char *input, unsigned int inputLen) 654 { 655 NSSLOWKEYPrivateKey *key = ctx; 656 SECStatus rv = SECFailure; 657 658 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 659 if (key->keyType != NSSLOWKEYRSAKey) { 660 PORT_SetError(SEC_ERROR_INVALID_KEY); 661 return SECFailure; 662 } 663 664 rv = RSA_DecryptBlock(&key->u.rsa, output, outputLen, maxLen, input, 665 inputLen); 666 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 667 sftk_fatalError = PR_TRUE; 668 } 669 670 return rv; 671 } 672 673 static void 674 sftk_freeRSAOAEPInfo(void *ctx, PRBool freeit) 675 { 676 SFTKOAEPInfo *info = ctx; 677 PORT_ZFree(info->params.pSourceData, info->params.ulSourceDataLen); 678 PORT_ZFree(info, sizeof(SFTKOAEPInfo)); 679 } 680 681 static SECStatus 682 sftk_RSAEncryptOAEP(void *ctx, unsigned char *output, 683 unsigned int *outputLen, unsigned int maxLen, 684 const unsigned char *input, unsigned int inputLen) 685 { 686 SFTKOAEPInfo *info = ctx; 687 HASH_HashType hashAlg; 688 HASH_HashType maskHashAlg; 689 690 PORT_Assert(info->key.pub->keyType == NSSLOWKEYRSAKey); 691 if (info->key.pub->keyType != NSSLOWKEYRSAKey) { 692 PORT_SetError(SEC_ERROR_INVALID_KEY); 693 return SECFailure; 694 } 695 696 hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg); 697 maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf); 698 699 return RSA_EncryptOAEP(&info->key.pub->u.rsa, hashAlg, maskHashAlg, 700 (const unsigned char *)info->params.pSourceData, 701 info->params.ulSourceDataLen, NULL, 0, 702 output, outputLen, maxLen, input, inputLen); 703 } 704 705 static SECStatus 706 sftk_RSADecryptOAEP(void *ctx, unsigned char *output, 707 unsigned int *outputLen, unsigned int maxLen, 708 const unsigned char *input, unsigned int inputLen) 709 { 710 SFTKOAEPInfo *info = ctx; 711 SECStatus rv = SECFailure; 712 HASH_HashType hashAlg; 713 HASH_HashType maskHashAlg; 714 715 PORT_Assert(info->key.priv->keyType == NSSLOWKEYRSAKey); 716 if (info->key.priv->keyType != NSSLOWKEYRSAKey) { 717 PORT_SetError(SEC_ERROR_INVALID_KEY); 718 return SECFailure; 719 } 720 721 hashAlg = sftk_GetHashTypeFromMechanism(info->params.hashAlg); 722 maskHashAlg = sftk_GetHashTypeFromMechanism(info->params.mgf); 723 724 rv = RSA_DecryptOAEP(&info->key.priv->u.rsa, hashAlg, maskHashAlg, 725 (const unsigned char *)info->params.pSourceData, 726 info->params.ulSourceDataLen, 727 output, outputLen, maxLen, input, inputLen); 728 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 729 sftk_fatalError = PR_TRUE; 730 } 731 return rv; 732 } 733 734 static SFTKChaCha20Poly1305Info * 735 sftk_ChaCha20Poly1305_CreateContext(const unsigned char *key, 736 unsigned int keyLen, 737 const CK_NSS_AEAD_PARAMS *params) 738 { 739 SFTKChaCha20Poly1305Info *ctx; 740 741 if (params->ulNonceLen != sizeof(ctx->nonce)) { 742 PORT_SetError(SEC_ERROR_INPUT_LEN); 743 return NULL; 744 } 745 746 ctx = PORT_New(SFTKChaCha20Poly1305Info); 747 if (ctx == NULL) { 748 return NULL; 749 } 750 751 if (ChaCha20Poly1305_InitContext(&ctx->freeblCtx, key, keyLen, 752 params->ulTagLen) != SECSuccess) { 753 PORT_Free(ctx); 754 return NULL; 755 } 756 757 PORT_Memcpy(ctx->nonce, params->pNonce, sizeof(ctx->nonce)); 758 759 /* AAD data and length must both be null, or both non-null. */ 760 PORT_Assert((params->pAAD == NULL) == (params->ulAADLen == 0)); 761 762 if (params->ulAADLen > sizeof(ctx->ad)) { 763 /* Need to allocate an overflow buffer for the additional data. */ 764 ctx->adOverflow = (unsigned char *)PORT_Alloc(params->ulAADLen); 765 if (!ctx->adOverflow) { 766 PORT_Free(ctx); 767 return NULL; 768 } 769 PORT_Memcpy(ctx->adOverflow, params->pAAD, params->ulAADLen); 770 } else { 771 ctx->adOverflow = NULL; 772 if (params->pAAD) { 773 PORT_Memcpy(ctx->ad, params->pAAD, params->ulAADLen); 774 } 775 } 776 ctx->adLen = params->ulAADLen; 777 778 return ctx; 779 } 780 781 static void 782 sftk_ChaCha20Poly1305_DestroyContext(void *vctx, 783 PRBool freeit) 784 { 785 SFTKChaCha20Poly1305Info *ctx = vctx; 786 ChaCha20Poly1305_DestroyContext(&ctx->freeblCtx, PR_FALSE); 787 if (ctx->adOverflow != NULL) { 788 PORT_ZFree(ctx->adOverflow, ctx->adLen); 789 ctx->adOverflow = NULL; 790 } else { 791 PORT_Memset(ctx->ad, 0, ctx->adLen); 792 } 793 ctx->adLen = 0; 794 if (freeit) { 795 PORT_Free(ctx); 796 } 797 } 798 799 static SECStatus 800 sftk_ChaCha20Poly1305_Encrypt(void *vctx, 801 unsigned char *output, unsigned int *outputLen, 802 unsigned int maxOutputLen, 803 const unsigned char *input, unsigned int inputLen) 804 { 805 const SFTKChaCha20Poly1305Info *ctx = vctx; 806 const unsigned char *ad = ctx->adOverflow; 807 808 if (ad == NULL) { 809 ad = ctx->ad; 810 } 811 812 return ChaCha20Poly1305_Seal(&ctx->freeblCtx, output, outputLen, 813 maxOutputLen, input, inputLen, ctx->nonce, 814 sizeof(ctx->nonce), ad, ctx->adLen); 815 } 816 817 static SECStatus 818 sftk_ChaCha20Poly1305_Decrypt(void *vctx, 819 unsigned char *output, unsigned int *outputLen, 820 unsigned int maxOutputLen, 821 const unsigned char *input, unsigned int inputLen) 822 { 823 const SFTKChaCha20Poly1305Info *ctx = vctx; 824 const unsigned char *ad = ctx->adOverflow; 825 826 if (ad == NULL) { 827 ad = ctx->ad; 828 } 829 830 return ChaCha20Poly1305_Open(&ctx->freeblCtx, output, outputLen, 831 maxOutputLen, input, inputLen, ctx->nonce, 832 sizeof(ctx->nonce), ad, ctx->adLen); 833 } 834 835 static SECStatus 836 sftk_ChaCha20Ctr(void *vctx, 837 unsigned char *output, unsigned int *outputLen, 838 unsigned int maxOutputLen, 839 const unsigned char *input, unsigned int inputLen) 840 { 841 if (maxOutputLen < inputLen) { 842 PORT_SetError(SEC_ERROR_OUTPUT_LEN); 843 return SECFailure; 844 } 845 SFTKChaCha20CtrInfo *ctx = vctx; 846 ChaCha20_Xor(output, input, inputLen, ctx->key, 847 ctx->nonce, ctx->counter); 848 *outputLen = inputLen; 849 return SECSuccess; 850 } 851 852 static void 853 sftk_ChaCha20Ctr_DestroyContext(void *vctx, 854 PRBool freeit) 855 { 856 SFTKChaCha20CtrInfo *ctx = vctx; 857 memset(ctx, 0, sizeof(SFTKChaCha20CtrInfo)); 858 if (freeit) { 859 PORT_Free(ctx); 860 } 861 } 862 863 /** NSC_CryptInit initializes an encryption/Decryption operation. 864 * 865 * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey. 866 * Called by NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac) only for block 867 * ciphers MAC'ing. 868 */ 869 CK_RV 870 sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 871 CK_OBJECT_HANDLE hKey, 872 CK_ATTRIBUTE_TYPE mechUsage, CK_ATTRIBUTE_TYPE keyUsage, 873 SFTKContextType contextType, PRBool isEncrypt) 874 { 875 SFTKSession *session; 876 SFTKObject *key; 877 SFTKSessionContext *context; 878 SFTKAttribute *att; 879 #ifndef NSS_DISABLE_DEPRECATED_RC2 880 CK_RC2_CBC_PARAMS *rc2_param; 881 unsigned effectiveKeyLength; 882 #endif 883 #if NSS_SOFTOKEN_DOES_RC5 884 CK_RC5_CBC_PARAMS *rc5_param; 885 SECItem rc5Key; 886 #endif 887 CK_NSS_GCM_PARAMS nss_gcm_param; 888 void *aes_param; 889 CK_NSS_AEAD_PARAMS nss_aead_params; 890 CK_NSS_AEAD_PARAMS *nss_aead_params_ptr = NULL; 891 CK_KEY_TYPE key_type; 892 CK_RV crv = CKR_OK; 893 unsigned char newdeskey[24]; 894 PRBool useNewKey = PR_FALSE; 895 int t; 896 897 if (!pMechanism) { 898 return CKR_MECHANISM_PARAM_INVALID; 899 } 900 901 crv = sftk_MechAllowsOperation(pMechanism->mechanism, mechUsage); 902 if (crv != CKR_OK) 903 return crv; 904 905 session = sftk_SessionFromHandle(hSession); 906 if (session == NULL) 907 return CKR_SESSION_HANDLE_INVALID; 908 909 crv = sftk_InitGeneric(session, pMechanism, &context, contextType, &key, 910 hKey, &key_type, 911 isEncrypt ? CKO_PUBLIC_KEY : CKO_PRIVATE_KEY, 912 keyUsage); 913 914 if (crv != CKR_OK) { 915 sftk_FreeSession(session); 916 return crv; 917 } 918 919 context->doPad = PR_FALSE; 920 switch (pMechanism->mechanism) { 921 case CKM_RSA_PKCS: 922 case CKM_RSA_X_509: 923 if (key_type != CKK_RSA) { 924 crv = CKR_KEY_TYPE_INCONSISTENT; 925 break; 926 } 927 context->multi = PR_FALSE; 928 context->rsa = PR_TRUE; 929 if (isEncrypt) { 930 NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key, CKK_RSA, &crv); 931 if (pubKey == NULL) { 932 crv = CKR_KEY_HANDLE_INVALID; 933 break; 934 } 935 context->maxLen = nsslowkey_PublicModulusLen(pubKey); 936 context->cipherInfo = (void *)pubKey; 937 context->update = pMechanism->mechanism == CKM_RSA_X_509 938 ? sftk_RSAEncryptRaw 939 : sftk_RSAEncrypt; 940 } else { 941 NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key, CKK_RSA, &crv); 942 if (privKey == NULL) { 943 crv = CKR_KEY_HANDLE_INVALID; 944 break; 945 } 946 context->maxLen = nsslowkey_PrivateModulusLen(privKey); 947 context->cipherInfo = (void *)privKey; 948 context->update = pMechanism->mechanism == CKM_RSA_X_509 949 ? sftk_RSADecryptRaw 950 : sftk_RSADecrypt; 951 } 952 context->destroy = sftk_Null; 953 break; 954 case CKM_RSA_PKCS_OAEP: 955 if (key_type != CKK_RSA) { 956 crv = CKR_KEY_TYPE_INCONSISTENT; 957 break; 958 } 959 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS) || 960 !sftk_ValidateOaepParams((CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter)) { 961 crv = CKR_MECHANISM_PARAM_INVALID; 962 break; 963 } 964 context->multi = PR_FALSE; 965 context->rsa = PR_TRUE; 966 { 967 SFTKOAEPInfo *info; 968 CK_RSA_PKCS_OAEP_PARAMS *params = 969 (CK_RSA_PKCS_OAEP_PARAMS *)pMechanism->pParameter; 970 /* make a copy of the source data value for future 971 * use (once the user has reclaimed his data in pParameter)*/ 972 void *newSource = NULL; 973 if (params->pSourceData) { 974 newSource = PORT_Alloc(params->ulSourceDataLen); 975 if (newSource == NULL) { 976 crv = CKR_HOST_MEMORY; 977 break; 978 } 979 PORT_Memcpy(newSource, params->pSourceData, params->ulSourceDataLen); 980 } 981 info = PORT_New(SFTKOAEPInfo); 982 if (info == NULL) { 983 PORT_ZFree(newSource, params->ulSourceDataLen); 984 crv = CKR_HOST_MEMORY; 985 break; 986 } 987 info->params = *params; 988 info->params.pSourceData = newSource; 989 info->isEncrypt = isEncrypt; 990 991 /* now setup encryption and decryption contexts */ 992 if (isEncrypt) { 993 info->key.pub = sftk_GetPubKey(key, CKK_RSA, &crv); 994 if (info->key.pub == NULL) { 995 sftk_freeRSAOAEPInfo(info, PR_TRUE); 996 crv = CKR_KEY_HANDLE_INVALID; 997 break; 998 } 999 context->update = sftk_RSAEncryptOAEP; 1000 context->maxLen = nsslowkey_PublicModulusLen(info->key.pub); 1001 } else { 1002 info->key.priv = sftk_GetPrivKey(key, CKK_RSA, &crv); 1003 if (info->key.priv == NULL) { 1004 sftk_freeRSAOAEPInfo(info, PR_TRUE); 1005 crv = CKR_KEY_HANDLE_INVALID; 1006 break; 1007 } 1008 context->update = sftk_RSADecryptOAEP; 1009 context->maxLen = nsslowkey_PrivateModulusLen(info->key.priv); 1010 } 1011 context->cipherInfo = info; 1012 } 1013 context->destroy = sftk_freeRSAOAEPInfo; 1014 break; 1015 #ifndef NSS_DISABLE_DEPRECATED_RC2 1016 case CKM_RC2_CBC_PAD: 1017 context->doPad = PR_TRUE; 1018 /* fall thru */ 1019 case CKM_RC2_ECB: 1020 case CKM_RC2_CBC: 1021 context->blockSize = 8; 1022 if (key_type != CKK_RC2) { 1023 crv = CKR_KEY_TYPE_INCONSISTENT; 1024 break; 1025 } 1026 att = sftk_FindAttribute(key, CKA_VALUE); 1027 if (att == NULL) { 1028 crv = CKR_KEY_HANDLE_INVALID; 1029 break; 1030 } 1031 1032 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_CBC_PARAMS))) { 1033 crv = CKR_MECHANISM_PARAM_INVALID; 1034 break; 1035 } 1036 rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter; 1037 effectiveKeyLength = (rc2_param->ulEffectiveBits + 7) / 8; 1038 context->cipherInfo = 1039 RC2_CreateContext((unsigned char *)att->attrib.pValue, 1040 att->attrib.ulValueLen, rc2_param->iv, 1041 pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 : NSS_RC2_CBC, effectiveKeyLength); 1042 sftk_FreeAttribute(att); 1043 if (context->cipherInfo == NULL) { 1044 crv = CKR_HOST_MEMORY; 1045 break; 1046 } 1047 context->update = isEncrypt ? SFTKCipher_RC2_Encrypt : SFTKCipher_RC2_Decrypt; 1048 context->destroy = SFTKCipher_RC2_DestroyContext; 1049 break; 1050 #endif /* NSS_DISABLE_DEPRECATED_RC2 */ 1051 1052 #if NSS_SOFTOKEN_DOES_RC5 1053 case CKM_RC5_CBC_PAD: 1054 context->doPad = PR_TRUE; 1055 /* fall thru */ 1056 case CKM_RC5_ECB: 1057 case CKM_RC5_CBC: 1058 if (key_type != CKK_RC5) { 1059 crv = CKR_KEY_TYPE_INCONSISTENT; 1060 break; 1061 } 1062 att = sftk_FindAttribute(key, CKA_VALUE); 1063 if (att == NULL) { 1064 crv = CKR_KEY_HANDLE_INVALID; 1065 break; 1066 } 1067 1068 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_CBC_PARAMS))) { 1069 crv = CKR_MECHANISM_PARAM_INVALID; 1070 break; 1071 } 1072 rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter; 1073 context->blockSize = rc5_param->ulWordsize * 2; 1074 rc5Key.data = (unsigned char *)att->attrib.pValue; 1075 rc5Key.len = att->attrib.ulValueLen; 1076 context->cipherInfo = RC5_CreateContext(&rc5Key, rc5_param->ulRounds, 1077 rc5_param->ulWordsize, rc5_param->pIv, 1078 pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC); 1079 sftk_FreeAttribute(att); 1080 if (context->cipherInfo == NULL) { 1081 crv = CKR_HOST_MEMORY; 1082 break; 1083 } 1084 context->update = isEncrypt ? SFTKCipher_RC5_Encrypt : SFTKCipher_RC5_Decrypt; 1085 context->destroy = SFTKCipher_RC5_DestroyContext; 1086 break; 1087 #endif 1088 case CKM_RC4: 1089 if (key_type != CKK_RC4) { 1090 crv = CKR_KEY_TYPE_INCONSISTENT; 1091 break; 1092 } 1093 att = sftk_FindAttribute(key, CKA_VALUE); 1094 if (att == NULL) { 1095 crv = CKR_KEY_HANDLE_INVALID; 1096 break; 1097 } 1098 context->cipherInfo = 1099 RC4_CreateContext((unsigned char *)att->attrib.pValue, 1100 att->attrib.ulValueLen); 1101 sftk_FreeAttribute(att); 1102 if (context->cipherInfo == NULL) { 1103 crv = CKR_HOST_MEMORY; /* WRONG !!! */ 1104 break; 1105 } 1106 context->update = isEncrypt ? SFTKCipher_RC4_Encrypt : SFTKCipher_RC4_Decrypt; 1107 context->destroy = SFTKCipher_RC4_DestroyContext; 1108 break; 1109 case CKM_CDMF_CBC_PAD: 1110 context->doPad = PR_TRUE; 1111 /* fall thru */ 1112 case CKM_CDMF_ECB: 1113 case CKM_CDMF_CBC: 1114 if (key_type != CKK_CDMF) { 1115 crv = CKR_KEY_TYPE_INCONSISTENT; 1116 break; 1117 } 1118 t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC; 1119 goto finish_des; 1120 case CKM_DES_ECB: 1121 if (key_type != CKK_DES) { 1122 crv = CKR_KEY_TYPE_INCONSISTENT; 1123 break; 1124 } 1125 t = NSS_DES; 1126 goto finish_des; 1127 case CKM_DES_CBC_PAD: 1128 context->doPad = PR_TRUE; 1129 /* fall thru */ 1130 case CKM_DES_CBC: 1131 if (key_type != CKK_DES) { 1132 crv = CKR_KEY_TYPE_INCONSISTENT; 1133 break; 1134 } 1135 t = NSS_DES_CBC; 1136 goto finish_des; 1137 case CKM_DES3_ECB: 1138 if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) { 1139 crv = CKR_KEY_TYPE_INCONSISTENT; 1140 break; 1141 } 1142 t = NSS_DES_EDE3; 1143 goto finish_des; 1144 case CKM_DES3_CBC_PAD: 1145 context->doPad = PR_TRUE; 1146 /* fall thru */ 1147 case CKM_DES3_CBC: 1148 if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) { 1149 crv = CKR_KEY_TYPE_INCONSISTENT; 1150 break; 1151 } 1152 t = NSS_DES_EDE3_CBC; 1153 finish_des: 1154 if ((t != NSS_DES && t != NSS_DES_EDE3) && (pMechanism->pParameter == NULL || 1155 pMechanism->ulParameterLen < 8)) { 1156 crv = CKR_DOMAIN_PARAMS_INVALID; 1157 break; 1158 } 1159 context->blockSize = 8; 1160 att = sftk_FindAttribute(key, CKA_VALUE); 1161 if (att == NULL) { 1162 crv = CKR_KEY_HANDLE_INVALID; 1163 break; 1164 } 1165 if (key_type == CKK_DES2 && 1166 (t == NSS_DES_EDE3_CBC || t == NSS_DES_EDE3)) { 1167 /* extend DES2 key to DES3 key. */ 1168 memcpy(newdeskey, att->attrib.pValue, 16); 1169 memcpy(newdeskey + 16, newdeskey, 8); 1170 useNewKey = PR_TRUE; 1171 } else if (key_type == CKK_CDMF) { 1172 crv = sftk_cdmf2des((unsigned char *)att->attrib.pValue, newdeskey); 1173 if (crv != CKR_OK) { 1174 sftk_FreeAttribute(att); 1175 break; 1176 } 1177 useNewKey = PR_TRUE; 1178 } 1179 context->cipherInfo = DES_CreateContext( 1180 useNewKey ? newdeskey : (unsigned char *)att->attrib.pValue, 1181 (unsigned char *)pMechanism->pParameter, t, isEncrypt); 1182 if (useNewKey) 1183 memset(newdeskey, 0, sizeof newdeskey); 1184 sftk_FreeAttribute(att); 1185 if (context->cipherInfo == NULL) { 1186 crv = CKR_HOST_MEMORY; 1187 break; 1188 } 1189 context->update = isEncrypt ? SFTKCipher_DES_Encrypt : SFTKCipher_DES_Decrypt; 1190 context->destroy = SFTKCipher_DES_DestroyContext; 1191 break; 1192 #ifndef NSS_DISABLE_DEPRECATED_SEED 1193 case CKM_SEED_CBC_PAD: 1194 context->doPad = PR_TRUE; 1195 /* fall thru */ 1196 case CKM_SEED_CBC: 1197 if (!pMechanism->pParameter || 1198 pMechanism->ulParameterLen != 16) { 1199 crv = CKR_MECHANISM_PARAM_INVALID; 1200 break; 1201 } 1202 /* fall thru */ 1203 case CKM_SEED_ECB: 1204 context->blockSize = 16; 1205 if (key_type != CKK_SEED) { 1206 crv = CKR_KEY_TYPE_INCONSISTENT; 1207 break; 1208 } 1209 att = sftk_FindAttribute(key, CKA_VALUE); 1210 if (att == NULL) { 1211 crv = CKR_KEY_HANDLE_INVALID; 1212 break; 1213 } 1214 context->cipherInfo = SEED_CreateContext( 1215 (unsigned char *)att->attrib.pValue, 1216 (unsigned char *)pMechanism->pParameter, 1217 pMechanism->mechanism == CKM_SEED_ECB ? NSS_SEED : NSS_SEED_CBC, 1218 isEncrypt); 1219 sftk_FreeAttribute(att); 1220 if (context->cipherInfo == NULL) { 1221 crv = CKR_HOST_MEMORY; 1222 break; 1223 } 1224 context->update = isEncrypt ? SFTKCipher_SEED_Encrypt : SFTKCipher_SEED_Decrypt; 1225 context->destroy = SFTKCipher_SEED_DestroyContext; 1226 break; 1227 #endif /* NSS_DISABLE_DEPRECATED_SEED */ 1228 case CKM_CAMELLIA_CBC_PAD: 1229 context->doPad = PR_TRUE; 1230 /* fall thru */ 1231 case CKM_CAMELLIA_CBC: 1232 if (!pMechanism->pParameter || 1233 pMechanism->ulParameterLen != 16) { 1234 crv = CKR_MECHANISM_PARAM_INVALID; 1235 break; 1236 } 1237 /* fall thru */ 1238 case CKM_CAMELLIA_ECB: 1239 context->blockSize = 16; 1240 if (key_type != CKK_CAMELLIA) { 1241 crv = CKR_KEY_TYPE_INCONSISTENT; 1242 break; 1243 } 1244 att = sftk_FindAttribute(key, CKA_VALUE); 1245 if (att == NULL) { 1246 crv = CKR_KEY_HANDLE_INVALID; 1247 break; 1248 } 1249 context->cipherInfo = Camellia_CreateContext( 1250 (unsigned char *)att->attrib.pValue, 1251 (unsigned char *)pMechanism->pParameter, 1252 pMechanism->mechanism == 1253 CKM_CAMELLIA_ECB 1254 ? NSS_CAMELLIA 1255 : NSS_CAMELLIA_CBC, 1256 isEncrypt, att->attrib.ulValueLen); 1257 sftk_FreeAttribute(att); 1258 if (context->cipherInfo == NULL) { 1259 crv = CKR_HOST_MEMORY; 1260 break; 1261 } 1262 context->update = isEncrypt ? SFTKCipher_Camellia_Encrypt : SFTKCipher_Camellia_Decrypt; 1263 context->destroy = SFTKCipher_Camellia_DestroyContext; 1264 break; 1265 1266 case CKM_AES_CBC_PAD: 1267 context->doPad = PR_TRUE; 1268 /* fall thru */ 1269 case CKM_AES_ECB: 1270 case CKM_AES_CBC: 1271 context->blockSize = 16; 1272 case CKM_AES_CTS: 1273 case CKM_AES_CTR: 1274 case CKM_AES_GCM: 1275 aes_param = pMechanism->pParameter; 1276 /* 1277 * Due to a mismatch between the documentation and the header 1278 * file, two different definitions for CK_GCM_PARAMS exist. 1279 * The header file is normative according to Oasis, but NSS used 1280 * the documentation. In PKCS #11 v3.0, this was reconciled in 1281 * favor of the header file definition. To maintain binary 1282 * compatibility, NSS now defines CK_GCM_PARAMS_V3 as the official 1283 * version v3 (V2.4 header file) and CK_NSS_GCM_PARAMS as the 1284 * legacy (V2.4 documentation, NSS version). CK_GCM_PARAMS 1285 * is defined as CK_GCM_PARAMS_V3 if NSS_PKCS11_2_0_COMPAT is not 1286 * defined and CK_NSS_GCM_PARAMS if it is. Internally 1287 * softoken continues to use the legacy version. The code below 1288 * automatically detects which parameter was passed in and 1289 * converts CK_GCM_PARAMS_V3 to the CK_NSS_GCM_PARAMS (legacy 1290 * version) on the fly. NSS proper will eventually start 1291 * using the CK_GCM_PARAMS_V3 version and fall back to the 1292 * CK_NSS_GCM_PARAMS if the CK_GCM_PARAMS_V3 version fails with 1293 * CKR_MECHANISM_PARAM_INVALID. 1294 */ 1295 if (pMechanism->mechanism == CKM_AES_GCM) { 1296 if (!aes_param) { 1297 crv = CKR_MECHANISM_PARAM_INVALID; 1298 break; 1299 } 1300 if (pMechanism->ulParameterLen == sizeof(CK_GCM_PARAMS_V3)) { 1301 /* convert the true V3 parameters into the old NSS parameters */ 1302 CK_GCM_PARAMS_V3 *gcm_params = (CK_GCM_PARAMS_V3 *)aes_param; 1303 if (gcm_params->ulIvLen * 8 != gcm_params->ulIvBits) { 1304 /* only support byte aligned IV lengths */ 1305 crv = CKR_MECHANISM_PARAM_INVALID; 1306 break; 1307 } 1308 aes_param = (void *)&nss_gcm_param; 1309 nss_gcm_param.pIv = gcm_params->pIv; 1310 nss_gcm_param.ulIvLen = gcm_params->ulIvLen; 1311 nss_gcm_param.pAAD = gcm_params->pAAD; 1312 nss_gcm_param.ulAADLen = gcm_params->ulAADLen; 1313 nss_gcm_param.ulTagBits = gcm_params->ulTagBits; 1314 } else if (pMechanism->ulParameterLen != sizeof(CK_NSS_GCM_PARAMS)) { 1315 /* neither old nor new style params, must be invalid */ 1316 crv = CKR_MECHANISM_PARAM_INVALID; 1317 break; 1318 } 1319 } else if ((pMechanism->mechanism == CKM_AES_CTR && BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CTR_PARAMS))) || 1320 ((pMechanism->mechanism == CKM_AES_CBC || pMechanism->mechanism == CKM_AES_CTS) && BAD_PARAM_CAST(pMechanism, AES_BLOCK_SIZE))) { 1321 crv = CKR_MECHANISM_PARAM_INVALID; 1322 break; 1323 } 1324 1325 if (pMechanism->mechanism == CKM_AES_GCM) { 1326 context->multi = PR_FALSE; 1327 } 1328 if (key_type != CKK_AES) { 1329 crv = CKR_KEY_TYPE_INCONSISTENT; 1330 break; 1331 } 1332 att = sftk_FindAttribute(key, CKA_VALUE); 1333 if (att == NULL) { 1334 crv = CKR_KEY_HANDLE_INVALID; 1335 break; 1336 } 1337 context->cipherInfo = AES_CreateContext( 1338 (unsigned char *)att->attrib.pValue, 1339 (unsigned char *)aes_param, 1340 sftk_aes_mode(pMechanism->mechanism), 1341 isEncrypt, att->attrib.ulValueLen, 16); 1342 sftk_FreeAttribute(att); 1343 if (context->cipherInfo == NULL) { 1344 crv = CKR_HOST_MEMORY; 1345 break; 1346 } 1347 context->update = isEncrypt ? SFTKCipher_AES_Encrypt : SFTKCipher_AES_Decrypt; 1348 context->destroy = SFTKCipher_AES_DestroyContext; 1349 break; 1350 1351 case CKM_NSS_CHACHA20_POLY1305: 1352 case CKM_CHACHA20_POLY1305: 1353 if (pMechanism->mechanism == CKM_NSS_CHACHA20_POLY1305) { 1354 if (key_type != CKK_NSS_CHACHA20) { 1355 crv = CKR_KEY_TYPE_INCONSISTENT; 1356 break; 1357 } 1358 if ((pMechanism->pParameter == NULL) || 1359 (pMechanism->ulParameterLen != sizeof(CK_NSS_AEAD_PARAMS))) { 1360 crv = CKR_MECHANISM_PARAM_INVALID; 1361 break; 1362 } 1363 nss_aead_params_ptr = (CK_NSS_AEAD_PARAMS *)pMechanism->pParameter; 1364 } else { 1365 CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR chacha_poly_params; 1366 if (key_type != CKK_CHACHA20) { 1367 crv = CKR_KEY_TYPE_INCONSISTENT; 1368 break; 1369 } 1370 if ((pMechanism->pParameter == NULL) || 1371 (pMechanism->ulParameterLen != 1372 sizeof(CK_SALSA20_CHACHA20_POLY1305_PARAMS))) { 1373 crv = CKR_MECHANISM_PARAM_INVALID; 1374 break; 1375 } 1376 chacha_poly_params = (CK_SALSA20_CHACHA20_POLY1305_PARAMS_PTR) 1377 pMechanism->pParameter; 1378 nss_aead_params_ptr = &nss_aead_params; 1379 nss_aead_params.pNonce = chacha_poly_params->pNonce; 1380 nss_aead_params.ulNonceLen = chacha_poly_params->ulNonceLen; 1381 nss_aead_params.pAAD = chacha_poly_params->pAAD; 1382 nss_aead_params.ulAADLen = chacha_poly_params->ulAADLen; 1383 nss_aead_params.ulTagLen = 16; /* Poly1305 is always 16 */ 1384 } 1385 1386 context->multi = PR_FALSE; 1387 att = sftk_FindAttribute(key, CKA_VALUE); 1388 if (att == NULL) { 1389 crv = CKR_KEY_HANDLE_INVALID; 1390 break; 1391 } 1392 context->cipherInfo = sftk_ChaCha20Poly1305_CreateContext( 1393 (unsigned char *)att->attrib.pValue, att->attrib.ulValueLen, 1394 nss_aead_params_ptr); 1395 sftk_FreeAttribute(att); 1396 if (context->cipherInfo == NULL) { 1397 crv = sftk_MapCryptError(PORT_GetError()); 1398 break; 1399 } 1400 context->update = isEncrypt ? sftk_ChaCha20Poly1305_Encrypt : sftk_ChaCha20Poly1305_Decrypt; 1401 context->destroy = sftk_ChaCha20Poly1305_DestroyContext; 1402 break; 1403 1404 case CKM_NSS_CHACHA20_CTR: /* old NSS private version */ 1405 case CKM_CHACHA20: /* PKCS #11 v3 version */ 1406 { 1407 unsigned char *counter; 1408 unsigned char *nonce; 1409 unsigned long counter_len; 1410 unsigned long nonce_len; 1411 context->multi = PR_FALSE; 1412 if (pMechanism->mechanism == CKM_NSS_CHACHA20_CTR) { 1413 if (key_type != CKK_NSS_CHACHA20) { 1414 crv = CKR_KEY_TYPE_INCONSISTENT; 1415 break; 1416 } 1417 if (pMechanism->pParameter == NULL || pMechanism->ulParameterLen != 16) { 1418 crv = CKR_MECHANISM_PARAM_INVALID; 1419 break; 1420 } 1421 counter_len = 4; 1422 counter = pMechanism->pParameter; 1423 nonce = counter + 4; 1424 nonce_len = 12; 1425 } else { 1426 CK_CHACHA20_PARAMS_PTR chacha20_param_ptr; 1427 if (key_type != CKK_CHACHA20) { 1428 crv = CKR_KEY_TYPE_INCONSISTENT; 1429 break; 1430 } 1431 if (pMechanism->pParameter == NULL || pMechanism->ulParameterLen != sizeof(CK_CHACHA20_PARAMS)) { 1432 crv = CKR_MECHANISM_PARAM_INVALID; 1433 break; 1434 } 1435 chacha20_param_ptr = (CK_CHACHA20_PARAMS_PTR)pMechanism->pParameter; 1436 if ((chacha20_param_ptr->blockCounterBits != 32) && 1437 (chacha20_param_ptr->blockCounterBits != 64)) { 1438 crv = CKR_MECHANISM_PARAM_INVALID; 1439 break; 1440 } 1441 counter_len = chacha20_param_ptr->blockCounterBits / PR_BITS_PER_BYTE; 1442 counter = chacha20_param_ptr->pBlockCounter; 1443 nonce = chacha20_param_ptr->pNonce; 1444 nonce_len = chacha20_param_ptr->ulNonceBits / PR_BITS_PER_BYTE; 1445 } 1446 1447 att = sftk_FindAttribute(key, CKA_VALUE); 1448 if (att == NULL) { 1449 crv = CKR_KEY_HANDLE_INVALID; 1450 break; 1451 } 1452 SFTKChaCha20CtrInfo *ctx = PORT_ZNew(SFTKChaCha20CtrInfo); 1453 if (!ctx) { 1454 sftk_FreeAttribute(att); 1455 crv = CKR_HOST_MEMORY; 1456 break; 1457 } 1458 if (att->attrib.ulValueLen != sizeof(ctx->key)) { 1459 sftk_FreeAttribute(att); 1460 PORT_Free(ctx); 1461 crv = CKR_KEY_HANDLE_INVALID; 1462 break; 1463 } 1464 memcpy(ctx->key, att->attrib.pValue, att->attrib.ulValueLen); 1465 sftk_FreeAttribute(att); 1466 1467 /* make sure we don't overflow our parameters */ 1468 if ((sizeof(ctx->counter) < counter_len) || 1469 (sizeof(ctx->nonce) < nonce_len)) { 1470 PORT_Free(ctx); 1471 crv = CKR_MECHANISM_PARAM_INVALID; 1472 break; 1473 } 1474 1475 /* The counter is little endian. */ 1476 int i = 0; 1477 for (; i < counter_len; ++i) { 1478 ctx->counter |= (PRUint32)counter[i] << (i * 8); 1479 } 1480 memcpy(ctx->nonce, nonce, nonce_len); 1481 context->cipherInfo = ctx; 1482 context->update = sftk_ChaCha20Ctr; 1483 context->destroy = sftk_ChaCha20Ctr_DestroyContext; 1484 break; 1485 } 1486 1487 case CKM_NSS_AES_KEY_WRAP_PAD: 1488 case CKM_AES_KEY_WRAP_PAD: 1489 context->doPad = PR_TRUE; 1490 /* fall thru */ 1491 case CKM_NSS_AES_KEY_WRAP: 1492 case CKM_AES_KEY_WRAP: 1493 context->blockSize = 8; 1494 case CKM_AES_KEY_WRAP_KWP: 1495 context->multi = PR_FALSE; 1496 if (key_type != CKK_AES) { 1497 crv = CKR_KEY_TYPE_INCONSISTENT; 1498 break; 1499 } 1500 att = sftk_FindAttribute(key, CKA_VALUE); 1501 if (att == NULL) { 1502 crv = CKR_KEY_HANDLE_INVALID; 1503 break; 1504 } 1505 context->cipherInfo = AESKeyWrap_CreateContext( 1506 (unsigned char *)att->attrib.pValue, 1507 (unsigned char *)pMechanism->pParameter, 1508 isEncrypt, att->attrib.ulValueLen); 1509 sftk_FreeAttribute(att); 1510 if (context->cipherInfo == NULL) { 1511 crv = CKR_HOST_MEMORY; 1512 break; 1513 } 1514 if (pMechanism->mechanism == CKM_AES_KEY_WRAP_KWP) { 1515 context->update = isEncrypt ? SFTKCipher_AESKeyWrap_EncryptKWP 1516 : SFTKCipher_AESKeyWrap_DecryptKWP; 1517 } else { 1518 context->update = isEncrypt ? SFTKCipher_AESKeyWrap_Encrypt 1519 : SFTKCipher_AESKeyWrap_Decrypt; 1520 } 1521 context->destroy = SFTKCipher_AESKeyWrap_DestroyContext; 1522 break; 1523 1524 default: 1525 crv = CKR_MECHANISM_INVALID; 1526 break; 1527 } 1528 1529 if (crv != CKR_OK) { 1530 sftk_FreeContext(context); 1531 sftk_FreeSession(session); 1532 return crv; 1533 } 1534 sftk_SetContextByType(session, contextType, context); 1535 sftk_FreeSession(session); 1536 return CKR_OK; 1537 } 1538 1539 /* NSC_EncryptInit initializes an encryption operation. */ 1540 CK_RV 1541 NSC_EncryptInit(CK_SESSION_HANDLE hSession, 1542 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1543 { 1544 CHECK_FORK(); 1545 return sftk_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT, CKA_ENCRYPT, 1546 SFTK_ENCRYPT, PR_TRUE); 1547 } 1548 1549 /* NSC_EncryptUpdate continues a multiple-part encryption operation. */ 1550 CK_RV 1551 NSC_EncryptUpdate(CK_SESSION_HANDLE hSession, 1552 CK_BYTE_PTR pPart, CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 1553 CK_ULONG_PTR pulEncryptedPartLen) 1554 { 1555 SFTKSessionContext *context; 1556 unsigned int outlen, i; 1557 unsigned int padoutlen = 0; 1558 unsigned int maxout = *pulEncryptedPartLen; 1559 CK_RV crv; 1560 SECStatus rv; 1561 1562 CHECK_FORK(); 1563 1564 /* make sure we're legal */ 1565 crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE, NULL); 1566 if (crv != CKR_OK) 1567 return crv; 1568 1569 if (!pEncryptedPart) { 1570 if (context->doPad) { 1571 CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength; 1572 CK_ULONG blocksToSend = totalDataAvailable / context->blockSize; 1573 1574 *pulEncryptedPartLen = blocksToSend * context->blockSize; 1575 return CKR_OK; 1576 } 1577 *pulEncryptedPartLen = ulPartLen; 1578 return CKR_OK; 1579 } 1580 1581 /* do padding */ 1582 if (context->doPad) { 1583 /* deal with previous buffered data */ 1584 if (context->padDataLength != 0) { 1585 /* fill in the padded to a full block size */ 1586 for (i = context->padDataLength; 1587 (ulPartLen != 0) && i < context->blockSize; i++) { 1588 context->padBuf[i] = *pPart++; 1589 ulPartLen--; 1590 context->padDataLength++; 1591 } 1592 1593 /* not enough data to encrypt yet? then return */ 1594 if (context->padDataLength != context->blockSize) { 1595 *pulEncryptedPartLen = 0; 1596 return CKR_OK; 1597 } 1598 /* encrypt the current padded data */ 1599 rv = (*context->update)(context->cipherInfo, pEncryptedPart, 1600 &padoutlen, maxout, context->padBuf, 1601 context->blockSize); 1602 if (rv != SECSuccess) { 1603 return sftk_MapCryptError(PORT_GetError()); 1604 } 1605 pEncryptedPart += padoutlen; 1606 maxout -= padoutlen; 1607 } 1608 /* save the residual */ 1609 context->padDataLength = ulPartLen % context->blockSize; 1610 if (context->padDataLength) { 1611 PORT_Memcpy(context->padBuf, 1612 &pPart[ulPartLen - context->padDataLength], 1613 context->padDataLength); 1614 ulPartLen -= context->padDataLength; 1615 } 1616 /* if we've exhausted our new buffer, we're done */ 1617 if (ulPartLen == 0) { 1618 *pulEncryptedPartLen = padoutlen; 1619 return CKR_OK; 1620 } 1621 } 1622 1623 /* do it: NOTE: this assumes buf size in is >= buf size out! */ 1624 rv = (*context->update)(context->cipherInfo, pEncryptedPart, 1625 &outlen, maxout, pPart, ulPartLen); 1626 if (rv != SECSuccess) { 1627 return sftk_MapCryptError(PORT_GetError()); 1628 } 1629 *pulEncryptedPartLen = (CK_ULONG)(outlen + padoutlen); 1630 return CKR_OK; 1631 } 1632 1633 /* NSC_EncryptFinal finishes a multiple-part encryption operation. */ 1634 CK_RV 1635 NSC_EncryptFinal(CK_SESSION_HANDLE hSession, 1636 CK_BYTE_PTR pLastEncryptedPart, CK_ULONG_PTR pulLastEncryptedPartLen) 1637 { 1638 SFTKSession *session; 1639 SFTKSessionContext *context; 1640 unsigned int outlen, i; 1641 unsigned int maxout = *pulLastEncryptedPartLen; 1642 CK_RV crv; 1643 SECStatus rv = SECSuccess; 1644 PRBool contextFinished = PR_TRUE; 1645 1646 CHECK_FORK(); 1647 1648 /* make sure we're legal */ 1649 crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_TRUE, &session); 1650 if (crv != CKR_OK) 1651 return crv; 1652 1653 *pulLastEncryptedPartLen = 0; 1654 if (!pLastEncryptedPart) { 1655 /* caller is checking the amount of remaining data */ 1656 if (context->blockSize > 0 && context->doPad) { 1657 *pulLastEncryptedPartLen = context->blockSize; 1658 contextFinished = PR_FALSE; /* still have padding to go */ 1659 } 1660 goto finish; 1661 } 1662 1663 /* do padding */ 1664 if (context->doPad) { 1665 unsigned char padbyte = (unsigned char)(context->blockSize - context->padDataLength); 1666 /* fill out rest of pad buffer with pad magic*/ 1667 for (i = context->padDataLength; i < context->blockSize; i++) { 1668 context->padBuf[i] = padbyte; 1669 } 1670 rv = (*context->update)(context->cipherInfo, pLastEncryptedPart, 1671 &outlen, maxout, context->padBuf, context->blockSize); 1672 if (rv == SECSuccess) 1673 *pulLastEncryptedPartLen = (CK_ULONG)outlen; 1674 } 1675 1676 finish: 1677 if (contextFinished) 1678 sftk_TerminateOp(session, SFTK_ENCRYPT, context); 1679 sftk_FreeSession(session); 1680 return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); 1681 } 1682 1683 /* NSC_Encrypt encrypts single-part data. */ 1684 CK_RV 1685 NSC_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 1686 CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, 1687 CK_ULONG_PTR pulEncryptedDataLen) 1688 { 1689 SFTKSession *session; 1690 SFTKSessionContext *context; 1691 unsigned int outlen; 1692 unsigned int maxoutlen = *pulEncryptedDataLen; 1693 CK_RV crv; 1694 CK_RV crv2; 1695 SECStatus rv = SECSuccess; 1696 SECItem pText; 1697 1698 pText.type = siBuffer; 1699 pText.data = pData; 1700 pText.len = ulDataLen; 1701 1702 CHECK_FORK(); 1703 1704 /* make sure we're legal */ 1705 crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_FALSE, &session); 1706 if (crv != CKR_OK) 1707 return crv; 1708 1709 if (!pEncryptedData) { 1710 outlen = context->rsa ? context->maxLen : ulDataLen + 2 * context->blockSize; 1711 goto done; 1712 } 1713 1714 if (context->doPad) { 1715 if (context->multi) { 1716 CK_ULONG updateLen = maxoutlen; 1717 CK_ULONG finalLen; 1718 /* padding is fairly complicated, have the update and final 1719 * code deal with it */ 1720 sftk_FreeSession(session); 1721 crv = NSC_EncryptUpdate(hSession, pData, ulDataLen, pEncryptedData, 1722 &updateLen); 1723 if (crv != CKR_OK) { 1724 updateLen = 0; 1725 } 1726 maxoutlen -= updateLen; 1727 pEncryptedData += updateLen; 1728 finalLen = maxoutlen; 1729 crv2 = NSC_EncryptFinal(hSession, pEncryptedData, &finalLen); 1730 if (crv == CKR_OK && crv2 == CKR_OK) { 1731 *pulEncryptedDataLen = updateLen + finalLen; 1732 } 1733 return crv == CKR_OK ? crv2 : crv; 1734 } 1735 /* doPad without multi means that padding must be done on the first 1736 ** and only update. There will be no final. 1737 */ 1738 PORT_Assert(context->blockSize > 1); 1739 if (context->blockSize > 1) { 1740 CK_ULONG remainder = ulDataLen % context->blockSize; 1741 CK_ULONG padding = context->blockSize - remainder; 1742 pText.len += padding; 1743 pText.data = PORT_ZAlloc(pText.len); 1744 if (pText.data) { 1745 memcpy(pText.data, pData, ulDataLen); 1746 memset(pText.data + ulDataLen, padding, padding); 1747 } else { 1748 crv = CKR_HOST_MEMORY; 1749 goto fail; 1750 } 1751 } 1752 } 1753 1754 /* do it: NOTE: this assumes buf size is big enough. */ 1755 rv = (*context->update)(context->cipherInfo, pEncryptedData, 1756 &outlen, maxoutlen, pText.data, pText.len); 1757 crv = (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); 1758 if (pText.data != pData) 1759 PORT_ZFree(pText.data, pText.len); 1760 fail: 1761 sftk_TerminateOp(session, SFTK_ENCRYPT, context); 1762 done: 1763 sftk_FreeSession(session); 1764 if (crv == CKR_OK) { 1765 *pulEncryptedDataLen = (CK_ULONG)outlen; 1766 } 1767 return crv; 1768 } 1769 1770 /* 1771 ************** Crypto Functions: Decrypt ************************ 1772 */ 1773 1774 /* NSC_DecryptInit initializes a decryption operation. */ 1775 CK_RV 1776 NSC_DecryptInit(CK_SESSION_HANDLE hSession, 1777 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 1778 { 1779 CHECK_FORK(); 1780 return sftk_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT, CKA_DECRYPT, 1781 SFTK_DECRYPT, PR_FALSE); 1782 } 1783 1784 /* NSC_DecryptUpdate continues a multiple-part decryption operation. */ 1785 CK_RV 1786 NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, 1787 CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, 1788 CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) 1789 { 1790 SFTKSessionContext *context; 1791 unsigned int padoutlen = 0; 1792 unsigned int outlen; 1793 unsigned int maxout = *pulPartLen; 1794 CK_RV crv; 1795 SECStatus rv; 1796 1797 CHECK_FORK(); 1798 1799 /* make sure we're legal */ 1800 crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE, NULL); 1801 if (crv != CKR_OK) 1802 return crv; 1803 1804 /* this can only happen on an NSS programming error */ 1805 PORT_Assert((context->padDataLength == 0) || context->padDataLength == context->blockSize); 1806 1807 if (context->doPad) { 1808 /* Check the data length for block ciphers. If we are padding, 1809 * then we must be using a block cipher. In the non-padding case 1810 * the error will be returned by the underlying decryption 1811 * function when we do the actual decrypt. We need to do the 1812 * check here to avoid returning a negative length to the caller 1813 * or reading before the beginning of the pEncryptedPart buffer. 1814 */ 1815 if ((ulEncryptedPartLen == 0) || 1816 (ulEncryptedPartLen % context->blockSize) != 0) { 1817 return CKR_ENCRYPTED_DATA_LEN_RANGE; 1818 } 1819 } 1820 1821 if (!pPart) { 1822 if (context->doPad) { 1823 *pulPartLen = 1824 ulEncryptedPartLen + context->padDataLength - context->blockSize; 1825 return CKR_OK; 1826 } 1827 /* for stream ciphers there is are no constraints on ulEncryptedPartLen. 1828 * for block ciphers, it must be a multiple of blockSize. The error is 1829 * detected when this function is called again do decrypt the output. 1830 */ 1831 *pulPartLen = ulEncryptedPartLen; 1832 return CKR_OK; 1833 } 1834 1835 if (context->doPad) { 1836 /* first decrypt our saved buffer */ 1837 if (context->padDataLength != 0) { 1838 rv = (*context->update)(context->cipherInfo, pPart, &padoutlen, 1839 maxout, context->padBuf, context->blockSize); 1840 if (rv != SECSuccess) 1841 return sftk_MapDecryptError(PORT_GetError()); 1842 pPart += padoutlen; 1843 maxout -= padoutlen; 1844 } 1845 /* now save the final block for the next decrypt or the final */ 1846 PORT_Memcpy(context->padBuf, &pEncryptedPart[ulEncryptedPartLen - context->blockSize], 1847 context->blockSize); 1848 context->padDataLength = context->blockSize; 1849 ulEncryptedPartLen -= context->padDataLength; 1850 } 1851 1852 /* do it: NOTE: this assumes buf size in is >= buf size out! */ 1853 rv = (*context->update)(context->cipherInfo, pPart, &outlen, 1854 maxout, pEncryptedPart, ulEncryptedPartLen); 1855 if (rv != SECSuccess) { 1856 return sftk_MapDecryptError(PORT_GetError()); 1857 } 1858 *pulPartLen = (CK_ULONG)(outlen + padoutlen); 1859 return CKR_OK; 1860 } 1861 1862 /* NSC_DecryptFinal finishes a multiple-part decryption operation. */ 1863 CK_RV 1864 NSC_DecryptFinal(CK_SESSION_HANDLE hSession, 1865 CK_BYTE_PTR pLastPart, CK_ULONG_PTR pulLastPartLen) 1866 { 1867 SFTKSession *session; 1868 SFTKSessionContext *context; 1869 unsigned int outlen; 1870 unsigned int maxout = *pulLastPartLen; 1871 CK_RV crv; 1872 SECStatus rv = SECSuccess; 1873 1874 CHECK_FORK(); 1875 1876 /* make sure we're legal */ 1877 crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_TRUE, &session); 1878 if (crv != CKR_OK) 1879 return crv; 1880 1881 *pulLastPartLen = 0; 1882 if (!pLastPart) { 1883 /* caller is checking the amount of remaining data */ 1884 if (context->padDataLength > 0) { 1885 *pulLastPartLen = context->padDataLength; 1886 } 1887 goto finish; 1888 } 1889 1890 if (context->doPad) { 1891 /* decrypt our saved buffer */ 1892 if (context->padDataLength != 0) { 1893 /* this assumes that pLastPart is big enough to hold the *whole* 1894 * buffer!!! */ 1895 rv = (*context->update)(context->cipherInfo, pLastPart, &outlen, 1896 maxout, context->padBuf, context->blockSize); 1897 if (rv != SECSuccess) { 1898 crv = sftk_MapDecryptError(PORT_GetError()); 1899 } else { 1900 unsigned int padSize = 0; 1901 crv = sftk_CheckCBCPadding(pLastPart, outlen, 1902 context->blockSize, &padSize); 1903 /* Update pulLastPartLen, in constant time, if crv is OK */ 1904 *pulLastPartLen = PORT_CT_SEL(sftk_CKRVToMask(crv), outlen - padSize, *pulLastPartLen); 1905 } 1906 } 1907 } 1908 1909 sftk_TerminateOp(session, SFTK_DECRYPT, context); 1910 finish: 1911 sftk_FreeSession(session); 1912 return crv; 1913 } 1914 1915 /* NSC_Decrypt decrypts encrypted data in a single part. */ 1916 CK_RV 1917 NSC_Decrypt(CK_SESSION_HANDLE hSession, 1918 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, 1919 CK_ULONG_PTR pulDataLen) 1920 { 1921 SFTKSession *session; 1922 SFTKSessionContext *context; 1923 unsigned int outlen; 1924 unsigned int maxoutlen = *pulDataLen; 1925 CK_RV crv; 1926 CK_RV crv2; 1927 SECStatus rv = SECSuccess; 1928 1929 CHECK_FORK(); 1930 1931 /* make sure we're legal */ 1932 crv = sftk_GetContext(hSession, &context, SFTK_DECRYPT, PR_FALSE, &session); 1933 if (crv != CKR_OK) 1934 return crv; 1935 1936 if (!pData) { 1937 *pulDataLen = (CK_ULONG)(ulEncryptedDataLen + context->blockSize); 1938 goto done; 1939 } 1940 1941 if (context->doPad && context->multi) { 1942 CK_ULONG updateLen = maxoutlen; 1943 CK_ULONG finalLen; 1944 /* padding is fairly complicated, have the update and final 1945 * code deal with it */ 1946 sftk_FreeSession(session); 1947 crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen, 1948 pData, &updateLen); 1949 if (crv == CKR_OK) { 1950 maxoutlen -= updateLen; 1951 pData += updateLen; 1952 } 1953 finalLen = maxoutlen; 1954 crv2 = NSC_DecryptFinal(hSession, pData, &finalLen); 1955 if (crv == CKR_OK) { 1956 *pulDataLen = PORT_CT_SEL(sftk_CKRVToMask(crv2), updateLen + finalLen, *pulDataLen); 1957 return crv2; 1958 } else { 1959 return crv; 1960 } 1961 } 1962 1963 rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, 1964 pEncryptedData, ulEncryptedDataLen); 1965 /* XXX need to do MUCH better error mapping than this. */ 1966 crv = (rv == SECSuccess) ? CKR_OK : sftk_MapDecryptError(PORT_GetError()); 1967 if (rv == SECSuccess) { 1968 if (context->doPad) { 1969 unsigned int padSize = 0; 1970 crv = sftk_CheckCBCPadding(pData, outlen, context->blockSize, 1971 &padSize); 1972 /* Update pulDataLen, in constant time, if crv is OK */ 1973 *pulDataLen = PORT_CT_SEL(sftk_CKRVToMask(crv), outlen - padSize, *pulDataLen); 1974 } else { 1975 *pulDataLen = (CK_ULONG)outlen; 1976 } 1977 } 1978 sftk_TerminateOp(session, SFTK_DECRYPT, context); 1979 done: 1980 sftk_FreeSession(session); 1981 return crv; 1982 } 1983 1984 /* 1985 ************** Crypto Functions: Digest (HASH) ************************ 1986 */ 1987 1988 /* NSC_DigestInit initializes a message-digesting operation. */ 1989 CK_RV 1990 NSC_DigestInit(CK_SESSION_HANDLE hSession, 1991 CK_MECHANISM_PTR pMechanism) 1992 { 1993 SFTKSession *session; 1994 SFTKSessionContext *context; 1995 CK_RV crv = CKR_OK; 1996 1997 CHECK_FORK(); 1998 1999 session = sftk_SessionFromHandle(hSession); 2000 if (session == NULL) 2001 return CKR_SESSION_HANDLE_INVALID; 2002 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_HASH, 2003 NULL, 0, NULL, 0, CKA_DIGEST); 2004 if (crv != CKR_OK) { 2005 sftk_FreeSession(session); 2006 return crv; 2007 } 2008 2009 #define INIT_MECH(mmm) \ 2010 case CKM_##mmm: { \ 2011 mmm##Context *mmm##_ctx = mmm##_NewContext(); \ 2012 context->cipherInfo = (void *)mmm##_ctx; \ 2013 context->cipherInfoLen = mmm##_FlattenSize(mmm##_ctx); \ 2014 context->currentMech = CKM_##mmm; \ 2015 context->hashUpdate = SFTKHash_##mmm##_Update; \ 2016 context->end = SFTKHash_##mmm##_End; \ 2017 context->destroy = SFTKHash_##mmm##_DestroyContext; \ 2018 context->maxLen = mmm##_LENGTH; \ 2019 if (mmm##_ctx) \ 2020 mmm##_Begin(mmm##_ctx); \ 2021 else \ 2022 crv = CKR_HOST_MEMORY; \ 2023 break; \ 2024 } 2025 2026 switch (pMechanism->mechanism) { 2027 INIT_MECH(MD2) 2028 INIT_MECH(MD5) 2029 INIT_MECH(SHA1) 2030 INIT_MECH(SHA224) 2031 INIT_MECH(SHA256) 2032 INIT_MECH(SHA384) 2033 INIT_MECH(SHA512) 2034 INIT_MECH(SHA3_224) 2035 INIT_MECH(SHA3_256) 2036 INIT_MECH(SHA3_384) 2037 INIT_MECH(SHA3_512) 2038 2039 default: 2040 crv = CKR_MECHANISM_INVALID; 2041 break; 2042 } 2043 2044 if (crv != CKR_OK) { 2045 sftk_FreeContext(context); 2046 sftk_FreeSession(session); 2047 return crv; 2048 } 2049 sftk_SetContextByType(session, SFTK_HASH, context); 2050 sftk_FreeSession(session); 2051 return CKR_OK; 2052 } 2053 2054 /* NSC_Digest digests data in a single part. */ 2055 CK_RV 2056 NSC_Digest(CK_SESSION_HANDLE hSession, 2057 CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, 2058 CK_ULONG_PTR pulDigestLen) 2059 { 2060 SFTKSession *session; 2061 SFTKSessionContext *context; 2062 unsigned int digestLen; 2063 unsigned int maxout = *pulDigestLen; 2064 CK_RV crv; 2065 2066 CHECK_FORK(); 2067 2068 /* make sure we're legal */ 2069 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_FALSE, &session); 2070 if (crv != CKR_OK) 2071 return crv; 2072 2073 if (pDigest == NULL) { 2074 *pulDigestLen = context->maxLen; 2075 goto finish; 2076 } 2077 2078 #if (ULONG_MAX > UINT_MAX) 2079 /* The context->hashUpdate function takes an unsigned int for its data 2080 * length argument, but NSC_Digest takes an unsigned long. */ 2081 while (ulDataLen > UINT_MAX) { 2082 (*context->hashUpdate)(context->cipherInfo, pData, UINT_MAX); 2083 pData += UINT_MAX; 2084 ulDataLen -= UINT_MAX; 2085 } 2086 #endif 2087 (*context->hashUpdate)(context->cipherInfo, pData, ulDataLen); 2088 2089 /* NOTE: this assumes buf size is bigenough for the algorithm */ 2090 (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout); 2091 *pulDigestLen = digestLen; 2092 2093 sftk_TerminateOp(session, SFTK_HASH, context); 2094 finish: 2095 sftk_FreeSession(session); 2096 return CKR_OK; 2097 } 2098 2099 /* NSC_DigestUpdate continues a multiple-part message-digesting operation. */ 2100 CK_RV 2101 NSC_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 2102 CK_ULONG ulPartLen) 2103 { 2104 SFTKSessionContext *context; 2105 CK_RV crv; 2106 2107 CHECK_FORK(); 2108 2109 /* make sure we're legal */ 2110 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, NULL); 2111 if (crv != CKR_OK) 2112 return crv; 2113 2114 #if (ULONG_MAX > UINT_MAX) 2115 /* The context->hashUpdate function takes an unsigned int for its data 2116 * length argument, but NSC_DigestUpdate takes an unsigned long. */ 2117 while (ulPartLen > UINT_MAX) { 2118 (*context->hashUpdate)(context->cipherInfo, pPart, UINT_MAX); 2119 pPart += UINT_MAX; 2120 ulPartLen -= UINT_MAX; 2121 } 2122 #endif 2123 (*context->hashUpdate)(context->cipherInfo, pPart, ulPartLen); 2124 2125 return CKR_OK; 2126 } 2127 2128 /* NSC_DigestFinal finishes a multiple-part message-digesting operation. */ 2129 CK_RV 2130 NSC_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, 2131 CK_ULONG_PTR pulDigestLen) 2132 { 2133 SFTKSession *session; 2134 SFTKSessionContext *context; 2135 unsigned int maxout = *pulDigestLen; 2136 unsigned int digestLen; 2137 CK_RV crv; 2138 2139 CHECK_FORK(); 2140 2141 /* make sure we're legal */ 2142 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session); 2143 if (crv != CKR_OK) 2144 return crv; 2145 2146 if (pDigest != NULL) { 2147 (*context->end)(context->cipherInfo, pDigest, &digestLen, maxout); 2148 *pulDigestLen = digestLen; 2149 sftk_TerminateOp(session, SFTK_HASH, context); 2150 } else { 2151 *pulDigestLen = context->maxLen; 2152 } 2153 2154 sftk_FreeSession(session); 2155 return CKR_OK; 2156 } 2157 2158 /* 2159 * these helper functions are used by Generic Macing and Signing functions 2160 * that use hashes as part of their operations. 2161 */ 2162 #define DOSUB(mmm) \ 2163 static CK_RV \ 2164 sftk_doSub##mmm(SFTKSessionContext *context) \ 2165 { \ 2166 mmm##Context *mmm##_ctx = mmm##_NewContext(); \ 2167 context->hashInfo = (void *)mmm##_ctx; \ 2168 context->hashUpdate = SFTKHash_##mmm##_Update; \ 2169 context->end = SFTKHash_##mmm##_End; \ 2170 context->hashdestroy = SFTKHash_##mmm##_DestroyContext; \ 2171 if (!context->hashInfo) { \ 2172 return CKR_HOST_MEMORY; \ 2173 } \ 2174 mmm##_Begin(mmm##_ctx); \ 2175 return CKR_OK; \ 2176 } 2177 2178 DOSUB(MD2) 2179 DOSUB(MD5) 2180 DOSUB(SHA1) 2181 DOSUB(SHA224) 2182 DOSUB(SHA256) 2183 DOSUB(SHA384) 2184 DOSUB(SHA512) 2185 2186 static SECStatus 2187 sftk_SignCopy( 2188 void *copyLen, 2189 unsigned char *out, unsigned int *outLength, 2190 unsigned int maxLength, 2191 const unsigned char *hashResult, 2192 unsigned int hashResultLength) 2193 { 2194 unsigned int toCopy = *(CK_ULONG *)copyLen; 2195 if (toCopy > maxLength) { 2196 toCopy = maxLength; 2197 } 2198 if (toCopy > hashResultLength) { 2199 toCopy = hashResultLength; 2200 } 2201 memcpy(out, hashResult, toCopy); 2202 if (outLength) { 2203 *outLength = toCopy; 2204 } 2205 return SECSuccess; 2206 } 2207 2208 /* Verify is just a compare for HMAC */ 2209 static SECStatus 2210 sftk_HMACCmp(void *copyLen, const unsigned char *sig, unsigned int sigLen, 2211 const unsigned char *hash, unsigned int hashLen) 2212 { 2213 if (NSS_SecureMemcmp(sig, hash, *(CK_ULONG *)copyLen) == 0) { 2214 return SECSuccess; 2215 } 2216 2217 PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 2218 return SECFailure; 2219 } 2220 2221 /* 2222 * common HMAC + CMAC initialization routine 2223 */ 2224 static CK_RV 2225 sftk_doMACInit(CK_MECHANISM_TYPE mech, SFTKSessionContext *session, 2226 SFTKObject *key, CK_ULONG mac_size) 2227 { 2228 CK_RV crv; 2229 sftk_MACCtx *context; 2230 CK_ULONG *intpointer; 2231 PRBool isFIPS = sftk_isFIPS(key->slot->slotID); 2232 2233 /* Set up the initial context. */ 2234 crv = sftk_MAC_Create(mech, key, &context); 2235 if (crv != CKR_OK) { 2236 return crv; 2237 } 2238 2239 session->hashInfo = context; 2240 session->multi = PR_TRUE; 2241 2242 /* Required by FIPS 198 Section 4. Delay this check until after the MAC 2243 * has been initialized to steal the output size of the MAC. */ 2244 if (isFIPS && (mac_size < 4 || mac_size < context->mac_size / 2)) { 2245 sftk_MAC_DestroyContext(context, PR_TRUE); 2246 return CKR_BUFFER_TOO_SMALL; 2247 } 2248 2249 /* Configure our helper functions appropriately. Note that these casts 2250 * ignore the return values. */ 2251 session->hashUpdate = SFTKHash_sftk_MAC_Update; 2252 session->end = SFTKHash_sftk_MAC_End; 2253 session->hashdestroy = SFTKHash_sftk_MAC_DestroyContext; 2254 2255 intpointer = PORT_New(CK_ULONG); 2256 if (intpointer == NULL) { 2257 sftk_MAC_DestroyContext(context, PR_TRUE); 2258 return CKR_HOST_MEMORY; 2259 } 2260 *intpointer = mac_size; 2261 session->cipherInfo = intpointer; 2262 2263 /* Since we're only "hashing", copy the result from session->end to the 2264 * caller using sftk_SignCopy. */ 2265 session->update = sftk_SignCopy; 2266 session->verify = sftk_HMACCmp; 2267 session->destroy = sftk_Space; 2268 2269 session->maxLen = context->mac_size; 2270 2271 return CKR_OK; 2272 } 2273 2274 /* 2275 * SSL Macing support. SSL Macs are inited, then update with the base 2276 * hashing algorithm, then finalized in sign and verify 2277 */ 2278 2279 /* 2280 * FROM SSL: 2281 * 60 bytes is 3 times the maximum length MAC size that is supported. 2282 * We probably should have one copy of this table. We still need this table 2283 * in ssl to 'sign' the handshake hashes. 2284 */ 2285 static unsigned char ssl_pad_1[60] = { 2286 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 2287 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 2288 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 2289 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 2290 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 2291 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 2292 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 2293 0x36, 0x36, 0x36, 0x36 2294 }; 2295 static unsigned char ssl_pad_2[60] = { 2296 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 2297 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 2298 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 2299 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 2300 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 2301 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 2302 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 2303 0x5c, 0x5c, 0x5c, 0x5c 2304 }; 2305 2306 static SECStatus 2307 sftk_SSLMACSign(void *ctx, unsigned char *sig, unsigned int *sigLen, 2308 unsigned int maxLen, const unsigned char *hash, unsigned int hashLen) 2309 { 2310 SFTKSSLMACInfo *info = ctx; 2311 unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH]; 2312 unsigned int out; 2313 2314 info->begin(info->hashContext); 2315 info->update(info->hashContext, info->key, info->keySize); 2316 info->update(info->hashContext, ssl_pad_2, info->padSize); 2317 info->update(info->hashContext, hash, hashLen); 2318 info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH); 2319 PORT_Memcpy(sig, tmpBuf, info->macSize); 2320 PORT_Memset(tmpBuf, 0, info->macSize); 2321 *sigLen = info->macSize; 2322 return SECSuccess; 2323 } 2324 2325 static SECStatus 2326 sftk_SSLMACVerify(void *ctx, const unsigned char *sig, unsigned int sigLen, 2327 const unsigned char *hash, unsigned int hashLen) 2328 { 2329 SFTKSSLMACInfo *info = ctx; 2330 unsigned char tmpBuf[SFTK_MAX_MAC_LENGTH]; 2331 unsigned int out; 2332 int cmp; 2333 2334 info->begin(info->hashContext); 2335 info->update(info->hashContext, info->key, info->keySize); 2336 info->update(info->hashContext, ssl_pad_2, info->padSize); 2337 info->update(info->hashContext, hash, hashLen); 2338 info->end(info->hashContext, tmpBuf, &out, SFTK_MAX_MAC_LENGTH); 2339 cmp = NSS_SecureMemcmp(sig, tmpBuf, info->macSize); 2340 PORT_Memset(tmpBuf, 0, info->macSize); 2341 return (cmp == 0) ? SECSuccess : SECFailure; 2342 } 2343 2344 /* 2345 * common HMAC initalization routine 2346 */ 2347 static CK_RV 2348 sftk_doSSLMACInit(SFTKSessionContext *context, SECOidTag oid, 2349 SFTKObject *key, CK_ULONG mac_size) 2350 { 2351 SFTKAttribute *keyval; 2352 SFTKBegin begin; 2353 int padSize; 2354 SFTKSSLMACInfo *sslmacinfo; 2355 CK_RV crv = CKR_MECHANISM_INVALID; 2356 2357 if (oid == SEC_OID_SHA1) { 2358 crv = sftk_doSubSHA1(context); 2359 if (crv != CKR_OK) 2360 return crv; 2361 begin = SFTKHash_SHA1_Begin; 2362 padSize = 40; 2363 } else { 2364 crv = sftk_doSubMD5(context); 2365 if (crv != CKR_OK) 2366 return crv; 2367 begin = SFTKHash_MD5_Begin; 2368 padSize = 48; 2369 } 2370 context->multi = PR_TRUE; 2371 2372 keyval = sftk_FindAttribute(key, CKA_VALUE); 2373 if (keyval == NULL) 2374 return CKR_KEY_SIZE_RANGE; 2375 2376 context->hashUpdate(context->hashInfo, keyval->attrib.pValue, 2377 keyval->attrib.ulValueLen); 2378 context->hashUpdate(context->hashInfo, ssl_pad_1, padSize); 2379 sslmacinfo = (SFTKSSLMACInfo *)PORT_Alloc(sizeof(SFTKSSLMACInfo)); 2380 if (sslmacinfo == NULL) { 2381 sftk_FreeAttribute(keyval); 2382 return CKR_HOST_MEMORY; 2383 } 2384 sslmacinfo->size = sizeof(SFTKSSLMACInfo); 2385 sslmacinfo->macSize = mac_size; 2386 sslmacinfo->hashContext = context->hashInfo; 2387 PORT_Memcpy(sslmacinfo->key, keyval->attrib.pValue, 2388 keyval->attrib.ulValueLen); 2389 sslmacinfo->keySize = keyval->attrib.ulValueLen; 2390 sslmacinfo->begin = begin; 2391 sslmacinfo->end = context->end; 2392 sslmacinfo->update = context->hashUpdate; 2393 sslmacinfo->padSize = padSize; 2394 sftk_FreeAttribute(keyval); 2395 context->cipherInfo = (void *)sslmacinfo; 2396 context->destroy = sftk_ZSpace; 2397 context->update = sftk_SSLMACSign; 2398 context->verify = sftk_SSLMACVerify; 2399 context->maxLen = mac_size; 2400 return CKR_OK; 2401 } 2402 2403 /* 2404 ************** Crypto Functions: Sign ************************ 2405 */ 2406 2407 /** 2408 * Check if We're using CBCMacing and initialize the session context if we are. 2409 * @param contextType SFTK_SIGN or SFTK_VERIFY 2410 * @param keyUsage check whether key allows this usage 2411 */ 2412 static CK_RV 2413 sftk_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, 2414 CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE keyUsage, 2415 SFTKContextType contextType) 2416 2417 { 2418 CK_MECHANISM cbc_mechanism; 2419 CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE; 2420 #ifndef NSS_DISABLE_DEPRECATED_RC2 2421 CK_RC2_CBC_PARAMS rc2_params; 2422 #endif 2423 #if NSS_SOFTOKEN_DOES_RC5 2424 CK_RC5_CBC_PARAMS rc5_params; 2425 CK_RC5_MAC_GENERAL_PARAMS *rc5_mac; 2426 #endif 2427 unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE]; 2428 unsigned char k2[SFTK_MAX_BLOCK_SIZE]; 2429 unsigned char k3[SFTK_MAX_BLOCK_SIZE]; 2430 SFTKSessionContext *context; 2431 CK_RV crv; 2432 unsigned int blockSize; 2433 PRBool isXCBC = PR_FALSE; 2434 2435 if (!pMechanism) { 2436 return CKR_MECHANISM_PARAM_INVALID; 2437 } 2438 2439 switch (pMechanism->mechanism) { 2440 #ifndef NSS_DISABLE_DEPRECATED_RC2 2441 case CKM_RC2_MAC_GENERAL: 2442 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC2_MAC_GENERAL_PARAMS))) { 2443 return CKR_MECHANISM_PARAM_INVALID; 2444 } 2445 mac_bytes = 2446 ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength; 2447 /* fall through */ 2448 case CKM_RC2_MAC: 2449 /* this works because ulEffectiveBits is in the same place in both the 2450 * CK_RC2_MAC_GENERAL_PARAMS and CK_RC2_CBC_PARAMS */ 2451 rc2_params.ulEffectiveBits = ((CK_RC2_MAC_GENERAL_PARAMS *) 2452 pMechanism->pParameter) 2453 ->ulEffectiveBits; 2454 PORT_Memset(rc2_params.iv, 0, sizeof(rc2_params.iv)); 2455 cbc_mechanism.mechanism = CKM_RC2_CBC; 2456 cbc_mechanism.pParameter = &rc2_params; 2457 cbc_mechanism.ulParameterLen = sizeof(rc2_params); 2458 blockSize = 8; 2459 break; 2460 #endif /* NSS_DISABLE_DEPRECATED_RC2 */ 2461 2462 #if NSS_SOFTOKEN_DOES_RC5 2463 case CKM_RC5_MAC_GENERAL: 2464 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))) { 2465 return CKR_MECHANISM_PARAM_INVALID; 2466 } 2467 mac_bytes = 2468 ((CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength; 2469 /* fall through */ 2470 case CKM_RC5_MAC: 2471 /* this works because ulEffectiveBits is in the same place in both the 2472 * CK_RC5_MAC_GENERAL_PARAMS and CK_RC5_CBC_PARAMS */ 2473 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_RC5_MAC_GENERAL_PARAMS))) { 2474 return CKR_MECHANISM_PARAM_INVALID; 2475 } 2476 rc5_mac = (CK_RC5_MAC_GENERAL_PARAMS *)pMechanism->pParameter; 2477 rc5_params.ulWordsize = rc5_mac->ulWordsize; 2478 rc5_params.ulRounds = rc5_mac->ulRounds; 2479 rc5_params.pIv = ivBlock; 2480 if ((blockSize = rc5_mac->ulWordsize * 2) > SFTK_MAX_BLOCK_SIZE) 2481 return CKR_MECHANISM_PARAM_INVALID; 2482 rc5_params.ulIvLen = blockSize; 2483 PORT_Memset(ivBlock, 0, blockSize); 2484 cbc_mechanism.mechanism = CKM_RC5_CBC; 2485 cbc_mechanism.pParameter = &rc5_params; 2486 cbc_mechanism.ulParameterLen = sizeof(rc5_params); 2487 break; 2488 #endif 2489 /* add cast and idea later */ 2490 case CKM_DES_MAC_GENERAL: 2491 mac_bytes = *(CK_ULONG *)pMechanism->pParameter; 2492 /* fall through */ 2493 case CKM_DES_MAC: 2494 blockSize = 8; 2495 PORT_Memset(ivBlock, 0, blockSize); 2496 cbc_mechanism.mechanism = CKM_DES_CBC; 2497 cbc_mechanism.pParameter = &ivBlock; 2498 cbc_mechanism.ulParameterLen = blockSize; 2499 break; 2500 case CKM_DES3_MAC_GENERAL: 2501 mac_bytes = *(CK_ULONG *)pMechanism->pParameter; 2502 /* fall through */ 2503 case CKM_DES3_MAC: 2504 blockSize = 8; 2505 PORT_Memset(ivBlock, 0, blockSize); 2506 cbc_mechanism.mechanism = CKM_DES3_CBC; 2507 cbc_mechanism.pParameter = &ivBlock; 2508 cbc_mechanism.ulParameterLen = blockSize; 2509 break; 2510 case CKM_CDMF_MAC_GENERAL: 2511 mac_bytes = *(CK_ULONG *)pMechanism->pParameter; 2512 /* fall through */ 2513 case CKM_CDMF_MAC: 2514 blockSize = 8; 2515 PORT_Memset(ivBlock, 0, blockSize); 2516 cbc_mechanism.mechanism = CKM_CDMF_CBC; 2517 cbc_mechanism.pParameter = &ivBlock; 2518 cbc_mechanism.ulParameterLen = blockSize; 2519 break; 2520 #ifndef NSS_DISABLE_DEPRECATED_SEED 2521 case CKM_SEED_MAC_GENERAL: 2522 mac_bytes = *(CK_ULONG *)pMechanism->pParameter; 2523 /* fall through */ 2524 case CKM_SEED_MAC: 2525 blockSize = 16; 2526 PORT_Memset(ivBlock, 0, blockSize); 2527 cbc_mechanism.mechanism = CKM_SEED_CBC; 2528 cbc_mechanism.pParameter = &ivBlock; 2529 cbc_mechanism.ulParameterLen = blockSize; 2530 break; 2531 #endif /* NSS_DISABLE_DEPRECATED_SEED */ 2532 case CKM_CAMELLIA_MAC_GENERAL: 2533 mac_bytes = *(CK_ULONG *)pMechanism->pParameter; 2534 /* fall through */ 2535 case CKM_CAMELLIA_MAC: 2536 blockSize = 16; 2537 PORT_Memset(ivBlock, 0, blockSize); 2538 cbc_mechanism.mechanism = CKM_CAMELLIA_CBC; 2539 cbc_mechanism.pParameter = &ivBlock; 2540 cbc_mechanism.ulParameterLen = blockSize; 2541 break; 2542 case CKM_AES_MAC_GENERAL: 2543 mac_bytes = *(CK_ULONG *)pMechanism->pParameter; 2544 /* fall through */ 2545 case CKM_AES_MAC: 2546 blockSize = 16; 2547 PORT_Memset(ivBlock, 0, blockSize); 2548 cbc_mechanism.mechanism = CKM_AES_CBC; 2549 cbc_mechanism.pParameter = &ivBlock; 2550 cbc_mechanism.ulParameterLen = blockSize; 2551 break; 2552 case CKM_AES_XCBC_MAC_96: 2553 case CKM_AES_XCBC_MAC: 2554 /* The only difference between CKM_AES_XCBC_MAC 2555 * and CKM_AES_XCBC_MAC_96 is the size of the returned mac. */ 2556 mac_bytes = pMechanism->mechanism == CKM_AES_XCBC_MAC_96 ? 12 : 16; 2557 blockSize = 16; 2558 PORT_Memset(ivBlock, 0, blockSize); 2559 cbc_mechanism.mechanism = CKM_AES_CBC; 2560 cbc_mechanism.pParameter = &ivBlock; 2561 cbc_mechanism.ulParameterLen = blockSize; 2562 /* is XCBC requires extra processing at the end of the operation */ 2563 isXCBC = PR_TRUE; 2564 /* The input key is used to generate k1, k2, and k3. k2 and k3 2565 * are used at the end in the pad step. k1 replaces the input 2566 * key in the aes cbc mac */ 2567 crv = sftk_aes_xcbc_new_keys(hSession, hKey, &hKey, k2, k3); 2568 if (crv != CKR_OK) { 2569 return crv; 2570 } 2571 break; 2572 default: 2573 return CKR_FUNCTION_NOT_SUPPORTED; 2574 } 2575 2576 /* if MAC size is externally supplied, it should be checked. 2577 */ 2578 if (mac_bytes == SFTK_INVALID_MAC_SIZE) 2579 mac_bytes = blockSize >> 1; 2580 else { 2581 if (mac_bytes > blockSize) { 2582 crv = CKR_MECHANISM_PARAM_INVALID; 2583 goto fail; 2584 } 2585 } 2586 2587 crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey, 2588 CKA_ENCRYPT, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */ 2589 keyUsage, contextType, PR_TRUE); 2590 if (crv != CKR_OK) 2591 goto fail; 2592 crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL); 2593 2594 /* this shouldn't happen! */ 2595 PORT_Assert(crv == CKR_OK); 2596 if (crv != CKR_OK) 2597 goto fail; 2598 context->blockSize = blockSize; 2599 context->macSize = mac_bytes; 2600 context->isXCBC = isXCBC; 2601 if (isXCBC) { 2602 /* save the xcbc specific parameters */ 2603 PORT_Memcpy(context->k2, k2, blockSize); 2604 PORT_Memcpy(context->k3, k3, blockSize); 2605 PORT_Memset(k2, 0, blockSize); 2606 PORT_Memset(k3, 0, blockSize); 2607 /* get rid of the temp key now that the context has been created */ 2608 NSC_DestroyObject(hSession, hKey); 2609 } 2610 return CKR_OK; 2611 fail: 2612 if (isXCBC) { 2613 PORT_Memset(k2, 0, blockSize); 2614 PORT_Memset(k3, 0, blockSize); 2615 NSC_DestroyObject(hSession, hKey); /* get rid of our temp key */ 2616 } 2617 return crv; 2618 } 2619 2620 /* 2621 * encode RSA PKCS #1 Signature data before signing... 2622 */ 2623 static SECStatus 2624 sftk_RSAHashSign(void *ctx, unsigned char *sig, 2625 unsigned int *sigLen, unsigned int maxLen, 2626 const unsigned char *hash, unsigned int hashLen) 2627 { 2628 SFTKHashSignInfo *info = ctx; 2629 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); 2630 if (info->key->keyType != NSSLOWKEYRSAKey) { 2631 PORT_SetError(SEC_ERROR_INVALID_KEY); 2632 return SECFailure; 2633 } 2634 2635 return RSA_HashSign(info->hashOid, info->key, sig, sigLen, maxLen, 2636 hash, hashLen); 2637 } 2638 2639 /* XXX Old template; want to expunge it eventually. */ 2640 static DERTemplate SECAlgorithmIDTemplate[] = { 2641 { DER_SEQUENCE, 2642 0, NULL, sizeof(SECAlgorithmID) }, 2643 { DER_OBJECT_ID, 2644 offsetof(SECAlgorithmID, algorithm) }, 2645 { DER_OPTIONAL | DER_ANY, 2646 offsetof(SECAlgorithmID, parameters) }, 2647 { 0 } 2648 }; 2649 2650 /* 2651 * XXX OLD Template. Once all uses have been switched over to new one, 2652 * remove this. 2653 */ 2654 static DERTemplate SGNDigestInfoTemplate[] = { 2655 { DER_SEQUENCE, 2656 0, NULL, sizeof(SGNDigestInfo) }, 2657 { DER_INLINE, 2658 offsetof(SGNDigestInfo, digestAlgorithm), 2659 SECAlgorithmIDTemplate }, 2660 { DER_OCTET_STRING, 2661 offsetof(SGNDigestInfo, digest) }, 2662 { 0 } 2663 }; 2664 2665 /* 2666 * encode RSA PKCS #1 Signature data before signing... 2667 */ 2668 SECStatus 2669 RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key, 2670 unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, 2671 const unsigned char *hash, unsigned int hashLen) 2672 { 2673 SECStatus rv = SECFailure; 2674 SECItem digder; 2675 PLArenaPool *arena = NULL; 2676 SGNDigestInfo *di = NULL; 2677 2678 digder.data = NULL; 2679 2680 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2681 if (!arena) { 2682 goto loser; 2683 } 2684 2685 /* Construct digest info */ 2686 di = SGN_CreateDigestInfo(hashOid, hash, hashLen); 2687 if (!di) { 2688 goto loser; 2689 } 2690 2691 /* Der encode the digest as a DigestInfo */ 2692 rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di); 2693 if (rv != SECSuccess) { 2694 goto loser; 2695 } 2696 2697 /* 2698 ** Encrypt signature after constructing appropriate PKCS#1 signature 2699 ** block 2700 */ 2701 rv = RSA_Sign(&key->u.rsa, sig, sigLen, maxLen, digder.data, 2702 digder.len); 2703 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 2704 sftk_fatalError = PR_TRUE; 2705 } 2706 2707 loser: 2708 SGN_DestroyDigestInfo(di); 2709 if (arena != NULL) { 2710 PORT_FreeArena(arena, PR_TRUE); 2711 } 2712 return rv; 2713 } 2714 2715 static SECStatus 2716 sftk_RSASign(void *ctx, unsigned char *output, 2717 unsigned int *outputLen, unsigned int maxOutputLen, 2718 const unsigned char *input, unsigned int inputLen) 2719 { 2720 NSSLOWKEYPrivateKey *key = ctx; 2721 SECStatus rv = SECFailure; 2722 2723 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 2724 if (key->keyType != NSSLOWKEYRSAKey) { 2725 PORT_SetError(SEC_ERROR_INVALID_KEY); 2726 return SECFailure; 2727 } 2728 2729 rv = RSA_Sign(&key->u.rsa, output, outputLen, maxOutputLen, input, 2730 inputLen); 2731 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 2732 sftk_fatalError = PR_TRUE; 2733 } 2734 return rv; 2735 } 2736 2737 static SECStatus 2738 sftk_RSASignRaw(void *ctx, unsigned char *output, 2739 unsigned int *outputLen, unsigned int maxOutputLen, 2740 const unsigned char *input, unsigned int inputLen) 2741 { 2742 NSSLOWKEYPrivateKey *key = ctx; 2743 SECStatus rv = SECFailure; 2744 2745 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 2746 if (key->keyType != NSSLOWKEYRSAKey) { 2747 PORT_SetError(SEC_ERROR_INVALID_KEY); 2748 return SECFailure; 2749 } 2750 2751 rv = RSA_SignRaw(&key->u.rsa, output, outputLen, maxOutputLen, input, 2752 inputLen); 2753 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 2754 sftk_fatalError = PR_TRUE; 2755 } 2756 return rv; 2757 } 2758 2759 static SECStatus 2760 sftk_RSASignPSS(void *ctx, unsigned char *sig, 2761 unsigned int *sigLen, unsigned int maxLen, 2762 const unsigned char *hash, unsigned int hashLen) 2763 { 2764 SFTKPSSSignInfo *info = ctx; 2765 SECStatus rv = SECFailure; 2766 HASH_HashType hashAlg; 2767 HASH_HashType maskHashAlg; 2768 CK_RSA_PKCS_PSS_PARAMS *params = &info->params; 2769 2770 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); 2771 if (info->key->keyType != NSSLOWKEYRSAKey) { 2772 PORT_SetError(SEC_ERROR_INVALID_KEY); 2773 return SECFailure; 2774 } 2775 2776 hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg); 2777 maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf); 2778 2779 rv = RSA_SignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, NULL, 2780 params->sLen, sig, sigLen, maxLen, hash, hashLen); 2781 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 2782 sftk_fatalError = PR_TRUE; 2783 } 2784 return rv; 2785 } 2786 2787 #ifndef NSS_DISABLE_DSA 2788 static SECStatus 2789 nsc_DSA_Verify_Stub(void *ctx, const unsigned char *sigBuf, unsigned int sigLen, 2790 const unsigned char *dataBuf, unsigned int dataLen) 2791 { 2792 NSSLOWKEYPublicKey *key = ctx; 2793 SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen }; 2794 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; 2795 return DSA_VerifyDigest(&(key->u.dsa), &signature, &digest); 2796 } 2797 2798 static SECStatus 2799 nsc_DSA_Sign_Stub(void *ctx, unsigned char *sigBuf, 2800 unsigned int *sigLen, unsigned int maxSigLen, 2801 const unsigned char *dataBuf, unsigned int dataLen) 2802 { 2803 NSSLOWKEYPrivateKey *key = ctx; 2804 SECItem signature = { siBuffer, (unsigned char *)sigBuf, maxSigLen }; 2805 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; 2806 SECStatus rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest); 2807 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 2808 sftk_fatalError = PR_TRUE; 2809 } 2810 *sigLen = signature.len; 2811 return rv; 2812 } 2813 #endif 2814 2815 static SECStatus 2816 nsc_ECDSAVerifyStub(void *ctx, const unsigned char *sigBuf, unsigned int sigLen, 2817 const unsigned char *dataBuf, unsigned int dataLen) 2818 { 2819 NSSLOWKEYPublicKey *key = ctx; 2820 SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen }; 2821 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; 2822 return ECDSA_VerifyDigest(&(key->u.ec), &signature, &digest); 2823 } 2824 2825 static SECStatus 2826 nsc_ECDSASignStub(void *ctx, unsigned char *sigBuf, 2827 unsigned int *sigLen, unsigned int maxSigLen, 2828 const unsigned char *dataBuf, unsigned int dataLen) 2829 { 2830 NSSLOWKEYPrivateKey *key = ctx; 2831 SECItem signature = { siBuffer, sigBuf, maxSigLen }; 2832 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; 2833 2834 SECStatus rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest); 2835 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 2836 sftk_fatalError = PR_TRUE; 2837 } 2838 *sigLen = signature.len; 2839 return rv; 2840 } 2841 2842 static SECStatus 2843 nsc_EDDSAVerifyStub(void *ctx, const unsigned char *sigBuf, unsigned int sigLen, 2844 const unsigned char *dataBuf, unsigned int dataLen) 2845 { 2846 NSSLOWKEYPublicKey *key = ctx; 2847 SECItem signature = { siBuffer, (unsigned char *)sigBuf, sigLen }; 2848 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; 2849 return ED_VerifyMessage(&(key->u.ec), &signature, &digest); 2850 } 2851 2852 static SECStatus 2853 nsc_EDDSASignStub(void *ctx, unsigned char *sigBuf, 2854 unsigned int *sigLen, unsigned int maxSigLen, 2855 const unsigned char *dataBuf, unsigned int dataLen) 2856 { 2857 NSSLOWKEYPrivateKey *key = ctx; 2858 SECItem signature = { siBuffer, sigBuf, maxSigLen }; 2859 SECItem digest = { siBuffer, (unsigned char *)dataBuf, dataLen }; 2860 2861 SECStatus rv = ED_SignMessage(&(key->u.ec), &signature, &digest); 2862 if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 2863 sftk_fatalError = PR_TRUE; 2864 } 2865 *sigLen = signature.len; 2866 return rv; 2867 } 2868 2869 void 2870 sftk_MLDSASignUpdate(void *info, const unsigned char *data, unsigned int len) 2871 { 2872 MLDSAContext *ctptr = (MLDSAContext *)info; 2873 const SECItem inData = { siBuffer, (unsigned char *)data, len }; 2874 (void)MLDSA_SignUpdate(ctptr, &inData); 2875 } 2876 2877 void 2878 sftk_MLDSAVerifyUpdate(void *info, const unsigned char *data, unsigned int len) 2879 { 2880 MLDSAContext *ctptr = (MLDSAContext *)info; 2881 const SECItem inData = { siBuffer, (unsigned char *)data, len }; 2882 (void)MLDSA_VerifyUpdate(ctptr, &inData); 2883 } 2884 2885 SECStatus 2886 sftk_MLDSASignFinal(void *info, unsigned char *sig, unsigned int *sigLen, 2887 unsigned int maxLen, const unsigned char *data, 2888 unsigned int len) 2889 { 2890 MLDSAContext *ctptr = (MLDSAContext *)info; 2891 SECItem sigOut = { siBuffer, sig, maxLen }; 2892 SECStatus rv; 2893 2894 if (len != 0) { 2895 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 2896 return SECFailure; 2897 } 2898 2899 rv = MLDSA_SignFinal(ctptr, &sigOut); 2900 *sigLen = sigOut.len; 2901 return rv; 2902 } 2903 2904 SECStatus 2905 sftk_MLDSAVerifyFinal(void *info, const unsigned char *sig, unsigned int sigLen, 2906 const unsigned char *data, unsigned int len) 2907 { 2908 MLDSAContext *ctptr = (MLDSAContext *)info; 2909 const SECItem sigIn = { siBuffer, (unsigned char *)sig, sigLen }; 2910 2911 if (len != 0) { 2912 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 2913 return SECFailure; 2914 } 2915 2916 return MLDSA_VerifyFinal(ctptr, &sigIn); 2917 } 2918 2919 unsigned int 2920 sftk_MLDSAGetSigLen(CK_ML_DSA_PARAMETER_SET_TYPE paramSet) 2921 { 2922 switch (paramSet) { 2923 case CKP_ML_DSA_44: 2924 return ML_DSA_44_SIGNATURE_LEN; 2925 case CKP_ML_DSA_65: 2926 return ML_DSA_65_SIGNATURE_LEN; 2927 case CKP_ML_DSA_87: 2928 return ML_DSA_87_SIGNATURE_LEN; 2929 } 2930 /* this is a programming error if we get a valid DSA key with an unknown 2931 * parmaSet */ 2932 PORT_Assert(/* unknown param set */ 0); 2933 return 0; 2934 } 2935 2936 /* NSC_SignInit setups up the signing operations. There are three basic 2937 * types of signing: 2938 * (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied 2939 * to data in a single Sign operation (which often looks a lot like an 2940 * encrypt, with data coming in and data going out). 2941 * (2) Hash based signing, where we continually hash the data, then apply 2942 * some sort of signature to the end. 2943 * (3) Block Encryption CBC MAC's, where the Data is encrypted with a key, 2944 * and only the final block is part of the mac. 2945 * 2946 * For case number 3, we initialize a context much like the Encryption Context 2947 * (in fact we share code). We detect case 3 in C_SignUpdate, C_Sign, and 2948 * C_Final by the following method... if it's not multi-part, and it's doesn't 2949 * have a hash context, it must be a block Encryption CBC MAC. 2950 * 2951 * For case number 2, we initialize a hash structure, as well as make it 2952 * multi-part. Updates are simple calls to the hash update function. Final 2953 * calls the hashend, then passes the result to the 'update' function (which 2954 * operates as a final signature function). In some hash based MAC'ing (as 2955 * opposed to hash base signatures), the update function is can be simply a 2956 * copy (as is the case with HMAC). 2957 */ 2958 CK_RV 2959 NSC_SignInit(CK_SESSION_HANDLE hSession, 2960 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 2961 { 2962 SFTKSession *session; 2963 SFTKObject *key; 2964 SFTKSessionContext *context; 2965 CK_KEY_TYPE key_type; 2966 CK_RV crv = CKR_OK; 2967 NSSLOWKEYPrivateKey *privKey; 2968 SFTKHashSignInfo *info = NULL; 2969 SFTKPSSSignInfo *pinfo = NULL; 2970 2971 CHECK_FORK(); 2972 2973 /* Block Cipher MACing Algorithms use a different Context init method..*/ 2974 crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_SIGN, SFTK_SIGN); 2975 if (crv != CKR_FUNCTION_NOT_SUPPORTED) 2976 return crv; 2977 2978 /* we're not using a block cipher mac */ 2979 session = sftk_SessionFromHandle(hSession); 2980 if (session == NULL) 2981 return CKR_SESSION_HANDLE_INVALID; 2982 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_SIGN, &key, 2983 hKey, &key_type, CKO_PRIVATE_KEY, CKA_SIGN); 2984 if (crv != CKR_OK) { 2985 sftk_FreeSession(session); 2986 return crv; 2987 } 2988 2989 context->multi = PR_FALSE; 2990 2991 #define INIT_RSA_SIGN_MECH(mmm) \ 2992 case CKM_##mmm##_RSA_PKCS: \ 2993 context->multi = PR_TRUE; \ 2994 crv = sftk_doSub##mmm(context); \ 2995 if (crv != CKR_OK) \ 2996 break; \ 2997 context->update = sftk_RSAHashSign; \ 2998 info = PORT_New(SFTKHashSignInfo); \ 2999 if (info == NULL) { \ 3000 crv = CKR_HOST_MEMORY; \ 3001 break; \ 3002 } \ 3003 info->hashOid = SEC_OID_##mmm; \ 3004 goto finish_rsa; 3005 3006 switch (pMechanism->mechanism) { 3007 INIT_RSA_SIGN_MECH(MD5) 3008 INIT_RSA_SIGN_MECH(MD2) 3009 INIT_RSA_SIGN_MECH(SHA1) 3010 INIT_RSA_SIGN_MECH(SHA224) 3011 INIT_RSA_SIGN_MECH(SHA256) 3012 INIT_RSA_SIGN_MECH(SHA384) 3013 INIT_RSA_SIGN_MECH(SHA512) 3014 3015 case CKM_RSA_PKCS: 3016 context->update = sftk_RSASign; 3017 goto finish_rsa; 3018 case CKM_RSA_X_509: 3019 context->update = sftk_RSASignRaw; 3020 finish_rsa: 3021 if (key_type != CKK_RSA) { 3022 crv = CKR_KEY_TYPE_INCONSISTENT; 3023 break; 3024 } 3025 context->rsa = PR_TRUE; 3026 privKey = sftk_GetPrivKey(key, CKK_RSA, &crv); 3027 if (privKey == NULL) { 3028 crv = CKR_KEY_TYPE_INCONSISTENT; 3029 break; 3030 } 3031 /* OK, info is allocated only if we're doing hash and sign mechanism. 3032 * It's necessary to be able to set the correct OID in the final 3033 * signature. 3034 */ 3035 if (info) { 3036 info->key = privKey; 3037 context->cipherInfo = info; 3038 context->destroy = sftk_Space; 3039 } else { 3040 context->cipherInfo = privKey; 3041 context->destroy = sftk_Null; 3042 } 3043 context->maxLen = nsslowkey_PrivateModulusLen(privKey); 3044 break; 3045 3046 #define INIT_RSA_PSS_SIG_MECH(mmm) \ 3047 case CKM_##mmm##_RSA_PKCS_PSS: \ 3048 context->multi = PR_TRUE; \ 3049 crv = sftk_doSub##mmm(context); \ 3050 if (crv != CKR_OK) \ 3051 break; \ 3052 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS)) { \ 3053 crv = CKR_MECHANISM_PARAM_INVALID; \ 3054 break; \ 3055 } \ 3056 if (((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)->hashAlg != CKM_##mmm) { \ 3057 crv = CKR_MECHANISM_PARAM_INVALID; \ 3058 break; \ 3059 } \ 3060 goto finish_rsa_pss; 3061 INIT_RSA_PSS_SIG_MECH(SHA1) 3062 INIT_RSA_PSS_SIG_MECH(SHA224) 3063 INIT_RSA_PSS_SIG_MECH(SHA256) 3064 INIT_RSA_PSS_SIG_MECH(SHA384) 3065 INIT_RSA_PSS_SIG_MECH(SHA512) 3066 case CKM_RSA_PKCS_PSS: 3067 finish_rsa_pss: 3068 if (key_type != CKK_RSA) { 3069 crv = CKR_KEY_TYPE_INCONSISTENT; 3070 break; 3071 } 3072 context->rsa = PR_TRUE; 3073 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) || 3074 !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) { 3075 crv = CKR_MECHANISM_PARAM_INVALID; 3076 break; 3077 } 3078 pinfo = PORT_New(SFTKPSSSignInfo); 3079 if (pinfo == NULL) { 3080 crv = CKR_HOST_MEMORY; 3081 break; 3082 } 3083 pinfo->size = sizeof(SFTKPSSSignInfo); 3084 pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; 3085 pinfo->key = sftk_GetPrivKey(key, CKK_RSA, &crv); 3086 if (pinfo->key == NULL) { 3087 crv = CKR_KEY_TYPE_INCONSISTENT; 3088 break; 3089 } 3090 context->cipherInfo = pinfo; 3091 context->destroy = sftk_ZSpace; 3092 context->update = sftk_RSASignPSS; 3093 context->maxLen = nsslowkey_PrivateModulusLen(pinfo->key); 3094 break; 3095 3096 #ifndef NSS_DISABLE_DSA 3097 #define INIT_DSA_SIG_MECH(mmm) \ 3098 case CKM_DSA_##mmm: \ 3099 context->multi = PR_TRUE; \ 3100 crv = sftk_doSub##mmm(context); \ 3101 if (crv != CKR_OK) \ 3102 break; \ 3103 goto finish_dsa; 3104 INIT_DSA_SIG_MECH(SHA1) 3105 INIT_DSA_SIG_MECH(SHA224) 3106 INIT_DSA_SIG_MECH(SHA256) 3107 INIT_DSA_SIG_MECH(SHA384) 3108 INIT_DSA_SIG_MECH(SHA512) 3109 case CKM_DSA: 3110 finish_dsa: 3111 if (key_type != CKK_DSA) { 3112 crv = CKR_KEY_TYPE_INCONSISTENT; 3113 break; 3114 } 3115 privKey = sftk_GetPrivKey(key, CKK_DSA, &crv); 3116 if (privKey == NULL) { 3117 break; 3118 } 3119 context->cipherInfo = privKey; 3120 context->update = nsc_DSA_Sign_Stub; 3121 context->destroy = (privKey == key->objectInfo) ? sftk_Null : sftk_FreePrivKey; 3122 context->maxLen = DSA_MAX_SIGNATURE_LEN; 3123 3124 break; 3125 #endif 3126 case CKM_ML_DSA: { 3127 /* set our defaults */ 3128 CK_HEDGE_TYPE hedgeType = CKH_HEDGE_PREFERRED; 3129 SECItem signCtx = { siBuffer, NULL, 0 }; 3130 MLDSAContext *ctptr = NULL; 3131 SECStatus rv; 3132 3133 /* make sure we have the right key type */ 3134 if (key_type != CKK_ML_DSA) { 3135 crv = CKR_KEY_TYPE_INCONSISTENT; 3136 break; 3137 } 3138 /* fill in our parameters from the mechanism parameters if 3139 * supplied */ 3140 if (pMechanism->ulParameterLen != 0) { 3141 CK_SIGN_ADDITIONAL_CONTEXT *param; 3142 if (pMechanism->ulParameterLen != 3143 sizeof(CK_SIGN_ADDITIONAL_CONTEXT)) { 3144 crv = CKR_MECHANISM_PARAM_INVALID; 3145 break; 3146 } 3147 param = (CK_SIGN_ADDITIONAL_CONTEXT *)pMechanism->pParameter; 3148 hedgeType = param->hedgeVariant; 3149 signCtx.data = param->pContext; 3150 signCtx.len = param->ulContextLen; 3151 } 3152 /* fetch the key */ 3153 privKey = sftk_GetPrivKey(key, key_type, &crv); 3154 if (privKey == NULL) { 3155 crv = CKR_HOST_MEMORY; 3156 break; 3157 } 3158 /* now initialize it the signature */ 3159 rv = MLDSA_SignInit(&privKey->u.mldsa, hedgeType, &signCtx, &ctptr); 3160 if (rv != SECSuccess) { 3161 crv = sftk_MapCryptError(PORT_GetError()); 3162 if (privKey != key->objectInfo) { 3163 nsslowkey_DestroyPrivateKey(privKey); 3164 } 3165 break; 3166 } 3167 /* set up our cipher info. MLDSA is only a combined hash/sign 3168 * so the hash update is our sign update, the hash end is a null 3169 * function returning a zero length value, and the final gets our 3170 * signature based on the context. Both the cipher context and the 3171 * hash Info is the same. The MLDSA_SignFinal frees the context, 3172 * so we don't have to */ 3173 context->multi = PR_TRUE; 3174 context->cipherInfo = ctptr; 3175 context->hashInfo = ctptr; 3176 context->hashUpdate = sftk_MLDSASignUpdate; 3177 context->end = sftk_NullHashEnd; 3178 context->hashdestroy = sftk_Null; 3179 context->destroy = sftk_Null; 3180 context->update = sftk_MLDSASignFinal; 3181 context->maxLen = sftk_MLDSAGetSigLen(privKey->u.mldsa.paramSet); 3182 if (privKey != key->objectInfo) { 3183 nsslowkey_DestroyPrivateKey(privKey); 3184 } 3185 break; 3186 } 3187 3188 #define INIT_ECDSA_SIG_MECH(mmm) \ 3189 case CKM_ECDSA_##mmm: \ 3190 context->multi = PR_TRUE; \ 3191 crv = sftk_doSub##mmm(context); \ 3192 if (crv != CKR_OK) \ 3193 break; \ 3194 goto finish_ecdsa; 3195 INIT_ECDSA_SIG_MECH(SHA1) 3196 INIT_ECDSA_SIG_MECH(SHA224) 3197 INIT_ECDSA_SIG_MECH(SHA256) 3198 INIT_ECDSA_SIG_MECH(SHA384) 3199 INIT_ECDSA_SIG_MECH(SHA512) 3200 case CKM_ECDSA: 3201 finish_ecdsa: 3202 if (key_type != CKK_EC) { 3203 crv = CKR_KEY_TYPE_INCONSISTENT; 3204 break; 3205 } 3206 privKey = sftk_GetPrivKey(key, CKK_EC, &crv); 3207 if (privKey == NULL) { 3208 crv = CKR_HOST_MEMORY; 3209 break; 3210 } 3211 context->cipherInfo = privKey; 3212 context->update = nsc_ECDSASignStub; 3213 context->destroy = (privKey == key->objectInfo) ? sftk_Null : sftk_FreePrivKey; 3214 context->maxLen = MAX_ECKEY_LEN * 2; 3215 3216 break; 3217 3218 case CKM_EDDSA: 3219 if (key_type != CKK_EC_EDWARDS) { 3220 crv = CKR_KEY_TYPE_INCONSISTENT; 3221 break; 3222 } 3223 3224 if (pMechanism->pParameter) { 3225 crv = CKR_MECHANISM_PARAM_INVALID; 3226 break; 3227 } 3228 3229 privKey = sftk_GetPrivKey(key, CKK_EC_EDWARDS, &crv); 3230 if (privKey == NULL) { 3231 crv = CKR_HOST_MEMORY; 3232 break; 3233 } 3234 context->cipherInfo = privKey; 3235 context->update = nsc_EDDSASignStub; 3236 context->destroy = (privKey == key->objectInfo) ? sftk_Null : sftk_FreePrivKey; 3237 context->maxLen = MAX_ECKEY_LEN * 2; 3238 3239 break; 3240 3241 #define INIT_HMAC_MECH(mmm) \ 3242 case CKM_##mmm##_HMAC_GENERAL: \ 3243 PORT_Assert(pMechanism->pParameter); \ 3244 if (!pMechanism->pParameter) { \ 3245 crv = CKR_MECHANISM_PARAM_INVALID; \ 3246 break; \ 3247 } \ 3248 crv = sftk_doMACInit(pMechanism->mechanism, context, key, \ 3249 *(CK_ULONG *)pMechanism->pParameter); \ 3250 break; \ 3251 case CKM_##mmm##_HMAC: \ 3252 crv = sftk_doMACInit(pMechanism->mechanism, context, key, \ 3253 mmm##_LENGTH); \ 3254 break; 3255 3256 INIT_HMAC_MECH(MD2) 3257 INIT_HMAC_MECH(MD5) 3258 INIT_HMAC_MECH(SHA1) 3259 INIT_HMAC_MECH(SHA224) 3260 INIT_HMAC_MECH(SHA256) 3261 INIT_HMAC_MECH(SHA384) 3262 INIT_HMAC_MECH(SHA512) 3263 INIT_HMAC_MECH(SHA3_224) 3264 INIT_HMAC_MECH(SHA3_256) 3265 INIT_HMAC_MECH(SHA3_384) 3266 INIT_HMAC_MECH(SHA3_512) 3267 3268 case CKM_AES_CMAC_GENERAL: 3269 PORT_Assert(pMechanism->pParameter); 3270 if (!pMechanism->pParameter || pMechanism->ulParameterLen != sizeof(CK_MAC_GENERAL_PARAMS)) { 3271 crv = CKR_MECHANISM_PARAM_INVALID; 3272 break; 3273 } 3274 crv = sftk_doMACInit(pMechanism->mechanism, context, key, *(CK_ULONG *)pMechanism->pParameter); 3275 break; 3276 case CKM_AES_CMAC: 3277 crv = sftk_doMACInit(pMechanism->mechanism, context, key, AES_BLOCK_SIZE); 3278 break; 3279 case CKM_SSL3_MD5_MAC: 3280 PORT_Assert(pMechanism->pParameter); 3281 if (!pMechanism->pParameter) { 3282 crv = CKR_MECHANISM_PARAM_INVALID; 3283 break; 3284 } 3285 crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key, 3286 *(CK_ULONG *)pMechanism->pParameter); 3287 break; 3288 case CKM_SSL3_SHA1_MAC: 3289 PORT_Assert(pMechanism->pParameter); 3290 if (!pMechanism->pParameter) { 3291 crv = CKR_MECHANISM_PARAM_INVALID; 3292 break; 3293 } 3294 crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key, 3295 *(CK_ULONG *)pMechanism->pParameter); 3296 break; 3297 case CKM_TLS_PRF_GENERAL: 3298 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0); 3299 break; 3300 case CKM_TLS_MAC: { 3301 CK_TLS_MAC_PARAMS *tls12_mac_params; 3302 HASH_HashType tlsPrfHash; 3303 const char *label; 3304 3305 if (pMechanism->ulParameterLen != sizeof(CK_TLS_MAC_PARAMS)) { 3306 crv = CKR_MECHANISM_PARAM_INVALID; 3307 break; 3308 } 3309 tls12_mac_params = (CK_TLS_MAC_PARAMS *)pMechanism->pParameter; 3310 if (tls12_mac_params->prfHashMechanism == CKM_TLS_PRF) { 3311 /* The TLS 1.0 and 1.1 PRF */ 3312 tlsPrfHash = HASH_AlgNULL; 3313 if (tls12_mac_params->ulMacLength != 12) { 3314 crv = CKR_MECHANISM_PARAM_INVALID; 3315 break; 3316 } 3317 } else { 3318 /* The hash function for the TLS 1.2 PRF */ 3319 tlsPrfHash = 3320 sftk_GetHashTypeFromMechanism(tls12_mac_params->prfHashMechanism); 3321 if (tlsPrfHash == HASH_AlgNULL || 3322 tls12_mac_params->ulMacLength < 12) { 3323 crv = CKR_MECHANISM_PARAM_INVALID; 3324 break; 3325 } 3326 } 3327 if (tls12_mac_params->ulServerOrClient == 1) { 3328 label = "server finished"; 3329 } else if (tls12_mac_params->ulServerOrClient == 2) { 3330 label = "client finished"; 3331 } else { 3332 crv = CKR_MECHANISM_PARAM_INVALID; 3333 break; 3334 } 3335 crv = sftk_TLSPRFInit(context, key, key_type, tlsPrfHash, 3336 tls12_mac_params->ulMacLength); 3337 if (crv == CKR_OK) { 3338 context->hashUpdate(context->hashInfo, (unsigned char *)label, 15); 3339 } 3340 break; 3341 } 3342 case CKM_NSS_TLS_PRF_GENERAL_SHA256: 3343 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0); 3344 break; 3345 3346 case CKM_NSS_HMAC_CONSTANT_TIME: { 3347 sftk_MACConstantTimeCtx *ctx = 3348 sftk_HMACConstantTime_New(pMechanism, key); 3349 CK_ULONG *intpointer; 3350 3351 if (ctx == NULL) { 3352 crv = CKR_ARGUMENTS_BAD; 3353 break; 3354 } 3355 intpointer = PORT_New(CK_ULONG); 3356 if (intpointer == NULL) { 3357 PORT_Free(ctx); 3358 crv = CKR_HOST_MEMORY; 3359 break; 3360 } 3361 *intpointer = ctx->hash->length; 3362 3363 context->cipherInfo = intpointer; 3364 context->hashInfo = ctx; 3365 context->currentMech = pMechanism->mechanism; 3366 context->hashUpdate = sftk_HMACConstantTime_Update; 3367 context->hashdestroy = sftk_MACConstantTime_DestroyContext; 3368 context->end = sftk_MACConstantTime_EndHash; 3369 context->update = sftk_SignCopy; 3370 context->destroy = sftk_Space; 3371 context->maxLen = 64; 3372 context->multi = PR_TRUE; 3373 break; 3374 } 3375 3376 case CKM_NSS_SSL3_MAC_CONSTANT_TIME: { 3377 sftk_MACConstantTimeCtx *ctx = 3378 sftk_SSLv3MACConstantTime_New(pMechanism, key); 3379 CK_ULONG *intpointer; 3380 3381 if (ctx == NULL) { 3382 crv = CKR_ARGUMENTS_BAD; 3383 break; 3384 } 3385 intpointer = PORT_New(CK_ULONG); 3386 if (intpointer == NULL) { 3387 PORT_Free(ctx); 3388 crv = CKR_HOST_MEMORY; 3389 break; 3390 } 3391 *intpointer = ctx->hash->length; 3392 3393 context->cipherInfo = intpointer; 3394 context->hashInfo = ctx; 3395 context->currentMech = pMechanism->mechanism; 3396 context->hashUpdate = sftk_SSLv3MACConstantTime_Update; 3397 context->hashdestroy = sftk_MACConstantTime_DestroyContext; 3398 context->end = sftk_MACConstantTime_EndHash; 3399 context->update = sftk_SignCopy; 3400 context->destroy = sftk_Space; 3401 context->maxLen = 64; 3402 context->multi = PR_TRUE; 3403 break; 3404 } 3405 3406 default: 3407 crv = CKR_MECHANISM_INVALID; 3408 break; 3409 } 3410 3411 if (crv != CKR_OK) { 3412 if (info) 3413 PORT_Free(info); 3414 if (pinfo) 3415 PORT_ZFree(pinfo, pinfo->size); 3416 sftk_FreeContext(context); 3417 sftk_FreeSession(session); 3418 return crv; 3419 } 3420 sftk_SetContextByType(session, SFTK_SIGN, context); 3421 sftk_FreeSession(session); 3422 return CKR_OK; 3423 } 3424 3425 /** MAC one block of data by block cipher 3426 */ 3427 static CK_RV 3428 sftk_MACBlock(SFTKSessionContext *ctx, void *blk) 3429 { 3430 unsigned int outlen; 3431 return (SECSuccess == (ctx->update)(ctx->cipherInfo, ctx->macBuf, &outlen, 3432 SFTK_MAX_BLOCK_SIZE, blk, ctx->blockSize)) 3433 ? CKR_OK 3434 : sftk_MapCryptError(PORT_GetError()); 3435 } 3436 3437 /** MAC last (incomplete) block of data by block cipher 3438 * 3439 * Call once, then terminate MACing operation. 3440 */ 3441 static CK_RV 3442 sftk_MACFinal(SFTKSessionContext *ctx) 3443 { 3444 unsigned int padLen = ctx->padDataLength; 3445 /* pad and proceed the residual */ 3446 if (ctx->isXCBC) { 3447 CK_RV crv = sftk_xcbc_mac_pad(ctx->padBuf, padLen, ctx->blockSize, 3448 ctx->k2, ctx->k3); 3449 if (crv != CKR_OK) 3450 return crv; 3451 return sftk_MACBlock(ctx, ctx->padBuf); 3452 } 3453 if (padLen) { 3454 /* shd clr ctx->padLen to make sftk_MACFinal idempotent */ 3455 PORT_Memset(ctx->padBuf + padLen, 0, ctx->blockSize - padLen); 3456 return sftk_MACBlock(ctx, ctx->padBuf); 3457 } else 3458 return CKR_OK; 3459 } 3460 3461 /** The common implementation for {Sign,Verify}Update. (S/V only vary in their 3462 * setup and final operations). 3463 * 3464 * A call which results in an error terminates the operation [PKCS#11,v2.11] 3465 */ 3466 static CK_RV 3467 sftk_MACUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 3468 CK_ULONG ulPartLen, SFTKContextType type) 3469 { 3470 SFTKSession *session; 3471 SFTKSessionContext *context; 3472 CK_RV crv; 3473 3474 /* make sure we're legal */ 3475 crv = sftk_GetContext(hSession, &context, type, PR_TRUE, &session); 3476 if (crv != CKR_OK) 3477 return crv; 3478 3479 if (context->hashInfo) { 3480 #if (ULONG_MAX > UINT_MAX) 3481 while (ulPartLen > UINT_MAX) { 3482 (*context->hashUpdate)(context->cipherInfo, pPart, UINT_MAX); 3483 pPart += UINT_MAX; 3484 ulPartLen -= UINT_MAX; 3485 } 3486 #endif 3487 (*context->hashUpdate)(context->hashInfo, pPart, ulPartLen); 3488 } else { 3489 /* must be block cipher MACing */ 3490 3491 unsigned int blkSize = context->blockSize; 3492 unsigned char *residual = /* free room in context->padBuf */ 3493 context->padBuf + context->padDataLength; 3494 unsigned int minInput = /* min input for MACing at least one block */ 3495 blkSize - context->padDataLength; 3496 3497 /* not enough data even for one block */ 3498 if (ulPartLen <= minInput) { 3499 PORT_Memcpy(residual, pPart, ulPartLen); 3500 context->padDataLength += ulPartLen; 3501 goto cleanup; 3502 } 3503 /* MACing residual */ 3504 if (context->padDataLength) { 3505 PORT_Memcpy(residual, pPart, minInput); 3506 ulPartLen -= minInput; 3507 pPart += minInput; 3508 if (CKR_OK != (crv = sftk_MACBlock(context, context->padBuf))) 3509 goto terminate; 3510 } 3511 /* MACing full blocks */ 3512 while (ulPartLen > blkSize) { 3513 if (CKR_OK != (crv = sftk_MACBlock(context, pPart))) 3514 goto terminate; 3515 ulPartLen -= blkSize; 3516 pPart += blkSize; 3517 } 3518 /* save the residual */ 3519 if ((context->padDataLength = ulPartLen)) 3520 PORT_Memcpy(context->padBuf, pPart, ulPartLen); 3521 } /* blk cipher MACing */ 3522 3523 goto cleanup; 3524 3525 terminate: 3526 sftk_TerminateOp(session, type, context); 3527 cleanup: 3528 sftk_FreeSession(session); 3529 return crv; 3530 } 3531 3532 /* NSC_SignUpdate continues a multiple-part signature operation, 3533 * where the signature is (will be) an appendix to the data, 3534 * and plaintext cannot be recovered from the signature 3535 * 3536 * A call which results in an error terminates the operation [PKCS#11,v2.11] 3537 */ 3538 CK_RV 3539 NSC_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 3540 CK_ULONG ulPartLen) 3541 { 3542 CHECK_FORK(); 3543 return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_SIGN); 3544 } 3545 3546 struct SFTK_SESSION_FLAGS { 3547 CK_FLAGS flag; 3548 SFTKContextType type; 3549 }; 3550 3551 const static struct SFTK_SESSION_FLAGS sftk_session_flags[] = { 3552 { CKF_ENCRYPT, SFTK_ENCRYPT }, 3553 { CKF_DECRYPT, SFTK_DECRYPT }, 3554 { CKF_DIGEST, SFTK_HASH }, 3555 { CKF_SIGN, SFTK_SIGN }, 3556 { CKF_SIGN_RECOVER, SFTK_SIGN_RECOVER }, 3557 { CKF_VERIFY, SFTK_VERIFY }, 3558 { CKF_VERIFY_RECOVER, SFTK_VERIFY_RECOVER }, 3559 { CKF_MESSAGE_ENCRYPT, SFTK_MESSAGE_ENCRYPT }, 3560 { CKF_MESSAGE_DECRYPT, SFTK_MESSAGE_DECRYPT }, 3561 { CKF_MESSAGE_SIGN, SFTK_MESSAGE_SIGN }, 3562 { CKF_MESSAGE_VERIFY, SFTK_MESSAGE_VERIFY }, 3563 }; 3564 const static int sftk_flag_count = PR_ARRAY_SIZE(sftk_session_flags); 3565 3566 /* 3567 * Cancel one or more operations running on the existing session. 3568 */ 3569 CK_RV 3570 NSC_SessionCancel(CK_SESSION_HANDLE hSession, CK_FLAGS flags) 3571 { 3572 SFTKSession *session; 3573 SFTKSessionContext *context; 3574 CK_RV gcrv = CKR_OK; 3575 CK_RV crv; 3576 int i; 3577 3578 for (i = 0; i < sftk_flag_count; i++) { 3579 if (flags & sftk_session_flags[i].flag) { 3580 flags &= ~sftk_session_flags[i].flag; 3581 crv = sftk_GetContext(hSession, &context, sftk_session_flags[i].type, PR_TRUE, &session); 3582 if (crv != CKR_OK) { 3583 gcrv = CKR_OPERATION_CANCEL_FAILED; 3584 continue; 3585 } 3586 sftk_TerminateOp(session, sftk_session_flags[i].type, context); 3587 } 3588 } 3589 if (flags & CKF_FIND_OBJECTS) { 3590 flags &= ~CKF_FIND_OBJECTS; 3591 crv = NSC_FindObjectsFinal(hSession); 3592 if (crv != CKR_OK) { 3593 gcrv = CKR_OPERATION_CANCEL_FAILED; 3594 } 3595 } 3596 if (flags) { 3597 gcrv = CKR_OPERATION_CANCEL_FAILED; 3598 } 3599 return gcrv; 3600 } 3601 3602 /* NSC_SignFinal finishes a multiple-part signature operation, 3603 * returning the signature. */ 3604 CK_RV 3605 NSC_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, 3606 CK_ULONG_PTR pulSignatureLen) 3607 { 3608 SFTKSession *session; 3609 SFTKSessionContext *context; 3610 unsigned int outlen; 3611 unsigned int maxoutlen = *pulSignatureLen; 3612 CK_RV crv; 3613 3614 CHECK_FORK(); 3615 3616 /* make sure we're legal */ 3617 crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_TRUE, &session); 3618 if (crv != CKR_OK) 3619 return crv; 3620 3621 if (context->hashInfo) { 3622 unsigned int digestLen; 3623 unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH]; 3624 3625 if (!pSignature) { 3626 outlen = context->maxLen; 3627 goto finish; 3628 } 3629 (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf)); 3630 if (SECSuccess != (context->update)(context->cipherInfo, pSignature, 3631 &outlen, maxoutlen, tmpbuf, digestLen)) 3632 crv = sftk_MapCryptError(PORT_GetError()); 3633 /* CKR_BUFFER_TOO_SMALL here isn't continuable, let operation terminate. 3634 * Keeping "too small" CK_RV intact is a standard violation, but allows 3635 * application read EXACT signature length */ 3636 PORT_Memset(tmpbuf, 0, sizeof tmpbuf); 3637 } else { 3638 /* must be block cipher MACing */ 3639 outlen = context->macSize; 3640 /* null or "too small" buf doesn't terminate operation [PKCS#11,v2.11]*/ 3641 if (!pSignature || maxoutlen < outlen) { 3642 if (pSignature) 3643 crv = CKR_BUFFER_TOO_SMALL; 3644 goto finish; 3645 } 3646 if (CKR_OK == (crv = sftk_MACFinal(context))) 3647 PORT_Memcpy(pSignature, context->macBuf, outlen); 3648 } 3649 3650 sftk_TerminateOp(session, SFTK_SIGN, context); 3651 finish: 3652 *pulSignatureLen = outlen; 3653 sftk_FreeSession(session); 3654 return crv; 3655 } 3656 3657 /* NSC_Sign signs (encrypts with private key) data in a single part, 3658 * where the signature is (will be) an appendix to the data, 3659 * and plaintext cannot be recovered from the signature */ 3660 CK_RV 3661 NSC_Sign(CK_SESSION_HANDLE hSession, 3662 CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, 3663 CK_ULONG_PTR pulSignatureLen) 3664 { 3665 SFTKSession *session; 3666 SFTKSessionContext *context; 3667 CK_RV crv; 3668 3669 CHECK_FORK(); 3670 3671 /* make sure we're legal */ 3672 crv = sftk_GetContext(hSession, &context, SFTK_SIGN, PR_FALSE, &session); 3673 if (crv != CKR_OK) 3674 return crv; 3675 3676 if (!pSignature) { 3677 /* see also how C_SignUpdate implements this */ 3678 *pulSignatureLen = (!context->multi || context->hashInfo) 3679 ? context->maxLen 3680 : context->macSize; /* must be block cipher MACing */ 3681 goto finish; 3682 } 3683 3684 /* multi part Signing are completely implemented by SignUpdate and 3685 * sign Final */ 3686 if (context->multi) { 3687 /* SignFinal can't follow failed SignUpdate */ 3688 if (CKR_OK == (crv = NSC_SignUpdate(hSession, pData, ulDataLen))) 3689 crv = NSC_SignFinal(hSession, pSignature, pulSignatureLen); 3690 } else { 3691 /* single-part PKC signature (e.g. CKM_ECDSA) */ 3692 unsigned int outlen; 3693 unsigned int maxoutlen = *pulSignatureLen; 3694 if (SECSuccess != (*context->update)(context->cipherInfo, pSignature, 3695 &outlen, maxoutlen, pData, ulDataLen)) 3696 crv = sftk_MapCryptError(PORT_GetError()); 3697 *pulSignatureLen = (CK_ULONG)outlen; 3698 /* "too small" here is certainly continuable */ 3699 if (crv != CKR_BUFFER_TOO_SMALL) 3700 sftk_TerminateOp(session, SFTK_SIGN, context); 3701 } /* single-part */ 3702 3703 finish: 3704 sftk_FreeSession(session); 3705 return crv; 3706 } 3707 3708 /* 3709 ************** Crypto Functions: Sign Recover ************************ 3710 */ 3711 /* NSC_SignRecoverInit initializes a signature operation, 3712 * where the (digest) data can be recovered from the signature. 3713 * E.g. encryption with the user's private key */ 3714 CK_RV 3715 NSC_SignRecoverInit(CK_SESSION_HANDLE hSession, 3716 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 3717 { 3718 CHECK_FORK(); 3719 3720 switch (pMechanism->mechanism) { 3721 case CKM_RSA_PKCS: 3722 case CKM_RSA_X_509: 3723 return NSC_SignInit(hSession, pMechanism, hKey); 3724 default: 3725 break; 3726 } 3727 return CKR_MECHANISM_INVALID; 3728 } 3729 3730 /* NSC_SignRecover signs data in a single operation 3731 * where the (digest) data can be recovered from the signature. 3732 * E.g. encryption with the user's private key */ 3733 CK_RV 3734 NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 3735 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) 3736 { 3737 CHECK_FORK(); 3738 3739 return NSC_Sign(hSession, pData, ulDataLen, pSignature, pulSignatureLen); 3740 } 3741 3742 /* 3743 ************** Crypto Functions: verify ************************ 3744 */ 3745 3746 /* Handle RSA Signature formatting */ 3747 static SECStatus 3748 sftk_hashCheckSign(void *ctx, const unsigned char *sig, 3749 unsigned int sigLen, const unsigned char *digest, 3750 unsigned int digestLen) 3751 { 3752 SFTKHashVerifyInfo *info = ctx; 3753 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); 3754 if (info->key->keyType != NSSLOWKEYRSAKey) { 3755 PORT_SetError(SEC_ERROR_INVALID_KEY); 3756 return SECFailure; 3757 } 3758 3759 return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, digest, 3760 digestLen); 3761 } 3762 3763 SECStatus 3764 RSA_HashCheckSign(SECOidTag digestOid, NSSLOWKEYPublicKey *key, 3765 const unsigned char *sig, unsigned int sigLen, 3766 const unsigned char *digestData, unsigned int digestLen) 3767 { 3768 unsigned char *pkcs1DigestInfoData; 3769 SECItem pkcs1DigestInfo; 3770 SECItem digest; 3771 unsigned int bufferSize; 3772 SECStatus rv; 3773 3774 /* pkcs1DigestInfo.data must be less than key->u.rsa.modulus.len */ 3775 bufferSize = key->u.rsa.modulus.len; 3776 pkcs1DigestInfoData = PORT_ZAlloc(bufferSize); 3777 if (!pkcs1DigestInfoData) { 3778 PORT_SetError(SEC_ERROR_NO_MEMORY); 3779 return SECFailure; 3780 } 3781 3782 pkcs1DigestInfo.data = pkcs1DigestInfoData; 3783 pkcs1DigestInfo.len = bufferSize; 3784 3785 /* decrypt the block */ 3786 rv = RSA_CheckSignRecover(&key->u.rsa, pkcs1DigestInfo.data, 3787 &pkcs1DigestInfo.len, pkcs1DigestInfo.len, 3788 sig, sigLen); 3789 if (rv != SECSuccess) { 3790 PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 3791 } else { 3792 digest.data = (PRUint8 *)digestData; 3793 digest.len = digestLen; 3794 rv = _SGN_VerifyPKCS1DigestInfo( 3795 digestOid, &digest, &pkcs1DigestInfo, 3796 PR_FALSE /*XXX: unsafeAllowMissingParameters*/); 3797 } 3798 3799 PORT_ZFree(pkcs1DigestInfoData, bufferSize); 3800 return rv; 3801 } 3802 3803 static SECStatus 3804 sftk_RSACheckSign(void *ctx, const unsigned char *sig, 3805 unsigned int sigLen, const unsigned char *digest, 3806 unsigned int digestLen) 3807 { 3808 NSSLOWKEYPublicKey *key = ctx; 3809 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 3810 if (key->keyType != NSSLOWKEYRSAKey) { 3811 PORT_SetError(SEC_ERROR_INVALID_KEY); 3812 return SECFailure; 3813 } 3814 3815 return RSA_CheckSign(&key->u.rsa, sig, sigLen, digest, digestLen); 3816 } 3817 3818 static SECStatus 3819 sftk_RSACheckSignRaw(void *ctx, const unsigned char *sig, 3820 unsigned int sigLen, const unsigned char *digest, 3821 unsigned int digestLen) 3822 { 3823 NSSLOWKEYPublicKey *key = ctx; 3824 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 3825 if (key->keyType != NSSLOWKEYRSAKey) { 3826 PORT_SetError(SEC_ERROR_INVALID_KEY); 3827 return SECFailure; 3828 } 3829 3830 return RSA_CheckSignRaw(&key->u.rsa, sig, sigLen, digest, digestLen); 3831 } 3832 3833 static SECStatus 3834 sftk_RSACheckSignPSS(void *ctx, const unsigned char *sig, 3835 unsigned int sigLen, const unsigned char *digest, 3836 unsigned int digestLen) 3837 { 3838 SFTKPSSVerifyInfo *info = ctx; 3839 HASH_HashType hashAlg; 3840 HASH_HashType maskHashAlg; 3841 CK_RSA_PKCS_PSS_PARAMS *params = &info->params; 3842 3843 PORT_Assert(info->key->keyType == NSSLOWKEYRSAKey); 3844 if (info->key->keyType != NSSLOWKEYRSAKey) { 3845 PORT_SetError(SEC_ERROR_INVALID_KEY); 3846 return SECFailure; 3847 } 3848 3849 hashAlg = sftk_GetHashTypeFromMechanism(params->hashAlg); 3850 maskHashAlg = sftk_GetHashTypeFromMechanism(params->mgf); 3851 3852 return RSA_CheckSignPSS(&info->key->u.rsa, hashAlg, maskHashAlg, 3853 params->sLen, sig, sigLen, digest, digestLen); 3854 } 3855 3856 /* NSC_VerifyInit initializes a verification operation, 3857 * where the signature is an appendix to the data, 3858 * and plaintext cannot be recovered from the signature (e.g. DSA) */ 3859 CK_RV 3860 NSC_VerifyInit(CK_SESSION_HANDLE hSession, 3861 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 3862 { 3863 SFTKSession *session; 3864 SFTKObject *key; 3865 SFTKSessionContext *context; 3866 CK_KEY_TYPE key_type; 3867 CK_RV crv = CKR_OK; 3868 NSSLOWKEYPublicKey *pubKey; 3869 SFTKHashVerifyInfo *info = NULL; 3870 SFTKPSSVerifyInfo *pinfo = NULL; 3871 3872 CHECK_FORK(); 3873 3874 /* Block Cipher MACing Algorithms use a different Context init method..*/ 3875 crv = sftk_InitCBCMac(hSession, pMechanism, hKey, CKA_VERIFY, SFTK_VERIFY); 3876 if (crv != CKR_FUNCTION_NOT_SUPPORTED) 3877 return crv; 3878 3879 session = sftk_SessionFromHandle(hSession); 3880 if (session == NULL) 3881 return CKR_SESSION_HANDLE_INVALID; 3882 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_VERIFY, &key, 3883 hKey, &key_type, CKO_PUBLIC_KEY, CKA_VERIFY); 3884 if (crv != CKR_OK) { 3885 sftk_FreeSession(session); 3886 return crv; 3887 } 3888 3889 context->multi = PR_FALSE; 3890 3891 #define INIT_RSA_VFY_MECH(mmm) \ 3892 case CKM_##mmm##_RSA_PKCS: \ 3893 context->multi = PR_TRUE; \ 3894 crv = sftk_doSub##mmm(context); \ 3895 if (crv != CKR_OK) \ 3896 break; \ 3897 context->verify = sftk_hashCheckSign; \ 3898 info = PORT_New(SFTKHashVerifyInfo); \ 3899 if (info == NULL) { \ 3900 crv = CKR_HOST_MEMORY; \ 3901 break; \ 3902 } \ 3903 info->hashOid = SEC_OID_##mmm; \ 3904 goto finish_rsa; 3905 3906 switch (pMechanism->mechanism) { 3907 INIT_RSA_VFY_MECH(MD5) 3908 INIT_RSA_VFY_MECH(MD2) 3909 INIT_RSA_VFY_MECH(SHA1) 3910 INIT_RSA_VFY_MECH(SHA224) 3911 INIT_RSA_VFY_MECH(SHA256) 3912 INIT_RSA_VFY_MECH(SHA384) 3913 INIT_RSA_VFY_MECH(SHA512) 3914 3915 case CKM_RSA_PKCS: 3916 context->verify = sftk_RSACheckSign; 3917 goto finish_rsa; 3918 case CKM_RSA_X_509: 3919 context->verify = sftk_RSACheckSignRaw; 3920 finish_rsa: 3921 if (key_type != CKK_RSA) { 3922 crv = CKR_KEY_TYPE_INCONSISTENT; 3923 break; 3924 } 3925 context->rsa = PR_TRUE; 3926 pubKey = sftk_GetPubKey(key, CKK_RSA, &crv); 3927 if (pubKey == NULL) { 3928 crv = CKR_KEY_TYPE_INCONSISTENT; 3929 break; 3930 } 3931 if (info) { 3932 info->key = pubKey; 3933 context->cipherInfo = info; 3934 context->destroy = sftk_Space; 3935 } else { 3936 context->cipherInfo = pubKey; 3937 context->destroy = sftk_Null; 3938 } 3939 break; 3940 3941 INIT_RSA_PSS_SIG_MECH(SHA1) 3942 INIT_RSA_PSS_SIG_MECH(SHA224) 3943 INIT_RSA_PSS_SIG_MECH(SHA256) 3944 INIT_RSA_PSS_SIG_MECH(SHA384) 3945 INIT_RSA_PSS_SIG_MECH(SHA512) 3946 case CKM_RSA_PKCS_PSS: 3947 finish_rsa_pss: 3948 if (key_type != CKK_RSA) { 3949 crv = CKR_KEY_TYPE_INCONSISTENT; 3950 break; 3951 } 3952 context->rsa = PR_TRUE; 3953 if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_PSS_PARAMS) || 3954 !sftk_ValidatePssParams((const CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter)) { 3955 crv = CKR_MECHANISM_PARAM_INVALID; 3956 break; 3957 } 3958 pinfo = PORT_New(SFTKPSSVerifyInfo); 3959 if (pinfo == NULL) { 3960 crv = CKR_HOST_MEMORY; 3961 break; 3962 } 3963 pinfo->size = sizeof(SFTKPSSVerifyInfo); 3964 pinfo->params = *(CK_RSA_PKCS_PSS_PARAMS *)pMechanism->pParameter; 3965 pinfo->key = sftk_GetPubKey(key, CKK_RSA, &crv); 3966 if (pinfo->key == NULL) { 3967 crv = CKR_KEY_TYPE_INCONSISTENT; 3968 break; 3969 } 3970 context->cipherInfo = pinfo; 3971 context->destroy = sftk_ZSpace; 3972 context->verify = sftk_RSACheckSignPSS; 3973 break; 3974 3975 #ifndef NSS_DISABLE_DSA 3976 INIT_DSA_SIG_MECH(SHA1) 3977 INIT_DSA_SIG_MECH(SHA224) 3978 INIT_DSA_SIG_MECH(SHA256) 3979 INIT_DSA_SIG_MECH(SHA384) 3980 INIT_DSA_SIG_MECH(SHA512) 3981 case CKM_DSA: 3982 finish_dsa: 3983 if (key_type != CKK_DSA) { 3984 crv = CKR_KEY_TYPE_INCONSISTENT; 3985 break; 3986 } 3987 pubKey = sftk_GetPubKey(key, CKK_DSA, &crv); 3988 if (pubKey == NULL) { 3989 break; 3990 } 3991 context->cipherInfo = pubKey; 3992 context->verify = nsc_DSA_Verify_Stub; 3993 context->destroy = sftk_Null; 3994 break; 3995 #endif 3996 case CKM_ML_DSA: { 3997 /* set our defaults */ 3998 SECItem signCtx = { siBuffer, NULL, 0 }; 3999 MLDSAContext *ctptr = NULL; 4000 SECStatus rv; 4001 4002 /* make sure we have the right key type */ 4003 if (key_type != CKK_ML_DSA) { 4004 crv = CKR_KEY_TYPE_INCONSISTENT; 4005 break; 4006 } 4007 /* fill in our parameters from the mechanism parameters if 4008 * supplied */ 4009 if (pMechanism->ulParameterLen != 0) { 4010 CK_SIGN_ADDITIONAL_CONTEXT *param; 4011 if (pMechanism->ulParameterLen != 4012 sizeof(CK_SIGN_ADDITIONAL_CONTEXT)) { 4013 crv = CKR_MECHANISM_PARAM_INVALID; 4014 break; 4015 } 4016 param = (CK_SIGN_ADDITIONAL_CONTEXT *)pMechanism->pParameter; 4017 signCtx.data = param->pContext; 4018 signCtx.len = param->ulContextLen; 4019 } 4020 /* fetch the key */ 4021 pubKey = sftk_GetPubKey(key, key_type, &crv); 4022 if (pubKey == NULL) { 4023 /* crv already set */ 4024 break; 4025 } 4026 /* now initialize it the signature */ 4027 rv = MLDSA_VerifyInit(&(pubKey->u.mldsa), &signCtx, &ctptr); 4028 if (rv != SECSuccess) { 4029 crv = sftk_MapVerifyError(PORT_GetError()); 4030 break; 4031 } 4032 /* set up our cipher info. MLDSA is only a combined hash/sign 4033 * so the hash update is our sign update, the hash end is a null 4034 * function returning a zero length value, and the final gets our 4035 * signature based on the context. Both the cipher context and the 4036 * hash Info is the same. The MLDSA_VerifyFinal frees the context, 4037 * so we don't have to */ 4038 context->multi = PR_TRUE; 4039 context->cipherInfo = ctptr; 4040 context->hashInfo = ctptr; 4041 context->hashUpdate = sftk_MLDSAVerifyUpdate; 4042 context->end = sftk_NullHashEnd; 4043 context->hashdestroy = sftk_Null; 4044 context->destroy = sftk_Null; 4045 context->verify = sftk_MLDSAVerifyFinal; 4046 context->maxLen = sftk_MLDSAGetSigLen(pubKey->u.mldsa.paramSet); 4047 break; 4048 } 4049 4050 INIT_ECDSA_SIG_MECH(SHA1) 4051 INIT_ECDSA_SIG_MECH(SHA224) 4052 INIT_ECDSA_SIG_MECH(SHA256) 4053 INIT_ECDSA_SIG_MECH(SHA384) 4054 INIT_ECDSA_SIG_MECH(SHA512) 4055 case CKM_ECDSA: 4056 finish_ecdsa: 4057 if (key_type != CKK_EC) { 4058 crv = CKR_KEY_TYPE_INCONSISTENT; 4059 break; 4060 } 4061 pubKey = sftk_GetPubKey(key, CKK_EC, &crv); 4062 if (pubKey == NULL) { 4063 crv = CKR_HOST_MEMORY; 4064 break; 4065 } 4066 context->cipherInfo = pubKey; 4067 context->verify = nsc_ECDSAVerifyStub; 4068 context->destroy = sftk_Null; 4069 break; 4070 4071 INIT_HMAC_MECH(MD2) 4072 INIT_HMAC_MECH(MD5) 4073 INIT_HMAC_MECH(SHA1) 4074 INIT_HMAC_MECH(SHA224) 4075 INIT_HMAC_MECH(SHA256) 4076 INIT_HMAC_MECH(SHA384) 4077 INIT_HMAC_MECH(SHA512) 4078 INIT_HMAC_MECH(SHA3_224) 4079 INIT_HMAC_MECH(SHA3_256) 4080 INIT_HMAC_MECH(SHA3_384) 4081 INIT_HMAC_MECH(SHA3_512) 4082 4083 case CKM_EDDSA: 4084 if (key_type != CKK_EC_EDWARDS) { 4085 crv = CKR_KEY_TYPE_INCONSISTENT; 4086 break; 4087 } 4088 pubKey = sftk_GetPubKey(key, CKK_EC_EDWARDS, &crv); 4089 if (pubKey == NULL) { 4090 crv = CKR_HOST_MEMORY; 4091 break; 4092 } 4093 4094 if (pMechanism->pParameter) { 4095 crv = CKR_FUNCTION_NOT_SUPPORTED; 4096 break; 4097 } 4098 4099 context->cipherInfo = pubKey; 4100 context->verify = nsc_EDDSAVerifyStub; 4101 context->destroy = sftk_Null; 4102 break; 4103 4104 case CKM_SSL3_MD5_MAC: 4105 PORT_Assert(pMechanism->pParameter); 4106 if (!pMechanism->pParameter) { 4107 crv = CKR_MECHANISM_PARAM_INVALID; 4108 break; 4109 } 4110 crv = sftk_doSSLMACInit(context, SEC_OID_MD5, key, 4111 *(CK_ULONG *)pMechanism->pParameter); 4112 break; 4113 case CKM_SSL3_SHA1_MAC: 4114 PORT_Assert(pMechanism->pParameter); 4115 if (!pMechanism->pParameter) { 4116 crv = CKR_MECHANISM_PARAM_INVALID; 4117 break; 4118 } 4119 crv = sftk_doSSLMACInit(context, SEC_OID_SHA1, key, 4120 *(CK_ULONG *)pMechanism->pParameter); 4121 break; 4122 case CKM_TLS_PRF_GENERAL: 4123 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgNULL, 0); 4124 break; 4125 case CKM_NSS_TLS_PRF_GENERAL_SHA256: 4126 crv = sftk_TLSPRFInit(context, key, key_type, HASH_AlgSHA256, 0); 4127 break; 4128 4129 default: 4130 crv = CKR_MECHANISM_INVALID; 4131 break; 4132 } 4133 4134 if (crv != CKR_OK) { 4135 if (info) 4136 PORT_Free(info); 4137 if (pinfo) 4138 PORT_ZFree(pinfo, pinfo->size); 4139 sftk_FreeContext(context); 4140 sftk_FreeSession(session); 4141 return crv; 4142 } 4143 sftk_SetContextByType(session, SFTK_VERIFY, context); 4144 sftk_FreeSession(session); 4145 return CKR_OK; 4146 } 4147 4148 /* NSC_Verify verifies a signature in a single-part operation, 4149 * where the signature is an appendix to the data, 4150 * and plaintext cannot be recovered from the signature */ 4151 CK_RV 4152 NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 4153 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) 4154 { 4155 SFTKSession *session; 4156 SFTKSessionContext *context; 4157 CK_RV crv; 4158 4159 CHECK_FORK(); 4160 4161 /* make sure we're legal */ 4162 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE, &session); 4163 if (crv != CKR_OK) 4164 return crv; 4165 4166 /* multi part Verifying are completely implemented by VerifyUpdate and 4167 * VerifyFinal */ 4168 if (context->multi) { 4169 /* VerifyFinal can't follow failed VerifyUpdate */ 4170 if (CKR_OK == (crv = NSC_VerifyUpdate(hSession, pData, ulDataLen))) 4171 crv = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen); 4172 } else { 4173 if (SECSuccess != (*context->verify)(context->cipherInfo, pSignature, 4174 ulSignatureLen, pData, ulDataLen)) 4175 crv = sftk_MapCryptError(PORT_GetError()); 4176 4177 sftk_TerminateOp(session, SFTK_VERIFY, context); 4178 } 4179 sftk_FreeSession(session); 4180 return crv; 4181 } 4182 4183 /* NSC_VerifyUpdate continues a multiple-part verification operation, 4184 * where the signature is an appendix to the data, 4185 * and plaintext cannot be recovered from the signature 4186 * 4187 * A call which results in an error terminates the operation [PKCS#11,v2.11] 4188 */ 4189 CK_RV 4190 NSC_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 4191 CK_ULONG ulPartLen) 4192 { 4193 CHECK_FORK(); 4194 return sftk_MACUpdate(hSession, pPart, ulPartLen, SFTK_VERIFY); 4195 } 4196 4197 /* NSC_VerifyFinal finishes a multiple-part verification operation, 4198 * checking the signature. */ 4199 CK_RV 4200 NSC_VerifyFinal(CK_SESSION_HANDLE hSession, 4201 CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) 4202 { 4203 SFTKSession *session; 4204 SFTKSessionContext *context; 4205 CK_RV crv; 4206 4207 CHECK_FORK(); 4208 4209 if (!pSignature) 4210 return CKR_ARGUMENTS_BAD; 4211 4212 /* make sure we're legal */ 4213 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE, &session); 4214 if (crv != CKR_OK) 4215 return crv; 4216 4217 if (context->hashInfo) { 4218 unsigned int digestLen; 4219 unsigned char tmpbuf[SFTK_MAX_MAC_LENGTH]; 4220 4221 (*context->end)(context->hashInfo, tmpbuf, &digestLen, sizeof(tmpbuf)); 4222 if (SECSuccess != (context->verify)(context->cipherInfo, pSignature, 4223 ulSignatureLen, tmpbuf, digestLen)) 4224 crv = sftk_MapCryptError(PORT_GetError()); 4225 PORT_Memset(tmpbuf, 0, sizeof tmpbuf); 4226 } else if (ulSignatureLen != context->macSize) { 4227 /* must be block cipher MACing */ 4228 crv = CKR_SIGNATURE_LEN_RANGE; 4229 } else if (CKR_OK == (crv = sftk_MACFinal(context))) { 4230 if (NSS_SecureMemcmp(pSignature, context->macBuf, ulSignatureLen)) 4231 crv = CKR_SIGNATURE_INVALID; 4232 } 4233 4234 sftk_TerminateOp(session, SFTK_VERIFY, context); 4235 sftk_FreeSession(session); 4236 return crv; 4237 } 4238 4239 /* 4240 ************** Crypto Functions: Verify Signature ************************ 4241 * some algorithms need the signature at the beginning of the verification, 4242 * VerifySignature provides such and API. For algorithms that don't need 4243 * the signature first, we stash the signature and just pass it to 4244 * NSC_VerifyXXX. 4245 */ 4246 CK_RV 4247 NSC_VerifySignatureInit(CK_SESSION_HANDLE hSession, 4248 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, 4249 CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen) 4250 { 4251 SFTKSession *session; 4252 SFTKSessionContext *context; 4253 CK_RV crv; 4254 SECItem tmpItem; 4255 4256 crv = NSC_VerifyInit(hSession, pMechanism, hKey); 4257 if (crv != CKR_OK) { 4258 return crv; 4259 } 4260 4261 CHECK_FORK(); 4262 4263 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE, &session); 4264 if (crv != CKR_OK) 4265 return crv; 4266 4267 tmpItem.type = siBuffer; 4268 tmpItem.data = pSignature; 4269 tmpItem.len = ulSignatureLen; 4270 context->signature = SECITEM_DupItem(&tmpItem); 4271 if (!context->signature) { 4272 sftk_TerminateOp(session, SFTK_VERIFY, context); 4273 sftk_FreeSession(session); 4274 return CKR_HOST_MEMORY; 4275 } 4276 sftk_FreeSession(session); 4277 return CKR_OK; 4278 } 4279 4280 CK_RV 4281 NSC_VerifySignature(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, 4282 CK_ULONG ulDataLen) 4283 { 4284 SFTKSession *session; 4285 SFTKSessionContext *context; 4286 CK_RV crv; 4287 4288 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_FALSE, &session); 4289 if (crv != CKR_OK) 4290 return crv; 4291 4292 /* make sure we're legal */ 4293 if (!context->signature) { 4294 sftk_FreeSession(session); 4295 return CKR_OPERATION_NOT_INITIALIZED; 4296 } 4297 crv = NSC_Verify(hSession, pData, ulDataLen, 4298 context->signature->data, context->signature->len); 4299 /* we free the signature here because the context is part of the session and has 4300 * a lifetime tied to the session. So we want to hold our reference to the 4301 * session so it doesn't go away on us */ 4302 sftk_FreeSession(session); 4303 return crv; 4304 } 4305 4306 CK_RV 4307 NSC_VerifySignatureUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 4308 CK_ULONG ulPartLen) 4309 { 4310 SFTKSession *session; 4311 SFTKSessionContext *context; 4312 CK_RV crv; 4313 4314 /* make sure we're legal */ 4315 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE, &session); 4316 if (crv != CKR_OK) 4317 return crv; 4318 4319 /* like verify above, we bother keeping the session to make sure the context 4320 * doesn't go way on use. there's little chance that it will since that application 4321 * must protect against multiple threads calling the same same session at the same 4322 * time (nss has session locks for this), but there are a couple of corner cases, 4323 * (like close all sessions, or shutting down the whole module. Also if the 4324 * application breaks the contract, we want to just fail rather than crash */ 4325 if (!context->signature) { 4326 sftk_FreeSession(session); 4327 return CKR_OPERATION_NOT_INITIALIZED; 4328 } 4329 sftk_FreeSession(session); 4330 return NSC_VerifyUpdate(hSession, pPart, ulPartLen); 4331 } 4332 4333 CK_RV 4334 NSC_VerifySignatureFinal(CK_SESSION_HANDLE hSession) 4335 { 4336 SFTKSession *session; 4337 SFTKSessionContext *context; 4338 CK_RV crv; 4339 4340 /* make sure we're legal */ 4341 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY, PR_TRUE, &session); 4342 if (crv != CKR_OK) 4343 return crv; 4344 4345 if (!context->signature) { 4346 sftk_FreeSession(session); 4347 return CKR_OPERATION_NOT_INITIALIZED; 4348 } 4349 crv = NSC_VerifyFinal(hSession, context->signature->data, 4350 context->signature->len); 4351 /* see comment in NSC_VerifySignature() */ 4352 sftk_FreeSession(session); 4353 return crv; 4354 } 4355 4356 /* 4357 ************** Crypto Functions: Verify Recover ************************ 4358 */ 4359 static SECStatus 4360 sftk_RSACheckSignRecover(void *ctx, unsigned char *data, 4361 unsigned int *dataLen, unsigned int maxDataLen, 4362 const unsigned char *sig, unsigned int sigLen) 4363 { 4364 NSSLOWKEYPublicKey *key = ctx; 4365 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 4366 if (key->keyType != NSSLOWKEYRSAKey) { 4367 PORT_SetError(SEC_ERROR_INVALID_KEY); 4368 return SECFailure; 4369 } 4370 4371 return RSA_CheckSignRecover(&key->u.rsa, data, dataLen, maxDataLen, 4372 sig, sigLen); 4373 } 4374 4375 static SECStatus 4376 sftk_RSACheckSignRecoverRaw(void *ctx, unsigned char *data, 4377 unsigned int *dataLen, unsigned int maxDataLen, 4378 const unsigned char *sig, unsigned int sigLen) 4379 { 4380 NSSLOWKEYPublicKey *key = ctx; 4381 PORT_Assert(key->keyType == NSSLOWKEYRSAKey); 4382 if (key->keyType != NSSLOWKEYRSAKey) { 4383 PORT_SetError(SEC_ERROR_INVALID_KEY); 4384 return SECFailure; 4385 } 4386 4387 return RSA_CheckSignRecoverRaw(&key->u.rsa, data, dataLen, maxDataLen, 4388 sig, sigLen); 4389 } 4390 4391 /* NSC_VerifyRecoverInit initializes a signature verification operation, 4392 * where the data is recovered from the signature. 4393 * E.g. Decryption with the user's public key */ 4394 CK_RV 4395 NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, 4396 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) 4397 { 4398 SFTKSession *session; 4399 SFTKObject *key; 4400 SFTKSessionContext *context; 4401 CK_KEY_TYPE key_type; 4402 CK_RV crv = CKR_OK; 4403 NSSLOWKEYPublicKey *pubKey; 4404 4405 CHECK_FORK(); 4406 4407 session = sftk_SessionFromHandle(hSession); 4408 if (session == NULL) 4409 return CKR_SESSION_HANDLE_INVALID; 4410 crv = sftk_InitGeneric(session, pMechanism, &context, SFTK_VERIFY_RECOVER, 4411 &key, hKey, &key_type, CKO_PUBLIC_KEY, CKA_VERIFY_RECOVER); 4412 if (crv != CKR_OK) { 4413 sftk_FreeSession(session); 4414 return crv; 4415 } 4416 4417 context->multi = PR_TRUE; 4418 4419 switch (pMechanism->mechanism) { 4420 case CKM_RSA_PKCS: 4421 case CKM_RSA_X_509: 4422 if (key_type != CKK_RSA) { 4423 crv = CKR_KEY_TYPE_INCONSISTENT; 4424 break; 4425 } 4426 context->multi = PR_FALSE; 4427 context->rsa = PR_TRUE; 4428 pubKey = sftk_GetPubKey(key, CKK_RSA, &crv); 4429 if (pubKey == NULL) { 4430 break; 4431 } 4432 context->cipherInfo = pubKey; 4433 context->update = pMechanism->mechanism == CKM_RSA_X_509 4434 ? sftk_RSACheckSignRecoverRaw 4435 : sftk_RSACheckSignRecover; 4436 context->destroy = sftk_Null; 4437 break; 4438 default: 4439 crv = CKR_MECHANISM_INVALID; 4440 break; 4441 } 4442 4443 if (crv != CKR_OK) { 4444 PORT_Free(context); 4445 sftk_FreeSession(session); 4446 return crv; 4447 } 4448 sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, context); 4449 sftk_FreeSession(session); 4450 return CKR_OK; 4451 } 4452 4453 /* NSC_VerifyRecover verifies a signature in a single-part operation, 4454 * where the data is recovered from the signature. 4455 * E.g. Decryption with the user's public key */ 4456 CK_RV 4457 NSC_VerifyRecover(CK_SESSION_HANDLE hSession, 4458 CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen, 4459 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) 4460 { 4461 SFTKSession *session; 4462 SFTKSessionContext *context; 4463 unsigned int outlen; 4464 unsigned int maxoutlen = *pulDataLen; 4465 CK_RV crv; 4466 SECStatus rv; 4467 4468 CHECK_FORK(); 4469 4470 /* make sure we're legal */ 4471 crv = sftk_GetContext(hSession, &context, SFTK_VERIFY_RECOVER, 4472 PR_FALSE, &session); 4473 if (crv != CKR_OK) 4474 return crv; 4475 if (pData == NULL) { 4476 /* to return the actual size, we need to do the decrypt, just return 4477 * the max size, which is the size of the input signature. */ 4478 *pulDataLen = ulSignatureLen; 4479 rv = SECSuccess; 4480 goto finish; 4481 } 4482 4483 rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, 4484 pSignature, ulSignatureLen); 4485 *pulDataLen = (CK_ULONG)outlen; 4486 4487 sftk_TerminateOp(session, SFTK_VERIFY_RECOVER, context); 4488 finish: 4489 sftk_FreeSession(session); 4490 return (rv == SECSuccess) ? CKR_OK : sftk_MapVerifyError(PORT_GetError()); 4491 } 4492 4493 /* 4494 **************************** Random Functions: ************************ 4495 */ 4496 4497 /* NSC_SeedRandom mixes additional seed material into the token's random number 4498 * generator. */ 4499 CK_RV 4500 NSC_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, 4501 CK_ULONG ulSeedLen) 4502 { 4503 SECStatus rv; 4504 4505 CHECK_FORK(); 4506 4507 rv = RNG_RandomUpdate(pSeed, ulSeedLen); 4508 return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); 4509 } 4510 4511 /* NSC_GenerateRandom generates random data. */ 4512 CK_RV 4513 NSC_GenerateRandom(CK_SESSION_HANDLE hSession, 4514 CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) 4515 { 4516 SECStatus rv; 4517 4518 CHECK_FORK(); 4519 4520 rv = RNG_GenerateGlobalRandomBytes(pRandomData, ulRandomLen); 4521 /* 4522 * This may fail with SEC_ERROR_NEED_RANDOM, which means the RNG isn't 4523 * seeded with enough entropy. 4524 */ 4525 return (rv == SECSuccess) ? CKR_OK : sftk_MapCryptError(PORT_GetError()); 4526 } 4527 4528 /* 4529 **************************** Key Functions: ************************ 4530 */ 4531 4532 /* 4533 * generate a password based encryption key. This code uses 4534 * PKCS5 to do the work. 4535 */ 4536 static CK_RV 4537 nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism, 4538 void *buf, CK_ULONG *key_length, PRBool faulty3DES) 4539 { 4540 SECItem *pbe_key = NULL, iv, pwitem; 4541 CK_PBE_PARAMS *pbe_params = NULL; 4542 CK_PKCS5_PBKD2_PARAMS2 *pbkd2_params = NULL; 4543 4544 *key_length = 0; 4545 iv.data = NULL; 4546 iv.len = 0; 4547 4548 if (pMechanism->mechanism == CKM_PKCS5_PBKD2) { 4549 pbkd2_params = (CK_PKCS5_PBKD2_PARAMS2 *)pMechanism->pParameter; 4550 if (!pMechanism->pParameter) { 4551 return CKR_MECHANISM_PARAM_INVALID; 4552 } 4553 4554 #ifdef SOFTOKEN_USE_PKCS5_PBKD2_PARAMS2_ONLY 4555 if (pMechanism->ulParameterLen < sizeof(CK_PKCS5_PBKD2_PARAMS2)) { 4556 return CKR_MECHANISM_PARAM_INVALID; 4557 } 4558 pwitem.len = pbkd2_params->ulPasswordLen; 4559 #else 4560 int v2; 4561 if (pMechanism->ulParameterLen < PR_MIN(sizeof(CK_PKCS5_PBKD2_PARAMS), 4562 sizeof(CK_PKCS5_PBKD2_PARAMS2))) { 4563 return CKR_MECHANISM_PARAM_INVALID; 4564 } 4565 4566 if (sizeof(CK_PKCS5_PBKD2_PARAMS2) != sizeof(CK_PKCS5_PBKD2_PARAMS)) { 4567 if (pMechanism->ulParameterLen == sizeof(CK_PKCS5_PBKD2_PARAMS)) { 4568 v2 = 0; 4569 } else if (pMechanism->ulParameterLen == sizeof(CK_PKCS5_PBKD2_PARAMS2)) { 4570 v2 = 1; 4571 } else { 4572 return CKR_MECHANISM_PARAM_INVALID; 4573 } 4574 } else { 4575 /* it's unlikely that the password will be longer than 8192 bytes, if so it is 4576 * most likely a pointer => CK_PKCS5_PBKD2_PARAMS */ 4577 v2 = pbkd2_params->ulPasswordLen <= CK_PKCS5_PBKD2_PARAMS_PTR_BOUNDARY; 4578 } 4579 pwitem.len = v2 ? pbkd2_params->ulPasswordLen : *((CK_PKCS5_PBKD2_PARAMS *)pMechanism->pParameter)->ulPasswordLen; 4580 #endif 4581 pwitem.data = (unsigned char *)pbkd2_params->pPassword; 4582 } else { 4583 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))) { 4584 return CKR_MECHANISM_PARAM_INVALID; 4585 } 4586 pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; 4587 pwitem.data = (unsigned char *)pbe_params->pPassword; 4588 pwitem.len = pbe_params->ulPasswordLen; 4589 } 4590 pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES); 4591 if (pbe_key == NULL) { 4592 return CKR_HOST_MEMORY; 4593 } 4594 4595 PORT_Memcpy(buf, pbe_key->data, pbe_key->len); 4596 *key_length = pbe_key->len; 4597 SECITEM_ZfreeItem(pbe_key, PR_TRUE); 4598 pbe_key = NULL; 4599 4600 if (iv.data) { 4601 if (pbe_params && pbe_params->pInitVector != NULL) { 4602 PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); 4603 } 4604 PORT_Free(iv.data); 4605 } 4606 4607 return CKR_OK; 4608 } 4609 4610 /* 4611 * this is coded for "full" support. These selections will be limitted to 4612 * the official subset by freebl. 4613 */ 4614 static unsigned int 4615 sftk_GetSubPrimeFromPrime(unsigned int primeBits) 4616 { 4617 if (primeBits <= 1024) { 4618 return 160; 4619 } else if (primeBits <= 2048) { 4620 return 224; 4621 } else if (primeBits <= 3072) { 4622 return 256; 4623 } else if (primeBits <= 7680) { 4624 return 384; 4625 } else { 4626 return 512; 4627 } 4628 } 4629 4630 static CK_RV 4631 nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key) 4632 { 4633 SFTKAttribute *attribute; 4634 CK_ULONG counter; 4635 unsigned int seedBits = 0; 4636 unsigned int subprimeBits = 0; 4637 unsigned int primeBits; 4638 unsigned int j = 8; /* default to 1024 bits */ 4639 CK_RV crv = CKR_OK; 4640 PQGParams *params = NULL; 4641 PQGVerify *vfy = NULL; 4642 SECStatus rv; 4643 4644 attribute = sftk_FindAttribute(key, CKA_PRIME_BITS); 4645 if (attribute == NULL) { 4646 attribute = sftk_FindAttribute(key, CKA_PRIME); 4647 if (attribute == NULL) { 4648 return CKR_TEMPLATE_INCOMPLETE; 4649 } else { 4650 primeBits = attribute->attrib.ulValueLen; 4651 sftk_FreeAttribute(attribute); 4652 } 4653 } else { 4654 primeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue; 4655 sftk_FreeAttribute(attribute); 4656 } 4657 if (primeBits < 1024) { 4658 j = PQG_PBITS_TO_INDEX(primeBits); 4659 if (j == (unsigned int)-1) { 4660 return CKR_ATTRIBUTE_VALUE_INVALID; 4661 } 4662 } 4663 4664 attribute = sftk_FindAttribute(key, CKA_NSS_PQG_SEED_BITS); 4665 if (attribute != NULL) { 4666 seedBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue; 4667 sftk_FreeAttribute(attribute); 4668 } 4669 4670 attribute = sftk_FindAttribute(key, CKA_SUBPRIME_BITS); 4671 if (attribute != NULL) { 4672 subprimeBits = (unsigned int)*(CK_ULONG *)attribute->attrib.pValue; 4673 sftk_FreeAttribute(attribute); 4674 } 4675 4676 /* if P and Q are supplied, we want to generate a new G */ 4677 attribute = sftk_FindAttribute(key, CKA_PRIME); 4678 if (attribute != NULL) { 4679 PLArenaPool *arena; 4680 4681 sftk_FreeAttribute(attribute); 4682 arena = PORT_NewArena(1024); 4683 if (arena == NULL) { 4684 crv = CKR_HOST_MEMORY; 4685 goto loser; 4686 } 4687 params = PORT_ArenaAlloc(arena, sizeof(*params)); 4688 if (params == NULL) { 4689 crv = CKR_HOST_MEMORY; 4690 goto loser; 4691 } 4692 params->arena = arena; 4693 crv = sftk_Attribute2SSecItem(arena, ¶ms->prime, key, CKA_PRIME); 4694 if (crv != CKR_OK) { 4695 goto loser; 4696 } 4697 crv = sftk_Attribute2SSecItem(arena, ¶ms->subPrime, 4698 key, CKA_SUBPRIME); 4699 if (crv != CKR_OK) { 4700 goto loser; 4701 } 4702 4703 arena = PORT_NewArena(1024); 4704 if (arena == NULL) { 4705 crv = CKR_HOST_MEMORY; 4706 goto loser; 4707 } 4708 vfy = PORT_ArenaAlloc(arena, sizeof(*vfy)); 4709 if (vfy == NULL) { 4710 crv = CKR_HOST_MEMORY; 4711 goto loser; 4712 } 4713 vfy->arena = arena; 4714 crv = sftk_Attribute2SSecItem(arena, &vfy->seed, key, CKA_NSS_PQG_SEED); 4715 if (crv != CKR_OK) { 4716 goto loser; 4717 } 4718 crv = sftk_Attribute2SSecItem(arena, &vfy->h, key, CKA_NSS_PQG_H); 4719 if (crv != CKR_OK) { 4720 goto loser; 4721 } 4722 sftk_DeleteAttributeType(key, CKA_PRIME); 4723 sftk_DeleteAttributeType(key, CKA_SUBPRIME); 4724 sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED); 4725 sftk_DeleteAttributeType(key, CKA_NSS_PQG_H); 4726 } 4727 4728 sftk_DeleteAttributeType(key, CKA_PRIME_BITS); 4729 sftk_DeleteAttributeType(key, CKA_SUBPRIME_BITS); 4730 sftk_DeleteAttributeType(key, CKA_NSS_PQG_SEED_BITS); 4731 4732 /* use the old PQG interface if we have old input data */ 4733 if ((primeBits < 1024) || ((primeBits == 1024) && (subprimeBits == 0))) { 4734 if (seedBits == 0) { 4735 rv = PQG_ParamGen(j, ¶ms, &vfy); 4736 } else { 4737 rv = PQG_ParamGenSeedLen(j, seedBits / 8, ¶ms, &vfy); 4738 } 4739 } else { 4740 if (subprimeBits == 0) { 4741 subprimeBits = sftk_GetSubPrimeFromPrime(primeBits); 4742 } 4743 if (seedBits == 0) { 4744 seedBits = primeBits; 4745 } 4746 rv = PQG_ParamGenV2(primeBits, subprimeBits, seedBits / 8, ¶ms, &vfy); 4747 } 4748 4749 if (rv != SECSuccess) { 4750 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 4751 sftk_fatalError = PR_TRUE; 4752 } 4753 return sftk_MapCryptError(PORT_GetError()); 4754 } 4755 crv = sftk_AddAttributeType(key, CKA_PRIME, 4756 params->prime.data, params->prime.len); 4757 if (crv != CKR_OK) 4758 goto loser; 4759 crv = sftk_AddAttributeType(key, CKA_SUBPRIME, 4760 params->subPrime.data, params->subPrime.len); 4761 if (crv != CKR_OK) 4762 goto loser; 4763 crv = sftk_AddAttributeType(key, CKA_BASE, 4764 params->base.data, params->base.len); 4765 if (crv != CKR_OK) 4766 goto loser; 4767 counter = vfy->counter; 4768 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_COUNTER, 4769 &counter, sizeof(counter)); 4770 if (crv != CKR_OK) 4771 goto loser; 4772 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_SEED, 4773 vfy->seed.data, vfy->seed.len); 4774 if (crv != CKR_OK) 4775 goto loser; 4776 crv = sftk_AddAttributeType(key, CKA_NSS_PQG_H, 4777 vfy->h.data, vfy->h.len); 4778 if (crv != CKR_OK) 4779 goto loser; 4780 4781 loser: 4782 if (params) { 4783 PQG_DestroyParams(params); 4784 } 4785 4786 if (vfy) { 4787 PQG_DestroyVerify(vfy); 4788 } 4789 return crv; 4790 } 4791 4792 static CK_RV 4793 nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type, 4794 CK_ULONG *key_length) 4795 { 4796 CK_RV crv = CKR_OK; 4797 4798 switch (mechanism) { 4799 #ifndef NSS_DISABLE_DEPRECATED_RC2 4800 case CKM_RC2_KEY_GEN: 4801 *key_type = CKK_RC2; 4802 if (*key_length == 0) 4803 crv = CKR_TEMPLATE_INCOMPLETE; 4804 break; 4805 #endif /* NSS_DISABLE_DEPRECATED_RC2 */ 4806 #if NSS_SOFTOKEN_DOES_RC5 4807 case CKM_RC5_KEY_GEN: 4808 *key_type = CKK_RC5; 4809 if (*key_length == 0) 4810 crv = CKR_TEMPLATE_INCOMPLETE; 4811 break; 4812 #endif 4813 case CKM_RC4_KEY_GEN: 4814 *key_type = CKK_RC4; 4815 if (*key_length == 0) 4816 crv = CKR_TEMPLATE_INCOMPLETE; 4817 break; 4818 case CKM_GENERIC_SECRET_KEY_GEN: 4819 *key_type = CKK_GENERIC_SECRET; 4820 if (*key_length == 0) 4821 crv = CKR_TEMPLATE_INCOMPLETE; 4822 break; 4823 case CKM_CDMF_KEY_GEN: 4824 *key_type = CKK_CDMF; 4825 *key_length = 8; 4826 break; 4827 case CKM_DES_KEY_GEN: 4828 *key_type = CKK_DES; 4829 *key_length = 8; 4830 break; 4831 case CKM_DES2_KEY_GEN: 4832 *key_type = CKK_DES2; 4833 *key_length = 16; 4834 break; 4835 case CKM_DES3_KEY_GEN: 4836 *key_type = CKK_DES3; 4837 *key_length = 24; 4838 break; 4839 #ifndef NSS_DISABLE_DEPRECATED_SEED 4840 case CKM_SEED_KEY_GEN: 4841 *key_type = CKK_SEED; 4842 *key_length = 16; 4843 break; 4844 #endif /* NSS_DISABLE_DEPRECATED_SEED */ 4845 case CKM_CAMELLIA_KEY_GEN: 4846 *key_type = CKK_CAMELLIA; 4847 if (*key_length == 0) 4848 crv = CKR_TEMPLATE_INCOMPLETE; 4849 break; 4850 case CKM_AES_KEY_GEN: 4851 *key_type = CKK_AES; 4852 if (*key_length == 0) 4853 crv = CKR_TEMPLATE_INCOMPLETE; 4854 break; 4855 case CKM_NSS_CHACHA20_KEY_GEN: 4856 *key_type = CKK_NSS_CHACHA20; 4857 *key_length = 32; 4858 break; 4859 case CKM_CHACHA20_KEY_GEN: 4860 *key_type = CKK_CHACHA20; 4861 *key_length = 32; 4862 break; 4863 case CKM_HKDF_KEY_GEN: 4864 *key_type = CKK_HKDF; 4865 if (*key_length == 0) 4866 crv = CKR_TEMPLATE_INCOMPLETE; 4867 break; 4868 default: 4869 PORT_Assert(0); 4870 crv = CKR_MECHANISM_INVALID; 4871 break; 4872 } 4873 4874 return crv; 4875 } 4876 4877 CK_RV 4878 nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe) 4879 { 4880 SECItem salt; 4881 CK_PBE_PARAMS *pbe_params = NULL; 4882 NSSPKCS5PBEParameter *params; 4883 PLArenaPool *arena = NULL; 4884 SECStatus rv; 4885 4886 *pbe = NULL; 4887 4888 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 4889 if (arena == NULL) { 4890 return CKR_HOST_MEMORY; 4891 } 4892 4893 params = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena, 4894 sizeof(NSSPKCS5PBEParameter)); 4895 if (params == NULL) { 4896 PORT_FreeArena(arena, PR_TRUE); 4897 return CKR_HOST_MEMORY; 4898 } 4899 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))) { 4900 PORT_FreeArena(arena, PR_TRUE); 4901 return CKR_MECHANISM_PARAM_INVALID; 4902 } 4903 4904 params->poolp = arena; 4905 params->ivLen = 0; 4906 params->pbeType = NSSPKCS5_PKCS12_V2; 4907 params->hashType = HASH_AlgSHA1; 4908 params->encAlg = SEC_OID_SHA1; /* any invalid value */ 4909 params->is2KeyDES = PR_FALSE; 4910 params->keyID = pbeBitGenIntegrityKey; 4911 pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; 4912 params->iter = pbe_params->ulIteration; 4913 4914 salt.data = (unsigned char *)pbe_params->pSalt; 4915 salt.len = (unsigned int)pbe_params->ulSaltLen; 4916 salt.type = siBuffer; 4917 rv = SECITEM_CopyItem(arena, ¶ms->salt, &salt); 4918 if (rv != SECSuccess) { 4919 PORT_FreeArena(arena, PR_TRUE); 4920 return CKR_HOST_MEMORY; 4921 } 4922 switch (pMechanism->mechanism) { 4923 case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN: 4924 case CKM_PBA_SHA1_WITH_SHA1_HMAC: 4925 params->hashType = HASH_AlgSHA1; 4926 params->keyLen = 20; 4927 break; 4928 case CKM_NSS_PBE_MD5_HMAC_KEY_GEN: 4929 params->hashType = HASH_AlgMD5; 4930 params->keyLen = 16; 4931 break; 4932 case CKM_NSS_PBE_MD2_HMAC_KEY_GEN: 4933 params->hashType = HASH_AlgMD2; 4934 params->keyLen = 16; 4935 break; 4936 case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: 4937 params->hashType = HASH_AlgSHA224; 4938 params->keyLen = 28; 4939 break; 4940 case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: 4941 params->hashType = HASH_AlgSHA256; 4942 params->keyLen = 32; 4943 break; 4944 case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: 4945 params->hashType = HASH_AlgSHA384; 4946 params->keyLen = 48; 4947 break; 4948 case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: 4949 params->hashType = HASH_AlgSHA512; 4950 params->keyLen = 64; 4951 break; 4952 default: 4953 PORT_FreeArena(arena, PR_TRUE); 4954 return CKR_MECHANISM_INVALID; 4955 } 4956 *pbe = params; 4957 return CKR_OK; 4958 } 4959 4960 /* maybe this should be table driven? */ 4961 static CK_RV 4962 nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe, 4963 CK_KEY_TYPE *key_type, CK_ULONG *key_length) 4964 { 4965 CK_RV crv = CKR_OK; 4966 SECOidData *oid; 4967 CK_PBE_PARAMS *pbe_params = NULL; 4968 NSSPKCS5PBEParameter *params = NULL; 4969 HASH_HashType hashType = HASH_AlgSHA1; 4970 CK_PKCS5_PBKD2_PARAMS2 *pbkd2_params = NULL; 4971 SECItem salt; 4972 CK_ULONG iteration = 0; 4973 4974 *pbe = NULL; 4975 4976 oid = SECOID_FindOIDByMechanism(pMechanism->mechanism); 4977 if (oid == NULL) { 4978 return CKR_MECHANISM_INVALID; 4979 } 4980 4981 if (pMechanism->mechanism == CKM_PKCS5_PBKD2) { 4982 if (pMechanism->ulParameterLen < PR_MIN(sizeof(CK_PKCS5_PBKD2_PARAMS2), 4983 sizeof(CK_PKCS5_PBKD2_PARAMS))) { 4984 return CKR_MECHANISM_PARAM_INVALID; 4985 } 4986 pbkd2_params = (CK_PKCS5_PBKD2_PARAMS2 *)pMechanism->pParameter; 4987 switch (pbkd2_params->prf) { 4988 case CKP_PKCS5_PBKD2_HMAC_SHA1: 4989 hashType = HASH_AlgSHA1; 4990 break; 4991 case CKP_PKCS5_PBKD2_HMAC_SHA224: 4992 hashType = HASH_AlgSHA224; 4993 break; 4994 case CKP_PKCS5_PBKD2_HMAC_SHA256: 4995 hashType = HASH_AlgSHA256; 4996 break; 4997 case CKP_PKCS5_PBKD2_HMAC_SHA384: 4998 hashType = HASH_AlgSHA384; 4999 break; 5000 case CKP_PKCS5_PBKD2_HMAC_SHA512: 5001 hashType = HASH_AlgSHA512; 5002 break; 5003 default: 5004 return CKR_MECHANISM_PARAM_INVALID; 5005 } 5006 if (pbkd2_params->saltSource != CKZ_SALT_SPECIFIED) { 5007 return CKR_MECHANISM_PARAM_INVALID; 5008 } 5009 salt.data = (unsigned char *)pbkd2_params->pSaltSourceData; 5010 salt.len = (unsigned int)pbkd2_params->ulSaltSourceDataLen; 5011 iteration = pbkd2_params->iterations; 5012 } else { 5013 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_PBE_PARAMS))) { 5014 return CKR_MECHANISM_PARAM_INVALID; 5015 } 5016 pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter; 5017 salt.data = (unsigned char *)pbe_params->pSalt; 5018 salt.len = (unsigned int)pbe_params->ulSaltLen; 5019 iteration = pbe_params->ulIteration; 5020 } 5021 params = nsspkcs5_NewParam(oid->offset, hashType, &salt, iteration); 5022 if (params == NULL) { 5023 return CKR_MECHANISM_INVALID; 5024 } 5025 5026 switch (params->encAlg) { 5027 case SEC_OID_DES_CBC: 5028 *key_type = CKK_DES; 5029 *key_length = params->keyLen; 5030 break; 5031 case SEC_OID_DES_EDE3_CBC: 5032 *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3; 5033 *key_length = params->keyLen; 5034 break; 5035 #ifndef NSS_DISABLE_DEPRECATED_RC2 5036 case SEC_OID_RC2_CBC: 5037 *key_type = CKK_RC2; 5038 *key_length = params->keyLen; 5039 break; 5040 #endif /* NSS_DISABLE_DEPRECATED_RC2 */ 5041 case SEC_OID_RC4: 5042 *key_type = CKK_RC4; 5043 *key_length = params->keyLen; 5044 break; 5045 case SEC_OID_PKCS5_PBKDF2: 5046 /* key type must already be set */ 5047 if (*key_type == CKK_INVALID_KEY_TYPE) { 5048 crv = CKR_TEMPLATE_INCOMPLETE; 5049 break; 5050 } 5051 /* PBKDF2 needs to calculate the key length from the other parameters 5052 */ 5053 if (*key_length == 0) { 5054 *key_length = sftk_MapKeySize(*key_type); 5055 } 5056 if (*key_length == 0) { 5057 crv = CKR_TEMPLATE_INCOMPLETE; 5058 break; 5059 } 5060 params->keyLen = *key_length; 5061 break; 5062 default: 5063 crv = CKR_MECHANISM_INVALID; 5064 break; 5065 } 5066 if (crv == CKR_OK) { 5067 *pbe = params; 5068 } else { 5069 nsspkcs5_DestroyPBEParameter(params); 5070 } 5071 return crv; 5072 } 5073 5074 /* NSC_GenerateKey generates a secret key, creating a new key object. */ 5075 CK_RV 5076 NSC_GenerateKey(CK_SESSION_HANDLE hSession, 5077 CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 5078 CK_OBJECT_HANDLE_PTR phKey) 5079 { 5080 SFTKObject *key; 5081 SFTKSession *session; 5082 PRBool checkWeak = PR_FALSE; 5083 CK_ULONG key_length = 0; 5084 CK_KEY_TYPE key_type = CKK_INVALID_KEY_TYPE; 5085 CK_OBJECT_CLASS objclass = CKO_SECRET_KEY; 5086 CK_RV crv = CKR_OK; 5087 CK_BBOOL cktrue = CK_TRUE; 5088 NSSPKCS5PBEParameter *pbe_param = NULL; 5089 int i; 5090 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); 5091 unsigned char buf[MAX_KEY_LEN]; 5092 enum { nsc_pbe, 5093 nsc_ssl, 5094 nsc_bulk, 5095 nsc_param, 5096 nsc_jpake } key_gen_type; 5097 SSL3RSAPreMasterSecret *rsa_pms; 5098 CK_VERSION *version; 5099 /* in very old versions of NSS, there were implementation errors with key 5100 * generation methods. We want to beable to read these, but not 5101 * produce them any more. The affected algorithm was 3DES. 5102 */ 5103 PRBool faultyPBE3DES = PR_FALSE; 5104 HASH_HashType hashType = HASH_AlgNULL; 5105 5106 CHECK_FORK(); 5107 5108 if (!slot) { 5109 return CKR_SESSION_HANDLE_INVALID; 5110 } 5111 /* 5112 * now lets create an object to hang the attributes off of 5113 */ 5114 key = sftk_NewObject(slot); /* fill in the handle later */ 5115 if (key == NULL) { 5116 return CKR_HOST_MEMORY; 5117 } 5118 5119 /* 5120 * load the template values into the object 5121 */ 5122 for (i = 0; i < (int)ulCount; i++) { 5123 if (pTemplate[i].type == CKA_VALUE_LEN) { 5124 key_length = *(CK_ULONG *)pTemplate[i].pValue; 5125 continue; 5126 } 5127 /* some algorithms need keytype specified */ 5128 if (pTemplate[i].type == CKA_KEY_TYPE) { 5129 key_type = *(CK_ULONG *)pTemplate[i].pValue; 5130 continue; 5131 } 5132 5133 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])); 5134 if (crv != CKR_OK) { 5135 break; 5136 } 5137 } 5138 if (crv != CKR_OK) { 5139 goto loser; 5140 } 5141 5142 /* make sure we don't have any class, key_type, or value fields */ 5143 sftk_DeleteAttributeType(key, CKA_CLASS); 5144 sftk_DeleteAttributeType(key, CKA_KEY_TYPE); 5145 sftk_DeleteAttributeType(key, CKA_VALUE); 5146 5147 /* Now Set up the parameters to generate the key (based on mechanism) */ 5148 key_gen_type = nsc_bulk; /* bulk key by default */ 5149 switch (pMechanism->mechanism) { 5150 case CKM_CDMF_KEY_GEN: 5151 case CKM_DES_KEY_GEN: 5152 case CKM_DES2_KEY_GEN: 5153 case CKM_DES3_KEY_GEN: 5154 checkWeak = PR_TRUE; 5155 /* fall through */ 5156 #ifndef NSS_DISABLE_DEPRECATED_RC2 5157 case CKM_RC2_KEY_GEN: 5158 #endif 5159 case CKM_RC4_KEY_GEN: 5160 case CKM_GENERIC_SECRET_KEY_GEN: 5161 #ifndef NSS_DISABLE_DEPRECATED_SEED 5162 case CKM_SEED_KEY_GEN: 5163 #endif 5164 case CKM_CAMELLIA_KEY_GEN: 5165 case CKM_AES_KEY_GEN: 5166 case CKM_NSS_CHACHA20_KEY_GEN: 5167 case CKM_CHACHA20_KEY_GEN: 5168 #if NSS_SOFTOKEN_DOES_RC5 5169 case CKM_RC5_KEY_GEN: 5170 #endif 5171 crv = nsc_SetupBulkKeyGen(pMechanism->mechanism, &key_type, &key_length); 5172 break; 5173 case CKM_SSL3_PRE_MASTER_KEY_GEN: 5174 key_type = CKK_GENERIC_SECRET; 5175 key_length = 48; 5176 key_gen_type = nsc_ssl; 5177 break; 5178 case CKM_PBA_SHA1_WITH_SHA1_HMAC: 5179 case CKM_NSS_PBE_SHA1_HMAC_KEY_GEN: 5180 case CKM_NSS_PBE_MD5_HMAC_KEY_GEN: 5181 case CKM_NSS_PBE_MD2_HMAC_KEY_GEN: 5182 case CKM_NSS_PKCS12_PBE_SHA224_HMAC_KEY_GEN: 5183 case CKM_NSS_PKCS12_PBE_SHA256_HMAC_KEY_GEN: 5184 case CKM_NSS_PKCS12_PBE_SHA384_HMAC_KEY_GEN: 5185 case CKM_NSS_PKCS12_PBE_SHA512_HMAC_KEY_GEN: 5186 key_gen_type = nsc_pbe; 5187 key_type = CKK_GENERIC_SECRET; 5188 crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param); 5189 break; 5190 case CKM_NSS_PBE_SHA1_FAULTY_3DES_CBC: 5191 faultyPBE3DES = PR_TRUE; 5192 /* fall through */ 5193 case CKM_NSS_PBE_SHA1_TRIPLE_DES_CBC: 5194 #ifndef NSS_DISABLE_DEPRECATED_RC2 5195 case CKM_NSS_PBE_SHA1_40_BIT_RC2_CBC: 5196 case CKM_NSS_PBE_SHA1_128_BIT_RC2_CBC: 5197 case CKM_PBE_SHA1_RC2_128_CBC: 5198 case CKM_PBE_SHA1_RC2_40_CBC: 5199 #endif 5200 case CKM_NSS_PBE_SHA1_DES_CBC: 5201 case CKM_NSS_PBE_SHA1_40_BIT_RC4: 5202 case CKM_NSS_PBE_SHA1_128_BIT_RC4: 5203 case CKM_PBE_SHA1_DES3_EDE_CBC: 5204 case CKM_PBE_SHA1_DES2_EDE_CBC: 5205 case CKM_PBE_SHA1_RC4_128: 5206 case CKM_PBE_SHA1_RC4_40: 5207 case CKM_PBE_MD5_DES_CBC: 5208 case CKM_PBE_MD2_DES_CBC: 5209 case CKM_PKCS5_PBKD2: 5210 key_gen_type = nsc_pbe; 5211 crv = nsc_SetupPBEKeyGen(pMechanism, &pbe_param, &key_type, &key_length); 5212 break; 5213 /*#ifndef NSS_DISABLE_DSA */ 5214 /* some applications use CKM_DSA_PARAMETER_GEN for weak DH keys... 5215 * most notably tests and even ssl... continue to allow it for now */ 5216 case CKM_DSA_PARAMETER_GEN: 5217 key_gen_type = nsc_param; 5218 key_type = CKK_DSA; 5219 objclass = CKO_DOMAIN_PARAMETERS; 5220 crv = CKR_OK; 5221 break; 5222 /* #endif */ 5223 case CKM_NSS_JPAKE_ROUND1_SHA1: 5224 hashType = HASH_AlgSHA1; 5225 goto jpake1; 5226 case CKM_NSS_JPAKE_ROUND1_SHA256: 5227 hashType = HASH_AlgSHA256; 5228 goto jpake1; 5229 case CKM_NSS_JPAKE_ROUND1_SHA384: 5230 hashType = HASH_AlgSHA384; 5231 goto jpake1; 5232 case CKM_NSS_JPAKE_ROUND1_SHA512: 5233 hashType = HASH_AlgSHA512; 5234 goto jpake1; 5235 jpake1: 5236 key_gen_type = nsc_jpake; 5237 key_type = CKK_NSS_JPAKE_ROUND1; 5238 objclass = CKO_PRIVATE_KEY; 5239 if (pMechanism->pParameter == NULL || 5240 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound1Params)) { 5241 crv = CKR_MECHANISM_PARAM_INVALID; 5242 break; 5243 } 5244 if (sftk_isTrue(key, CKA_TOKEN)) { 5245 crv = CKR_TEMPLATE_INCONSISTENT; 5246 break; 5247 } 5248 crv = CKR_OK; 5249 break; 5250 default: 5251 crv = CKR_MECHANISM_INVALID; 5252 break; 5253 } 5254 5255 /* make sure we aren't going to overflow the buffer */ 5256 if (sizeof(buf) < key_length) { 5257 /* someone is getting pretty optimistic about how big their key can 5258 * be... */ 5259 crv = CKR_TEMPLATE_INCONSISTENT; 5260 } 5261 5262 if (crv != CKR_OK) { 5263 if (pbe_param) { 5264 nsspkcs5_DestroyPBEParameter(pbe_param); 5265 } 5266 goto loser; 5267 } 5268 5269 /* if there was no error, 5270 * key_type *MUST* be set in the switch statement above */ 5271 PORT_Assert(key_type != CKK_INVALID_KEY_TYPE); 5272 5273 /* 5274 * now to the actual key gen. 5275 */ 5276 switch (key_gen_type) { 5277 case nsc_pbe: 5278 crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length, 5279 faultyPBE3DES); 5280 nsspkcs5_DestroyPBEParameter(pbe_param); 5281 break; 5282 case nsc_ssl: 5283 rsa_pms = (SSL3RSAPreMasterSecret *)buf; 5284 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_VERSION))) { 5285 crv = CKR_MECHANISM_PARAM_INVALID; 5286 goto loser; 5287 } 5288 version = (CK_VERSION *)pMechanism->pParameter; 5289 rsa_pms->client_version[0] = version->major; 5290 rsa_pms->client_version[1] = version->minor; 5291 crv = 5292 NSC_GenerateRandom(0, &rsa_pms->random[0], sizeof(rsa_pms->random)); 5293 break; 5294 case nsc_bulk: 5295 /* get the key, check for weak keys and repeat if found */ 5296 do { 5297 crv = NSC_GenerateRandom(0, buf, key_length); 5298 } while (crv == CKR_OK && checkWeak && sftk_IsWeakKey(buf, key_type)); 5299 break; 5300 case nsc_param: 5301 /* generate parameters */ 5302 *buf = 0; 5303 crv = nsc_parameter_gen(key_type, key); 5304 break; 5305 case nsc_jpake: 5306 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_NSS_JPAKERound1Params))) { 5307 crv = CKR_MECHANISM_PARAM_INVALID; 5308 goto loser; 5309 } 5310 crv = jpake_Round1(hashType, 5311 (CK_NSS_JPAKERound1Params *)pMechanism->pParameter, 5312 key); 5313 break; 5314 } 5315 5316 if (crv != CKR_OK) { 5317 goto loser; 5318 } 5319 5320 /* Add the class, key_type, and value */ 5321 crv = sftk_AddAttributeType(key, CKA_CLASS, &objclass, sizeof(CK_OBJECT_CLASS)); 5322 if (crv != CKR_OK) { 5323 goto loser; 5324 } 5325 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &key_type, sizeof(CK_KEY_TYPE)); 5326 if (crv != CKR_OK) { 5327 goto loser; 5328 } 5329 if (key_length != 0) { 5330 crv = sftk_AddAttributeType(key, CKA_VALUE, buf, key_length); 5331 if (crv != CKR_OK) { 5332 goto loser; 5333 } 5334 } 5335 5336 /* get the session */ 5337 session = sftk_SessionFromHandle(hSession); 5338 if (session == NULL) { 5339 crv = CKR_SESSION_HANDLE_INVALID; 5340 goto loser; 5341 } 5342 5343 /* 5344 * handle the base object stuff 5345 */ 5346 crv = sftk_handleObject(key, session); 5347 sftk_FreeSession(session); 5348 if (crv == CKR_OK && sftk_isTrue(key, CKA_SENSITIVE)) { 5349 crv = sftk_forceAttribute(key, CKA_ALWAYS_SENSITIVE, &cktrue, sizeof(CK_BBOOL)); 5350 } 5351 if (crv == CKR_OK && !sftk_isTrue(key, CKA_EXTRACTABLE)) { 5352 crv = sftk_forceAttribute(key, CKA_NEVER_EXTRACTABLE, &cktrue, sizeof(CK_BBOOL)); 5353 } 5354 if (crv == CKR_OK) { 5355 *phKey = key->handle; 5356 } 5357 loser: 5358 PORT_Memset(buf, 0, sizeof buf); 5359 sftk_FreeObject(key); 5360 return crv; 5361 } 5362 5363 /* takes raw sessions and key handles and determines if the keys 5364 * have the same value. */ 5365 PRBool 5366 sftk_compareKeysEqual(CK_SESSION_HANDLE hSession, 5367 CK_OBJECT_HANDLE key1, CK_OBJECT_HANDLE key2) 5368 { 5369 PRBool result = PR_FALSE; 5370 SFTKSession *session; 5371 SFTKObject *key1obj = NULL; 5372 SFTKObject *key2obj = NULL; 5373 SFTKAttribute *att1 = NULL; 5374 SFTKAttribute *att2 = NULL; 5375 5376 /* fetch the pkcs11 objects from the handles */ 5377 session = sftk_SessionFromHandle(hSession); 5378 if (session == NULL) { 5379 return CKR_SESSION_HANDLE_INVALID; 5380 } 5381 5382 key1obj = sftk_ObjectFromHandle(key1, session); 5383 key2obj = sftk_ObjectFromHandle(key2, session); 5384 sftk_FreeSession(session); 5385 if ((key1obj == NULL) || (key2obj == NULL)) { 5386 goto loser; 5387 } 5388 /* fetch the value attributes */ 5389 att1 = sftk_FindAttribute(key1obj, CKA_VALUE); 5390 if (att1 == NULL) { 5391 goto loser; 5392 } 5393 att2 = sftk_FindAttribute(key2obj, CKA_VALUE); 5394 if (att2 == NULL) { 5395 goto loser; 5396 } 5397 /* make sure that they are equal */ 5398 if (att1->attrib.ulValueLen != att2->attrib.ulValueLen) { 5399 goto loser; 5400 } 5401 if (PORT_Memcmp(att1->attrib.pValue, att2->attrib.pValue, 5402 att1->attrib.ulValueLen) != 0) { 5403 goto loser; 5404 } 5405 result = PR_TRUE; 5406 loser: 5407 if (key1obj) { 5408 sftk_FreeObject(key1obj); 5409 } 5410 if (key2obj) { 5411 sftk_FreeObject(key1obj); 5412 } 5413 if (att1) { 5414 sftk_FreeAttribute(att1); 5415 } 5416 if (att2) { 5417 sftk_FreeAttribute(att2); 5418 } 5419 return result; 5420 } 5421 5422 #define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */ 5423 5424 /* 5425 * FIPS 140-3 pairwise consistency check utilized to validate key pair. 5426 * 5427 * This function returns 5428 * CKR_OK if pairwise consistency check passed 5429 * CKR_GENERAL_ERROR if pairwise consistency check failed 5430 * other error codes if paiswise consistency check could not be 5431 * performed, for example, CKR_HOST_MEMORY. 5432 */ 5433 static CK_RV 5434 sftk_PairwiseConsistencyCheck(CK_SESSION_HANDLE hSession, SFTKSlot *slot, 5435 SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType) 5436 { 5437 /* 5438 * Key type Mechanism type 5439 * -------------------------------- 5440 * For encrypt/decrypt: CKK_RSA => CKM_RSA_PKCS_OAEP 5441 * others => CKM_INVALID_MECHANISM 5442 * 5443 * For sign/verify: CKK_RSA => CKM_SHA256_RSA_PKCS_PSS 5444 * CKK_DSA => CKM_DSA_SHA256 5445 * CKK_EC => CKM_ECDSA_SHA256 5446 * CKK_ML_DSA => CKM_ML_DSA 5447 * others => CKM_INVALID_MECHANISM 5448 * 5449 * None of these mechanisms has a parameter. 5450 * 5451 * For derive CKK_DH => CKM_DH_PKCS_DERIVE 5452 * CKK_EC => CKM_ECDH1_DERIVE 5453 * CKK_EC_MONTGOMERY => CKM_ECDH1_DERIVE 5454 * others => CKM_INVALID_MECHANISM 5455 * 5456 * For KEM mechanisms: 5457 * CKK_NSS_KYBER => don't 5458 * CKK_NSS_ML_KEM => don't 5459 * CKK_ML_KEM => CM_ML_KEM 5460 * 5461 * The parameters for these mechanisms is the public key. 5462 */ 5463 CK_MECHANISM mech = { 0, NULL, 0 }; 5464 5465 CK_ULONG modulusLen = 0; 5466 #ifndef NSS_DISABLE_DSA 5467 CK_ULONG subPrimeLen = 0; 5468 #endif 5469 PRBool isEncryptable = PR_FALSE; 5470 PRBool canSignVerify = PR_FALSE; 5471 PRBool isDerivable = PR_FALSE; 5472 PRBool isKEM = PR_FALSE; 5473 CK_RV crv; 5474 5475 /* Variables used for Encrypt/Decrypt functions. */ 5476 unsigned char *known_message = (unsigned char *)"Known Crypto Message"; 5477 unsigned char plaintext[PAIRWISE_MESSAGE_LENGTH]; 5478 CK_ULONG bytes_decrypted; 5479 unsigned char *ciphertext; 5480 unsigned char *text_compared; 5481 CK_ULONG bytes_encrypted; 5482 CK_ULONG bytes_compared; 5483 5484 /* Variables used for Signature/Verification functions. */ 5485 unsigned char *signature; 5486 CK_ULONG signature_length; 5487 SFTKAttribute *attribute; 5488 5489 switch (keyType) { 5490 case CKK_RSA: 5491 /* Get modulus length of private key. */ 5492 attribute = sftk_FindAttribute(privateKey, CKA_MODULUS); 5493 if (attribute == NULL) { 5494 return CKR_DEVICE_ERROR; 5495 } 5496 modulusLen = attribute->attrib.ulValueLen; 5497 if (*(unsigned char *)attribute->attrib.pValue == 0) { 5498 modulusLen--; 5499 } 5500 sftk_FreeAttribute(attribute); 5501 #if RSA_MIN_MODULUS_BITS < 1023 5502 /* if we allow weak RSA keys, and this is a weak RSA key and 5503 * we aren't in FIPS mode, skip the tests, These keys are 5504 * factorable anyway, the pairwise test doen't matter. */ 5505 if ((modulusLen < 1023) && !sftk_isFIPS(slot->slotID)) { 5506 return CKR_OK; 5507 } 5508 #endif 5509 break; 5510 #ifndef NSS_DISABLE_DSA 5511 case CKK_DSA: 5512 /* Get subprime length of private key. */ 5513 attribute = sftk_FindAttribute(privateKey, CKA_SUBPRIME); 5514 if (attribute == NULL) { 5515 return CKR_DEVICE_ERROR; 5516 } 5517 subPrimeLen = attribute->attrib.ulValueLen; 5518 if (subPrimeLen > 1 && 5519 *(unsigned char *)attribute->attrib.pValue == 0) { 5520 subPrimeLen--; 5521 } 5522 sftk_FreeAttribute(attribute); 5523 break; 5524 #endif 5525 case CKK_NSS_KYBER: 5526 case CKK_NSS_ML_KEM: 5527 /* these aren't FIPS. we use them to generate keys without a 5528 * pairwise consistency check */ 5529 return CKR_OK; 5530 } 5531 5532 /**************************************************/ 5533 /* Pairwise Consistency Check of Encrypt/Decrypt. */ 5534 /**************************************************/ 5535 5536 isEncryptable = sftk_isTrue(privateKey, CKA_DECRYPT); 5537 5538 /* 5539 * If the decryption attribute is set, attempt to encrypt 5540 * with the public key and decrypt with the private key. 5541 */ 5542 if (isEncryptable) { 5543 if (keyType != CKK_RSA) { 5544 return CKR_DEVICE_ERROR; 5545 } 5546 bytes_encrypted = modulusLen; 5547 mech.mechanism = CKM_RSA_PKCS_OAEP; 5548 CK_RSA_PKCS_OAEP_PARAMS oaepParams; 5549 oaepParams.hashAlg = CKM_SHA256; 5550 oaepParams.mgf = CKG_MGF1_SHA256; 5551 oaepParams.source = CKZ_DATA_SPECIFIED; 5552 oaepParams.pSourceData = NULL; 5553 oaepParams.ulSourceDataLen = 0; 5554 mech.pParameter = &oaepParams; 5555 mech.ulParameterLen = sizeof(oaepParams); 5556 5557 /* Allocate space for ciphertext. */ 5558 ciphertext = (unsigned char *)PORT_ZAlloc(bytes_encrypted); 5559 if (ciphertext == NULL) { 5560 return CKR_HOST_MEMORY; 5561 } 5562 5563 /* Prepare for encryption using the public key. */ 5564 crv = NSC_EncryptInit(hSession, &mech, publicKey->handle); 5565 if (crv != CKR_OK) { 5566 PORT_Free(ciphertext); 5567 return crv; 5568 } 5569 5570 /* Encrypt using the public key. */ 5571 crv = NSC_Encrypt(hSession, 5572 known_message, 5573 PAIRWISE_MESSAGE_LENGTH, 5574 ciphertext, 5575 &bytes_encrypted); 5576 if (crv != CKR_OK) { 5577 PORT_Free(ciphertext); 5578 return crv; 5579 } 5580 5581 /* Always use the smaller of these two values . . . */ 5582 bytes_compared = PR_MIN(bytes_encrypted, PAIRWISE_MESSAGE_LENGTH); 5583 5584 /* 5585 * If there was a failure, the plaintext 5586 * goes at the end, therefore . . . 5587 */ 5588 text_compared = ciphertext + bytes_encrypted - bytes_compared; 5589 5590 /* 5591 * Check to ensure that ciphertext does 5592 * NOT EQUAL known input message text 5593 * per FIPS PUB 140-2 directive. 5594 */ 5595 if (PORT_Memcmp(text_compared, known_message, 5596 bytes_compared) == 0) { 5597 /* Set error to Invalid PRIVATE Key. */ 5598 PORT_SetError(SEC_ERROR_INVALID_KEY); 5599 PORT_Free(ciphertext); 5600 return CKR_GENERAL_ERROR; 5601 } 5602 5603 /* Prepare for decryption using the private key. */ 5604 crv = NSC_DecryptInit(hSession, &mech, privateKey->handle); 5605 if (crv != CKR_OK) { 5606 PORT_Free(ciphertext); 5607 return crv; 5608 } 5609 5610 memset(plaintext, 0, PAIRWISE_MESSAGE_LENGTH); 5611 5612 /* 5613 * Initialize bytes decrypted to be the 5614 * expected PAIRWISE_MESSAGE_LENGTH. 5615 */ 5616 bytes_decrypted = PAIRWISE_MESSAGE_LENGTH; 5617 5618 /* 5619 * Decrypt using the private key. 5620 * NOTE: No need to reset the 5621 * value of bytes_encrypted. 5622 */ 5623 crv = NSC_Decrypt(hSession, 5624 ciphertext, 5625 bytes_encrypted, 5626 plaintext, 5627 &bytes_decrypted); 5628 5629 /* Finished with ciphertext; free it. */ 5630 PORT_Free(ciphertext); 5631 5632 if (crv != CKR_OK) { 5633 return crv; 5634 } 5635 5636 /* 5637 * Check to ensure that the output plaintext 5638 * does EQUAL known input message text. 5639 */ 5640 if ((bytes_decrypted != PAIRWISE_MESSAGE_LENGTH) || 5641 (PORT_Memcmp(plaintext, known_message, 5642 PAIRWISE_MESSAGE_LENGTH) != 0)) { 5643 /* Set error to Bad PUBLIC Key. */ 5644 PORT_SetError(SEC_ERROR_BAD_KEY); 5645 return CKR_GENERAL_ERROR; 5646 } 5647 } 5648 5649 /**********************************************/ 5650 /* Pairwise Consistency Check of Sign/Verify. */ 5651 /**********************************************/ 5652 5653 canSignVerify = sftk_isTrue(privateKey, CKA_SIGN); 5654 /* Unfortunately CKA_SIGN is always true in lg dbs. We have to check the 5655 * actual curve to determine if we can do sign/verify. */ 5656 if (canSignVerify && keyType == CKK_EC) { 5657 NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(privateKey, CKK_EC, &crv); 5658 if (privKey && privKey->u.ec.ecParams.name == ECCurve25519) { 5659 canSignVerify = PR_FALSE; 5660 } 5661 } 5662 5663 if (canSignVerify) { 5664 CK_RSA_PKCS_PSS_PARAMS pssParams; 5665 /* Determine length of signature. */ 5666 switch (keyType) { 5667 case CKK_RSA: 5668 signature_length = modulusLen; 5669 mech.mechanism = CKM_SHA256_RSA_PKCS_PSS; 5670 pssParams.hashAlg = CKM_SHA256; 5671 pssParams.mgf = CKG_MGF1_SHA256; 5672 pssParams.sLen = 0; 5673 mech.pParameter = &pssParams; 5674 mech.ulParameterLen = sizeof(pssParams); 5675 break; 5676 #ifndef NSS_DISABLE_DSA 5677 case CKK_DSA: 5678 signature_length = DSA_MAX_SIGNATURE_LEN; 5679 mech.mechanism = CKM_DSA_SHA256; 5680 break; 5681 #endif 5682 case CKK_EC: 5683 signature_length = MAX_ECKEY_LEN * 2; 5684 mech.mechanism = CKM_ECDSA_SHA256; 5685 break; 5686 case CKK_ML_DSA: 5687 signature_length = MAX_ML_DSA_SIGNATURE_LEN; 5688 mech.mechanism = CKM_ML_DSA; 5689 break; 5690 case CKK_EC_EDWARDS: 5691 signature_length = ED25519_SIGN_LEN; 5692 mech.mechanism = CKM_EDDSA; 5693 break; 5694 default: 5695 return CKR_DEVICE_ERROR; 5696 } 5697 5698 /* Allocate space for signature data. */ 5699 signature = (unsigned char *)PORT_ZAlloc(signature_length); 5700 if (signature == NULL) { 5701 return CKR_HOST_MEMORY; 5702 } 5703 5704 /* Sign the known hash using the private key. */ 5705 crv = NSC_SignInit(hSession, &mech, privateKey->handle); 5706 if (crv != CKR_OK) { 5707 PORT_Free(signature); 5708 return crv; 5709 } 5710 5711 crv = NSC_Sign(hSession, 5712 known_message, 5713 PAIRWISE_MESSAGE_LENGTH, 5714 signature, 5715 &signature_length); 5716 if (crv != CKR_OK) { 5717 PORT_Free(signature); 5718 return crv; 5719 } 5720 5721 /* detect trivial signing transforms */ 5722 if ((signature_length >= PAIRWISE_MESSAGE_LENGTH) && 5723 (PORT_Memcmp(known_message, signature + (signature_length - PAIRWISE_MESSAGE_LENGTH), PAIRWISE_MESSAGE_LENGTH) == 0)) { 5724 PORT_Free(signature); 5725 return CKR_GENERAL_ERROR; 5726 } 5727 5728 /* Verify the known hash using the public key. */ 5729 crv = NSC_VerifyInit(hSession, &mech, publicKey->handle); 5730 if (crv != CKR_OK) { 5731 PORT_Free(signature); 5732 return crv; 5733 } 5734 5735 crv = NSC_Verify(hSession, 5736 known_message, 5737 PAIRWISE_MESSAGE_LENGTH, 5738 signature, 5739 signature_length); 5740 5741 /* Free signature data. */ 5742 PORT_Free(signature); 5743 5744 if ((crv == CKR_SIGNATURE_LEN_RANGE) || 5745 (crv == CKR_SIGNATURE_INVALID)) { 5746 return CKR_GENERAL_ERROR; 5747 } 5748 if (crv != CKR_OK) { 5749 return crv; 5750 } 5751 } 5752 5753 /**********************************************/ 5754 /* Pairwise Consistency Check for Derivation */ 5755 /**********************************************/ 5756 5757 isDerivable = sftk_isTrue(privateKey, CKA_DERIVE); 5758 5759 if (isDerivable) { 5760 SFTKAttribute *pubAttribute = NULL; 5761 PRBool isFIPS = sftk_isFIPS(slot->slotID); 5762 NSSLOWKEYPrivateKey *lowPrivKey = NULL; 5763 ECPrivateKey *ecPriv = NULL; 5764 SECItem *lowPubValue = NULL; 5765 SECItem item = { siBuffer, NULL, 0 }; 5766 SECStatus rv; 5767 5768 crv = CKR_OK; /*paranoia, already get's set before we drop to the end */ 5769 5770 /* FIPS 140-3 requires we verify that the resulting key is a valid key 5771 * by recalculating the public can an compare it to our own public 5772 * key. */ 5773 lowPrivKey = sftk_GetPrivKey(privateKey, keyType, &crv); 5774 if (lowPrivKey == NULL) { 5775 return sftk_MapCryptError(PORT_GetError()); 5776 } 5777 /* recalculate the public key from the private key */ 5778 switch (keyType) { 5779 case CKK_DH: 5780 rv = DH_Derive(&lowPrivKey->u.dh.base, &lowPrivKey->u.dh.prime, 5781 &lowPrivKey->u.dh.privateValue, &item, 0); 5782 if (rv != SECSuccess) { 5783 return CKR_GENERAL_ERROR; 5784 } 5785 lowPubValue = SECITEM_DupItem(&item); 5786 SECITEM_ZfreeItem(&item, PR_FALSE); 5787 pubAttribute = sftk_FindAttribute(publicKey, CKA_VALUE); 5788 break; 5789 case CKK_EC_MONTGOMERY: 5790 case CKK_EC: 5791 rv = EC_NewKeyFromSeed(&lowPrivKey->u.ec.ecParams, &ecPriv, 5792 lowPrivKey->u.ec.privateValue.data, 5793 lowPrivKey->u.ec.privateValue.len); 5794 if (rv != SECSuccess) { 5795 return CKR_GENERAL_ERROR; 5796 } 5797 /* make sure it has the same encoding */ 5798 if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") || 5799 lowPrivKey->u.ec.ecParams.type != ec_params_named) { 5800 lowPubValue = SECITEM_DupItem(&ecPriv->publicValue); 5801 } else { 5802 lowPubValue = SEC_ASN1EncodeItem(NULL, NULL, &ecPriv->publicValue, 5803 SEC_ASN1_GET(SEC_OctetStringTemplate)); 5804 } 5805 pubAttribute = sftk_FindAttribute(publicKey, CKA_EC_POINT); 5806 /* clear out our generated private key */ 5807 PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE); 5808 break; 5809 default: 5810 return CKR_DEVICE_ERROR; 5811 } 5812 5813 /* now compare new public key with our already generated key */ 5814 if ((pubAttribute == NULL) || (lowPubValue == NULL) || 5815 (pubAttribute->attrib.ulValueLen != lowPubValue->len) || 5816 (PORT_Memcmp(pubAttribute->attrib.pValue, lowPubValue->data, 5817 lowPubValue->len) != 0)) { 5818 if (pubAttribute) 5819 sftk_FreeAttribute(pubAttribute); 5820 if (lowPubValue) 5821 SECITEM_ZfreeItem(lowPubValue, PR_TRUE); 5822 PORT_SetError(SEC_ERROR_BAD_KEY); 5823 return CKR_GENERAL_ERROR; 5824 } 5825 SECITEM_ZfreeItem(lowPubValue, PR_TRUE); 5826 5827 /* FIPS requires full validation, but in fipx mode NSC_Derive 5828 * only does partial validation with approved primes, now handle 5829 * full validation */ 5830 if (isFIPS && keyType == CKK_DH) { 5831 SECItem pubKey = { siBuffer, pubAttribute->attrib.pValue, 5832 pubAttribute->attrib.ulValueLen }; 5833 SECItem base = { siBuffer, NULL, 0 }; 5834 SECItem prime = { siBuffer, NULL, 0 }; 5835 SECItem subPrime = { siBuffer, NULL, 0 }; 5836 SECItem generator = { siBuffer, NULL, 0 }; 5837 const SECItem *subPrimePtr = &subPrime; 5838 5839 crv = sftk_Attribute2SecItem(NULL, &prime, privateKey, CKA_PRIME); 5840 if (crv != CKR_OK) { 5841 goto done; 5842 } 5843 crv = sftk_Attribute2SecItem(NULL, &base, privateKey, CKA_BASE); 5844 if (crv != CKR_OK) { 5845 goto done; 5846 } 5847 /* we ignore the return code an only look at the length */ 5848 /* do we have a known prime ? */ 5849 subPrimePtr = sftk_VerifyDH_Prime(&prime, &generator, isFIPS); 5850 if (subPrimePtr == NULL) { 5851 if (subPrime.len == 0) { 5852 /* if not a known prime, subprime must be supplied */ 5853 crv = CKR_ATTRIBUTE_VALUE_INVALID; 5854 goto done; 5855 } else { 5856 /* not a known prime, check for primality of prime 5857 * and subPrime */ 5858 if (!KEA_PrimeCheck(&prime)) { 5859 crv = CKR_ATTRIBUTE_VALUE_INVALID; 5860 goto done; 5861 } 5862 if (!KEA_PrimeCheck(&subPrime)) { 5863 crv = CKR_ATTRIBUTE_VALUE_INVALID; 5864 goto done; 5865 } 5866 /* if we aren't using a defined group, make sure base is in the 5867 * subgroup. If it's not, then our key could fail or succeed sometimes. 5868 * This makes the failure reliable */ 5869 if (!KEA_Verify(&base, &prime, &subPrime)) { 5870 crv = CKR_ATTRIBUTE_VALUE_INVALID; 5871 } 5872 } 5873 subPrimePtr = &subPrime; 5874 } else { 5875 /* we're using a known group, make sure we are using the known generator for that group */ 5876 if (SECITEM_CompareItem(&generator, &base) != 0) { 5877 crv = CKR_ATTRIBUTE_VALUE_INVALID; 5878 goto done; 5879 } 5880 if (subPrime.len != 0) { 5881 /* we have a known prime and a supplied subPrime, 5882 * make sure the subPrime matches the subPrime for 5883 * the known Prime */ 5884 if (SECITEM_CompareItem(subPrimePtr, &subPrime) != 0) { 5885 crv = CKR_ATTRIBUTE_VALUE_INVALID; 5886 goto done; 5887 } 5888 } 5889 } 5890 if (!KEA_Verify(&pubKey, &prime, (SECItem *)subPrimePtr)) { 5891 crv = CKR_ATTRIBUTE_VALUE_INVALID; 5892 } 5893 done: 5894 SECITEM_ZfreeItem(&base, PR_FALSE); 5895 SECITEM_ZfreeItem(&subPrime, PR_FALSE); 5896 SECITEM_ZfreeItem(&prime, PR_FALSE); 5897 } 5898 /* clean up before we return */ 5899 sftk_FreeAttribute(pubAttribute); 5900 if (crv != CKR_OK) { 5901 return crv; 5902 } 5903 } 5904 5905 isKEM = sftk_isTrue(privateKey, CKA_ENCAPSULATE); 5906 if (isKEM) { 5907 unsigned char *cipher_text = NULL; 5908 CK_ULONG cipher_text_length = 0; 5909 CK_OBJECT_HANDLE key1 = CK_INVALID_HANDLE; 5910 CK_OBJECT_HANDLE key2 = CK_INVALID_HANDLE; 5911 CK_KEY_TYPE genType = CKO_SECRET_KEY; 5912 CK_ATTRIBUTE template = { CKA_KEY_TYPE, NULL, 0 }; 5913 5914 template.pValue = &genType; 5915 template.ulValueLen = sizeof(genType); 5916 crv = CKR_OK; 5917 switch (keyType) { 5918 case CKK_ML_KEM: 5919 cipher_text_length = MAX_ML_KEM_CIPHER_LENGTH; 5920 mech.mechanism = CKM_ML_KEM; 5921 break; 5922 default: 5923 return CKR_DEVICE_ERROR; 5924 } 5925 /* Allocate space for kem cipher text. */ 5926 cipher_text = (unsigned char *)PORT_ZAlloc(cipher_text_length); 5927 if (cipher_text == NULL) { 5928 return CKR_HOST_MEMORY; 5929 } 5930 crv = NSC_Encapsulate(hSession, &mech, publicKey->handle, &template, 1, 5931 &key1, cipher_text, &cipher_text_length); 5932 if (crv != CKR_OK) { 5933 goto kem_done; 5934 } 5935 crv = NSC_Decapsulate(hSession, &mech, privateKey->handle, 5936 cipher_text, cipher_text_length, &template, 1, 5937 &key2); 5938 if (crv != CKR_OK) { 5939 goto kem_done; 5940 } 5941 if (!sftk_compareKeysEqual(hSession, key1, key2)) { 5942 crv = CKR_DEVICE_ERROR; 5943 goto kem_done; 5944 } 5945 kem_done: 5946 /* PORT_Free already checks for NULL */ 5947 PORT_Free(cipher_text); 5948 if (key1 != CK_INVALID_HANDLE) { 5949 NSC_DestroyObject(hSession, key1); 5950 } 5951 if (key2 != CK_INVALID_HANDLE) { 5952 NSC_DestroyObject(hSession, key2); 5953 } 5954 if (crv != CKR_OK) { 5955 return CKR_DEVICE_ERROR; 5956 } 5957 } 5958 5959 return CKR_OK; 5960 } 5961 5962 /* NSC_GenerateKeyPair generates a public-key/private-key pair, 5963 * creating new key objects. */ 5964 CK_RV 5965 NSC_GenerateKeyPair(CK_SESSION_HANDLE hSession, 5966 CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, 5967 CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, 5968 CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, 5969 CK_OBJECT_HANDLE_PTR phPrivateKey) 5970 { 5971 SFTKObject *publicKey, *privateKey; 5972 SFTKSession *session; 5973 CK_KEY_TYPE key_type; 5974 CK_RV crv = CKR_OK; 5975 CK_BBOOL cktrue = CK_TRUE; 5976 SECStatus rv; 5977 CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; 5978 CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; 5979 int i; 5980 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); 5981 unsigned int bitSize; 5982 5983 /* RSA */ 5984 int public_modulus_bits = 0; 5985 SECItem pubExp; 5986 RSAPrivateKey *rsaPriv; 5987 5988 DHParams dhParam; 5989 #ifndef NSS_DISABLE_DSA 5990 /* DSA */ 5991 PQGParams pqgParam; 5992 DSAPrivateKey *dsaPriv; 5993 #endif 5994 MLDSAPrivateKey mldsaPriv; 5995 MLDSAPublicKey mldsaPub; 5996 5997 /* Diffie Hellman */ 5998 DHPrivateKey *dhPriv; 5999 6000 /* Elliptic Curve Cryptography */ 6001 SECItem ecEncodedParams; /* DER Encoded parameters */ 6002 ECPrivateKey *ecPriv; 6003 ECParams *ecParams; 6004 6005 /* parameter set, mostly pq keys */ 6006 CK_ULONG genParamSet = 0; 6007 6008 CHECK_FORK(); 6009 6010 if (!slot) { 6011 return CKR_SESSION_HANDLE_INVALID; 6012 } 6013 /* 6014 * now lets create an object to hang the attributes off of 6015 */ 6016 publicKey = sftk_NewObject(slot); /* fill in the handle later */ 6017 if (publicKey == NULL) { 6018 return CKR_HOST_MEMORY; 6019 } 6020 6021 /* 6022 * load the template values into the publicKey 6023 */ 6024 for (i = 0; i < (int)ulPublicKeyAttributeCount; i++) { 6025 if (pPublicKeyTemplate[i].type == CKA_MODULUS_BITS) { 6026 public_modulus_bits = *(CK_ULONG *)pPublicKeyTemplate[i].pValue; 6027 continue; 6028 } 6029 6030 if ((pPublicKeyTemplate[i].type == CKA_PARAMETER_SET) || 6031 (pPublicKeyTemplate[i].type == CKA_NSS_PARAMETER_SET)) { 6032 genParamSet = *(CK_ULONG *)pPublicKeyTemplate[i].pValue; 6033 continue; 6034 } 6035 6036 crv = sftk_AddAttributeType(publicKey, 6037 sftk_attr_expand(&pPublicKeyTemplate[i])); 6038 if (crv != CKR_OK) 6039 break; 6040 } 6041 6042 if (crv != CKR_OK) { 6043 sftk_FreeObject(publicKey); 6044 return CKR_HOST_MEMORY; 6045 } 6046 6047 privateKey = sftk_NewObject(slot); /* fill in the handle later */ 6048 if (privateKey == NULL) { 6049 sftk_FreeObject(publicKey); 6050 return CKR_HOST_MEMORY; 6051 } 6052 /* 6053 * now load the private key template 6054 */ 6055 for (i = 0; i < (int)ulPrivateKeyAttributeCount; i++) { 6056 if (pPrivateKeyTemplate[i].type == CKA_VALUE_BITS) { 6057 continue; 6058 } 6059 6060 crv = sftk_AddAttributeType(privateKey, 6061 sftk_attr_expand(&pPrivateKeyTemplate[i])); 6062 if (crv != CKR_OK) 6063 break; 6064 } 6065 6066 if (crv != CKR_OK) { 6067 sftk_FreeObject(publicKey); 6068 sftk_FreeObject(privateKey); 6069 return CKR_HOST_MEMORY; 6070 } 6071 sftk_DeleteAttributeType(privateKey, CKA_CLASS); 6072 sftk_DeleteAttributeType(privateKey, CKA_KEY_TYPE); 6073 sftk_DeleteAttributeType(privateKey, CKA_VALUE); 6074 sftk_DeleteAttributeType(publicKey, CKA_CLASS); 6075 sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE); 6076 sftk_DeleteAttributeType(publicKey, CKA_VALUE); 6077 6078 /* Now Set up the parameters to generate the key (based on mechanism) */ 6079 switch (pMechanism->mechanism) { 6080 case CKM_RSA_PKCS_KEY_PAIR_GEN: 6081 /* format the keys */ 6082 sftk_DeleteAttributeType(publicKey, CKA_MODULUS); 6083 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB); 6084 sftk_DeleteAttributeType(privateKey, CKA_MODULUS); 6085 sftk_DeleteAttributeType(privateKey, CKA_PRIVATE_EXPONENT); 6086 sftk_DeleteAttributeType(privateKey, CKA_PUBLIC_EXPONENT); 6087 sftk_DeleteAttributeType(privateKey, CKA_PRIME_1); 6088 sftk_DeleteAttributeType(privateKey, CKA_PRIME_2); 6089 sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_1); 6090 sftk_DeleteAttributeType(privateKey, CKA_EXPONENT_2); 6091 sftk_DeleteAttributeType(privateKey, CKA_COEFFICIENT); 6092 key_type = CKK_RSA; 6093 if (public_modulus_bits == 0) { 6094 crv = CKR_TEMPLATE_INCOMPLETE; 6095 break; 6096 } 6097 if (public_modulus_bits < RSA_MIN_MODULUS_BITS) { 6098 crv = CKR_ATTRIBUTE_VALUE_INVALID; 6099 break; 6100 } 6101 if (public_modulus_bits % 2 != 0) { 6102 crv = CKR_ATTRIBUTE_VALUE_INVALID; 6103 break; 6104 } 6105 6106 /* extract the exponent */ 6107 crv = sftk_Attribute2SSecItem(NULL, &pubExp, publicKey, CKA_PUBLIC_EXPONENT); 6108 if (crv != CKR_OK) 6109 break; 6110 bitSize = sftk_GetLengthInBits(pubExp.data, pubExp.len); 6111 if (bitSize < 2) { 6112 crv = CKR_ATTRIBUTE_VALUE_INVALID; 6113 SECITEM_ZfreeItem(&pubExp, PR_FALSE); 6114 break; 6115 } 6116 crv = sftk_AddAttributeType(privateKey, CKA_PUBLIC_EXPONENT, 6117 sftk_item_expand(&pubExp)); 6118 if (crv != CKR_OK) { 6119 SECITEM_ZfreeItem(&pubExp, PR_FALSE); 6120 break; 6121 } 6122 6123 rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp); 6124 SECITEM_ZfreeItem(&pubExp, PR_FALSE); 6125 if (rsaPriv == NULL) { 6126 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 6127 sftk_fatalError = PR_TRUE; 6128 } 6129 crv = sftk_MapCryptError(PORT_GetError()); 6130 break; 6131 } 6132 /* now fill in the RSA dependent paramenters in the public key */ 6133 crv = sftk_AddAttributeType(publicKey, CKA_MODULUS, 6134 sftk_item_expand(&rsaPriv->modulus)); 6135 if (crv != CKR_OK) 6136 goto kpg_done; 6137 /* now fill in the RSA dependent paramenters in the private key */ 6138 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB, 6139 sftk_item_expand(&rsaPriv->modulus)); 6140 if (crv != CKR_OK) 6141 goto kpg_done; 6142 crv = sftk_AddAttributeType(privateKey, CKA_MODULUS, 6143 sftk_item_expand(&rsaPriv->modulus)); 6144 if (crv != CKR_OK) 6145 goto kpg_done; 6146 crv = sftk_AddAttributeType(privateKey, CKA_PRIVATE_EXPONENT, 6147 sftk_item_expand(&rsaPriv->privateExponent)); 6148 if (crv != CKR_OK) 6149 goto kpg_done; 6150 crv = sftk_AddAttributeType(privateKey, CKA_PRIME_1, 6151 sftk_item_expand(&rsaPriv->prime1)); 6152 if (crv != CKR_OK) 6153 goto kpg_done; 6154 crv = sftk_AddAttributeType(privateKey, CKA_PRIME_2, 6155 sftk_item_expand(&rsaPriv->prime2)); 6156 if (crv != CKR_OK) 6157 goto kpg_done; 6158 crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_1, 6159 sftk_item_expand(&rsaPriv->exponent1)); 6160 if (crv != CKR_OK) 6161 goto kpg_done; 6162 crv = sftk_AddAttributeType(privateKey, CKA_EXPONENT_2, 6163 sftk_item_expand(&rsaPriv->exponent2)); 6164 if (crv != CKR_OK) 6165 goto kpg_done; 6166 crv = sftk_AddAttributeType(privateKey, CKA_COEFFICIENT, 6167 sftk_item_expand(&rsaPriv->coefficient)); 6168 kpg_done: 6169 /* Should zeroize the contents first, since this func doesn't. */ 6170 PORT_FreeArena(rsaPriv->arena, PR_TRUE); 6171 break; 6172 #ifndef NSS_DISABLE_DSA 6173 case CKM_DSA_KEY_PAIR_GEN: 6174 sftk_DeleteAttributeType(publicKey, CKA_VALUE); 6175 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB); 6176 sftk_DeleteAttributeType(privateKey, CKA_PRIME); 6177 sftk_DeleteAttributeType(privateKey, CKA_SUBPRIME); 6178 sftk_DeleteAttributeType(privateKey, CKA_BASE); 6179 key_type = CKK_DSA; 6180 6181 /* extract the necessary parameters and copy them to the private key */ 6182 crv = sftk_Attribute2SSecItem(NULL, &pqgParam.prime, publicKey, CKA_PRIME); 6183 if (crv != CKR_OK) 6184 break; 6185 crv = sftk_Attribute2SSecItem(NULL, &pqgParam.subPrime, publicKey, 6186 CKA_SUBPRIME); 6187 if (crv != CKR_OK) { 6188 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6189 break; 6190 } 6191 crv = sftk_Attribute2SSecItem(NULL, &pqgParam.base, publicKey, CKA_BASE); 6192 if (crv != CKR_OK) { 6193 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6194 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6195 break; 6196 } 6197 crv = sftk_AddAttributeType(privateKey, CKA_PRIME, 6198 sftk_item_expand(&pqgParam.prime)); 6199 if (crv != CKR_OK) { 6200 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6201 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6202 SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); 6203 break; 6204 } 6205 crv = sftk_AddAttributeType(privateKey, CKA_SUBPRIME, 6206 sftk_item_expand(&pqgParam.subPrime)); 6207 if (crv != CKR_OK) { 6208 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6209 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6210 SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); 6211 break; 6212 } 6213 crv = sftk_AddAttributeType(privateKey, CKA_BASE, 6214 sftk_item_expand(&pqgParam.base)); 6215 if (crv != CKR_OK) { 6216 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6217 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6218 SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); 6219 break; 6220 } 6221 6222 /* 6223 * these are checked by DSA_NewKey 6224 */ 6225 bitSize = sftk_GetLengthInBits(pqgParam.subPrime.data, 6226 pqgParam.subPrime.len); 6227 if ((bitSize < DSA_MIN_Q_BITS) || (bitSize > DSA_MAX_Q_BITS)) { 6228 crv = CKR_TEMPLATE_INCOMPLETE; 6229 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6230 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6231 SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); 6232 break; 6233 } 6234 bitSize = sftk_GetLengthInBits(pqgParam.prime.data, pqgParam.prime.len); 6235 if ((bitSize < DSA_MIN_P_BITS) || (bitSize > DSA_MAX_P_BITS)) { 6236 crv = CKR_TEMPLATE_INCOMPLETE; 6237 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6238 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6239 SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); 6240 break; 6241 } 6242 bitSize = sftk_GetLengthInBits(pqgParam.base.data, pqgParam.base.len); 6243 if ((bitSize < 2) || (bitSize > DSA_MAX_P_BITS)) { 6244 crv = CKR_TEMPLATE_INCOMPLETE; 6245 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6246 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6247 SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); 6248 break; 6249 } 6250 6251 /* Generate the key */ 6252 rv = DSA_NewKey(&pqgParam, &dsaPriv); 6253 6254 SECITEM_ZfreeItem(&pqgParam.prime, PR_FALSE); 6255 SECITEM_ZfreeItem(&pqgParam.subPrime, PR_FALSE); 6256 SECITEM_ZfreeItem(&pqgParam.base, PR_FALSE); 6257 6258 if (rv != SECSuccess) { 6259 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 6260 sftk_fatalError = PR_TRUE; 6261 } 6262 crv = sftk_MapCryptError(PORT_GetError()); 6263 break; 6264 } 6265 6266 /* store the generated key into the attributes */ 6267 crv = sftk_AddAttributeType(publicKey, CKA_VALUE, 6268 sftk_item_expand(&dsaPriv->publicValue)); 6269 if (crv != CKR_OK) 6270 goto dsagn_done; 6271 6272 /* now fill in the RSA dependent paramenters in the private key */ 6273 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB, 6274 sftk_item_expand(&dsaPriv->publicValue)); 6275 if (crv != CKR_OK) 6276 goto dsagn_done; 6277 crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 6278 sftk_item_expand(&dsaPriv->privateValue)); 6279 6280 dsagn_done: 6281 /* should zeroize, since this function doesn't. */ 6282 PORT_FreeArena(dsaPriv->params.arena, PR_TRUE); 6283 break; 6284 #endif 6285 case CKM_DH_PKCS_KEY_PAIR_GEN: 6286 sftk_DeleteAttributeType(privateKey, CKA_PRIME); 6287 sftk_DeleteAttributeType(privateKey, CKA_BASE); 6288 sftk_DeleteAttributeType(privateKey, CKA_VALUE); 6289 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB); 6290 key_type = CKK_DH; 6291 6292 /* extract the necessary parameters and copy them to private keys */ 6293 crv = sftk_Attribute2SSecItem(NULL, &dhParam.prime, publicKey, 6294 CKA_PRIME); 6295 if (crv != CKR_OK) 6296 break; 6297 crv = sftk_Attribute2SSecItem(NULL, &dhParam.base, publicKey, CKA_BASE); 6298 if (crv != CKR_OK) { 6299 SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); 6300 break; 6301 } 6302 crv = sftk_AddAttributeType(privateKey, CKA_PRIME, 6303 sftk_item_expand(&dhParam.prime)); 6304 if (crv != CKR_OK) { 6305 SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); 6306 SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); 6307 break; 6308 } 6309 crv = sftk_AddAttributeType(privateKey, CKA_BASE, 6310 sftk_item_expand(&dhParam.base)); 6311 if (crv != CKR_OK) { 6312 SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); 6313 SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); 6314 break; 6315 } 6316 bitSize = sftk_GetLengthInBits(dhParam.prime.data, dhParam.prime.len); 6317 if ((bitSize < DH_MIN_P_BITS) || (bitSize > DH_MAX_P_BITS)) { 6318 crv = CKR_TEMPLATE_INCOMPLETE; 6319 SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); 6320 SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); 6321 break; 6322 } 6323 bitSize = sftk_GetLengthInBits(dhParam.base.data, dhParam.base.len); 6324 if ((bitSize < 1) || (bitSize > DH_MAX_P_BITS)) { 6325 crv = CKR_TEMPLATE_INCOMPLETE; 6326 SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); 6327 SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); 6328 break; 6329 } 6330 6331 rv = DH_NewKey(&dhParam, &dhPriv); 6332 SECITEM_ZfreeItem(&dhParam.prime, PR_FALSE); 6333 SECITEM_ZfreeItem(&dhParam.base, PR_FALSE); 6334 if (rv != SECSuccess) { 6335 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 6336 sftk_fatalError = PR_TRUE; 6337 } 6338 crv = sftk_MapCryptError(PORT_GetError()); 6339 break; 6340 } 6341 6342 crv = sftk_AddAttributeType(publicKey, CKA_VALUE, 6343 sftk_item_expand(&dhPriv->publicValue)); 6344 if (crv != CKR_OK) 6345 goto dhgn_done; 6346 6347 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB, 6348 sftk_item_expand(&dhPriv->publicValue)); 6349 if (crv != CKR_OK) 6350 goto dhgn_done; 6351 6352 crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 6353 sftk_item_expand(&dhPriv->privateValue)); 6354 6355 dhgn_done: 6356 /* should zeroize, since this function doesn't. */ 6357 PORT_FreeArena(dhPriv->arena, PR_TRUE); 6358 break; 6359 6360 case CKM_EC_KEY_PAIR_GEN: 6361 case CKM_NSS_ECDHE_NO_PAIRWISE_CHECK_KEY_PAIR_GEN: 6362 sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS); 6363 sftk_DeleteAttributeType(privateKey, CKA_VALUE); 6364 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB); 6365 key_type = CKK_EC; 6366 6367 /* extract the necessary parameters and copy them to private keys */ 6368 crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey, 6369 CKA_EC_PARAMS); 6370 if (crv != CKR_OK) 6371 break; 6372 6373 crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS, 6374 sftk_item_expand(&ecEncodedParams)); 6375 if (crv != CKR_OK) { 6376 SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE); 6377 break; 6378 } 6379 6380 /* Decode ec params before calling EC_NewKey */ 6381 rv = EC_DecodeParams(&ecEncodedParams, &ecParams); 6382 SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE); 6383 if (rv != SECSuccess) { 6384 crv = sftk_MapCryptError(PORT_GetError()); 6385 break; 6386 } 6387 rv = EC_NewKey(ecParams, &ecPriv); 6388 if (rv != SECSuccess) { 6389 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 6390 sftk_fatalError = PR_TRUE; 6391 } 6392 PORT_FreeArena(ecParams->arena, PR_TRUE); 6393 crv = sftk_MapCryptError(PORT_GetError()); 6394 break; 6395 } 6396 6397 if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT") || 6398 ecParams->type != ec_params_named) { 6399 PORT_FreeArena(ecParams->arena, PR_TRUE); 6400 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, 6401 sftk_item_expand(&ecPriv->publicValue)); 6402 } else { 6403 PORT_FreeArena(ecParams->arena, PR_TRUE); 6404 SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, 6405 &ecPriv->publicValue, 6406 SEC_ASN1_GET(SEC_OctetStringTemplate)); 6407 if (!pubValue) { 6408 crv = CKR_ARGUMENTS_BAD; 6409 goto ecgn_done; 6410 } 6411 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, 6412 sftk_item_expand(pubValue)); 6413 SECITEM_ZfreeItem(pubValue, PR_TRUE); 6414 } 6415 if (crv != CKR_OK) 6416 goto ecgn_done; 6417 6418 crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 6419 sftk_item_expand(&ecPriv->privateValue)); 6420 if (crv != CKR_OK) 6421 goto ecgn_done; 6422 6423 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB, 6424 sftk_item_expand(&ecPriv->publicValue)); 6425 ecgn_done: 6426 /* should zeroize, since this function doesn't. */ 6427 PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE); 6428 break; 6429 6430 #ifndef NSS_DISABLE_KYBER 6431 case CKM_NSS_KYBER_KEY_PAIR_GEN: 6432 key_type = CKK_NSS_KYBER; 6433 goto do_ml_kem; 6434 #endif 6435 case CKM_NSS_ML_KEM_KEY_PAIR_GEN: 6436 key_type = CKK_NSS_ML_KEM; 6437 goto do_ml_kem; 6438 6439 case CKM_ML_KEM_KEY_PAIR_GEN: 6440 key_type = CKK_ML_KEM; 6441 6442 do_ml_kem: 6443 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB); 6444 SECItem privKey = { siBuffer, NULL, 0 }; 6445 SECItem pubKey = { siBuffer, NULL, 0 }; 6446 KyberParams kyberParams = sftk_kyber_PK11ParamToInternal(genParamSet); 6447 if (!sftk_kyber_AllocPrivKeyItem(kyberParams, &privKey)) { 6448 crv = CKR_HOST_MEMORY; 6449 goto kyber_done; 6450 } 6451 if (!sftk_kyber_AllocPubKeyItem(kyberParams, &pubKey)) { 6452 crv = CKR_HOST_MEMORY; 6453 goto kyber_done; 6454 } 6455 rv = Kyber_NewKey(kyberParams, NULL, &privKey, &pubKey); 6456 if (rv != SECSuccess) { 6457 crv = sftk_MapCryptError(PORT_GetError()); 6458 goto kyber_done; 6459 } 6460 6461 crv = sftk_AddAttributeType(publicKey, CKA_VALUE, sftk_item_expand(&pubKey)); 6462 if (crv != CKR_OK) { 6463 goto kyber_done; 6464 } 6465 crv = sftk_AddAttributeType(publicKey, CKA_PARAMETER_SET, 6466 &genParamSet, 6467 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); 6468 if (crv != CKR_OK) { 6469 goto kyber_done; 6470 } 6471 crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 6472 sftk_item_expand(&privKey)); 6473 if (crv != CKR_OK) { 6474 goto kyber_done; 6475 } 6476 crv = sftk_AddAttributeType(privateKey, CKA_PARAMETER_SET, 6477 &genParamSet, 6478 sizeof(CK_ML_KEM_PARAMETER_SET_TYPE)); 6479 if (crv != CKR_OK) { 6480 goto kyber_done; 6481 } 6482 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB, 6483 sftk_item_expand(&pubKey)); 6484 kyber_done: 6485 SECITEM_ZfreeItem(&privKey, PR_FALSE); 6486 SECITEM_FreeItem(&pubKey, PR_FALSE); 6487 break; 6488 6489 case CKM_ML_DSA_KEY_PAIR_GEN: 6490 sftk_DeleteAttributeType(publicKey, CKA_VALUE); 6491 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB); 6492 sftk_DeleteAttributeType(privateKey, CKA_SEED); 6493 key_type = CKK_ML_DSA; 6494 6495 /* 6496 * the parameters are recognized by us 6497 */ 6498 bitSize = sftk_MLDSAGetSigLen(genParamSet); 6499 if (bitSize == 0) { 6500 crv = CKR_TEMPLATE_INCOMPLETE; 6501 break; 6502 } 6503 6504 /* Generate the key */ 6505 rv = MLDSA_NewKey(genParamSet, NULL, &mldsaPriv, &mldsaPub); 6506 6507 if (rv != SECSuccess) { 6508 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 6509 sftk_fatalError = PR_TRUE; 6510 } 6511 crv = sftk_MapCryptError(PORT_GetError()); 6512 break; 6513 } 6514 6515 /* store the generated key into the attributes */ 6516 crv = sftk_AddAttributeType(publicKey, CKA_VALUE, 6517 mldsaPub.keyVal, mldsaPub.keyValLen); 6518 if (crv != CKR_OK) 6519 goto mldsagn_done; 6520 crv = sftk_AddAttributeType(publicKey, CKA_PARAMETER_SET, 6521 &genParamSet, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); 6522 if (crv != CKR_OK) { 6523 goto mldsagn_done; 6524 } 6525 6526 /* now fill in the ML-DSA specfic paramenters in the private key */ 6527 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB, 6528 mldsaPub.keyVal, mldsaPub.keyValLen); 6529 if (crv != CKR_OK) 6530 goto mldsagn_done; 6531 6532 crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 6533 mldsaPriv.keyVal, 6534 mldsaPriv.keyValLen); 6535 if (crv != CKR_OK) 6536 goto mldsagn_done; 6537 crv = sftk_AddAttributeType(privateKey, CKA_PARAMETER_SET, 6538 &genParamSet, sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); 6539 if (crv != CKR_OK) { 6540 goto mldsagn_done; 6541 } 6542 6543 if (mldsaPriv.seedLen != 0) { 6544 crv = sftk_AddAttributeType(privateKey, CKA_SEED, 6545 mldsaPriv.seed, mldsaPriv.seedLen); 6546 if (crv != CKR_OK) { 6547 goto mldsagn_done; 6548 } 6549 /* pseudo attribute that says the seed came with the key 6550 * so don't try to regenerate the key in handleObject. 6551 * it will be removed before the object sees the light of 6552 * day. */ 6553 crv = sftk_AddAttributeType(privateKey, CKA_NSS_SEED_OK, 6554 NULL, 0); 6555 /* it was either this or a comment 'fall through' which would 6556 * be cryptic to some users */ 6557 if (crv != CKR_OK) { 6558 goto mldsagn_done; 6559 } 6560 } 6561 mldsagn_done: 6562 PORT_SafeZero(&mldsaPriv, sizeof(mldsaPriv)); 6563 PORT_SafeZero(&mldsaPub, sizeof(mldsaPub)); 6564 break; 6565 6566 case CKM_EC_MONTGOMERY_KEY_PAIR_GEN: 6567 case CKM_EC_EDWARDS_KEY_PAIR_GEN: 6568 sftk_DeleteAttributeType(privateKey, CKA_EC_PARAMS); 6569 sftk_DeleteAttributeType(privateKey, CKA_VALUE); 6570 sftk_DeleteAttributeType(privateKey, CKA_NSS_DB); 6571 key_type = (pMechanism->mechanism == CKM_EC_EDWARDS_KEY_PAIR_GEN) ? CKK_EC_EDWARDS : CKK_EC_MONTGOMERY; 6572 6573 /* extract the necessary parameters and copy them to private keys */ 6574 crv = sftk_Attribute2SSecItem(NULL, &ecEncodedParams, publicKey, 6575 CKA_EC_PARAMS); 6576 if (crv != CKR_OK) { 6577 break; 6578 } 6579 6580 crv = sftk_AddAttributeType(privateKey, CKA_EC_PARAMS, 6581 sftk_item_expand(&ecEncodedParams)); 6582 if (crv != CKR_OK) { 6583 SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE); 6584 break; 6585 } 6586 6587 /* Decode ec params before calling EC_NewKey */ 6588 rv = EC_DecodeParams(&ecEncodedParams, &ecParams); 6589 SECITEM_ZfreeItem(&ecEncodedParams, PR_FALSE); 6590 if (rv != SECSuccess) { 6591 crv = sftk_MapCryptError(PORT_GetError()); 6592 break; 6593 } 6594 6595 rv = EC_NewKey(ecParams, &ecPriv); 6596 if (rv != SECSuccess) { 6597 if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { 6598 sftk_fatalError = PR_TRUE; 6599 } 6600 PORT_FreeArena(ecParams->arena, PR_TRUE); 6601 crv = sftk_MapCryptError(PORT_GetError()); 6602 break; 6603 } 6604 PORT_FreeArena(ecParams->arena, PR_TRUE); 6605 crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, 6606 sftk_item_expand(&ecPriv->publicValue)); 6607 if (crv != CKR_OK) 6608 goto edgn_done; 6609 6610 crv = sftk_AddAttributeType(privateKey, CKA_VALUE, 6611 sftk_item_expand(&ecPriv->privateValue)); 6612 if (crv != CKR_OK) 6613 goto edgn_done; 6614 6615 crv = sftk_AddAttributeType(privateKey, CKA_NSS_DB, 6616 sftk_item_expand(&ecPriv->publicValue)); 6617 edgn_done: 6618 /* should zeroize, since this function doesn't. */ 6619 PORT_FreeArena(ecPriv->ecParams.arena, PR_TRUE); 6620 break; 6621 6622 default: 6623 crv = CKR_MECHANISM_INVALID; 6624 } 6625 6626 if (crv != CKR_OK) { 6627 sftk_FreeObject(privateKey); 6628 sftk_FreeObject(publicKey); 6629 return crv; 6630 } 6631 6632 /* Add the class, key_type The loop lets us check errors blow out 6633 * on errors and clean up at the bottom */ 6634 session = NULL; /* make pedtantic happy... session cannot leave the*/ 6635 /* loop below NULL unless an error is set... */ 6636 do { 6637 crv = sftk_AddAttributeType(privateKey, CKA_CLASS, &privClass, 6638 sizeof(CK_OBJECT_CLASS)); 6639 if (crv != CKR_OK) 6640 break; 6641 crv = sftk_AddAttributeType(publicKey, CKA_CLASS, &pubClass, 6642 sizeof(CK_OBJECT_CLASS)); 6643 if (crv != CKR_OK) 6644 break; 6645 crv = sftk_AddAttributeType(privateKey, CKA_KEY_TYPE, &key_type, 6646 sizeof(CK_KEY_TYPE)); 6647 if (crv != CKR_OK) 6648 break; 6649 crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE, &key_type, 6650 sizeof(CK_KEY_TYPE)); 6651 if (crv != CKR_OK) 6652 break; 6653 session = sftk_SessionFromHandle(hSession); 6654 if (session == NULL) 6655 crv = CKR_SESSION_HANDLE_INVALID; 6656 } while (0); 6657 6658 if (crv != CKR_OK) { 6659 sftk_FreeObject(privateKey); 6660 sftk_FreeObject(publicKey); 6661 return crv; 6662 } 6663 6664 /* 6665 * handle the base object cleanup for the public Key 6666 */ 6667 crv = sftk_handleObject(privateKey, session); 6668 if (crv != CKR_OK) { 6669 sftk_FreeSession(session); 6670 sftk_FreeObject(privateKey); 6671 sftk_FreeObject(publicKey); 6672 return crv; 6673 } 6674 6675 /* 6676 * handle the base object cleanup for the private Key 6677 * If we have any problems, we destroy the public Key we've 6678 * created and linked. 6679 */ 6680 crv = sftk_handleObject(publicKey, session); 6681 sftk_FreeSession(session); 6682 if (crv != CKR_OK) { 6683 sftk_FreeObject(publicKey); 6684 NSC_DestroyObject(hSession, privateKey->handle); 6685 sftk_FreeObject(privateKey); 6686 return crv; 6687 } 6688 if (sftk_isTrue(privateKey, CKA_SENSITIVE)) { 6689 crv = sftk_forceAttribute(privateKey, CKA_ALWAYS_SENSITIVE, 6690 &cktrue, sizeof(CK_BBOOL)); 6691 } 6692 if (crv == CKR_OK && sftk_isTrue(publicKey, CKA_SENSITIVE)) { 6693 crv = sftk_forceAttribute(publicKey, CKA_ALWAYS_SENSITIVE, 6694 &cktrue, sizeof(CK_BBOOL)); 6695 } 6696 if (crv == CKR_OK && !sftk_isTrue(privateKey, CKA_EXTRACTABLE)) { 6697 crv = sftk_forceAttribute(privateKey, CKA_NEVER_EXTRACTABLE, 6698 &cktrue, sizeof(CK_BBOOL)); 6699 } 6700 if (crv == CKR_OK && !sftk_isTrue(publicKey, CKA_EXTRACTABLE)) { 6701 crv = sftk_forceAttribute(publicKey, CKA_NEVER_EXTRACTABLE, 6702 &cktrue, sizeof(CK_BBOOL)); 6703 } 6704 6705 if (crv == CKR_OK && 6706 pMechanism->mechanism != CKM_NSS_ECDHE_NO_PAIRWISE_CHECK_KEY_PAIR_GEN) { 6707 /* Perform FIPS 140-2 pairwise consistency check. */ 6708 crv = sftk_PairwiseConsistencyCheck(hSession, slot, 6709 publicKey, privateKey, key_type); 6710 if (crv != CKR_OK) { 6711 if (sftk_audit_enabled) { 6712 char msg[128]; 6713 PR_snprintf(msg, sizeof msg, 6714 "C_GenerateKeyPair(hSession=0x%08lX, " 6715 "pMechanism->mechanism=0x%08lX)=0x%08lX " 6716 "self-test: pair-wise consistency test failed", 6717 (PRUint32)hSession, (PRUint32)pMechanism->mechanism, 6718 (PRUint32)crv); 6719 sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg); 6720 } 6721 } 6722 } 6723 6724 if (crv != CKR_OK) { 6725 NSC_DestroyObject(hSession, publicKey->handle); 6726 sftk_FreeObject(publicKey); 6727 NSC_DestroyObject(hSession, privateKey->handle); 6728 sftk_FreeObject(privateKey); 6729 return crv; 6730 } 6731 *phPrivateKey = privateKey->handle; 6732 *phPublicKey = publicKey->handle; 6733 sftk_FreeObject(publicKey); 6734 sftk_FreeObject(privateKey); 6735 6736 return CKR_OK; 6737 } 6738 6739 static SECItem * 6740 sftk_PackagePrivateKey(SFTKObject *key, CK_RV *crvp) 6741 { 6742 NSSLOWKEYPrivateKey *lk = NULL; 6743 NSSLOWKEYPrivateKeyInfo *pki = NULL; 6744 SFTKAttribute *attribute = NULL; 6745 PLArenaPool *arena = NULL; 6746 SECOidTag algorithm = SEC_OID_UNKNOWN; 6747 void *dummy, *param = NULL; 6748 SECStatus rv = SECSuccess; 6749 SECItem *encodedKey = NULL; 6750 #ifdef EC_DEBUG 6751 SECItem *fordebug; 6752 #endif 6753 int savelen; 6754 6755 if (!key) { 6756 *crvp = CKR_KEY_HANDLE_INVALID; /* really can't happen */ 6757 return NULL; 6758 } 6759 6760 attribute = sftk_FindAttribute(key, CKA_KEY_TYPE); 6761 if (!attribute) { 6762 *crvp = CKR_KEY_TYPE_INCONSISTENT; 6763 return NULL; 6764 } 6765 6766 lk = sftk_GetPrivKey(key, *(CK_KEY_TYPE *)attribute->attrib.pValue, crvp); 6767 sftk_FreeAttribute(attribute); 6768 if (!lk) { 6769 return NULL; 6770 } 6771 6772 arena = PORT_NewArena(2048); /* XXX different size? */ 6773 if (!arena) { 6774 *crvp = CKR_HOST_MEMORY; 6775 rv = SECFailure; 6776 goto loser; 6777 } 6778 6779 pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(arena, 6780 sizeof(NSSLOWKEYPrivateKeyInfo)); 6781 if (!pki) { 6782 *crvp = CKR_HOST_MEMORY; 6783 rv = SECFailure; 6784 goto loser; 6785 } 6786 pki->arena = arena; 6787 6788 param = NULL; 6789 switch (lk->keyType) { 6790 case NSSLOWKEYRSAKey: 6791 prepare_low_rsa_priv_key_for_asn1(lk); 6792 dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, 6793 nsslowkey_RSAPrivateKeyTemplate); 6794 6795 /* determine RSA key type from the CKA_PUBLIC_KEY_INFO if present */ 6796 attribute = sftk_FindAttribute(key, CKA_PUBLIC_KEY_INFO); 6797 if (attribute) { 6798 NSSLOWKEYSubjectPublicKeyInfo *publicKeyInfo; 6799 SECItem spki; 6800 6801 spki.data = attribute->attrib.pValue; 6802 spki.len = attribute->attrib.ulValueLen; 6803 6804 publicKeyInfo = PORT_ArenaZAlloc(arena, 6805 sizeof(NSSLOWKEYSubjectPublicKeyInfo)); 6806 if (!publicKeyInfo) { 6807 sftk_FreeAttribute(attribute); 6808 *crvp = CKR_HOST_MEMORY; 6809 rv = SECFailure; 6810 goto loser; 6811 } 6812 rv = SEC_QuickDERDecodeItem(arena, publicKeyInfo, 6813 nsslowkey_SubjectPublicKeyInfoTemplate, 6814 &spki); 6815 if (rv != SECSuccess) { 6816 sftk_FreeAttribute(attribute); 6817 *crvp = CKR_KEY_TYPE_INCONSISTENT; 6818 goto loser; 6819 } 6820 algorithm = SECOID_GetAlgorithmTag(&publicKeyInfo->algorithm); 6821 if (algorithm != SEC_OID_PKCS1_RSA_ENCRYPTION && 6822 algorithm != SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { 6823 sftk_FreeAttribute(attribute); 6824 rv = SECFailure; 6825 *crvp = CKR_KEY_TYPE_INCONSISTENT; 6826 goto loser; 6827 } 6828 param = SECITEM_DupItem(&publicKeyInfo->algorithm.parameters); 6829 if (!param) { 6830 sftk_FreeAttribute(attribute); 6831 rv = SECFailure; 6832 *crvp = CKR_HOST_MEMORY; 6833 goto loser; 6834 } 6835 sftk_FreeAttribute(attribute); 6836 } else { 6837 /* default to PKCS #1 */ 6838 algorithm = SEC_OID_PKCS1_RSA_ENCRYPTION; 6839 } 6840 break; 6841 case NSSLOWKEYDSAKey: 6842 prepare_low_dsa_priv_key_export_for_asn1(lk); 6843 dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, 6844 nsslowkey_DSAPrivateKeyExportTemplate); 6845 prepare_low_pqg_params_for_asn1(&lk->u.dsa.params); 6846 param = SEC_ASN1EncodeItem(NULL, NULL, &(lk->u.dsa.params), 6847 nsslowkey_PQGParamsTemplate); 6848 algorithm = SEC_OID_ANSIX9_DSA_SIGNATURE; 6849 break; 6850 case NSSLOWKEYECKey: 6851 prepare_low_ec_priv_key_for_asn1(lk); 6852 /* Public value is encoded as a bit string so adjust length 6853 * to be in bits before ASN encoding and readjust 6854 * immediately after. 6855 * 6856 * Since the SECG specification recommends not including the 6857 * parameters as part of ECPrivateKey, we zero out the curveOID 6858 * length before encoding and restore it later. 6859 */ 6860 lk->u.ec.publicValue.len <<= 3; 6861 savelen = lk->u.ec.ecParams.curveOID.len; 6862 lk->u.ec.ecParams.curveOID.len = 0; 6863 dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, 6864 nsslowkey_ECPrivateKeyTemplate); 6865 lk->u.ec.ecParams.curveOID.len = savelen; 6866 lk->u.ec.publicValue.len >>= 3; 6867 6868 #ifdef EC_DEBUG 6869 fordebug = &pki->privateKey; 6870 SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKey", lk->keyType, 6871 fordebug); 6872 #endif 6873 6874 param = SECITEM_DupItem(&lk->u.ec.ecParams.DEREncoding); 6875 6876 algorithm = SEC_OID_ANSIX962_EC_PUBLIC_KEY; 6877 break; 6878 case NSSLOWKEYMLDSAKey: { 6879 SECItem seed = { siBuffer, NULL, 0 }; 6880 SECItem keyVal = { siBuffer, NULL, 0 }; 6881 dummy = NULL; 6882 6883 /* paramSet sets the algorithm */ 6884 switch (lk->u.mldsa.paramSet) { 6885 case CKP_ML_DSA_44: 6886 algorithm = SEC_OID_ML_DSA_44_PUBLIC_KEY; 6887 break; 6888 case CKP_ML_DSA_65: 6889 algorithm = SEC_OID_ML_DSA_65_PUBLIC_KEY; 6890 break; 6891 case CKP_ML_DSA_87: 6892 algorithm = SEC_OID_ML_DSA_87_PUBLIC_KEY; 6893 break; 6894 default: 6895 algorithm = SEC_OID_UNKNOWN; 6896 break; 6897 } 6898 if (algorithm == SEC_OID_UNKNOWN) { 6899 break; 6900 } 6901 6902 /* if we have the seed, copy it */ 6903 if (lk->u.mldsa.seedLen != 0) { 6904 rv = SECITEM_MakeItem(arena, &seed, lk->u.mldsa.seed, 6905 lk->u.mldsa.seedLen); 6906 if (rv != SECSuccess) { 6907 break; 6908 } 6909 } 6910 rv = SECITEM_MakeItem(arena, &keyVal, lk->u.mldsa.keyVal, 6911 lk->u.mldsa.keyValLen); 6912 if (rv != SECSuccess) { 6913 break; 6914 } 6915 if (lk == key->objectInfo) { 6916 /* we have a cached key, and we are about to 6917 * overwrite it, let's get a duplicate first */ 6918 lk = nsslowkey_CopyPrivateKey(lk); 6919 if (lk == NULL) { 6920 break; 6921 } 6922 } 6923 /* this overwrites the mldsa data, but we don't need it any 6924 * more because we are discarding lk once we encode */ 6925 lk->u.genpq.seedItem = seed; 6926 lk->u.genpq.keyItem = keyVal; 6927 6928 if (seed.len) { 6929 dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, 6930 nsslowkey_PQBothSeedAndPrivateKeyTemplate); 6931 } else { 6932 dummy = SEC_ASN1EncodeItem(arena, &pki->privateKey, lk, 6933 nsslowkey_PQPrivateKeyTemplate); 6934 } 6935 } break; 6936 6937 case NSSLOWKEYDHKey: 6938 default: 6939 dummy = NULL; 6940 break; 6941 } 6942 6943 if (!dummy || ((lk->keyType == NSSLOWKEYDSAKey) && !param)) { 6944 *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */ 6945 rv = SECFailure; 6946 goto loser; 6947 } 6948 6949 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, algorithm, 6950 (SECItem *)param); 6951 if (rv != SECSuccess) { 6952 *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */ 6953 rv = SECFailure; 6954 goto loser; 6955 } 6956 6957 dummy = SEC_ASN1EncodeInteger(arena, &pki->version, 6958 NSSLOWKEY_PRIVATE_KEY_INFO_VERSION); 6959 if (!dummy) { 6960 *crvp = CKR_DEVICE_ERROR; /* should map NSS SECError */ 6961 rv = SECFailure; 6962 goto loser; 6963 } 6964 6965 encodedKey = SEC_ASN1EncodeItem(NULL, NULL, pki, 6966 nsslowkey_PrivateKeyInfoTemplate); 6967 *crvp = encodedKey ? CKR_OK : CKR_DEVICE_ERROR; 6968 6969 #ifdef EC_DEBUG 6970 fordebug = encodedKey; 6971 SEC_PRINT("sftk_PackagePrivateKey()", "PrivateKeyInfo", lk->keyType, 6972 fordebug); 6973 #endif 6974 loser: 6975 if (arena) { 6976 PORT_FreeArena(arena, PR_TRUE); 6977 } 6978 6979 if (lk && (lk != key->objectInfo)) { 6980 nsslowkey_DestroyPrivateKey(lk); 6981 } 6982 6983 if (param) { 6984 SECITEM_ZfreeItem((SECItem *)param, PR_TRUE); 6985 } 6986 6987 if (rv != SECSuccess) { 6988 return NULL; 6989 } 6990 6991 return encodedKey; 6992 } 6993 6994 /* it doesn't matter yet, since we colapse error conditions in the 6995 * level above, but we really should map those few key error differences */ 6996 static CK_RV 6997 sftk_mapWrap(CK_RV crv) 6998 { 6999 switch (crv) { 7000 case CKR_ENCRYPTED_DATA_INVALID: 7001 crv = CKR_WRAPPED_KEY_INVALID; 7002 break; 7003 } 7004 return crv; 7005 } 7006 7007 /* NSC_WrapKey wraps (i.e., encrypts) a key. */ 7008 CK_RV 7009 NSC_WrapKey(CK_SESSION_HANDLE hSession, 7010 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, 7011 CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, 7012 CK_ULONG_PTR pulWrappedKeyLen) 7013 { 7014 SFTKSession *session; 7015 SFTKAttribute *attribute; 7016 SFTKObject *key; 7017 CK_RV crv; 7018 7019 CHECK_FORK(); 7020 7021 session = sftk_SessionFromHandle(hSession); 7022 if (session == NULL) { 7023 return CKR_SESSION_HANDLE_INVALID; 7024 } 7025 7026 key = sftk_ObjectFromHandle(hKey, session); 7027 if (key == NULL) { 7028 sftk_FreeSession(session); 7029 return CKR_KEY_HANDLE_INVALID; 7030 } 7031 7032 switch (key->objclass) { 7033 case CKO_SECRET_KEY: { 7034 SFTKSessionContext *context = NULL; 7035 SECItem pText; 7036 7037 attribute = sftk_FindAttribute(key, CKA_VALUE); 7038 7039 if (attribute == NULL) { 7040 crv = CKR_KEY_TYPE_INCONSISTENT; 7041 break; 7042 } 7043 crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey, 7044 CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE); 7045 if (crv != CKR_OK) { 7046 sftk_FreeAttribute(attribute); 7047 break; 7048 } 7049 7050 pText.type = siBuffer; 7051 pText.data = (unsigned char *)attribute->attrib.pValue; 7052 pText.len = attribute->attrib.ulValueLen; 7053 7054 /* Find out if this is a block cipher. */ 7055 crv = sftk_GetContext(hSession, &context, SFTK_ENCRYPT, PR_FALSE, NULL); 7056 if (crv != CKR_OK || !context) 7057 break; 7058 if (context->blockSize > 1) { 7059 unsigned int remainder = pText.len % context->blockSize; 7060 if (!context->doPad && remainder) { 7061 /* When wrapping secret keys with unpadded block ciphers, 7062 ** the keys are zero padded, if necessary, to fill out 7063 ** a full block. 7064 */ 7065 pText.len += context->blockSize - remainder; 7066 pText.data = PORT_ZAlloc(pText.len); 7067 if (pText.data) 7068 memcpy(pText.data, attribute->attrib.pValue, 7069 attribute->attrib.ulValueLen); 7070 else { 7071 crv = CKR_HOST_MEMORY; 7072 break; 7073 } 7074 } 7075 } 7076 7077 crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data, 7078 pText.len, pWrappedKey, pulWrappedKeyLen); 7079 /* always force a finalize, both on errors and when 7080 * we are just getting the size */ 7081 if (crv != CKR_OK || pWrappedKey == NULL) { 7082 CK_RV lcrv; 7083 lcrv = sftk_GetContext(hSession, &context, 7084 SFTK_ENCRYPT, PR_FALSE, NULL); 7085 sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); 7086 if (lcrv == CKR_OK && context) { 7087 sftk_FreeContext(context); 7088 } 7089 } 7090 7091 if (pText.data != (unsigned char *)attribute->attrib.pValue) 7092 PORT_ZFree(pText.data, pText.len); 7093 sftk_FreeAttribute(attribute); 7094 break; 7095 } 7096 7097 case CKO_PRIVATE_KEY: { 7098 SECItem *bpki = sftk_PackagePrivateKey(key, &crv); 7099 SFTKSessionContext *context = NULL; 7100 7101 if (!bpki) { 7102 break; 7103 } 7104 7105 crv = sftk_CryptInit(hSession, pMechanism, hWrappingKey, 7106 CKA_WRAP, CKA_WRAP, SFTK_ENCRYPT, PR_TRUE); 7107 if (crv != CKR_OK) { 7108 SECITEM_ZfreeItem(bpki, PR_TRUE); 7109 crv = CKR_KEY_TYPE_INCONSISTENT; 7110 break; 7111 } 7112 7113 crv = NSC_Encrypt(hSession, bpki->data, bpki->len, 7114 pWrappedKey, pulWrappedKeyLen); 7115 /* always force a finalize */ 7116 if (crv != CKR_OK || pWrappedKey == NULL) { 7117 CK_RV lcrv; 7118 lcrv = sftk_GetContext(hSession, &context, 7119 SFTK_ENCRYPT, PR_FALSE, NULL); 7120 sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); 7121 if (lcrv == CKR_OK && context) { 7122 sftk_FreeContext(context); 7123 } 7124 } 7125 SECITEM_ZfreeItem(bpki, PR_TRUE); 7126 break; 7127 } 7128 7129 default: 7130 crv = CKR_KEY_TYPE_INCONSISTENT; 7131 break; 7132 } 7133 sftk_FreeObject(key); 7134 sftk_FreeSession(session); 7135 return sftk_mapWrap(crv); 7136 } 7137 7138 /* 7139 * import a pprivate key info into the desired slot 7140 */ 7141 static SECStatus 7142 sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) 7143 { 7144 CK_BBOOL cktrue = CK_TRUE; 7145 CK_BBOOL ckfalse = CK_FALSE; 7146 CK_KEY_TYPE keyType = CKK_RSA; 7147 SECStatus rv = SECFailure; 7148 const SEC_ASN1Template *keyTemplate, *paramTemplate; 7149 void *paramDest = NULL; 7150 PLArenaPool *arena; 7151 NSSLOWKEYPrivateKey *lpk = NULL; 7152 NSSLOWKEYPrivateKeyInfo *pki = NULL; 7153 CK_RV crv = CKR_KEY_TYPE_INCONSISTENT; 7154 CK_ULONG paramSet = 0; 7155 7156 arena = PORT_NewArena(2048); 7157 if (!arena) { 7158 return SECFailure; 7159 } 7160 7161 pki = (NSSLOWKEYPrivateKeyInfo *)PORT_ArenaZAlloc(arena, 7162 sizeof(NSSLOWKEYPrivateKeyInfo)); 7163 if (!pki) { 7164 PORT_FreeArena(arena, PR_FALSE); 7165 return SECFailure; 7166 } 7167 7168 if (SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) != SECSuccess) { 7169 PORT_FreeArena(arena, PR_TRUE); 7170 return SECFailure; 7171 } 7172 7173 lpk = (NSSLOWKEYPrivateKey *)PORT_ArenaZAlloc(arena, 7174 sizeof(NSSLOWKEYPrivateKey)); 7175 if (lpk == NULL) { 7176 goto loser; 7177 } 7178 lpk->arena = arena; 7179 7180 switch (SECOID_GetAlgorithmTag(&pki->algorithm)) { 7181 case SEC_OID_PKCS1_RSA_ENCRYPTION: 7182 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: 7183 keyTemplate = nsslowkey_RSAPrivateKeyTemplate; 7184 paramTemplate = NULL; 7185 paramDest = NULL; 7186 lpk->keyType = NSSLOWKEYRSAKey; 7187 prepare_low_rsa_priv_key_for_asn1(lpk); 7188 break; 7189 case SEC_OID_ANSIX9_DSA_SIGNATURE: 7190 keyTemplate = nsslowkey_DSAPrivateKeyExportTemplate; 7191 paramTemplate = nsslowkey_PQGParamsTemplate; 7192 paramDest = &(lpk->u.dsa.params); 7193 lpk->keyType = NSSLOWKEYDSAKey; 7194 prepare_low_dsa_priv_key_export_for_asn1(lpk); 7195 prepare_low_pqg_params_for_asn1(&lpk->u.dsa.params); 7196 break; 7197 /* case NSSLOWKEYDHKey: */ 7198 case SEC_OID_ANSIX962_EC_PUBLIC_KEY: 7199 keyTemplate = nsslowkey_ECPrivateKeyTemplate; 7200 paramTemplate = NULL; 7201 paramDest = &(lpk->u.ec.ecParams.DEREncoding); 7202 lpk->keyType = NSSLOWKEYECKey; 7203 prepare_low_ec_priv_key_for_asn1(lpk); 7204 prepare_low_ecparams_for_asn1(&lpk->u.ec.ecParams); 7205 break; 7206 case SEC_OID_ML_DSA_44_PUBLIC_KEY: 7207 paramSet = CKP_ML_DSA_44; 7208 goto mldsa_next; 7209 case SEC_OID_ML_DSA_65_PUBLIC_KEY: 7210 paramSet = CKP_ML_DSA_65; 7211 goto mldsa_next; 7212 case SEC_OID_ML_DSA_87_PUBLIC_KEY: 7213 paramSet = CKP_ML_DSA_87; 7214 mldsa_next: 7215 switch (pki->privateKey.data[0]) { 7216 case SEC_ASN1_CONTEXT_SPECIFIC | 0: 7217 keyTemplate = nsslowkey_PQSeedTemplate; 7218 break; 7219 case SEC_ASN1_OCTET_STRING: 7220 keyTemplate = nsslowkey_PQPrivateKeyTemplate; 7221 break; 7222 case SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE: 7223 keyTemplate = nsslowkey_PQBothSeedAndPrivateKeyTemplate; 7224 break; 7225 default: 7226 keyTemplate = NULL; 7227 break; 7228 } 7229 7230 paramTemplate = NULL; 7231 paramDest = NULL; 7232 lpk->keyType = NSSLOWKEYMLDSAKey; 7233 /* genpq encodes ocect, not integer, so no need to prep it */ 7234 break; 7235 default: 7236 keyTemplate = NULL; 7237 paramTemplate = NULL; 7238 paramDest = NULL; 7239 break; 7240 } 7241 7242 if (!keyTemplate) { 7243 goto loser; 7244 } 7245 7246 /* decode the private key and any algorithm parameters */ 7247 rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey); 7248 7249 if (lpk->keyType == NSSLOWKEYECKey) { 7250 /* convert length in bits to length in bytes */ 7251 lpk->u.ec.publicValue.len >>= 3; 7252 rv = SECITEM_CopyItem(arena, 7253 &(lpk->u.ec.ecParams.DEREncoding), 7254 &(pki->algorithm.parameters)); 7255 if (rv != SECSuccess) { 7256 goto loser; 7257 } 7258 } 7259 7260 if (rv != SECSuccess) { 7261 goto loser; 7262 } 7263 if (paramDest && paramTemplate) { 7264 rv = SEC_QuickDERDecodeItem(arena, paramDest, paramTemplate, 7265 &(pki->algorithm.parameters)); 7266 if (rv != SECSuccess) { 7267 goto loser; 7268 } 7269 } 7270 7271 rv = SECFailure; 7272 7273 switch (lpk->keyType) { 7274 case NSSLOWKEYRSAKey: 7275 keyType = CKK_RSA; 7276 if (sftk_hasAttribute(key, CKA_NSS_DB)) { 7277 sftk_DeleteAttributeType(key, CKA_NSS_DB); 7278 } 7279 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType, 7280 sizeof(keyType)); 7281 if (crv != CKR_OK) 7282 break; 7283 crv = sftk_AddAttributeType(key, CKA_UNWRAP, &cktrue, 7284 sizeof(CK_BBOOL)); 7285 if (crv != CKR_OK) 7286 break; 7287 crv = sftk_AddAttributeType(key, CKA_DECRYPT, &cktrue, 7288 sizeof(CK_BBOOL)); 7289 if (crv != CKR_OK) 7290 break; 7291 crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue, 7292 sizeof(CK_BBOOL)); 7293 if (crv != CKR_OK) 7294 break; 7295 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &cktrue, 7296 sizeof(CK_BBOOL)); 7297 if (crv != CKR_OK) 7298 break; 7299 crv = sftk_AddAttributeType(key, CKA_MODULUS, 7300 sftk_item_expand(&lpk->u.rsa.modulus)); 7301 if (crv != CKR_OK) 7302 break; 7303 crv = sftk_AddAttributeType(key, CKA_PUBLIC_EXPONENT, 7304 sftk_item_expand(&lpk->u.rsa.publicExponent)); 7305 if (crv != CKR_OK) 7306 break; 7307 crv = sftk_AddAttributeType(key, CKA_PRIVATE_EXPONENT, 7308 sftk_item_expand(&lpk->u.rsa.privateExponent)); 7309 if (crv != CKR_OK) 7310 break; 7311 crv = sftk_AddAttributeType(key, CKA_PRIME_1, 7312 sftk_item_expand(&lpk->u.rsa.prime1)); 7313 if (crv != CKR_OK) 7314 break; 7315 crv = sftk_AddAttributeType(key, CKA_PRIME_2, 7316 sftk_item_expand(&lpk->u.rsa.prime2)); 7317 if (crv != CKR_OK) 7318 break; 7319 crv = sftk_AddAttributeType(key, CKA_EXPONENT_1, 7320 sftk_item_expand(&lpk->u.rsa.exponent1)); 7321 if (crv != CKR_OK) 7322 break; 7323 crv = sftk_AddAttributeType(key, CKA_EXPONENT_2, 7324 sftk_item_expand(&lpk->u.rsa.exponent2)); 7325 if (crv != CKR_OK) 7326 break; 7327 crv = sftk_AddAttributeType(key, CKA_COEFFICIENT, 7328 sftk_item_expand(&lpk->u.rsa.coefficient)); 7329 break; 7330 case NSSLOWKEYDSAKey: 7331 keyType = CKK_DSA; 7332 crv = (sftk_hasAttribute(key, CKA_NSS_DB)) ? CKR_OK : CKR_KEY_TYPE_INCONSISTENT; 7333 if (crv != CKR_OK) 7334 break; 7335 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType, 7336 sizeof(keyType)); 7337 if (crv != CKR_OK) 7338 break; 7339 crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue, 7340 sizeof(CK_BBOOL)); 7341 if (crv != CKR_OK) 7342 break; 7343 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &ckfalse, 7344 sizeof(CK_BBOOL)); 7345 if (crv != CKR_OK) 7346 break; 7347 crv = sftk_AddAttributeType(key, CKA_PRIME, 7348 sftk_item_expand(&lpk->u.dsa.params.prime)); 7349 if (crv != CKR_OK) 7350 break; 7351 crv = sftk_AddAttributeType(key, CKA_SUBPRIME, 7352 sftk_item_expand(&lpk->u.dsa.params.subPrime)); 7353 if (crv != CKR_OK) 7354 break; 7355 crv = sftk_AddAttributeType(key, CKA_BASE, 7356 sftk_item_expand(&lpk->u.dsa.params.base)); 7357 if (crv != CKR_OK) 7358 break; 7359 crv = sftk_AddAttributeType(key, CKA_VALUE, 7360 sftk_item_expand(&lpk->u.dsa.privateValue)); 7361 if (crv != CKR_OK) 7362 break; 7363 break; 7364 case NSSLOWKEYMLDSAKey: 7365 keyType = CKK_ML_DSA; 7366 crv = (sftk_hasAttribute(key, CKA_NSS_DB)) ? CKR_OK : CKR_KEY_TYPE_INCONSISTENT; 7367 if (crv != CKR_OK) 7368 break; 7369 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType, 7370 sizeof(keyType)); 7371 if (crv != CKR_OK) 7372 break; 7373 crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue, 7374 sizeof(CK_BBOOL)); 7375 if (crv != CKR_OK) 7376 break; 7377 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &ckfalse, 7378 sizeof(CK_BBOOL)); 7379 if (crv != CKR_OK) 7380 break; 7381 crv = sftk_AddAttributeType(key, CKA_PARAMETER_SET, ¶mSet, 7382 sizeof(CK_ML_DSA_PARAMETER_SET_TYPE)); 7383 if (crv != CKR_OK) 7384 break; 7385 if (lpk->u.genpq.seedItem.len != 0) { 7386 crv = sftk_AddAttributeType(key, CKA_SEED, 7387 sftk_item_expand(&lpk->u.genpq.seedItem)); 7388 if (crv != CKR_OK) 7389 break; 7390 } 7391 7392 /* if we were given just the seed, we'll regenerate the key 7393 * from the seed in handleObject */ 7394 if (lpk->u.genpq.keyItem.len != 0) { 7395 crv = sftk_AddAttributeType(key, CKA_VALUE, 7396 sftk_item_expand(&lpk->u.genpq.keyItem)); 7397 /* I know, this is redundant, but it would be too easy 7398 * for someone to add another sftk_AddAttributeType after 7399 * this without adding this check back because of the if */ 7400 if (crv != CKR_OK) 7401 break; 7402 } 7403 break; 7404 #ifdef notdef 7405 case NSSLOWKEYDHKey: 7406 template = dhTemplate; 7407 templateCount = sizeof(dhTemplate) / sizeof(CK_ATTRIBUTE); 7408 keyType = CKK_DH; 7409 break; 7410 #endif 7411 /* what about fortezza??? */ 7412 case NSSLOWKEYECKey: 7413 keyType = CKK_EC; 7414 crv = (sftk_hasAttribute(key, CKA_NSS_DB)) ? CKR_OK : CKR_KEY_TYPE_INCONSISTENT; 7415 if (crv != CKR_OK) 7416 break; 7417 crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &keyType, 7418 sizeof(keyType)); 7419 if (crv != CKR_OK) 7420 break; 7421 crv = sftk_AddAttributeType(key, CKA_SIGN, &cktrue, 7422 sizeof(CK_BBOOL)); 7423 if (crv != CKR_OK) 7424 break; 7425 crv = sftk_AddAttributeType(key, CKA_SIGN_RECOVER, &ckfalse, 7426 sizeof(CK_BBOOL)); 7427 if (crv != CKR_OK) 7428 break; 7429 crv = sftk_AddAttributeType(key, CKA_DERIVE, &cktrue, 7430 sizeof(CK_BBOOL)); 7431 if (crv != CKR_OK) 7432 break; 7433 crv = sftk_AddAttributeType(key, CKA_EC_PARAMS, 7434 sftk_item_expand(&lpk->u.ec.ecParams.DEREncoding)); 7435 if (crv != CKR_OK) 7436 break; 7437 crv = sftk_AddAttributeType(key, CKA_VALUE, 7438 sftk_item_expand(&lpk->u.ec.privateValue)); 7439 if (crv != CKR_OK) 7440 break; 7441 /* XXX Do we need to decode the EC Params here ?? */ 7442 break; 7443 default: 7444 crv = CKR_KEY_TYPE_INCONSISTENT; 7445 break; 7446 } 7447 7448 if (crv != CKR_OK) { 7449 goto loser; 7450 } 7451 7452 /* For RSA-PSS, record the original algorithm parameters so 7453 * they can be encrypted altoghether when wrapping */ 7454 if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) { 7455 NSSLOWKEYSubjectPublicKeyInfo spki; 7456 NSSLOWKEYPublicKey pubk; 7457 SECItem *publicKeyInfo; 7458 7459 memset(&spki, 0, sizeof(NSSLOWKEYSubjectPublicKeyInfo)); 7460 rv = SECOID_CopyAlgorithmID(arena, &spki.algorithm, &pki->algorithm); 7461 if (rv != SECSuccess) { 7462 crv = CKR_HOST_MEMORY; 7463 goto loser; 7464 } 7465 7466 prepare_low_rsa_pub_key_for_asn1(&pubk); 7467 7468 rv = SECITEM_CopyItem(arena, &pubk.u.rsa.modulus, &lpk->u.rsa.modulus); 7469 if (rv != SECSuccess) { 7470 crv = CKR_HOST_MEMORY; 7471 goto loser; 7472 } 7473 rv = SECITEM_CopyItem(arena, &pubk.u.rsa.publicExponent, &lpk->u.rsa.publicExponent); 7474 if (rv != SECSuccess) { 7475 crv = CKR_HOST_MEMORY; 7476 goto loser; 7477 } 7478 7479 if (SEC_ASN1EncodeItem(arena, &spki.subjectPublicKey, 7480 &pubk, nsslowkey_RSAPublicKeyTemplate) == NULL) { 7481 crv = CKR_HOST_MEMORY; 7482 goto loser; 7483 } 7484 7485 publicKeyInfo = SEC_ASN1EncodeItem(arena, NULL, 7486 &spki, nsslowkey_SubjectPublicKeyInfoTemplate); 7487 if (!publicKeyInfo) { 7488 crv = CKR_HOST_MEMORY; 7489 goto loser; 7490 } 7491 crv = sftk_AddAttributeType(key, CKA_PUBLIC_KEY_INFO, 7492 sftk_item_expand(publicKeyInfo)); 7493 } 7494 7495 loser: 7496 if (lpk) { 7497 nsslowkey_DestroyPrivateKey(lpk); 7498 } 7499 7500 if (crv != CKR_OK) { 7501 return SECFailure; 7502 } 7503 7504 return SECSuccess; 7505 } 7506 7507 /* NSC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ 7508 CK_RV 7509 NSC_UnwrapKey(CK_SESSION_HANDLE hSession, 7510 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, 7511 CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, 7512 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 7513 CK_OBJECT_HANDLE_PTR phKey) 7514 { 7515 SFTKObject *key = NULL; 7516 SFTKSession *session; 7517 CK_ULONG key_length = 0; 7518 unsigned char *buf = NULL; 7519 CK_RV crv = CKR_OK; 7520 int i; 7521 CK_ULONG bsize = ulWrappedKeyLen; 7522 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); 7523 SECItem bpki; 7524 CK_OBJECT_CLASS target_type = CKO_SECRET_KEY; 7525 7526 CHECK_FORK(); 7527 7528 if (!slot) { 7529 return CKR_SESSION_HANDLE_INVALID; 7530 } 7531 /* 7532 * now lets create an object to hang the attributes off of 7533 */ 7534 key = sftk_NewObject(slot); /* fill in the handle later */ 7535 if (key == NULL) { 7536 return CKR_HOST_MEMORY; 7537 } 7538 7539 /* 7540 * load the template values into the object 7541 */ 7542 for (i = 0; i < (int)ulAttributeCount; i++) { 7543 if (pTemplate[i].type == CKA_VALUE_LEN) { 7544 key_length = *(CK_ULONG *)pTemplate[i].pValue; 7545 continue; 7546 } 7547 if (pTemplate[i].type == CKA_CLASS) { 7548 target_type = *(CK_OBJECT_CLASS *)pTemplate[i].pValue; 7549 } 7550 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])); 7551 if (crv != CKR_OK) 7552 break; 7553 } 7554 if (crv != CKR_OK) { 7555 sftk_FreeObject(key); 7556 return crv; 7557 } 7558 7559 crv = sftk_CryptInit(hSession, pMechanism, hUnwrappingKey, CKA_UNWRAP, 7560 CKA_UNWRAP, SFTK_DECRYPT, PR_FALSE); 7561 if (crv != CKR_OK) { 7562 sftk_FreeObject(key); 7563 return sftk_mapWrap(crv); 7564 } 7565 7566 /* allocate the buffer to decrypt into 7567 * this assumes the unwrapped key is never larger than the 7568 * wrapped key. For all the mechanisms we support this is true */ 7569 buf = (unsigned char *)PORT_Alloc(ulWrappedKeyLen); 7570 bsize = ulWrappedKeyLen; 7571 7572 crv = NSC_Decrypt(hSession, pWrappedKey, ulWrappedKeyLen, buf, &bsize); 7573 if (crv != CKR_OK) { 7574 sftk_FreeObject(key); 7575 PORT_Free(buf); 7576 return sftk_mapWrap(crv); 7577 } 7578 7579 switch (target_type) { 7580 case CKO_SECRET_KEY: 7581 if (!sftk_hasAttribute(key, CKA_KEY_TYPE)) { 7582 crv = CKR_TEMPLATE_INCOMPLETE; 7583 break; 7584 } 7585 7586 if (key_length == 0 || key_length > bsize) { 7587 key_length = bsize; 7588 } 7589 if (key_length > MAX_KEY_LEN) { 7590 crv = CKR_TEMPLATE_INCONSISTENT; 7591 break; 7592 } 7593 7594 /* add the value */ 7595 crv = sftk_AddAttributeType(key, CKA_VALUE, buf, key_length); 7596 break; 7597 case CKO_PRIVATE_KEY: 7598 bpki.data = (unsigned char *)buf; 7599 bpki.len = bsize; 7600 crv = CKR_OK; 7601 if (sftk_unwrapPrivateKey(key, &bpki) != SECSuccess) { 7602 crv = CKR_TEMPLATE_INCOMPLETE; 7603 } 7604 break; 7605 default: 7606 crv = CKR_TEMPLATE_INCONSISTENT; 7607 break; 7608 } 7609 7610 PORT_ZFree(buf, bsize); 7611 if (crv != CKR_OK) { 7612 sftk_FreeObject(key); 7613 return crv; 7614 } 7615 7616 /* get the session */ 7617 session = sftk_SessionFromHandle(hSession); 7618 if (session == NULL) { 7619 sftk_FreeObject(key); 7620 return CKR_SESSION_HANDLE_INVALID; 7621 } 7622 7623 /* mark the key as FIPS if the previous operation was all FIPS */ 7624 sftk_setFIPS(key, session->lastOpWasFIPS); 7625 /* 7626 * handle the base object stuff 7627 */ 7628 crv = sftk_handleObject(key, session); 7629 *phKey = key->handle; 7630 sftk_FreeSession(session); 7631 sftk_FreeObject(key); 7632 7633 return crv; 7634 } 7635 7636 CK_RV 7637 NSC_WrapKeyAuthenticated(CK_SESSION_HANDLE hSession, 7638 CK_MECHANISM_PTR pMechanism, 7639 CK_OBJECT_HANDLE hWrappingKey, 7640 CK_OBJECT_HANDLE hKey, 7641 CK_BYTE_PTR pAssociatedData, 7642 CK_ULONG ulAssociatedDataLen, 7643 CK_BYTE_PTR pWrappedKey, 7644 CK_ULONG_PTR pulWrappedKeyLen) 7645 { 7646 CHECK_FORK(); 7647 7648 return CKR_FUNCTION_NOT_SUPPORTED; 7649 } 7650 7651 CK_RV 7652 NSC_UnwrapKeyAuthenticated(CK_SESSION_HANDLE hSession, 7653 CK_MECHANISM_PTR pMechanism, 7654 CK_OBJECT_HANDLE hUnwrappingKey, 7655 CK_BYTE_PTR pWrappedKey, 7656 CK_ULONG ulWrappedKeyLen, 7657 CK_ATTRIBUTE_PTR pTemplate, 7658 CK_ULONG ulAttributeCount, 7659 CK_BYTE_PTR pAssociatedData, 7660 CK_ULONG ulAssociatedDataLen, 7661 CK_OBJECT_HANDLE_PTR phKey) 7662 { 7663 CHECK_FORK(); 7664 7665 return CKR_FUNCTION_NOT_SUPPORTED; 7666 } 7667 7668 /* 7669 * The SSL key gen mechanism create's lots of keys. This function handles the 7670 * details of each of these key creation. 7671 */ 7672 static CK_RV 7673 sftk_buildSSLKey(CK_SESSION_HANDLE hSession, SFTKObject *baseKey, 7674 PRBool isMacKey, unsigned char *keyBlock, unsigned int keySize, 7675 CK_OBJECT_HANDLE *keyHandle) 7676 { 7677 SFTKObject *key; 7678 SFTKSession *session; 7679 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; 7680 CK_BBOOL cktrue = CK_TRUE; 7681 CK_BBOOL ckfalse = CK_FALSE; 7682 CK_RV crv = CKR_HOST_MEMORY; 7683 7684 /* 7685 * now lets create an object to hang the attributes off of 7686 */ 7687 *keyHandle = CK_INVALID_HANDLE; 7688 key = sftk_NewObject(baseKey->slot); 7689 if (key == NULL) 7690 return CKR_HOST_MEMORY; 7691 sftk_narrowToSessionObject(key)->wasDerived = PR_TRUE; 7692 7693 crv = sftk_CopyObject(key, baseKey); 7694 if (crv != CKR_OK) 7695 goto loser; 7696 if (isMacKey) { 7697 crv = sftk_forceAttribute(key, CKA_KEY_TYPE, &keyType, sizeof(keyType)); 7698 if (crv != CKR_OK) 7699 goto loser; 7700 crv = sftk_forceAttribute(key, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); 7701 if (crv != CKR_OK) 7702 goto loser; 7703 crv = sftk_forceAttribute(key, CKA_ENCRYPT, &ckfalse, sizeof(CK_BBOOL)); 7704 if (crv != CKR_OK) 7705 goto loser; 7706 crv = sftk_forceAttribute(key, CKA_DECRYPT, &ckfalse, sizeof(CK_BBOOL)); 7707 if (crv != CKR_OK) 7708 goto loser; 7709 crv = sftk_forceAttribute(key, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); 7710 if (crv != CKR_OK) 7711 goto loser; 7712 crv = sftk_forceAttribute(key, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 7713 if (crv != CKR_OK) 7714 goto loser; 7715 crv = sftk_forceAttribute(key, CKA_WRAP, &ckfalse, sizeof(CK_BBOOL)); 7716 if (crv != CKR_OK) 7717 goto loser; 7718 crv = sftk_forceAttribute(key, CKA_UNWRAP, &ckfalse, sizeof(CK_BBOOL)); 7719 if (crv != CKR_OK) 7720 goto loser; 7721 } 7722 crv = sftk_forceAttribute(key, CKA_VALUE, keyBlock, keySize); 7723 if (crv != CKR_OK) 7724 goto loser; 7725 7726 /* get the session */ 7727 crv = CKR_HOST_MEMORY; 7728 session = sftk_SessionFromHandle(hSession); 7729 if (session == NULL) { 7730 goto loser; 7731 } 7732 7733 crv = sftk_handleObject(key, session); 7734 sftk_FreeSession(session); 7735 *keyHandle = key->handle; 7736 loser: 7737 if (key) 7738 sftk_FreeObject(key); 7739 return crv; 7740 } 7741 7742 /* 7743 * if there is an error, we need to free the keys we already created in SSL 7744 * This is the routine that will do it.. 7745 */ 7746 static void 7747 sftk_freeSSLKeys(CK_SESSION_HANDLE session, 7748 CK_SSL3_KEY_MAT_OUT *returnedMaterial) 7749 { 7750 if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) { 7751 NSC_DestroyObject(session, returnedMaterial->hClientMacSecret); 7752 } 7753 if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) { 7754 NSC_DestroyObject(session, returnedMaterial->hServerMacSecret); 7755 } 7756 if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) { 7757 NSC_DestroyObject(session, returnedMaterial->hClientKey); 7758 } 7759 if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) { 7760 NSC_DestroyObject(session, returnedMaterial->hServerKey); 7761 } 7762 } 7763 7764 /* 7765 * when deriving from sensitive and extractable keys, we need to preserve some 7766 * of the semantics in the derived key. This helper routine maintains these 7767 * semantics. 7768 */ 7769 static CK_RV 7770 sftk_DeriveSensitiveCheck(SFTKObject *baseKey, SFTKObject *destKey, 7771 PRBool canBeData) 7772 { 7773 PRBool hasSensitive; 7774 PRBool sensitive = PR_FALSE; 7775 CK_BBOOL bFalse = CK_FALSE; 7776 PRBool hasExtractable; 7777 PRBool extractable = PR_TRUE; 7778 CK_BBOOL bTrue = CK_TRUE; 7779 CK_RV crv = CKR_OK; 7780 SFTKAttribute *att; 7781 PRBool isData = PR_TRUE; 7782 7783 if (canBeData) { 7784 CK_OBJECT_CLASS objClass; 7785 7786 /* if the target key is actually data, don't set the unexpected 7787 * attributes */ 7788 crv = sftk_GetULongAttribute(destKey, CKA_CLASS, &objClass); 7789 if (crv != CKR_OK) { 7790 return crv; 7791 } 7792 if (objClass == CKO_DATA) { 7793 return CKR_OK; 7794 } 7795 7796 /* if the base key is data, it doesn't have sensitive attributes, 7797 * allow the destKey to get it's own */ 7798 crv = sftk_GetULongAttribute(baseKey, CKA_CLASS, &objClass); 7799 if (crv != CKR_OK) { 7800 return crv; 7801 } 7802 if (objClass == CKO_DATA) { 7803 isData = PR_TRUE; 7804 } 7805 } 7806 7807 hasSensitive = PR_FALSE; 7808 att = sftk_FindAttribute(destKey, CKA_SENSITIVE); 7809 if (att) { 7810 hasSensitive = PR_TRUE; 7811 sensitive = (PRBool) * (CK_BBOOL *)att->attrib.pValue; 7812 sftk_FreeAttribute(att); 7813 } 7814 7815 hasExtractable = PR_FALSE; 7816 att = sftk_FindAttribute(destKey, CKA_EXTRACTABLE); 7817 if (att) { 7818 hasExtractable = PR_TRUE; 7819 extractable = (PRBool) * (CK_BBOOL *)att->attrib.pValue; 7820 sftk_FreeAttribute(att); 7821 } 7822 7823 /* don't make a key more accessible */ 7824 if (sftk_isTrue(baseKey, CKA_SENSITIVE) && hasSensitive && 7825 (sensitive == PR_FALSE)) { 7826 return CKR_KEY_FUNCTION_NOT_PERMITTED; 7827 } 7828 if (!sftk_isTrue(baseKey, CKA_EXTRACTABLE) && hasExtractable && 7829 (extractable == PR_TRUE)) { 7830 return CKR_KEY_FUNCTION_NOT_PERMITTED; 7831 } 7832 7833 /* inherit parent's sensitivity */ 7834 if (!hasSensitive) { 7835 att = sftk_FindAttribute(baseKey, CKA_SENSITIVE); 7836 if (att != NULL) { 7837 crv = sftk_defaultAttribute(destKey, 7838 sftk_attr_expand(&att->attrib)); 7839 sftk_FreeAttribute(att); 7840 } else if (isData) { 7841 crv = sftk_defaultAttribute(destKey, CKA_SENSITIVE, 7842 &bFalse, sizeof(bFalse)); 7843 } else { 7844 return CKR_KEY_TYPE_INCONSISTENT; 7845 } 7846 if (crv != CKR_OK) 7847 return crv; 7848 } 7849 if (!hasExtractable) { 7850 att = sftk_FindAttribute(baseKey, CKA_EXTRACTABLE); 7851 if (att != NULL) { 7852 crv = sftk_defaultAttribute(destKey, 7853 sftk_attr_expand(&att->attrib)); 7854 sftk_FreeAttribute(att); 7855 } else if (isData) { 7856 crv = sftk_defaultAttribute(destKey, CKA_EXTRACTABLE, 7857 &bTrue, sizeof(bTrue)); 7858 } else { 7859 return CKR_KEY_TYPE_INCONSISTENT; 7860 } 7861 if (crv != CKR_OK) 7862 return crv; 7863 } 7864 7865 /* we should inherit the parent's always extractable/ never sensitive info, 7866 * but handleObject always forces this attributes, so we would need to do 7867 * something special. */ 7868 return CKR_OK; 7869 } 7870 7871 /* 7872 * make known fixed PKCS #11 key types to their sizes in bytes 7873 */ 7874 unsigned long 7875 sftk_MapKeySize(CK_KEY_TYPE keyType) 7876 { 7877 switch (keyType) { 7878 case CKK_CDMF: 7879 return 8; 7880 case CKK_DES: 7881 return 8; 7882 case CKK_DES2: 7883 return 16; 7884 case CKK_DES3: 7885 return 24; 7886 /* IDEA and CAST need to be added */ 7887 default: 7888 break; 7889 } 7890 return 0; 7891 } 7892 7893 /* Inputs: 7894 * key_len: Length of derived key to be generated. 7895 * SharedSecret: a shared secret that is the output of a key agreement primitive. 7896 * SharedInfo: (Optional) some data shared by the entities computing the secret key. 7897 * SharedInfoLen: the length in octets of SharedInfo 7898 * Hash: The hash function to be used in the KDF 7899 * HashLen: the length in octets of the output of Hash 7900 * Output: 7901 * key: Pointer to a buffer containing derived key, if return value is SECSuccess. 7902 */ 7903 static CK_RV 7904 sftk_compute_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, SECItem *SharedSecret, 7905 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, 7906 SECStatus Hash(unsigned char *, const unsigned char *, PRUint32), 7907 CK_ULONG HashLen) 7908 { 7909 unsigned char *buffer = NULL, *output_buffer = NULL; 7910 PRUint32 buffer_len, max_counter, i; 7911 SECStatus rv; 7912 CK_RV crv; 7913 7914 /* Check that key_len isn't too long. The maximum key length could be 7915 * greatly increased if the code below did not limit the 4-byte counter 7916 * to a maximum value of 255. */ 7917 if (key_len > 254 * HashLen) 7918 return CKR_ARGUMENTS_BAD; 7919 7920 if (SharedInfo == NULL) 7921 SharedInfoLen = 0; 7922 7923 buffer_len = SharedSecret->len + 4 + SharedInfoLen; 7924 buffer = (CK_BYTE *)PORT_Alloc(buffer_len); 7925 if (buffer == NULL) { 7926 crv = CKR_HOST_MEMORY; 7927 goto loser; 7928 } 7929 7930 max_counter = key_len / HashLen; 7931 if (key_len > max_counter * HashLen) 7932 max_counter++; 7933 7934 output_buffer = (CK_BYTE *)PORT_Alloc(max_counter * HashLen); 7935 if (output_buffer == NULL) { 7936 crv = CKR_HOST_MEMORY; 7937 goto loser; 7938 } 7939 7940 /* Populate buffer with SharedSecret || Counter || [SharedInfo] 7941 * where Counter is 0x00000001 */ 7942 PORT_Memcpy(buffer, SharedSecret->data, SharedSecret->len); 7943 buffer[SharedSecret->len] = 0; 7944 buffer[SharedSecret->len + 1] = 0; 7945 buffer[SharedSecret->len + 2] = 0; 7946 buffer[SharedSecret->len + 3] = 1; 7947 if (SharedInfo) { 7948 PORT_Memcpy(&buffer[SharedSecret->len + 4], SharedInfo, SharedInfoLen); 7949 } 7950 7951 for (i = 0; i < max_counter; i++) { 7952 rv = Hash(&output_buffer[i * HashLen], buffer, buffer_len); 7953 if (rv != SECSuccess) { 7954 /* 'Hash' should not fail. */ 7955 crv = CKR_FUNCTION_FAILED; 7956 goto loser; 7957 } 7958 7959 /* Increment counter (assumes max_counter < 255) */ 7960 buffer[SharedSecret->len + 3]++; 7961 } 7962 7963 PORT_ZFree(buffer, buffer_len); 7964 if (key_len < max_counter * HashLen) { 7965 PORT_Memset(output_buffer + key_len, 0, max_counter * HashLen - key_len); 7966 } 7967 *key = output_buffer; 7968 7969 return CKR_OK; 7970 7971 loser: 7972 if (buffer) { 7973 PORT_ZFree(buffer, buffer_len); 7974 } 7975 if (output_buffer) { 7976 PORT_ZFree(output_buffer, max_counter * HashLen); 7977 } 7978 return crv; 7979 } 7980 7981 static CK_RV 7982 sftk_ANSI_X9_63_kdf(CK_BYTE **key, CK_ULONG key_len, 7983 SECItem *SharedSecret, 7984 CK_BYTE_PTR SharedInfo, CK_ULONG SharedInfoLen, 7985 CK_EC_KDF_TYPE kdf) 7986 { 7987 if (kdf == CKD_SHA1_KDF) 7988 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, 7989 SharedInfoLen, SHA1_HashBuf, SHA1_LENGTH); 7990 else if (kdf == CKD_SHA224_KDF) 7991 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, 7992 SharedInfoLen, SHA224_HashBuf, SHA224_LENGTH); 7993 else if (kdf == CKD_SHA256_KDF) 7994 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, 7995 SharedInfoLen, SHA256_HashBuf, SHA256_LENGTH); 7996 else if (kdf == CKD_SHA384_KDF) 7997 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, 7998 SharedInfoLen, SHA384_HashBuf, SHA384_LENGTH); 7999 else if (kdf == CKD_SHA512_KDF) 8000 return sftk_compute_ANSI_X9_63_kdf(key, key_len, SharedSecret, SharedInfo, 8001 SharedInfoLen, SHA512_HashBuf, SHA512_LENGTH); 8002 else 8003 return CKR_MECHANISM_INVALID; 8004 } 8005 8006 /* 8007 * Handle the derive from a block encryption cipher 8008 */ 8009 CK_RV 8010 sftk_DeriveEncrypt(SFTKCipher encrypt, void *cipherInfo, 8011 int blockSize, SFTKObject *key, CK_ULONG keySize, 8012 unsigned char *data, CK_ULONG len) 8013 { 8014 /* large enough for a 512-bit key */ 8015 unsigned char tmpdata[SFTK_MAX_DERIVE_KEY_SIZE]; 8016 SECStatus rv; 8017 unsigned int outLen; 8018 CK_RV crv; 8019 8020 if ((len % blockSize) != 0) { 8021 return CKR_MECHANISM_PARAM_INVALID; 8022 } 8023 if (len > SFTK_MAX_DERIVE_KEY_SIZE) { 8024 return CKR_MECHANISM_PARAM_INVALID; 8025 } 8026 if (keySize && (len < keySize)) { 8027 return CKR_MECHANISM_PARAM_INVALID; 8028 } 8029 if (keySize == 0) { 8030 keySize = len; 8031 } 8032 8033 rv = (*encrypt)(cipherInfo, (unsigned char *)&tmpdata, &outLen, len, data, len); 8034 if (rv != SECSuccess) { 8035 crv = sftk_MapCryptError(PORT_GetError()); 8036 return crv; 8037 } 8038 8039 crv = sftk_forceAttribute(key, CKA_VALUE, tmpdata, keySize); 8040 PORT_Memset(tmpdata, 0, sizeof tmpdata); 8041 return crv; 8042 } 8043 8044 CK_RV 8045 sftk_HKDF(CK_HKDF_PARAMS_PTR params, CK_SESSION_HANDLE hSession, 8046 SFTKObject *sourceKey, const unsigned char *sourceKeyBytes, 8047 int sourceKeyLen, SFTKObject *key, unsigned char *outKeyBytes, 8048 int keySize, PRBool canBeData, PRBool isFIPS) 8049 { 8050 SFTKSession *session; 8051 SFTKAttribute *saltKey_att = NULL; 8052 const SECHashObject *rawHash; 8053 unsigned hashLen; 8054 unsigned genLen = 0; 8055 unsigned char hashbuf[HASH_LENGTH_MAX]; 8056 unsigned char keyBlock[9 * SFTK_MAX_MAC_LENGTH]; 8057 unsigned char *keyBlockAlloc = NULL; /* allocated keyBlock */ 8058 unsigned char *keyBlockData = keyBlock; /* pointer to current keyBlock */ 8059 const unsigned char *prk; /* psuedo-random key */ 8060 CK_ULONG prkLen; 8061 const unsigned char *okm; /* output keying material */ 8062 HASH_HashType hashType = sftk_GetHashTypeFromMechanism(params->prfHashMechanism); 8063 SFTKObject *saltKey = NULL; 8064 CK_RV crv = CKR_OK; 8065 8066 /* Spec says it should be the base hash, but also accept the HMAC */ 8067 if (hashType == HASH_AlgNULL) { 8068 hashType = sftk_HMACMechanismToHash(params->prfHashMechanism); 8069 } 8070 rawHash = HASH_GetRawHashObject(hashType); 8071 if (rawHash == NULL || rawHash->length > sizeof(hashbuf)) { 8072 return CKR_MECHANISM_INVALID; 8073 } 8074 hashLen = rawHash->length; 8075 8076 if ((!params->bExpand && !params->bExtract) || 8077 (params->bExtract && params->ulSaltLen > 0 && !params->pSalt) || 8078 (params->bExpand && params->ulInfoLen > 0 && !params->pInfo)) { 8079 return CKR_MECHANISM_PARAM_INVALID; 8080 } 8081 if ((params->bExpand && keySize == 0) || 8082 (!params->bExpand && keySize > hashLen) || 8083 (params->bExpand && keySize > 255 * hashLen)) { 8084 return CKR_TEMPLATE_INCONSISTENT; 8085 } 8086 8087 /* sourceKey is NULL if we are called from the POST, skip the 8088 * sensitiveCheck */ 8089 if (sourceKey != NULL) { 8090 crv = sftk_DeriveSensitiveCheck(sourceKey, key, canBeData); 8091 if (crv != CKR_OK) 8092 return crv; 8093 } 8094 8095 /* HKDF-Extract(salt, base key value) */ 8096 if (params->bExtract) { 8097 CK_BYTE *salt; 8098 CK_ULONG saltLen; 8099 HMACContext *hmac; 8100 unsigned int bufLen; 8101 8102 switch (params->ulSaltType) { 8103 case CKF_HKDF_SALT_NULL: 8104 saltLen = hashLen; 8105 salt = hashbuf; 8106 memset(salt, 0, saltLen); 8107 break; 8108 case CKF_HKDF_SALT_DATA: 8109 salt = params->pSalt; 8110 saltLen = params->ulSaltLen; 8111 if ((salt == NULL) || (params->ulSaltLen == 0)) { 8112 return CKR_MECHANISM_PARAM_INVALID; 8113 } 8114 break; 8115 case CKF_HKDF_SALT_KEY: 8116 /* lookup key */ 8117 session = sftk_SessionFromHandle(hSession); 8118 if (session == NULL) { 8119 return CKR_SESSION_HANDLE_INVALID; 8120 } 8121 8122 saltKey = sftk_ObjectFromHandle(params->hSaltKey, session); 8123 sftk_FreeSession(session); 8124 if (saltKey == NULL) { 8125 return CKR_KEY_HANDLE_INVALID; 8126 } 8127 /* if the base key is not fips, but the salt key is, the 8128 * resulting key can be fips */ 8129 if (isFIPS && !sftk_hasFIPS(key) && sftk_hasFIPS(saltKey)) { 8130 CK_MECHANISM mech; 8131 mech.mechanism = CKM_HKDF_DERIVE; 8132 mech.pParameter = params; 8133 mech.ulParameterLen = sizeof(*params); 8134 sftk_setFIPS(key, sftk_operationIsFIPS(saltKey->slot, 8135 &mech, CKA_DERIVE, 8136 saltKey)); 8137 } 8138 saltKey_att = sftk_FindAttribute(saltKey, CKA_VALUE); 8139 if (saltKey_att == NULL) { 8140 sftk_FreeObject(saltKey); 8141 return CKR_KEY_HANDLE_INVALID; 8142 } 8143 /* save the resulting salt */ 8144 salt = saltKey_att->attrib.pValue; 8145 saltLen = saltKey_att->attrib.ulValueLen; 8146 break; 8147 default: 8148 return CKR_MECHANISM_PARAM_INVALID; 8149 break; 8150 } 8151 8152 hmac = HMAC_Create(rawHash, salt, saltLen, isFIPS); 8153 if (saltKey_att) { 8154 sftk_FreeAttribute(saltKey_att); 8155 } 8156 if (saltKey) { 8157 sftk_FreeObject(saltKey); 8158 } 8159 if (!hmac) { 8160 return CKR_HOST_MEMORY; 8161 } 8162 HMAC_Begin(hmac); 8163 HMAC_Update(hmac, sourceKeyBytes, sourceKeyLen); 8164 HMAC_Finish(hmac, hashbuf, &bufLen, sizeof(hashbuf)); 8165 HMAC_Destroy(hmac, PR_TRUE); 8166 PORT_Assert(bufLen == rawHash->length); 8167 prk = hashbuf; 8168 prkLen = bufLen; 8169 } else { 8170 /* PRK = base key value */ 8171 prk = sourceKeyBytes; 8172 prkLen = sourceKeyLen; 8173 } 8174 8175 /* HKDF-Expand */ 8176 if (!params->bExpand) { 8177 okm = prk; 8178 keySize = genLen = hashLen; 8179 } else { 8180 /* T(1) = HMAC-Hash(prk, "" | info | 0x01) 8181 * T(n) = HMAC-Hash(prk, T(n-1) | info | n 8182 * key material = T(1) | ... | T(n) 8183 */ 8184 HMACContext *hmac; 8185 CK_BYTE bi; 8186 unsigned iterations; 8187 8188 genLen = PR_ROUNDUP(keySize, hashLen); 8189 iterations = genLen / hashLen; 8190 8191 if (genLen > sizeof(keyBlock)) { 8192 keyBlockAlloc = PORT_Alloc(genLen); 8193 if (keyBlockAlloc == NULL) { 8194 return CKR_HOST_MEMORY; 8195 } 8196 keyBlockData = keyBlockAlloc; 8197 } 8198 hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS); 8199 if (hmac == NULL) { 8200 PORT_Free(keyBlockAlloc); 8201 return CKR_HOST_MEMORY; 8202 } 8203 for (bi = 1; bi <= iterations && bi > 0; ++bi) { 8204 unsigned len; 8205 HMAC_Begin(hmac); 8206 if (bi > 1) { 8207 HMAC_Update(hmac, &keyBlockData[(bi - 2) * hashLen], hashLen); 8208 } 8209 if (params->ulInfoLen != 0) { 8210 HMAC_Update(hmac, params->pInfo, params->ulInfoLen); 8211 } 8212 HMAC_Update(hmac, &bi, 1); 8213 HMAC_Finish(hmac, &keyBlockData[(bi - 1) * hashLen], &len, 8214 hashLen); 8215 PORT_Assert(len == hashLen); 8216 } 8217 HMAC_Destroy(hmac, PR_TRUE); 8218 okm = &keyBlockData[0]; 8219 } 8220 /* key material = okm */ 8221 crv = CKR_OK; 8222 if (key) { 8223 crv = sftk_forceAttribute(key, CKA_VALUE, okm, keySize); 8224 } else { 8225 PORT_Assert(outKeyBytes != NULL); 8226 PORT_Memcpy(outKeyBytes, okm, keySize); 8227 } 8228 PORT_Memset(keyBlockData, 0, genLen); 8229 PORT_Memset(hashbuf, 0, sizeof(hashbuf)); 8230 PORT_Free(keyBlockAlloc); 8231 return crv; 8232 } 8233 8234 /* 8235 * SSL Key generation given pre master secret 8236 */ 8237 #define NUM_MIXERS 9 8238 static const char *const mixers[NUM_MIXERS] = { 8239 "A", 8240 "BB", 8241 "CCC", 8242 "DDDD", 8243 "EEEEE", 8244 "FFFFFF", 8245 "GGGGGGG", 8246 "HHHHHHHH", 8247 "IIIIIIIII" 8248 }; 8249 #define SSL3_PMS_LENGTH 48 8250 #define SSL3_MASTER_SECRET_LENGTH 48 8251 #define SSL3_RANDOM_LENGTH 32 8252 8253 /* NSC_DeriveKey derives a key from a base key, creating a new key object. */ 8254 CK_RV 8255 NSC_DeriveKey(CK_SESSION_HANDLE hSession, 8256 CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, 8257 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 8258 CK_OBJECT_HANDLE_PTR phKey) 8259 { 8260 SFTKSession *session; 8261 SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); 8262 SFTKObject *key; 8263 SFTKObject *sourceKey; 8264 SFTKAttribute *att = NULL; 8265 SFTKAttribute *att2 = NULL; 8266 unsigned char *buf; 8267 SHA1Context *sha; 8268 MD5Context *md5; 8269 MD2Context *md2; 8270 CK_ULONG macSize; 8271 CK_ULONG tmpKeySize; 8272 CK_ULONG IVSize; 8273 CK_ULONG keySize = 0; 8274 CK_RV crv = CKR_OK; 8275 CK_BBOOL cktrue = CK_TRUE; 8276 CK_BBOOL ckfalse = CK_FALSE; 8277 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; 8278 CK_OBJECT_CLASS classType = CKO_SECRET_KEY; 8279 CK_KEY_DERIVATION_STRING_DATA *stringPtr; 8280 PRBool isTLS = PR_FALSE; 8281 PRBool isDH = PR_FALSE; 8282 HASH_HashType tlsPrfHash = HASH_AlgNULL; 8283 SECStatus rv; 8284 int i; 8285 unsigned int outLen; 8286 unsigned char sha_out[SHA1_LENGTH]; 8287 unsigned char key_block[NUM_MIXERS * SFTK_MAX_MAC_LENGTH]; 8288 PRBool isFIPS; 8289 HASH_HashType hashType; 8290 CK_MECHANISM_TYPE hashMech; 8291 PRBool extractValue = PR_TRUE; 8292 CK_IKE1_EXTENDED_DERIVE_PARAMS ikeAppB; 8293 CK_IKE1_EXTENDED_DERIVE_PARAMS *pIkeAppB; 8294 8295 CHECK_FORK(); 8296 8297 if (!slot) { 8298 return CKR_SESSION_HANDLE_INVALID; 8299 } 8300 if (!pMechanism) { 8301 return CKR_MECHANISM_PARAM_INVALID; 8302 } 8303 CK_MECHANISM_TYPE mechanism = pMechanism->mechanism; 8304 8305 /* 8306 * now lets create an object to hang the attributes off of 8307 */ 8308 if (phKey) { 8309 *phKey = CK_INVALID_HANDLE; 8310 } 8311 8312 key = sftk_NewObject(slot); /* fill in the handle later */ 8313 if (key == NULL) { 8314 return CKR_HOST_MEMORY; 8315 } 8316 isFIPS = sftk_isFIPS(slot->slotID); 8317 8318 /* 8319 * load the template values into the object 8320 */ 8321 for (i = 0; i < (int)ulAttributeCount; i++) { 8322 crv = sftk_AddAttributeType(key, sftk_attr_expand(&pTemplate[i])); 8323 if (crv != CKR_OK) 8324 break; 8325 8326 if (pTemplate[i].type == CKA_KEY_TYPE) { 8327 keyType = *(CK_KEY_TYPE *)pTemplate[i].pValue; 8328 } 8329 if (pTemplate[i].type == CKA_VALUE_LEN) { 8330 keySize = *(CK_ULONG *)pTemplate[i].pValue; 8331 } 8332 } 8333 if (crv != CKR_OK) { 8334 sftk_FreeObject(key); 8335 return crv; 8336 } 8337 8338 if (keySize == 0) { 8339 keySize = sftk_MapKeySize(keyType); 8340 } 8341 8342 switch (mechanism) { 8343 case CKM_NSS_JPAKE_ROUND2_SHA1: /* fall through */ 8344 case CKM_NSS_JPAKE_ROUND2_SHA256: /* fall through */ 8345 case CKM_NSS_JPAKE_ROUND2_SHA384: /* fall through */ 8346 case CKM_NSS_JPAKE_ROUND2_SHA512: 8347 extractValue = PR_FALSE; 8348 classType = CKO_PRIVATE_KEY; 8349 break; 8350 case CKM_NSS_PUB_FROM_PRIV: 8351 extractValue = PR_FALSE; 8352 classType = CKO_PUBLIC_KEY; 8353 break; 8354 case CKM_HKDF_DATA: /* fall through */ 8355 case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA: /* fall through */ 8356 case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA: /* fall through */ 8357 case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA: 8358 classType = CKO_DATA; 8359 break; 8360 case CKM_NSS_JPAKE_FINAL_SHA1: /* fall through */ 8361 case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */ 8362 case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */ 8363 case CKM_NSS_JPAKE_FINAL_SHA512: 8364 extractValue = PR_FALSE; 8365 /* fall through */ 8366 default: 8367 classType = CKO_SECRET_KEY; 8368 } 8369 8370 crv = sftk_forceAttribute(key, CKA_CLASS, &classType, sizeof(classType)); 8371 if (crv != CKR_OK) { 8372 sftk_FreeObject(key); 8373 return crv; 8374 } 8375 8376 /* look up the base key we're deriving with */ 8377 session = sftk_SessionFromHandle(hSession); 8378 if (session == NULL) { 8379 sftk_FreeObject(key); 8380 return CKR_SESSION_HANDLE_INVALID; 8381 } 8382 8383 sourceKey = sftk_ObjectFromHandle(hBaseKey, session); 8384 sftk_FreeSession(session); 8385 /* is this eventually succeeds, lastOpWasFIPS will be set the resulting key's 8386 * FIPS state below. */ 8387 session->lastOpWasFIPS = PR_FALSE; 8388 if (sourceKey == NULL) { 8389 sftk_FreeObject(key); 8390 return CKR_KEY_HANDLE_INVALID; 8391 } 8392 8393 if (extractValue) { 8394 /* get the value of the base key */ 8395 att = sftk_FindAttribute(sourceKey, CKA_VALUE); 8396 if (att == NULL) { 8397 sftk_FreeObject(key); 8398 sftk_FreeObject(sourceKey); 8399 return CKR_KEY_HANDLE_INVALID; 8400 } 8401 } 8402 sftk_setFIPS(key, sftk_operationIsFIPS(slot, pMechanism, 8403 CKA_DERIVE, sourceKey)); 8404 8405 switch (mechanism) { 8406 /* get a public key from a private key. nsslowkey_ConvertToPublickey() 8407 * will generate the public portion if it doesn't already exist. */ 8408 case CKM_NSS_PUB_FROM_PRIV: { 8409 NSSLOWKEYPrivateKey *privKey; 8410 NSSLOWKEYPublicKey *pubKey; 8411 int error; 8412 8413 crv = sftk_GetULongAttribute(sourceKey, CKA_KEY_TYPE, &keyType); 8414 if (crv != CKR_OK) { 8415 break; 8416 } 8417 8418 /* privKey is stored in sourceKey and will be destroyed when 8419 * the sourceKey is freed. */ 8420 privKey = sftk_GetPrivKey(sourceKey, keyType, &crv); 8421 if (privKey == NULL) { 8422 break; 8423 } 8424 pubKey = nsslowkey_ConvertToPublicKey(privKey); 8425 if (pubKey == NULL) { 8426 error = PORT_GetError(); 8427 crv = sftk_MapCryptError(error); 8428 break; 8429 } 8430 crv = sftk_PutPubKey(key, sourceKey, keyType, pubKey); 8431 nsslowkey_DestroyPublicKey(pubKey); 8432 break; 8433 } 8434 case CKM_NSS_IKE_PRF_DERIVE: 8435 case CKM_IKE_PRF_DERIVE: 8436 if (pMechanism->ulParameterLen != 8437 sizeof(CK_IKE_PRF_DERIVE_PARAMS)) { 8438 crv = CKR_MECHANISM_PARAM_INVALID; 8439 break; 8440 } 8441 crv = sftk_ike_prf(hSession, att, 8442 (CK_IKE_PRF_DERIVE_PARAMS *)pMechanism->pParameter, key); 8443 break; 8444 case CKM_NSS_IKE1_PRF_DERIVE: 8445 case CKM_IKE1_PRF_DERIVE: 8446 if (pMechanism->ulParameterLen != 8447 sizeof(CK_IKE1_PRF_DERIVE_PARAMS)) { 8448 crv = CKR_MECHANISM_PARAM_INVALID; 8449 break; 8450 } 8451 crv = sftk_ike1_prf(hSession, att, 8452 (CK_IKE1_PRF_DERIVE_PARAMS *)pMechanism->pParameter, 8453 key, keySize); 8454 break; 8455 case CKM_NSS_IKE1_APP_B_PRF_DERIVE: 8456 case CKM_IKE1_EXTENDED_DERIVE: 8457 pIkeAppB = (CK_IKE1_EXTENDED_DERIVE_PARAMS *)pMechanism->pParameter; 8458 if (pMechanism->ulParameterLen == 8459 sizeof(CK_MECHANISM_TYPE)) { 8460 ikeAppB.prfMechanism = *(CK_MECHANISM_TYPE *)pMechanism->pParameter; 8461 ikeAppB.bHasKeygxy = PR_FALSE; 8462 ikeAppB.hKeygxy = CK_INVALID_HANDLE; 8463 ikeAppB.pExtraData = NULL; 8464 ikeAppB.ulExtraDataLen = 0; 8465 pIkeAppB = &ikeAppB; 8466 } else if (pMechanism->ulParameterLen != 8467 sizeof(CK_IKE1_EXTENDED_DERIVE_PARAMS)) { 8468 crv = CKR_MECHANISM_PARAM_INVALID; 8469 break; 8470 } 8471 crv = sftk_ike1_appendix_b_prf(hSession, att, pIkeAppB, key, 8472 keySize); 8473 break; 8474 case CKM_NSS_IKE_PRF_PLUS_DERIVE: 8475 case CKM_IKE2_PRF_PLUS_DERIVE: 8476 if (pMechanism->ulParameterLen != 8477 sizeof(CK_IKE2_PRF_PLUS_DERIVE_PARAMS)) { 8478 crv = CKR_MECHANISM_PARAM_INVALID; 8479 break; 8480 } 8481 crv = sftk_ike_prf_plus(hSession, att, 8482 (CK_IKE2_PRF_PLUS_DERIVE_PARAMS *)pMechanism->pParameter, 8483 key, keySize); 8484 break; 8485 /* 8486 * generate the master secret 8487 */ 8488 case CKM_TLS12_MASTER_KEY_DERIVE: 8489 case CKM_TLS12_MASTER_KEY_DERIVE_DH: 8490 case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256: 8491 case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256: 8492 case CKM_TLS_MASTER_KEY_DERIVE: 8493 case CKM_TLS_MASTER_KEY_DERIVE_DH: 8494 case CKM_SSL3_MASTER_KEY_DERIVE: 8495 case CKM_SSL3_MASTER_KEY_DERIVE_DH: { 8496 CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master; 8497 SSL3RSAPreMasterSecret *rsa_pms; 8498 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; 8499 8500 if ((mechanism == CKM_TLS12_MASTER_KEY_DERIVE) || 8501 (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) { 8502 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_MASTER_KEY_DERIVE_PARAMS))) { 8503 crv = CKR_MECHANISM_PARAM_INVALID; 8504 break; 8505 } 8506 CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tls12_master = 8507 (CK_TLS12_MASTER_KEY_DERIVE_PARAMS *)pMechanism->pParameter; 8508 tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_master->prfHashMechanism); 8509 if (tlsPrfHash == HASH_AlgNULL) { 8510 crv = CKR_MECHANISM_PARAM_INVALID; 8511 break; 8512 } 8513 } else if ((mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256) || 8514 (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256)) { 8515 tlsPrfHash = HASH_AlgSHA256; 8516 } 8517 8518 if ((mechanism != CKM_SSL3_MASTER_KEY_DERIVE) && 8519 (mechanism != CKM_SSL3_MASTER_KEY_DERIVE_DH)) { 8520 isTLS = PR_TRUE; 8521 } 8522 if ((mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) || 8523 (mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH) || 8524 (mechanism == CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256) || 8525 (mechanism == CKM_TLS12_MASTER_KEY_DERIVE_DH)) { 8526 isDH = PR_TRUE; 8527 } 8528 8529 /* first do the consistency checks */ 8530 if (!isDH && (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) { 8531 crv = CKR_KEY_TYPE_INCONSISTENT; 8532 break; 8533 } 8534 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE); 8535 if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue != 8536 CKK_GENERIC_SECRET)) { 8537 if (att2) 8538 sftk_FreeAttribute(att2); 8539 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8540 break; 8541 } 8542 sftk_FreeAttribute(att2); 8543 if (keyType != CKK_GENERIC_SECRET) { 8544 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8545 break; 8546 } 8547 if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) { 8548 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8549 break; 8550 } 8551 8552 /* finally do the key gen */ 8553 ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) 8554 pMechanism->pParameter; 8555 8556 if (ssl3_master->pVersion) { 8557 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); 8558 rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue; 8559 /* don't leak more key material then necessary for SSL to work */ 8560 if ((sessKey == NULL) || sessKey->wasDerived) { 8561 ssl3_master->pVersion->major = 0xff; 8562 ssl3_master->pVersion->minor = 0xff; 8563 } else { 8564 ssl3_master->pVersion->major = rsa_pms->client_version[0]; 8565 ssl3_master->pVersion->minor = rsa_pms->client_version[1]; 8566 } 8567 } 8568 if (ssl3_master->RandomInfo.ulClientRandomLen != SSL3_RANDOM_LENGTH) { 8569 crv = CKR_MECHANISM_PARAM_INVALID; 8570 break; 8571 } 8572 if (ssl3_master->RandomInfo.ulServerRandomLen != SSL3_RANDOM_LENGTH) { 8573 crv = CKR_MECHANISM_PARAM_INVALID; 8574 break; 8575 } 8576 PORT_Memcpy(crsrdata, 8577 ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); 8578 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, 8579 ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); 8580 8581 if (isTLS) { 8582 SECStatus status; 8583 SECItem crsr = { siBuffer, NULL, 0 }; 8584 SECItem master = { siBuffer, NULL, 0 }; 8585 SECItem pms = { siBuffer, NULL, 0 }; 8586 8587 crsr.data = crsrdata; 8588 crsr.len = sizeof crsrdata; 8589 master.data = key_block; 8590 master.len = SSL3_MASTER_SECRET_LENGTH; 8591 pms.data = (unsigned char *)att->attrib.pValue; 8592 pms.len = att->attrib.ulValueLen; 8593 8594 if (tlsPrfHash != HASH_AlgNULL) { 8595 status = TLS_P_hash(tlsPrfHash, &pms, "master secret", 8596 &crsr, &master, isFIPS); 8597 } else { 8598 status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); 8599 } 8600 if (status != SECSuccess) { 8601 PORT_Memset(crsrdata, 0, sizeof crsrdata); 8602 crv = CKR_FUNCTION_FAILED; 8603 break; 8604 } 8605 } else { 8606 /* now allocate the hash contexts */ 8607 md5 = MD5_NewContext(); 8608 if (md5 == NULL) { 8609 PORT_Memset(crsrdata, 0, sizeof crsrdata); 8610 crv = CKR_HOST_MEMORY; 8611 break; 8612 } 8613 sha = SHA1_NewContext(); 8614 if (sha == NULL) { 8615 PORT_Memset(crsrdata, 0, sizeof crsrdata); 8616 PORT_Free(md5); 8617 crv = CKR_HOST_MEMORY; 8618 break; 8619 } 8620 for (i = 0; i < 3; i++) { 8621 SHA1_Begin(sha); 8622 SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i])); 8623 SHA1_Update(sha, (const unsigned char *)att->attrib.pValue, 8624 att->attrib.ulValueLen); 8625 SHA1_Update(sha, crsrdata, sizeof crsrdata); 8626 SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); 8627 PORT_Assert(outLen == SHA1_LENGTH); 8628 8629 MD5_Begin(md5); 8630 MD5_Update(md5, (const unsigned char *)att->attrib.pValue, 8631 att->attrib.ulValueLen); 8632 MD5_Update(md5, sha_out, outLen); 8633 MD5_End(md5, &key_block[i * MD5_LENGTH], &outLen, MD5_LENGTH); 8634 PORT_Assert(outLen == MD5_LENGTH); 8635 } 8636 PORT_Free(md5); 8637 PORT_Free(sha); 8638 PORT_Memset(crsrdata, 0, sizeof crsrdata); 8639 PORT_Memset(sha_out, 0, sizeof sha_out); 8640 } 8641 8642 /* store the results */ 8643 crv = sftk_forceAttribute(key, CKA_VALUE, key_block, SSL3_MASTER_SECRET_LENGTH); 8644 PORT_Memset(key_block, 0, sizeof key_block); 8645 if (crv != CKR_OK) 8646 break; 8647 keyType = CKK_GENERIC_SECRET; 8648 crv = sftk_forceAttribute(key, CKA_KEY_TYPE, &keyType, sizeof(keyType)); 8649 if (isTLS) { 8650 /* TLS's master secret is used to "sign" finished msgs with PRF. */ 8651 /* XXX This seems like a hack. But SFTK_Derive only accepts 8652 * one "operation" argument. */ 8653 crv = sftk_forceAttribute(key, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); 8654 if (crv != CKR_OK) 8655 break; 8656 crv = sftk_forceAttribute(key, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); 8657 if (crv != CKR_OK) 8658 break; 8659 /* While we're here, we might as well force this, too. */ 8660 crv = sftk_forceAttribute(key, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); 8661 if (crv != CKR_OK) 8662 break; 8663 } 8664 break; 8665 } 8666 8667 /* Extended master key derivation [draft-ietf-tls-session-hash] */ 8668 case CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE: 8669 case CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE_DH: 8670 case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE: 8671 case CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH: { 8672 CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS *ems_params; 8673 SSL3RSAPreMasterSecret *rsa_pms; 8674 SECStatus status; 8675 SECItem pms = { siBuffer, NULL, 0 }; 8676 SECItem seed = { siBuffer, NULL, 0 }; 8677 SECItem master = { siBuffer, NULL, 0 }; 8678 8679 ems_params = (CK_TLS12_EXTENDED_MASTER_KEY_DERIVE_PARAMS *) 8680 pMechanism->pParameter; 8681 8682 /* First do the consistency checks */ 8683 if (((mechanism == CKM_TLS12_EXTENDED_MASTER_KEY_DERIVE) || 8684 (mechanism == CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE)) && 8685 (att->attrib.ulValueLen != SSL3_PMS_LENGTH)) { 8686 crv = CKR_KEY_TYPE_INCONSISTENT; 8687 break; 8688 } 8689 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE); 8690 if ((att2 == NULL) || 8691 (*(CK_KEY_TYPE *)att2->attrib.pValue != CKK_GENERIC_SECRET)) { 8692 if (att2) 8693 sftk_FreeAttribute(att2); 8694 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8695 break; 8696 } 8697 sftk_FreeAttribute(att2); 8698 if (keyType != CKK_GENERIC_SECRET) { 8699 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8700 break; 8701 } 8702 if ((keySize != 0) && (keySize != SSL3_MASTER_SECRET_LENGTH)) { 8703 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8704 break; 8705 } 8706 8707 /* Do the key derivation */ 8708 pms.data = (unsigned char *)att->attrib.pValue; 8709 pms.len = att->attrib.ulValueLen; 8710 seed.data = ems_params->pSessionHash; 8711 seed.len = ems_params->ulSessionHashLen; 8712 master.data = key_block; 8713 master.len = SSL3_MASTER_SECRET_LENGTH; 8714 if (ems_params->prfHashMechanism == CKM_TLS_PRF) { 8715 /* 8716 * In this case, the session hash is the concatenation of SHA-1 8717 * and MD5, so it should be 36 bytes long. 8718 */ 8719 if (seed.len != MD5_LENGTH + SHA1_LENGTH) { 8720 crv = CKR_TEMPLATE_INCONSISTENT; 8721 break; 8722 } 8723 8724 status = TLS_PRF(&pms, "extended master secret", 8725 &seed, &master, isFIPS); 8726 } else { 8727 const SECHashObject *hashObj; 8728 8729 tlsPrfHash = sftk_GetHashTypeFromMechanism(ems_params->prfHashMechanism); 8730 if (tlsPrfHash == HASH_AlgNULL) { 8731 crv = CKR_MECHANISM_PARAM_INVALID; 8732 break; 8733 } 8734 8735 hashObj = HASH_GetRawHashObject(tlsPrfHash); 8736 if (seed.len != hashObj->length) { 8737 crv = CKR_TEMPLATE_INCONSISTENT; 8738 break; 8739 } 8740 8741 status = TLS_P_hash(tlsPrfHash, &pms, "extended master secret", 8742 &seed, &master, isFIPS); 8743 } 8744 if (status != SECSuccess) { 8745 crv = CKR_FUNCTION_FAILED; 8746 break; 8747 } 8748 8749 /* Reflect the version if required */ 8750 if (ems_params->pVersion) { 8751 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); 8752 rsa_pms = (SSL3RSAPreMasterSecret *)att->attrib.pValue; 8753 /* don't leak more key material than necessary for SSL to work */ 8754 if ((sessKey == NULL) || sessKey->wasDerived) { 8755 ems_params->pVersion->major = 0xff; 8756 ems_params->pVersion->minor = 0xff; 8757 } else { 8758 ems_params->pVersion->major = rsa_pms->client_version[0]; 8759 ems_params->pVersion->minor = rsa_pms->client_version[1]; 8760 } 8761 } 8762 8763 /* Store the results */ 8764 crv = sftk_forceAttribute(key, CKA_VALUE, key_block, 8765 SSL3_MASTER_SECRET_LENGTH); 8766 PORT_Memset(key_block, 0, sizeof key_block); 8767 break; 8768 } 8769 8770 case CKM_TLS12_KEY_AND_MAC_DERIVE: 8771 case CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256: 8772 case CKM_TLS_KEY_AND_MAC_DERIVE: 8773 case CKM_SSL3_KEY_AND_MAC_DERIVE: { 8774 CK_SSL3_KEY_MAT_PARAMS *ssl3_keys; 8775 CK_SSL3_KEY_MAT_OUT *ssl3_keys_out; 8776 CK_ULONG effKeySize; 8777 unsigned int block_needed; 8778 unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; 8779 8780 if (mechanism == CKM_TLS12_KEY_AND_MAC_DERIVE) { 8781 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_TLS12_KEY_MAT_PARAMS))) { 8782 crv = CKR_MECHANISM_PARAM_INVALID; 8783 break; 8784 } 8785 CK_TLS12_KEY_MAT_PARAMS *tls12_keys = 8786 (CK_TLS12_KEY_MAT_PARAMS *)pMechanism->pParameter; 8787 tlsPrfHash = sftk_GetHashTypeFromMechanism(tls12_keys->prfHashMechanism); 8788 if (tlsPrfHash == HASH_AlgNULL) { 8789 crv = CKR_MECHANISM_PARAM_INVALID; 8790 break; 8791 } 8792 } else if (mechanism == CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256) { 8793 tlsPrfHash = HASH_AlgSHA256; 8794 } 8795 8796 if (mechanism != CKM_SSL3_KEY_AND_MAC_DERIVE) { 8797 isTLS = PR_TRUE; 8798 } 8799 8800 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 8801 if (crv != CKR_OK) 8802 break; 8803 8804 if (att->attrib.ulValueLen != SSL3_MASTER_SECRET_LENGTH) { 8805 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8806 break; 8807 } 8808 att2 = sftk_FindAttribute(sourceKey, CKA_KEY_TYPE); 8809 if ((att2 == NULL) || (*(CK_KEY_TYPE *)att2->attrib.pValue != 8810 CKK_GENERIC_SECRET)) { 8811 if (att2) 8812 sftk_FreeAttribute(att2); 8813 crv = CKR_KEY_FUNCTION_NOT_PERMITTED; 8814 break; 8815 } 8816 sftk_FreeAttribute(att2); 8817 md5 = MD5_NewContext(); 8818 if (md5 == NULL) { 8819 crv = CKR_HOST_MEMORY; 8820 break; 8821 } 8822 sha = SHA1_NewContext(); 8823 if (sha == NULL) { 8824 MD5_DestroyContext(md5, PR_TRUE); 8825 crv = CKR_HOST_MEMORY; 8826 break; 8827 } 8828 8829 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_SSL3_KEY_MAT_PARAMS))) { 8830 MD5_DestroyContext(md5, PR_TRUE); 8831 SHA1_DestroyContext(sha, PR_TRUE); 8832 crv = CKR_MECHANISM_PARAM_INVALID; 8833 break; 8834 } 8835 ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; 8836 8837 PORT_Memcpy(srcrdata, 8838 ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); 8839 PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, 8840 ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); 8841 8842 /* 8843 * clear out our returned keys so we can recover on failure 8844 */ 8845 ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial; 8846 ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE; 8847 ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE; 8848 ssl3_keys_out->hClientKey = CK_INVALID_HANDLE; 8849 ssl3_keys_out->hServerKey = CK_INVALID_HANDLE; 8850 8851 /* 8852 * How much key material do we need? 8853 */ 8854 macSize = ssl3_keys->ulMacSizeInBits / 8; 8855 effKeySize = ssl3_keys->ulKeySizeInBits / 8; 8856 IVSize = ssl3_keys->ulIVSizeInBits / 8; 8857 if (keySize == 0) { 8858 effKeySize = keySize; 8859 } 8860 8861 /* bIsExport must be false. */ 8862 if (ssl3_keys->bIsExport) { 8863 MD5_DestroyContext(md5, PR_TRUE); 8864 SHA1_DestroyContext(sha, PR_TRUE); 8865 PORT_Memset(srcrdata, 0, sizeof srcrdata); 8866 crv = CKR_MECHANISM_PARAM_INVALID; 8867 break; 8868 } 8869 8870 block_needed = 2 * (macSize + effKeySize + IVSize); 8871 PORT_Assert(block_needed <= sizeof key_block); 8872 if (block_needed > sizeof key_block) 8873 block_needed = sizeof key_block; 8874 8875 /* 8876 * generate the key material: This looks amazingly similar to the 8877 * PMS code, and is clearly crying out for a function to provide it. 8878 */ 8879 if (isTLS) { 8880 SECStatus status; 8881 SECItem srcr = { siBuffer, NULL, 0 }; 8882 SECItem keyblk = { siBuffer, NULL, 0 }; 8883 SECItem master = { siBuffer, NULL, 0 }; 8884 8885 srcr.data = srcrdata; 8886 srcr.len = sizeof srcrdata; 8887 keyblk.data = key_block; 8888 keyblk.len = block_needed; 8889 master.data = (unsigned char *)att->attrib.pValue; 8890 master.len = att->attrib.ulValueLen; 8891 8892 if (tlsPrfHash != HASH_AlgNULL) { 8893 status = TLS_P_hash(tlsPrfHash, &master, "key expansion", 8894 &srcr, &keyblk, isFIPS); 8895 } else { 8896 status = TLS_PRF(&master, "key expansion", &srcr, &keyblk, 8897 isFIPS); 8898 } 8899 if (status != SECSuccess) { 8900 goto key_and_mac_derive_fail; 8901 } 8902 } else { 8903 unsigned int block_bytes = 0; 8904 /* key_block = 8905 * MD5(master_secret + SHA('A' + master_secret + 8906 * ServerHello.random + ClientHello.random)) + 8907 * MD5(master_secret + SHA('BB' + master_secret + 8908 * ServerHello.random + ClientHello.random)) + 8909 * MD5(master_secret + SHA('CCC' + master_secret + 8910 * ServerHello.random + ClientHello.random)) + 8911 * [...]; 8912 */ 8913 for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) { 8914 SHA1_Begin(sha); 8915 SHA1_Update(sha, (unsigned char *)mixers[i], strlen(mixers[i])); 8916 SHA1_Update(sha, (const unsigned char *)att->attrib.pValue, 8917 att->attrib.ulValueLen); 8918 SHA1_Update(sha, srcrdata, sizeof srcrdata); 8919 SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); 8920 PORT_Assert(outLen == SHA1_LENGTH); 8921 MD5_Begin(md5); 8922 MD5_Update(md5, (const unsigned char *)att->attrib.pValue, 8923 att->attrib.ulValueLen); 8924 MD5_Update(md5, sha_out, outLen); 8925 MD5_End(md5, &key_block[i * MD5_LENGTH], &outLen, MD5_LENGTH); 8926 PORT_Assert(outLen == MD5_LENGTH); 8927 block_bytes += outLen; 8928 } 8929 PORT_Memset(sha_out, 0, sizeof sha_out); 8930 } 8931 8932 /* 8933 * Put the key material where it goes. 8934 */ 8935 i = 0; /* now shows how much consumed */ 8936 8937 /* 8938 * The key_block is partitioned as follows: 8939 * client_write_MAC_secret[CipherSpec.hash_size] 8940 */ 8941 crv = sftk_buildSSLKey(hSession, key, PR_TRUE, &key_block[i], macSize, 8942 &ssl3_keys_out->hClientMacSecret); 8943 if (crv != CKR_OK) 8944 goto key_and_mac_derive_fail; 8945 8946 i += macSize; 8947 8948 /* 8949 * server_write_MAC_secret[CipherSpec.hash_size] 8950 */ 8951 crv = sftk_buildSSLKey(hSession, key, PR_TRUE, &key_block[i], macSize, 8952 &ssl3_keys_out->hServerMacSecret); 8953 if (crv != CKR_OK) { 8954 goto key_and_mac_derive_fail; 8955 } 8956 i += macSize; 8957 8958 if (keySize) { 8959 /* 8960 ** Generate Domestic write keys and IVs. 8961 ** client_write_key[CipherSpec.key_material] 8962 */ 8963 crv = sftk_buildSSLKey(hSession, key, PR_FALSE, &key_block[i], 8964 keySize, &ssl3_keys_out->hClientKey); 8965 if (crv != CKR_OK) { 8966 goto key_and_mac_derive_fail; 8967 } 8968 i += keySize; 8969 8970 /* 8971 ** server_write_key[CipherSpec.key_material] 8972 */ 8973 crv = sftk_buildSSLKey(hSession, key, PR_FALSE, &key_block[i], 8974 keySize, &ssl3_keys_out->hServerKey); 8975 if (crv != CKR_OK) { 8976 goto key_and_mac_derive_fail; 8977 } 8978 i += keySize; 8979 8980 /* 8981 ** client_write_IV[CipherSpec.IV_size] 8982 */ 8983 if (IVSize > 0) { 8984 PORT_Memcpy(ssl3_keys_out->pIVClient, 8985 &key_block[i], IVSize); 8986 i += IVSize; 8987 } 8988 8989 /* 8990 ** server_write_IV[CipherSpec.IV_size] 8991 */ 8992 if (IVSize > 0) { 8993 PORT_Memcpy(ssl3_keys_out->pIVServer, 8994 &key_block[i], IVSize); 8995 i += IVSize; 8996 } 8997 PORT_Assert(i <= sizeof key_block); 8998 } 8999 9000 crv = CKR_OK; 9001 9002 if (0) { 9003 key_and_mac_derive_fail: 9004 if (crv == CKR_OK) 9005 crv = CKR_FUNCTION_FAILED; 9006 sftk_freeSSLKeys(hSession, ssl3_keys_out); 9007 } 9008 PORT_Memset(srcrdata, 0, sizeof srcrdata); 9009 PORT_Memset(key_block, 0, sizeof key_block); 9010 MD5_DestroyContext(md5, PR_TRUE); 9011 SHA1_DestroyContext(sha, PR_TRUE); 9012 sftk_FreeObject(key); 9013 key = NULL; 9014 break; 9015 } 9016 9017 case CKM_DES3_ECB_ENCRYPT_DATA: 9018 case CKM_DES3_CBC_ENCRYPT_DATA: { 9019 void *cipherInfo; 9020 unsigned char des3key[MAX_DES3_KEY_SIZE]; 9021 CK_DES_CBC_ENCRYPT_DATA_PARAMS *desEncryptPtr; 9022 int mode; 9023 unsigned char *iv; 9024 unsigned char *data; 9025 CK_ULONG len; 9026 9027 if (mechanism == CKM_DES3_ECB_ENCRYPT_DATA) { 9028 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) { 9029 crv = CKR_MECHANISM_PARAM_INVALID; 9030 break; 9031 } 9032 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) 9033 pMechanism->pParameter; 9034 mode = NSS_DES_EDE3; 9035 iv = NULL; 9036 data = stringPtr->pData; 9037 len = stringPtr->ulLen; 9038 } else { 9039 mode = NSS_DES_EDE3_CBC; 9040 desEncryptPtr = 9041 (CK_DES_CBC_ENCRYPT_DATA_PARAMS *) 9042 pMechanism->pParameter; 9043 iv = desEncryptPtr->iv; 9044 data = desEncryptPtr->pData; 9045 len = desEncryptPtr->length; 9046 } 9047 if (att->attrib.ulValueLen == 16) { 9048 PORT_Memcpy(des3key, att->attrib.pValue, 16); 9049 PORT_Memcpy(des3key + 16, des3key, 8); 9050 } else if (att->attrib.ulValueLen == 24) { 9051 PORT_Memcpy(des3key, att->attrib.pValue, 24); 9052 } else { 9053 crv = CKR_KEY_SIZE_RANGE; 9054 break; 9055 } 9056 cipherInfo = DES_CreateContext(des3key, iv, mode, PR_TRUE); 9057 PORT_Memset(des3key, 0, 24); 9058 if (cipherInfo == NULL) { 9059 crv = CKR_HOST_MEMORY; 9060 break; 9061 } 9062 crv = sftk_DeriveEncrypt(SFTKCipher_DES_Encrypt, 9063 cipherInfo, 8, key, keySize, 9064 data, len); 9065 DES_DestroyContext(cipherInfo, PR_TRUE); 9066 break; 9067 } 9068 9069 case CKM_AES_ECB_ENCRYPT_DATA: 9070 case CKM_AES_CBC_ENCRYPT_DATA: { 9071 void *cipherInfo; 9072 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; 9073 int mode; 9074 unsigned char *iv; 9075 unsigned char *data; 9076 CK_ULONG len; 9077 9078 if (mechanism == CKM_AES_ECB_ENCRYPT_DATA) { 9079 mode = NSS_AES; 9080 iv = NULL; 9081 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) { 9082 crv = CKR_MECHANISM_PARAM_INVALID; 9083 break; 9084 } 9085 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; 9086 data = stringPtr->pData; 9087 len = stringPtr->ulLen; 9088 } else { 9089 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) { 9090 crv = CKR_MECHANISM_PARAM_INVALID; 9091 break; 9092 } 9093 aesEncryptPtr = 9094 (CK_AES_CBC_ENCRYPT_DATA_PARAMS *)pMechanism->pParameter; 9095 mode = NSS_AES_CBC; 9096 iv = aesEncryptPtr->iv; 9097 data = aesEncryptPtr->pData; 9098 len = aesEncryptPtr->length; 9099 } 9100 9101 cipherInfo = AES_CreateContext((unsigned char *)att->attrib.pValue, 9102 iv, mode, PR_TRUE, 9103 att->attrib.ulValueLen, 16); 9104 if (cipherInfo == NULL) { 9105 crv = CKR_HOST_MEMORY; 9106 break; 9107 } 9108 crv = sftk_DeriveEncrypt(SFTKCipher_AES_Encrypt, 9109 cipherInfo, 16, key, keySize, 9110 data, len); 9111 AES_DestroyContext(cipherInfo, PR_TRUE); 9112 break; 9113 } 9114 9115 case CKM_CAMELLIA_ECB_ENCRYPT_DATA: 9116 case CKM_CAMELLIA_CBC_ENCRYPT_DATA: { 9117 void *cipherInfo; 9118 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; 9119 int mode; 9120 unsigned char *iv; 9121 unsigned char *data; 9122 CK_ULONG len; 9123 9124 if (mechanism == CKM_CAMELLIA_ECB_ENCRYPT_DATA) { 9125 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) { 9126 crv = CKR_MECHANISM_PARAM_INVALID; 9127 break; 9128 } 9129 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) 9130 pMechanism->pParameter; 9131 aesEncryptPtr = NULL; 9132 mode = NSS_CAMELLIA; 9133 data = stringPtr->pData; 9134 len = stringPtr->ulLen; 9135 iv = NULL; 9136 } else { 9137 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) { 9138 crv = CKR_MECHANISM_PARAM_INVALID; 9139 break; 9140 } 9141 stringPtr = NULL; 9142 aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) 9143 pMechanism->pParameter; 9144 mode = NSS_CAMELLIA_CBC; 9145 iv = aesEncryptPtr->iv; 9146 data = aesEncryptPtr->pData; 9147 len = aesEncryptPtr->length; 9148 } 9149 9150 cipherInfo = Camellia_CreateContext((unsigned char *)att->attrib.pValue, 9151 iv, mode, PR_TRUE, 9152 att->attrib.ulValueLen); 9153 if (cipherInfo == NULL) { 9154 crv = CKR_HOST_MEMORY; 9155 break; 9156 } 9157 crv = sftk_DeriveEncrypt(SFTKCipher_Camellia_Encrypt, 9158 cipherInfo, 16, key, keySize, 9159 data, len); 9160 Camellia_DestroyContext(cipherInfo, PR_TRUE); 9161 break; 9162 } 9163 9164 #ifndef NSS_DISABLE_DEPRECATED_SEED 9165 case CKM_SEED_ECB_ENCRYPT_DATA: 9166 case CKM_SEED_CBC_ENCRYPT_DATA: { 9167 void *cipherInfo; 9168 CK_AES_CBC_ENCRYPT_DATA_PARAMS *aesEncryptPtr; 9169 int mode; 9170 unsigned char *iv; 9171 unsigned char *data; 9172 CK_ULONG len; 9173 9174 if (mechanism == CKM_SEED_ECB_ENCRYPT_DATA) { 9175 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) { 9176 crv = CKR_MECHANISM_PARAM_INVALID; 9177 break; 9178 } 9179 mode = NSS_SEED; 9180 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) 9181 pMechanism->pParameter; 9182 aesEncryptPtr = NULL; 9183 data = stringPtr->pData; 9184 len = stringPtr->ulLen; 9185 iv = NULL; 9186 } else { 9187 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_AES_CBC_ENCRYPT_DATA_PARAMS))) { 9188 crv = CKR_MECHANISM_PARAM_INVALID; 9189 break; 9190 } 9191 mode = NSS_SEED_CBC; 9192 aesEncryptPtr = (CK_AES_CBC_ENCRYPT_DATA_PARAMS *) 9193 pMechanism->pParameter; 9194 iv = aesEncryptPtr->iv; 9195 data = aesEncryptPtr->pData; 9196 len = aesEncryptPtr->length; 9197 } 9198 9199 cipherInfo = SEED_CreateContext((unsigned char *)att->attrib.pValue, 9200 iv, mode, PR_TRUE); 9201 if (cipherInfo == NULL) { 9202 crv = CKR_HOST_MEMORY; 9203 break; 9204 } 9205 crv = sftk_DeriveEncrypt(SFTKCipher_SEED_Encrypt, 9206 cipherInfo, 16, key, keySize, 9207 data, len); 9208 SEED_DestroyContext(cipherInfo, PR_TRUE); 9209 break; 9210 } 9211 #endif /* NSS_DISABLE_DEPRECATED_SEED */ 9212 9213 case CKM_CONCATENATE_BASE_AND_KEY: { 9214 SFTKObject *paramKey; 9215 9216 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 9217 if (crv != CKR_OK) 9218 break; 9219 9220 session = sftk_SessionFromHandle(hSession); 9221 if (session == NULL) { 9222 crv = CKR_SESSION_HANDLE_INVALID; 9223 break; 9224 } 9225 9226 paramKey = sftk_ObjectFromHandle(*(CK_OBJECT_HANDLE *) 9227 pMechanism->pParameter, 9228 session); 9229 sftk_FreeSession(session); 9230 if (paramKey == NULL) { 9231 crv = CKR_KEY_HANDLE_INVALID; 9232 break; 9233 } 9234 9235 if (sftk_isTrue(paramKey, CKA_SENSITIVE)) { 9236 crv = sftk_forceAttribute(key, CKA_SENSITIVE, &cktrue, 9237 sizeof(CK_BBOOL)); 9238 if (crv != CKR_OK) { 9239 sftk_FreeObject(paramKey); 9240 break; 9241 } 9242 } 9243 9244 if (sftk_hasAttribute(paramKey, CKA_EXTRACTABLE) && !sftk_isTrue(paramKey, CKA_EXTRACTABLE)) { 9245 crv = sftk_forceAttribute(key, CKA_EXTRACTABLE, &ckfalse, sizeof(CK_BBOOL)); 9246 if (crv != CKR_OK) { 9247 sftk_FreeObject(paramKey); 9248 break; 9249 } 9250 } 9251 9252 att2 = sftk_FindAttribute(paramKey, CKA_VALUE); 9253 if (att2 == NULL) { 9254 sftk_FreeObject(paramKey); 9255 crv = CKR_KEY_HANDLE_INVALID; 9256 break; 9257 } 9258 tmpKeySize = att->attrib.ulValueLen + att2->attrib.ulValueLen; 9259 if (keySize == 0) 9260 keySize = tmpKeySize; 9261 if (keySize > tmpKeySize) { 9262 sftk_FreeObject(paramKey); 9263 sftk_FreeAttribute(att2); 9264 crv = CKR_TEMPLATE_INCONSISTENT; 9265 break; 9266 } 9267 buf = (unsigned char *)PORT_Alloc(tmpKeySize); 9268 if (buf == NULL) { 9269 sftk_FreeAttribute(att2); 9270 sftk_FreeObject(paramKey); 9271 crv = CKR_HOST_MEMORY; 9272 break; 9273 } 9274 9275 PORT_Memcpy(buf, att->attrib.pValue, att->attrib.ulValueLen); 9276 PORT_Memcpy(buf + att->attrib.ulValueLen, 9277 att2->attrib.pValue, att2->attrib.ulValueLen); 9278 9279 crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize); 9280 PORT_ZFree(buf, tmpKeySize); 9281 sftk_FreeAttribute(att2); 9282 sftk_FreeObject(paramKey); 9283 break; 9284 } 9285 9286 case CKM_CONCATENATE_BASE_AND_DATA: 9287 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 9288 if (crv != CKR_OK) 9289 break; 9290 9291 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) { 9292 crv = CKR_MECHANISM_PARAM_INVALID; 9293 break; 9294 } 9295 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; 9296 tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen; 9297 if (keySize == 0) 9298 keySize = tmpKeySize; 9299 if (keySize > tmpKeySize) { 9300 crv = CKR_TEMPLATE_INCONSISTENT; 9301 break; 9302 } 9303 buf = (unsigned char *)PORT_Alloc(tmpKeySize); 9304 if (buf == NULL) { 9305 crv = CKR_HOST_MEMORY; 9306 break; 9307 } 9308 9309 PORT_Memcpy(buf, att->attrib.pValue, att->attrib.ulValueLen); 9310 PORT_Memcpy(buf + att->attrib.ulValueLen, stringPtr->pData, 9311 stringPtr->ulLen); 9312 9313 crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize); 9314 PORT_ZFree(buf, tmpKeySize); 9315 break; 9316 case CKM_CONCATENATE_DATA_AND_BASE: 9317 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 9318 if (crv != CKR_OK) 9319 break; 9320 9321 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) { 9322 crv = CKR_MECHANISM_PARAM_INVALID; 9323 break; 9324 } 9325 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; 9326 tmpKeySize = att->attrib.ulValueLen + stringPtr->ulLen; 9327 if (keySize == 0) 9328 keySize = tmpKeySize; 9329 if (keySize > tmpKeySize) { 9330 crv = CKR_TEMPLATE_INCONSISTENT; 9331 break; 9332 } 9333 buf = (unsigned char *)PORT_Alloc(tmpKeySize); 9334 if (buf == NULL) { 9335 crv = CKR_HOST_MEMORY; 9336 break; 9337 } 9338 9339 PORT_Memcpy(buf, stringPtr->pData, stringPtr->ulLen); 9340 PORT_Memcpy(buf + stringPtr->ulLen, att->attrib.pValue, 9341 att->attrib.ulValueLen); 9342 9343 crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize); 9344 PORT_ZFree(buf, tmpKeySize); 9345 break; 9346 case CKM_XOR_BASE_AND_DATA: 9347 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 9348 if (crv != CKR_OK) 9349 break; 9350 9351 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_KEY_DERIVATION_STRING_DATA))) { 9352 crv = CKR_MECHANISM_PARAM_INVALID; 9353 break; 9354 } 9355 stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; 9356 tmpKeySize = PR_MIN(att->attrib.ulValueLen, stringPtr->ulLen); 9357 if (keySize == 0) 9358 keySize = tmpKeySize; 9359 if (keySize > tmpKeySize) { 9360 crv = CKR_TEMPLATE_INCONSISTENT; 9361 break; 9362 } 9363 buf = (unsigned char *)PORT_Alloc(keySize); 9364 if (buf == NULL) { 9365 crv = CKR_HOST_MEMORY; 9366 break; 9367 } 9368 9369 PORT_Memcpy(buf, att->attrib.pValue, keySize); 9370 for (i = 0; i < (int)keySize; i++) { 9371 buf[i] ^= stringPtr->pData[i]; 9372 } 9373 9374 crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize); 9375 PORT_ZFree(buf, keySize); 9376 break; 9377 9378 case CKM_EXTRACT_KEY_FROM_KEY: { 9379 if (BAD_PARAM_CAST(pMechanism, sizeof(CK_EXTRACT_PARAMS))) { 9380 crv = CKR_MECHANISM_PARAM_INVALID; 9381 break; 9382 } 9383 /* the following assumes 8 bits per byte */ 9384 CK_ULONG extract = *(CK_EXTRACT_PARAMS *)pMechanism->pParameter; 9385 CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */ 9386 CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */ 9387 9388 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 9389 if (crv != CKR_OK) 9390 break; 9391 9392 if (keySize == 0) { 9393 crv = CKR_TEMPLATE_INCOMPLETE; 9394 break; 9395 } 9396 /* make sure we have enough bits in the original key */ 9397 if (att->attrib.ulValueLen < 9398 (offset + keySize + ((shift != 0) ? 1 : 0))) { 9399 crv = CKR_MECHANISM_PARAM_INVALID; 9400 break; 9401 } 9402 buf = (unsigned char *)PORT_Alloc(keySize); 9403 if (buf == NULL) { 9404 crv = CKR_HOST_MEMORY; 9405 break; 9406 } 9407 9408 /* copy the bits we need into the new key */ 9409 for (i = 0; i < (int)keySize; i++) { 9410 unsigned char *value = 9411 ((unsigned char *)att->attrib.pValue) + offset + i; 9412 if (shift) { 9413 buf[i] = (value[0] << (shift)) | (value[1] >> (8 - shift)); 9414 } else { 9415 buf[i] = value[0]; 9416 } 9417 } 9418 9419 crv = sftk_forceAttribute(key, CKA_VALUE, buf, keySize); 9420 PORT_ZFree(buf, keySize); 9421 break; 9422 } 9423 case CKM_MD2_KEY_DERIVATION: 9424 if (keySize == 0) 9425 keySize = MD2_LENGTH; 9426 if (keySize > MD2_LENGTH) { 9427 crv = CKR_TEMPLATE_INCONSISTENT; 9428 break; 9429 } 9430 /* now allocate the hash contexts */ 9431 md2 = MD2_NewContext(); 9432 if (md2 == NULL) { 9433 crv = CKR_HOST_MEMORY; 9434 break; 9435 } 9436 MD2_Begin(md2); 9437 MD2_Update(md2, (const unsigned char *)att->attrib.pValue, 9438 att->attrib.ulValueLen); 9439 MD2_End(md2, key_block, &outLen, MD2_LENGTH); 9440 MD2_DestroyContext(md2, PR_TRUE); 9441 9442 crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); 9443 PORT_Memset(key_block, 0, MD2_LENGTH); 9444 break; 9445 #define DERIVE_KEY_HASH(hash) \ 9446 case CKM_##hash##_KEY_DERIVATION: \ 9447 if (keySize == 0) \ 9448 keySize = hash##_LENGTH; \ 9449 if (keySize > hash##_LENGTH) { \ 9450 crv = CKR_TEMPLATE_INCONSISTENT; \ 9451 break; \ 9452 } \ 9453 hash##_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, \ 9454 att->attrib.ulValueLen); \ 9455 crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); \ 9456 PORT_Memset(key_block, 0, hash##_LENGTH); \ 9457 break; 9458 DERIVE_KEY_HASH(MD5) 9459 DERIVE_KEY_HASH(SHA1) 9460 DERIVE_KEY_HASH(SHA224) 9461 DERIVE_KEY_HASH(SHA256) 9462 DERIVE_KEY_HASH(SHA384) 9463 DERIVE_KEY_HASH(SHA512) 9464 DERIVE_KEY_HASH(SHA3_224) 9465 DERIVE_KEY_HASH(SHA3_256) 9466 DERIVE_KEY_HASH(SHA3_384) 9467 DERIVE_KEY_HASH(SHA3_512) 9468 9469 case CKM_DH_PKCS_DERIVE: { 9470 SECItem derived, dhPublic; 9471 SECItem dhPrime, dhValue; 9472 const SECItem *subPrime; 9473 /* sourceKey - values for the local existing low key */ 9474 /* get prime and value attributes */ 9475 crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME); 9476 if (crv != CKR_OK) 9477 break; 9478 9479 dhPublic.data = pMechanism->pParameter; 9480 dhPublic.len = pMechanism->ulParameterLen; 9481 9482 /* if the prime is an approved prime, we can skip all the other 9483 * checks. */ 9484 subPrime = sftk_VerifyDH_Prime(&dhPrime, NULL, isFIPS); 9485 if (subPrime == NULL) { 9486 SECItem dhSubPrime; 9487 /* If the caller set the subprime value, it means that 9488 * either the caller knows the subprime value and wants us 9489 * to validate the key against the subprime, or that the 9490 * caller wants us to verify that the prime is a safe prime 9491 * by passing in subprime = (prime-1)/2 */ 9492 dhSubPrime.data = NULL; 9493 dhSubPrime.len = 0; 9494 crv = sftk_Attribute2SecItem(NULL, &dhSubPrime, 9495 sourceKey, CKA_SUBPRIME); 9496 /* we ignore the value of crv here, We treat a valid 9497 * return of len = 0 and a failure to find a subrime the same 9498 * NOTE: we free the subprime in both cases depending on 9499 * PORT_Free of NULL to be a noop */ 9500 if (dhSubPrime.len != 0) { 9501 PRBool isSafe = PR_FALSE; 9502 9503 /* Callers can set dhSubPrime to q=(p-1)/2 to force 9504 * checks for safe primes. If so we only need to check 9505 * q and p for primality and skip the group test. */ 9506 rv = sftk_IsSafePrime(&dhPrime, &dhSubPrime, &isSafe); 9507 if (rv != SECSuccess) { 9508 /* either p or q was even and therefore not prime, 9509 * we can stop processing here and fail now */ 9510 crv = CKR_ARGUMENTS_BAD; 9511 SECITEM_ZfreeItem(&dhPrime, PR_FALSE); 9512 SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); 9513 break; 9514 } 9515 9516 /* first make sure the primes are really prime */ 9517 if (!KEA_PrimeCheck(&dhPrime)) { 9518 crv = CKR_ARGUMENTS_BAD; 9519 SECITEM_ZfreeItem(&dhPrime, PR_FALSE); 9520 SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); 9521 break; 9522 } 9523 if (!KEA_PrimeCheck(&dhSubPrime)) { 9524 crv = CKR_ARGUMENTS_BAD; 9525 SECITEM_ZfreeItem(&dhPrime, PR_FALSE); 9526 SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); 9527 break; 9528 } 9529 if (isFIPS || !isSafe) { 9530 /* With safe primes, there is only one other small 9531 * subgroup. As long as y isn't 0, 1, or -1 mod p, 9532 * any other y is safe. Only do the full check for 9533 * non-safe primes, except in FIPS mode we need 9534 * to do this check on all primes in which 9535 * we receive the subprime value */ 9536 if (!KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime)) { 9537 crv = CKR_ARGUMENTS_BAD; 9538 SECITEM_ZfreeItem(&dhPrime, PR_FALSE); 9539 SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); 9540 break; 9541 } 9542 } 9543 } else if (isFIPS) { 9544 /* In FIPS mode we only accept approved primes, or 9545 * primes with the full subprime value */ 9546 crv = CKR_ARGUMENTS_BAD; 9547 SECITEM_ZfreeItem(&dhPrime, PR_FALSE); 9548 break; 9549 } 9550 /* checks are complete, no need for the subPrime any longer */ 9551 SECITEM_ZfreeItem(&dhSubPrime, PR_FALSE); 9552 } 9553 9554 /* now that the prime is validated, get the private value */ 9555 crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE); 9556 if (crv != CKR_OK) { 9557 SECITEM_ZfreeItem(&dhPrime, PR_FALSE); 9558 break; 9559 } 9560 9561 /* calculate private value - oct */ 9562 rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize); 9563 9564 SECITEM_ZfreeItem(&dhPrime, PR_FALSE); 9565 SECITEM_ZfreeItem(&dhValue, PR_FALSE); 9566 9567 if (rv == SECSuccess) { 9568 sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len); 9569 SECITEM_ZfreeItem(&derived, PR_FALSE); 9570 crv = CKR_OK; 9571 } else 9572 crv = CKR_HOST_MEMORY; 9573 9574 break; 9575 } 9576 9577 case CKM_ECDH1_DERIVE: 9578 case CKM_ECDH1_COFACTOR_DERIVE: { 9579 SECItem ecScalar, ecPoint; 9580 SECItem tmp; 9581 PRBool withCofactor = PR_FALSE; 9582 unsigned char *secret; 9583 unsigned char *keyData = NULL; 9584 unsigned int secretlen, pubKeyLen; 9585 CK_ECDH1_DERIVE_PARAMS *mechParams; 9586 NSSLOWKEYPrivateKey *privKey; 9587 PLArenaPool *arena = NULL; 9588 9589 /* Check mechanism parameters */ 9590 mechParams = (CK_ECDH1_DERIVE_PARAMS *)pMechanism->pParameter; 9591 if ((pMechanism->ulParameterLen != sizeof(CK_ECDH1_DERIVE_PARAMS)) || 9592 ((mechParams->kdf == CKD_NULL) && 9593 ((mechParams->ulSharedDataLen != 0) || 9594 (mechParams->pSharedData != NULL)))) { 9595 crv = CKR_MECHANISM_PARAM_INVALID; 9596 break; 9597 } 9598 9599 privKey = sftk_GetPrivKey(sourceKey, CKK_EC, &crv); 9600 if (privKey == NULL) { 9601 break; 9602 } 9603 9604 /* Now we are working with a non-NULL private key */ 9605 SECITEM_CopyItem(NULL, &ecScalar, &privKey->u.ec.privateValue); 9606 9607 ecPoint.data = mechParams->pPublicData; 9608 ecPoint.len = mechParams->ulPublicDataLen; 9609 9610 pubKeyLen = EC_GetPointSize(&privKey->u.ec.ecParams); 9611 9612 /* if the len is too large, might be an encoded point */ 9613 if (ecPoint.len > pubKeyLen) { 9614 SECItem newPoint; 9615 9616 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 9617 if (arena == NULL) { 9618 goto ec_loser; 9619 } 9620 9621 rv = SEC_QuickDERDecodeItem(arena, &newPoint, 9622 SEC_ASN1_GET(SEC_OctetStringTemplate), 9623 &ecPoint); 9624 if (rv != SECSuccess) { 9625 goto ec_loser; 9626 } 9627 ecPoint = newPoint; 9628 } 9629 9630 if (mechanism == CKM_ECDH1_COFACTOR_DERIVE) { 9631 withCofactor = PR_TRUE; 9632 } 9633 9634 rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar, 9635 withCofactor, &tmp); 9636 SECITEM_ZfreeItem(&ecScalar, PR_FALSE); 9637 ecScalar.data = NULL; 9638 if (privKey != sourceKey->objectInfo) { 9639 nsslowkey_DestroyPrivateKey(privKey); 9640 privKey = NULL; 9641 } 9642 if (arena) { 9643 PORT_FreeArena(arena, PR_FALSE); 9644 arena = NULL; 9645 } 9646 9647 if (rv != SECSuccess) { 9648 crv = sftk_MapCryptError(PORT_GetError()); 9649 break; 9650 } 9651 9652 /* 9653 * apply the kdf function. 9654 */ 9655 if (mechParams->kdf == CKD_NULL) { 9656 /* 9657 * tmp is the raw data created by ECDH_Derive, 9658 * secret and secretlen are the values we will 9659 * eventually pass as our generated key. 9660 */ 9661 secret = tmp.data; 9662 secretlen = tmp.len; 9663 } else { 9664 secretlen = keySize; 9665 crv = sftk_ANSI_X9_63_kdf(&secret, keySize, 9666 &tmp, mechParams->pSharedData, 9667 mechParams->ulSharedDataLen, mechParams->kdf); 9668 PORT_ZFree(tmp.data, tmp.len); 9669 if (crv != CKR_OK) { 9670 break; 9671 } 9672 tmp.data = secret; 9673 tmp.len = secretlen; 9674 } 9675 9676 /* 9677 * if keySize is supplied, then we are generating a key of a specific 9678 * length. This is done by taking the least significant 'keySize' 9679 * bytes from the unsigned value calculated by ECDH. Note: this may 9680 * mean padding temp with extra leading zeros from what ECDH_Derive 9681 * already returned (which itself may contain leading zeros). 9682 */ 9683 if (keySize) { 9684 if (secretlen < keySize) { 9685 keyData = PORT_ZAlloc(keySize); 9686 if (!keyData) { 9687 PORT_ZFree(tmp.data, tmp.len); 9688 crv = CKR_HOST_MEMORY; 9689 break; 9690 } 9691 PORT_Memcpy(&keyData[keySize - secretlen], secret, secretlen); 9692 secret = keyData; 9693 } else { 9694 secret += (secretlen - keySize); 9695 } 9696 secretlen = keySize; 9697 } 9698 9699 sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); 9700 PORT_ZFree(tmp.data, tmp.len); 9701 if (keyData) { 9702 PORT_ZFree(keyData, keySize); 9703 } 9704 break; 9705 9706 ec_loser: 9707 crv = CKR_ARGUMENTS_BAD; 9708 SECITEM_ZfreeItem(&ecScalar, PR_FALSE); 9709 if (privKey != sourceKey->objectInfo) 9710 nsslowkey_DestroyPrivateKey(privKey); 9711 if (arena) { 9712 PORT_FreeArena(arena, PR_TRUE); 9713 } 9714 break; 9715 } 9716 /* See RFC 5869 and CK_NSS_HKDFParams for documentation. */ 9717 case CKM_NSS_HKDF_SHA1: 9718 hashMech = CKM_SHA_1; 9719 goto hkdf; 9720 case CKM_NSS_HKDF_SHA256: 9721 hashMech = CKM_SHA256; 9722 goto hkdf; 9723 case CKM_NSS_HKDF_SHA384: 9724 hashMech = CKM_SHA384; 9725 goto hkdf; 9726 case CKM_NSS_HKDF_SHA512: 9727 hashMech = CKM_SHA512; 9728 goto hkdf; 9729 hkdf : { 9730 const CK_NSS_HKDFParams *params = 9731 (const CK_NSS_HKDFParams *)pMechanism->pParameter; 9732 CK_HKDF_PARAMS hkdfParams; 9733 9734 if (pMechanism->ulParameterLen != sizeof(CK_NSS_HKDFParams)) { 9735 crv = CKR_MECHANISM_PARAM_INVALID; 9736 break; 9737 } 9738 hkdfParams.bExtract = params->bExtract; 9739 hkdfParams.bExpand = params->bExpand; 9740 if (params->pSalt) { 9741 hkdfParams.ulSaltType = CKF_HKDF_SALT_DATA; 9742 } else { 9743 hkdfParams.ulSaltType = CKF_HKDF_SALT_NULL; 9744 } 9745 hkdfParams.pSalt = params->pSalt; 9746 hkdfParams.ulSaltLen = params->ulSaltLen; 9747 hkdfParams.hSaltKey = CK_INVALID_HANDLE; 9748 hkdfParams.pInfo = params->pInfo; 9749 hkdfParams.ulInfoLen = params->ulInfoLen; 9750 hkdfParams.prfHashMechanism = hashMech; 9751 9752 crv = sftk_HKDF(&hkdfParams, hSession, sourceKey, 9753 att->attrib.pValue, att->attrib.ulValueLen, 9754 key, NULL, keySize, PR_FALSE, isFIPS); 9755 } break; 9756 case CKM_HKDF_DERIVE: 9757 case CKM_HKDF_DATA: /* only difference is the class of key */ 9758 if ((pMechanism->pParameter == NULL) || 9759 (pMechanism->ulParameterLen != sizeof(CK_HKDF_PARAMS))) { 9760 crv = CKR_MECHANISM_PARAM_INVALID; 9761 break; 9762 } 9763 crv = sftk_HKDF((CK_HKDF_PARAMS_PTR)pMechanism->pParameter, 9764 hSession, sourceKey, att->attrib.pValue, 9765 att->attrib.ulValueLen, key, NULL, keySize, PR_TRUE, 9766 isFIPS); 9767 break; 9768 case CKM_NSS_JPAKE_ROUND2_SHA1: 9769 hashType = HASH_AlgSHA1; 9770 goto jpake2; 9771 case CKM_NSS_JPAKE_ROUND2_SHA256: 9772 hashType = HASH_AlgSHA256; 9773 goto jpake2; 9774 case CKM_NSS_JPAKE_ROUND2_SHA384: 9775 hashType = HASH_AlgSHA384; 9776 goto jpake2; 9777 case CKM_NSS_JPAKE_ROUND2_SHA512: 9778 hashType = HASH_AlgSHA512; 9779 goto jpake2; 9780 jpake2: 9781 if (pMechanism->pParameter == NULL || 9782 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKERound2Params)) 9783 crv = CKR_MECHANISM_PARAM_INVALID; 9784 if (crv == CKR_OK && sftk_isTrue(key, CKA_TOKEN)) 9785 crv = CKR_TEMPLATE_INCONSISTENT; 9786 if (crv == CKR_OK) 9787 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 9788 if (crv == CKR_OK) 9789 crv = jpake_Round2(hashType, 9790 (CK_NSS_JPAKERound2Params *)pMechanism->pParameter, 9791 sourceKey, key); 9792 break; 9793 9794 case CKM_NSS_JPAKE_FINAL_SHA1: 9795 hashType = HASH_AlgSHA1; 9796 goto jpakeFinal; 9797 case CKM_NSS_JPAKE_FINAL_SHA256: 9798 hashType = HASH_AlgSHA256; 9799 goto jpakeFinal; 9800 case CKM_NSS_JPAKE_FINAL_SHA384: 9801 hashType = HASH_AlgSHA384; 9802 goto jpakeFinal; 9803 case CKM_NSS_JPAKE_FINAL_SHA512: 9804 hashType = HASH_AlgSHA512; 9805 goto jpakeFinal; 9806 jpakeFinal: 9807 if (pMechanism->pParameter == NULL || 9808 pMechanism->ulParameterLen != sizeof(CK_NSS_JPAKEFinalParams)) 9809 crv = CKR_MECHANISM_PARAM_INVALID; 9810 /* We purposely do not do the derive sensitivity check; we want to be 9811 able to derive non-sensitive keys while allowing the ROUND1 and 9812 ROUND2 keys to be sensitive (which they always are, since they are 9813 in the CKO_PRIVATE_KEY class). The caller must include CKA_SENSITIVE 9814 in the template in order for the resultant keyblock key to be 9815 sensitive. 9816 */ 9817 if (crv == CKR_OK) 9818 crv = jpake_Final(hashType, 9819 (CK_NSS_JPAKEFinalParams *)pMechanism->pParameter, 9820 sourceKey, key); 9821 break; 9822 9823 case CKM_NSS_SP800_108_COUNTER_KDF_DERIVE_DATA: /* fall through */ 9824 case CKM_NSS_SP800_108_FEEDBACK_KDF_DERIVE_DATA: /* fall through */ 9825 case CKM_NSS_SP800_108_DOUBLE_PIPELINE_KDF_DERIVE_DATA: /* fall through */ 9826 case CKM_SP800_108_COUNTER_KDF: /* fall through */ 9827 case CKM_SP800_108_FEEDBACK_KDF: /* fall through */ 9828 case CKM_SP800_108_DOUBLE_PIPELINE_KDF: 9829 crv = sftk_DeriveSensitiveCheck(sourceKey, key, PR_FALSE); 9830 if (crv != CKR_OK) { 9831 break; 9832 } 9833 9834 crv = kbkdf_Dispatch(mechanism, hSession, pMechanism, sourceKey, key, keySize); 9835 break; 9836 default: 9837 crv = CKR_MECHANISM_INVALID; 9838 } 9839 if (att) { 9840 sftk_FreeAttribute(att); 9841 } 9842 sftk_FreeObject(sourceKey); 9843 if (crv != CKR_OK) { 9844 if (key) 9845 sftk_FreeObject(key); 9846 return crv; 9847 } 9848 9849 /* link the key object into the list */ 9850 if (key) { 9851 SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); 9852 PORT_Assert(sessKey); 9853 /* get the session */ 9854 sessKey->wasDerived = PR_TRUE; 9855 session = sftk_SessionFromHandle(hSession); 9856 if (session == NULL) { 9857 sftk_FreeObject(key); 9858 return CKR_HOST_MEMORY; 9859 } 9860 9861 crv = sftk_handleObject(key, session); 9862 session->lastOpWasFIPS = sftk_hasFIPS(key); 9863 sftk_FreeSession(session); 9864 if (phKey) { 9865 *phKey = key->handle; 9866 } 9867 sftk_FreeObject(key); 9868 } 9869 return crv; 9870 } 9871 9872 /* NSC_GetFunctionStatus obtains an updated status of a function running 9873 * in parallel with an application. */ 9874 CK_RV 9875 NSC_GetFunctionStatus(CK_SESSION_HANDLE hSession) 9876 { 9877 CHECK_FORK(); 9878 9879 return CKR_FUNCTION_NOT_PARALLEL; 9880 } 9881 9882 /* NSC_CancelFunction cancels a function running in parallel */ 9883 CK_RV 9884 NSC_CancelFunction(CK_SESSION_HANDLE hSession) 9885 { 9886 CHECK_FORK(); 9887 9888 return CKR_FUNCTION_NOT_PARALLEL; 9889 } 9890 9891 /* NSC_GetOperationState saves the state of the cryptographic 9892 * operation in a session. 9893 * NOTE: This code only works for digest functions for now. eventually need 9894 * to add full flatten/resurect to our state stuff so that all types of state 9895 * can be saved */ 9896 CK_RV 9897 NSC_GetOperationState(CK_SESSION_HANDLE hSession, 9898 CK_BYTE_PTR pOperationState, CK_ULONG_PTR pulOperationStateLen) 9899 { 9900 SFTKSessionContext *context; 9901 SFTKSession *session; 9902 CK_RV crv; 9903 CK_ULONG pOSLen = *pulOperationStateLen; 9904 9905 CHECK_FORK(); 9906 9907 /* make sure we're legal */ 9908 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, &session); 9909 if (crv != CKR_OK) 9910 return crv; 9911 9912 /* a zero cipherInfoLen signals that this context cannot be serialized */ 9913 if (context->cipherInfoLen == 0) { 9914 return CKR_STATE_UNSAVEABLE; 9915 } 9916 9917 *pulOperationStateLen = context->cipherInfoLen + sizeof(CK_MECHANISM_TYPE) + sizeof(SFTKContextType); 9918 if (pOperationState == NULL) { 9919 sftk_FreeSession(session); 9920 return CKR_OK; 9921 } else { 9922 if (pOSLen < *pulOperationStateLen) { 9923 return CKR_BUFFER_TOO_SMALL; 9924 } 9925 } 9926 PORT_Memcpy(pOperationState, &context->type, sizeof(SFTKContextType)); 9927 pOperationState += sizeof(SFTKContextType); 9928 PORT_Memcpy(pOperationState, &context->currentMech, 9929 sizeof(CK_MECHANISM_TYPE)); 9930 pOperationState += sizeof(CK_MECHANISM_TYPE); 9931 PORT_Memcpy(pOperationState, context->cipherInfo, context->cipherInfoLen); 9932 sftk_FreeSession(session); 9933 return CKR_OK; 9934 } 9935 9936 #define sftk_Decrement(stateSize, len) \ 9937 stateSize = ((stateSize) > (CK_ULONG)(len)) ? ((stateSize) - (CK_ULONG)(len)) : 0; 9938 9939 /* NSC_SetOperationState restores the state of the cryptographic 9940 * operation in a session. This is coded like it can restore lots of 9941 * states, but it only works for truly flat cipher structures. */ 9942 CK_RV 9943 NSC_SetOperationState(CK_SESSION_HANDLE hSession, 9944 CK_BYTE_PTR pOperationState, CK_ULONG ulOperationStateLen, 9945 CK_OBJECT_HANDLE hEncryptionKey, CK_OBJECT_HANDLE hAuthenticationKey) 9946 { 9947 SFTKSessionContext *context; 9948 SFTKSession *session; 9949 SFTKContextType type; 9950 CK_MECHANISM mech; 9951 CK_RV crv = CKR_OK; 9952 9953 CHECK_FORK(); 9954 9955 while (ulOperationStateLen != 0) { 9956 /* get what type of state we're dealing with... */ 9957 PORT_Memcpy(&type, pOperationState, sizeof(SFTKContextType)); 9958 9959 /* fix up session contexts based on type */ 9960 session = sftk_SessionFromHandle(hSession); 9961 if (session == NULL) 9962 return CKR_SESSION_HANDLE_INVALID; 9963 context = sftk_ReturnContextByType(session, type); 9964 sftk_SetContextByType(session, type, NULL); 9965 if (context) { 9966 sftk_FreeContext(context); 9967 } 9968 pOperationState += sizeof(SFTKContextType); 9969 sftk_Decrement(ulOperationStateLen, sizeof(SFTKContextType)); 9970 9971 /* get the mechanism structure */ 9972 PORT_Memcpy(&mech.mechanism, pOperationState, sizeof(CK_MECHANISM_TYPE)); 9973 pOperationState += sizeof(CK_MECHANISM_TYPE); 9974 sftk_Decrement(ulOperationStateLen, sizeof(CK_MECHANISM_TYPE)); 9975 /* should be filled in... but not necessary for hash */ 9976 mech.pParameter = NULL; 9977 mech.ulParameterLen = 0; 9978 switch (type) { 9979 case SFTK_HASH: 9980 crv = NSC_DigestInit(hSession, &mech); 9981 if (crv != CKR_OK) 9982 break; 9983 crv = sftk_GetContext(hSession, &context, SFTK_HASH, PR_TRUE, 9984 NULL); 9985 if (crv != CKR_OK) 9986 break; 9987 if (context->cipherInfoLen == 0) { 9988 crv = CKR_SAVED_STATE_INVALID; 9989 break; 9990 } 9991 PORT_Memcpy(context->cipherInfo, pOperationState, 9992 context->cipherInfoLen); 9993 pOperationState += context->cipherInfoLen; 9994 sftk_Decrement(ulOperationStateLen, context->cipherInfoLen); 9995 break; 9996 default: 9997 /* do sign/encrypt/decrypt later */ 9998 crv = CKR_SAVED_STATE_INVALID; 9999 } 10000 sftk_FreeSession(session); 10001 if (crv != CKR_OK) 10002 break; 10003 } 10004 return crv; 10005 } 10006 10007 /* Dual-function cryptographic operations */ 10008 10009 /* NSC_DigestEncryptUpdate continues a multiple-part digesting and encryption 10010 * operation. */ 10011 CK_RV 10012 NSC_DigestEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 10013 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 10014 CK_ULONG_PTR pulEncryptedPartLen) 10015 { 10016 CK_RV crv; 10017 10018 CHECK_FORK(); 10019 10020 crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, 10021 pulEncryptedPartLen); 10022 if (crv != CKR_OK) 10023 return crv; 10024 crv = NSC_DigestUpdate(hSession, pPart, ulPartLen); 10025 10026 return crv; 10027 } 10028 10029 /* NSC_DecryptDigestUpdate continues a multiple-part decryption and 10030 * digesting operation. */ 10031 CK_RV 10032 NSC_DecryptDigestUpdate(CK_SESSION_HANDLE hSession, 10033 CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, 10034 CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) 10035 { 10036 CK_RV crv; 10037 10038 CHECK_FORK(); 10039 10040 crv = NSC_DecryptUpdate(hSession, pEncryptedPart, ulEncryptedPartLen, 10041 pPart, pulPartLen); 10042 if (crv != CKR_OK) 10043 return crv; 10044 crv = NSC_DigestUpdate(hSession, pPart, *pulPartLen); 10045 10046 return crv; 10047 } 10048 10049 /* NSC_SignEncryptUpdate continues a multiple-part signing and 10050 * encryption operation. */ 10051 CK_RV 10052 NSC_SignEncryptUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, 10053 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 10054 CK_ULONG_PTR pulEncryptedPartLen) 10055 { 10056 CK_RV crv; 10057 10058 CHECK_FORK(); 10059 10060 crv = NSC_EncryptUpdate(hSession, pPart, ulPartLen, pEncryptedPart, 10061 pulEncryptedPartLen); 10062 if (crv != CKR_OK) 10063 return crv; 10064 crv = NSC_SignUpdate(hSession, pPart, ulPartLen); 10065 10066 return crv; 10067 } 10068 10069 /* NSC_DecryptVerifyUpdate continues a multiple-part decryption 10070 * and verify operation. */ 10071 CK_RV 10072 NSC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, 10073 CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, 10074 CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen) 10075 { 10076 CK_RV crv; 10077 10078 CHECK_FORK(); 10079 10080 crv = NSC_DecryptUpdate(hSession, pEncryptedData, ulEncryptedDataLen, 10081 pData, pulDataLen); 10082 if (crv != CKR_OK) 10083 return crv; 10084 crv = NSC_VerifyUpdate(hSession, pData, *pulDataLen); 10085 10086 return crv; 10087 } 10088 10089 /* NSC_DigestKey continues a multi-part message-digesting operation, 10090 * by digesting the value of a secret key as part of the data already digested. 10091 */ 10092 CK_RV 10093 NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) 10094 { 10095 SFTKSession *session = NULL; 10096 SFTKObject *key = NULL; 10097 SFTKAttribute *att; 10098 CK_RV crv; 10099 10100 CHECK_FORK(); 10101 10102 session = sftk_SessionFromHandle(hSession); 10103 if (session == NULL) 10104 return CKR_SESSION_HANDLE_INVALID; 10105 10106 key = sftk_ObjectFromHandle(hKey, session); 10107 sftk_FreeSession(session); 10108 if (key == NULL) 10109 return CKR_KEY_HANDLE_INVALID; 10110 10111 /* PUT ANY DIGEST KEY RESTRICTION CHECKS HERE */ 10112 10113 /* make sure it's a valid key for this operation */ 10114 if (key->objclass != CKO_SECRET_KEY) { 10115 sftk_FreeObject(key); 10116 return CKR_KEY_TYPE_INCONSISTENT; 10117 } 10118 /* get the key value */ 10119 att = sftk_FindAttribute(key, CKA_VALUE); 10120 sftk_FreeObject(key); 10121 if (!att) { 10122 return CKR_KEY_HANDLE_INVALID; 10123 } 10124 crv = NSC_DigestUpdate(hSession, (CK_BYTE_PTR)att->attrib.pValue, 10125 att->attrib.ulValueLen); 10126 sftk_FreeAttribute(att); 10127 return crv; 10128 }