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