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