9642 PKCS#11 softtoken should use explicit_bzero
[unleashed.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softEncryptUtil.c
blobfb7da5af3bdba64c41fb53ad67654528d85fc1b0
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.
25 * Copyright (c) 2018, Joyent, Inc.
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"
43 * Add padding bytes with the value of length of padding.
45 void
46 soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
48 (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
52 * Perform encrypt init operation internally for the support of
53 * CKM_AES and CKM_DES MAC operations.
55 * This function is called with the session being held, and without
56 * its mutex taken.
58 CK_RV
59 soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
60 pMechanism, soft_object_t *key_p)
62 CK_RV rv;
64 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
72 session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
74 (void) pthread_mutex_unlock(&session_p->session_mutex);
76 rv = soft_encrypt_init(session_p, pMechanism, key_p);
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);
84 return (rv);
88 * soft_encrypt_init()
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
95 * Description:
96 * called by C_EncryptInit(). This function calls the corresponding
97 * encrypt init routine based on the mechanism.
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
107 CK_RV
108 soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
109 soft_object_t *key_p)
112 CK_RV rv;
114 switch (pMechanism->mechanism) {
116 case CKM_DES_ECB:
118 if (key_p->key_type != CKK_DES) {
119 return (CKR_KEY_TYPE_INCONSISTENT);
121 goto ecb_common;
123 case CKM_DES3_ECB:
125 if ((key_p->key_type != CKK_DES2) &&
126 (key_p->key_type != CKK_DES3)) {
127 return (CKR_KEY_TYPE_INCONSISTENT);
130 ecb_common:
131 return (soft_des_crypt_init_common(session_p, pMechanism,
132 key_p, B_TRUE));
134 case CKM_DES_CBC:
135 case CKM_DES_CBC_PAD:
137 if (key_p->key_type != CKK_DES) {
138 return (CKR_KEY_TYPE_INCONSISTENT);
141 goto cbc_common;
143 case CKM_DES3_CBC:
144 case CKM_DES3_CBC_PAD:
147 soft_des_ctx_t *soft_des_ctx;
149 if ((key_p->key_type != CKK_DES2) &&
150 (key_p->key_type != CKK_DES3)) {
151 return (CKR_KEY_TYPE_INCONSISTENT);
154 cbc_common:
155 if ((pMechanism->pParameter == NULL) ||
156 (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
157 return (CKR_MECHANISM_PARAM_INVALID);
160 rv = soft_des_crypt_init_common(session_p, pMechanism,
161 key_p, B_TRUE);
163 if (rv != CKR_OK)
164 return (rv);
166 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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);
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;
187 (void) pthread_mutex_unlock(&session_p->session_mutex);
189 return (rv);
191 case CKM_AES_ECB:
193 if (key_p->key_type != CKK_AES) {
194 return (CKR_KEY_TYPE_INCONSISTENT);
197 return (soft_aes_crypt_init_common(session_p, pMechanism,
198 key_p, B_TRUE));
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);
206 /* FALLTHRU */
207 case CKM_AES_CMAC:
209 soft_aes_ctx_t *soft_aes_ctx;
211 if (key_p->key_type != CKK_AES) {
212 return (CKR_KEY_TYPE_INCONSISTENT);
216 rv = soft_aes_crypt_init_common(session_p, pMechanism,
217 key_p, B_TRUE);
219 if (rv != CKR_OK)
220 return (rv);
222 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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;
251 (void) pthread_mutex_unlock(&session_p->session_mutex);
253 return (rv);
255 case CKM_AES_CTR:
257 soft_aes_ctx_t *soft_aes_ctx;
259 if (key_p->key_type != CKK_AES) {
260 return (CKR_KEY_TYPE_INCONSISTENT);
263 if (pMechanism->pParameter == NULL ||
264 pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
265 return (CKR_MECHANISM_PARAM_INVALID);
268 rv = soft_aes_crypt_init_common(session_p, pMechanism,
269 key_p, B_TRUE);
271 if (rv != CKR_OK)
272 return (rv);
274 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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;
290 (void) pthread_mutex_unlock(&session_p->session_mutex);
292 return (rv);
294 case CKM_RC4:
296 if (key_p->key_type != CKK_RC4) {
297 return (CKR_KEY_TYPE_INCONSISTENT);
300 return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
301 B_TRUE));
303 case CKM_RSA_X_509:
304 case CKM_RSA_PKCS:
306 if (key_p->key_type != CKK_RSA) {
307 return (CKR_KEY_TYPE_INCONSISTENT);
310 return (soft_rsa_crypt_init_common(session_p, pMechanism,
311 key_p, B_TRUE));
313 case CKM_BLOWFISH_CBC:
315 soft_blowfish_ctx_t *soft_blowfish_ctx;
317 if (key_p->key_type != CKK_BLOWFISH)
318 return (CKR_KEY_TYPE_INCONSISTENT);
320 if ((pMechanism->pParameter == NULL) ||
321 (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
322 return (CKR_MECHANISM_PARAM_INVALID);
324 rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
325 key_p, B_TRUE);
327 if (rv != CKR_OK)
328 return (rv);
330 (void) pthread_mutex_lock(&session_p->session_mutex);
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);
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);
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;
353 (void) pthread_mutex_unlock(&session_p->session_mutex);
355 return (rv);
357 default:
358 return (CKR_MECHANISM_INVALID);
364 * soft_encrypt_common()
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
375 * Description:
376 * This function calls the corresponding encrypt routine based
377 * on the mechanism.
379 * Returns:
380 * see corresponding encrypt routine.
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)
388 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
390 switch (mechanism) {
392 case CKM_DES_ECB:
393 case CKM_DES_CBC:
394 case CKM_DES3_ECB:
395 case CKM_DES3_CBC:
397 if (ulDataLen == 0) {
398 *pulEncryptedLen = 0;
399 return (CKR_OK);
401 /* FALLTHROUGH */
403 case CKM_DES_CBC_PAD:
404 case CKM_DES3_CBC_PAD:
406 return (soft_des_encrypt_common(session_p, pData,
407 ulDataLen, pEncrypted, pulEncryptedLen, update));
409 case CKM_AES_ECB:
410 case CKM_AES_CBC:
411 case CKM_AES_CTR:
413 if (ulDataLen == 0) {
414 *pulEncryptedLen = 0;
415 return (CKR_OK);
417 /* FALLTHROUGH */
419 case CKM_AES_CMAC:
420 case CKM_AES_CBC_PAD:
422 return (soft_aes_encrypt_common(session_p, pData,
423 ulDataLen, pEncrypted, pulEncryptedLen, update));
425 case CKM_BLOWFISH_CBC:
427 if (ulDataLen == 0) {
428 *pulEncryptedLen = 0;
429 return (CKR_OK);
432 return (soft_blowfish_encrypt_common(session_p, pData,
433 ulDataLen, pEncrypted, pulEncryptedLen, update));
435 case CKM_RC4:
437 if (ulDataLen == 0) {
438 *pulEncryptedLen = 0;
439 return (CKR_OK);
442 return (soft_arcfour_crypt(&(session_p->encrypt), pData,
443 ulDataLen, pEncrypted, pulEncryptedLen));
445 case CKM_RSA_X_509:
446 case CKM_RSA_PKCS:
448 return (soft_rsa_encrypt_common(session_p, pData,
449 ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
451 default:
452 return (CKR_MECHANISM_INVALID);
458 * soft_encrypt()
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
467 * Description:
468 * called by C_Encrypt(). This function calls the soft_encrypt_common
469 * routine.
471 * Returns:
472 * see soft_encrypt_common().
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)
480 return (soft_encrypt_common(session_p, pData, ulDataLen,
481 pEncryptedData, pulEncryptedDataLen, B_FALSE));
486 * soft_encrypt_update()
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
495 * Description:
496 * called by C_EncryptUpdate(). This function calls the
497 * soft_encrypt_common routine (with update flag on).
499 * Returns:
500 * see soft_encrypt_common().
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)
508 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
510 switch (mechanism) {
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:
526 return (soft_encrypt_common(session_p, pPart, ulPartLen,
527 pEncryptedPart, pulEncryptedPartLen, B_TRUE));
529 default:
530 /* PKCS11: The mechanism only supports single-part operation. */
531 return (CKR_MECHANISM_INVALID);
537 * soft_encrypt_final()
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
545 * Description:
546 * called by C_EncryptFinal().
548 * Returns:
549 * CKR_OK: success
550 * CKR_FUNCTION_FAILED: encrypt final function failed
551 * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
553 CK_RV
554 soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
555 CK_ULONG_PTR pulLastEncryptedPartLen)
558 CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
559 CK_ULONG out_len;
560 CK_RV rv = CKR_OK;
561 int rc;
563 (void) pthread_mutex_lock(&session_p->session_mutex);
565 if (session_p->encrypt.context == NULL) {
566 rv = CKR_OPERATION_NOT_INITIALIZED;
567 *pulLastEncryptedPartLen = 0;
568 goto clean1;
570 switch (mechanism) {
572 case CKM_DES_CBC_PAD:
573 case CKM_DES3_CBC_PAD:
575 soft_des_ctx_t *soft_des_ctx;
577 soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
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.
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;
591 if (pLastEncryptedPart == NULL) {
593 * Application asks for the length of the output
594 * buffer to hold the ciphertext.
596 *pulLastEncryptedPartLen = out_len;
597 goto clean1;
598 } else {
599 crypto_data_t out;
601 /* Copy remaining data to the output buffer. */
602 (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
603 soft_des_ctx->remain_len);
606 * Add padding bytes prior to encrypt final.
608 soft_add_pkcs7_padding(pLastEncryptedPart +
609 soft_des_ctx->remain_len, DES_BLOCK_LEN,
610 soft_des_ctx->remain_len);
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;
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);
623 if (rc == 0) {
624 *pulLastEncryptedPartLen = out_len;
625 } else {
626 *pulLastEncryptedPartLen = 0;
627 rv = CKR_FUNCTION_FAILED;
630 /* Cleanup memory space. */
631 free(soft_des_ctx->des_cbc);
632 freezero(soft_des_ctx->key_sched,
633 soft_des_ctx->keysched_len);
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 freezero(soft_des_ctx->key_sched,
663 soft_des_ctx->keysched_len);
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 freezero(soft_aes_ctx->key_sched,
727 soft_aes_ctx->keysched_len);
730 break;
732 case CKM_AES_CMAC:
734 soft_aes_ctx_t *soft_aes_ctx;
735 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
737 if (pLastEncryptedPart == NULL) {
739 * Application asks for the length of the output
740 * buffer to hold the ciphertext.
742 *pulLastEncryptedPartLen = AES_BLOCK_LEN;
743 goto clean1;
744 } else {
745 crypto_data_t out;
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;
753 rc = cmac_mode_final(soft_aes_ctx->aes_cbc, &out,
754 aes_encrypt_block, aes_xor_block);
756 if (rc == 0) {
757 *pulLastEncryptedPartLen = AES_BLOCK_LEN;
758 } else {
759 *pulLastEncryptedPartLen = 0;
760 rv = CKR_FUNCTION_FAILED;
763 /* Cleanup memory space. */
764 free(soft_aes_ctx->aes_cbc);
765 freezero(soft_aes_ctx->key_sched,
766 soft_aes_ctx->keysched_len);
769 break;
771 case CKM_AES_CBC:
772 case CKM_AES_ECB:
774 soft_aes_ctx_t *soft_aes_ctx;
776 soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
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.
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;
790 /* Cleanup memory space. */
791 free(soft_aes_ctx->aes_cbc);
792 freezero(soft_aes_ctx->key_sched,
793 soft_aes_ctx->keysched_len);
795 break;
797 case CKM_AES_CTR:
799 crypto_data_t out;
800 soft_aes_ctx_t *soft_aes_ctx;
801 ctr_ctx_t *ctr_ctx;
802 size_t len;
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;
808 if (pLastEncryptedPart == NULL) {
809 *pulLastEncryptedPartLen = len;
810 goto clean1;
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;
819 rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
821 if (rv == CRYPTO_BUFFER_TOO_SMALL) {
822 *pulLastEncryptedPartLen = len;
823 goto clean1;
826 /* Cleanup memory space. */
827 free(ctr_ctx);
828 freezero(soft_aes_ctx->key_sched,
829 soft_aes_ctx->keysched_len);
831 break;
833 case CKM_BLOWFISH_CBC:
835 soft_blowfish_ctx_t *soft_blowfish_ctx;
837 soft_blowfish_ctx =
838 (soft_blowfish_ctx_t *)session_p->encrypt.context;
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
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;
852 free(soft_blowfish_ctx->blowfish_cbc);
853 freezero(soft_blowfish_ctx->key_sched,
854 soft_blowfish_ctx->keysched_len);
855 break;
858 case CKM_RC4:
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;
868 default:
869 /* PKCS11: The mechanism only supports single-part operation. */
870 rv = CKR_MECHANISM_INVALID;
871 break;
874 free(session_p->encrypt.context);
875 session_p->encrypt.context = NULL;
876 clean1:
877 (void) pthread_mutex_unlock(&session_p->session_mutex);
879 return (rv);
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.
891 void
892 soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
893 boolean_t lock_held)
896 crypto_active_op_t *active_op;
897 boolean_t lock_true = B_TRUE;
899 if (!lock_held)
900 (void) pthread_mutex_lock(&session_p->session_mutex);
902 active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
904 switch (active_op->mech.mechanism) {
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:
914 soft_des_ctx_t *soft_des_ctx =
915 (soft_des_ctx_t *)active_op->context;
916 des_ctx_t *des_ctx;
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);
925 freezero(soft_des_ctx->key_sched,
926 soft_des_ctx->keysched_len);
928 break;
931 case CKM_AES_CBC_PAD:
932 case CKM_AES_CBC:
933 case CKM_AES_CMAC:
934 case CKM_AES_ECB:
936 soft_aes_ctx_t *soft_aes_ctx =
937 (soft_aes_ctx_t *)active_op->context;
938 aes_ctx_t *aes_ctx;
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);
947 freezero(soft_aes_ctx->key_sched,
948 soft_aes_ctx->keysched_len);
950 break;
953 case CKM_BLOWFISH_CBC:
955 soft_blowfish_ctx_t *soft_blowfish_ctx =
956 (soft_blowfish_ctx_t *)active_op->context;
957 blowfish_ctx_t *blowfish_ctx;
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);
968 freezero(soft_blowfish_ctx->key_sched,
969 soft_blowfish_ctx->keysched_len);
971 break;
974 case CKM_RC4:
976 ARCFour_key *key = (ARCFour_key *)active_op->context;
978 if (key != NULL)
979 explicit_bzero(key, sizeof (*key));
980 break;
983 case CKM_RSA_X_509:
984 case CKM_RSA_PKCS:
986 soft_rsa_ctx_t *rsa_ctx =
987 (soft_rsa_ctx_t *)active_op->context;
989 if (rsa_ctx != NULL)
990 if (rsa_ctx->key != NULL) {
991 soft_cleanup_object(rsa_ctx->key);
992 free(rsa_ctx->key);
995 break;
998 } /* switch */
1000 if (active_op->context != NULL) {
1001 free(active_op->context);
1002 active_op->context = NULL;
1005 active_op->flags = 0;
1007 if (!lock_held)
1008 SES_REFRELE(session_p, lock_true);