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, 477 CK_ULONG_PTR pulPartLen) 478 { 479 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 480 481 switch (mechanism) { 482 483 case CKM_DES_ECB: 484 case CKM_DES_CBC: 485 case CKM_DES_CBC_PAD: 486 case CKM_DES3_ECB: 487 case CKM_DES3_CBC: 488 case CKM_DES3_CBC_PAD: 489 case CKM_AES_ECB: 490 case CKM_AES_CBC: 491 case CKM_AES_CBC_PAD: 492 case CKM_AES_CTR: 493 case CKM_BLOWFISH_CBC: 494 case CKM_RC4: 495 496 return (soft_decrypt_common(session_p, pEncryptedPart, 497 ulEncryptedPartLen, pPart, pulPartLen, B_TRUE)); 498 499 default: 500 /* PKCS11: The mechanism only supports single-part operation. */ 501 return (CKR_MECHANISM_INVALID); 502 } 503 504 } 505 506 507 /* 508 * soft_decrypt_final() 509 * 510 * Arguments: 511 * session_p: pointer to soft_session_t struct 512 * pLastPart: pointer to the last recovered data part 513 * pulLastPartLen: pointer to the length of the last recovered data part 514 * 515 * Description: 516 * called by C_DecryptFinal(). 517 * 518 * Returns: 519 * CKR_OK: success 520 * CKR_FUNCTION_FAILED: decrypt final function failed 521 * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length 522 */ 523 CK_RV 524 soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart, 525 CK_ULONG_PTR pulLastPartLen) 526 { 527 528 CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism; 529 CK_ULONG out_len; 530 CK_RV rv = CKR_OK; 531 int rc; 532 533 (void) pthread_mutex_lock(&session_p->session_mutex); 534 535 if (session_p->decrypt.context == NULL) { 536 rv = CKR_OPERATION_NOT_INITIALIZED; 537 *pulLastPartLen = 0; 538 goto clean2; 539 } 540 switch (mechanism) { 541 542 case CKM_DES_CBC_PAD: 543 case CKM_DES3_CBC_PAD: 544 { 545 546 soft_des_ctx_t *soft_des_ctx; 547 548 soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context; 549 550 /* 551 * We should have only one block of data left in the 552 * remaining buffer. 553 */ 554 if (soft_des_ctx->remain_len != DES_BLOCK_LEN) { 555 *pulLastPartLen = 0; 556 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 557 /* Cleanup memory space. */ 558 free(soft_des_ctx->des_cbc); 559 freezero(soft_des_ctx->key_sched, 560 soft_des_ctx->keysched_len); 561 562 goto clean1; 563 } 564 565 out_len = DES_BLOCK_LEN; 566 567 /* 568 * If application asks for the length of the output buffer 569 * to hold the plaintext? 570 */ 571 if (pLastPart == NULL) { 572 *pulLastPartLen = out_len; 573 rv = CKR_OK; 574 goto clean2; 575 } else { 576 crypto_data_t out; 577 578 /* Copy remaining data to the output buffer. */ 579 (void) memcpy(pLastPart, soft_des_ctx->data, 580 DES_BLOCK_LEN); 581 582 out.cd_format = CRYPTO_DATA_RAW; 583 out.cd_offset = 0; 584 out.cd_length = DES_BLOCK_LEN; 585 out.cd_raw.iov_base = (char *)pLastPart; 586 out.cd_raw.iov_len = DES_BLOCK_LEN; 587 588 /* Decrypt final block of data. */ 589 rc = des_decrypt_contiguous_blocks( 590 (des_ctx_t *)soft_des_ctx->des_cbc, 591 (char *)pLastPart, DES_BLOCK_LEN, &out); 592 593 if (rc == 0) { 594 /* 595 * Remove padding bytes after decryption of 596 * ciphertext block to produce the original 597 * plaintext. 598 */ 599 rv = soft_remove_pkcs7_padding(pLastPart, 600 DES_BLOCK_LEN, &out_len); 601 if (rv != CKR_OK) 602 *pulLastPartLen = 0; 603 else 604 *pulLastPartLen = out_len; 605 } else { 606 *pulLastPartLen = 0; 607 rv = CKR_FUNCTION_FAILED; 608 } 609 610 /* Cleanup memory space. */ 611 free(soft_des_ctx->des_cbc); 612 freezero(soft_des_ctx->key_sched, 613 soft_des_ctx->keysched_len); 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 freezero(soft_des_ctx->key_sched, 645 soft_des_ctx->keysched_len); 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 freezero(soft_aes_ctx->key_sched, 667 soft_aes_ctx->keysched_len); 668 669 goto clean1; 670 } 671 672 out_len = AES_BLOCK_LEN; 673 674 /* 675 * If application asks for the length of the output buffer 676 * to hold the plaintext? 677 */ 678 if (pLastPart == NULL) { 679 *pulLastPartLen = out_len; 680 rv = CKR_OK; 681 goto clean2; 682 } else { 683 crypto_data_t out; 684 685 /* Copy remaining data to the output buffer. */ 686 (void) memcpy(pLastPart, soft_aes_ctx->data, 687 AES_BLOCK_LEN); 688 689 out.cd_format = CRYPTO_DATA_RAW; 690 out.cd_offset = 0; 691 out.cd_length = AES_BLOCK_LEN; 692 out.cd_raw.iov_base = (char *)pLastPart; 693 out.cd_raw.iov_len = AES_BLOCK_LEN; 694 695 /* Decrypt final block of data. */ 696 rc = aes_decrypt_contiguous_blocks( 697 (aes_ctx_t *)soft_aes_ctx->aes_cbc, 698 (char *)pLastPart, AES_BLOCK_LEN, &out); 699 700 if (rc == 0) { 701 /* 702 * Remove padding bytes after decryption of 703 * ciphertext block to produce the original 704 * plaintext. 705 */ 706 rv = soft_remove_pkcs7_padding(pLastPart, 707 AES_BLOCK_LEN, &out_len); 708 if (rv != CKR_OK) 709 *pulLastPartLen = 0; 710 else 711 *pulLastPartLen = out_len; 712 } else { 713 *pulLastPartLen = 0; 714 rv = CKR_FUNCTION_FAILED; 715 } 716 717 /* Cleanup memory space. */ 718 free(soft_aes_ctx->aes_cbc); 719 freezero(soft_aes_ctx->key_sched, 720 soft_aes_ctx->keysched_len); 721 722 } 723 724 break; 725 } 726 727 case CKM_AES_CBC: 728 case CKM_AES_ECB: 729 { 730 soft_aes_ctx_t *soft_aes_ctx; 731 732 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 733 /* 734 * CKM_AES_CBC and CKM_AES_ECB does not do any padding, 735 * so when the final is called, the remaining buffer 736 * should not contain any more data. 737 */ 738 *pulLastPartLen = 0; 739 if (soft_aes_ctx->remain_len != 0) { 740 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 741 } else { 742 if (pLastPart == NULL) 743 goto clean2; 744 } 745 746 /* Cleanup memory space. */ 747 free(soft_aes_ctx->aes_cbc); 748 freezero(soft_aes_ctx->key_sched, 749 soft_aes_ctx->keysched_len); 750 751 break; 752 } 753 case CKM_AES_CTR: 754 { 755 crypto_data_t out; 756 soft_aes_ctx_t *soft_aes_ctx; 757 ctr_ctx_t *ctr_ctx; 758 size_t len; 759 760 soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context; 761 ctr_ctx = soft_aes_ctx->aes_cbc; 762 len = ctr_ctx->ctr_remainder_len; 763 if (pLastPart == NULL) { 764 *pulLastPartLen = len; 765 goto clean1; 766 } 767 if (len > 0) { 768 out.cd_format = CRYPTO_DATA_RAW; 769 out.cd_offset = 0; 770 out.cd_length = len; 771 out.cd_raw.iov_base = (char *)pLastPart; 772 out.cd_raw.iov_len = len; 773 774 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block); 775 if (rv == CRYPTO_DATA_LEN_RANGE) 776 rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE; 777 } 778 if (rv == CRYPTO_BUFFER_TOO_SMALL) { 779 *pulLastPartLen = len; 780 goto clean1; 781 } 782 783 /* Cleanup memory space. */ 784 free(ctr_ctx); 785 freezero(soft_aes_ctx->key_sched, 786 soft_aes_ctx->keysched_len); 787 788 break; 789 } 790 case CKM_BLOWFISH_CBC: 791 { 792 soft_blowfish_ctx_t *soft_blowfish_ctx; 793 794 soft_blowfish_ctx = 795 (soft_blowfish_ctx_t *)session_p->decrypt.context; 796 797 *pulLastPartLen = 0; 798 if (soft_blowfish_ctx->remain_len != 0) 799 rv = CKR_ENCRYPTED_DATA_LEN_RANGE; 800 else { 801 if (pLastPart == NULL) 802 goto clean2; 803 } 804 805 free(soft_blowfish_ctx->blowfish_cbc); 806 freezero(soft_blowfish_ctx->key_sched, 807 soft_blowfish_ctx->keysched_len); 808 809 break; 810 } 811 812 case CKM_RC4: 813 { 814 ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context; 815 explicit_bzero(key, sizeof (*key)); 816 *pulLastPartLen = 0; 817 break; 818 } 819 820 default: 821 /* PKCS11: The mechanism only supports single-part operation. */ 822 rv = CKR_MECHANISM_INVALID; 823 break; 824 } 825 826 clean1: 827 free(session_p->decrypt.context); 828 session_p->decrypt.context = NULL; 829 830 clean2: 831 (void) pthread_mutex_unlock(&session_p->session_mutex); 832 833 return (rv); 834 835 }