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