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