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