1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2018, Joyent, Inc. 26 * Copyright 2017 Jason King. 27 */ 28 29 #include <pthread.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <strings.h> 33 #include <sys/types.h> 34 #include <security/cryptoki.h> 35 #include <modes/modes.h> 36 #include <arcfour.h> 37 #include "softSession.h" 38 #include "softObject.h" 39 #include "softOps.h" 40 #include "softCrypt.h" 41 #include "softRSA.h" 42 43 /* 44 * Add padding bytes with the value of length of padding. 45 */ 46 void 47 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len) 48 { 49 (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size); 50 } 51 52 /* 53 * Perform encrypt init operation internally for the support of 54 * CKM_AES and CKM_DES MAC operations. 55 * 56 * This function is called with the session being held, and without 57 * its mutex taken. 58 */ 59 CK_RV 60 soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR 61 pMechanism, soft_object_t *key_p) 62 { 63 CK_RV rv; 64 65 (void) pthread_mutex_lock(&session_p->session_mutex); 66 67 /* Check to see if encrypt operation is already active */ 68 if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) { 69 (void) pthread_mutex_unlock(&session_p->session_mutex); 70 return (CKR_OPERATION_ACTIVE); 71 } 72 73 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE; 74 75 (void) pthread_mutex_unlock(&session_p->session_mutex); 76 77 rv = soft_encrypt_init(session_p, pMechanism, key_p); 78 79 if (rv != CKR_OK) { 80 (void) pthread_mutex_lock(&session_p->session_mutex); 81 session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE; 82 (void) pthread_mutex_unlock(&session_p->session_mutex); 83 } 84 85 return (rv); 86 } 87 88 /* 89 * soft_encrypt_init() 90 * 91 * Arguments: 92 * session_p: pointer to soft_session_t struct 93 * pMechanism: pointer to CK_MECHANISM struct provided by application 94 * key_p: pointer to key soft_object_t struct 95 * 96 * Description: 97 * called by C_EncryptInit(). This function calls the corresponding 98 * encrypt init routine based on the mechanism. 99 * 100 * Returns: 101 * CKR_OK: success 102 * CKR_HOST_MEMORY: run out of system memory 103 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism 104 * CKR_MECHANISM_INVALID: invalid mechanism type 105 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use 106 * with the specified mechanism 107 */ 108 CK_RV 109 soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 110 soft_object_t *key_p) 111 { 112 113 CK_RV rv; 114 115 switch (pMechanism->mechanism) { 116 117 case CKM_DES_ECB: 118 119 if (key_p->key_type != CKK_DES) { 120 return (CKR_KEY_TYPE_INCONSISTENT); 121 } 122 goto ecb_common; 123 124 case CKM_DES3_ECB: 125 126 if ((key_p->key_type != CKK_DES2) && 127 (key_p->key_type != CKK_DES3)) { 128 return (CKR_KEY_TYPE_INCONSISTENT); 129 } 130 131 ecb_common: 132 return (soft_des_crypt_init_common(session_p, pMechanism, 133 key_p, B_TRUE)); 134 135 case CKM_DES_CBC: 136 case CKM_DES_CBC_PAD: 137 138 if (key_p->key_type != CKK_DES) { 139 return (CKR_KEY_TYPE_INCONSISTENT); 140 } 141 142 goto cbc_common; 143 144 case CKM_DES3_CBC: 145 case CKM_DES3_CBC_PAD: 146 { 147 148 soft_des_ctx_t *soft_des_ctx; 149 150 if ((key_p->key_type != CKK_DES2) && 151 (key_p->key_type != CKK_DES3)) { 152 return (CKR_KEY_TYPE_INCONSISTENT); 153 } 154 155 cbc_common: 156 if ((pMechanism->pParameter == NULL) || 157 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) { 158 return (CKR_MECHANISM_PARAM_INVALID); 159 } 160 161 rv = soft_des_crypt_init_common(session_p, pMechanism, 162 key_p, B_TRUE); 163 164 if (rv != CKR_OK) 165 return (rv); 166 167 (void) pthread_mutex_lock(&session_p->session_mutex); 168 169 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context; 170 /* Copy Initialization Vector (IV) into the context. */ 171 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter, 172 DES_BLOCK_LEN); 173 174 /* Allocate a context for DES cipher-block chaining. */ 175 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init( 176 soft_des_ctx->key_sched, soft_des_ctx->keysched_len, 177 soft_des_ctx->ivec, key_p->key_type); 178 179 if (soft_des_ctx->des_cbc == NULL) { 180 freezero(soft_des_ctx->key_sched, 181 soft_des_ctx->keysched_len); 182 freezero(session_p->encrypt.context, 183 sizeof (soft_des_ctx_t)); 184 session_p->encrypt.context = NULL; 185 rv = CKR_HOST_MEMORY; 186 } 187 188 (void) pthread_mutex_unlock(&session_p->session_mutex); 189 190 return (rv); 191 } 192 193 case CKM_AES_ECB: 194 case CKM_AES_CBC: 195 case CKM_AES_CBC_PAD: 196 case CKM_AES_CMAC: 197 case CKM_AES_CTR: 198 case CKM_AES_CCM: 199 case CKM_AES_GCM: 200 case CKM_AES_GMAC: 201 return (soft_aes_crypt_init_common(session_p, pMechanism, 202 key_p, B_TRUE)); 203 204 case CKM_RC4: 205 206 if (key_p->key_type != CKK_RC4) { 207 return (CKR_KEY_TYPE_INCONSISTENT); 208 } 209 210 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p, 211 B_TRUE)); 212 213 case CKM_RSA_X_509: 214 case CKM_RSA_PKCS: 215 216 if (key_p->key_type != CKK_RSA) { 217 return (CKR_KEY_TYPE_INCONSISTENT); 218 } 219 220 return (soft_rsa_crypt_init_common(session_p, pMechanism, 221 key_p, B_TRUE)); 222 223 case CKM_BLOWFISH_CBC: 224 { 225 soft_blowfish_ctx_t *soft_blowfish_ctx; 226 227 if (key_p->key_type != CKK_BLOWFISH) 228 return (CKR_KEY_TYPE_INCONSISTENT); 229 230 if ((pMechanism->pParameter == NULL) || 231 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN)) 232 return (CKR_MECHANISM_PARAM_INVALID); 233 234 rv = soft_blowfish_crypt_init_common(session_p, pMechanism, 235 key_p, B_TRUE); 236 237 if (rv != CKR_OK) 238 return (rv); 239 240 (void) pthread_mutex_lock(&session_p->session_mutex); 241 242 soft_blowfish_ctx = 243 (soft_blowfish_ctx_t *)session_p->encrypt.context; 244 /* Copy Initialization Vector (IV) into the context. */ 245 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter, 246 BLOWFISH_BLOCK_LEN); 247 248 /* Allocate a context for Blowfish cipher-block chaining */ 249 soft_blowfish_ctx->blowfish_cbc = 250 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched, 251 soft_blowfish_ctx->keysched_len, 252 soft_blowfish_ctx->ivec); 253 254 if (soft_blowfish_ctx->blowfish_cbc == NULL) { 255 freezero(soft_blowfish_ctx->key_sched, 256 soft_blowfish_ctx->keysched_len); 257 freezero(session_p->encrypt.context, 258 sizeof (soft_blowfish_ctx_t)); 259 session_p->encrypt.context = NULL; 260 rv = CKR_HOST_MEMORY; 261 } 262 263 (void) pthread_mutex_unlock(&session_p->session_mutex); 264 265 return (rv); 266 } 267 default: 268 return (CKR_MECHANISM_INVALID); 269 } 270 } 271 272 273 /* 274 * soft_encrypt_common() 275 * 276 * Arguments: 277 * session_p: pointer to soft_session_t struct 278 * pData: pointer to the input data to be encrypted 279 * ulDataLen: length of the input data 280 * pEncrypted: pointer to the output data after encryption 281 * pulEncryptedLen: pointer to the length of the output data 282 * update: boolean flag indicates caller is soft_encrypt 283 * or soft_encrypt_update 284 * 285 * Description: 286 * This function calls the corresponding encrypt routine based 287 * on the mechanism. 288 * 289 * Returns: 290 * see corresponding encrypt routine. 291 */ 292 CK_RV 293 soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, 294 CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted, 295 CK_ULONG_PTR pulEncryptedLen, boolean_t update) 296 { 297 298 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; 299 300 switch (mechanism) { 301 302 case CKM_DES_ECB: 303 case CKM_DES_CBC: 304 case CKM_DES3_ECB: 305 case CKM_DES3_CBC: 306 307 if (ulDataLen == 0) { 308 *pulEncryptedLen = 0; 309 return (CKR_OK); 310 } 311 /* FALLTHROUGH */ 312 313 case CKM_DES_CBC_PAD: 314 case CKM_DES3_CBC_PAD: 315 316 return (soft_des_encrypt_common(session_p, pData, 317 ulDataLen, pEncrypted, pulEncryptedLen, update)); 318 319 case CKM_AES_ECB: 320 case CKM_AES_CBC: 321 case CKM_AES_CBC_PAD: 322 case CKM_AES_CTR: 323 case CKM_AES_CCM: 324 case CKM_AES_CMAC: 325 case CKM_AES_GCM: 326 case CKM_AES_GMAC: 327 if (update) { 328 return (soft_aes_encrypt_update(session_p, pData, 329 ulDataLen, pEncrypted, pulEncryptedLen)); 330 } else { 331 return (soft_aes_encrypt(session_p, pData, 332 ulDataLen, pEncrypted, pulEncryptedLen)); 333 } 334 335 case CKM_BLOWFISH_CBC: 336 337 if (ulDataLen == 0) { 338 *pulEncryptedLen = 0; 339 return (CKR_OK); 340 } 341 342 return (soft_blowfish_encrypt_common(session_p, pData, 343 ulDataLen, pEncrypted, pulEncryptedLen, update)); 344 345 case CKM_RC4: 346 347 if (ulDataLen == 0) { 348 *pulEncryptedLen = 0; 349 return (CKR_OK); 350 } 351 352 return (soft_arcfour_crypt(&(session_p->encrypt), pData, 353 ulDataLen, pEncrypted, pulEncryptedLen)); 354 355 case CKM_RSA_X_509: 356 case CKM_RSA_PKCS: 357 358 return (soft_rsa_encrypt_common(session_p, pData, 359 ulDataLen, pEncrypted, pulEncryptedLen, mechanism)); 360 361 default: 362 return (CKR_MECHANISM_INVALID); 363 } 364 } 365 366 367 /* 368 * soft_encrypt() 369 * 370 * Arguments: 371 * session_p: pointer to soft_session_t struct 372 * pData: pointer to the input data to be encrypted 373 * ulDataLen: length of the input data 374 * pEncryptedData: pointer to the output data after encryption 375 * pulEncryptedDataLen: pointer to the length of the output data 376 * 377 * Description: 378 * called by C_Encrypt(). This function calls the soft_encrypt_common 379 * routine. 380 * 381 * Returns: 382 * see soft_encrypt_common(). 383 */ 384 CK_RV 385 soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData, 386 CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, 387 CK_ULONG_PTR pulEncryptedDataLen) 388 { 389 return (soft_encrypt_common(session_p, pData, ulDataLen, 390 pEncryptedData, pulEncryptedDataLen, B_FALSE)); 391 } 392 393 394 /* 395 * soft_encrypt_update() 396 * 397 * Arguments: 398 * session_p: pointer to soft_session_t struct 399 * pPart: pointer to the input data to be digested 400 * ulPartLen: length of the input data 401 * pEncryptedPart: pointer to the ciphertext 402 * pulEncryptedPartLen: pointer to the length of the ciphertext 403 * 404 * Description: 405 * called by C_EncryptUpdate(). This function calls the 406 * soft_encrypt_common routine (with update flag on). 407 * 408 * Returns: 409 * see soft_encrypt_common(). 410 */ 411 CK_RV 412 soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart, 413 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 414 CK_ULONG_PTR pulEncryptedPartLen) 415 { 416 417 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; 418 419 switch (mechanism) { 420 421 case CKM_DES_ECB: 422 case CKM_DES_CBC: 423 case CKM_DES_CBC_PAD: 424 case CKM_DES3_ECB: 425 case CKM_DES3_CBC: 426 case CKM_DES3_CBC_PAD: 427 case CKM_AES_ECB: 428 case CKM_AES_CBC: 429 case CKM_AES_CBC_PAD: 430 case CKM_AES_CMAC: 431 case CKM_AES_CTR: 432 case CKM_AES_CCM: 433 case CKM_AES_GCM: 434 case CKM_AES_GMAC: 435 case CKM_BLOWFISH_CBC: 436 case CKM_RC4: 437 438 return (soft_encrypt_common(session_p, pPart, ulPartLen, 439 pEncryptedPart, pulEncryptedPartLen, B_TRUE)); 440 441 default: 442 /* PKCS11: The mechanism only supports single-part operation. */ 443 return (CKR_MECHANISM_INVALID); 444 } 445 } 446 447 448 /* 449 * soft_encrypt_final() 450 * 451 * Arguments: 452 * session_p: pointer to soft_session_t struct 453 * pLastEncryptedPart: pointer to the last encrypted data part 454 * pulLastEncryptedPartLen: pointer to the length of the last 455 * encrypted data part 456 * 457 * Description: 458 * called by C_EncryptFinal(). 459 * 460 * Returns: 461 * CKR_OK: success 462 * CKR_FUNCTION_FAILED: encrypt final function failed 463 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length 464 */ 465 CK_RV 466 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart, 467 CK_ULONG_PTR pulLastEncryptedPartLen) 468 { 469 470 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; 471 CK_ULONG out_len; 472 CK_RV rv = CKR_OK; 473 int rc; 474 475 (void) pthread_mutex_lock(&session_p->session_mutex); 476 477 if (session_p->encrypt.context == NULL) { 478 rv = CKR_OPERATION_NOT_INITIALIZED; 479 *pulLastEncryptedPartLen = 0; 480 goto clean1; 481 } 482 switch (mechanism) { 483 484 case CKM_DES_CBC_PAD: 485 case CKM_DES3_CBC_PAD: 486 { 487 soft_des_ctx_t *soft_des_ctx; 488 489 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context; 490 /* 491 * For CKM_DES_CBC_PAD, compute output length with 492 * padding. If the remaining buffer has one block 493 * of data, then output length will be two blocksize of 494 * ciphertext. If the remaining buffer has less than 495 * one block of data, then output length will be 496 * one blocksize. 497 */ 498 if (soft_des_ctx->remain_len == DES_BLOCK_LEN) 499 out_len = 2 * DES_BLOCK_LEN; 500 else 501 out_len = DES_BLOCK_LEN; 502 503 if (pLastEncryptedPart == NULL) { 504 /* 505 * Application asks for the length of the output 506 * buffer to hold the ciphertext. 507 */ 508 *pulLastEncryptedPartLen = out_len; 509 goto clean1; 510 } else { 511 crypto_data_t out; 512 513 /* Copy remaining data to the output buffer. */ 514 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data, 515 soft_des_ctx->remain_len); 516 517 /* 518 * Add padding bytes prior to encrypt final. 519 */ 520 soft_add_pkcs7_padding(pLastEncryptedPart + 521 soft_des_ctx->remain_len, DES_BLOCK_LEN, 522 soft_des_ctx->remain_len); 523 524 out.cd_format = CRYPTO_DATA_RAW; 525 out.cd_offset = 0; 526 out.cd_length = out_len; 527 out.cd_raw.iov_base = (char *)pLastEncryptedPart; 528 out.cd_raw.iov_len = out_len; 529 530 /* Encrypt multiple blocks of data. */ 531 rc = des_encrypt_contiguous_blocks( 532 (des_ctx_t *)soft_des_ctx->des_cbc, 533 (char *)pLastEncryptedPart, out_len, &out); 534 535 if (rc == 0) { 536 *pulLastEncryptedPartLen = out_len; 537 } else { 538 *pulLastEncryptedPartLen = 0; 539 rv = CKR_FUNCTION_FAILED; 540 } 541 542 /* Cleanup memory space. */ 543 free(soft_des_ctx->des_cbc); 544 freezero(soft_des_ctx->key_sched, 545 soft_des_ctx->keysched_len); 546 } 547 548 break; 549 } 550 case CKM_DES_CBC: 551 case CKM_DES_ECB: 552 case CKM_DES3_CBC: 553 case CKM_DES3_ECB: 554 { 555 556 soft_des_ctx_t *soft_des_ctx; 557 558 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context; 559 /* 560 * CKM_DES_CBC and CKM_DES_ECB does not do any padding, 561 * so when the final is called, the remaining buffer 562 * should not contain any more data. 563 */ 564 *pulLastEncryptedPartLen = 0; 565 if (soft_des_ctx->remain_len != 0) { 566 rv = CKR_DATA_LEN_RANGE; 567 } else { 568 if (pLastEncryptedPart == NULL) 569 goto clean1; 570 } 571 572 /* Cleanup memory space. */ 573 free(soft_des_ctx->des_cbc); 574 freezero(soft_des_ctx->key_sched, 575 soft_des_ctx->keysched_len); 576 577 break; 578 } 579 case CKM_AES_CBC: 580 case CKM_AES_CBC_PAD: 581 case CKM_AES_CMAC: 582 case CKM_AES_ECB: 583 case CKM_AES_CTR: 584 case CKM_AES_CCM: 585 case CKM_AES_GCM: 586 case CKM_AES_GMAC: 587 rv = soft_aes_encrypt_final(session_p, pLastEncryptedPart, 588 pulLastEncryptedPartLen); 589 break; 590 591 case CKM_BLOWFISH_CBC: 592 { 593 soft_blowfish_ctx_t *soft_blowfish_ctx; 594 595 soft_blowfish_ctx = 596 (soft_blowfish_ctx_t *)session_p->encrypt.context; 597 /* 598 * CKM_BLOWFISH_CBC does not do any padding, so when the 599 * final is called, the remaining buffer should not contain 600 * any more data 601 */ 602 *pulLastEncryptedPartLen = 0; 603 if (soft_blowfish_ctx->remain_len != 0) 604 rv = CKR_DATA_LEN_RANGE; 605 else { 606 if (pLastEncryptedPart == NULL) 607 goto clean1; 608 } 609 610 free(soft_blowfish_ctx->blowfish_cbc); 611 freezero(soft_blowfish_ctx->key_sched, 612 soft_blowfish_ctx->keysched_len); 613 break; 614 } 615 616 case CKM_RC4: 617 { 618 ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context; 619 /* Remaining data size is always zero for RC4. */ 620 *pulLastEncryptedPartLen = 0; 621 if (pLastEncryptedPart == NULL) 622 goto clean1; 623 explicit_bzero(key, sizeof (*key)); 624 break; 625 } 626 default: 627 /* PKCS11: The mechanism only supports single-part operation. */ 628 rv = CKR_MECHANISM_INVALID; 629 break; 630 } 631 632 free(session_p->encrypt.context); 633 session_p->encrypt.context = NULL; 634 clean1: 635 (void) pthread_mutex_unlock(&session_p->session_mutex); 636 637 return (rv); 638 } 639 640 /* 641 * This function frees the allocated active crypto context and the 642 * lower level of allocated struct as needed. 643 * This function is called by the 1st tier of encrypt/decrypt routines 644 * or by the 2nd tier of session close routine. Since the 1st tier 645 * caller will always call this function without locking the session 646 * mutex and the 2nd tier caller will call with the lock, we add the 647 * third parameter "lock_held" to distinguish this case. 648 */ 649 void 650 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt, 651 boolean_t lock_held) 652 { 653 654 crypto_active_op_t *active_op; 655 boolean_t lock_true = B_TRUE; 656 657 if (!lock_held) 658 (void) pthread_mutex_lock(&session_p->session_mutex); 659 660 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt); 661 662 switch (active_op->mech.mechanism) { 663 664 case CKM_DES_CBC_PAD: 665 case CKM_DES3_CBC_PAD: 666 case CKM_DES_CBC: 667 case CKM_DES_ECB: 668 case CKM_DES3_CBC: 669 case CKM_DES3_ECB: 670 { 671 672 soft_des_ctx_t *soft_des_ctx = 673 (soft_des_ctx_t *)active_op->context; 674 des_ctx_t *des_ctx; 675 676 if (soft_des_ctx != NULL) { 677 des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc; 678 if (des_ctx != NULL) { 679 explicit_bzero(des_ctx->dc_keysched, 680 des_ctx->dc_keysched_len); 681 free(soft_des_ctx->des_cbc); 682 } 683 freezero(soft_des_ctx->key_sched, 684 soft_des_ctx->keysched_len); 685 } 686 break; 687 } 688 689 case CKM_AES_CBC: 690 case CKM_AES_CBC_PAD: 691 case CKM_AES_CMAC: 692 case CKM_AES_ECB: 693 case CKM_AES_CTR: 694 case CKM_AES_CCM: 695 case CKM_AES_GCM: 696 case CKM_AES_GMAC: 697 soft_aes_free_ctx(active_op->context); 698 active_op->context = NULL; 699 break; 700 701 case CKM_BLOWFISH_CBC: 702 { 703 soft_blowfish_ctx_t *soft_blowfish_ctx = 704 (soft_blowfish_ctx_t *)active_op->context; 705 blowfish_ctx_t *blowfish_ctx; 706 707 if (soft_blowfish_ctx != NULL) { 708 blowfish_ctx = 709 (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc; 710 if (blowfish_ctx != NULL) { 711 explicit_bzero(blowfish_ctx->bc_keysched, 712 blowfish_ctx->bc_keysched_len); 713 free(soft_blowfish_ctx->blowfish_cbc); 714 } 715 716 freezero(soft_blowfish_ctx->key_sched, 717 soft_blowfish_ctx->keysched_len); 718 } 719 break; 720 } 721 722 case CKM_RC4: 723 { 724 ARCFour_key *key = (ARCFour_key *)active_op->context; 725 726 if (key != NULL) 727 explicit_bzero(key, sizeof (*key)); 728 break; 729 } 730 731 case CKM_RSA_X_509: 732 case CKM_RSA_PKCS: 733 { 734 soft_rsa_ctx_t *rsa_ctx = 735 (soft_rsa_ctx_t *)active_op->context; 736 737 if (rsa_ctx != NULL) 738 if (rsa_ctx->key != NULL) { 739 soft_cleanup_object(rsa_ctx->key); 740 free(rsa_ctx->key); 741 } 742 743 break; 744 } 745 746 } /* switch */ 747 748 if (active_op->context != NULL) { 749 free(active_op->context); 750 active_op->context = NULL; 751 } 752 753 active_op->flags = 0; 754 755 if (!lock_held) 756 SES_REFRELE(session_p, lock_true); 757 } 758