5869 Need AES CMAC support in KCF+PKCS11
[unleashed.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softEncryptUtil.c
blobaebacaa868ba0296b5584d0455b471952c9a40b3
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
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"
42 * Add padding bytes with the value of length of padding.
44 void
45 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
47 (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
51 * Perform encrypt init operation internally for the support of
52 * CKM_AES and CKM_DES MAC operations.
54 * This function is called with the session being held, and without
55 * its mutex taken.
57 CK_RV
58 soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
59 pMechanism, soft_object_t *key_p)
61 CK_RV rv;
63 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
71 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
73 (void) pthread_mutex_unlock(&session_p->session_mutex);
75 rv = soft_encrypt_init(session_p, pMechanism, key_p);
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);
83 return (rv);
87 * soft_encrypt_init()
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
94 * Description:
95 * called by C_EncryptInit(). This function calls the corresponding
96 * encrypt init routine based on the mechanism.
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
106 CK_RV
107 soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
108 soft_object_t *key_p)
111 CK_RV rv;
113 switch (pMechanism->mechanism) {
115 case CKM_DES_ECB:
117 if (key_p->key_type != CKK_DES) {
118 return (CKR_KEY_TYPE_INCONSISTENT);
120 goto ecb_common;
122 case CKM_DES3_ECB:
124 if ((key_p->key_type != CKK_DES2) &&
125 (key_p->key_type != CKK_DES3)) {
126 return (CKR_KEY_TYPE_INCONSISTENT);
129 ecb_common:
130 return (soft_des_crypt_init_common(session_p, pMechanism,
131 key_p, B_TRUE));
133 case CKM_DES_CBC:
134 case CKM_DES_CBC_PAD:
136 if (key_p->key_type != CKK_DES) {
137 return (CKR_KEY_TYPE_INCONSISTENT);
140 goto cbc_common;
142 case CKM_DES3_CBC:
143 case CKM_DES3_CBC_PAD:
146 soft_des_ctx_t *soft_des_ctx;
148 if ((key_p->key_type != CKK_DES2) &&
149 (key_p->key_type != CKK_DES3)) {
150 return (CKR_KEY_TYPE_INCONSISTENT);
153 cbc_common:
154 if ((pMechanism->pParameter == NULL) ||
155 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
156 return (CKR_MECHANISM_PARAM_INVALID);
159 rv = soft_des_crypt_init_common(session_p, pMechanism,
160 key_p, B_TRUE);
162 if (rv != CKR_OK)
163 return (rv);
165 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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);
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;
186 (void) pthread_mutex_unlock(&session_p->session_mutex);
188 return (rv);
190 case CKM_AES_ECB:
192 if (key_p->key_type != CKK_AES) {
193 return (CKR_KEY_TYPE_INCONSISTENT);
196 return (soft_aes_crypt_init_common(session_p, pMechanism,
197 key_p, B_TRUE));
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);
205 /* FALLTHRU */
206 case CKM_AES_CMAC:
208 soft_aes_ctx_t *soft_aes_ctx;
210 if (key_p->key_type != CKK_AES) {
211 return (CKR_KEY_TYPE_INCONSISTENT);
215 rv = soft_aes_crypt_init_common(session_p, pMechanism,
216 key_p, B_TRUE);
218 if (rv != CKR_OK)
219 return (rv);
221 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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;
250 (void) pthread_mutex_unlock(&session_p->session_mutex);
252 return (rv);
254 case CKM_AES_CTR:
256 soft_aes_ctx_t *soft_aes_ctx;
258 if (key_p->key_type != CKK_AES) {
259 return (CKR_KEY_TYPE_INCONSISTENT);
262 if (pMechanism->pParameter == NULL ||
263 pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
264 return (CKR_MECHANISM_PARAM_INVALID);
267 rv = soft_aes_crypt_init_common(session_p, pMechanism,
268 key_p, B_TRUE);
270 if (rv != CKR_OK)
271 return (rv);
273 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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;
289 (void) pthread_mutex_unlock(&session_p->session_mutex);
291 return (rv);
293 case CKM_RC4:
295 if (key_p->key_type != CKK_RC4) {
296 return (CKR_KEY_TYPE_INCONSISTENT);
299 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
300 B_TRUE));
302 case CKM_RSA_X_509:
303 case CKM_RSA_PKCS:
305 if (key_p->key_type != CKK_RSA) {
306 return (CKR_KEY_TYPE_INCONSISTENT);
309 return (soft_rsa_crypt_init_common(session_p, pMechanism,
310 key_p, B_TRUE));
312 case CKM_BLOWFISH_CBC:
314 soft_blowfish_ctx_t *soft_blowfish_ctx;
316 if (key_p->key_type != CKK_BLOWFISH)
317 return (CKR_KEY_TYPE_INCONSISTENT);
319 if ((pMechanism->pParameter == NULL) ||
320 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
321 return (CKR_MECHANISM_PARAM_INVALID);
323 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
324 key_p, B_TRUE);
326 if (rv != CKR_OK)
327 return (rv);
329 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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);
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;
352 (void) pthread_mutex_unlock(&session_p->session_mutex);
354 return (rv);
356 default:
357 return (CKR_MECHANISM_INVALID);
363 * soft_encrypt_common()
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
374 * Description:
375 * This function calls the corresponding encrypt routine based
376 * on the mechanism.
378 * Returns:
379 * see corresponding encrypt routine.
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)
387 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
389 switch (mechanism) {
391 case CKM_DES_ECB:
392 case CKM_DES_CBC:
393 case CKM_DES3_ECB:
394 case CKM_DES3_CBC:
396 if (ulDataLen == 0) {
397 *pulEncryptedLen = 0;
398 return (CKR_OK);
400 /* FALLTHROUGH */
402 case CKM_DES_CBC_PAD:
403 case CKM_DES3_CBC_PAD:
405 return (soft_des_encrypt_common(session_p, pData,
406 ulDataLen, pEncrypted, pulEncryptedLen, update));
408 case CKM_AES_ECB:
409 case CKM_AES_CBC:
410 case CKM_AES_CTR:
412 if (ulDataLen == 0) {
413 *pulEncryptedLen = 0;
414 return (CKR_OK);
416 /* FALLTHROUGH */
418 case CKM_AES_CMAC:
419 case CKM_AES_CBC_PAD:
421 return (soft_aes_encrypt_common(session_p, pData,
422 ulDataLen, pEncrypted, pulEncryptedLen, update));
424 case CKM_BLOWFISH_CBC:
426 if (ulDataLen == 0) {
427 *pulEncryptedLen = 0;
428 return (CKR_OK);
431 return (soft_blowfish_encrypt_common(session_p, pData,
432 ulDataLen, pEncrypted, pulEncryptedLen, update));
434 case CKM_RC4:
436 if (ulDataLen == 0) {
437 *pulEncryptedLen = 0;
438 return (CKR_OK);
441 return (soft_arcfour_crypt(&(session_p->encrypt), pData,
442 ulDataLen, pEncrypted, pulEncryptedLen));
444 case CKM_RSA_X_509:
445 case CKM_RSA_PKCS:
447 return (soft_rsa_encrypt_common(session_p, pData,
448 ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
450 default:
451 return (CKR_MECHANISM_INVALID);
457 * soft_encrypt()
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
466 * Description:
467 * called by C_Encrypt(). This function calls the soft_encrypt_common
468 * routine.
470 * Returns:
471 * see soft_encrypt_common().
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)
479 return (soft_encrypt_common(session_p, pData, ulDataLen,
480 pEncryptedData, pulEncryptedDataLen, B_FALSE));
485 * soft_encrypt_update()
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
494 * Description:
495 * called by C_EncryptUpdate(). This function calls the
496 * soft_encrypt_common routine (with update flag on).
498 * Returns:
499 * see soft_encrypt_common().
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)
507 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
509 switch (mechanism) {
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:
525 return (soft_encrypt_common(session_p, pPart, ulPartLen,
526 pEncryptedPart, pulEncryptedPartLen, B_TRUE));
528 default:
529 /* PKCS11: The mechanism only supports single-part operation. */
530 return (CKR_MECHANISM_INVALID);
536 * soft_encrypt_final()
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
544 * Description:
545 * called by C_EncryptFinal().
547 * Returns:
548 * CKR_OK: success
549 * CKR_FUNCTION_FAILED: encrypt final function failed
550 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
552 CK_RV
553 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
554 CK_ULONG_PTR pulLastEncryptedPartLen)
557 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
558 CK_ULONG out_len;
559 CK_RV rv = CKR_OK;
560 int rc;
562 (void) pthread_mutex_lock(&session_p->session_mutex);
564 if (session_p->encrypt.context == NULL) {
565 rv = CKR_OPERATION_NOT_INITIALIZED;
566 *pulLastEncryptedPartLen = 0;
567 goto clean1;
569 switch (mechanism) {
571 case CKM_DES_CBC_PAD:
572 case CKM_DES3_CBC_PAD:
574 soft_des_ctx_t *soft_des_ctx;
576 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
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.
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;
590 if (pLastEncryptedPart == NULL) {
592 * Application asks for the length of the output
593 * buffer to hold the ciphertext.
595 *pulLastEncryptedPartLen = out_len;
596 goto clean1;
597 } else {
598 crypto_data_t out;
600 /* Copy remaining data to the output buffer. */
601 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
602 soft_des_ctx->remain_len);
605 * Add padding bytes prior to encrypt final.
607 soft_add_pkcs7_padding(pLastEncryptedPart +
608 soft_des_ctx->remain_len, DES_BLOCK_LEN,
609 soft_des_ctx->remain_len);
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;
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);
622 if (rc == 0) {
623 *pulLastEncryptedPartLen = out_len;
624 } else {
625 *pulLastEncryptedPartLen = 0;
626 rv = CKR_FUNCTION_FAILED;
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);
636 break;
638 case CKM_DES_CBC:
639 case CKM_DES_ECB:
640 case CKM_DES3_CBC:
641 case CKM_DES3_ECB:
644 soft_des_ctx_t *soft_des_ctx;
646 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
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.
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;
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);
665 break;
667 case CKM_AES_CBC_PAD:
669 soft_aes_ctx_t *soft_aes_ctx;
671 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
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.
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;
685 if (pLastEncryptedPart == NULL) {
687 * Application asks for the length of the output
688 * buffer to hold the ciphertext.
690 *pulLastEncryptedPartLen = out_len;
691 goto clean1;
692 } else {
693 crypto_data_t out;
695 /* Copy remaining data to the output buffer. */
696 (void) memcpy(pLastEncryptedPart, soft_aes_ctx->data,
697 soft_aes_ctx->remain_len);
700 * Add padding bytes prior to encrypt final.
702 soft_add_pkcs7_padding(pLastEncryptedPart +
703 soft_aes_ctx->remain_len, AES_BLOCK_LEN,
704 soft_aes_ctx->remain_len);
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;
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);
717 if (rc == 0) {
718 *pulLastEncryptedPartLen = out_len;
719 } else {
720 *pulLastEncryptedPartLen = 0;
721 rv = CKR_FUNCTION_FAILED;
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);
731 break;
733 case CKM_AES_CMAC:
735 soft_aes_ctx_t *soft_aes_ctx;
736 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
738 if (pLastEncryptedPart == NULL) {
740 * Application asks for the length of the output
741 * buffer to hold the ciphertext.
743 *pulLastEncryptedPartLen = AES_BLOCK_LEN;
744 goto clean1;
745 } else {
746 crypto_data_t out;
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;
754 rc = cmac_mode_final(soft_aes_ctx->aes_cbc, &out,
755 aes_encrypt_block, aes_xor_block);
757 if (rc == 0) {
758 *pulLastEncryptedPartLen = AES_BLOCK_LEN;
759 } else {
760 *pulLastEncryptedPartLen = 0;
761 rv = CKR_FUNCTION_FAILED;
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);
771 break;
773 case CKM_AES_CBC:
774 case CKM_AES_ECB:
776 soft_aes_ctx_t *soft_aes_ctx;
778 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
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.
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;
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);
797 break;
799 case CKM_AES_CTR:
801 crypto_data_t out;
802 soft_aes_ctx_t *soft_aes_ctx;
803 ctr_ctx_t *ctr_ctx;
804 size_t len;
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;
810 if (pLastEncryptedPart == NULL) {
811 *pulLastEncryptedPartLen = len;
812 goto clean1;
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;
821 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
823 if (rv == CRYPTO_BUFFER_TOO_SMALL) {
824 *pulLastEncryptedPartLen = len;
825 goto clean1;
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);
833 break;
835 case CKM_BLOWFISH_CBC:
837 soft_blowfish_ctx_t *soft_blowfish_ctx;
839 soft_blowfish_ctx =
840 (soft_blowfish_ctx_t *)session_p->encrypt.context;
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
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;
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;
861 case CKM_RC4:
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;
871 default:
872 /* PKCS11: The mechanism only supports single-part operation. */
873 rv = CKR_MECHANISM_INVALID;
874 break;
877 free(session_p->encrypt.context);
878 session_p->encrypt.context = NULL;
879 clean1:
880 (void) pthread_mutex_unlock(&session_p->session_mutex);
882 return (rv);
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.
894 void
895 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
896 boolean_t lock_held)
899 crypto_active_op_t *active_op;
900 boolean_t lock_true = B_TRUE;
902 if (!lock_held)
903 (void) pthread_mutex_lock(&session_p->session_mutex);
905 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
907 switch (active_op->mech.mechanism) {
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:
917 soft_des_ctx_t *soft_des_ctx =
918 (soft_des_ctx_t *)active_op->context;
919 des_ctx_t *des_ctx;
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);
928 bzero(soft_des_ctx->key_sched,
929 soft_des_ctx->keysched_len);
930 free(soft_des_ctx->key_sched);
932 break;
935 case CKM_AES_CBC_PAD:
936 case CKM_AES_CBC:
937 case CKM_AES_CMAC:
938 case CKM_AES_ECB:
940 soft_aes_ctx_t *soft_aes_ctx =
941 (soft_aes_ctx_t *)active_op->context;
942 aes_ctx_t *aes_ctx;
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);
951 bzero(soft_aes_ctx->key_sched,
952 soft_aes_ctx->keysched_len);
953 free(soft_aes_ctx->key_sched);
955 break;
958 case CKM_BLOWFISH_CBC:
960 soft_blowfish_ctx_t *soft_blowfish_ctx =
961 (soft_blowfish_ctx_t *)active_op->context;
962 blowfish_ctx_t *blowfish_ctx;
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);
973 bzero(soft_blowfish_ctx->key_sched,
974 soft_blowfish_ctx->keysched_len);
975 free(soft_blowfish_ctx->key_sched);
977 break;
980 case CKM_RC4:
982 ARCFour_key *key = (ARCFour_key *)active_op->context;
984 if (key != NULL)
985 bzero(key, sizeof (*key));
986 break;
989 case CKM_RSA_X_509:
990 case CKM_RSA_PKCS:
992 soft_rsa_ctx_t *rsa_ctx =
993 (soft_rsa_ctx_t *)active_op->context;
995 if (rsa_ctx != NULL)
996 if (rsa_ctx->key != NULL) {
997 soft_cleanup_object(rsa_ctx->key);
998 free(rsa_ctx->key);
1001 break;
1004 } /* switch */
1006 if (active_op->context != NULL) {
1007 free(active_op->context);
1008 active_op->context = NULL;
1011 active_op->flags = 0;
1013 if (!lock_held)
1014 SES_REFRELE(session_p, lock_true);