pk11cxt.c (63598B)
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 PK11Contexts which are used in multipart hashing, 6 * encryption/decryption, and signing/verication operations. 7 */ 8 9 #include "seccomon.h" 10 #include "secmod.h" 11 #include "nssilock.h" 12 #include "secmodi.h" 13 #include "secmodti.h" 14 #include "pkcs11.h" 15 #include "pk11func.h" 16 #include "secitem.h" 17 #include "secoid.h" 18 #include "sechash.h" 19 #include "secerr.h" 20 #include "blapit.h" 21 #include "secport.h" 22 23 static const SECItem pk11_null_params = { 0 }; 24 25 /********************************************************************** 26 * 27 * Now Deal with Crypto Contexts 28 * 29 **********************************************************************/ 30 31 /* 32 * the monitors... 33 */ 34 void 35 PK11_EnterContextMonitor(PK11Context *cx) 36 { 37 /* if we own the session and our slot is ThreadSafe, only monitor 38 * the Context */ 39 if ((cx->ownSession) && (cx->slot->isThreadSafe)) { 40 /* Should this use monitors instead? */ 41 PZ_Lock(cx->sessionLock); 42 } else { 43 PK11_EnterSlotMonitor(cx->slot); 44 } 45 } 46 47 void 48 PK11_ExitContextMonitor(PK11Context *cx) 49 { 50 /* if we own the session and our slot is ThreadSafe, only monitor 51 * the Context */ 52 if ((cx->ownSession) && (cx->slot->isThreadSafe)) { 53 /* Should this use monitors instead? */ 54 PZ_Unlock(cx->sessionLock); 55 } else { 56 PK11_ExitSlotMonitor(cx->slot); 57 } 58 } 59 60 /* 61 * Free up a Cipher Context 62 */ 63 void 64 PK11_DestroyContext(PK11Context *context, PRBool freeit) 65 { 66 pk11_CloseSession(context->slot, context->session, context->ownSession); 67 /* initialize the critical fields of the context */ 68 if (context->savedData != NULL) 69 PORT_Free(context->savedData); 70 if (context->key) 71 PK11_FreeSymKey(context->key); 72 if (context->param && context->param != &pk11_null_params) 73 SECITEM_FreeItem(context->param, PR_TRUE); 74 if (context->sessionLock) 75 PZ_DestroyLock(context->sessionLock); 76 PK11_FreeSlot(context->slot); 77 if (freeit) 78 PORT_Free(context); 79 } 80 81 /* 82 * save the current context. Allocate Space if necessary. 83 */ 84 static unsigned char * 85 pk11_saveContextHelper(PK11Context *context, unsigned char *buffer, 86 unsigned long *savedLength) 87 { 88 CK_RV crv; 89 90 /* If buffer is NULL, this will get the length */ 91 crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session, (CK_BYTE_PTR)buffer, savedLength); 92 if (!buffer || (crv == CKR_BUFFER_TOO_SMALL)) { 93 /* the given buffer wasn't big enough (or was NULL), but we 94 * have the length, so try again with a new buffer and the 95 * correct length 96 */ 97 unsigned long bufLen = *savedLength; 98 buffer = PORT_Alloc(bufLen); 99 if (buffer == NULL) { 100 return (unsigned char *)NULL; 101 } 102 crv = PK11_GETTAB(context->slot)->C_GetOperationState(context->session, (CK_BYTE_PTR)buffer, savedLength); 103 if (crv != CKR_OK) { 104 PORT_ZFree(buffer, bufLen); 105 } 106 } 107 if (crv != CKR_OK) { 108 PORT_SetError(PK11_MapError(crv)); 109 return (unsigned char *)NULL; 110 } 111 return buffer; 112 } 113 114 void * 115 pk11_saveContext(PK11Context *context, void *space, unsigned long *savedLength) 116 { 117 return pk11_saveContextHelper(context, 118 (unsigned char *)space, savedLength); 119 } 120 121 /* 122 * restore the current context 123 */ 124 SECStatus 125 pk11_restoreContext(PK11Context *context, void *space, unsigned long savedLength) 126 { 127 CK_RV crv; 128 CK_OBJECT_HANDLE objectID = context->objectID; 129 130 PORT_Assert(space != NULL); 131 if (space == NULL) { 132 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 133 return SECFailure; 134 } 135 crv = PK11_GETTAB(context->slot)->C_SetOperationState(context->session, (CK_BYTE_PTR)space, savedLength, objectID, 0); 136 if (crv != CKR_OK) { 137 PORT_SetError(PK11_MapError(crv)); 138 return SECFailure; 139 } 140 return SECSuccess; 141 } 142 143 SECStatus pk11_Finalize(PK11Context *context); 144 145 /* 146 * Initialize a Message function. Particular function is passed in as a 147 * function pointer. Since all C_Message*Init funcitons have the same 148 * prototype, we just pick one of the the prototypes to declare our init 149 * function. 150 */ 151 static CK_RV 152 pk11_contextInitMessage(PK11Context *context, CK_MECHANISM_PTR mech, 153 CK_C_MessageEncryptInit initFunc, 154 CK_FLAGS flags, CK_RV scrv) 155 { 156 PK11SlotInfo *slot = context->slot; 157 CK_RV crv = CKR_OK; 158 159 context->ivCounter = 0; 160 context->ivMaxCount = 0; 161 context->ivFixedBits = 0; 162 context->ivLen = 0; 163 context->ivGen = CKG_NO_GENERATE; 164 context->simulate_mechanism = (mech)->mechanism; 165 context->simulate_message = PR_FALSE; 166 /* check that we can do the Message interface. We need to check 167 * for either 1) are we using a PKCS #11 v3 interface and 2) is the 168 * Message flag set on the mechanism. If either is false we simulate 169 * the message interface for the Encrypt and Decrypt cases using the 170 * PKCS #11 V2 interface. 171 * Sign and verify do not have V2 interfaces, so we go ahead and fail 172 * if those cases */ 173 if ((PK11_CheckPKCS11Version(slot, 3, 0, PR_TRUE) >= 0) && 174 PK11_DoesMechanismFlag(slot, (mech)->mechanism, flags)) { 175 PK11_EnterContextMonitor(context); 176 crv = (*initFunc)((context)->session, (mech), (context)->objectID); 177 PK11_ExitContextMonitor(context); 178 if ((crv == CKR_FUNCTION_NOT_SUPPORTED) || 179 (crv == CKR_MECHANISM_INVALID)) { 180 /* we have a 3.0 interface, and the flag was set (or ignored) 181 * but the implementation was not there, use the V2 interface */ 182 crv = (scrv); 183 context->simulate_message = PR_TRUE; 184 } 185 } else { 186 crv = (scrv); 187 context->simulate_message = PR_TRUE; 188 } 189 return crv; 190 } 191 192 /* 193 * Context initialization. Used by all flavors of CreateContext 194 */ 195 static SECStatus 196 pk11_context_init(PK11Context *context, CK_MECHANISM *mech_info, 197 const SECItem *sig) 198 { 199 CK_RV crv; 200 SECStatus rv = SECSuccess; 201 202 context->simulate_message = PR_FALSE; 203 switch (context->operation) { 204 case CKA_ENCRYPT: 205 PK11_EnterContextMonitor(context); 206 crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, context->objectID); 207 PK11_ExitContextMonitor(context); 208 break; 209 case CKA_DECRYPT: 210 PK11_EnterContextMonitor(context); 211 if (context->fortezzaHack) { 212 CK_ULONG count = 0; 213 /* generate the IV for fortezza */ 214 crv = PK11_GETTAB(context->slot)->C_EncryptInit(context->session, mech_info, context->objectID); 215 if (crv != CKR_OK) { 216 PK11_ExitContextMonitor(context); 217 break; 218 } 219 PK11_GETTAB(context->slot) 220 ->C_EncryptFinal(context->session, 221 NULL, &count); 222 } 223 crv = PK11_GETTAB(context->slot)->C_DecryptInit(context->session, mech_info, context->objectID); 224 PK11_ExitContextMonitor(context); 225 break; 226 case CKA_SIGN: 227 PK11_EnterContextMonitor(context); 228 crv = PK11_GETTAB(context->slot)->C_SignInit(context->session, mech_info, context->objectID); 229 PK11_ExitContextMonitor(context); 230 break; 231 case CKA_VERIFY: 232 /* NOTE: we previously has this set to C_SignInit for Macing. 233 * It turns out now one could possibly use it that way, though, 234 * because PK11_HashOp() always called C_VerifyUpdate on CKA_VERIFY, 235 * which would have failed. So everyone just calls us with CKA_SIGN 236 * when Macing even when they are verifying, no need to 'do it 237 * for them'. It needs to be VerifyInit now so that we can do 238 * PKCS #11 hash/Verify combo operations. */ 239 PK11_EnterContextMonitor(context); 240 crv = PK11_GETTAB(context->slot)->C_VerifyInit(context->session, mech_info, context->objectID); 241 PK11_ExitContextMonitor(context); 242 break; 243 /* fake attibute to distingush CKA_VERIFY from CKA_VERIFY_SIGNAGURE */ 244 case CKA_NSS_VERIFY_SIGNATURE: 245 if (!sig || !sig->data) { 246 PORT_SetError(SEC_ERROR_INVALID_ARGS); 247 return SECFailure; 248 } 249 PK11_EnterContextMonitor(context); 250 crv = PK11_GETTAB(context->slot)->C_VerifySignatureInit(context->session, mech_info, context->objectID, sig->data, sig->len); 251 PK11_ExitContextMonitor(context); 252 break; 253 case CKA_DIGEST: 254 PK11_EnterContextMonitor(context); 255 crv = PK11_GETTAB(context->slot)->C_DigestInit(context->session, mech_info); 256 PK11_ExitContextMonitor(context); 257 break; 258 259 case CKA_NSS_MESSAGE | CKA_ENCRYPT: 260 crv = pk11_contextInitMessage(context, mech_info, 261 PK11_GETTAB(context->slot)->C_MessageEncryptInit, 262 CKF_MESSAGE_ENCRYPT, CKR_OK); 263 break; 264 case CKA_NSS_MESSAGE | CKA_DECRYPT: 265 crv = pk11_contextInitMessage(context, mech_info, 266 PK11_GETTAB(context->slot)->C_MessageDecryptInit, 267 CKF_MESSAGE_DECRYPT, CKR_OK); 268 break; 269 case CKA_NSS_MESSAGE | CKA_SIGN: 270 crv = pk11_contextInitMessage(context, mech_info, 271 PK11_GETTAB(context->slot)->C_MessageSignInit, 272 CKF_MESSAGE_SIGN, CKR_FUNCTION_NOT_SUPPORTED); 273 break; 274 case CKA_NSS_MESSAGE | CKA_VERIFY: 275 crv = pk11_contextInitMessage(context, mech_info, 276 PK11_GETTAB(context->slot)->C_MessageVerifyInit, 277 CKF_MESSAGE_VERIFY, CKR_FUNCTION_NOT_SUPPORTED); 278 break; 279 default: 280 crv = CKR_OPERATION_NOT_INITIALIZED; 281 break; 282 } 283 284 if (crv != CKR_OK) { 285 PORT_SetError(PK11_MapError(crv)); 286 return SECFailure; 287 } 288 289 /* handle the case where the token is using the old NSS mechanism */ 290 if (context->simulate_message && 291 !PK11_DoesMechanism(context->slot, context->simulate_mechanism)) { 292 if ((context->simulate_mechanism == CKM_CHACHA20_POLY1305) && 293 PK11_DoesMechanism(context->slot, CKM_NSS_CHACHA20_POLY1305)) { 294 context->simulate_mechanism = CKM_NSS_CHACHA20_POLY1305; 295 } else { 296 PORT_SetError(PK11_MapError(CKR_MECHANISM_INVALID)); 297 return SECFailure; 298 } 299 } 300 301 /* 302 * handle session starvation case.. use our last session to multiplex 303 */ 304 if (!context->ownSession) { 305 PK11_EnterContextMonitor(context); 306 context->savedData = pk11_saveContext(context, context->savedData, 307 &context->savedLength); 308 if (context->savedData == NULL) 309 rv = SECFailure; 310 /* clear out out session for others to use */ 311 pk11_Finalize(context); 312 PK11_ExitContextMonitor(context); 313 } 314 return rv; 315 } 316 317 /* 318 * Testing interfaces, not for general use. This function forces 319 * an AEAD context into simulation mode even though the target token 320 * can already do PKCS #11 v3.0 Message (i.e. softoken). 321 */ 322 SECStatus 323 _PK11_ContextSetAEADSimulation(PK11Context *context) 324 { 325 CK_RV crv; 326 /* only message encrypt and message decrypt contexts can be simulated */ 327 if ((context->operation != (CKA_NSS_MESSAGE | CKA_ENCRYPT)) && 328 (context->operation != (CKA_NSS_MESSAGE | CKA_DECRYPT))) { 329 PORT_SetError(SEC_ERROR_INVALID_ARGS); 330 return SECFailure; 331 } 332 /* if we are already simulating, return */ 333 if (context->simulate_message) { 334 return SECSuccess; 335 } 336 /* we need to shutdown the existing AEAD operation */ 337 switch (context->operation) { 338 case CKA_NSS_MESSAGE | CKA_ENCRYPT: 339 crv = PK11_GETTAB(context->slot)->C_MessageEncryptFinal(context->session); 340 break; 341 case CKA_NSS_MESSAGE | CKA_DECRYPT: 342 crv = PK11_GETTAB(context->slot)->C_MessageDecryptFinal(context->session); 343 break; 344 default: 345 PORT_SetError(SEC_ERROR_NOT_INITIALIZED); 346 return SECFailure; 347 } 348 if (crv != CKR_OK) { 349 PORT_SetError(PK11_MapError(crv)); 350 return SECFailure; 351 } 352 context->simulate_message = PR_TRUE; 353 return SECSuccess; 354 } 355 356 PRBool 357 _PK11_ContextGetAEADSimulation(PK11Context *context) 358 { 359 return context->simulate_message; 360 } 361 362 /* 363 * Common Helper Function do come up with a new context. 364 */ 365 static PK11Context * 366 pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type, 367 PK11SlotInfo *slot, CK_ATTRIBUTE_TYPE operation, 368 PK11SymKey *symKey, CK_OBJECT_HANDLE objectID, 369 const SECItem *param, const SECItem *sig, 370 void *pwArg) 371 { 372 CK_MECHANISM mech_info; 373 PK11Context *context; 374 SECStatus rv; 375 376 PORT_Assert(slot != NULL); 377 if (!slot || ((objectID == CK_INVALID_HANDLE) && ((operation != CKA_DIGEST) || 378 (type == CKM_SKIPJACK_CBC64)))) { 379 PORT_SetError(SEC_ERROR_INVALID_ARGS); 380 return NULL; 381 } 382 context = (PK11Context *)PORT_Alloc(sizeof(PK11Context)); 383 if (context == NULL) { 384 return NULL; 385 } 386 387 /* now deal with the fortezza hack... the fortezza hack is an attempt 388 * to get around the issue of the card not allowing you to do a FORTEZZA 389 * LoadIV/Encrypt, which was added because such a combination could be 390 * use to circumvent the key escrow system. Unfortunately SSL needs to 391 * do this kind of operation, so in SSL we do a loadIV (to verify it), 392 * Then GenerateIV, and through away the first 8 bytes on either side 393 * of the connection.*/ 394 context->fortezzaHack = PR_FALSE; 395 if (type == CKM_SKIPJACK_CBC64) { 396 if (symKey && (symKey->origin == PK11_OriginFortezzaHack)) { 397 context->fortezzaHack = PR_TRUE; 398 } 399 } 400 401 /* initialize the critical fields of the context */ 402 context->operation = operation; 403 /* If we were given a symKey, keep our own reference to it so 404 * that the key doesn't disappear in the middle of the operation 405 * if the caller frees it. Public and Private keys are not reference 406 * counted, so the caller just has to keep his copies around until 407 * the operation completes */ 408 context->key = symKey ? PK11_ReferenceSymKey(symKey) : NULL; 409 context->objectID = objectID; 410 context->slot = PK11_ReferenceSlot(slot); 411 context->session = pk11_GetNewSession(slot, &context->ownSession); 412 context->pwArg = pwArg; 413 /* get our session */ 414 context->savedData = NULL; 415 416 /* save the parameters so that some digesting stuff can do multiple 417 * begins on a single context */ 418 context->type = type; 419 if (param) { 420 if (param->len > 0) { 421 context->param = SECITEM_DupItem(param); 422 } else { 423 context->param = (SECItem *)&pk11_null_params; 424 } 425 } else { 426 PORT_SetError(SEC_ERROR_INVALID_ARGS); 427 context->param = NULL; 428 } 429 context->init = PR_FALSE; 430 context->sessionLock = PZ_NewLock(nssILockPK11cxt); 431 if ((context->param == NULL) || (context->sessionLock == NULL)) { 432 PK11_DestroyContext(context, PR_TRUE); 433 return NULL; 434 } 435 436 mech_info.mechanism = type; 437 mech_info.pParameter = param->data; 438 mech_info.ulParameterLen = param->len; 439 rv = pk11_context_init(context, &mech_info, sig); 440 441 if (rv != SECSuccess) { 442 PK11_DestroyContext(context, PR_TRUE); 443 return NULL; 444 } 445 context->init = PR_TRUE; 446 return context; 447 } 448 449 /* 450 * put together the various PK11_Create_Context calls used by different 451 * parts of libsec. 452 */ 453 PK11Context * 454 __PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, 455 PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, 456 SECItem *param, void *wincx) 457 { 458 PK11SymKey *symKey = NULL; 459 PK11Context *context = NULL; 460 461 /* first get a slot */ 462 if (slot == NULL) { 463 slot = PK11_GetBestSlot(type, wincx); 464 if (slot == NULL) { 465 PORT_SetError(SEC_ERROR_NO_MODULE); 466 goto loser; 467 } 468 } else { 469 PK11_ReferenceSlot(slot); 470 } 471 472 /* now import the key */ 473 symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx); 474 if (symKey == NULL) 475 goto loser; 476 477 context = PK11_CreateContextBySymKey(type, operation, symKey, param); 478 479 loser: 480 if (symKey) { 481 PK11_FreeSymKey(symKey); 482 } 483 if (slot) { 484 PK11_FreeSlot(slot); 485 } 486 487 return context; 488 } 489 490 PK11Context * 491 PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, 492 PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, 493 SECItem *param, void *wincx) 494 { 495 return __PK11_CreateContextByRawKey(slot, type, origin, operation, 496 key, param, wincx); 497 } 498 499 /* 500 * Create a context from a key. We really should make sure we aren't using 501 * the same key in multiple sessions! 502 */ 503 PK11Context * 504 PK11_CreateContextBySymKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation, 505 PK11SymKey *symKey, const SECItem *param) 506 { 507 PK11SymKey *newKey; 508 PK11Context *context; 509 510 /* if this slot doesn't support the mechanism, go to a slot that does */ 511 newKey = pk11_ForceSlot(symKey, type, operation); 512 if (newKey == NULL) { 513 PK11_ReferenceSymKey(symKey); 514 } else { 515 symKey = newKey; 516 } 517 518 /* Context keeps its reference to the symKey, so it's safe to 519 * free our reference we we are through, even though we may have 520 * created the key using pk11_ForceSlot. */ 521 context = pk11_CreateNewContextInSlot(type, symKey->slot, operation, symKey, 522 symKey->objectID, param, NULL, 523 symKey->cx); 524 PK11_FreeSymKey(symKey); 525 return context; 526 } 527 528 /* To support multipart public key operations (like hash/verify operations), 529 * we need to create contexts with public keys. */ 530 PK11Context * 531 PK11_CreateSignatureContextByPubKey(CK_MECHANISM_TYPE type, 532 CK_ATTRIBUTE_TYPE operation, 533 SECKEYPublicKey *pubKey, const SECItem *param, 534 const SECItem *sig, void *pwArg) 535 { 536 PK11SlotInfo *slot = pubKey->pkcs11Slot; 537 SECItem nullparam = { 0, 0, 0 }; 538 539 /* if this slot doesn't support the mechanism, go to a slot that does */ 540 /* public keys have all their data in the public key data structure, 541 * so there's no need to export the old key, just import this one. The 542 * import manages consistancy of the public key data structure */ 543 if (slot == NULL || !PK11_DoesMechanism(slot, type)) { 544 CK_OBJECT_HANDLE objectID; 545 slot = PK11_GetBestSlot(type, NULL); 546 if (slot == NULL) { 547 return NULL; 548 } 549 objectID = PK11_ImportPublicKey(slot, pubKey, PR_FALSE); 550 PK11_FreeSlot(slot); 551 if (objectID == CK_INVALID_HANDLE) { 552 return NULL; 553 } 554 } 555 556 /* unlike symkeys, we accept a NULL parameter. map a null parameter 557 * to the empty parameter. This matches the semantics of 558 * PK11_VerifyWithMechanism */ 559 return pk11_CreateNewContextInSlot(type, pubKey->pkcs11Slot, operation, 560 NULL, pubKey->pkcs11ID, 561 param ? param : &nullparam, sig, pwArg); 562 } 563 564 /* traditional PK11_CreateContextByPubKey just doesn't have the signature. 565 * This will work unless operation is CKA_NSS_VERIFY_SIGNATURE */ 566 PK11Context * 567 PK11_CreateContextByPubKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation, 568 SECKEYPublicKey *pubKey, const SECItem *param, 569 void *pwArg) 570 { 571 return PK11_CreateSignatureContextByPubKey(type, operation, pubKey, param, 572 NULL, pwArg); 573 } 574 575 /* To support multipart private key operations (like hash/sign operations), 576 * we need to create contexts with private keys. */ 577 PK11Context * 578 PK11_CreateContextByPrivKey(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE operation, 579 SECKEYPrivateKey *privKey, const SECItem *param) 580 { 581 SECItem nullparam = { 0, 0, 0 }; 582 /* Private keys are generally not movable. If the token the 583 * private key lives on can't do the operation, generally we are 584 * stuck anyway. So no need to try to manipulate the key into 585 * another token */ 586 587 /* if this slot doesn't support the mechanism, go to a slot that does */ 588 /* unlike symkeys, we accept a NULL parameter. map a null parameter 589 * to the empty parameter. This matches the semantics of 590 * PK11_SignWithMechanism */ 591 return pk11_CreateNewContextInSlot(type, privKey->pkcs11Slot, operation, 592 NULL, privKey->pkcs11ID, 593 param ? param : &nullparam, NULL, 594 privKey->wincx); 595 } 596 597 /* 598 * Digest contexts don't need keys, but the do need to find a slot. 599 * Macing should use PK11_CreateContextBySymKey. 600 */ 601 PK11Context * 602 PK11_CreateDigestContext(SECOidTag hashAlg) 603 { 604 /* digesting has to work without authentication to the slot */ 605 CK_MECHANISM_TYPE type; 606 PK11SlotInfo *slot; 607 PK11Context *context; 608 SECItem param; 609 610 type = PK11_AlgtagToMechanism(hashAlg); 611 slot = PK11_GetBestSlot(type, NULL); 612 if (slot == NULL) { 613 PORT_SetError(SEC_ERROR_NO_MODULE); 614 return NULL; 615 } 616 617 /* maybe should really be PK11_GenerateNewParam?? */ 618 param.data = NULL; 619 param.len = 0; 620 param.type = 0; 621 622 context = pk11_CreateNewContextInSlot(type, slot, CKA_DIGEST, NULL, 623 CK_INVALID_HANDLE, ¶m, NULL, NULL); 624 PK11_FreeSlot(slot); 625 return context; 626 } 627 628 /* 629 * create a new context which is the clone of the state of old context. 630 */ 631 PK11Context * 632 PK11_CloneContext(PK11Context *old) 633 { 634 PK11Context *newcx; 635 PRBool needFree = PR_FALSE; 636 SECStatus rv = SECSuccess; 637 void *data; 638 unsigned long len; 639 640 newcx = pk11_CreateNewContextInSlot(old->type, old->slot, old->operation, 641 old->key, old->objectID, old->param, 642 NULL, old->pwArg); 643 if (newcx == NULL) 644 return NULL; 645 646 /* now clone the save state. First we need to find the save state 647 * of the old session. If the old context owns it's session, 648 * the state needs to be saved, otherwise the state is in saveData. */ 649 if (old->ownSession) { 650 PK11_EnterContextMonitor(old); 651 data = pk11_saveContext(old, NULL, &len); 652 PK11_ExitContextMonitor(old); 653 needFree = PR_TRUE; 654 } else { 655 data = old->savedData; 656 len = old->savedLength; 657 } 658 659 if (data == NULL) { 660 PK11_DestroyContext(newcx, PR_TRUE); 661 return NULL; 662 } 663 664 /* now copy that state into our new context. Again we have different 665 * work if the new context owns it's own session. If it does, we 666 * restore the state gathered above. If it doesn't, we copy the 667 * saveData pointer... */ 668 if (newcx->ownSession) { 669 PK11_EnterContextMonitor(newcx); 670 rv = pk11_restoreContext(newcx, data, len); 671 PK11_ExitContextMonitor(newcx); 672 } else { 673 PORT_Assert(newcx->savedData != NULL); 674 if ((newcx->savedData == NULL) || (newcx->savedLength < len)) { 675 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 676 rv = SECFailure; 677 } else { 678 PORT_Memcpy(newcx->savedData, data, len); 679 newcx->savedLength = len; 680 } 681 } 682 683 if (needFree) 684 PORT_Free(data); 685 686 if (rv != SECSuccess) { 687 PK11_DestroyContext(newcx, PR_TRUE); 688 return NULL; 689 } 690 return newcx; 691 } 692 693 /* 694 * save the current context state into a variable. Required to make FORTEZZA 695 * work. 696 */ 697 SECStatus 698 PK11_SaveContext(PK11Context *cx, unsigned char *save, int *len, int saveLength) 699 { 700 unsigned char *data = NULL; 701 CK_ULONG length = saveLength; 702 703 if (cx->ownSession) { 704 PK11_EnterContextMonitor(cx); 705 data = pk11_saveContextHelper(cx, save, &length); 706 PK11_ExitContextMonitor(cx); 707 if (data) 708 *len = length; 709 } else if ((unsigned)saveLength >= cx->savedLength) { 710 data = (unsigned char *)cx->savedData; 711 if (cx->savedData) { 712 PORT_Memcpy(save, cx->savedData, cx->savedLength); 713 } 714 *len = cx->savedLength; 715 } 716 if (data != NULL) { 717 if (cx->ownSession) { 718 PORT_ZFree(data, length); 719 } 720 return SECSuccess; 721 } else { 722 return SECFailure; 723 } 724 } 725 726 /* same as above, but may allocate the return buffer. */ 727 unsigned char * 728 PK11_SaveContextAlloc(PK11Context *cx, 729 unsigned char *preAllocBuf, unsigned int pabLen, 730 unsigned int *stateLen) 731 { 732 unsigned char *stateBuf = NULL; 733 unsigned long length = (unsigned long)pabLen; 734 735 if (cx->ownSession) { 736 PK11_EnterContextMonitor(cx); 737 stateBuf = pk11_saveContextHelper(cx, preAllocBuf, &length); 738 PK11_ExitContextMonitor(cx); 739 *stateLen = (stateBuf != NULL) ? length : 0; 740 } else { 741 if (pabLen < cx->savedLength) { 742 stateBuf = (unsigned char *)PORT_Alloc(cx->savedLength); 743 if (!stateBuf) { 744 return (unsigned char *)NULL; 745 } 746 } else { 747 stateBuf = preAllocBuf; 748 } 749 if (cx->savedData) { 750 PORT_Memcpy(stateBuf, cx->savedData, cx->savedLength); 751 } 752 *stateLen = cx->savedLength; 753 } 754 return stateBuf; 755 } 756 757 /* 758 * restore the context state into a new running context. Also required for 759 * FORTEZZA . 760 */ 761 SECStatus 762 PK11_RestoreContext(PK11Context *cx, unsigned char *save, int len) 763 { 764 SECStatus rv = SECSuccess; 765 if (cx->ownSession) { 766 PK11_EnterContextMonitor(cx); 767 pk11_Finalize(cx); 768 rv = pk11_restoreContext(cx, save, len); 769 PK11_ExitContextMonitor(cx); 770 } else { 771 PORT_Assert(cx->savedData != NULL); 772 if ((cx->savedData == NULL) || (cx->savedLength < (unsigned)len)) { 773 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 774 rv = SECFailure; 775 } else { 776 PORT_Memcpy(cx->savedData, save, len); 777 cx->savedLength = len; 778 } 779 } 780 return rv; 781 } 782 783 /* 784 * This is to get FIPS compliance until we can convert 785 * libjar to use PK11_ hashing functions. It returns PR_FALSE 786 * if we can't get a PK11 Context. 787 */ 788 PRBool 789 PK11_HashOK(SECOidTag algID) 790 { 791 PK11Context *cx; 792 793 cx = PK11_CreateDigestContext(algID); 794 if (cx == NULL) 795 return PR_FALSE; 796 PK11_DestroyContext(cx, PR_TRUE); 797 return PR_TRUE; 798 } 799 800 /* 801 * start a new digesting or Mac'ing operation on this context 802 */ 803 SECStatus 804 PK11_DigestBegin(PK11Context *cx) 805 { 806 CK_MECHANISM mech_info; 807 SECStatus rv; 808 809 if (cx->init == PR_TRUE) { 810 return SECSuccess; 811 } 812 813 /* 814 * make sure the old context is clear first 815 */ 816 PK11_EnterContextMonitor(cx); 817 pk11_Finalize(cx); 818 PK11_ExitContextMonitor(cx); 819 820 mech_info.mechanism = cx->type; 821 mech_info.pParameter = cx->param->data; 822 mech_info.ulParameterLen = cx->param->len; 823 rv = pk11_context_init(cx, &mech_info, NULL); 824 825 if (rv != SECSuccess) { 826 return SECFailure; 827 } 828 cx->init = PR_TRUE; 829 return SECSuccess; 830 } 831 832 SECStatus 833 PK11_HashBuf(SECOidTag hashAlg, unsigned char *out, const unsigned char *in, 834 PRInt32 len) 835 { 836 PK11Context *context; 837 unsigned int max_length; 838 unsigned int out_length; 839 SECStatus rv; 840 841 /* len will be passed to PK11_DigestOp as unsigned. */ 842 if (len < 0) { 843 PORT_SetError(SEC_ERROR_INVALID_ARGS); 844 return SECFailure; 845 } 846 847 context = PK11_CreateDigestContext(hashAlg); 848 if (context == NULL) 849 return SECFailure; 850 851 rv = PK11_DigestBegin(context); 852 if (rv != SECSuccess) { 853 PK11_DestroyContext(context, PR_TRUE); 854 return rv; 855 } 856 857 rv = PK11_DigestOp(context, in, len); 858 if (rv != SECSuccess) { 859 PK11_DestroyContext(context, PR_TRUE); 860 return rv; 861 } 862 863 /* XXX This really should have been an argument to this function! */ 864 max_length = HASH_ResultLenByOidTag(hashAlg); 865 PORT_Assert(max_length); 866 if (!max_length) 867 max_length = HASH_LENGTH_MAX; 868 869 rv = PK11_DigestFinal(context, out, &out_length, max_length); 870 PK11_DestroyContext(context, PR_TRUE); 871 return rv; 872 } 873 874 /* 875 * execute a bulk encryption operation 876 */ 877 SECStatus 878 PK11_CipherOp(PK11Context *context, unsigned char *out, int *outlen, 879 int maxout, const unsigned char *in, int inlen) 880 { 881 CK_RV crv = CKR_OK; 882 CK_ULONG length = maxout; 883 CK_ULONG offset = 0; 884 SECStatus rv = SECSuccess; 885 unsigned char *saveOut = out; 886 unsigned char *allocOut = NULL; 887 888 /* if we ran out of session, we need to restore our previously stored 889 * state. 890 */ 891 PK11_EnterContextMonitor(context); 892 if (!context->ownSession) { 893 rv = pk11_restoreContext(context, context->savedData, 894 context->savedLength); 895 if (rv != SECSuccess) { 896 PK11_ExitContextMonitor(context); 897 return rv; 898 } 899 } 900 901 /* 902 * The fortezza hack is to send 8 extra bytes on the first encrypted and 903 * lose them on the first decrypt. 904 */ 905 if (context->fortezzaHack) { 906 unsigned char random[8]; 907 if (context->operation == CKA_ENCRYPT) { 908 PK11_ExitContextMonitor(context); 909 rv = PK11_GenerateRandom(random, sizeof(random)); 910 PK11_EnterContextMonitor(context); 911 912 /* since we are offseting the output, we can't encrypt back into 913 * the same buffer... allocate a temporary buffer just for this 914 * call. */ 915 allocOut = out = (unsigned char *)PORT_Alloc(maxout); 916 if (out == NULL) { 917 PK11_ExitContextMonitor(context); 918 return SECFailure; 919 } 920 crv = PK11_GETTAB(context->slot)->C_EncryptUpdate(context->session, random, sizeof(random), out, &length); 921 922 out += length; 923 maxout -= length; 924 offset = length; 925 } else if (context->operation == CKA_DECRYPT) { 926 length = sizeof(random); 927 crv = PK11_GETTAB(context->slot)->C_DecryptUpdate(context->session, (CK_BYTE_PTR)in, sizeof(random), random, &length); 928 inlen -= length; 929 in += length; 930 context->fortezzaHack = PR_FALSE; 931 } 932 } 933 934 switch (context->operation) { 935 case CKA_ENCRYPT: 936 length = maxout; 937 crv = PK11_GETTAB(context->slot)->C_EncryptUpdate(context->session, (CK_BYTE_PTR)in, inlen, out, &length); 938 length += offset; 939 break; 940 case CKA_DECRYPT: 941 length = maxout; 942 crv = PK11_GETTAB(context->slot)->C_DecryptUpdate(context->session, (CK_BYTE_PTR)in, inlen, out, &length); 943 break; 944 default: 945 crv = CKR_OPERATION_NOT_INITIALIZED; 946 break; 947 } 948 949 if (crv != CKR_OK) { 950 PORT_SetError(PK11_MapError(crv)); 951 *outlen = 0; 952 rv = SECFailure; 953 } else { 954 *outlen = length; 955 } 956 957 if (context->fortezzaHack) { 958 if (context->operation == CKA_ENCRYPT) { 959 PORT_Assert(allocOut); 960 PORT_Memcpy(saveOut, allocOut, length); 961 PORT_Free(allocOut); 962 } 963 context->fortezzaHack = PR_FALSE; 964 } 965 966 /* 967 * handle session starvation case.. use our last session to multiplex 968 */ 969 if (!context->ownSession) { 970 context->savedData = pk11_saveContext(context, context->savedData, 971 &context->savedLength); 972 if (context->savedData == NULL) 973 rv = SECFailure; 974 975 /* clear out out session for others to use */ 976 pk11_Finalize(context); 977 } 978 PK11_ExitContextMonitor(context); 979 return rv; 980 } 981 982 /* 983 * Simulate the IV generation that normally would happen in the token. 984 * 985 * This is a modifed copy of what is in freebl/gcm.c. We can't use the 986 * version in freebl because of layering, since freebl is inside the token 987 * boundary. These issues are traditionally handled by moving them to util, 988 * but we also have two different Random functions we have two switch between. 989 * Since this is primarily here for tokens that don't support the PKCS #11 990 * Message Interface, it's OK if they diverge a bit. Slight semantic 991 * differences from the freebl/gcm.c version shouldn't be much more than the 992 * sematic differences between freebl and other tokens which do implement the 993 * Message Interface. */ 994 static SECStatus 995 pk11_GenerateIV(PK11Context *context, CK_GENERATOR_FUNCTION ivgen, 996 int fixedBits, unsigned char *iv, int ivLen) 997 { 998 unsigned int i; 999 unsigned int flexBits; 1000 unsigned int ivOffset; 1001 unsigned int ivNewCount; 1002 unsigned char ivMask; 1003 unsigned char ivSave; 1004 SECStatus rv; 1005 1006 if (context->ivCounter != 0) { 1007 /* If we've already generated a message, make sure all subsequent 1008 * messages are using the same generator */ 1009 if ((context->ivGen != ivgen) || 1010 (context->ivFixedBits != fixedBits) || 1011 (context->ivLen != ivLen)) { 1012 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1013 return SECFailure; 1014 } 1015 } else { 1016 /* remember these values */ 1017 context->ivGen = ivgen; 1018 context->ivFixedBits = fixedBits; 1019 context->ivLen = ivLen; 1020 /* now calculate how may bits of IV we have to supply */ 1021 flexBits = ivLen * PR_BITS_PER_BYTE; 1022 /* first make sure we aren't going to overflow */ 1023 if (flexBits < fixedBits) { 1024 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1025 return SECFailure; 1026 } 1027 flexBits -= fixedBits; 1028 /* if we are generating a random number reduce the acceptable bits to 1029 * avoid birthday attacks */ 1030 if (ivgen == CKG_GENERATE_RANDOM) { 1031 if (flexBits <= GCMIV_RANDOM_BIRTHDAY_BITS) { 1032 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1033 return SECFailure; 1034 } 1035 /* see freebl/blapit.h for how GCMIV_RANDOM_BIRTHDAY_BITS is 1036 * calculated. */ 1037 flexBits -= GCMIV_RANDOM_BIRTHDAY_BITS; 1038 flexBits = flexBits >> 1; 1039 } 1040 if (flexBits == 0) { 1041 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1042 return SECFailure; 1043 } 1044 /* Turn those bits into the number of IV's we can safely return */ 1045 if (flexBits >= sizeof(context->ivMaxCount) * PR_BITS_PER_BYTE) { 1046 context->ivMaxCount = PR_UINT64(0xffffffffffffffff); 1047 } else { 1048 context->ivMaxCount = (PR_UINT64(1) << flexBits); 1049 } 1050 } 1051 1052 /* no generate, accept the IV from the source */ 1053 if (ivgen == CKG_NO_GENERATE) { 1054 context->ivCounter = 1; 1055 return SECSuccess; 1056 } 1057 1058 /* make sure we haven't exceeded the number of IVs we can return 1059 * for this key, generator, and IV size */ 1060 if (context->ivCounter >= context->ivMaxCount) { 1061 /* use a unique error from just bad user input */ 1062 PORT_SetError(SEC_ERROR_EXTRA_INPUT); 1063 return SECFailure; 1064 } 1065 1066 /* build to mask to handle the first byte of the IV */ 1067 ivOffset = fixedBits / PR_BITS_PER_BYTE; 1068 ivMask = 0xff >> ((PR_BITS_PER_BYTE - (fixedBits & 7)) & 7); 1069 ivNewCount = ivLen - ivOffset; 1070 1071 /* finally generate the IV */ 1072 switch (ivgen) { 1073 case CKG_GENERATE: /* default to counter */ 1074 case CKG_GENERATE_COUNTER: 1075 iv[ivOffset] = (iv[ivOffset] & ~ivMask) | 1076 (PORT_GET_BYTE_BE(context->ivCounter, 0, ivNewCount) & ivMask); 1077 for (i = 1; i < ivNewCount; i++) { 1078 iv[ivOffset + i] = 1079 PORT_GET_BYTE_BE(context->ivCounter, i, ivNewCount); 1080 } 1081 break; 1082 case CKG_GENERATE_COUNTER_XOR: 1083 iv[ivOffset] ^= 1084 (PORT_GET_BYTE_BE(context->ivCounter, 0, ivNewCount) & ivMask); 1085 for (i = 1; i < ivNewCount; i++) { 1086 iv[ivOffset + i] ^= 1087 PORT_GET_BYTE_BE(context->ivCounter, i, ivNewCount); 1088 } 1089 break; 1090 case CKG_GENERATE_RANDOM: 1091 ivSave = iv[ivOffset] & ~ivMask; 1092 rv = PK11_GenerateRandom(iv + ivOffset, ivNewCount); 1093 iv[ivOffset] = ivSave | (iv[ivOffset] & ivMask); 1094 if (rv != SECSuccess) { 1095 return rv; 1096 } 1097 break; 1098 } 1099 context->ivCounter++; 1100 return SECSuccess; 1101 } 1102 1103 /* 1104 * PKCS #11 v2.40 did not have a message interface. If our module can't 1105 * do the message interface use the old method of doing AEAD */ 1106 static SECStatus 1107 pk11_AEADSimulateOp(PK11Context *context, void *params, int paramslen, 1108 const unsigned char *aad, int aadlen, 1109 unsigned char *out, int *outlen, 1110 int maxout, const unsigned char *in, int inlen) 1111 { 1112 unsigned int length = maxout; 1113 SECStatus rv = SECSuccess; 1114 unsigned char *saveOut = out; 1115 unsigned char *allocOut = NULL; 1116 1117 /* 1118 * first we need to convert the single shot (v2.40) parameters into 1119 * the message version of the parameters. This usually involves 1120 * copying the Nonce or IV, setting the AAD from our parameter list 1121 * and handling the tag differences */ 1122 CK_GCM_PARAMS_V3 gcm; 1123 CK_GCM_MESSAGE_PARAMS *gcm_message; 1124 CK_CCM_PARAMS ccm; 1125 CK_CCM_MESSAGE_PARAMS *ccm_message; 1126 CK_SALSA20_CHACHA20_POLY1305_PARAMS chacha_poly; 1127 CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *chacha_poly_message; 1128 CK_NSS_AEAD_PARAMS nss_chacha_poly; 1129 CK_MECHANISM_TYPE mechanism = context->simulate_mechanism; 1130 SECItem sim_params = { 0, NULL, 0 }; 1131 unsigned char *tag = NULL; 1132 unsigned int taglen; 1133 PRBool encrypt; 1134 1135 *outlen = 0; 1136 /* figure out if we are encrypting or decrypting, as tags are 1137 * handled differently in both */ 1138 switch (context->operation) { 1139 case CKA_NSS_MESSAGE | CKA_ENCRYPT: 1140 encrypt = PR_TRUE; 1141 break; 1142 case CKA_NSS_MESSAGE | CKA_DECRYPT: 1143 encrypt = PR_FALSE; 1144 break; 1145 default: 1146 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1147 return SECFailure; 1148 } 1149 1150 switch (mechanism) { 1151 case CKM_CHACHA20_POLY1305: 1152 case CKM_SALSA20_POLY1305: 1153 if (paramslen != sizeof(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS)) { 1154 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1155 return SECFailure; 1156 } 1157 chacha_poly_message = 1158 (CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *)params; 1159 chacha_poly.pNonce = chacha_poly_message->pNonce; 1160 chacha_poly.ulNonceLen = chacha_poly_message->ulNonceLen; 1161 chacha_poly.pAAD = (CK_BYTE_PTR)aad; 1162 chacha_poly.ulAADLen = aadlen; 1163 tag = chacha_poly_message->pTag; 1164 taglen = 16; 1165 sim_params.data = (unsigned char *)&chacha_poly; 1166 sim_params.len = sizeof(chacha_poly); 1167 /* SALSA20_POLY1305 and CHACHA20_POLY1305 do not generate the iv 1168 * internally, don't simulate it either */ 1169 break; 1170 case CKM_NSS_CHACHA20_POLY1305: 1171 if (paramslen != sizeof(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS)) { 1172 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1173 return SECFailure; 1174 } 1175 chacha_poly_message = 1176 (CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS *)params; 1177 tag = chacha_poly_message->pTag; 1178 taglen = 16; 1179 nss_chacha_poly.pNonce = chacha_poly_message->pNonce; 1180 nss_chacha_poly.ulNonceLen = chacha_poly_message->ulNonceLen; 1181 nss_chacha_poly.pAAD = (CK_BYTE_PTR)aad; 1182 nss_chacha_poly.ulAADLen = aadlen; 1183 nss_chacha_poly.ulTagLen = taglen; 1184 sim_params.data = (unsigned char *)&nss_chacha_poly; 1185 sim_params.len = sizeof(nss_chacha_poly); 1186 /* CKM_NSS_CHACHA20_POLY1305 does not generate the iv 1187 * internally, don't simulate it either */ 1188 break; 1189 case CKM_AES_CCM: 1190 if (paramslen != sizeof(CK_CCM_MESSAGE_PARAMS)) { 1191 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1192 return SECFailure; 1193 } 1194 ccm_message = (CK_CCM_MESSAGE_PARAMS *)params; 1195 ccm.ulDataLen = ccm_message->ulDataLen; 1196 ccm.pNonce = ccm_message->pNonce; 1197 ccm.ulNonceLen = ccm_message->ulNonceLen; 1198 ccm.pAAD = (CK_BYTE_PTR)aad; 1199 ccm.ulAADLen = aadlen; 1200 ccm.ulMACLen = ccm_message->ulMACLen; 1201 tag = ccm_message->pMAC; 1202 taglen = ccm_message->ulMACLen; 1203 sim_params.data = (unsigned char *)&ccm; 1204 sim_params.len = sizeof(ccm); 1205 if (encrypt) { 1206 /* simulate generating the IV */ 1207 rv = pk11_GenerateIV(context, ccm_message->nonceGenerator, 1208 ccm_message->ulNonceFixedBits, 1209 ccm_message->pNonce, 1210 ccm_message->ulNonceLen); 1211 if (rv != SECSuccess) { 1212 return rv; 1213 } 1214 } 1215 break; 1216 case CKM_AES_GCM: 1217 if (paramslen != sizeof(CK_GCM_MESSAGE_PARAMS)) { 1218 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1219 return SECFailure; 1220 } 1221 gcm_message = (CK_GCM_MESSAGE_PARAMS *)params; 1222 gcm.pIv = gcm_message->pIv; 1223 gcm.ulIvLen = gcm_message->ulIvLen; 1224 gcm.ulIvBits = gcm.ulIvLen * PR_BITS_PER_BYTE; 1225 gcm.pAAD = (CK_BYTE_PTR)aad; 1226 gcm.ulAADLen = aadlen; 1227 gcm.ulTagBits = gcm_message->ulTagBits; 1228 tag = gcm_message->pTag; 1229 taglen = (gcm_message->ulTagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; 1230 sim_params.data = (unsigned char *)&gcm; 1231 sim_params.len = sizeof(gcm); 1232 if (encrypt) { 1233 /* simulate generating the IV */ 1234 rv = pk11_GenerateIV(context, gcm_message->ivGenerator, 1235 gcm_message->ulIvFixedBits, 1236 gcm_message->pIv, gcm_message->ulIvLen); 1237 if (rv != SECSuccess) { 1238 return rv; 1239 } 1240 } 1241 break; 1242 default: 1243 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1244 return SECFailure; 1245 } 1246 /* now handle the tag. The message interface separates the tag from 1247 * the data, while the single shot gets and puts the tag at the end of 1248 * the encrypted data. */ 1249 if (!encrypt) { 1250 /* In the decrypt case, if the tag is already at the end of the 1251 * input buffer we are golden, otherwise we'll need a new input 1252 * buffer and copy the tag at the end of it */ 1253 if (tag != in + inlen) { 1254 allocOut = PORT_Alloc(inlen + taglen); 1255 if (allocOut == NULL) { 1256 return SECFailure; 1257 } 1258 PORT_Memcpy(allocOut, in, inlen); 1259 PORT_Memcpy(allocOut + inlen, tag, taglen); 1260 in = allocOut; 1261 } 1262 inlen = inlen + taglen; 1263 } else { 1264 /* if we end up allocating, we don't want to overrun this buffer, 1265 * so we fail early here */ 1266 if (maxout < inlen) { 1267 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1268 return SECFailure; 1269 } 1270 /* in the encrypt case, we are fine if maxout is big enough to hold 1271 * the tag. We'll copy the tag after the operation */ 1272 if (maxout < inlen + taglen) { 1273 allocOut = PORT_Alloc(inlen + taglen); 1274 if (allocOut == NULL) { 1275 return SECFailure; 1276 } 1277 out = allocOut; 1278 length = maxout = inlen + taglen; 1279 } 1280 } 1281 /* now do the operation */ 1282 if (encrypt) { 1283 rv = PK11_Encrypt(context->key, mechanism, &sim_params, out, &length, 1284 maxout, in, inlen); 1285 } else { 1286 rv = PK11_Decrypt(context->key, mechanism, &sim_params, out, &length, 1287 maxout, in, inlen); 1288 } 1289 if (rv != SECSuccess) { 1290 /* If the mechanism was CKM_AES_GCM, the module may have been 1291 * following the same error as old versions of NSS. Retry with 1292 * the CK_NSS_GCM_PARAMS */ 1293 if ((mechanism == CKM_AES_GCM) && 1294 (PORT_GetError() == SEC_ERROR_BAD_DATA)) { 1295 CK_NSS_GCM_PARAMS gcm_nss; 1296 gcm_message = (CK_GCM_MESSAGE_PARAMS *)params; 1297 gcm_nss.pIv = gcm_message->pIv; 1298 gcm_nss.ulIvLen = gcm_message->ulIvLen; 1299 gcm_nss.pAAD = (CK_BYTE_PTR)aad; 1300 gcm_nss.ulAADLen = aadlen; 1301 gcm_nss.ulTagBits = gcm_message->ulTagBits; 1302 sim_params.data = (unsigned char *)&gcm_nss; 1303 sim_params.len = sizeof(gcm_nss); 1304 if (encrypt) { 1305 rv = PK11_Encrypt(context->key, mechanism, &sim_params, out, 1306 &length, maxout, in, inlen); 1307 } else { 1308 rv = PK11_Decrypt(context->key, mechanism, &sim_params, out, 1309 &length, maxout, in, inlen); 1310 } 1311 if (rv != SECSuccess) { 1312 goto fail; 1313 } 1314 } else { 1315 goto fail; 1316 } 1317 } 1318 1319 /* on encrypt, separate the output buffer from the tag */ 1320 if (encrypt) { 1321 if ((length < taglen) || (length > inlen + taglen)) { 1322 /* PKCS #11 module should not return a length smaller than 1323 * taglen, or bigger than inlen+taglen */ 1324 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 1325 rv = SECFailure; 1326 goto fail; 1327 } 1328 length = length - taglen; 1329 if (allocOut) { 1330 /* 1331 * If we used a temporary buffer, copy it out to the original 1332 * buffer. 1333 */ 1334 PORT_Memcpy(saveOut, allocOut, length); 1335 } 1336 /* if the tag isn't in the right place, copy it out */ 1337 if (tag != out + length) { 1338 PORT_Memcpy(tag, out + length, taglen); 1339 } 1340 } 1341 *outlen = length; 1342 rv = SECSuccess; 1343 fail: 1344 if (allocOut) { 1345 PORT_Free(allocOut); 1346 } 1347 return rv; 1348 } 1349 1350 /* 1351 * Do an AEAD operation. This function optionally returns 1352 * and IV on Encrypt for all mechanism. NSS knows which mechanisms 1353 * generate IV's in the token and which don't. This allows the 1354 * applications to make a single call without special handling for 1355 * each AEAD mechanism (the special handling is all contained here. 1356 */ 1357 SECStatus 1358 PK11_AEADOp(PK11Context *context, CK_GENERATOR_FUNCTION ivgen, 1359 int fixedbits, unsigned char *iv, int ivlen, 1360 const unsigned char *aad, int aadlen, 1361 unsigned char *out, int *outlen, 1362 int maxout, unsigned char *tag, int taglen, 1363 const unsigned char *in, int inlen) 1364 { 1365 CK_GCM_MESSAGE_PARAMS gcm_message; 1366 CK_CCM_MESSAGE_PARAMS ccm_message; 1367 CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS chacha_poly_message; 1368 void *params; 1369 int paramslen; 1370 SECStatus rv; 1371 1372 switch (context->simulate_mechanism) { 1373 case CKM_CHACHA20_POLY1305: 1374 case CKM_SALSA20_POLY1305: 1375 case CKM_NSS_CHACHA20_POLY1305: 1376 chacha_poly_message.pNonce = iv; 1377 chacha_poly_message.ulNonceLen = ivlen; 1378 chacha_poly_message.pTag = tag; 1379 params = &chacha_poly_message; 1380 paramslen = sizeof(CK_SALSA20_CHACHA20_POLY1305_MSG_PARAMS); 1381 /* SALSA20_POLY1305 and CHACHA20_POLY1305 do not generate the iv 1382 * internally, Do it here. */ 1383 if (context->operation == (CKA_NSS_MESSAGE | CKA_ENCRYPT)) { 1384 /* simulate generating the IV */ 1385 rv = pk11_GenerateIV(context, ivgen, fixedbits, iv, ivlen); 1386 if (rv != SECSuccess) { 1387 return rv; 1388 } 1389 } 1390 break; 1391 case CKM_AES_GCM: 1392 gcm_message.pIv = iv; 1393 gcm_message.ulIvLen = ivlen; 1394 gcm_message.ivGenerator = ivgen; 1395 gcm_message.ulIvFixedBits = fixedbits; 1396 gcm_message.pTag = tag; 1397 gcm_message.ulTagBits = taglen * 8; 1398 params = &gcm_message; 1399 paramslen = sizeof(CK_GCM_MESSAGE_PARAMS); 1400 /* GCM generates IV internally */ 1401 break; 1402 case CKM_AES_CCM: 1403 ccm_message.ulDataLen = inlen; 1404 ccm_message.pNonce = iv; 1405 ccm_message.ulNonceLen = ivlen; 1406 ccm_message.nonceGenerator = ivgen; 1407 ccm_message.ulNonceFixedBits = fixedbits; 1408 ccm_message.pMAC = tag; 1409 ccm_message.ulMACLen = taglen; 1410 params = &ccm_message; 1411 paramslen = sizeof(CK_GCM_MESSAGE_PARAMS); 1412 /* CCM generates IV internally */ 1413 break; 1414 1415 default: 1416 PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); 1417 return SECFailure; 1418 } 1419 return PK11_AEADRawOp(context, params, paramslen, aad, aadlen, out, outlen, 1420 maxout, in, inlen); 1421 } 1422 1423 /* Do and AED operation. The application builds the params on it's own 1424 * and passes them in. This allows applications direct access to the params 1425 * so they can use mechanisms not yet understood by, NSS, or get semantics 1426 * not suppied by PK11_AEAD. */ 1427 SECStatus 1428 PK11_AEADRawOp(PK11Context *context, void *params, int paramslen, 1429 const unsigned char *aad, int aadlen, 1430 unsigned char *out, int *outlen, 1431 int maxout, const unsigned char *in, int inlen) 1432 { 1433 CK_RV crv = CKR_OK; 1434 CK_ULONG length = maxout; 1435 SECStatus rv = SECSuccess; 1436 1437 PORT_Assert(outlen != NULL); 1438 *outlen = 0; 1439 if (((context->operation) & CKA_NSS_MESSAGE_MASK) != CKA_NSS_MESSAGE) { 1440 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1441 return SECFailure; 1442 } 1443 1444 /* 1445 * The PKCS 11 module does not support the message interface, fall 1446 * back to using single shot operation */ 1447 if (context->simulate_message) { 1448 return pk11_AEADSimulateOp(context, params, paramslen, aad, aadlen, 1449 out, outlen, maxout, in, inlen); 1450 } 1451 1452 /* if we ran out of session, we need to restore our previously stored 1453 * state. 1454 */ 1455 PK11_EnterContextMonitor(context); 1456 if (!context->ownSession) { 1457 rv = pk11_restoreContext(context, context->savedData, 1458 context->savedLength); 1459 if (rv != SECSuccess) { 1460 PK11_ExitContextMonitor(context); 1461 return rv; 1462 } 1463 } 1464 1465 switch (context->operation) { 1466 case CKA_NSS_MESSAGE | CKA_ENCRYPT: 1467 length = maxout; 1468 crv = PK11_GETTAB(context->slot)->C_EncryptMessage(context->session, params, paramslen, (CK_BYTE_PTR)aad, aadlen, (CK_BYTE_PTR)in, inlen, out, &length); 1469 break; 1470 case CKA_NSS_MESSAGE | CKA_DECRYPT: 1471 length = maxout; 1472 crv = PK11_GETTAB(context->slot)->C_DecryptMessage(context->session, params, paramslen, (CK_BYTE_PTR)aad, aadlen, (CK_BYTE_PTR)in, inlen, out, &length); 1473 break; 1474 case CKA_NSS_MESSAGE | CKA_SIGN: 1475 length = maxout; 1476 crv = PK11_GETTAB(context->slot)->C_SignMessage(context->session, params, paramslen, (CK_BYTE_PTR)in, inlen, out, &length); 1477 break; 1478 case CKA_NSS_MESSAGE | CKA_VERIFY: 1479 length = maxout; /* sig length */ 1480 crv = PK11_GETTAB(context->slot)->C_VerifyMessage(context->session, params, paramslen, (CK_BYTE_PTR)in, inlen, out /* sig */, length); 1481 break; 1482 default: 1483 crv = CKR_OPERATION_NOT_INITIALIZED; 1484 break; 1485 } 1486 1487 if (crv != CKR_OK) { 1488 PORT_SetError(PK11_MapError(crv)); 1489 rv = SECFailure; 1490 } else { 1491 *outlen = length; 1492 } 1493 1494 /* 1495 * handle session starvation case.. use our last session to multiplex 1496 */ 1497 if (!context->ownSession) { 1498 context->savedData = pk11_saveContext(context, context->savedData, 1499 &context->savedLength); 1500 if (context->savedData == NULL) 1501 rv = SECFailure; 1502 1503 /* clear out out session for others to use */ 1504 pk11_Finalize(context); 1505 } 1506 PK11_ExitContextMonitor(context); 1507 return rv; 1508 } 1509 1510 /* 1511 * execute a digest/signature operation 1512 */ 1513 SECStatus 1514 PK11_DigestOp(PK11Context *context, const unsigned char *in, unsigned inLen) 1515 { 1516 CK_RV crv = CKR_OK; 1517 SECStatus rv = SECSuccess; 1518 1519 if (inLen == 0) { 1520 return SECSuccess; 1521 } 1522 if (!in) { 1523 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1524 return SECFailure; 1525 } 1526 1527 /* if we ran out of session, we need to restore our previously stored 1528 * state. 1529 */ 1530 context->init = PR_FALSE; 1531 PK11_EnterContextMonitor(context); 1532 if (!context->ownSession) { 1533 rv = pk11_restoreContext(context, context->savedData, 1534 context->savedLength); 1535 if (rv != SECSuccess) { 1536 PK11_ExitContextMonitor(context); 1537 return rv; 1538 } 1539 } 1540 1541 switch (context->operation) { 1542 /* also for MAC'ing */ 1543 case CKA_SIGN: 1544 crv = PK11_GETTAB(context->slot)->C_SignUpdate(context->session, (unsigned char *)in, inLen); 1545 break; 1546 case CKA_VERIFY: 1547 crv = PK11_GETTAB(context->slot)->C_VerifyUpdate(context->session, (unsigned char *)in, inLen); 1548 break; 1549 case CKA_NSS_VERIFY_SIGNATURE: 1550 crv = PK11_GETTAB(context->slot)->C_VerifySignatureUpdate(context->session, (unsigned char *)in, inLen); 1551 break; 1552 case CKA_DIGEST: 1553 crv = PK11_GETTAB(context->slot)->C_DigestUpdate(context->session, (unsigned char *)in, inLen); 1554 break; 1555 default: 1556 crv = CKR_OPERATION_NOT_INITIALIZED; 1557 break; 1558 } 1559 1560 if (crv != CKR_OK) { 1561 PORT_SetError(PK11_MapError(crv)); 1562 rv = SECFailure; 1563 } 1564 1565 /* 1566 * handle session starvation case.. use our last session to multiplex 1567 */ 1568 if (!context->ownSession) { 1569 context->savedData = pk11_saveContext(context, context->savedData, 1570 &context->savedLength); 1571 if (context->savedData == NULL) 1572 rv = SECFailure; 1573 1574 /* clear out out session for others to use */ 1575 pk11_Finalize(context); 1576 } 1577 PK11_ExitContextMonitor(context); 1578 return rv; 1579 } 1580 1581 /* 1582 * Digest a key if possible./ 1583 */ 1584 SECStatus 1585 PK11_DigestKey(PK11Context *context, PK11SymKey *key) 1586 { 1587 CK_RV crv = CKR_OK; 1588 SECStatus rv = SECSuccess; 1589 PK11SymKey *newKey = NULL; 1590 1591 if (!context || !key) { 1592 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1593 return SECFailure; 1594 } 1595 1596 /* if we ran out of session, we need to restore our previously stored 1597 * state. 1598 */ 1599 if (context->slot != key->slot) { 1600 newKey = pk11_CopyToSlot(context->slot, CKM_SSL3_SHA1_MAC, CKA_SIGN, key); 1601 } else { 1602 newKey = PK11_ReferenceSymKey(key); 1603 } 1604 1605 context->init = PR_FALSE; 1606 PK11_EnterContextMonitor(context); 1607 if (!context->ownSession) { 1608 rv = pk11_restoreContext(context, context->savedData, 1609 context->savedLength); 1610 if (rv != SECSuccess) { 1611 PK11_ExitContextMonitor(context); 1612 PK11_FreeSymKey(newKey); 1613 return rv; 1614 } 1615 } 1616 1617 if (newKey == NULL) { 1618 crv = CKR_KEY_TYPE_INCONSISTENT; 1619 if (key->data.data) { 1620 crv = PK11_GETTAB(context->slot)->C_DigestUpdate(context->session, key->data.data, key->data.len); 1621 } 1622 } else { 1623 crv = PK11_GETTAB(context->slot)->C_DigestKey(context->session, newKey->objectID); 1624 } 1625 1626 if (crv != CKR_OK) { 1627 PORT_SetError(PK11_MapError(crv)); 1628 rv = SECFailure; 1629 } 1630 1631 /* 1632 * handle session starvation case.. use our last session to multiplex 1633 */ 1634 if (!context->ownSession) { 1635 context->savedData = pk11_saveContext(context, context->savedData, 1636 &context->savedLength); 1637 if (context->savedData == NULL) 1638 rv = SECFailure; 1639 1640 /* clear out out session for others to use */ 1641 pk11_Finalize(context); 1642 } 1643 PK11_ExitContextMonitor(context); 1644 if (newKey) 1645 PK11_FreeSymKey(newKey); 1646 return rv; 1647 } 1648 1649 /* 1650 * externally callable version of the lowercase pk11_finalize(). 1651 */ 1652 SECStatus 1653 PK11_Finalize(PK11Context *context) 1654 { 1655 SECStatus rv; 1656 1657 PK11_EnterContextMonitor(context); 1658 rv = pk11_Finalize(context); 1659 PK11_ExitContextMonitor(context); 1660 return rv; 1661 } 1662 1663 /* 1664 * clean up a cipher operation, so the session can be used by 1665 * someone new. 1666 */ 1667 SECStatus 1668 pk11_Finalize(PK11Context *context) 1669 { 1670 CK_ULONG count = 0; 1671 CK_RV crv; 1672 unsigned char stackBuf[256]; 1673 unsigned char *buffer = NULL; 1674 1675 if (!context->ownSession) { 1676 return SECSuccess; 1677 } 1678 1679 finalize: 1680 switch (context->operation) { 1681 case CKA_ENCRYPT: 1682 crv = PK11_GETTAB(context->slot)->C_EncryptFinal(context->session, buffer, &count); 1683 break; 1684 case CKA_DECRYPT: 1685 crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session, buffer, &count); 1686 break; 1687 case CKA_SIGN: 1688 crv = PK11_GETTAB(context->slot)->C_SignFinal(context->session, buffer, &count); 1689 break; 1690 case CKA_VERIFY: 1691 crv = PK11_GETTAB(context->slot)->C_VerifyFinal(context->session, buffer, count); 1692 break; 1693 case CKA_NSS_VERIFY_SIGNATURE: 1694 crv = PK11_GETTAB(context->slot)->C_VerifySignatureFinal(context->session); 1695 break; 1696 case CKA_DIGEST: 1697 crv = PK11_GETTAB(context->slot)->C_DigestFinal(context->session, buffer, &count); 1698 break; 1699 case CKA_NSS_MESSAGE | CKA_ENCRYPT: 1700 crv = PK11_GETTAB(context->slot)->C_MessageEncryptFinal(context->session); 1701 break; 1702 case CKA_NSS_MESSAGE | CKA_DECRYPT: 1703 crv = PK11_GETTAB(context->slot)->C_MessageDecryptFinal(context->session); 1704 break; 1705 case CKA_NSS_MESSAGE | CKA_SIGN: 1706 crv = PK11_GETTAB(context->slot)->C_MessageSignFinal(context->session); 1707 break; 1708 case CKA_NSS_MESSAGE | CKA_VERIFY: 1709 crv = PK11_GETTAB(context->slot)->C_MessageVerifyFinal(context->session); 1710 break; 1711 default: 1712 crv = CKR_OPERATION_NOT_INITIALIZED; 1713 break; 1714 } 1715 1716 if (crv != CKR_OK) { 1717 if (buffer != stackBuf) { 1718 PORT_Free(buffer); 1719 } 1720 if (crv == CKR_OPERATION_NOT_INITIALIZED) { 1721 /* if there's no operation, it is finalized */ 1722 return SECSuccess; 1723 } 1724 PORT_SetError(PK11_MapError(crv)); 1725 return SECFailure; 1726 } 1727 1728 /* Message interface does not need to allocate a final buffer */ 1729 /* nor does CKA_NSS_VERIFY_SIGNATURE. We could use a clever trick 1730 * here to include the CKA_NSS_SIGNATURE addition, but this form is 1731 * more clear to the reader what is happenning */ 1732 if ((((context->operation) & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) || 1733 ((context->operation) == CKA_NSS_VERIFY_SIGNATURE)) { 1734 return SECSuccess; 1735 } 1736 1737 /* try to finalize the session with a buffer */ 1738 if (buffer == NULL) { 1739 if (count <= sizeof stackBuf) { 1740 buffer = stackBuf; 1741 } else { 1742 buffer = PORT_Alloc(count); 1743 if (buffer == NULL) { 1744 return SECFailure; 1745 } 1746 } 1747 goto finalize; 1748 } 1749 if (buffer != stackBuf) { 1750 PORT_Free(buffer); 1751 } 1752 return SECSuccess; 1753 } 1754 1755 /* 1756 * Return the final digested or signed data... 1757 * this routine can either take pre initialized data, or allocate data 1758 * either out of an arena or out of the standard heap. 1759 */ 1760 SECStatus 1761 PK11_DigestFinal(PK11Context *context, unsigned char *data, 1762 unsigned int *outLen, unsigned int length) 1763 { 1764 CK_ULONG len; 1765 CK_RV crv; 1766 SECStatus rv; 1767 1768 /* message interface returns no data on Final, Should not use DigestFinal 1769 * in this case */ 1770 if (((context->operation) & CKA_NSS_MESSAGE_MASK) == CKA_NSS_MESSAGE) { 1771 PORT_SetError(SEC_ERROR_INVALID_ARGS); 1772 return SECFailure; 1773 } 1774 1775 /* if we ran out of session, we need to restore our previously stored 1776 * state. 1777 */ 1778 PK11_EnterContextMonitor(context); 1779 if (!context->ownSession) { 1780 rv = pk11_restoreContext(context, context->savedData, 1781 context->savedLength); 1782 if (rv != SECSuccess) { 1783 PK11_ExitContextMonitor(context); 1784 return rv; 1785 } 1786 } 1787 1788 len = length; 1789 switch (context->operation) { 1790 case CKA_SIGN: 1791 crv = PK11_GETTAB(context->slot)->C_SignFinal(context->session, data, &len); 1792 break; 1793 case CKA_VERIFY: 1794 crv = PK11_GETTAB(context->slot)->C_VerifyFinal(context->session, data, len); 1795 break; 1796 case CKA_NSS_VERIFY_SIGNATURE: 1797 crv = PK11_GETTAB(context->slot)->C_VerifySignatureFinal(context->session); 1798 break; 1799 case CKA_DIGEST: 1800 crv = PK11_GETTAB(context->slot)->C_DigestFinal(context->session, data, &len); 1801 break; 1802 case CKA_ENCRYPT: 1803 crv = PK11_GETTAB(context->slot)->C_EncryptFinal(context->session, data, &len); 1804 break; 1805 case CKA_DECRYPT: 1806 crv = PK11_GETTAB(context->slot)->C_DecryptFinal(context->session, data, &len); 1807 break; 1808 default: 1809 crv = CKR_OPERATION_NOT_INITIALIZED; 1810 break; 1811 } 1812 PK11_ExitContextMonitor(context); 1813 1814 context->init = PR_FALSE; /* allow Begin to start up again */ 1815 1816 if (crv != CKR_OK) { 1817 PORT_SetError(PK11_MapError(crv)); 1818 return SECFailure; 1819 } 1820 *outLen = (unsigned int)len; 1821 return SECSuccess; 1822 } 1823 1824 PRBool 1825 PK11_ContextGetFIPSStatus(PK11Context *context) 1826 { 1827 if (context->slot == NULL) { 1828 return PR_FALSE; 1829 } 1830 return pk11slot_GetFIPSStatus(context->slot, context->session, 1831 CK_INVALID_HANDLE, context->init ? CKT_NSS_SESSION_CHECK : CKT_NSS_SESSION_LAST_CHECK); 1832 }