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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <pthread.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include <strings.h> 32 #include <sys/types.h> 33 #include <security/cryptoki.h> 34 #include <des_cbc_crypt.h> 35 #include <aes_cbc_crypt.h> 36 #include <blowfish_cbc_crypt.h> 37 #include <arcfour.h> 38 #include "softSession.h" 39 #include "softObject.h" 40 #include "softOps.h" 41 #include "softCrypt.h" 42 #include "softRSA.h" 43 44 45 /* 46 * Remove padding bytes. 47 */ 48 CK_RV 49 soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len, 50 CK_ULONG *pulDataLen, int block_size) 51 { 52 53 CK_BYTE pad_value; 54 55 pad_value = pData[padded_len - 1]; 56 57 58 /* Make sure there is a valid padding value. */ 59 if ((pad_value == 0) || (pad_value > block_size)) 60 return (CKR_ENCRYPTED_DATA_INVALID); 61 62 *pulDataLen = padded_len - pad_value; 63 return (CKR_OK); 64 } 65 66 67 /* 68 * soft_decrypt_init() 69 * 70 * Arguments: 71 * session_p: pointer to soft_session_t struct 72 * pMechanism: pointer to CK_MECHANISM struct provided by application 73 * key_p: pointer to key soft_object_t struct 74 * 75 * Description: 76 * called by C_DecryptInit(). This function calls the corresponding 77 * decrypt init routine based on the mechanism. 78 * 79 * Returns: 80 * CKR_OK: success 81 * CKR_HOST_MEMORY: run out of system memory 82 * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism 83 * CKR_MECHANISM_INVALID: invalid mechanism type 84 * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use 85 * with the specified mechanism 86 */ 87 CK_RV 88 soft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism, 89 soft_object_t *key_p) 90 { 91 92 CK_RV rv; 93 94 switch (pMechanism->mechanism) { 95 96 case CKM_DES_ECB: 97 98 if (key_p->key_type != CKK_DES) { 99 return (CKR_KEY_TYPE_INCONSISTENT); 100 } 101 102 goto ecb_common; 103 104 case CKM_DES3_ECB: 105 106 if ((key_p->key_type != CKK_DES2) && 107 (key_p->key_type != CKK_DES3)) { 108 return (CKR_KEY_TYPE_INCONSISTENT); 109 } 110 111 ecb_common: 112 113 return (soft_des_crypt_init_common(session_p, pMechanism, 114 key_p, B_FALSE)); 115 116 case CKM_DES_CBC: 117 case CKM_DES_CBC_PAD: 118 119 if (key_p->key_type != CKK_DES) { 120 return (CKR_KEY_TYPE_INCONSISTENT); 121 } 122 123 goto cbc_common; 124 125 case CKM_DES3_CBC: 126 case CKM_DES3_CBC_PAD: 127 { 128 soft_des_ctx_t *soft_des_ctx; 129 130 if ((key_p->key_type != CKK_DES2) && 131 (key_p->key_type != CKK_DES3)) { 132 return (CKR_KEY_TYPE_INCONSISTENT); 133 } 134 135 cbc_common: 136 if ((pMechanism->pParameter == NULL) || 137 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) { 138 return (CKR_MECHANISM_PARAM_INVALID); 139 } 140 141 rv = soft_des_crypt_init_common(session_p, pMechanism, 142 key_p, B_FALSE); 143 144 if (rv != CKR_OK) 145 return (rv); 146 147 (void) pthread_mutex_lock(&session_p->session_mutex); 148 149 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 150 /* Save Initialization Vector (IV) in the context. */ 151 (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter, 152 DES_BLOCK_LEN); 153 154 /* Allocate a context for DES cipher-block chaining. */ 155 soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init( 156 soft_des_ctx->key_sched, soft_des_ctx->keysched_len, 157 soft_des_ctx->ivec, key_p->key_type); 158 159 if (soft_des_ctx->des_cbc == NULL) { 160 bzero(soft_des_ctx->key_sched, 161 soft_des_ctx->keysched_len); 162 free(soft_des_ctx->key_sched); 163 free(session_p->decrypt.context); 164 session_p->decrypt.context = NULL; 165 (void) pthread_mutex_unlock(&session_p->session_mutex); 166 return (CKR_HOST_MEMORY); 167 } 168 169 (void) pthread_mutex_unlock(&session_p->session_mutex); 170 171 return (rv); 172 } 173 case CKM_AES_ECB: 174 175 if (key_p->key_type != CKK_AES) { 176 return (CKR_KEY_TYPE_INCONSISTENT); 177 } 178 179 return (soft_aes_crypt_init_common(session_p, pMechanism, 180 key_p, B_FALSE)); 181 182 case CKM_AES_CBC: 183 case CKM_AES_CBC_PAD: 184 { 185 soft_aes_ctx_t *soft_aes_ctx; 186 187 if (key_p->key_type != CKK_AES) { 188 return (CKR_KEY_TYPE_INCONSISTENT); 189 } 190 191 if ((pMechanism->pParameter == NULL) || 192 (pMechanism->ulParameterLen != AES_BLOCK_LEN)) { 193 return (CKR_MECHANISM_PARAM_INVALID); 194 } 195 196 rv = soft_aes_crypt_init_common(session_p, pMechanism, 197 key_p, B_FALSE); 198 199 if (rv != CKR_OK) 200 return (rv); 201 202 (void) pthread_mutex_lock(&session_p->session_mutex); 203 204 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 205 206 /* Save Initialization Vector (IV) in the context. */ 207 (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter, 208 AES_BLOCK_LEN); 209 210 /* Allocate a context for AES cipher-block chaining. */ 211 soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init( 212 soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len, 213 soft_aes_ctx->ivec); 214 215 if (soft_aes_ctx->aes_cbc == NULL) { 216 bzero(soft_aes_ctx->key_sched, 217 soft_aes_ctx->keysched_len); 218 free(soft_aes_ctx->key_sched); 219 free(session_p->decrypt.context); 220 session_p->decrypt.context = NULL; 221 (void) pthread_mutex_unlock(&session_p->session_mutex); 222 return (CKR_HOST_MEMORY); 223 } 224 225 (void) pthread_mutex_unlock(&session_p->session_mutex); 226 227 return (rv); 228 } 229 230 case CKM_BLOWFISH_CBC: 231 { 232 soft_blowfish_ctx_t *soft_blowfish_ctx; 233 234 if (key_p->key_type != CKK_BLOWFISH) 235 return (CKR_KEY_TYPE_INCONSISTENT); 236 237 if ((pMechanism->pParameter == NULL) || 238 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN)) 239 return (CKR_MECHANISM_PARAM_INVALID); 240 241 rv = soft_blowfish_crypt_init_common(session_p, pMechanism, 242 key_p, B_FALSE); 243 244 if (rv != CKR_OK) 245 return (rv); 246 247 (void) pthread_mutex_lock(&session_p->session_mutex); 248 249 soft_blowfish_ctx = 250 (soft_blowfish_ctx_t *)session_p->decrypt.context; 251 252 /* Save Initialization Vector in the context. */ 253 (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter, 254 BLOWFISH_BLOCK_LEN); 255 256 /* Allocate a context for CBC */ 257 soft_blowfish_ctx->blowfish_cbc = 258 (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched, 259 soft_blowfish_ctx->keysched_len, 260 soft_blowfish_ctx->ivec); 261 262 if (soft_blowfish_ctx->blowfish_cbc == NULL) { 263 bzero(soft_blowfish_ctx->key_sched, 264 soft_blowfish_ctx->keysched_len); 265 free(soft_blowfish_ctx->key_sched); 266 free(session_p->decrypt.context = NULL); 267 (void) pthread_mutex_unlock(&session_p->session_mutex); 268 return (CKR_HOST_MEMORY); 269 } 270 271 (void) pthread_mutex_unlock(&session_p->session_mutex); 272 return (rv); 273 } 274 275 case CKM_RC4: 276 277 if (key_p->key_type != CKK_RC4) { 278 return (CKR_KEY_TYPE_INCONSISTENT); 279 } 280 281 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p, 282 B_FALSE)); 283 284 case CKM_RSA_X_509: 285 case CKM_RSA_PKCS: 286 287 if (key_p->key_type != CKK_RSA) { 288 return (CKR_KEY_TYPE_INCONSISTENT); 289 } 290 291 return (soft_rsa_crypt_init_common(session_p, pMechanism, 292 key_p, B_FALSE)); 293 294 default: 295 return (CKR_MECHANISM_INVALID); 296 } 297 } 298 299 300 /* 301 * soft_decrypt_common() 302 * 303 * Arguments: 304 * session_p: pointer to soft_session_t struct 305 * pEncrypted: pointer to the encrypted data as input 306 * ulEncryptedLen: length of the input data 307 * pData: pointer to the output data contains plaintext 308 * pulDataLen: pointer to the length of the output data 309 * Update: boolean flag indicates caller is soft_decrypt 310 * or soft_decrypt_update 311 * 312 * Description: 313 * This function calls the corresponding decrypt routine based 314 * on the mechanism. 315 * 316 * Returns: 317 * see soft_decrypt_common(). 318 */ 319 CK_RV 320 soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted, 321 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData, 322 CK_ULONG_PTR pulDataLen, boolean_t Update) 323 { 324 325 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 326 327 switch (mechanism) { 328 329 case CKM_DES_ECB: 330 case CKM_DES_CBC: 331 case CKM_DES3_ECB: 332 case CKM_DES3_CBC: 333 334 if (ulEncryptedLen == 0) { 335 *pulDataLen = 0; 336 return (CKR_OK); 337 } 338 /* FALLTHROUGH */ 339 340 case CKM_DES_CBC_PAD: 341 case CKM_DES3_CBC_PAD: 342 343 return (soft_des_decrypt_common(session_p, pEncrypted, 344 ulEncryptedLen, pData, pulDataLen, Update)); 345 346 case CKM_AES_ECB: 347 case CKM_AES_CBC: 348 349 if (ulEncryptedLen == 0) { 350 *pulDataLen = 0; 351 return (CKR_OK); 352 } 353 /* FALLTHROUGH */ 354 355 case CKM_AES_CBC_PAD: 356 357 return (soft_aes_decrypt_common(session_p, pEncrypted, 358 ulEncryptedLen, pData, pulDataLen, Update)); 359 360 case CKM_BLOWFISH_CBC: 361 362 if (ulEncryptedLen == 0) { 363 *pulDataLen = 0; 364 return (CKR_OK); 365 } 366 367 return (soft_blowfish_decrypt_common(session_p, pEncrypted, 368 ulEncryptedLen, pData, pulDataLen, Update)); 369 370 case CKM_RC4: 371 372 if (ulEncryptedLen == 0) { 373 *pulDataLen = 0; 374 return (CKR_OK); 375 } 376 377 378 return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted, 379 ulEncryptedLen, pData, pulDataLen)); 380 381 case CKM_RSA_X_509: 382 case CKM_RSA_PKCS: 383 384 return (soft_rsa_decrypt_common(session_p, pEncrypted, 385 ulEncryptedLen, pData, pulDataLen, mechanism)); 386 387 default: 388 return (CKR_MECHANISM_INVALID); 389 390 } 391 } 392 393 394 /* 395 * soft_decrypt() 396 * 397 * Arguments: 398 * session_p: pointer to soft_session_t struct 399 * pEncryptedData: pointer to the encrypted data as input 400 * ulEncryptedDataLen: length of the input data 401 * pData: pointer to the output data contains plaintext 402 * pulDataLen: pointer to the length of the output data 403 * 404 * Description: 405 * called by C_Decrypt(). This function calls the soft_decrypt_common 406 * routine. 407 * 408 * Returns: 409 * see soft_decrypt_common(). 410 */ 411 CK_RV 412 soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData, 413 CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, 414 CK_ULONG_PTR pulDataLen) 415 { 416 417 return (soft_decrypt_common(session_p, pEncryptedData, 418 ulEncryptedDataLen, pData, pulDataLen, B_FALSE)); 419 } 420 421 422 /* 423 * soft_decrypt_update() 424 * 425 * Arguments: 426 * session_p: pointer to soft_session_t struct 427 * pEncryptedPart: pointer to the encrypted data as input 428 * ulEncryptedPartLen: length of the input data 429 * pPart: pointer to the output data contains plaintext 430 * pulPartLen: pointer to the length of the output data 431 * 432 * Description: 433 * called by C_DecryptUpdate(). This function calls the 434 * soft_decrypt_common routine (with update flag on). 435 * 436 * Returns: 437 * see soft_decrypt_common(). 438 */ 439 CK_RV 440 soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart, 441 CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, 442 CK_ULONG_PTR pulPartLen) 443 { 444 445 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 446 447 switch (mechanism) { 448 449 case CKM_DES_ECB: 450 case CKM_DES_CBC: 451 case CKM_DES_CBC_PAD: 452 case CKM_DES3_ECB: 453 case CKM_DES3_CBC: 454 case CKM_DES3_CBC_PAD: 455 case CKM_AES_ECB: 456 case CKM_AES_CBC: 457 case CKM_AES_CBC_PAD: 458 case CKM_BLOWFISH_CBC: 459 case CKM_RC4: 460 461 return (soft_decrypt_common(session_p, pEncryptedPart, 462 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE)); 463 464 default: 465 /* PKCS11: The mechanism only supports single-part operation. */ 466 return (CKR_MECHANISM_INVALID); 467 } 468 469 } 470 471 472 /* 473 * soft_decrypt_final() 474 * 475 * Arguments: 476 * session_p: pointer to soft_session_t struct 477 * pLastPart: pointer to the last recovered data part 478 * pulLastPartLen: pointer to the length of the last recovered data part 479 * 480 * Description: 481 * called by C_DecryptFinal(). 482 * 483 * Returns: 484 * CKR_OK: success 485 * CKR_FUNCTION_FAILED: decrypt final function failed 486 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length 487 */ 488 CK_RV 489 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart, 490 CK_ULONG_PTR pulLastPartLen) 491 { 492 493 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 494 CK_ULONG out_len; 495 CK_RV rv = CKR_OK; 496 int rc; 497 498 (void) pthread_mutex_lock(&session_p->session_mutex); 499 500 if (session_p->decrypt.context == NULL) { 501 rv = CKR_OPERATION_NOT_INITIALIZED; 502 *pulLastPartLen = 0; 503 goto clean2; 504 } 505 switch (mechanism) { 506 507 case CKM_DES_CBC_PAD: 508 case CKM_DES3_CBC_PAD: 509 { 510 511 soft_des_ctx_t *soft_des_ctx; 512 513 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 514 515 /* 516 * We should have only one block of data left in the 517 * remaining buffer. 518 */ 519 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) { 520 *pulLastPartLen = 0; 521 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 522 /* Cleanup memory space. */ 523 free(soft_des_ctx->des_cbc); 524 bzero(soft_des_ctx->key_sched, 525 soft_des_ctx->keysched_len); 526 free(soft_des_ctx->key_sched); 527 528 goto clean1; 529 } 530 531 out_len = DES_BLOCK_LEN; 532 533 /* 534 * If application asks for the length of the output buffer 535 * to hold the plaintext? 536 */ 537 if (pLastPart == NULL) { 538 *pulLastPartLen = out_len; 539 rv = CKR_OK; 540 goto clean2; 541 } else { 542 crypto_data_t out; 543 544 /* Copy remaining data to the output buffer. */ 545 (void) memcpy(pLastPart, soft_des_ctx->data, 546 DES_BLOCK_LEN); 547 548 out.cd_format = CRYPTO_DATA_RAW; 549 out.cd_offset = 0; 550 out.cd_length = DES_BLOCK_LEN; 551 out.cd_raw.iov_base = (char *)pLastPart; 552 out.cd_raw.iov_len = DES_BLOCK_LEN; 553 554 /* Decrypt final block of data. */ 555 rc = des_decrypt_contiguous_blocks( 556 (des_ctx_t *)soft_des_ctx->des_cbc, 557 (char *)pLastPart, DES_BLOCK_LEN, &out); 558 559 if (rc == 0) { 560 /* 561 * Remove padding bytes after decryption of 562 * ciphertext block to produce the original 563 * plaintext. 564 */ 565 rv = soft_remove_pkcs7_padding(pLastPart, 566 DES_BLOCK_LEN, &out_len, DES_BLOCK_LEN); 567 if (rv != CKR_OK) 568 *pulLastPartLen = 0; 569 else 570 *pulLastPartLen = out_len; 571 } else { 572 *pulLastPartLen = 0; 573 rv = CKR_FUNCTION_FAILED; 574 } 575 576 /* Cleanup memory space. */ 577 free(soft_des_ctx->des_cbc); 578 bzero(soft_des_ctx->key_sched, 579 soft_des_ctx->keysched_len); 580 free(soft_des_ctx->key_sched); 581 582 } 583 584 break; 585 } 586 587 case CKM_DES_CBC: 588 case CKM_DES_ECB: 589 case CKM_DES3_CBC: 590 case CKM_DES3_ECB: 591 { 592 593 soft_des_ctx_t *soft_des_ctx; 594 595 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 596 /* 597 * CKM_DES_CBC and CKM_DES_ECB does not do any padding, 598 * so when the final is called, the remaining buffer 599 * should not contain any more data. 600 */ 601 *pulLastPartLen = 0; 602 if (soft_des_ctx->remain_len != 0) { 603 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 604 } else { 605 if (pLastPart == NULL) 606 goto clean2; 607 } 608 609 /* Cleanup memory space. */ 610 free(soft_des_ctx->des_cbc); 611 bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len); 612 free(soft_des_ctx->key_sched); 613 614 break; 615 } 616 617 case CKM_AES_CBC_PAD: 618 { 619 620 soft_aes_ctx_t *soft_aes_ctx; 621 622 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 623 624 /* 625 * We should have only one block of data left in the 626 * remaining buffer. 627 */ 628 if (soft_aes_ctx->remain_len != AES_BLOCK_LEN) { 629 *pulLastPartLen = 0; 630 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 631 /* Cleanup memory space. */ 632 free(soft_aes_ctx->aes_cbc); 633 bzero(soft_aes_ctx->key_sched, 634 soft_aes_ctx->keysched_len); 635 free(soft_aes_ctx->key_sched); 636 637 goto clean1; 638 } 639 640 out_len = AES_BLOCK_LEN; 641 642 /* 643 * If application asks for the length of the output buffer 644 * to hold the plaintext? 645 */ 646 if (pLastPart == NULL) { 647 *pulLastPartLen = out_len; 648 rv = CKR_OK; 649 goto clean2; 650 } else { 651 crypto_data_t out; 652 653 /* Copy remaining data to the output buffer. */ 654 (void) memcpy(pLastPart, soft_aes_ctx->data, 655 AES_BLOCK_LEN); 656 657 out.cd_format = CRYPTO_DATA_RAW; 658 out.cd_offset = 0; 659 out.cd_length = AES_BLOCK_LEN; 660 out.cd_raw.iov_base = (char *)pLastPart; 661 out.cd_raw.iov_len = AES_BLOCK_LEN; 662 663 /* Decrypt final block of data. */ 664 rc = aes_decrypt_contiguous_blocks( 665 (aes_ctx_t *)soft_aes_ctx->aes_cbc, 666 (char *)pLastPart, AES_BLOCK_LEN, &out); 667 668 if (rc == 0) { 669 /* 670 * Remove padding bytes after decryption of 671 * ciphertext block to produce the original 672 * plaintext. 673 */ 674 rv = soft_remove_pkcs7_padding(pLastPart, 675 AES_BLOCK_LEN, &out_len, AES_BLOCK_LEN); 676 if (rv != CKR_OK) 677 *pulLastPartLen = 0; 678 else 679 *pulLastPartLen = out_len; 680 } else { 681 *pulLastPartLen = 0; 682 rv = CKR_FUNCTION_FAILED; 683 } 684 685 /* Cleanup memory space. */ 686 free(soft_aes_ctx->aes_cbc); 687 bzero(soft_aes_ctx->key_sched, 688 soft_aes_ctx->keysched_len); 689 free(soft_aes_ctx->key_sched); 690 691 } 692 693 break; 694 } 695 696 case CKM_AES_CBC: 697 case CKM_AES_ECB: 698 { 699 soft_aes_ctx_t *soft_aes_ctx; 700 701 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 702 /* 703 * CKM_AES_CBC and CKM_AES_ECB does not do any padding, 704 * so when the final is called, the remaining buffer 705 * should not contain any more data. 706 */ 707 *pulLastPartLen = 0; 708 if (soft_aes_ctx->remain_len != 0) { 709 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 710 } else { 711 if (pLastPart == NULL) 712 goto clean2; 713 } 714 715 /* Cleanup memory space. */ 716 free(soft_aes_ctx->aes_cbc); 717 bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len); 718 free(soft_aes_ctx->key_sched); 719 720 break; 721 } 722 723 case CKM_BLOWFISH_CBC: 724 { 725 soft_blowfish_ctx_t *soft_blowfish_ctx; 726 727 soft_blowfish_ctx = 728 (soft_blowfish_ctx_t *)session_p->decrypt.context; 729 730 *pulLastPartLen = 0; 731 if (soft_blowfish_ctx->remain_len != 0) 732 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 733 else { 734 if (pLastPart == NULL) 735 goto clean2; 736 } 737 738 free(soft_blowfish_ctx->blowfish_cbc); 739 bzero(soft_blowfish_ctx->key_sched, 740 soft_blowfish_ctx->keysched_len); 741 free(soft_blowfish_ctx->key_sched); 742 743 break; 744 } 745 746 case CKM_RC4: 747 { 748 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context; 749 bzero(key, sizeof (*key)); 750 *pulLastPartLen = 0; 751 break; 752 } 753 754 default: 755 /* PKCS11: The mechanism only supports single-part operation. */ 756 rv = CKR_MECHANISM_INVALID; 757 break; 758 } 759 760 clean1: 761 free(session_p->decrypt.context); 762 session_p->decrypt.context = NULL; 763 764 clean2: 765 (void) pthread_mutex_unlock(&session_p->session_mutex); 766 767 return (rv); 768 769 } 770