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 */
21*726fad2aSDina K Nimeh
227c478bd9Sstevel@tonic-gate /*
23*726fad2aSDina K Nimeh * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <pthread.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <string.h>
297c478bd9Sstevel@tonic-gate #include <strings.h>
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
3223c57df7Smcpowers #include <modes/modes.h>
337c478bd9Sstevel@tonic-gate #include <arcfour.h>
347c478bd9Sstevel@tonic-gate #include "softSession.h"
357c478bd9Sstevel@tonic-gate #include "softObject.h"
367c478bd9Sstevel@tonic-gate #include "softOps.h"
377c478bd9Sstevel@tonic-gate #include "softCrypt.h"
387c478bd9Sstevel@tonic-gate #include "softRSA.h"
397c478bd9Sstevel@tonic-gate
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate * Add padding bytes with the value of length of padding.
427c478bd9Sstevel@tonic-gate */
437c478bd9Sstevel@tonic-gate void
soft_add_pkcs7_padding(CK_BYTE * buf,int block_size,CK_ULONG data_len)447c478bd9Sstevel@tonic-gate soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
457c478bd9Sstevel@tonic-gate {
46*726fad2aSDina K Nimeh (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
477c478bd9Sstevel@tonic-gate }
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate * Perform encrypt init operation internally for the support of
517c478bd9Sstevel@tonic-gate * CKM_DES_MAC and CKM_DES_MAC_GENERAL
527c478bd9Sstevel@tonic-gate *
537c478bd9Sstevel@tonic-gate * This function is called with the session being held, and without
547c478bd9Sstevel@tonic-gate * its mutex taken.
557c478bd9Sstevel@tonic-gate */
567c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)577c478bd9Sstevel@tonic-gate soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
587c478bd9Sstevel@tonic-gate pMechanism, soft_object_t *key_p)
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate CK_RV rv;
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate /* Check to see if encrypt operation is already active */
657c478bd9Sstevel@tonic-gate if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
667c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
677c478bd9Sstevel@tonic-gate return (CKR_OPERATION_ACTIVE);
687c478bd9Sstevel@tonic-gate }
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate rv = soft_encrypt_init(session_p, pMechanism, key_p);
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
777c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
787c478bd9Sstevel@tonic-gate session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
797c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate return (rv);
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate /*
867c478bd9Sstevel@tonic-gate * soft_encrypt_init()
877c478bd9Sstevel@tonic-gate *
887c478bd9Sstevel@tonic-gate * Arguments:
897c478bd9Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
907c478bd9Sstevel@tonic-gate * pMechanism: pointer to CK_MECHANISM struct provided by application
917c478bd9Sstevel@tonic-gate * key_p: pointer to key soft_object_t struct
927c478bd9Sstevel@tonic-gate *
937c478bd9Sstevel@tonic-gate * Description:
947c478bd9Sstevel@tonic-gate * called by C_EncryptInit(). This function calls the corresponding
957c478bd9Sstevel@tonic-gate * encrypt init routine based on the mechanism.
967c478bd9Sstevel@tonic-gate *
977c478bd9Sstevel@tonic-gate * Returns:
987c478bd9Sstevel@tonic-gate * CKR_OK: success
997c478bd9Sstevel@tonic-gate * CKR_HOST_MEMORY: run out of system memory
1007c478bd9Sstevel@tonic-gate * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
1017c478bd9Sstevel@tonic-gate * CKR_MECHANISM_INVALID: invalid mechanism type
1027c478bd9Sstevel@tonic-gate * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
1037c478bd9Sstevel@tonic-gate * with the specified mechanism
1047c478bd9Sstevel@tonic-gate */
1057c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)1067c478bd9Sstevel@tonic-gate soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1077c478bd9Sstevel@tonic-gate soft_object_t *key_p)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate CK_RV rv;
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate switch (pMechanism->mechanism) {
1137c478bd9Sstevel@tonic-gate
1147c478bd9Sstevel@tonic-gate case CKM_DES_ECB:
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate if (key_p->key_type != CKK_DES) {
1177c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate goto ecb_common;
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate case CKM_DES3_ECB:
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate if ((key_p->key_type != CKK_DES2) &&
1247c478bd9Sstevel@tonic-gate (key_p->key_type != CKK_DES3)) {
1257c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate ecb_common:
1297c478bd9Sstevel@tonic-gate return (soft_des_crypt_init_common(session_p, pMechanism,
1307c478bd9Sstevel@tonic-gate key_p, B_TRUE));
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate case CKM_DES_CBC:
1337c478bd9Sstevel@tonic-gate case CKM_DES_CBC_PAD:
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate if (key_p->key_type != CKK_DES) {
1367c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1377c478bd9Sstevel@tonic-gate }
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate goto cbc_common;
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate case CKM_DES3_CBC:
1427c478bd9Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
1437c478bd9Sstevel@tonic-gate {
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
1467c478bd9Sstevel@tonic-gate
1477c478bd9Sstevel@tonic-gate if ((key_p->key_type != CKK_DES2) &&
1487c478bd9Sstevel@tonic-gate (key_p->key_type != CKK_DES3)) {
1497c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate cbc_common:
1537c478bd9Sstevel@tonic-gate if ((pMechanism->pParameter == NULL) ||
1547c478bd9Sstevel@tonic-gate (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
1557c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_PARAM_INVALID);
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate rv = soft_des_crypt_init_common(session_p, pMechanism,
1597c478bd9Sstevel@tonic-gate key_p, B_TRUE);
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1627c478bd9Sstevel@tonic-gate return (rv);
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
1677c478bd9Sstevel@tonic-gate /* Copy Initialization Vector (IV) into the context. */
1687c478bd9Sstevel@tonic-gate (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
1697c478bd9Sstevel@tonic-gate DES_BLOCK_LEN);
1707c478bd9Sstevel@tonic-gate
1717c478bd9Sstevel@tonic-gate /* Allocate a context for DES cipher-block chaining. */
1727c478bd9Sstevel@tonic-gate soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
1737c478bd9Sstevel@tonic-gate soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
1747c478bd9Sstevel@tonic-gate soft_des_ctx->ivec, key_p->key_type);
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate if (soft_des_ctx->des_cbc == NULL) {
1777c478bd9Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
1787c478bd9Sstevel@tonic-gate soft_des_ctx->keysched_len);
1797c478bd9Sstevel@tonic-gate free(soft_des_ctx->key_sched);
1807c478bd9Sstevel@tonic-gate free(session_p->encrypt.context);
1817c478bd9Sstevel@tonic-gate session_p->encrypt.context = NULL;
1827c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate return (rv);
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate case CKM_AES_ECB:
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate if (key_p->key_type != CKK_AES) {
1927c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate return (soft_aes_crypt_init_common(session_p, pMechanism,
1967c478bd9Sstevel@tonic-gate key_p, B_TRUE));
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate case CKM_AES_CBC:
1997c478bd9Sstevel@tonic-gate case CKM_AES_CBC_PAD:
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate if (key_p->key_type != CKK_AES) {
2047c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate if ((pMechanism->pParameter == NULL) ||
2087c478bd9Sstevel@tonic-gate (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
2097c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_PARAM_INVALID);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate rv = soft_aes_crypt_init_common(session_p, pMechanism,
2137c478bd9Sstevel@tonic-gate key_p, B_TRUE);
2147c478bd9Sstevel@tonic-gate
2157c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
2167c478bd9Sstevel@tonic-gate return (rv);
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
2217c478bd9Sstevel@tonic-gate /* Copy Initialization Vector (IV) into the context. */
2227c478bd9Sstevel@tonic-gate (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter,
2237c478bd9Sstevel@tonic-gate AES_BLOCK_LEN);
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate /* Allocate a context for AES cipher-block chaining. */
2267c478bd9Sstevel@tonic-gate soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2277c478bd9Sstevel@tonic-gate soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2287c478bd9Sstevel@tonic-gate soft_aes_ctx->ivec);
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate if (soft_aes_ctx->aes_cbc == NULL) {
2317c478bd9Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
2327c478bd9Sstevel@tonic-gate soft_aes_ctx->keysched_len);
2337c478bd9Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
2347c478bd9Sstevel@tonic-gate free(session_p->encrypt.context);
2357c478bd9Sstevel@tonic-gate session_p->encrypt.context = NULL;
2367c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate return (rv);
2427c478bd9Sstevel@tonic-gate }
24323c57df7Smcpowers case CKM_AES_CTR:
24423c57df7Smcpowers {
24523c57df7Smcpowers soft_aes_ctx_t *soft_aes_ctx;
24623c57df7Smcpowers
24723c57df7Smcpowers if (key_p->key_type != CKK_AES) {
24823c57df7Smcpowers return (CKR_KEY_TYPE_INCONSISTENT);
24923c57df7Smcpowers }
25023c57df7Smcpowers
25123c57df7Smcpowers if (pMechanism->pParameter == NULL ||
25223c57df7Smcpowers pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
25323c57df7Smcpowers return (CKR_MECHANISM_PARAM_INVALID);
25423c57df7Smcpowers }
25523c57df7Smcpowers
25623c57df7Smcpowers rv = soft_aes_crypt_init_common(session_p, pMechanism,
25723c57df7Smcpowers key_p, B_TRUE);
25823c57df7Smcpowers
25923c57df7Smcpowers if (rv != CKR_OK)
26023c57df7Smcpowers return (rv);
26123c57df7Smcpowers
26223c57df7Smcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
26323c57df7Smcpowers
26423c57df7Smcpowers soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
26523c57df7Smcpowers soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
26623c57df7Smcpowers soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
26723c57df7Smcpowers pMechanism->pParameter);
26823c57df7Smcpowers
26923c57df7Smcpowers if (soft_aes_ctx->aes_cbc == NULL) {
27023c57df7Smcpowers bzero(soft_aes_ctx->key_sched,
27123c57df7Smcpowers soft_aes_ctx->keysched_len);
27223c57df7Smcpowers free(soft_aes_ctx->key_sched);
27323c57df7Smcpowers free(session_p->encrypt.context);
27423c57df7Smcpowers session_p->encrypt.context = NULL;
27523c57df7Smcpowers rv = CKR_HOST_MEMORY;
27623c57df7Smcpowers }
27723c57df7Smcpowers
27823c57df7Smcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
27923c57df7Smcpowers
28023c57df7Smcpowers return (rv);
28123c57df7Smcpowers }
2827c478bd9Sstevel@tonic-gate case CKM_RC4:
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate if (key_p->key_type != CKK_RC4) {
2857c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
2897c478bd9Sstevel@tonic-gate B_TRUE));
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate case CKM_RSA_X_509:
2927c478bd9Sstevel@tonic-gate case CKM_RSA_PKCS:
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate if (key_p->key_type != CKK_RSA) {
2957c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate return (soft_rsa_crypt_init_common(session_p, pMechanism,
2997c478bd9Sstevel@tonic-gate key_p, B_TRUE));
3007c478bd9Sstevel@tonic-gate
301f66d273dSizick case CKM_BLOWFISH_CBC:
302f66d273dSizick {
303f66d273dSizick soft_blowfish_ctx_t *soft_blowfish_ctx;
304f66d273dSizick
305f66d273dSizick if (key_p->key_type != CKK_BLOWFISH)
306f66d273dSizick return (CKR_KEY_TYPE_INCONSISTENT);
307f66d273dSizick
308f66d273dSizick if ((pMechanism->pParameter == NULL) ||
309f66d273dSizick (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
310f66d273dSizick return (CKR_MECHANISM_PARAM_INVALID);
311f66d273dSizick
312f66d273dSizick rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
313f66d273dSizick key_p, B_TRUE);
314f66d273dSizick
315f66d273dSizick if (rv != CKR_OK)
316f66d273dSizick return (rv);
317f66d273dSizick
318f66d273dSizick (void) pthread_mutex_lock(&session_p->session_mutex);
319f66d273dSizick
320f66d273dSizick soft_blowfish_ctx =
321f66d273dSizick (soft_blowfish_ctx_t *)session_p->encrypt.context;
322f66d273dSizick /* Copy Initialization Vector (IV) into the context. */
323f66d273dSizick (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
324f66d273dSizick BLOWFISH_BLOCK_LEN);
325f66d273dSizick
326f66d273dSizick /* Allocate a context for Blowfish cipher-block chaining */
327f66d273dSizick soft_blowfish_ctx->blowfish_cbc =
328f66d273dSizick (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
329f66d273dSizick soft_blowfish_ctx->keysched_len,
330f66d273dSizick soft_blowfish_ctx->ivec);
331f66d273dSizick
332f66d273dSizick if (soft_blowfish_ctx->blowfish_cbc == NULL) {
333f66d273dSizick bzero(soft_blowfish_ctx->key_sched,
334f66d273dSizick soft_blowfish_ctx->keysched_len);
335f66d273dSizick free(soft_blowfish_ctx->key_sched);
336f66d273dSizick free(session_p->encrypt.context);
337f66d273dSizick session_p->encrypt.context = NULL;
338f66d273dSizick rv = CKR_HOST_MEMORY;
339f66d273dSizick }
340f66d273dSizick
341f66d273dSizick (void) pthread_mutex_unlock(&session_p->session_mutex);
342f66d273dSizick
343f66d273dSizick return (rv);
344f66d273dSizick }
3457c478bd9Sstevel@tonic-gate default:
3467c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate }
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate
3517c478bd9Sstevel@tonic-gate /*
3527c478bd9Sstevel@tonic-gate * soft_encrypt_common()
3537c478bd9Sstevel@tonic-gate *
3547c478bd9Sstevel@tonic-gate * Arguments:
3557c478bd9Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
3567c478bd9Sstevel@tonic-gate * pData: pointer to the input data to be encrypted
3577c478bd9Sstevel@tonic-gate * ulDataLen: length of the input data
3587c478bd9Sstevel@tonic-gate * pEncrypted: pointer to the output data after encryption
3597c478bd9Sstevel@tonic-gate * pulEncryptedLen: pointer to the length of the output data
3607c478bd9Sstevel@tonic-gate * update: boolean flag indicates caller is soft_encrypt
3617c478bd9Sstevel@tonic-gate * or soft_encrypt_update
3627c478bd9Sstevel@tonic-gate *
3637c478bd9Sstevel@tonic-gate * Description:
3647c478bd9Sstevel@tonic-gate * This function calls the corresponding encrypt routine based
3657c478bd9Sstevel@tonic-gate * on the mechanism.
3667c478bd9Sstevel@tonic-gate *
3677c478bd9Sstevel@tonic-gate * Returns:
3687c478bd9Sstevel@tonic-gate * see corresponding encrypt routine.
3697c478bd9Sstevel@tonic-gate */
3707c478bd9Sstevel@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)3717c478bd9Sstevel@tonic-gate soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
3727c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
3737c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedLen, boolean_t update)
3747c478bd9Sstevel@tonic-gate {
3757c478bd9Sstevel@tonic-gate
3767c478bd9Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate switch (mechanism) {
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate case CKM_DES_ECB:
3817c478bd9Sstevel@tonic-gate case CKM_DES_CBC:
3827c478bd9Sstevel@tonic-gate case CKM_DES3_ECB:
3837c478bd9Sstevel@tonic-gate case CKM_DES3_CBC:
38447c883c7Sdinak
38547c883c7Sdinak if (ulDataLen == 0) {
38647c883c7Sdinak *pulEncryptedLen = 0;
38747c883c7Sdinak return (CKR_OK);
38847c883c7Sdinak }
38947c883c7Sdinak /* FALLTHROUGH */
39047c883c7Sdinak
39147c883c7Sdinak case CKM_DES_CBC_PAD:
3927c478bd9Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate return (soft_des_encrypt_common(session_p, pData,
3957c478bd9Sstevel@tonic-gate ulDataLen, pEncrypted, pulEncryptedLen, update));
3967c478bd9Sstevel@tonic-gate
3977c478bd9Sstevel@tonic-gate case CKM_AES_ECB:
3987c478bd9Sstevel@tonic-gate case CKM_AES_CBC:
39923c57df7Smcpowers case CKM_AES_CTR:
40047c883c7Sdinak
40147c883c7Sdinak if (ulDataLen == 0) {
40247c883c7Sdinak *pulEncryptedLen = 0;
40347c883c7Sdinak return (CKR_OK);
40447c883c7Sdinak }
40547c883c7Sdinak /* FALLTHROUGH */
40647c883c7Sdinak
4077c478bd9Sstevel@tonic-gate case CKM_AES_CBC_PAD:
4087c478bd9Sstevel@tonic-gate
4097c478bd9Sstevel@tonic-gate return (soft_aes_encrypt_common(session_p, pData,
4107c478bd9Sstevel@tonic-gate ulDataLen, pEncrypted, pulEncryptedLen, update));
4117c478bd9Sstevel@tonic-gate
412f66d273dSizick case CKM_BLOWFISH_CBC:
413f66d273dSizick
41447c883c7Sdinak if (ulDataLen == 0) {
41547c883c7Sdinak *pulEncryptedLen = 0;
41647c883c7Sdinak return (CKR_OK);
41747c883c7Sdinak }
41847c883c7Sdinak
419f66d273dSizick return (soft_blowfish_encrypt_common(session_p, pData,
420f66d273dSizick ulDataLen, pEncrypted, pulEncryptedLen, update));
421f66d273dSizick
4227c478bd9Sstevel@tonic-gate case CKM_RC4:
4237c478bd9Sstevel@tonic-gate
42447c883c7Sdinak if (ulDataLen == 0) {
42547c883c7Sdinak *pulEncryptedLen = 0;
42647c883c7Sdinak return (CKR_OK);
4277c478bd9Sstevel@tonic-gate }
42847c883c7Sdinak
42947c883c7Sdinak return (soft_arcfour_crypt(&(session_p->encrypt), pData,
43047c883c7Sdinak ulDataLen, pEncrypted, pulEncryptedLen));
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate case CKM_RSA_X_509:
4337c478bd9Sstevel@tonic-gate case CKM_RSA_PKCS:
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate return (soft_rsa_encrypt_common(session_p, pData,
4367c478bd9Sstevel@tonic-gate ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
4377c478bd9Sstevel@tonic-gate
4387c478bd9Sstevel@tonic-gate default:
4397c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
4407c478bd9Sstevel@tonic-gate }
4417c478bd9Sstevel@tonic-gate }
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate
4447c478bd9Sstevel@tonic-gate /*
4457c478bd9Sstevel@tonic-gate * soft_encrypt()
4467c478bd9Sstevel@tonic-gate *
4477c478bd9Sstevel@tonic-gate * Arguments:
4487c478bd9Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
4497c478bd9Sstevel@tonic-gate * pData: pointer to the input data to be encrypted
4507c478bd9Sstevel@tonic-gate * ulDataLen: length of the input data
4517c478bd9Sstevel@tonic-gate * pEncryptedData: pointer to the output data after encryption
4527c478bd9Sstevel@tonic-gate * pulEncryptedDataLen: pointer to the length of the output data
4537c478bd9Sstevel@tonic-gate *
4547c478bd9Sstevel@tonic-gate * Description:
4557c478bd9Sstevel@tonic-gate * called by C_Encrypt(). This function calls the soft_encrypt_common
4567c478bd9Sstevel@tonic-gate * routine.
4577c478bd9Sstevel@tonic-gate *
4587c478bd9Sstevel@tonic-gate * Returns:
4597c478bd9Sstevel@tonic-gate * see soft_encrypt_common().
4607c478bd9Sstevel@tonic-gate */
4617c478bd9Sstevel@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)4627c478bd9Sstevel@tonic-gate soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData,
4637c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
4647c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedDataLen)
4657c478bd9Sstevel@tonic-gate {
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate return (soft_encrypt_common(session_p, pData, ulDataLen,
4687c478bd9Sstevel@tonic-gate pEncryptedData, pulEncryptedDataLen, B_FALSE));
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate
4727c478bd9Sstevel@tonic-gate /*
4737c478bd9Sstevel@tonic-gate * soft_encrypt_update()
4747c478bd9Sstevel@tonic-gate *
4757c478bd9Sstevel@tonic-gate * Arguments:
4767c478bd9Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
4777c478bd9Sstevel@tonic-gate * pPart: pointer to the input data to be digested
4787c478bd9Sstevel@tonic-gate * ulPartLen: length of the input data
4797c478bd9Sstevel@tonic-gate * pEncryptedPart: pointer to the ciphertext
4807c478bd9Sstevel@tonic-gate * pulEncryptedPartLen: pointer to the length of the ciphertext
4817c478bd9Sstevel@tonic-gate *
4827c478bd9Sstevel@tonic-gate * Description:
4837c478bd9Sstevel@tonic-gate * called by C_EncryptUpdate(). This function calls the
4847c478bd9Sstevel@tonic-gate * soft_encrypt_common routine (with update flag on).
4857c478bd9Sstevel@tonic-gate *
4867c478bd9Sstevel@tonic-gate * Returns:
4877c478bd9Sstevel@tonic-gate * see soft_encrypt_common().
4887c478bd9Sstevel@tonic-gate */
4897c478bd9Sstevel@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)4907c478bd9Sstevel@tonic-gate soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
4917c478bd9Sstevel@tonic-gate CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
4927c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedPartLen)
4937c478bd9Sstevel@tonic-gate {
4947c478bd9Sstevel@tonic-gate
4957c478bd9Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate switch (mechanism) {
4987c478bd9Sstevel@tonic-gate
4997c478bd9Sstevel@tonic-gate case CKM_DES_ECB:
5007c478bd9Sstevel@tonic-gate case CKM_DES_CBC:
5017c478bd9Sstevel@tonic-gate case CKM_DES_CBC_PAD:
5027c478bd9Sstevel@tonic-gate case CKM_DES3_ECB:
5037c478bd9Sstevel@tonic-gate case CKM_DES3_CBC:
5047c478bd9Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
5057c478bd9Sstevel@tonic-gate case CKM_AES_ECB:
5067c478bd9Sstevel@tonic-gate case CKM_AES_CBC:
5077c478bd9Sstevel@tonic-gate case CKM_AES_CBC_PAD:
50823c57df7Smcpowers case CKM_AES_CTR:
509f66d273dSizick case CKM_BLOWFISH_CBC:
51047c883c7Sdinak case CKM_RC4:
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate return (soft_encrypt_common(session_p, pPart, ulPartLen,
5137c478bd9Sstevel@tonic-gate pEncryptedPart, pulEncryptedPartLen, B_TRUE));
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate default:
5167c478bd9Sstevel@tonic-gate /* PKCS11: The mechanism only supports single-part operation. */
5177c478bd9Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
5187c478bd9Sstevel@tonic-gate }
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate /*
5237c478bd9Sstevel@tonic-gate * soft_encrypt_final()
5247c478bd9Sstevel@tonic-gate *
5257c478bd9Sstevel@tonic-gate * Arguments:
5267c478bd9Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
5277c478bd9Sstevel@tonic-gate * pLastEncryptedPart: pointer to the last encrypted data part
5287c478bd9Sstevel@tonic-gate * pulLastEncryptedPartLen: pointer to the length of the last
5297c478bd9Sstevel@tonic-gate * encrypted data part
5307c478bd9Sstevel@tonic-gate *
5317c478bd9Sstevel@tonic-gate * Description:
5327c478bd9Sstevel@tonic-gate * called by C_EncryptFinal().
5337c478bd9Sstevel@tonic-gate *
5347c478bd9Sstevel@tonic-gate * Returns:
5357c478bd9Sstevel@tonic-gate * CKR_OK: success
5367c478bd9Sstevel@tonic-gate * CKR_FUNCTION_FAILED: encrypt final function failed
5377c478bd9Sstevel@tonic-gate * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
5387c478bd9Sstevel@tonic-gate */
5397c478bd9Sstevel@tonic-gate CK_RV
soft_encrypt_final(soft_session_t * session_p,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)5407c478bd9Sstevel@tonic-gate soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
5417c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulLastEncryptedPartLen)
5427c478bd9Sstevel@tonic-gate {
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
5457c478bd9Sstevel@tonic-gate CK_ULONG out_len;
5467c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
5477c478bd9Sstevel@tonic-gate int rc;
5487c478bd9Sstevel@tonic-gate
5497c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
5507c478bd9Sstevel@tonic-gate
5517c478bd9Sstevel@tonic-gate if (session_p->encrypt.context == NULL) {
5527c478bd9Sstevel@tonic-gate rv = CKR_OPERATION_NOT_INITIALIZED;
5537c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
5547c478bd9Sstevel@tonic-gate goto clean1;
5557c478bd9Sstevel@tonic-gate }
5567c478bd9Sstevel@tonic-gate switch (mechanism) {
5577c478bd9Sstevel@tonic-gate
5587c478bd9Sstevel@tonic-gate case CKM_DES_CBC_PAD:
5597c478bd9Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
5607c478bd9Sstevel@tonic-gate {
5617c478bd9Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
5647c478bd9Sstevel@tonic-gate /*
5657c478bd9Sstevel@tonic-gate * For CKM_DES_CBC_PAD, compute output length with
5667c478bd9Sstevel@tonic-gate * padding. If the remaining buffer has one block
5677c478bd9Sstevel@tonic-gate * of data, then output length will be two blocksize of
5687c478bd9Sstevel@tonic-gate * ciphertext. If the remaining buffer has less than
5697c478bd9Sstevel@tonic-gate * one block of data, then output length will be
5707c478bd9Sstevel@tonic-gate * one blocksize.
5717c478bd9Sstevel@tonic-gate */
5727c478bd9Sstevel@tonic-gate if (soft_des_ctx->remain_len == DES_BLOCK_LEN)
5737c478bd9Sstevel@tonic-gate out_len = 2 * DES_BLOCK_LEN;
5747c478bd9Sstevel@tonic-gate else
5757c478bd9Sstevel@tonic-gate out_len = DES_BLOCK_LEN;
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate if (pLastEncryptedPart == NULL) {
5787c478bd9Sstevel@tonic-gate /*
5797c478bd9Sstevel@tonic-gate * Application asks for the length of the output
5807c478bd9Sstevel@tonic-gate * buffer to hold the ciphertext.
5817c478bd9Sstevel@tonic-gate */
5827c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
5837c478bd9Sstevel@tonic-gate goto clean1;
5847c478bd9Sstevel@tonic-gate } else {
5857c478bd9Sstevel@tonic-gate crypto_data_t out;
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate /* Copy remaining data to the output buffer. */
5887c478bd9Sstevel@tonic-gate (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
5897c478bd9Sstevel@tonic-gate soft_des_ctx->remain_len);
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate /*
5927c478bd9Sstevel@tonic-gate * Add padding bytes prior to encrypt final.
5937c478bd9Sstevel@tonic-gate */
5947c478bd9Sstevel@tonic-gate soft_add_pkcs7_padding(pLastEncryptedPart +
5957c478bd9Sstevel@tonic-gate soft_des_ctx->remain_len, DES_BLOCK_LEN,
5967c478bd9Sstevel@tonic-gate soft_des_ctx->remain_len);
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate out.cd_format = CRYPTO_DATA_RAW;
5997c478bd9Sstevel@tonic-gate out.cd_offset = 0;
6007c478bd9Sstevel@tonic-gate out.cd_length = out_len;
6017c478bd9Sstevel@tonic-gate out.cd_raw.iov_base = (char *)pLastEncryptedPart;
6027c478bd9Sstevel@tonic-gate out.cd_raw.iov_len = out_len;
6037c478bd9Sstevel@tonic-gate
6047c478bd9Sstevel@tonic-gate /* Encrypt multiple blocks of data. */
6057c478bd9Sstevel@tonic-gate rc = des_encrypt_contiguous_blocks(
6067c478bd9Sstevel@tonic-gate (des_ctx_t *)soft_des_ctx->des_cbc,
6077c478bd9Sstevel@tonic-gate (char *)pLastEncryptedPart, out_len, &out);
6087c478bd9Sstevel@tonic-gate
6097c478bd9Sstevel@tonic-gate if (rc == 0) {
6107c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
6117c478bd9Sstevel@tonic-gate } else {
6127c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
6137c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate
6167c478bd9Sstevel@tonic-gate /* Cleanup memory space. */
6177c478bd9Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
6187c478bd9Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
6197c478bd9Sstevel@tonic-gate soft_des_ctx->keysched_len);
6207c478bd9Sstevel@tonic-gate free(soft_des_ctx->key_sched);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate break;
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate case CKM_DES_CBC:
6267c478bd9Sstevel@tonic-gate case CKM_DES_ECB:
6277c478bd9Sstevel@tonic-gate case CKM_DES3_CBC:
6287c478bd9Sstevel@tonic-gate case CKM_DES3_ECB:
6297c478bd9Sstevel@tonic-gate {
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
6327c478bd9Sstevel@tonic-gate
6337c478bd9Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
6347c478bd9Sstevel@tonic-gate /*
6357c478bd9Sstevel@tonic-gate * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
6367c478bd9Sstevel@tonic-gate * so when the final is called, the remaining buffer
6377c478bd9Sstevel@tonic-gate * should not contain any more data.
6387c478bd9Sstevel@tonic-gate */
6397c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
6407c478bd9Sstevel@tonic-gate if (soft_des_ctx->remain_len != 0) {
6417c478bd9Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
6427c478bd9Sstevel@tonic-gate } else {
6437c478bd9Sstevel@tonic-gate if (pLastEncryptedPart == NULL)
6447c478bd9Sstevel@tonic-gate goto clean1;
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate /* Cleanup memory space. */
6487c478bd9Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
6497c478bd9Sstevel@tonic-gate bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
6507c478bd9Sstevel@tonic-gate free(soft_des_ctx->key_sched);
6517c478bd9Sstevel@tonic-gate
6527c478bd9Sstevel@tonic-gate break;
6537c478bd9Sstevel@tonic-gate }
6547c478bd9Sstevel@tonic-gate case CKM_AES_CBC_PAD:
6557c478bd9Sstevel@tonic-gate {
6567c478bd9Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
6577c478bd9Sstevel@tonic-gate
6587c478bd9Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
6597c478bd9Sstevel@tonic-gate /*
6607c478bd9Sstevel@tonic-gate * For CKM_AES_CBC_PAD, compute output length with
6617c478bd9Sstevel@tonic-gate * padding. If the remaining buffer has one block
6627c478bd9Sstevel@tonic-gate * of data, then output length will be two blocksize of
6637c478bd9Sstevel@tonic-gate * ciphertext. If the remaining buffer has less than
6647c478bd9Sstevel@tonic-gate * one block of data, then output length will be
6657c478bd9Sstevel@tonic-gate * one blocksize.
6667c478bd9Sstevel@tonic-gate */
6677c478bd9Sstevel@tonic-gate if (soft_aes_ctx->remain_len == AES_BLOCK_LEN)
6687c478bd9Sstevel@tonic-gate out_len = 2 * AES_BLOCK_LEN;
6697c478bd9Sstevel@tonic-gate else
6707c478bd9Sstevel@tonic-gate out_len = AES_BLOCK_LEN;
6717c478bd9Sstevel@tonic-gate
6727c478bd9Sstevel@tonic-gate if (pLastEncryptedPart == NULL) {
6737c478bd9Sstevel@tonic-gate /*
6747c478bd9Sstevel@tonic-gate * Application asks for the length of the output
6757c478bd9Sstevel@tonic-gate * buffer to hold the ciphertext.
6767c478bd9Sstevel@tonic-gate */
6777c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
6787c478bd9Sstevel@tonic-gate goto clean1;
6797c478bd9Sstevel@tonic-gate } else {
6807c478bd9Sstevel@tonic-gate crypto_data_t out;
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate /* Copy remaining data to the output buffer. */
6837c478bd9Sstevel@tonic-gate (void) memcpy(pLastEncryptedPart, soft_aes_ctx->data,
6847c478bd9Sstevel@tonic-gate soft_aes_ctx->remain_len);
6857c478bd9Sstevel@tonic-gate
6867c478bd9Sstevel@tonic-gate /*
6877c478bd9Sstevel@tonic-gate * Add padding bytes prior to encrypt final.
6887c478bd9Sstevel@tonic-gate */
6897c478bd9Sstevel@tonic-gate soft_add_pkcs7_padding(pLastEncryptedPart +
6907c478bd9Sstevel@tonic-gate soft_aes_ctx->remain_len, AES_BLOCK_LEN,
6917c478bd9Sstevel@tonic-gate soft_aes_ctx->remain_len);
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate out.cd_format = CRYPTO_DATA_RAW;
6947c478bd9Sstevel@tonic-gate out.cd_offset = 0;
6957c478bd9Sstevel@tonic-gate out.cd_length = out_len;
6967c478bd9Sstevel@tonic-gate out.cd_raw.iov_base = (char *)pLastEncryptedPart;
6977c478bd9Sstevel@tonic-gate out.cd_raw.iov_len = out_len;
6987c478bd9Sstevel@tonic-gate
6997c478bd9Sstevel@tonic-gate /* Encrypt multiple blocks of data. */
7007c478bd9Sstevel@tonic-gate rc = aes_encrypt_contiguous_blocks(
7017c478bd9Sstevel@tonic-gate (aes_ctx_t *)soft_aes_ctx->aes_cbc,
7027c478bd9Sstevel@tonic-gate (char *)pLastEncryptedPart, out_len, &out);
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate if (rc == 0) {
7057c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
7067c478bd9Sstevel@tonic-gate } else {
7077c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
7087c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
7097c478bd9Sstevel@tonic-gate }
7107c478bd9Sstevel@tonic-gate
7117c478bd9Sstevel@tonic-gate /* Cleanup memory space. */
7127c478bd9Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
7137c478bd9Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
7147c478bd9Sstevel@tonic-gate soft_aes_ctx->keysched_len);
7157c478bd9Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate
7187c478bd9Sstevel@tonic-gate break;
7197c478bd9Sstevel@tonic-gate }
7207c478bd9Sstevel@tonic-gate case CKM_AES_CBC:
7217c478bd9Sstevel@tonic-gate case CKM_AES_ECB:
7227c478bd9Sstevel@tonic-gate {
7237c478bd9Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
7247c478bd9Sstevel@tonic-gate
7257c478bd9Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
7267c478bd9Sstevel@tonic-gate /*
7277c478bd9Sstevel@tonic-gate * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
7287c478bd9Sstevel@tonic-gate * so when the final is called, the remaining buffer
7297c478bd9Sstevel@tonic-gate * should not contain any more data.
7307c478bd9Sstevel@tonic-gate */
7317c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
7327c478bd9Sstevel@tonic-gate if (soft_aes_ctx->remain_len != 0) {
7337c478bd9Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
7347c478bd9Sstevel@tonic-gate } else {
7357c478bd9Sstevel@tonic-gate if (pLastEncryptedPart == NULL)
7367c478bd9Sstevel@tonic-gate goto clean1;
7377c478bd9Sstevel@tonic-gate }
7387c478bd9Sstevel@tonic-gate
7397c478bd9Sstevel@tonic-gate /* Cleanup memory space. */
7407c478bd9Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
7417c478bd9Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
7427c478bd9Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
7437c478bd9Sstevel@tonic-gate
7447c478bd9Sstevel@tonic-gate break;
7457c478bd9Sstevel@tonic-gate }
74623c57df7Smcpowers case CKM_AES_CTR:
74723c57df7Smcpowers {
74823c57df7Smcpowers crypto_data_t out;
74923c57df7Smcpowers soft_aes_ctx_t *soft_aes_ctx;
75023c57df7Smcpowers ctr_ctx_t *ctr_ctx;
75123c57df7Smcpowers size_t len;
7527c478bd9Sstevel@tonic-gate
75323c57df7Smcpowers soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
75423c57df7Smcpowers ctr_ctx = soft_aes_ctx->aes_cbc;
75523c57df7Smcpowers len = ctr_ctx->ctr_remainder_len;
75623c57df7Smcpowers
75723c57df7Smcpowers if (pLastEncryptedPart == NULL) {
75823c57df7Smcpowers *pulLastEncryptedPartLen = len;
75923c57df7Smcpowers goto clean1;
76023c57df7Smcpowers }
76123c57df7Smcpowers if (len > 0) {
76223c57df7Smcpowers out.cd_format = CRYPTO_DATA_RAW;
76323c57df7Smcpowers out.cd_offset = 0;
76423c57df7Smcpowers out.cd_length = len;
76523c57df7Smcpowers out.cd_raw.iov_base = (char *)pLastEncryptedPart;
76623c57df7Smcpowers out.cd_raw.iov_len = len;
76723c57df7Smcpowers
76823c57df7Smcpowers rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
76923c57df7Smcpowers }
77023c57df7Smcpowers if (rv == CRYPTO_BUFFER_TOO_SMALL) {
77123c57df7Smcpowers *pulLastEncryptedPartLen = len;
77223c57df7Smcpowers goto clean1;
77323c57df7Smcpowers }
77423c57df7Smcpowers
77523c57df7Smcpowers /* Cleanup memory space. */
77623c57df7Smcpowers free(ctr_ctx);
77723c57df7Smcpowers bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
77823c57df7Smcpowers free(soft_aes_ctx->key_sched);
77923c57df7Smcpowers
78023c57df7Smcpowers break;
78123c57df7Smcpowers }
782f66d273dSizick case CKM_BLOWFISH_CBC:
783f66d273dSizick {
784f66d273dSizick soft_blowfish_ctx_t *soft_blowfish_ctx;
785f66d273dSizick
786f66d273dSizick soft_blowfish_ctx =
787f66d273dSizick (soft_blowfish_ctx_t *)session_p->encrypt.context;
788f66d273dSizick /*
789f66d273dSizick * CKM_BLOWFISH_CBC does not do any padding, so when the
790f66d273dSizick * final is called, the remaining buffer should not contain
791f66d273dSizick * any more data
792f66d273dSizick */
793f66d273dSizick *pulLastEncryptedPartLen = 0;
794f66d273dSizick if (soft_blowfish_ctx->remain_len != 0)
795f66d273dSizick rv = CKR_DATA_LEN_RANGE;
796f66d273dSizick else {
797f66d273dSizick if (pLastEncryptedPart == NULL)
798f66d273dSizick goto clean1;
799f66d273dSizick }
800f66d273dSizick
801f66d273dSizick free(soft_blowfish_ctx->blowfish_cbc);
802f66d273dSizick bzero(soft_blowfish_ctx->key_sched,
803f66d273dSizick soft_blowfish_ctx->keysched_len);
804f66d273dSizick free(soft_blowfish_ctx->key_sched);
805f66d273dSizick break;
806f66d273dSizick }
807f66d273dSizick
8087c478bd9Sstevel@tonic-gate case CKM_RC4:
8097c478bd9Sstevel@tonic-gate {
8107c478bd9Sstevel@tonic-gate ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context;
811c00745c7SZdenek Kotala /* Remaining data size is always zero for RC4. */
8127c478bd9Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
813c00745c7SZdenek Kotala if (pLastEncryptedPart == NULL)
814c00745c7SZdenek Kotala goto clean1;
815c00745c7SZdenek Kotala bzero(key, sizeof (*key));
8167c478bd9Sstevel@tonic-gate break;
8177c478bd9Sstevel@tonic-gate }
8187c478bd9Sstevel@tonic-gate default:
8197c478bd9Sstevel@tonic-gate /* PKCS11: The mechanism only supports single-part operation. */
8207c478bd9Sstevel@tonic-gate rv = CKR_MECHANISM_INVALID;
8217c478bd9Sstevel@tonic-gate break;
8227c478bd9Sstevel@tonic-gate }
8237c478bd9Sstevel@tonic-gate
8247c478bd9Sstevel@tonic-gate free(session_p->encrypt.context);
8257c478bd9Sstevel@tonic-gate session_p->encrypt.context = NULL;
8267c478bd9Sstevel@tonic-gate clean1:
8277c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
8287c478bd9Sstevel@tonic-gate
8297c478bd9Sstevel@tonic-gate return (rv);
8307c478bd9Sstevel@tonic-gate }
8317c478bd9Sstevel@tonic-gate
8327c478bd9Sstevel@tonic-gate /*
8337c478bd9Sstevel@tonic-gate * This function frees the allocated active crypto context and the
8347c478bd9Sstevel@tonic-gate * lower level of allocated struct as needed.
8357c478bd9Sstevel@tonic-gate * This function is called by the 1st tier of encrypt/decrypt routines
8367c478bd9Sstevel@tonic-gate * or by the 2nd tier of session close routine. Since the 1st tier
8377c478bd9Sstevel@tonic-gate * caller will always call this function without locking the session
8387c478bd9Sstevel@tonic-gate * mutex and the 2nd tier caller will call with the lock, we add the
839*726fad2aSDina K Nimeh * third parameter "lock_held" to distinguish this case.
8407c478bd9Sstevel@tonic-gate */
8417c478bd9Sstevel@tonic-gate void
soft_crypt_cleanup(soft_session_t * session_p,boolean_t encrypt,boolean_t lock_held)8427c478bd9Sstevel@tonic-gate soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
8437c478bd9Sstevel@tonic-gate boolean_t lock_held)
8447c478bd9Sstevel@tonic-gate {
8457c478bd9Sstevel@tonic-gate
8467c478bd9Sstevel@tonic-gate crypto_active_op_t *active_op;
8477c478bd9Sstevel@tonic-gate boolean_t lock_true = B_TRUE;
8487c478bd9Sstevel@tonic-gate
8497c478bd9Sstevel@tonic-gate if (!lock_held)
8507c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
8517c478bd9Sstevel@tonic-gate
8527c478bd9Sstevel@tonic-gate active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
8537c478bd9Sstevel@tonic-gate
8547c478bd9Sstevel@tonic-gate switch (active_op->mech.mechanism) {
8557c478bd9Sstevel@tonic-gate
8567c478bd9Sstevel@tonic-gate case CKM_DES_CBC_PAD:
8577c478bd9Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
8587c478bd9Sstevel@tonic-gate case CKM_DES_CBC:
8597c478bd9Sstevel@tonic-gate case CKM_DES_ECB:
8607c478bd9Sstevel@tonic-gate case CKM_DES3_CBC:
8617c478bd9Sstevel@tonic-gate case CKM_DES3_ECB:
8627c478bd9Sstevel@tonic-gate {
8637c478bd9Sstevel@tonic-gate
8647c478bd9Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx =
8657c478bd9Sstevel@tonic-gate (soft_des_ctx_t *)active_op->context;
8667c478bd9Sstevel@tonic-gate des_ctx_t *des_ctx;
8677c478bd9Sstevel@tonic-gate
8687c478bd9Sstevel@tonic-gate if (soft_des_ctx != NULL) {
8697c478bd9Sstevel@tonic-gate des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
8707c478bd9Sstevel@tonic-gate if (des_ctx != NULL) {
8717c478bd9Sstevel@tonic-gate bzero(des_ctx->dc_keysched,
8727c478bd9Sstevel@tonic-gate des_ctx->dc_keysched_len);
8737c478bd9Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
8747c478bd9Sstevel@tonic-gate }
8757c478bd9Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
8767c478bd9Sstevel@tonic-gate soft_des_ctx->keysched_len);
8777c478bd9Sstevel@tonic-gate free(soft_des_ctx->key_sched);
8787c478bd9Sstevel@tonic-gate }
8797c478bd9Sstevel@tonic-gate break;
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate
8827c478bd9Sstevel@tonic-gate case CKM_AES_CBC_PAD:
8837c478bd9Sstevel@tonic-gate case CKM_AES_CBC:
8847c478bd9Sstevel@tonic-gate case CKM_AES_ECB:
8857c478bd9Sstevel@tonic-gate {
8867c478bd9Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx =
8877c478bd9Sstevel@tonic-gate (soft_aes_ctx_t *)active_op->context;
8887c478bd9Sstevel@tonic-gate aes_ctx_t *aes_ctx;
8897c478bd9Sstevel@tonic-gate
8907c478bd9Sstevel@tonic-gate if (soft_aes_ctx != NULL) {
8917c478bd9Sstevel@tonic-gate aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
8927c478bd9Sstevel@tonic-gate if (aes_ctx != NULL) {
8937c478bd9Sstevel@tonic-gate bzero(aes_ctx->ac_keysched,
8947c478bd9Sstevel@tonic-gate aes_ctx->ac_keysched_len);
8957c478bd9Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
8987c478bd9Sstevel@tonic-gate soft_aes_ctx->keysched_len);
8997c478bd9Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
9007c478bd9Sstevel@tonic-gate }
9017c478bd9Sstevel@tonic-gate break;
9027c478bd9Sstevel@tonic-gate }
9037c478bd9Sstevel@tonic-gate
904f66d273dSizick case CKM_BLOWFISH_CBC:
905f66d273dSizick {
906f66d273dSizick soft_blowfish_ctx_t *soft_blowfish_ctx =
907f66d273dSizick (soft_blowfish_ctx_t *)active_op->context;
908f66d273dSizick blowfish_ctx_t *blowfish_ctx;
909f66d273dSizick
910f66d273dSizick if (soft_blowfish_ctx != NULL) {
911f66d273dSizick blowfish_ctx =
912f66d273dSizick (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
913f66d273dSizick if (blowfish_ctx != NULL) {
914f66d273dSizick bzero(blowfish_ctx->bc_keysched,
915f66d273dSizick blowfish_ctx->bc_keysched_len);
916f66d273dSizick free(soft_blowfish_ctx->blowfish_cbc);
917f66d273dSizick }
918f66d273dSizick
919f66d273dSizick bzero(soft_blowfish_ctx->key_sched,
920f66d273dSizick soft_blowfish_ctx->keysched_len);
921f66d273dSizick free(soft_blowfish_ctx->key_sched);
922f66d273dSizick }
923f66d273dSizick break;
924f66d273dSizick }
925f66d273dSizick
9267c478bd9Sstevel@tonic-gate case CKM_RC4:
9277c478bd9Sstevel@tonic-gate {
9287c478bd9Sstevel@tonic-gate ARCFour_key *key = (ARCFour_key *)active_op->context;
9297c478bd9Sstevel@tonic-gate
9307c478bd9Sstevel@tonic-gate if (key != NULL)
9317c478bd9Sstevel@tonic-gate bzero(key, sizeof (*key));
9327c478bd9Sstevel@tonic-gate break;
9337c478bd9Sstevel@tonic-gate }
9347c478bd9Sstevel@tonic-gate
9357c478bd9Sstevel@tonic-gate case CKM_RSA_X_509:
9367c478bd9Sstevel@tonic-gate case CKM_RSA_PKCS:
9374c21f043Sizick {
9384c21f043Sizick soft_rsa_ctx_t *rsa_ctx =
9394c21f043Sizick (soft_rsa_ctx_t *)active_op->context;
9404c21f043Sizick
9414c21f043Sizick if (rsa_ctx != NULL)
9424c21f043Sizick if (rsa_ctx->key != NULL) {
9434c21f043Sizick soft_cleanup_object(rsa_ctx->key);
9444c21f043Sizick free(rsa_ctx->key);
9454c21f043Sizick }
9464c21f043Sizick
9477c478bd9Sstevel@tonic-gate break;
9484c21f043Sizick }
9497c478bd9Sstevel@tonic-gate
9507c478bd9Sstevel@tonic-gate } /* switch */
9517c478bd9Sstevel@tonic-gate
9527c478bd9Sstevel@tonic-gate if (active_op->context != NULL) {
9537c478bd9Sstevel@tonic-gate free(active_op->context);
9547c478bd9Sstevel@tonic-gate active_op->context = NULL;
9557c478bd9Sstevel@tonic-gate }
9567c478bd9Sstevel@tonic-gate
9577c478bd9Sstevel@tonic-gate active_op->flags = 0;
9587c478bd9Sstevel@tonic-gate
9597c478bd9Sstevel@tonic-gate if (!lock_held)
9607c478bd9Sstevel@tonic-gate SES_REFRELE(session_p, lock_true);
9617c478bd9Sstevel@tonic-gate }
962