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