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