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