17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
547c883c7Sdinak  * Common Development and Distribution License (the "License").
647c883c7Sdinak  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21726fad2aSDina K Nimeh 
227c478bd9Sstevel@tonic-gate /*
23726fad2aSDina K Nimeh  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24cd964fceSMatt Barden  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
25a8793c76SJason King  * Copyright (c) 2018, Joyent, Inc.
26*fb261280SJason King  * Copyright 2017 Jason King.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <pthread.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <string.h>
327c478bd9Sstevel@tonic-gate #include <strings.h>
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
3523c57df7Smcpowers #include <modes/modes.h>
367c478bd9Sstevel@tonic-gate #include <arcfour.h>
377c478bd9Sstevel@tonic-gate #include "softSession.h"
387c478bd9Sstevel@tonic-gate #include "softObject.h"
397c478bd9Sstevel@tonic-gate #include "softOps.h"
407c478bd9Sstevel@tonic-gate #include "softCrypt.h"
417c478bd9Sstevel@tonic-gate #include "softRSA.h"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /*
447c478bd9Sstevel@tonic-gate  * Add padding bytes with the value of length of padding.
457c478bd9Sstevel@tonic-gate  */
467c478bd9Sstevel@tonic-gate void
soft_add_pkcs7_padding(CK_BYTE * buf,int block_size,CK_ULONG data_len)477c478bd9Sstevel@tonic-gate soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
487c478bd9Sstevel@tonic-gate {
49726fad2aSDina K Nimeh 	(void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /*
537c478bd9Sstevel@tonic-gate  * Perform encrypt init operation internally for the support of
54cd964fceSMatt Barden  * CKM_AES and CKM_DES MAC operations.
557c478bd9Sstevel@tonic-gate  *
567c478bd9Sstevel@tonic-gate  * This function is called with the session being held, and without
577c478bd9Sstevel@tonic-gate  * its mutex taken.
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)607c478bd9Sstevel@tonic-gate soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
61cd964fceSMatt Barden     pMechanism, soft_object_t *key_p)
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	CK_RV rv;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate 	/* Check to see if encrypt operation is already active */
687c478bd9Sstevel@tonic-gate 	if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
697c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
707c478bd9Sstevel@tonic-gate 		return (CKR_OPERATION_ACTIVE);
717c478bd9Sstevel@tonic-gate 	}
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	rv = soft_encrypt_init(session_p, pMechanism, key_p);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
807c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
817c478bd9Sstevel@tonic-gate 		session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
827c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
837c478bd9Sstevel@tonic-gate 	}
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	return (rv);
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate  * soft_encrypt_init()
907c478bd9Sstevel@tonic-gate  *
917c478bd9Sstevel@tonic-gate  * Arguments:
927c478bd9Sstevel@tonic-gate  *	session_p:	pointer to soft_session_t struct
937c478bd9Sstevel@tonic-gate  *	pMechanism:	pointer to CK_MECHANISM struct provided by application
947c478bd9Sstevel@tonic-gate  *	key_p:		pointer to key soft_object_t struct
957c478bd9Sstevel@tonic-gate  *
967c478bd9Sstevel@tonic-gate  * Description:
977c478bd9Sstevel@tonic-gate  *	called by C_EncryptInit(). This function calls the corresponding
987c478bd9Sstevel@tonic-gate  *	encrypt init routine based on the mechanism.
997c478bd9Sstevel@tonic-gate  *
1007c478bd9Sstevel@tonic-gate  * Returns:
1017c478bd9Sstevel@tonic-gate  *	CKR_OK: success
1027c478bd9Sstevel@tonic-gate  *	CKR_HOST_MEMORY: run out of system memory
1037c478bd9Sstevel@tonic-gate  *	CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
1047c478bd9Sstevel@tonic-gate  *	CKR_MECHANISM_INVALID: invalid mechanism type
1057c478bd9Sstevel@tonic-gate  *	CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
1067c478bd9Sstevel@tonic-gate  *		with the specified mechanism
1077c478bd9Sstevel@tonic-gate  */
1087c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)1097c478bd9Sstevel@tonic-gate soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1107c478bd9Sstevel@tonic-gate     soft_object_t *key_p)
1117c478bd9Sstevel@tonic-gate {
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	CK_RV rv;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	switch (pMechanism->mechanism) {
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	case CKM_DES_ECB:
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate 		if (key_p->key_type != CKK_DES) {
1207c478bd9Sstevel@tonic-gate 			return (CKR_KEY_TYPE_INCONSISTENT);
1217c478bd9Sstevel@tonic-gate 		}
1227c478bd9Sstevel@tonic-gate 		goto ecb_common;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 	case CKM_DES3_ECB:
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 		if ((key_p->key_type != CKK_DES2) &&
1277c478bd9Sstevel@tonic-gate 		    (key_p->key_type != CKK_DES3)) {
1287c478bd9Sstevel@tonic-gate 			return (CKR_KEY_TYPE_INCONSISTENT);
1297c478bd9Sstevel@tonic-gate 		}
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate ecb_common:
1327c478bd9Sstevel@tonic-gate 		return (soft_des_crypt_init_common(session_p, pMechanism,
1337c478bd9Sstevel@tonic-gate 		    key_p, B_TRUE));
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC:
1367c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC_PAD:
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 		if (key_p->key_type != CKK_DES) {
1397c478bd9Sstevel@tonic-gate 			return (CKR_KEY_TYPE_INCONSISTENT);
1407c478bd9Sstevel@tonic-gate 		}
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 		goto cbc_common;
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC:
1457c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC_PAD:
1467c478bd9Sstevel@tonic-gate 	{
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 		soft_des_ctx_t *soft_des_ctx;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 		if ((key_p->key_type != CKK_DES2) &&
1517c478bd9Sstevel@tonic-gate 		    (key_p->key_type != CKK_DES3)) {
1527c478bd9Sstevel@tonic-gate 			return (CKR_KEY_TYPE_INCONSISTENT);
1537c478bd9Sstevel@tonic-gate 		}
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate cbc_common:
1567c478bd9Sstevel@tonic-gate 		if ((pMechanism->pParameter == NULL) ||
1577c478bd9Sstevel@tonic-gate 		    (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
1587c478bd9Sstevel@tonic-gate 			return (CKR_MECHANISM_PARAM_INVALID);
1597c478bd9Sstevel@tonic-gate 		}
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 		rv = soft_des_crypt_init_common(session_p, pMechanism,
1627c478bd9Sstevel@tonic-gate 		    key_p, B_TRUE);
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 		if (rv != CKR_OK)
1657c478bd9Sstevel@tonic-gate 			return (rv);
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 		soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
1707c478bd9Sstevel@tonic-gate 		/* Copy Initialization Vector (IV) into the context. */
1717c478bd9Sstevel@tonic-gate 		(void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
1727c478bd9Sstevel@tonic-gate 		    DES_BLOCK_LEN);
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate 		/* Allocate a context for DES cipher-block chaining. */
1757c478bd9Sstevel@tonic-gate 		soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
1767c478bd9Sstevel@tonic-gate 		    soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
1777c478bd9Sstevel@tonic-gate 		    soft_des_ctx->ivec, key_p->key_type);
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 		if (soft_des_ctx->des_cbc == NULL) {
180a8793c76SJason King 			freezero(soft_des_ctx->key_sched,
1817c478bd9Sstevel@tonic-gate 			    soft_des_ctx->keysched_len);
182a8793c76SJason King 			freezero(session_p->encrypt.context,
183a8793c76SJason King 			    sizeof (soft_des_ctx_t));
1847c478bd9Sstevel@tonic-gate 			session_p->encrypt.context = NULL;
1857c478bd9Sstevel@tonic-gate 			rv = CKR_HOST_MEMORY;
1867c478bd9Sstevel@tonic-gate 		}
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_unlock(&session_p->session_mutex);
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 		return (rv);
1917c478bd9Sstevel@tonic-gate 	}
1927c478bd9Sstevel@tonic-gate 
193*fb261280SJason King 	case CKM_AES_ECB:
1947c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC:
1957c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC_PAD:
196cd964fceSMatt Barden 	case CKM_AES_CMAC:
19723c57df7Smcpowers 	case CKM_AES_CTR:
198*fb261280SJason King 	case CKM_AES_CCM:
199*fb261280SJason King 	case CKM_AES_GCM:
200*fb261280SJason King 		return (soft_aes_crypt_init_common(session_p, pMechanism,
201*fb261280SJason King 		    key_p, B_TRUE));
20223c57df7Smcpowers 
2037c478bd9Sstevel@tonic-gate 	case CKM_RC4:
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate 		if (key_p->key_type != CKK_RC4) {
2067c478bd9Sstevel@tonic-gate 			return (CKR_KEY_TYPE_INCONSISTENT);
2077c478bd9Sstevel@tonic-gate 		}
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate 		return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
2107c478bd9Sstevel@tonic-gate 		    B_TRUE));
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 	case CKM_RSA_X_509:
2137c478bd9Sstevel@tonic-gate 	case CKM_RSA_PKCS:
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate 		if (key_p->key_type != CKK_RSA) {
2167c478bd9Sstevel@tonic-gate 			return (CKR_KEY_TYPE_INCONSISTENT);
2177c478bd9Sstevel@tonic-gate 		}
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 		return (soft_rsa_crypt_init_common(session_p, pMechanism,
2207c478bd9Sstevel@tonic-gate 		    key_p, B_TRUE));
2217c478bd9Sstevel@tonic-gate 
222f66d273dSizick 	case CKM_BLOWFISH_CBC:
223f66d273dSizick 	{
224f66d273dSizick 		soft_blowfish_ctx_t *soft_blowfish_ctx;
225f66d273dSizick 
226f66d273dSizick 		if (key_p->key_type != CKK_BLOWFISH)
227f66d273dSizick 			return (CKR_KEY_TYPE_INCONSISTENT);
228f66d273dSizick 
229f66d273dSizick 		if ((pMechanism->pParameter == NULL) ||
230f66d273dSizick 		    (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
231f66d273dSizick 			return (CKR_MECHANISM_PARAM_INVALID);
232f66d273dSizick 
233f66d273dSizick 		rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
234f66d273dSizick 		    key_p, B_TRUE);
235f66d273dSizick 
236f66d273dSizick 		if (rv != CKR_OK)
237f66d273dSizick 			return (rv);
238f66d273dSizick 
239f66d273dSizick 		(void) pthread_mutex_lock(&session_p->session_mutex);
240f66d273dSizick 
241f66d273dSizick 		soft_blowfish_ctx =
242f66d273dSizick 		    (soft_blowfish_ctx_t *)session_p->encrypt.context;
243f66d273dSizick 		/* Copy Initialization Vector (IV) into the context. */
244f66d273dSizick 		(void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
245f66d273dSizick 		    BLOWFISH_BLOCK_LEN);
246f66d273dSizick 
247f66d273dSizick 		/* Allocate a context for Blowfish cipher-block chaining */
248f66d273dSizick 		soft_blowfish_ctx->blowfish_cbc =
249f66d273dSizick 		    (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
25023c57df7Smcpowers 		    soft_blowfish_ctx->keysched_len,
25123c57df7Smcpowers 		    soft_blowfish_ctx->ivec);
252f66d273dSizick 
253f66d273dSizick 		if (soft_blowfish_ctx->blowfish_cbc == NULL) {
254a8793c76SJason King 			freezero(soft_blowfish_ctx->key_sched,
255f66d273dSizick 			    soft_blowfish_ctx->keysched_len);
256a8793c76SJason King 			freezero(session_p->encrypt.context,
257a8793c76SJason King 			    sizeof (soft_blowfish_ctx_t));
258f66d273dSizick 			session_p->encrypt.context = NULL;
259f66d273dSizick 			rv = CKR_HOST_MEMORY;
260f66d273dSizick 		}
261f66d273dSizick 
262f66d273dSizick 		(void) pthread_mutex_unlock(&session_p->session_mutex);
263f66d273dSizick 
264f66d273dSizick 		return (rv);
265f66d273dSizick 	}
2667c478bd9Sstevel@tonic-gate 	default:
2677c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate 
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate /*
2737c478bd9Sstevel@tonic-gate  * soft_encrypt_common()
2747c478bd9Sstevel@tonic-gate  *
2757c478bd9Sstevel@tonic-gate  * Arguments:
2767c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
2777c478bd9Sstevel@tonic-gate  *	pData:		pointer to the input data to be encrypted
2787c478bd9Sstevel@tonic-gate  *	ulDataLen:	length of the input data
2797c478bd9Sstevel@tonic-gate  *	pEncrypted:	pointer to the output data after encryption
2807c478bd9Sstevel@tonic-gate  *	pulEncryptedLen: pointer to the length of the output data
2817c478bd9Sstevel@tonic-gate  *	update:		boolean flag indicates caller is soft_encrypt
2827c478bd9Sstevel@tonic-gate  *			or soft_encrypt_update
2837c478bd9Sstevel@tonic-gate  *
2847c478bd9Sstevel@tonic-gate  * Description:
2857c478bd9Sstevel@tonic-gate  *      This function calls the corresponding encrypt routine based
2867c478bd9Sstevel@tonic-gate  *	on the mechanism.
2877c478bd9Sstevel@tonic-gate  *
2887c478bd9Sstevel@tonic-gate  * Returns:
2897c478bd9Sstevel@tonic-gate  *	see corresponding encrypt routine.
2907c478bd9Sstevel@tonic-gate  */
2917c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncrypted,CK_ULONG_PTR pulEncryptedLen,boolean_t update)2927c478bd9Sstevel@tonic-gate soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
2937c478bd9Sstevel@tonic-gate     CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
2947c478bd9Sstevel@tonic-gate     CK_ULONG_PTR pulEncryptedLen, boolean_t update)
2957c478bd9Sstevel@tonic-gate {
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 	CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	switch (mechanism) {
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 	case CKM_DES_ECB:
3027c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC:
3037c478bd9Sstevel@tonic-gate 	case CKM_DES3_ECB:
3047c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC:
30547c883c7Sdinak 
30647c883c7Sdinak 		if (ulDataLen == 0) {
30747c883c7Sdinak 			*pulEncryptedLen = 0;
30847c883c7Sdinak 			return (CKR_OK);
30947c883c7Sdinak 		}
31047c883c7Sdinak 		/* FALLTHROUGH */
31147c883c7Sdinak 
31247c883c7Sdinak 	case CKM_DES_CBC_PAD:
3137c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC_PAD:
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 		return (soft_des_encrypt_common(session_p, pData,
3167c478bd9Sstevel@tonic-gate 		    ulDataLen, pEncrypted, pulEncryptedLen, update));
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	case CKM_AES_ECB:
3197c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC:
32023c57df7Smcpowers 	case CKM_AES_CTR:
321*fb261280SJason King 	case CKM_AES_CCM:
322cd964fceSMatt Barden 	case CKM_AES_CMAC:
3237c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC_PAD:
324*fb261280SJason King 	case CKM_AES_GCM:
325*fb261280SJason King 		if (update) {
326*fb261280SJason King 			return (soft_aes_encrypt_update(session_p, pData,
327*fb261280SJason King 			    ulDataLen, pEncrypted, pulEncryptedLen));
328*fb261280SJason King 		} else {
329*fb261280SJason King 			return (soft_aes_encrypt(session_p, pData,
330*fb261280SJason King 			    ulDataLen, pEncrypted, pulEncryptedLen));
331*fb261280SJason King 		}
3327c478bd9Sstevel@tonic-gate 
333f66d273dSizick 	case CKM_BLOWFISH_CBC:
334f66d273dSizick 
33547c883c7Sdinak 		if (ulDataLen == 0) {
33647c883c7Sdinak 			*pulEncryptedLen = 0;
33747c883c7Sdinak 			return (CKR_OK);
33847c883c7Sdinak 		}
33947c883c7Sdinak 
340f66d273dSizick 		return (soft_blowfish_encrypt_common(session_p, pData,
341f66d273dSizick 		    ulDataLen, pEncrypted, pulEncryptedLen, update));
342f66d273dSizick 
3437c478bd9Sstevel@tonic-gate 	case CKM_RC4:
34447c883c7Sdinak 
34547c883c7Sdinak 		if (ulDataLen == 0) {
34647c883c7Sdinak 			*pulEncryptedLen = 0;
34747c883c7Sdinak 			return (CKR_OK);
3487c478bd9Sstevel@tonic-gate 		}
34947c883c7Sdinak 
35047c883c7Sdinak 		return (soft_arcfour_crypt(&(session_p->encrypt), pData,
35147c883c7Sdinak 		    ulDataLen, pEncrypted, pulEncryptedLen));
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	case CKM_RSA_X_509:
3547c478bd9Sstevel@tonic-gate 	case CKM_RSA_PKCS:
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 		return (soft_rsa_encrypt_common(session_p, pData,
3577c478bd9Sstevel@tonic-gate 		    ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	default:
3607c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
3617c478bd9Sstevel@tonic-gate 	}
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 
3657c478bd9Sstevel@tonic-gate /*
3667c478bd9Sstevel@tonic-gate  * soft_encrypt()
3677c478bd9Sstevel@tonic-gate  *
3687c478bd9Sstevel@tonic-gate  * Arguments:
3697c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
3707c478bd9Sstevel@tonic-gate  *	pData:		pointer to the input data to be encrypted
3717c478bd9Sstevel@tonic-gate  *	ulDataLen:	length of the input data
3727c478bd9Sstevel@tonic-gate  *	pEncryptedData:	pointer to the output data after encryption
3737c478bd9Sstevel@tonic-gate  *	pulEncryptedDataLen: pointer to the length of the output data
3747c478bd9Sstevel@tonic-gate  *
3757c478bd9Sstevel@tonic-gate  * Description:
3767c478bd9Sstevel@tonic-gate  *      called by C_Encrypt(). This function calls the soft_encrypt_common
3777c478bd9Sstevel@tonic-gate  *	routine.
3787c478bd9Sstevel@tonic-gate  *
3797c478bd9Sstevel@tonic-gate  * Returns:
3807c478bd9Sstevel@tonic-gate  *	see soft_encrypt_common().
3817c478bd9Sstevel@tonic-gate  */
3827c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)3837c478bd9Sstevel@tonic-gate soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData,
3847c478bd9Sstevel@tonic-gate     CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
3857c478bd9Sstevel@tonic-gate     CK_ULONG_PTR pulEncryptedDataLen)
3867c478bd9Sstevel@tonic-gate {
3877c478bd9Sstevel@tonic-gate 	return (soft_encrypt_common(session_p, pData, ulDataLen,
3887c478bd9Sstevel@tonic-gate 	    pEncryptedData, pulEncryptedDataLen, B_FALSE));
3897c478bd9Sstevel@tonic-gate }
3907c478bd9Sstevel@tonic-gate 
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate /*
3937c478bd9Sstevel@tonic-gate  * soft_encrypt_update()
3947c478bd9Sstevel@tonic-gate  *
3957c478bd9Sstevel@tonic-gate  * Arguments:
3967c478bd9Sstevel@tonic-gate  *      session_p:	pointer to soft_session_t struct
3977c478bd9Sstevel@tonic-gate  *      pPart:		pointer to the input data to be digested
3987c478bd9Sstevel@tonic-gate  *      ulPartLen:	length of the input data
3997c478bd9Sstevel@tonic-gate  *	pEncryptedPart:	pointer to the ciphertext
4007c478bd9Sstevel@tonic-gate  *	pulEncryptedPartLen: pointer to the length of the ciphertext
4017c478bd9Sstevel@tonic-gate  *
4027c478bd9Sstevel@tonic-gate  * Description:
4037c478bd9Sstevel@tonic-gate  *      called by C_EncryptUpdate(). This function calls the
4047c478bd9Sstevel@tonic-gate  *	soft_encrypt_common routine (with update flag on).
4057c478bd9Sstevel@tonic-gate  *
4067c478bd9Sstevel@tonic-gate  * Returns:
4077c478bd9Sstevel@tonic-gate  *	see soft_encrypt_common().
4087c478bd9Sstevel@tonic-gate  */
4097c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_update(soft_session_t * session_p,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)4107c478bd9Sstevel@tonic-gate soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
411cd964fceSMatt Barden     CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
412cd964fceSMatt Barden     CK_ULONG_PTR pulEncryptedPartLen)
4137c478bd9Sstevel@tonic-gate {
4147c478bd9Sstevel@tonic-gate 
4157c478bd9Sstevel@tonic-gate 	CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	switch (mechanism) {
4187c478bd9Sstevel@tonic-gate 
4197c478bd9Sstevel@tonic-gate 	case CKM_DES_ECB:
4207c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC:
4217c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC_PAD:
4227c478bd9Sstevel@tonic-gate 	case CKM_DES3_ECB:
4237c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC:
4247c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC_PAD:
4257c478bd9Sstevel@tonic-gate 	case CKM_AES_ECB:
4267c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC:
4277c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC_PAD:
428cd964fceSMatt Barden 	case CKM_AES_CMAC:
42923c57df7Smcpowers 	case CKM_AES_CTR:
430*fb261280SJason King 	case CKM_AES_GCM:
431*fb261280SJason King 	case CKM_AES_CCM:
432f66d273dSizick 	case CKM_BLOWFISH_CBC:
43347c883c7Sdinak 	case CKM_RC4:
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 		return (soft_encrypt_common(session_p, pPart, ulPartLen,
4367c478bd9Sstevel@tonic-gate 		    pEncryptedPart, pulEncryptedPartLen, B_TRUE));
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 	default:
4397c478bd9Sstevel@tonic-gate 		/* PKCS11: The mechanism only supports single-part operation. */
4407c478bd9Sstevel@tonic-gate 		return (CKR_MECHANISM_INVALID);
4417c478bd9Sstevel@tonic-gate 	}
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate /*
4467c478bd9Sstevel@tonic-gate  * soft_encrypt_final()
4477c478bd9Sstevel@tonic-gate  *
4487c478bd9Sstevel@tonic-gate  * Arguments:
4497c478bd9Sstevel@tonic-gate  *      session_p:		pointer to soft_session_t struct
4507c478bd9Sstevel@tonic-gate  *      pLastEncryptedPart:	pointer to the last encrypted data part
4517c478bd9Sstevel@tonic-gate  *      pulLastEncryptedPartLen: pointer to the length of the last
4527c478bd9Sstevel@tonic-gate  *				encrypted data part
4537c478bd9Sstevel@tonic-gate  *
4547c478bd9Sstevel@tonic-gate  * Description:
4557c478bd9Sstevel@tonic-gate  *      called by C_EncryptFinal().
4567c478bd9Sstevel@tonic-gate  *
4577c478bd9Sstevel@tonic-gate  * Returns:
4587c478bd9Sstevel@tonic-gate  *	CKR_OK: success
4597c478bd9Sstevel@tonic-gate  *	CKR_FUNCTION_FAILED: encrypt final function failed
4607c478bd9Sstevel@tonic-gate  *	CKR_DATA_LEN_RANGE: remaining buffer contains bad length
4617c478bd9Sstevel@tonic-gate  */
4627c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_final(soft_session_t * session_p,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)4637c478bd9Sstevel@tonic-gate soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
464cd964fceSMatt Barden     CK_ULONG_PTR pulLastEncryptedPartLen)
4657c478bd9Sstevel@tonic-gate {
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
4687c478bd9Sstevel@tonic-gate 	CK_ULONG out_len;
4697c478bd9Sstevel@tonic-gate 	CK_RV rv = CKR_OK;
4707c478bd9Sstevel@tonic-gate 	int rc;
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_lock(&session_p->session_mutex);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	if (session_p->encrypt.context == NULL) {
4757c478bd9Sstevel@tonic-gate 		rv = CKR_OPERATION_NOT_INITIALIZED;
4767c478bd9Sstevel@tonic-gate 		*pulLastEncryptedPartLen = 0;
4777c478bd9Sstevel@tonic-gate 		goto clean1;
4787c478bd9Sstevel@tonic-gate 	}
4797c478bd9Sstevel@tonic-gate 	switch (mechanism) {
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC_PAD:
4827c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC_PAD:
4837c478bd9Sstevel@tonic-gate 	{
4847c478bd9Sstevel@tonic-gate 		soft_des_ctx_t *soft_des_ctx;
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate 		soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
4877c478bd9Sstevel@tonic-gate 		/*
4887c478bd9Sstevel@tonic-gate 		 * For CKM_DES_CBC_PAD, compute output length with
4897c478bd9Sstevel@tonic-gate 		 * padding. If the remaining buffer has one block
4907c478bd9Sstevel@tonic-gate 		 * of data, then output length will be two blocksize of
4917c478bd9Sstevel@tonic-gate 		 * ciphertext. If the remaining buffer has less than
4927c478bd9Sstevel@tonic-gate 		 * one block of data, then output length will be
4937c478bd9Sstevel@tonic-gate 		 * one blocksize.
4947c478bd9Sstevel@tonic-gate 		 */
4957c478bd9Sstevel@tonic-gate 		if (soft_des_ctx->remain_len == DES_BLOCK_LEN)
4967c478bd9Sstevel@tonic-gate 			out_len = 2 * DES_BLOCK_LEN;
4977c478bd9Sstevel@tonic-gate 		else
4987c478bd9Sstevel@tonic-gate 			out_len = DES_BLOCK_LEN;
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 		if (pLastEncryptedPart == NULL) {
5017c478bd9Sstevel@tonic-gate 			/*
5027c478bd9Sstevel@tonic-gate 			 * Application asks for the length of the output
5037c478bd9Sstevel@tonic-gate 			 * buffer to hold the ciphertext.
5047c478bd9Sstevel@tonic-gate 			 */
5057c478bd9Sstevel@tonic-gate 			*pulLastEncryptedPartLen = out_len;
5067c478bd9Sstevel@tonic-gate 			goto clean1;
5077c478bd9Sstevel@tonic-gate 		} else {
5087c478bd9Sstevel@tonic-gate 			crypto_data_t out;
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate 			/* Copy remaining data to the output buffer. */
5117c478bd9Sstevel@tonic-gate 			(void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
5127c478bd9Sstevel@tonic-gate 			    soft_des_ctx->remain_len);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 			/*
5157c478bd9Sstevel@tonic-gate 			 * Add padding bytes prior to encrypt final.
5167c478bd9Sstevel@tonic-gate 			 */
5177c478bd9Sstevel@tonic-gate 			soft_add_pkcs7_padding(pLastEncryptedPart +
5187c478bd9Sstevel@tonic-gate 			    soft_des_ctx->remain_len, DES_BLOCK_LEN,
5197c478bd9Sstevel@tonic-gate 			    soft_des_ctx->remain_len);
5207c478bd9Sstevel@tonic-gate 
5217c478bd9Sstevel@tonic-gate 			out.cd_format = CRYPTO_DATA_RAW;
5227c478bd9Sstevel@tonic-gate 			out.cd_offset = 0;
5237c478bd9Sstevel@tonic-gate 			out.cd_length = out_len;
5247c478bd9Sstevel@tonic-gate 			out.cd_raw.iov_base = (char *)pLastEncryptedPart;
5257c478bd9Sstevel@tonic-gate 			out.cd_raw.iov_len = out_len;
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 			/* Encrypt multiple blocks of data. */
5287c478bd9Sstevel@tonic-gate 			rc = des_encrypt_contiguous_blocks(
5297c478bd9Sstevel@tonic-gate 			    (des_ctx_t *)soft_des_ctx->des_cbc,
5307c478bd9Sstevel@tonic-gate 			    (char *)pLastEncryptedPart, out_len, &out);
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 			if (rc == 0) {
5337c478bd9Sstevel@tonic-gate 				*pulLastEncryptedPartLen = out_len;
5347c478bd9Sstevel@tonic-gate 			} else {
5357c478bd9Sstevel@tonic-gate 				*pulLastEncryptedPartLen = 0;
5367c478bd9Sstevel@tonic-gate 				rv = CKR_FUNCTION_FAILED;
5377c478bd9Sstevel@tonic-gate 			}
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate 			/* Cleanup memory space. */
5407c478bd9Sstevel@tonic-gate 			free(soft_des_ctx->des_cbc);
541a8793c76SJason King 			freezero(soft_des_ctx->key_sched,
5427c478bd9Sstevel@tonic-gate 			    soft_des_ctx->keysched_len);
5437c478bd9Sstevel@tonic-gate 		}
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 		break;
5467c478bd9Sstevel@tonic-gate 	}
5477c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC:
5487c478bd9Sstevel@tonic-gate 	case CKM_DES_ECB:
5497c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC:
5507c478bd9Sstevel@tonic-gate 	case CKM_DES3_ECB:
5517c478bd9Sstevel@tonic-gate 	{
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 		soft_des_ctx_t *soft_des_ctx;
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 		soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
5567c478bd9Sstevel@tonic-gate 		/*
5577c478bd9Sstevel@tonic-gate 		 * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
5587c478bd9Sstevel@tonic-gate 		 * so when the final is called, the remaining buffer
5597c478bd9Sstevel@tonic-gate 		 * should not contain any more data.
5607c478bd9Sstevel@tonic-gate 		 */
5617c478bd9Sstevel@tonic-gate 		*pulLastEncryptedPartLen = 0;
5627c478bd9Sstevel@tonic-gate 		if (soft_des_ctx->remain_len != 0) {
5637c478bd9Sstevel@tonic-gate 			rv = CKR_DATA_LEN_RANGE;
5647c478bd9Sstevel@tonic-gate 		} else {
5657c478bd9Sstevel@tonic-gate 			if (pLastEncryptedPart == NULL)
5667c478bd9Sstevel@tonic-gate 				goto clean1;
5677c478bd9Sstevel@tonic-gate 		}
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 		/* Cleanup memory space. */
5707c478bd9Sstevel@tonic-gate 		free(soft_des_ctx->des_cbc);
571a8793c76SJason King 		freezero(soft_des_ctx->key_sched,
572a8793c76SJason King 		    soft_des_ctx->keysched_len);
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 		break;
5757c478bd9Sstevel@tonic-gate 	}
5767c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC_PAD:
577cd964fceSMatt Barden 	case CKM_AES_CMAC:
5787c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC:
5797c478bd9Sstevel@tonic-gate 	case CKM_AES_ECB:
58023c57df7Smcpowers 	case CKM_AES_CTR:
581*fb261280SJason King 	case CKM_AES_CCM:
582*fb261280SJason King 	case CKM_AES_GCM:
583*fb261280SJason King 		rv = soft_aes_encrypt_final(session_p, pLastEncryptedPart,
584*fb261280SJason King 		    pulLastEncryptedPartLen);
58523c57df7Smcpowers 		break;
586*fb261280SJason King 
587f66d273dSizick 	case CKM_BLOWFISH_CBC:
588f66d273dSizick 	{
589f66d273dSizick 		soft_blowfish_ctx_t *soft_blowfish_ctx;
590f66d273dSizick 
591f66d273dSizick 		soft_blowfish_ctx =
592f66d273dSizick 		    (soft_blowfish_ctx_t *)session_p->encrypt.context;
593f66d273dSizick 		/*
594f66d273dSizick 		 * CKM_BLOWFISH_CBC does not do any padding, so when the
595f66d273dSizick 		 * final is called, the remaining buffer should not contain
596f66d273dSizick 		 * any more data
597f66d273dSizick 		 */
598f66d273dSizick 		*pulLastEncryptedPartLen = 0;
599f66d273dSizick 		if (soft_blowfish_ctx->remain_len != 0)
600f66d273dSizick 			rv = CKR_DATA_LEN_RANGE;
601f66d273dSizick 		else {
602f66d273dSizick 			if (pLastEncryptedPart == NULL)
603f66d273dSizick 				goto clean1;
604f66d273dSizick 		}
605f66d273dSizick 
606f66d273dSizick 		free(soft_blowfish_ctx->blowfish_cbc);
607a8793c76SJason King 		freezero(soft_blowfish_ctx->key_sched,
608f66d273dSizick 		    soft_blowfish_ctx->keysched_len);
609f66d273dSizick 		break;
610f66d273dSizick 	}
611f66d273dSizick 
6127c478bd9Sstevel@tonic-gate 	case CKM_RC4:
6137c478bd9Sstevel@tonic-gate 	{
6147c478bd9Sstevel@tonic-gate 		ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context;
615c00745c7SZdenek Kotala 		/* Remaining data size is always zero for RC4. */
6167c478bd9Sstevel@tonic-gate 		*pulLastEncryptedPartLen = 0;
617c00745c7SZdenek Kotala 		if (pLastEncryptedPart == NULL)
618c00745c7SZdenek Kotala 			goto clean1;
619a8793c76SJason King 		explicit_bzero(key, sizeof (*key));
6207c478bd9Sstevel@tonic-gate 		break;
6217c478bd9Sstevel@tonic-gate 	}
6227c478bd9Sstevel@tonic-gate 	default:
6237c478bd9Sstevel@tonic-gate 		/* PKCS11: The mechanism only supports single-part operation. */
6247c478bd9Sstevel@tonic-gate 		rv = CKR_MECHANISM_INVALID;
6257c478bd9Sstevel@tonic-gate 		break;
6267c478bd9Sstevel@tonic-gate 	}
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	free(session_p->encrypt.context);
6297c478bd9Sstevel@tonic-gate 	session_p->encrypt.context = NULL;
6307c478bd9Sstevel@tonic-gate clean1:
6317c478bd9Sstevel@tonic-gate 	(void) pthread_mutex_unlock(&session_p->session_mutex);
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	return (rv);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate /*
6377c478bd9Sstevel@tonic-gate  * This function frees the allocated active crypto context and the
6387c478bd9Sstevel@tonic-gate  * lower level of allocated struct as needed.
6397c478bd9Sstevel@tonic-gate  * This function is called by the 1st tier of encrypt/decrypt routines
6407c478bd9Sstevel@tonic-gate  * or by the 2nd tier of session close routine. Since the 1st tier
6417c478bd9Sstevel@tonic-gate  * caller will always call this function without locking the session
6427c478bd9Sstevel@tonic-gate  * mutex and the 2nd tier caller will call with the lock, we add the
643726fad2aSDina K Nimeh  * third parameter "lock_held" to distinguish this case.
6447c478bd9Sstevel@tonic-gate  */
6457c478bd9Sstevel@tonic-gate void
soft_crypt_cleanup(soft_session_t * session_p,boolean_t encrypt,boolean_t lock_held)6467c478bd9Sstevel@tonic-gate soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
647cd964fceSMatt Barden     boolean_t lock_held)
6487c478bd9Sstevel@tonic-gate {
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate 	crypto_active_op_t *active_op;
6517c478bd9Sstevel@tonic-gate 	boolean_t lock_true = B_TRUE;
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 	if (!lock_held)
6547c478bd9Sstevel@tonic-gate 		(void) pthread_mutex_lock(&session_p->session_mutex);
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 	active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	switch (active_op->mech.mechanism) {
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC_PAD:
6617c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC_PAD:
6627c478bd9Sstevel@tonic-gate 	case CKM_DES_CBC:
6637c478bd9Sstevel@tonic-gate 	case CKM_DES_ECB:
6647c478bd9Sstevel@tonic-gate 	case CKM_DES3_CBC:
6657c478bd9Sstevel@tonic-gate 	case CKM_DES3_ECB:
6667c478bd9Sstevel@tonic-gate 	{
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 		soft_des_ctx_t *soft_des_ctx =
6697c478bd9Sstevel@tonic-gate 		    (soft_des_ctx_t *)active_op->context;
6707c478bd9Sstevel@tonic-gate 		des_ctx_t *des_ctx;
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 		if (soft_des_ctx != NULL) {
6737c478bd9Sstevel@tonic-gate 			des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
6747c478bd9Sstevel@tonic-gate 			if (des_ctx != NULL) {
675a8793c76SJason King 				explicit_bzero(des_ctx->dc_keysched,
6767c478bd9Sstevel@tonic-gate 				    des_ctx->dc_keysched_len);
6777c478bd9Sstevel@tonic-gate 				free(soft_des_ctx->des_cbc);
6787c478bd9Sstevel@tonic-gate 			}
679a8793c76SJason King 			freezero(soft_des_ctx->key_sched,
6807c478bd9Sstevel@tonic-gate 			    soft_des_ctx->keysched_len);
6817c478bd9Sstevel@tonic-gate 		}
6827c478bd9Sstevel@tonic-gate 		break;
6837c478bd9Sstevel@tonic-gate 	}
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC_PAD:
6867c478bd9Sstevel@tonic-gate 	case CKM_AES_CBC:
687cd964fceSMatt Barden 	case CKM_AES_CMAC:
6887c478bd9Sstevel@tonic-gate 	case CKM_AES_ECB:
689*fb261280SJason King 	case CKM_AES_GCM:
690*fb261280SJason King 	case CKM_AES_CCM:
691*fb261280SJason King 	case CKM_AES_CTR:
692*fb261280SJason King 		soft_aes_free_ctx(active_op->context);
693*fb261280SJason King 		active_op->context = NULL;
6947c478bd9Sstevel@tonic-gate 		break;
6957c478bd9Sstevel@tonic-gate 
696f66d273dSizick 	case CKM_BLOWFISH_CBC:
697f66d273dSizick 	{
698f66d273dSizick 		soft_blowfish_ctx_t *soft_blowfish_ctx =
699f66d273dSizick 		    (soft_blowfish_ctx_t *)active_op->context;
700f66d273dSizick 		blowfish_ctx_t *blowfish_ctx;
701f66d273dSizick 
702f66d273dSizick 		if (soft_blowfish_ctx != NULL) {
703f66d273dSizick 			blowfish_ctx =
704f66d273dSizick 			    (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
705f66d273dSizick 			if (blowfish_ctx != NULL) {
706a8793c76SJason King 				explicit_bzero(blowfish_ctx->bc_keysched,
707f66d273dSizick 				    blowfish_ctx->bc_keysched_len);
708f66d273dSizick 				free(soft_blowfish_ctx->blowfish_cbc);
709f66d273dSizick 			}
710f66d273dSizick 
711a8793c76SJason King 			freezero(soft_blowfish_ctx->key_sched,
712f66d273dSizick 			    soft_blowfish_ctx->keysched_len);
713f66d273dSizick 		}
714f66d273dSizick 		break;
715f66d273dSizick 	}
716f66d273dSizick 
7177c478bd9Sstevel@tonic-gate 	case CKM_RC4:
7187c478bd9Sstevel@tonic-gate 	{
7197c478bd9Sstevel@tonic-gate 		ARCFour_key *key = (ARCFour_key *)active_op->context;
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 		if (key != NULL)
722a8793c76SJason King 			explicit_bzero(key, sizeof (*key));
7237c478bd9Sstevel@tonic-gate 		break;
7247c478bd9Sstevel@tonic-gate 	}
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate 	case CKM_RSA_X_509:
7277c478bd9Sstevel@tonic-gate 	case CKM_RSA_PKCS:
7284c21f043Sizick 	{
7294c21f043Sizick 		soft_rsa_ctx_t *rsa_ctx =
7304c21f043Sizick 		    (soft_rsa_ctx_t *)active_op->context;
7314c21f043Sizick 
7324c21f043Sizick 		if (rsa_ctx != NULL)
7334c21f043Sizick 			if (rsa_ctx->key != NULL) {
7344c21f043Sizick 				soft_cleanup_object(rsa_ctx->key);
7354c21f043Sizick 				free(rsa_ctx->key);
7364c21f043Sizick 			}
7374c21f043Sizick 
7387c478bd9Sstevel@tonic-gate 		break;
7394c21f043Sizick 	}
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 	} /* switch */
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate 	if (active_op->context != NULL) {
7447c478bd9Sstevel@tonic-gate 		free(active_op->context);
7457c478bd9Sstevel@tonic-gate 		active_op->context = NULL;
7467c478bd9Sstevel@tonic-gate 	}
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 	active_op->flags = 0;
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 	if (!lock_held)
7517c478bd9Sstevel@tonic-gate 		SES_REFRELE(session_p, lock_true);
7527c478bd9Sstevel@tonic-gate }
753