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