10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52786Sdinak * Common Development and Distribution License (the "License").
62786Sdinak * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*12573SDina.Nimeh@Sun.COM
220Sstevel@tonic-gate /*
23*12573SDina.Nimeh@Sun.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <pthread.h>
270Sstevel@tonic-gate #include <stdlib.h>
280Sstevel@tonic-gate #include <string.h>
290Sstevel@tonic-gate #include <strings.h>
300Sstevel@tonic-gate #include <sys/types.h>
310Sstevel@tonic-gate #include <security/cryptoki.h>
327188Smcpowers #include <modes/modes.h>
330Sstevel@tonic-gate #include <arcfour.h>
340Sstevel@tonic-gate #include "softSession.h"
350Sstevel@tonic-gate #include "softObject.h"
360Sstevel@tonic-gate #include "softOps.h"
370Sstevel@tonic-gate #include "softCrypt.h"
380Sstevel@tonic-gate #include "softRSA.h"
390Sstevel@tonic-gate
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate * Add padding bytes with the value of length of padding.
420Sstevel@tonic-gate */
430Sstevel@tonic-gate void
soft_add_pkcs7_padding(CK_BYTE * buf,int block_size,CK_ULONG data_len)440Sstevel@tonic-gate soft_add_pkcs7_padding(CK_BYTE *buf, int block_size, CK_ULONG data_len)
450Sstevel@tonic-gate {
46*12573SDina.Nimeh@Sun.COM (void) pkcs7_encode(NULL, data_len, buf, block_size, block_size);
470Sstevel@tonic-gate }
480Sstevel@tonic-gate
490Sstevel@tonic-gate /*
500Sstevel@tonic-gate * Perform encrypt init operation internally for the support of
510Sstevel@tonic-gate * CKM_DES_MAC and CKM_DES_MAC_GENERAL
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * This function is called with the session being held, and without
540Sstevel@tonic-gate * its mutex taken.
550Sstevel@tonic-gate */
560Sstevel@tonic-gate CK_RV
soft_encrypt_init_internal(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)570Sstevel@tonic-gate soft_encrypt_init_internal(soft_session_t *session_p, CK_MECHANISM_PTR
580Sstevel@tonic-gate pMechanism, soft_object_t *key_p)
590Sstevel@tonic-gate {
600Sstevel@tonic-gate CK_RV rv;
610Sstevel@tonic-gate
620Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
630Sstevel@tonic-gate
640Sstevel@tonic-gate /* Check to see if encrypt operation is already active */
650Sstevel@tonic-gate if (session_p->encrypt.flags & CRYPTO_OPERATION_ACTIVE) {
660Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
670Sstevel@tonic-gate return (CKR_OPERATION_ACTIVE);
680Sstevel@tonic-gate }
690Sstevel@tonic-gate
700Sstevel@tonic-gate session_p->encrypt.flags = CRYPTO_OPERATION_ACTIVE;
710Sstevel@tonic-gate
720Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
730Sstevel@tonic-gate
740Sstevel@tonic-gate rv = soft_encrypt_init(session_p, pMechanism, key_p);
750Sstevel@tonic-gate
760Sstevel@tonic-gate if (rv != CKR_OK) {
770Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
780Sstevel@tonic-gate session_p->encrypt.flags &= ~CRYPTO_OPERATION_ACTIVE;
790Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
800Sstevel@tonic-gate }
810Sstevel@tonic-gate
820Sstevel@tonic-gate return (rv);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate
850Sstevel@tonic-gate /*
860Sstevel@tonic-gate * soft_encrypt_init()
870Sstevel@tonic-gate *
880Sstevel@tonic-gate * Arguments:
890Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
900Sstevel@tonic-gate * pMechanism: pointer to CK_MECHANISM struct provided by application
910Sstevel@tonic-gate * key_p: pointer to key soft_object_t struct
920Sstevel@tonic-gate *
930Sstevel@tonic-gate * Description:
940Sstevel@tonic-gate * called by C_EncryptInit(). This function calls the corresponding
950Sstevel@tonic-gate * encrypt init routine based on the mechanism.
960Sstevel@tonic-gate *
970Sstevel@tonic-gate * Returns:
980Sstevel@tonic-gate * CKR_OK: success
990Sstevel@tonic-gate * CKR_HOST_MEMORY: run out of system memory
1000Sstevel@tonic-gate * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
1010Sstevel@tonic-gate * CKR_MECHANISM_INVALID: invalid mechanism type
1020Sstevel@tonic-gate * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
1030Sstevel@tonic-gate * with the specified mechanism
1040Sstevel@tonic-gate */
1050Sstevel@tonic-gate CK_RV
soft_encrypt_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)1060Sstevel@tonic-gate soft_encrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
1070Sstevel@tonic-gate soft_object_t *key_p)
1080Sstevel@tonic-gate {
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate CK_RV rv;
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate switch (pMechanism->mechanism) {
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate case CKM_DES_ECB:
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate if (key_p->key_type != CKK_DES) {
1170Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1180Sstevel@tonic-gate }
1190Sstevel@tonic-gate goto ecb_common;
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate case CKM_DES3_ECB:
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate if ((key_p->key_type != CKK_DES2) &&
1240Sstevel@tonic-gate (key_p->key_type != CKK_DES3)) {
1250Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1260Sstevel@tonic-gate }
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate ecb_common:
1290Sstevel@tonic-gate return (soft_des_crypt_init_common(session_p, pMechanism,
1300Sstevel@tonic-gate key_p, B_TRUE));
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate case CKM_DES_CBC:
1330Sstevel@tonic-gate case CKM_DES_CBC_PAD:
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate if (key_p->key_type != CKK_DES) {
1360Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate goto cbc_common;
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate case CKM_DES3_CBC:
1420Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
1430Sstevel@tonic-gate {
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate if ((key_p->key_type != CKK_DES2) &&
1480Sstevel@tonic-gate (key_p->key_type != CKK_DES3)) {
1490Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate cbc_common:
1530Sstevel@tonic-gate if ((pMechanism->pParameter == NULL) ||
1540Sstevel@tonic-gate (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
1550Sstevel@tonic-gate return (CKR_MECHANISM_PARAM_INVALID);
1560Sstevel@tonic-gate }
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate rv = soft_des_crypt_init_common(session_p, pMechanism,
1590Sstevel@tonic-gate key_p, B_TRUE);
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate if (rv != CKR_OK)
1620Sstevel@tonic-gate return (rv);
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
1670Sstevel@tonic-gate /* Copy Initialization Vector (IV) into the context. */
1680Sstevel@tonic-gate (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
1690Sstevel@tonic-gate DES_BLOCK_LEN);
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate /* Allocate a context for DES cipher-block chaining. */
1720Sstevel@tonic-gate soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
1730Sstevel@tonic-gate soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
1740Sstevel@tonic-gate soft_des_ctx->ivec, key_p->key_type);
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate if (soft_des_ctx->des_cbc == NULL) {
1770Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
1780Sstevel@tonic-gate soft_des_ctx->keysched_len);
1790Sstevel@tonic-gate free(soft_des_ctx->key_sched);
1800Sstevel@tonic-gate free(session_p->encrypt.context);
1810Sstevel@tonic-gate session_p->encrypt.context = NULL;
1820Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate return (rv);
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate case CKM_AES_ECB:
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate if (key_p->key_type != CKK_AES) {
1920Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate return (soft_aes_crypt_init_common(session_p, pMechanism,
1960Sstevel@tonic-gate key_p, B_TRUE));
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate case CKM_AES_CBC:
1990Sstevel@tonic-gate case CKM_AES_CBC_PAD:
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate if (key_p->key_type != CKK_AES) {
2040Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
2050Sstevel@tonic-gate }
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate if ((pMechanism->pParameter == NULL) ||
2080Sstevel@tonic-gate (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
2090Sstevel@tonic-gate return (CKR_MECHANISM_PARAM_INVALID);
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate rv = soft_aes_crypt_init_common(session_p, pMechanism,
2130Sstevel@tonic-gate key_p, B_TRUE);
2140Sstevel@tonic-gate
2150Sstevel@tonic-gate if (rv != CKR_OK)
2160Sstevel@tonic-gate return (rv);
2170Sstevel@tonic-gate
2180Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
2210Sstevel@tonic-gate /* Copy Initialization Vector (IV) into the context. */
2220Sstevel@tonic-gate (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter,
2230Sstevel@tonic-gate AES_BLOCK_LEN);
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate /* Allocate a context for AES cipher-block chaining. */
2260Sstevel@tonic-gate soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2270Sstevel@tonic-gate soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2280Sstevel@tonic-gate soft_aes_ctx->ivec);
2290Sstevel@tonic-gate
2300Sstevel@tonic-gate if (soft_aes_ctx->aes_cbc == NULL) {
2310Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
2320Sstevel@tonic-gate soft_aes_ctx->keysched_len);
2330Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
2340Sstevel@tonic-gate free(session_p->encrypt.context);
2350Sstevel@tonic-gate session_p->encrypt.context = NULL;
2360Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate
2390Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate return (rv);
2420Sstevel@tonic-gate }
2437188Smcpowers case CKM_AES_CTR:
2447188Smcpowers {
2457188Smcpowers soft_aes_ctx_t *soft_aes_ctx;
2467188Smcpowers
2477188Smcpowers if (key_p->key_type != CKK_AES) {
2487188Smcpowers return (CKR_KEY_TYPE_INCONSISTENT);
2497188Smcpowers }
2507188Smcpowers
2517188Smcpowers if (pMechanism->pParameter == NULL ||
2527188Smcpowers pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
2537188Smcpowers return (CKR_MECHANISM_PARAM_INVALID);
2547188Smcpowers }
2557188Smcpowers
2567188Smcpowers rv = soft_aes_crypt_init_common(session_p, pMechanism,
2577188Smcpowers key_p, B_TRUE);
2587188Smcpowers
2597188Smcpowers if (rv != CKR_OK)
2607188Smcpowers return (rv);
2617188Smcpowers
2627188Smcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
2637188Smcpowers
2647188Smcpowers soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
2657188Smcpowers soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
2667188Smcpowers soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2677188Smcpowers pMechanism->pParameter);
2687188Smcpowers
2697188Smcpowers if (soft_aes_ctx->aes_cbc == NULL) {
2707188Smcpowers bzero(soft_aes_ctx->key_sched,
2717188Smcpowers soft_aes_ctx->keysched_len);
2727188Smcpowers free(soft_aes_ctx->key_sched);
2737188Smcpowers free(session_p->encrypt.context);
2747188Smcpowers session_p->encrypt.context = NULL;
2757188Smcpowers rv = CKR_HOST_MEMORY;
2767188Smcpowers }
2777188Smcpowers
2787188Smcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
2797188Smcpowers
2807188Smcpowers return (rv);
2817188Smcpowers }
2820Sstevel@tonic-gate case CKM_RC4:
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate if (key_p->key_type != CKK_RC4) {
2850Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
2860Sstevel@tonic-gate }
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
2890Sstevel@tonic-gate B_TRUE));
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate case CKM_RSA_X_509:
2920Sstevel@tonic-gate case CKM_RSA_PKCS:
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate if (key_p->key_type != CKK_RSA) {
2950Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate
2980Sstevel@tonic-gate return (soft_rsa_crypt_init_common(session_p, pMechanism,
2990Sstevel@tonic-gate key_p, B_TRUE));
3000Sstevel@tonic-gate
301676Sizick case CKM_BLOWFISH_CBC:
302676Sizick {
303676Sizick soft_blowfish_ctx_t *soft_blowfish_ctx;
304676Sizick
305676Sizick if (key_p->key_type != CKK_BLOWFISH)
306676Sizick return (CKR_KEY_TYPE_INCONSISTENT);
307676Sizick
308676Sizick if ((pMechanism->pParameter == NULL) ||
309676Sizick (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
310676Sizick return (CKR_MECHANISM_PARAM_INVALID);
311676Sizick
312676Sizick rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
313676Sizick key_p, B_TRUE);
314676Sizick
315676Sizick if (rv != CKR_OK)
316676Sizick return (rv);
317676Sizick
318676Sizick (void) pthread_mutex_lock(&session_p->session_mutex);
319676Sizick
320676Sizick soft_blowfish_ctx =
321676Sizick (soft_blowfish_ctx_t *)session_p->encrypt.context;
322676Sizick /* Copy Initialization Vector (IV) into the context. */
323676Sizick (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
324676Sizick BLOWFISH_BLOCK_LEN);
325676Sizick
326676Sizick /* Allocate a context for Blowfish cipher-block chaining */
327676Sizick soft_blowfish_ctx->blowfish_cbc =
328676Sizick (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
3297188Smcpowers soft_blowfish_ctx->keysched_len,
3307188Smcpowers soft_blowfish_ctx->ivec);
331676Sizick
332676Sizick if (soft_blowfish_ctx->blowfish_cbc == NULL) {
333676Sizick bzero(soft_blowfish_ctx->key_sched,
334676Sizick soft_blowfish_ctx->keysched_len);
335676Sizick free(soft_blowfish_ctx->key_sched);
336676Sizick free(session_p->encrypt.context);
337676Sizick session_p->encrypt.context = NULL;
338676Sizick rv = CKR_HOST_MEMORY;
339676Sizick }
340676Sizick
341676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
342676Sizick
343676Sizick return (rv);
344676Sizick }
3450Sstevel@tonic-gate default:
3460Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate }
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate /*
3520Sstevel@tonic-gate * soft_encrypt_common()
3530Sstevel@tonic-gate *
3540Sstevel@tonic-gate * Arguments:
3550Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
3560Sstevel@tonic-gate * pData: pointer to the input data to be encrypted
3570Sstevel@tonic-gate * ulDataLen: length of the input data
3580Sstevel@tonic-gate * pEncrypted: pointer to the output data after encryption
3590Sstevel@tonic-gate * pulEncryptedLen: pointer to the length of the output data
3600Sstevel@tonic-gate * update: boolean flag indicates caller is soft_encrypt
3610Sstevel@tonic-gate * or soft_encrypt_update
3620Sstevel@tonic-gate *
3630Sstevel@tonic-gate * Description:
3640Sstevel@tonic-gate * This function calls the corresponding encrypt routine based
3650Sstevel@tonic-gate * on the mechanism.
3660Sstevel@tonic-gate *
3670Sstevel@tonic-gate * Returns:
3680Sstevel@tonic-gate * see corresponding encrypt routine.
3690Sstevel@tonic-gate */
3700Sstevel@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)3710Sstevel@tonic-gate soft_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
3720Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
3730Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedLen, boolean_t update)
3740Sstevel@tonic-gate {
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate switch (mechanism) {
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate case CKM_DES_ECB:
3810Sstevel@tonic-gate case CKM_DES_CBC:
3820Sstevel@tonic-gate case CKM_DES3_ECB:
3830Sstevel@tonic-gate case CKM_DES3_CBC:
3842786Sdinak
3852786Sdinak if (ulDataLen == 0) {
3862786Sdinak *pulEncryptedLen = 0;
3872786Sdinak return (CKR_OK);
3882786Sdinak }
3892786Sdinak /* FALLTHROUGH */
3902786Sdinak
3912786Sdinak case CKM_DES_CBC_PAD:
3920Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate return (soft_des_encrypt_common(session_p, pData,
3950Sstevel@tonic-gate ulDataLen, pEncrypted, pulEncryptedLen, update));
3960Sstevel@tonic-gate
3970Sstevel@tonic-gate case CKM_AES_ECB:
3980Sstevel@tonic-gate case CKM_AES_CBC:
3997188Smcpowers case CKM_AES_CTR:
4002786Sdinak
4012786Sdinak if (ulDataLen == 0) {
4022786Sdinak *pulEncryptedLen = 0;
4032786Sdinak return (CKR_OK);
4042786Sdinak }
4052786Sdinak /* FALLTHROUGH */
4062786Sdinak
4070Sstevel@tonic-gate case CKM_AES_CBC_PAD:
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate return (soft_aes_encrypt_common(session_p, pData,
4100Sstevel@tonic-gate ulDataLen, pEncrypted, pulEncryptedLen, update));
4110Sstevel@tonic-gate
412676Sizick case CKM_BLOWFISH_CBC:
413676Sizick
4142786Sdinak if (ulDataLen == 0) {
4152786Sdinak *pulEncryptedLen = 0;
4162786Sdinak return (CKR_OK);
4172786Sdinak }
4182786Sdinak
419676Sizick return (soft_blowfish_encrypt_common(session_p, pData,
420676Sizick ulDataLen, pEncrypted, pulEncryptedLen, update));
421676Sizick
4220Sstevel@tonic-gate case CKM_RC4:
4230Sstevel@tonic-gate
4242786Sdinak if (ulDataLen == 0) {
4252786Sdinak *pulEncryptedLen = 0;
4262786Sdinak return (CKR_OK);
4270Sstevel@tonic-gate }
4282786Sdinak
4292786Sdinak return (soft_arcfour_crypt(&(session_p->encrypt), pData,
4302786Sdinak ulDataLen, pEncrypted, pulEncryptedLen));
4310Sstevel@tonic-gate
4320Sstevel@tonic-gate case CKM_RSA_X_509:
4330Sstevel@tonic-gate case CKM_RSA_PKCS:
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate return (soft_rsa_encrypt_common(session_p, pData,
4360Sstevel@tonic-gate ulDataLen, pEncrypted, pulEncryptedLen, mechanism));
4370Sstevel@tonic-gate
4380Sstevel@tonic-gate default:
4390Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate }
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate
4440Sstevel@tonic-gate /*
4450Sstevel@tonic-gate * soft_encrypt()
4460Sstevel@tonic-gate *
4470Sstevel@tonic-gate * Arguments:
4480Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
4490Sstevel@tonic-gate * pData: pointer to the input data to be encrypted
4500Sstevel@tonic-gate * ulDataLen: length of the input data
4510Sstevel@tonic-gate * pEncryptedData: pointer to the output data after encryption
4520Sstevel@tonic-gate * pulEncryptedDataLen: pointer to the length of the output data
4530Sstevel@tonic-gate *
4540Sstevel@tonic-gate * Description:
4550Sstevel@tonic-gate * called by C_Encrypt(). This function calls the soft_encrypt_common
4560Sstevel@tonic-gate * routine.
4570Sstevel@tonic-gate *
4580Sstevel@tonic-gate * Returns:
4590Sstevel@tonic-gate * see soft_encrypt_common().
4600Sstevel@tonic-gate */
4610Sstevel@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)4620Sstevel@tonic-gate soft_encrypt(soft_session_t *session_p, CK_BYTE_PTR pData,
4630Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData,
4640Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedDataLen)
4650Sstevel@tonic-gate {
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate return (soft_encrypt_common(session_p, pData, ulDataLen,
4680Sstevel@tonic-gate pEncryptedData, pulEncryptedDataLen, B_FALSE));
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate
4720Sstevel@tonic-gate /*
4730Sstevel@tonic-gate * soft_encrypt_update()
4740Sstevel@tonic-gate *
4750Sstevel@tonic-gate * Arguments:
4760Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
4770Sstevel@tonic-gate * pPart: pointer to the input data to be digested
4780Sstevel@tonic-gate * ulPartLen: length of the input data
4790Sstevel@tonic-gate * pEncryptedPart: pointer to the ciphertext
4800Sstevel@tonic-gate * pulEncryptedPartLen: pointer to the length of the ciphertext
4810Sstevel@tonic-gate *
4820Sstevel@tonic-gate * Description:
4830Sstevel@tonic-gate * called by C_EncryptUpdate(). This function calls the
4840Sstevel@tonic-gate * soft_encrypt_common routine (with update flag on).
4850Sstevel@tonic-gate *
4860Sstevel@tonic-gate * Returns:
4870Sstevel@tonic-gate * see soft_encrypt_common().
4880Sstevel@tonic-gate */
4890Sstevel@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)4900Sstevel@tonic-gate soft_encrypt_update(soft_session_t *session_p, CK_BYTE_PTR pPart,
4910Sstevel@tonic-gate CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
4920Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedPartLen)
4930Sstevel@tonic-gate {
4940Sstevel@tonic-gate
4950Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate switch (mechanism) {
4980Sstevel@tonic-gate
4990Sstevel@tonic-gate case CKM_DES_ECB:
5000Sstevel@tonic-gate case CKM_DES_CBC:
5010Sstevel@tonic-gate case CKM_DES_CBC_PAD:
5020Sstevel@tonic-gate case CKM_DES3_ECB:
5030Sstevel@tonic-gate case CKM_DES3_CBC:
5040Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
5050Sstevel@tonic-gate case CKM_AES_ECB:
5060Sstevel@tonic-gate case CKM_AES_CBC:
5070Sstevel@tonic-gate case CKM_AES_CBC_PAD:
5087188Smcpowers case CKM_AES_CTR:
509676Sizick case CKM_BLOWFISH_CBC:
5102786Sdinak case CKM_RC4:
5110Sstevel@tonic-gate
5120Sstevel@tonic-gate return (soft_encrypt_common(session_p, pPart, ulPartLen,
5130Sstevel@tonic-gate pEncryptedPart, pulEncryptedPartLen, B_TRUE));
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate default:
5160Sstevel@tonic-gate /* PKCS11: The mechanism only supports single-part operation. */
5170Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
5180Sstevel@tonic-gate }
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate
5220Sstevel@tonic-gate /*
5230Sstevel@tonic-gate * soft_encrypt_final()
5240Sstevel@tonic-gate *
5250Sstevel@tonic-gate * Arguments:
5260Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
5270Sstevel@tonic-gate * pLastEncryptedPart: pointer to the last encrypted data part
5280Sstevel@tonic-gate * pulLastEncryptedPartLen: pointer to the length of the last
5290Sstevel@tonic-gate * encrypted data part
5300Sstevel@tonic-gate *
5310Sstevel@tonic-gate * Description:
5320Sstevel@tonic-gate * called by C_EncryptFinal().
5330Sstevel@tonic-gate *
5340Sstevel@tonic-gate * Returns:
5350Sstevel@tonic-gate * CKR_OK: success
5360Sstevel@tonic-gate * CKR_FUNCTION_FAILED: encrypt final function failed
5370Sstevel@tonic-gate * CKR_DATA_LEN_RANGE: remaining buffer contains bad length
5380Sstevel@tonic-gate */
5390Sstevel@tonic-gate CK_RV
soft_encrypt_final(soft_session_t * session_p,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)5400Sstevel@tonic-gate soft_encrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastEncryptedPart,
5410Sstevel@tonic-gate CK_ULONG_PTR pulLastEncryptedPartLen)
5420Sstevel@tonic-gate {
5430Sstevel@tonic-gate
5440Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->encrypt.mech.mechanism;
5450Sstevel@tonic-gate CK_ULONG out_len;
5460Sstevel@tonic-gate CK_RV rv = CKR_OK;
5470Sstevel@tonic-gate int rc;
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate if (session_p->encrypt.context == NULL) {
5520Sstevel@tonic-gate rv = CKR_OPERATION_NOT_INITIALIZED;
5530Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
5540Sstevel@tonic-gate goto clean1;
5550Sstevel@tonic-gate }
5560Sstevel@tonic-gate switch (mechanism) {
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate case CKM_DES_CBC_PAD:
5590Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
5600Sstevel@tonic-gate {
5610Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
5640Sstevel@tonic-gate /*
5650Sstevel@tonic-gate * For CKM_DES_CBC_PAD, compute output length with
5660Sstevel@tonic-gate * padding. If the remaining buffer has one block
5670Sstevel@tonic-gate * of data, then output length will be two blocksize of
5680Sstevel@tonic-gate * ciphertext. If the remaining buffer has less than
5690Sstevel@tonic-gate * one block of data, then output length will be
5700Sstevel@tonic-gate * one blocksize.
5710Sstevel@tonic-gate */
5720Sstevel@tonic-gate if (soft_des_ctx->remain_len == DES_BLOCK_LEN)
5730Sstevel@tonic-gate out_len = 2 * DES_BLOCK_LEN;
5740Sstevel@tonic-gate else
5750Sstevel@tonic-gate out_len = DES_BLOCK_LEN;
5760Sstevel@tonic-gate
5770Sstevel@tonic-gate if (pLastEncryptedPart == NULL) {
5780Sstevel@tonic-gate /*
5790Sstevel@tonic-gate * Application asks for the length of the output
5800Sstevel@tonic-gate * buffer to hold the ciphertext.
5810Sstevel@tonic-gate */
5820Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
5830Sstevel@tonic-gate goto clean1;
5840Sstevel@tonic-gate } else {
5850Sstevel@tonic-gate crypto_data_t out;
5860Sstevel@tonic-gate
5870Sstevel@tonic-gate /* Copy remaining data to the output buffer. */
5880Sstevel@tonic-gate (void) memcpy(pLastEncryptedPart, soft_des_ctx->data,
5890Sstevel@tonic-gate soft_des_ctx->remain_len);
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate /*
5920Sstevel@tonic-gate * Add padding bytes prior to encrypt final.
5930Sstevel@tonic-gate */
5940Sstevel@tonic-gate soft_add_pkcs7_padding(pLastEncryptedPart +
5950Sstevel@tonic-gate soft_des_ctx->remain_len, DES_BLOCK_LEN,
5960Sstevel@tonic-gate soft_des_ctx->remain_len);
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate out.cd_format = CRYPTO_DATA_RAW;
5990Sstevel@tonic-gate out.cd_offset = 0;
6000Sstevel@tonic-gate out.cd_length = out_len;
6010Sstevel@tonic-gate out.cd_raw.iov_base = (char *)pLastEncryptedPart;
6020Sstevel@tonic-gate out.cd_raw.iov_len = out_len;
6030Sstevel@tonic-gate
6040Sstevel@tonic-gate /* Encrypt multiple blocks of data. */
6050Sstevel@tonic-gate rc = des_encrypt_contiguous_blocks(
6060Sstevel@tonic-gate (des_ctx_t *)soft_des_ctx->des_cbc,
6070Sstevel@tonic-gate (char *)pLastEncryptedPart, out_len, &out);
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate if (rc == 0) {
6100Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
6110Sstevel@tonic-gate } else {
6120Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
6130Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
6140Sstevel@tonic-gate }
6150Sstevel@tonic-gate
6160Sstevel@tonic-gate /* Cleanup memory space. */
6170Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
6180Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
6190Sstevel@tonic-gate soft_des_ctx->keysched_len);
6200Sstevel@tonic-gate free(soft_des_ctx->key_sched);
6210Sstevel@tonic-gate }
6220Sstevel@tonic-gate
6230Sstevel@tonic-gate break;
6240Sstevel@tonic-gate }
6250Sstevel@tonic-gate case CKM_DES_CBC:
6260Sstevel@tonic-gate case CKM_DES_ECB:
6270Sstevel@tonic-gate case CKM_DES3_CBC:
6280Sstevel@tonic-gate case CKM_DES3_ECB:
6290Sstevel@tonic-gate {
6300Sstevel@tonic-gate
6310Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
6320Sstevel@tonic-gate
6330Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->encrypt.context;
6340Sstevel@tonic-gate /*
6350Sstevel@tonic-gate * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
6360Sstevel@tonic-gate * so when the final is called, the remaining buffer
6370Sstevel@tonic-gate * should not contain any more data.
6380Sstevel@tonic-gate */
6390Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
6400Sstevel@tonic-gate if (soft_des_ctx->remain_len != 0) {
6410Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
6420Sstevel@tonic-gate } else {
6430Sstevel@tonic-gate if (pLastEncryptedPart == NULL)
6440Sstevel@tonic-gate goto clean1;
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate
6470Sstevel@tonic-gate /* Cleanup memory space. */
6480Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
6490Sstevel@tonic-gate bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
6500Sstevel@tonic-gate free(soft_des_ctx->key_sched);
6510Sstevel@tonic-gate
6520Sstevel@tonic-gate break;
6530Sstevel@tonic-gate }
6540Sstevel@tonic-gate case CKM_AES_CBC_PAD:
6550Sstevel@tonic-gate {
6560Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
6570Sstevel@tonic-gate
6580Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
6590Sstevel@tonic-gate /*
6600Sstevel@tonic-gate * For CKM_AES_CBC_PAD, compute output length with
6610Sstevel@tonic-gate * padding. If the remaining buffer has one block
6620Sstevel@tonic-gate * of data, then output length will be two blocksize of
6630Sstevel@tonic-gate * ciphertext. If the remaining buffer has less than
6640Sstevel@tonic-gate * one block of data, then output length will be
6650Sstevel@tonic-gate * one blocksize.
6660Sstevel@tonic-gate */
6670Sstevel@tonic-gate if (soft_aes_ctx->remain_len == AES_BLOCK_LEN)
6680Sstevel@tonic-gate out_len = 2 * AES_BLOCK_LEN;
6690Sstevel@tonic-gate else
6700Sstevel@tonic-gate out_len = AES_BLOCK_LEN;
6710Sstevel@tonic-gate
6720Sstevel@tonic-gate if (pLastEncryptedPart == NULL) {
6730Sstevel@tonic-gate /*
6740Sstevel@tonic-gate * Application asks for the length of the output
6750Sstevel@tonic-gate * buffer to hold the ciphertext.
6760Sstevel@tonic-gate */
6770Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
6780Sstevel@tonic-gate goto clean1;
6790Sstevel@tonic-gate } else {
6800Sstevel@tonic-gate crypto_data_t out;
6810Sstevel@tonic-gate
6820Sstevel@tonic-gate /* Copy remaining data to the output buffer. */
6830Sstevel@tonic-gate (void) memcpy(pLastEncryptedPart, soft_aes_ctx->data,
6840Sstevel@tonic-gate soft_aes_ctx->remain_len);
6850Sstevel@tonic-gate
6860Sstevel@tonic-gate /*
6870Sstevel@tonic-gate * Add padding bytes prior to encrypt final.
6880Sstevel@tonic-gate */
6890Sstevel@tonic-gate soft_add_pkcs7_padding(pLastEncryptedPart +
6900Sstevel@tonic-gate soft_aes_ctx->remain_len, AES_BLOCK_LEN,
6910Sstevel@tonic-gate soft_aes_ctx->remain_len);
6920Sstevel@tonic-gate
6930Sstevel@tonic-gate out.cd_format = CRYPTO_DATA_RAW;
6940Sstevel@tonic-gate out.cd_offset = 0;
6950Sstevel@tonic-gate out.cd_length = out_len;
6960Sstevel@tonic-gate out.cd_raw.iov_base = (char *)pLastEncryptedPart;
6970Sstevel@tonic-gate out.cd_raw.iov_len = out_len;
6980Sstevel@tonic-gate
6990Sstevel@tonic-gate /* Encrypt multiple blocks of data. */
7000Sstevel@tonic-gate rc = aes_encrypt_contiguous_blocks(
7010Sstevel@tonic-gate (aes_ctx_t *)soft_aes_ctx->aes_cbc,
7020Sstevel@tonic-gate (char *)pLastEncryptedPart, out_len, &out);
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate if (rc == 0) {
7050Sstevel@tonic-gate *pulLastEncryptedPartLen = out_len;
7060Sstevel@tonic-gate } else {
7070Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
7080Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
7090Sstevel@tonic-gate }
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate /* Cleanup memory space. */
7120Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
7130Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
7140Sstevel@tonic-gate soft_aes_ctx->keysched_len);
7150Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
7160Sstevel@tonic-gate }
7170Sstevel@tonic-gate
7180Sstevel@tonic-gate break;
7190Sstevel@tonic-gate }
7200Sstevel@tonic-gate case CKM_AES_CBC:
7210Sstevel@tonic-gate case CKM_AES_ECB:
7220Sstevel@tonic-gate {
7230Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
7240Sstevel@tonic-gate
7250Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
7260Sstevel@tonic-gate /*
7270Sstevel@tonic-gate * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
7280Sstevel@tonic-gate * so when the final is called, the remaining buffer
7290Sstevel@tonic-gate * should not contain any more data.
7300Sstevel@tonic-gate */
7310Sstevel@tonic-gate *pulLastEncryptedPartLen = 0;
7320Sstevel@tonic-gate if (soft_aes_ctx->remain_len != 0) {
7330Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
7340Sstevel@tonic-gate } else {
7350Sstevel@tonic-gate if (pLastEncryptedPart == NULL)
7360Sstevel@tonic-gate goto clean1;
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate
7390Sstevel@tonic-gate /* Cleanup memory space. */
7400Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
7410Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
7420Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
7430Sstevel@tonic-gate
7440Sstevel@tonic-gate break;
7450Sstevel@tonic-gate }
7467188Smcpowers case CKM_AES_CTR:
7477188Smcpowers {
7487188Smcpowers crypto_data_t out;
7497188Smcpowers soft_aes_ctx_t *soft_aes_ctx;
7507188Smcpowers ctr_ctx_t *ctr_ctx;
7517188Smcpowers size_t len;
7520Sstevel@tonic-gate
7537188Smcpowers soft_aes_ctx = (soft_aes_ctx_t *)session_p->encrypt.context;
7547188Smcpowers ctr_ctx = soft_aes_ctx->aes_cbc;
7557188Smcpowers len = ctr_ctx->ctr_remainder_len;
7567188Smcpowers
7577188Smcpowers if (pLastEncryptedPart == NULL) {
7587188Smcpowers *pulLastEncryptedPartLen = len;
7597188Smcpowers goto clean1;
7607188Smcpowers }
7617188Smcpowers if (len > 0) {
7627188Smcpowers out.cd_format = CRYPTO_DATA_RAW;
7637188Smcpowers out.cd_offset = 0;
7647188Smcpowers out.cd_length = len;
7657188Smcpowers out.cd_raw.iov_base = (char *)pLastEncryptedPart;
7667188Smcpowers out.cd_raw.iov_len = len;
7677188Smcpowers
7687188Smcpowers rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
7697188Smcpowers }
7707188Smcpowers if (rv == CRYPTO_BUFFER_TOO_SMALL) {
7717188Smcpowers *pulLastEncryptedPartLen = len;
7727188Smcpowers goto clean1;
7737188Smcpowers }
7747188Smcpowers
7757188Smcpowers /* Cleanup memory space. */
7767188Smcpowers free(ctr_ctx);
7777188Smcpowers bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
7787188Smcpowers free(soft_aes_ctx->key_sched);
7797188Smcpowers
7807188Smcpowers break;
7817188Smcpowers }
782676Sizick case CKM_BLOWFISH_CBC:
783676Sizick {
784676Sizick soft_blowfish_ctx_t *soft_blowfish_ctx;
785676Sizick
786676Sizick soft_blowfish_ctx =
787676Sizick (soft_blowfish_ctx_t *)session_p->encrypt.context;
788676Sizick /*
789676Sizick * CKM_BLOWFISH_CBC does not do any padding, so when the
790676Sizick * final is called, the remaining buffer should not contain
791676Sizick * any more data
792676Sizick */
793676Sizick *pulLastEncryptedPartLen = 0;
794676Sizick if (soft_blowfish_ctx->remain_len != 0)
795676Sizick rv = CKR_DATA_LEN_RANGE;
796676Sizick else {
797676Sizick if (pLastEncryptedPart == NULL)
798676Sizick goto clean1;
799676Sizick }
800676Sizick
801676Sizick free(soft_blowfish_ctx->blowfish_cbc);
802676Sizick bzero(soft_blowfish_ctx->key_sched,
803676Sizick soft_blowfish_ctx->keysched_len);
804676Sizick free(soft_blowfish_ctx->key_sched);
805676Sizick break;
806676Sizick }
807676Sizick
8080Sstevel@tonic-gate case CKM_RC4:
8090Sstevel@tonic-gate {
8100Sstevel@tonic-gate ARCFour_key *key = (ARCFour_key *)session_p->encrypt.context;
81110287SZdenek.Kotala@Sun.COM /* Remaining data size is always zero for RC4. */
81210287SZdenek.Kotala@Sun.COM *pulLastEncryptedPartLen = 0;
81310287SZdenek.Kotala@Sun.COM if (pLastEncryptedPart == NULL)
81410287SZdenek.Kotala@Sun.COM goto clean1;
8150Sstevel@tonic-gate bzero(key, sizeof (*key));
8160Sstevel@tonic-gate break;
8170Sstevel@tonic-gate }
8180Sstevel@tonic-gate default:
8190Sstevel@tonic-gate /* PKCS11: The mechanism only supports single-part operation. */
8200Sstevel@tonic-gate rv = CKR_MECHANISM_INVALID;
8210Sstevel@tonic-gate break;
8220Sstevel@tonic-gate }
8230Sstevel@tonic-gate
8240Sstevel@tonic-gate free(session_p->encrypt.context);
8250Sstevel@tonic-gate session_p->encrypt.context = NULL;
8260Sstevel@tonic-gate clean1:
8270Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
8280Sstevel@tonic-gate
8290Sstevel@tonic-gate return (rv);
8300Sstevel@tonic-gate }
8310Sstevel@tonic-gate
8320Sstevel@tonic-gate /*
8330Sstevel@tonic-gate * This function frees the allocated active crypto context and the
8340Sstevel@tonic-gate * lower level of allocated struct as needed.
8350Sstevel@tonic-gate * This function is called by the 1st tier of encrypt/decrypt routines
8360Sstevel@tonic-gate * or by the 2nd tier of session close routine. Since the 1st tier
8370Sstevel@tonic-gate * caller will always call this function without locking the session
8380Sstevel@tonic-gate * mutex and the 2nd tier caller will call with the lock, we add the
839*12573SDina.Nimeh@Sun.COM * third parameter "lock_held" to distinguish this case.
8400Sstevel@tonic-gate */
8410Sstevel@tonic-gate void
soft_crypt_cleanup(soft_session_t * session_p,boolean_t encrypt,boolean_t lock_held)8420Sstevel@tonic-gate soft_crypt_cleanup(soft_session_t *session_p, boolean_t encrypt,
8430Sstevel@tonic-gate boolean_t lock_held)
8440Sstevel@tonic-gate {
8450Sstevel@tonic-gate
8460Sstevel@tonic-gate crypto_active_op_t *active_op;
8470Sstevel@tonic-gate boolean_t lock_true = B_TRUE;
8480Sstevel@tonic-gate
8490Sstevel@tonic-gate if (!lock_held)
8500Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
8510Sstevel@tonic-gate
8520Sstevel@tonic-gate active_op = (encrypt) ? &(session_p->encrypt) : &(session_p->decrypt);
8530Sstevel@tonic-gate
8540Sstevel@tonic-gate switch (active_op->mech.mechanism) {
8550Sstevel@tonic-gate
8560Sstevel@tonic-gate case CKM_DES_CBC_PAD:
8570Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
8580Sstevel@tonic-gate case CKM_DES_CBC:
8590Sstevel@tonic-gate case CKM_DES_ECB:
8600Sstevel@tonic-gate case CKM_DES3_CBC:
8610Sstevel@tonic-gate case CKM_DES3_ECB:
8620Sstevel@tonic-gate {
8630Sstevel@tonic-gate
8640Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx =
8650Sstevel@tonic-gate (soft_des_ctx_t *)active_op->context;
8660Sstevel@tonic-gate des_ctx_t *des_ctx;
8670Sstevel@tonic-gate
8680Sstevel@tonic-gate if (soft_des_ctx != NULL) {
8690Sstevel@tonic-gate des_ctx = (des_ctx_t *)soft_des_ctx->des_cbc;
8700Sstevel@tonic-gate if (des_ctx != NULL) {
8710Sstevel@tonic-gate bzero(des_ctx->dc_keysched,
8720Sstevel@tonic-gate des_ctx->dc_keysched_len);
8730Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
8740Sstevel@tonic-gate }
8750Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
8760Sstevel@tonic-gate soft_des_ctx->keysched_len);
8770Sstevel@tonic-gate free(soft_des_ctx->key_sched);
8780Sstevel@tonic-gate }
8790Sstevel@tonic-gate break;
8800Sstevel@tonic-gate }
8810Sstevel@tonic-gate
8820Sstevel@tonic-gate case CKM_AES_CBC_PAD:
8830Sstevel@tonic-gate case CKM_AES_CBC:
8840Sstevel@tonic-gate case CKM_AES_ECB:
8850Sstevel@tonic-gate {
8860Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx =
8870Sstevel@tonic-gate (soft_aes_ctx_t *)active_op->context;
8880Sstevel@tonic-gate aes_ctx_t *aes_ctx;
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate if (soft_aes_ctx != NULL) {
8910Sstevel@tonic-gate aes_ctx = (aes_ctx_t *)soft_aes_ctx->aes_cbc;
8920Sstevel@tonic-gate if (aes_ctx != NULL) {
8930Sstevel@tonic-gate bzero(aes_ctx->ac_keysched,
8940Sstevel@tonic-gate aes_ctx->ac_keysched_len);
8950Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
8960Sstevel@tonic-gate }
8970Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
8980Sstevel@tonic-gate soft_aes_ctx->keysched_len);
8990Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
9000Sstevel@tonic-gate }
9010Sstevel@tonic-gate break;
9020Sstevel@tonic-gate }
9030Sstevel@tonic-gate
904676Sizick case CKM_BLOWFISH_CBC:
905676Sizick {
906676Sizick soft_blowfish_ctx_t *soft_blowfish_ctx =
907676Sizick (soft_blowfish_ctx_t *)active_op->context;
908676Sizick blowfish_ctx_t *blowfish_ctx;
909676Sizick
910676Sizick if (soft_blowfish_ctx != NULL) {
911676Sizick blowfish_ctx =
912676Sizick (blowfish_ctx_t *)soft_blowfish_ctx->blowfish_cbc;
913676Sizick if (blowfish_ctx != NULL) {
914676Sizick bzero(blowfish_ctx->bc_keysched,
915676Sizick blowfish_ctx->bc_keysched_len);
916676Sizick free(soft_blowfish_ctx->blowfish_cbc);
917676Sizick }
918676Sizick
919676Sizick bzero(soft_blowfish_ctx->key_sched,
920676Sizick soft_blowfish_ctx->keysched_len);
921676Sizick free(soft_blowfish_ctx->key_sched);
922676Sizick }
923676Sizick break;
924676Sizick }
925676Sizick
9260Sstevel@tonic-gate case CKM_RC4:
9270Sstevel@tonic-gate {
9280Sstevel@tonic-gate ARCFour_key *key = (ARCFour_key *)active_op->context;
9290Sstevel@tonic-gate
9300Sstevel@tonic-gate if (key != NULL)
9310Sstevel@tonic-gate bzero(key, sizeof (*key));
9320Sstevel@tonic-gate break;
9330Sstevel@tonic-gate }
9340Sstevel@tonic-gate
9350Sstevel@tonic-gate case CKM_RSA_X_509:
9360Sstevel@tonic-gate case CKM_RSA_PKCS:
9372940Sizick {
9382940Sizick soft_rsa_ctx_t *rsa_ctx =
9392940Sizick (soft_rsa_ctx_t *)active_op->context;
9402940Sizick
9412940Sizick if (rsa_ctx != NULL)
9422940Sizick if (rsa_ctx->key != NULL) {
9432940Sizick soft_cleanup_object(rsa_ctx->key);
9442940Sizick free(rsa_ctx->key);
9452940Sizick }
9462940Sizick
9470Sstevel@tonic-gate break;
9482940Sizick }
9490Sstevel@tonic-gate
9500Sstevel@tonic-gate } /* switch */
9510Sstevel@tonic-gate
9520Sstevel@tonic-gate if (active_op->context != NULL) {
9530Sstevel@tonic-gate free(active_op->context);
9540Sstevel@tonic-gate active_op->context = NULL;
9550Sstevel@tonic-gate }
9560Sstevel@tonic-gate
9570Sstevel@tonic-gate active_op->flags = 0;
9580Sstevel@tonic-gate
9590Sstevel@tonic-gate if (!lock_held)
9600Sstevel@tonic-gate SES_REFRELE(session_p, lock_true);
9610Sstevel@tonic-gate }
962