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