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