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 return (soft_aes_crypt_init_common(session_p, pMechanism, 201 key_p, B_TRUE)); 202 203 case CKM_RC4: 204 205 if (key_p->key_type != CKK_RC4) { 206 return (CKR_KEY_TYPE_INCONSISTENT); 207 } 208 209 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p, 210 B_TRUE)); 211 212 case CKM_RSA_X_509: 213 case CKM_RSA_PKCS: 214 215 if (key_p->key_type != CKK_RSA) { 216 return (CKR_KEY_TYPE_INCONSISTENT); 217 } 218 219 return (soft_rsa_crypt_init_common(session_p, pMechanism, 220 key_p, B_TRUE)); 221 222 case CKM_BLOWFISH_CBC: 223 { 224 soft_blowfish_ctx_t *soft_blowfish_ctx; 225 226 if (key_p->key_type != CKK_BLOWFISH) 227 return (CKR_KEY_TYPE_INCONSISTENT); 228 229 if ((pMechanism->pParameter == NULL) || 230 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN)) 231 return (CKR_MECHANISM_PARAM_INVALID); 232 233 rv = soft_blowfish_crypt_init_common(session_p, pMechanism, 234 key_p, B_TRUE); 235 236 if (rv != CKR_OK) 237 return (rv); 238 239 (void) pthread_mutex_lock(&session_p->session_mutex); 240 241 soft_blowfish_ctx = 242 (soft_blowfish_ctx_t *)session_p->encrypt.context; 243 /* Copy Initialization Vector (IV) into the context. */ 244 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter, 245 BLOWFISH_BLOCK_LEN); 246 247 /* Allocate a context for Blowfish cipher-block chaining */ 248 soft_blowfish_ctx->blowfish_cbc = 249 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched, 250 soft_blowfish_ctx->keysched_len, 251 soft_blowfish_ctx->ivec); 252 253 if (soft_blowfish_ctx->blowfish_cbc == NULL) { 254 freezero(soft_blowfish_ctx->key_sched, 255 soft_blowfish_ctx->keysched_len); 256 freezero(session_p->encrypt.context, 257 sizeof (soft_blowfish_ctx_t)); 258 session_p->encrypt.context = NULL; 259 rv = CKR_HOST_MEMORY; 260 } 261 262 (void) pthread_mutex_unlock(&session_p->session_mutex); 263 264 return (rv); 265 } 266 default: 267 return (CKR_MECHANISM_INVALID); 268 } 269 } 270 271 272 /* 273 * soft_encrypt_common() 274 * 275 * Arguments: 276 * session_p: pointer to soft_session_t struct 277 * pData: pointer to the input data to be encrypted 278 * ulDataLen: length of the input data 279 * pEncrypted: pointer to the output data after encryption 280 * pulEncryptedLen: pointer to the length of the output data 281 * update: boolean flag indicates caller is soft_encrypt 282 * or soft_encrypt_update 283 * 284 * Description: 285 * This function calls the corresponding encrypt routine based 286 * on the mechanism. 287 * 288 * Returns: 289 * see corresponding encrypt routine. 290 */ 291 CK_RV 292 soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData, 293 CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted, 294 CK_ULONG_PTR pulEncryptedLen, boolean_t update) 295 { 296 297 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; 298 299 switch (mechanism) { 300 301 case CKM_DES_ECB: 302 case CKM_DES_CBC: 303 case CKM_DES3_ECB: 304 case CKM_DES3_CBC: 305 306 if (ulDataLen == 0) { 307 *pulEncryptedLen = 0; 308 return (CKR_OK); 309 } 310 /* FALLTHROUGH */ 311 312 case CKM_DES_CBC_PAD: 313 case CKM_DES3_CBC_PAD: 314 315 return (soft_des_encrypt_common(session_p, pData, 316 ulDataLen, pEncrypted, pulEncryptedLen, update)); 317 318 case CKM_AES_ECB: 319 case CKM_AES_CBC: 320 case CKM_AES_CTR: 321 case CKM_AES_CCM: 322 case CKM_AES_CMAC: 323 case CKM_AES_CBC_PAD: 324 case CKM_AES_GCM: 325 if (update) { 326 return (soft_aes_encrypt_update(session_p, pData, 327 ulDataLen, pEncrypted, pulEncryptedLen)); 328 } else { 329 return (soft_aes_encrypt(session_p, pData, 330 ulDataLen, pEncrypted, pulEncryptedLen)); 331 } 332 333 case CKM_BLOWFISH_CBC: 334 335 if (ulDataLen == 0) { 336 *pulEncryptedLen = 0; 337 return (CKR_OK); 338 } 339 340 return (soft_blowfish_encrypt_common(session_p, pData, 341 ulDataLen, pEncrypted, pulEncryptedLen, update)); 342 343 case CKM_RC4: 344 345 if (ulDataLen == 0) { 346 *pulEncryptedLen = 0; 347 return (CKR_OK); 348 } 349 350 return (soft_arcfour_crypt(&(session_p->encrypt), pData, 351 ulDataLen, pEncrypted, pulEncryptedLen)); 352 353 case CKM_RSA_X_509: 354 case CKM_RSA_PKCS: 355 356 return (soft_rsa_encrypt_common(session_p, pData, 357 ulDataLen, pEncrypted, pulEncryptedLen, mechanism)); 358 359 default: 360 return (CKR_MECHANISM_INVALID); 361 } 362 } 363 364 365 /* 366 * soft_encrypt() 367 * 368 * Arguments: 369 * session_p: pointer to soft_session_t struct 370 * pData: pointer to the input data to be encrypted 371 * ulDataLen: length of the input data 372 * pEncryptedData: pointer to the output data after encryption 373 * pulEncryptedDataLen: pointer to the length of the output data 374 * 375 * Description: 376 * called by C_Encrypt(). This function calls the soft_encrypt_common 377 * routine. 378 * 379 * Returns: 380 * see soft_encrypt_common(). 381 */ 382 CK_RV 383 soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData, 384 CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, 385 CK_ULONG_PTR pulEncryptedDataLen) 386 { 387 return (soft_encrypt_common(session_p, pData, ulDataLen, 388 pEncryptedData, pulEncryptedDataLen, B_FALSE)); 389 } 390 391 392 /* 393 * soft_encrypt_update() 394 * 395 * Arguments: 396 * session_p: pointer to soft_session_t struct 397 * pPart: pointer to the input data to be digested 398 * ulPartLen: length of the input data 399 * pEncryptedPart: pointer to the ciphertext 400 * pulEncryptedPartLen: pointer to the length of the ciphertext 401 * 402 * Description: 403 * called by C_EncryptUpdate(). This function calls the 404 * soft_encrypt_common routine (with update flag on). 405 * 406 * Returns: 407 * see soft_encrypt_common(). 408 */ 409 CK_RV 410 soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart, 411 CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart, 412 CK_ULONG_PTR pulEncryptedPartLen) 413 { 414 415 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; 416 417 switch (mechanism) { 418 419 case CKM_DES_ECB: 420 case CKM_DES_CBC: 421 case CKM_DES_CBC_PAD: 422 case CKM_DES3_ECB: 423 case CKM_DES3_CBC: 424 case CKM_DES3_CBC_PAD: 425 case CKM_AES_ECB: 426 case CKM_AES_CBC: 427 case CKM_AES_CBC_PAD: 428 case CKM_AES_CMAC: 429 case CKM_AES_CTR: 430 case CKM_AES_GCM: 431 case CKM_AES_CCM: 432 case CKM_BLOWFISH_CBC: 433 case CKM_RC4: 434 435 return (soft_encrypt_common(session_p, pPart, ulPartLen, 436 pEncryptedPart, pulEncryptedPartLen, B_TRUE)); 437 438 default: 439 /* PKCS11: The mechanism only supports single-part operation. */ 440 return (CKR_MECHANISM_INVALID); 441 } 442 } 443 444 445 /* 446 * soft_encrypt_final() 447 * 448 * Arguments: 449 * session_p: pointer to soft_session_t struct 450 * pLastEncryptedPart: pointer to the last encrypted data part 451 * pulLastEncryptedPartLen: pointer to the length of the last 452 * encrypted data part 453 * 454 * Description: 455 * called by C_EncryptFinal(). 456 * 457 * Returns: 458 * CKR_OK: success 459 * CKR_FUNCTION_FAILED: encrypt final function failed 460 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length 461 */ 462 CK_RV 463 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart, 464 CK_ULONG_PTR pulLastEncryptedPartLen) 465 { 466 467 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism; 468 CK_ULONG out_len; 469 CK_RV rv = CKR_OK; 470 int rc; 471 472 (void) pthread_mutex_lock(&session_p->session_mutex); 473 474 if (session_p->encrypt.context == NULL) { 475 rv = CKR_OPERATION_NOT_INITIALIZED; 476 *pulLastEncryptedPartLen = 0; 477 goto clean1; 478 } 479 switch (mechanism) { 480 481 case CKM_DES_CBC_PAD: 482 case CKM_DES3_CBC_PAD: 483 { 484 soft_des_ctx_t *soft_des_ctx; 485 486 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context; 487 /* 488 * For CKM_DES_CBC_PAD, compute output length with 489 * padding. If the remaining buffer has one block 490 * of data, then output length will be two blocksize of 491 * ciphertext. If the remaining buffer has less than 492 * one block of data, then output length will be 493 * one blocksize. 494 */ 495 if (soft_des_ctx->remain_len == DES_BLOCK_LEN) 496 out_len = 2 * DES_BLOCK_LEN; 497 else 498 out_len = DES_BLOCK_LEN; 499 500 if (pLastEncryptedPart == NULL) { 501 /* 502 * Application asks for the length of the output 503 * buffer to hold the ciphertext. 504 */ 505 *pulLastEncryptedPartLen = out_len; 506 goto clean1; 507 } else { 508 crypto_data_t out; 509 510 /* Copy remaining data to the output buffer. */ 511 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data, 512 soft_des_ctx->remain_len); 513 514 /* 515 * Add padding bytes prior to encrypt final. 516 */ 517 soft_add_pkcs7_padding(pLastEncryptedPart + 518 soft_des_ctx->remain_len, DES_BLOCK_LEN, 519 soft_des_ctx->remain_len); 520 521 out.cd_format = CRYPTO_DATA_RAW; 522 out.cd_offset = 0; 523 out.cd_length = out_len; 524 out.cd_raw.iov_base = (char *)pLastEncryptedPart; 525 out.cd_raw.iov_len = out_len; 526 527 /* Encrypt multiple blocks of data. */ 528 rc = des_encrypt_contiguous_blocks( 529 (des_ctx_t *)soft_des_ctx->des_cbc, 530 (char *)pLastEncryptedPart, out_len, &out); 531 532 if (rc == 0) { 533 *pulLastEncryptedPartLen = out_len; 534 } else { 535 *pulLastEncryptedPartLen = 0; 536 rv = CKR_FUNCTION_FAILED; 537 } 538 539 /* Cleanup memory space. */ 540 free(soft_des_ctx->des_cbc); 541 freezero(soft_des_ctx->key_sched, 542 soft_des_ctx->keysched_len); 543 } 544 545 break; 546 } 547 case CKM_DES_CBC: 548 case CKM_DES_ECB: 549 case CKM_DES3_CBC: 550 case CKM_DES3_ECB: 551 { 552 553 soft_des_ctx_t *soft_des_ctx; 554 555 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context; 556 /* 557 * CKM_DES_CBC and CKM_DES_ECB does not do any padding, 558 * so when the final is called, the remaining buffer 559 * should not contain any more data. 560 */ 561 *pulLastEncryptedPartLen = 0; 562 if (soft_des_ctx->remain_len != 0) { 563 rv = CKR_DATA_LEN_RANGE; 564 } else { 565 if (pLastEncryptedPart == NULL) 566 goto clean1; 567 } 568 569 /* Cleanup memory space. */ 570 free(soft_des_ctx->des_cbc); 571 freezero(soft_des_ctx->key_sched, 572 soft_des_ctx->keysched_len); 573 574 break; 575 } 576 case CKM_AES_CBC_PAD: 577 case CKM_AES_CMAC: 578 case CKM_AES_CBC: 579 case CKM_AES_ECB: 580 case CKM_AES_CTR: 581 case CKM_AES_CCM: 582 case CKM_AES_GCM: 583 rv = soft_aes_encrypt_final(session_p, pLastEncryptedPart, 584 pulLastEncryptedPartLen); 585 break; 586 587 case CKM_BLOWFISH_CBC: 588 { 589 soft_blowfish_ctx_t *soft_blowfish_ctx; 590 591 soft_blowfish_ctx = 592 (soft_blowfish_ctx_t *)session_p->encrypt.context; 593 /* 594 * CKM_BLOWFISH_CBC does not do any padding, so when the 595 * final is called, the remaining buffer should not contain 596 * any more data 597 */ 598 *pulLastEncryptedPartLen = 0; 599 if (soft_blowfish_ctx->remain_len != 0) 600 rv = CKR_DATA_LEN_RANGE; 601 else { 602 if (pLastEncryptedPart == NULL) 603 goto clean1; 604 } 605 606 free(soft_blowfish_ctx->blowfish_cbc); 607 freezero(soft_blowfish_ctx->key_sched, 608 soft_blowfish_ctx->keysched_len); 609 break; 610 } 611 612 case CKM_RC4: 613 { 614 ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context; 615 /* Remaining data size is always zero for RC4. */ 616 *pulLastEncryptedPartLen = 0; 617 if (pLastEncryptedPart == NULL) 618 goto clean1; 619 explicit_bzero(key, sizeof (*key)); 620 break; 621 } 622 default: 623 /* PKCS11: The mechanism only supports single-part operation. */ 624 rv = CKR_MECHANISM_INVALID; 625 break; 626 } 627 628 free(session_p->encrypt.context); 629 session_p->encrypt.context = NULL; 630 clean1: 631 (void) pthread_mutex_unlock(&session_p->session_mutex); 632 633 return (rv); 634 } 635 636 /* 637 * This function frees the allocated active crypto context and the 638 * lower level of allocated struct as needed. 639 * This function is called by the 1st tier of encrypt/decrypt routines 640 * or by the 2nd tier of session close routine. Since the 1st tier 641 * caller will always call this function without locking the session 642 * mutex and the 2nd tier caller will call with the lock, we add the 643 * third parameter "lock_held" to distinguish this case. 644 */ 645 void 646 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt, 647 boolean_t lock_held) 648 { 649 650 crypto_active_op_t *active_op; 651 boolean_t lock_true = B_TRUE; 652 653 if (!lock_held) 654 (void) pthread_mutex_lock(&session_p->session_mutex); 655 656 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt); 657 658 switch (active_op->mech.mechanism) { 659 660 case CKM_DES_CBC_PAD: 661 case CKM_DES3_CBC_PAD: 662 case CKM_DES_CBC: 663 case CKM_DES_ECB: 664 case CKM_DES3_CBC: 665 case CKM_DES3_ECB: 666 { 667 668 soft_des_ctx_t *soft_des_ctx = 669 (soft_des_ctx_t *)active_op->context; 670 des_ctx_t *des_ctx; 671 672 if (soft_des_ctx != NULL) { 673 des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc; 674 if (des_ctx != NULL) { 675 explicit_bzero(des_ctx->dc_keysched, 676 des_ctx->dc_keysched_len); 677 free(soft_des_ctx->des_cbc); 678 } 679 freezero(soft_des_ctx->key_sched, 680 soft_des_ctx->keysched_len); 681 } 682 break; 683 } 684 685 case CKM_AES_CBC_PAD: 686 case CKM_AES_CBC: 687 case CKM_AES_CMAC: 688 case CKM_AES_ECB: 689 case CKM_AES_GCM: 690 case CKM_AES_CCM: 691 case CKM_AES_CTR: 692 soft_aes_free_ctx(active_op->context); 693 active_op->context = NULL; 694 break; 695 696 case CKM_BLOWFISH_CBC: 697 { 698 soft_blowfish_ctx_t *soft_blowfish_ctx = 699 (soft_blowfish_ctx_t *)active_op->context; 700 blowfish_ctx_t *blowfish_ctx; 701 702 if (soft_blowfish_ctx != NULL) { 703 blowfish_ctx = 704 (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc; 705 if (blowfish_ctx != NULL) { 706 explicit_bzero(blowfish_ctx->bc_keysched, 707 blowfish_ctx->bc_keysched_len); 708 free(soft_blowfish_ctx->blowfish_cbc); 709 } 710 711 freezero(soft_blowfish_ctx->key_sched, 712 soft_blowfish_ctx->keysched_len); 713 } 714 break; 715 } 716 717 case CKM_RC4: 718 { 719 ARCFour_key *key = (ARCFour_key *)active_op->context; 720 721 if (key != NULL) 722 explicit_bzero(key, sizeof (*key)); 723 break; 724 } 725 726 case CKM_RSA_X_509: 727 case CKM_RSA_PKCS: 728 { 729 soft_rsa_ctx_t *rsa_ctx = 730 (soft_rsa_ctx_t *)active_op->context; 731 732 if (rsa_ctx != NULL) 733 if (rsa_ctx->key != NULL) { 734 soft_cleanup_object(rsa_ctx->key); 735 free(rsa_ctx->key); 736 } 737 738 break; 739 } 740 741 } /* switch */ 742 743 if (active_op->context != NULL) { 744 free(active_op->context); 745 active_op->context = NULL; 746 } 747 748 active_op->flags = 0; 749 750 if (!lock_held) 751 SES_REFRELE(session_p, lock_true); 752 } 753