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 * Remove padding bytes.
420Sstevel@tonic-gate */
430Sstevel@tonic-gate CK_RV
soft_remove_pkcs7_padding(CK_BYTE * pData,CK_ULONG padded_len,CK_ULONG * pulDataLen)440Sstevel@tonic-gate soft_remove_pkcs7_padding(CK_BYTE *pData, CK_ULONG padded_len,
45*12573SDina.Nimeh@Sun.COM CK_ULONG *pulDataLen)
460Sstevel@tonic-gate {
47*12573SDina.Nimeh@Sun.COM CK_RV rv;
480Sstevel@tonic-gate
49*12573SDina.Nimeh@Sun.COM #ifdef __sparcv9
50*12573SDina.Nimeh@Sun.COM if ((rv = pkcs7_decode(pData, (&padded_len))) != CKR_OK)
51*12573SDina.Nimeh@Sun.COM #else /* !__sparcv9 */
52*12573SDina.Nimeh@Sun.COM if ((rv = pkcs7_decode(pData, (size_t *)(&padded_len))) != CKR_OK)
53*12573SDina.Nimeh@Sun.COM #endif /* __sparcv9 */
54*12573SDina.Nimeh@Sun.COM return (rv);
550Sstevel@tonic-gate
56*12573SDina.Nimeh@Sun.COM *pulDataLen = padded_len;
570Sstevel@tonic-gate return (CKR_OK);
580Sstevel@tonic-gate }
590Sstevel@tonic-gate
600Sstevel@tonic-gate
610Sstevel@tonic-gate /*
620Sstevel@tonic-gate * soft_decrypt_init()
630Sstevel@tonic-gate *
640Sstevel@tonic-gate * Arguments:
650Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
660Sstevel@tonic-gate * pMechanism: pointer to CK_MECHANISM struct provided by application
670Sstevel@tonic-gate * key_p: pointer to key soft_object_t struct
680Sstevel@tonic-gate *
690Sstevel@tonic-gate * Description:
700Sstevel@tonic-gate * called by C_DecryptInit(). This function calls the corresponding
710Sstevel@tonic-gate * decrypt init routine based on the mechanism.
720Sstevel@tonic-gate *
730Sstevel@tonic-gate * Returns:
740Sstevel@tonic-gate * CKR_OK: success
750Sstevel@tonic-gate * CKR_HOST_MEMORY: run out of system memory
760Sstevel@tonic-gate * CKR_MECHANISM_PARAM_INVALID: invalid parameters in mechanism
770Sstevel@tonic-gate * CKR_MECHANISM_INVALID: invalid mechanism type
780Sstevel@tonic-gate * CKR_KEY_TYPE_INCONSISTENT: incorrect type of key to use
790Sstevel@tonic-gate * with the specified mechanism
800Sstevel@tonic-gate */
810Sstevel@tonic-gate CK_RV
soft_decrypt_init(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p)820Sstevel@tonic-gate soft_decrypt_init(soft_session_t *session_p, CK_MECHANISM_PTR pMechanism,
830Sstevel@tonic-gate soft_object_t *key_p)
840Sstevel@tonic-gate {
850Sstevel@tonic-gate
860Sstevel@tonic-gate CK_RV rv;
870Sstevel@tonic-gate
880Sstevel@tonic-gate switch (pMechanism->mechanism) {
890Sstevel@tonic-gate
900Sstevel@tonic-gate case CKM_DES_ECB:
910Sstevel@tonic-gate
920Sstevel@tonic-gate if (key_p->key_type != CKK_DES) {
930Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
940Sstevel@tonic-gate }
950Sstevel@tonic-gate
960Sstevel@tonic-gate goto ecb_common;
970Sstevel@tonic-gate
980Sstevel@tonic-gate case CKM_DES3_ECB:
990Sstevel@tonic-gate
1000Sstevel@tonic-gate if ((key_p->key_type != CKK_DES2) &&
1010Sstevel@tonic-gate (key_p->key_type != CKK_DES3)) {
1020Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1030Sstevel@tonic-gate }
1040Sstevel@tonic-gate
1050Sstevel@tonic-gate ecb_common:
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate return (soft_des_crypt_init_common(session_p, pMechanism,
1080Sstevel@tonic-gate key_p, B_FALSE));
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate case CKM_DES_CBC:
1110Sstevel@tonic-gate case CKM_DES_CBC_PAD:
1120Sstevel@tonic-gate
1130Sstevel@tonic-gate if (key_p->key_type != CKK_DES) {
1140Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1150Sstevel@tonic-gate }
1160Sstevel@tonic-gate
1170Sstevel@tonic-gate goto cbc_common;
1180Sstevel@tonic-gate
1190Sstevel@tonic-gate case CKM_DES3_CBC:
1200Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
1210Sstevel@tonic-gate {
1220Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate if ((key_p->key_type != CKK_DES2) &&
1250Sstevel@tonic-gate (key_p->key_type != CKK_DES3)) {
1260Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate cbc_common:
1300Sstevel@tonic-gate if ((pMechanism->pParameter == NULL) ||
1310Sstevel@tonic-gate (pMechanism->ulParameterLen != DES_BLOCK_LEN)) {
1320Sstevel@tonic-gate return (CKR_MECHANISM_PARAM_INVALID);
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate rv = soft_des_crypt_init_common(session_p, pMechanism,
1360Sstevel@tonic-gate key_p, B_FALSE);
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate if (rv != CKR_OK)
1390Sstevel@tonic-gate return (rv);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
1440Sstevel@tonic-gate /* Save Initialization Vector (IV) in the context. */
1450Sstevel@tonic-gate (void) memcpy(soft_des_ctx->ivec, pMechanism->pParameter,
1460Sstevel@tonic-gate DES_BLOCK_LEN);
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate /* Allocate a context for DES cipher-block chaining. */
1490Sstevel@tonic-gate soft_des_ctx->des_cbc = (void *)des_cbc_ctx_init(
1500Sstevel@tonic-gate soft_des_ctx->key_sched, soft_des_ctx->keysched_len,
1510Sstevel@tonic-gate soft_des_ctx->ivec, key_p->key_type);
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate if (soft_des_ctx->des_cbc == NULL) {
1540Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
1550Sstevel@tonic-gate soft_des_ctx->keysched_len);
1560Sstevel@tonic-gate free(soft_des_ctx->key_sched);
1570Sstevel@tonic-gate free(session_p->decrypt.context);
1580Sstevel@tonic-gate session_p->decrypt.context = NULL;
1590Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
1600Sstevel@tonic-gate return (CKR_HOST_MEMORY);
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate return (rv);
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate case CKM_AES_ECB:
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate if (key_p->key_type != CKK_AES) {
1700Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate return (soft_aes_crypt_init_common(session_p, pMechanism,
1740Sstevel@tonic-gate key_p, B_FALSE));
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate case CKM_AES_CBC:
1770Sstevel@tonic-gate case CKM_AES_CBC_PAD:
1780Sstevel@tonic-gate {
1790Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
1800Sstevel@tonic-gate
1810Sstevel@tonic-gate if (key_p->key_type != CKK_AES) {
1820Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
1830Sstevel@tonic-gate }
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate if ((pMechanism->pParameter == NULL) ||
1860Sstevel@tonic-gate (pMechanism->ulParameterLen != AES_BLOCK_LEN)) {
1870Sstevel@tonic-gate return (CKR_MECHANISM_PARAM_INVALID);
1880Sstevel@tonic-gate }
1890Sstevel@tonic-gate
1900Sstevel@tonic-gate rv = soft_aes_crypt_init_common(session_p, pMechanism,
1910Sstevel@tonic-gate key_p, B_FALSE);
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate if (rv != CKR_OK)
1940Sstevel@tonic-gate return (rv);
1950Sstevel@tonic-gate
1960Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate /* Save Initialization Vector (IV) in the context. */
2010Sstevel@tonic-gate (void) memcpy(soft_aes_ctx->ivec, pMechanism->pParameter,
2020Sstevel@tonic-gate AES_BLOCK_LEN);
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate /* Allocate a context for AES cipher-block chaining. */
2050Sstevel@tonic-gate soft_aes_ctx->aes_cbc = (void *)aes_cbc_ctx_init(
2060Sstevel@tonic-gate soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2070Sstevel@tonic-gate soft_aes_ctx->ivec);
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate if (soft_aes_ctx->aes_cbc == NULL) {
2100Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
2110Sstevel@tonic-gate soft_aes_ctx->keysched_len);
2120Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
2130Sstevel@tonic-gate free(session_p->decrypt.context);
2140Sstevel@tonic-gate session_p->decrypt.context = NULL;
2150Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
2160Sstevel@tonic-gate return (CKR_HOST_MEMORY);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate
2190Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate return (rv);
2220Sstevel@tonic-gate }
2237188Smcpowers case CKM_AES_CTR:
2247188Smcpowers {
2257188Smcpowers soft_aes_ctx_t *soft_aes_ctx;
2260Sstevel@tonic-gate
2277188Smcpowers if (key_p->key_type != CKK_AES) {
2287188Smcpowers return (CKR_KEY_TYPE_INCONSISTENT);
2297188Smcpowers }
2307188Smcpowers
2317188Smcpowers if (pMechanism->pParameter == NULL ||
2327188Smcpowers pMechanism->ulParameterLen != sizeof (CK_AES_CTR_PARAMS)) {
2337188Smcpowers return (CKR_MECHANISM_PARAM_INVALID);
2347188Smcpowers }
2357188Smcpowers
2367188Smcpowers rv = soft_aes_crypt_init_common(session_p, pMechanism,
2377188Smcpowers key_p, B_FALSE);
2387188Smcpowers
2397188Smcpowers if (rv != CKR_OK)
2407188Smcpowers return (rv);
2417188Smcpowers
2427188Smcpowers (void) pthread_mutex_lock(&session_p->session_mutex);
2437188Smcpowers
2447188Smcpowers soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
2457188Smcpowers soft_aes_ctx->aes_cbc = aes_ctr_ctx_init(
2467188Smcpowers soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len,
2477188Smcpowers pMechanism->pParameter);
2487188Smcpowers
2497188Smcpowers if (soft_aes_ctx->aes_cbc == NULL) {
2507188Smcpowers bzero(soft_aes_ctx->key_sched,
2517188Smcpowers soft_aes_ctx->keysched_len);
2527188Smcpowers free(soft_aes_ctx->key_sched);
2537188Smcpowers free(session_p->decrypt.context);
2547188Smcpowers session_p->decrypt.context = NULL;
2557188Smcpowers rv = CKR_HOST_MEMORY;
2567188Smcpowers }
2577188Smcpowers
2587188Smcpowers (void) pthread_mutex_unlock(&session_p->session_mutex);
2597188Smcpowers
2607188Smcpowers return (rv);
2617188Smcpowers }
262676Sizick case CKM_BLOWFISH_CBC:
263676Sizick {
264676Sizick soft_blowfish_ctx_t *soft_blowfish_ctx;
265676Sizick
266676Sizick if (key_p->key_type != CKK_BLOWFISH)
267676Sizick return (CKR_KEY_TYPE_INCONSISTENT);
268676Sizick
269676Sizick if ((pMechanism->pParameter == NULL) ||
270676Sizick (pMechanism->ulParameterLen != BLOWFISH_BLOCK_LEN))
271676Sizick return (CKR_MECHANISM_PARAM_INVALID);
272676Sizick
273676Sizick rv = soft_blowfish_crypt_init_common(session_p, pMechanism,
274676Sizick key_p, B_FALSE);
275676Sizick
276676Sizick if (rv != CKR_OK)
277676Sizick return (rv);
278676Sizick
279676Sizick (void) pthread_mutex_lock(&session_p->session_mutex);
280676Sizick
281676Sizick soft_blowfish_ctx =
282676Sizick (soft_blowfish_ctx_t *)session_p->decrypt.context;
283676Sizick
284676Sizick /* Save Initialization Vector in the context. */
285676Sizick (void) memcpy(soft_blowfish_ctx->ivec, pMechanism->pParameter,
286676Sizick BLOWFISH_BLOCK_LEN);
287676Sizick
288676Sizick /* Allocate a context for CBC */
289676Sizick soft_blowfish_ctx->blowfish_cbc =
290676Sizick (void *)blowfish_cbc_ctx_init(soft_blowfish_ctx->key_sched,
2917188Smcpowers soft_blowfish_ctx->keysched_len,
2927188Smcpowers soft_blowfish_ctx->ivec);
293676Sizick
294676Sizick if (soft_blowfish_ctx->blowfish_cbc == NULL) {
295676Sizick bzero(soft_blowfish_ctx->key_sched,
296676Sizick soft_blowfish_ctx->keysched_len);
297676Sizick free(soft_blowfish_ctx->key_sched);
298676Sizick free(session_p->decrypt.context = NULL);
299676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
300676Sizick return (CKR_HOST_MEMORY);
301676Sizick }
302676Sizick
303676Sizick (void) pthread_mutex_unlock(&session_p->session_mutex);
304676Sizick return (rv);
305676Sizick }
306676Sizick
3070Sstevel@tonic-gate case CKM_RC4:
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate if (key_p->key_type != CKK_RC4) {
3100Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate return (soft_arcfour_crypt_init(session_p, pMechanism, key_p,
3140Sstevel@tonic-gate B_FALSE));
3150Sstevel@tonic-gate
3160Sstevel@tonic-gate case CKM_RSA_X_509:
3170Sstevel@tonic-gate case CKM_RSA_PKCS:
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate if (key_p->key_type != CKK_RSA) {
3200Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
3210Sstevel@tonic-gate }
3220Sstevel@tonic-gate
3230Sstevel@tonic-gate return (soft_rsa_crypt_init_common(session_p, pMechanism,
3240Sstevel@tonic-gate key_p, B_FALSE));
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate default:
3270Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
3280Sstevel@tonic-gate }
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate /*
3330Sstevel@tonic-gate * soft_decrypt_common()
3340Sstevel@tonic-gate *
3350Sstevel@tonic-gate * Arguments:
3360Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
3370Sstevel@tonic-gate * pEncrypted: pointer to the encrypted data as input
3380Sstevel@tonic-gate * ulEncryptedLen: length of the input data
3390Sstevel@tonic-gate * pData: pointer to the output data contains plaintext
3400Sstevel@tonic-gate * pulDataLen: pointer to the length of the output data
3410Sstevel@tonic-gate * Update: boolean flag indicates caller is soft_decrypt
3420Sstevel@tonic-gate * or soft_decrypt_update
3430Sstevel@tonic-gate *
3440Sstevel@tonic-gate * Description:
3450Sstevel@tonic-gate * This function calls the corresponding decrypt routine based
3460Sstevel@tonic-gate * on the mechanism.
3470Sstevel@tonic-gate *
3480Sstevel@tonic-gate * Returns:
3490Sstevel@tonic-gate * see soft_decrypt_common().
3500Sstevel@tonic-gate */
3510Sstevel@tonic-gate CK_RV
soft_decrypt_common(soft_session_t * session_p,CK_BYTE_PTR pEncrypted,CK_ULONG ulEncryptedLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen,boolean_t Update)3520Sstevel@tonic-gate soft_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
3530Sstevel@tonic-gate CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
3540Sstevel@tonic-gate CK_ULONG_PTR pulDataLen, boolean_t Update)
3550Sstevel@tonic-gate {
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate switch (mechanism) {
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate case CKM_DES_ECB:
3620Sstevel@tonic-gate case CKM_DES_CBC:
3630Sstevel@tonic-gate case CKM_DES3_ECB:
3640Sstevel@tonic-gate case CKM_DES3_CBC:
3652786Sdinak
3662786Sdinak if (ulEncryptedLen == 0) {
3672786Sdinak *pulDataLen = 0;
3682786Sdinak return (CKR_OK);
3692786Sdinak }
3702786Sdinak /* FALLTHROUGH */
3712786Sdinak
3722786Sdinak case CKM_DES_CBC_PAD:
3730Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate return (soft_des_decrypt_common(session_p, pEncrypted,
3760Sstevel@tonic-gate ulEncryptedLen, pData, pulDataLen, Update));
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate case CKM_AES_ECB:
3790Sstevel@tonic-gate case CKM_AES_CBC:
3807188Smcpowers case CKM_AES_CTR:
3812786Sdinak
3822786Sdinak if (ulEncryptedLen == 0) {
3832786Sdinak *pulDataLen = 0;
3842786Sdinak return (CKR_OK);
3852786Sdinak }
3862786Sdinak /* FALLTHROUGH */
3872786Sdinak
3880Sstevel@tonic-gate case CKM_AES_CBC_PAD:
3890Sstevel@tonic-gate
3900Sstevel@tonic-gate return (soft_aes_decrypt_common(session_p, pEncrypted,
3910Sstevel@tonic-gate ulEncryptedLen, pData, pulDataLen, Update));
3920Sstevel@tonic-gate
393676Sizick case CKM_BLOWFISH_CBC:
394676Sizick
3952786Sdinak if (ulEncryptedLen == 0) {
3962786Sdinak *pulDataLen = 0;
3972786Sdinak return (CKR_OK);
3982786Sdinak }
3992786Sdinak
400676Sizick return (soft_blowfish_decrypt_common(session_p, pEncrypted,
401676Sizick ulEncryptedLen, pData, pulDataLen, Update));
402676Sizick
4030Sstevel@tonic-gate case CKM_RC4:
4040Sstevel@tonic-gate
4052786Sdinak if (ulEncryptedLen == 0) {
4062786Sdinak *pulDataLen = 0;
4072786Sdinak return (CKR_OK);
4080Sstevel@tonic-gate }
4092786Sdinak
4102786Sdinak
4112786Sdinak return (soft_arcfour_crypt(&(session_p->decrypt), pEncrypted,
4122786Sdinak ulEncryptedLen, pData, pulDataLen));
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate case CKM_RSA_X_509:
4150Sstevel@tonic-gate case CKM_RSA_PKCS:
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate return (soft_rsa_decrypt_common(session_p, pEncrypted,
4180Sstevel@tonic-gate ulEncryptedLen, pData, pulDataLen, mechanism));
4190Sstevel@tonic-gate
4200Sstevel@tonic-gate default:
4210Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate }
4240Sstevel@tonic-gate }
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate
4270Sstevel@tonic-gate /*
4280Sstevel@tonic-gate * soft_decrypt()
4290Sstevel@tonic-gate *
4300Sstevel@tonic-gate * Arguments:
4310Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
4320Sstevel@tonic-gate * pEncryptedData: pointer to the encrypted data as input
4330Sstevel@tonic-gate * ulEncryptedDataLen: length of the input data
4340Sstevel@tonic-gate * pData: pointer to the output data contains plaintext
4350Sstevel@tonic-gate * pulDataLen: pointer to the length of the output data
4360Sstevel@tonic-gate *
4370Sstevel@tonic-gate * Description:
4380Sstevel@tonic-gate * called by C_Decrypt(). This function calls the soft_decrypt_common
4390Sstevel@tonic-gate * routine.
4400Sstevel@tonic-gate *
4410Sstevel@tonic-gate * Returns:
4420Sstevel@tonic-gate * see soft_decrypt_common().
4430Sstevel@tonic-gate */
4440Sstevel@tonic-gate CK_RV
soft_decrypt(soft_session_t * session_p,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)4450Sstevel@tonic-gate soft_decrypt(soft_session_t *session_p, CK_BYTE_PTR pEncryptedData,
4460Sstevel@tonic-gate CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData,
4470Sstevel@tonic-gate CK_ULONG_PTR pulDataLen)
4480Sstevel@tonic-gate {
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate return (soft_decrypt_common(session_p, pEncryptedData,
4510Sstevel@tonic-gate ulEncryptedDataLen, pData, pulDataLen, B_FALSE));
4520Sstevel@tonic-gate }
4530Sstevel@tonic-gate
4540Sstevel@tonic-gate
4550Sstevel@tonic-gate /*
4560Sstevel@tonic-gate * soft_decrypt_update()
4570Sstevel@tonic-gate *
4580Sstevel@tonic-gate * Arguments:
4590Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
4600Sstevel@tonic-gate * pEncryptedPart: pointer to the encrypted data as input
4610Sstevel@tonic-gate * ulEncryptedPartLen: length of the input data
4620Sstevel@tonic-gate * pPart: pointer to the output data contains plaintext
4630Sstevel@tonic-gate * pulPartLen: pointer to the length of the output data
4640Sstevel@tonic-gate *
4650Sstevel@tonic-gate * Description:
4660Sstevel@tonic-gate * called by C_DecryptUpdate(). This function calls the
4670Sstevel@tonic-gate * soft_decrypt_common routine (with update flag on).
4680Sstevel@tonic-gate *
4690Sstevel@tonic-gate * Returns:
4700Sstevel@tonic-gate * see soft_decrypt_common().
4710Sstevel@tonic-gate */
4720Sstevel@tonic-gate CK_RV
soft_decrypt_update(soft_session_t * session_p,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)4730Sstevel@tonic-gate soft_decrypt_update(soft_session_t *session_p, CK_BYTE_PTR pEncryptedPart,
4740Sstevel@tonic-gate CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
4750Sstevel@tonic-gate CK_ULONG_PTR pulPartLen)
4760Sstevel@tonic-gate {
4770Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate switch (mechanism) {
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate case CKM_DES_ECB:
4820Sstevel@tonic-gate case CKM_DES_CBC:
4830Sstevel@tonic-gate case CKM_DES_CBC_PAD:
4840Sstevel@tonic-gate case CKM_DES3_ECB:
4850Sstevel@tonic-gate case CKM_DES3_CBC:
4860Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
4870Sstevel@tonic-gate case CKM_AES_ECB:
4880Sstevel@tonic-gate case CKM_AES_CBC:
4890Sstevel@tonic-gate case CKM_AES_CBC_PAD:
4907188Smcpowers case CKM_AES_CTR:
491676Sizick case CKM_BLOWFISH_CBC:
4922786Sdinak case CKM_RC4:
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate return (soft_decrypt_common(session_p, pEncryptedPart,
4950Sstevel@tonic-gate ulEncryptedPartLen, pPart, pulPartLen, B_TRUE));
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate default:
4980Sstevel@tonic-gate /* PKCS11: The mechanism only supports single-part operation. */
4990Sstevel@tonic-gate return (CKR_MECHANISM_INVALID);
5000Sstevel@tonic-gate }
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate
5050Sstevel@tonic-gate /*
5060Sstevel@tonic-gate * soft_decrypt_final()
5070Sstevel@tonic-gate *
5080Sstevel@tonic-gate * Arguments:
5090Sstevel@tonic-gate * session_p: pointer to soft_session_t struct
5100Sstevel@tonic-gate * pLastPart: pointer to the last recovered data part
5110Sstevel@tonic-gate * pulLastPartLen: pointer to the length of the last recovered data part
5120Sstevel@tonic-gate *
5130Sstevel@tonic-gate * Description:
5140Sstevel@tonic-gate * called by C_DecryptFinal().
5150Sstevel@tonic-gate *
5160Sstevel@tonic-gate * Returns:
5170Sstevel@tonic-gate * CKR_OK: success
5180Sstevel@tonic-gate * CKR_FUNCTION_FAILED: decrypt final function failed
5190Sstevel@tonic-gate * CKR_ENCRYPTED_DATA_LEN_RANGE: remaining buffer contains bad length
5200Sstevel@tonic-gate */
5210Sstevel@tonic-gate CK_RV
soft_decrypt_final(soft_session_t * session_p,CK_BYTE_PTR pLastPart,CK_ULONG_PTR pulLastPartLen)5220Sstevel@tonic-gate soft_decrypt_final(soft_session_t *session_p, CK_BYTE_PTR pLastPart,
5230Sstevel@tonic-gate CK_ULONG_PTR pulLastPartLen)
5240Sstevel@tonic-gate {
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->decrypt.mech.mechanism;
5270Sstevel@tonic-gate CK_ULONG out_len;
5280Sstevel@tonic-gate CK_RV rv = CKR_OK;
5290Sstevel@tonic-gate int rc;
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate if (session_p->decrypt.context == NULL) {
5340Sstevel@tonic-gate rv = CKR_OPERATION_NOT_INITIALIZED;
5350Sstevel@tonic-gate *pulLastPartLen = 0;
5360Sstevel@tonic-gate goto clean2;
5370Sstevel@tonic-gate }
5380Sstevel@tonic-gate switch (mechanism) {
5390Sstevel@tonic-gate
5400Sstevel@tonic-gate case CKM_DES_CBC_PAD:
5410Sstevel@tonic-gate case CKM_DES3_CBC_PAD:
5420Sstevel@tonic-gate {
5430Sstevel@tonic-gate
5440Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
5470Sstevel@tonic-gate
5480Sstevel@tonic-gate /*
5490Sstevel@tonic-gate * We should have only one block of data left in the
5500Sstevel@tonic-gate * remaining buffer.
5510Sstevel@tonic-gate */
5520Sstevel@tonic-gate if (soft_des_ctx->remain_len != DES_BLOCK_LEN) {
5530Sstevel@tonic-gate *pulLastPartLen = 0;
5540Sstevel@tonic-gate rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
5550Sstevel@tonic-gate /* Cleanup memory space. */
5560Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
5570Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
5580Sstevel@tonic-gate soft_des_ctx->keysched_len);
5590Sstevel@tonic-gate free(soft_des_ctx->key_sched);
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate goto clean1;
5620Sstevel@tonic-gate }
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate out_len = DES_BLOCK_LEN;
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate /*
5670Sstevel@tonic-gate * If application asks for the length of the output buffer
5680Sstevel@tonic-gate * to hold the plaintext?
5690Sstevel@tonic-gate */
5700Sstevel@tonic-gate if (pLastPart == NULL) {
5710Sstevel@tonic-gate *pulLastPartLen = out_len;
5720Sstevel@tonic-gate rv = CKR_OK;
5730Sstevel@tonic-gate goto clean2;
5740Sstevel@tonic-gate } else {
5750Sstevel@tonic-gate crypto_data_t out;
5760Sstevel@tonic-gate
5770Sstevel@tonic-gate /* Copy remaining data to the output buffer. */
5780Sstevel@tonic-gate (void) memcpy(pLastPart, soft_des_ctx->data,
5790Sstevel@tonic-gate DES_BLOCK_LEN);
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate out.cd_format = CRYPTO_DATA_RAW;
5820Sstevel@tonic-gate out.cd_offset = 0;
5830Sstevel@tonic-gate out.cd_length = DES_BLOCK_LEN;
5840Sstevel@tonic-gate out.cd_raw.iov_base = (char *)pLastPart;
5850Sstevel@tonic-gate out.cd_raw.iov_len = DES_BLOCK_LEN;
5860Sstevel@tonic-gate
5870Sstevel@tonic-gate /* Decrypt final block of data. */
5880Sstevel@tonic-gate rc = des_decrypt_contiguous_blocks(
5890Sstevel@tonic-gate (des_ctx_t *)soft_des_ctx->des_cbc,
5900Sstevel@tonic-gate (char *)pLastPart, DES_BLOCK_LEN, &out);
5910Sstevel@tonic-gate
5920Sstevel@tonic-gate if (rc == 0) {
5930Sstevel@tonic-gate /*
5940Sstevel@tonic-gate * Remove padding bytes after decryption of
5950Sstevel@tonic-gate * ciphertext block to produce the original
5960Sstevel@tonic-gate * plaintext.
5970Sstevel@tonic-gate */
5980Sstevel@tonic-gate rv = soft_remove_pkcs7_padding(pLastPart,
599*12573SDina.Nimeh@Sun.COM DES_BLOCK_LEN, &out_len);
6000Sstevel@tonic-gate if (rv != CKR_OK)
6010Sstevel@tonic-gate *pulLastPartLen = 0;
6020Sstevel@tonic-gate else
6030Sstevel@tonic-gate *pulLastPartLen = out_len;
6040Sstevel@tonic-gate } else {
6050Sstevel@tonic-gate *pulLastPartLen = 0;
6060Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate /* Cleanup memory space. */
6100Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
6110Sstevel@tonic-gate bzero(soft_des_ctx->key_sched,
6120Sstevel@tonic-gate soft_des_ctx->keysched_len);
6130Sstevel@tonic-gate free(soft_des_ctx->key_sched);
6140Sstevel@tonic-gate
6150Sstevel@tonic-gate }
6160Sstevel@tonic-gate
6170Sstevel@tonic-gate break;
6180Sstevel@tonic-gate }
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate case CKM_DES_CBC:
6210Sstevel@tonic-gate case CKM_DES_ECB:
6220Sstevel@tonic-gate case CKM_DES3_CBC:
6230Sstevel@tonic-gate case CKM_DES3_ECB:
6240Sstevel@tonic-gate {
6250Sstevel@tonic-gate
6260Sstevel@tonic-gate soft_des_ctx_t *soft_des_ctx;
6270Sstevel@tonic-gate
6280Sstevel@tonic-gate soft_des_ctx = (soft_des_ctx_t *)session_p->decrypt.context;
6290Sstevel@tonic-gate /*
6300Sstevel@tonic-gate * CKM_DES_CBC and CKM_DES_ECB does not do any padding,
6310Sstevel@tonic-gate * so when the final is called, the remaining buffer
6320Sstevel@tonic-gate * should not contain any more data.
6330Sstevel@tonic-gate */
6340Sstevel@tonic-gate *pulLastPartLen = 0;
6350Sstevel@tonic-gate if (soft_des_ctx->remain_len != 0) {
6360Sstevel@tonic-gate rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
6370Sstevel@tonic-gate } else {
6380Sstevel@tonic-gate if (pLastPart == NULL)
6390Sstevel@tonic-gate goto clean2;
6400Sstevel@tonic-gate }
6410Sstevel@tonic-gate
6420Sstevel@tonic-gate /* Cleanup memory space. */
6430Sstevel@tonic-gate free(soft_des_ctx->des_cbc);
6440Sstevel@tonic-gate bzero(soft_des_ctx->key_sched, soft_des_ctx->keysched_len);
6450Sstevel@tonic-gate free(soft_des_ctx->key_sched);
6460Sstevel@tonic-gate
6470Sstevel@tonic-gate break;
6480Sstevel@tonic-gate }
6490Sstevel@tonic-gate
6500Sstevel@tonic-gate case CKM_AES_CBC_PAD:
6510Sstevel@tonic-gate {
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
6540Sstevel@tonic-gate
6550Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate /*
6580Sstevel@tonic-gate * We should have only one block of data left in the
6590Sstevel@tonic-gate * remaining buffer.
6600Sstevel@tonic-gate */
6610Sstevel@tonic-gate if (soft_aes_ctx->remain_len != AES_BLOCK_LEN) {
6620Sstevel@tonic-gate *pulLastPartLen = 0;
6630Sstevel@tonic-gate rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
6640Sstevel@tonic-gate /* Cleanup memory space. */
6650Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
6660Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
6670Sstevel@tonic-gate soft_aes_ctx->keysched_len);
6680Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
6690Sstevel@tonic-gate
6700Sstevel@tonic-gate goto clean1;
6710Sstevel@tonic-gate }
6720Sstevel@tonic-gate
6730Sstevel@tonic-gate out_len = AES_BLOCK_LEN;
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate /*
6760Sstevel@tonic-gate * If application asks for the length of the output buffer
6770Sstevel@tonic-gate * to hold the plaintext?
6780Sstevel@tonic-gate */
6790Sstevel@tonic-gate if (pLastPart == NULL) {
6800Sstevel@tonic-gate *pulLastPartLen = out_len;
6810Sstevel@tonic-gate rv = CKR_OK;
6820Sstevel@tonic-gate goto clean2;
6830Sstevel@tonic-gate } else {
6840Sstevel@tonic-gate crypto_data_t out;
6850Sstevel@tonic-gate
6860Sstevel@tonic-gate /* Copy remaining data to the output buffer. */
6870Sstevel@tonic-gate (void) memcpy(pLastPart, soft_aes_ctx->data,
6880Sstevel@tonic-gate AES_BLOCK_LEN);
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate out.cd_format = CRYPTO_DATA_RAW;
6910Sstevel@tonic-gate out.cd_offset = 0;
6920Sstevel@tonic-gate out.cd_length = AES_BLOCK_LEN;
6930Sstevel@tonic-gate out.cd_raw.iov_base = (char *)pLastPart;
6940Sstevel@tonic-gate out.cd_raw.iov_len = AES_BLOCK_LEN;
6950Sstevel@tonic-gate
6960Sstevel@tonic-gate /* Decrypt final block of data. */
6970Sstevel@tonic-gate rc = aes_decrypt_contiguous_blocks(
6980Sstevel@tonic-gate (aes_ctx_t *)soft_aes_ctx->aes_cbc,
6990Sstevel@tonic-gate (char *)pLastPart, AES_BLOCK_LEN, &out);
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate if (rc == 0) {
7020Sstevel@tonic-gate /*
7030Sstevel@tonic-gate * Remove padding bytes after decryption of
7040Sstevel@tonic-gate * ciphertext block to produce the original
7050Sstevel@tonic-gate * plaintext.
7060Sstevel@tonic-gate */
7070Sstevel@tonic-gate rv = soft_remove_pkcs7_padding(pLastPart,
708*12573SDina.Nimeh@Sun.COM AES_BLOCK_LEN, &out_len);
7090Sstevel@tonic-gate if (rv != CKR_OK)
7100Sstevel@tonic-gate *pulLastPartLen = 0;
7110Sstevel@tonic-gate else
7120Sstevel@tonic-gate *pulLastPartLen = out_len;
7130Sstevel@tonic-gate } else {
7140Sstevel@tonic-gate *pulLastPartLen = 0;
7150Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
7160Sstevel@tonic-gate }
7170Sstevel@tonic-gate
7180Sstevel@tonic-gate /* Cleanup memory space. */
7190Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
7200Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched,
7210Sstevel@tonic-gate soft_aes_ctx->keysched_len);
7220Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
7230Sstevel@tonic-gate
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate
7260Sstevel@tonic-gate break;
7270Sstevel@tonic-gate }
7280Sstevel@tonic-gate
7290Sstevel@tonic-gate case CKM_AES_CBC:
7300Sstevel@tonic-gate case CKM_AES_ECB:
7310Sstevel@tonic-gate {
7320Sstevel@tonic-gate soft_aes_ctx_t *soft_aes_ctx;
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
7350Sstevel@tonic-gate /*
7360Sstevel@tonic-gate * CKM_AES_CBC and CKM_AES_ECB does not do any padding,
7370Sstevel@tonic-gate * so when the final is called, the remaining buffer
7380Sstevel@tonic-gate * should not contain any more data.
7390Sstevel@tonic-gate */
7400Sstevel@tonic-gate *pulLastPartLen = 0;
7410Sstevel@tonic-gate if (soft_aes_ctx->remain_len != 0) {
7420Sstevel@tonic-gate rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
7430Sstevel@tonic-gate } else {
7440Sstevel@tonic-gate if (pLastPart == NULL)
7450Sstevel@tonic-gate goto clean2;
7460Sstevel@tonic-gate }
7470Sstevel@tonic-gate
7480Sstevel@tonic-gate /* Cleanup memory space. */
7490Sstevel@tonic-gate free(soft_aes_ctx->aes_cbc);
7500Sstevel@tonic-gate bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
7510Sstevel@tonic-gate free(soft_aes_ctx->key_sched);
7520Sstevel@tonic-gate
7530Sstevel@tonic-gate break;
7540Sstevel@tonic-gate }
7557188Smcpowers case CKM_AES_CTR:
7567188Smcpowers {
7577188Smcpowers crypto_data_t out;
7587188Smcpowers soft_aes_ctx_t *soft_aes_ctx;
7597188Smcpowers ctr_ctx_t *ctr_ctx;
7607188Smcpowers size_t len;
7610Sstevel@tonic-gate
7627188Smcpowers soft_aes_ctx = (soft_aes_ctx_t *)session_p->decrypt.context;
7637188Smcpowers ctr_ctx = soft_aes_ctx->aes_cbc;
7647188Smcpowers len = ctr_ctx->ctr_remainder_len;
7657188Smcpowers if (pLastPart == NULL) {
7667188Smcpowers *pulLastPartLen = len;
7677188Smcpowers goto clean1;
7687188Smcpowers }
7697188Smcpowers if (len > 0) {
7707188Smcpowers out.cd_format = CRYPTO_DATA_RAW;
7717188Smcpowers out.cd_offset = 0;
7727188Smcpowers out.cd_length = len;
7737188Smcpowers out.cd_raw.iov_base = (char *)pLastPart;
7747188Smcpowers out.cd_raw.iov_len = len;
7757188Smcpowers
7767188Smcpowers rv = ctr_mode_final(ctr_ctx, &out, aes_encrypt_block);
7777188Smcpowers if (rv == CRYPTO_DATA_LEN_RANGE)
7787188Smcpowers rv = CRYPTO_ENCRYPTED_DATA_LEN_RANGE;
7797188Smcpowers }
7807188Smcpowers if (rv == CRYPTO_BUFFER_TOO_SMALL) {
7817188Smcpowers *pulLastPartLen = len;
7827188Smcpowers goto clean1;
7837188Smcpowers }
7847188Smcpowers
7857188Smcpowers /* Cleanup memory space. */
7867188Smcpowers free(ctr_ctx);
7877188Smcpowers bzero(soft_aes_ctx->key_sched, soft_aes_ctx->keysched_len);
7887188Smcpowers free(soft_aes_ctx->key_sched);
7897188Smcpowers
7907188Smcpowers break;
7917188Smcpowers }
792676Sizick case CKM_BLOWFISH_CBC:
793676Sizick {
794676Sizick soft_blowfish_ctx_t *soft_blowfish_ctx;
795676Sizick
796676Sizick soft_blowfish_ctx =
797676Sizick (soft_blowfish_ctx_t *)session_p->decrypt.context;
798676Sizick
799676Sizick *pulLastPartLen = 0;
800676Sizick if (soft_blowfish_ctx->remain_len != 0)
801676Sizick rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
802676Sizick else {
803676Sizick if (pLastPart == NULL)
804676Sizick goto clean2;
805676Sizick }
806676Sizick
807676Sizick free(soft_blowfish_ctx->blowfish_cbc);
808676Sizick bzero(soft_blowfish_ctx->key_sched,
809676Sizick soft_blowfish_ctx->keysched_len);
810676Sizick free(soft_blowfish_ctx->key_sched);
811676Sizick
812676Sizick break;
813676Sizick }
814676Sizick
8150Sstevel@tonic-gate case CKM_RC4:
8160Sstevel@tonic-gate {
8170Sstevel@tonic-gate ARCFour_key *key = (ARCFour_key *)session_p->decrypt.context;
8180Sstevel@tonic-gate bzero(key, sizeof (*key));
8190Sstevel@tonic-gate *pulLastPartLen = 0;
8200Sstevel@tonic-gate break;
8210Sstevel@tonic-gate }
8220Sstevel@tonic-gate
8230Sstevel@tonic-gate default:
8240Sstevel@tonic-gate /* PKCS11: The mechanism only supports single-part operation. */
8250Sstevel@tonic-gate rv = CKR_MECHANISM_INVALID;
8260Sstevel@tonic-gate break;
8270Sstevel@tonic-gate }
8280Sstevel@tonic-gate
8290Sstevel@tonic-gate clean1:
8300Sstevel@tonic-gate free(session_p->decrypt.context);
8310Sstevel@tonic-gate session_p->decrypt.context = NULL;
8320Sstevel@tonic-gate
8330Sstevel@tonic-gate clean2:
8340Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
8350Sstevel@tonic-gate
8360Sstevel@tonic-gate return (rv);
8370Sstevel@tonic-gate
8380Sstevel@tonic-gate }
839