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
5b60f2a0bSfr41279 * Common Development and Distribution License (the "License").
6b60f2a0bSfr41279 * 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 */
217c478bd9Sstevel@tonic-gate
22*726fad2aSDina K Nimeh /*
23*726fad2aSDina K Nimeh * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24*726fad2aSDina K Nimeh */
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>
32*726fad2aSDina K Nimeh #include <cryptoutil.h>
337c478bd9Sstevel@tonic-gate #include "softGlobal.h"
347c478bd9Sstevel@tonic-gate #include "softSession.h"
357c478bd9Sstevel@tonic-gate #include "softObject.h"
367c478bd9Sstevel@tonic-gate #include "softOps.h"
377c478bd9Sstevel@tonic-gate #include "softRSA.h"
387c478bd9Sstevel@tonic-gate #include "softMAC.h"
397c478bd9Sstevel@tonic-gate #include "softCrypt.h"
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_encrypt(soft_object_t * key,CK_BYTE_PTR in,uint32_t in_len,CK_BYTE_PTR out,int realpublic)427c478bd9Sstevel@tonic-gate soft_rsa_encrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
437c478bd9Sstevel@tonic-gate CK_BYTE_PTR out, int realpublic)
447c478bd9Sstevel@tonic-gate {
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
477c478bd9Sstevel@tonic-gate
487c478bd9Sstevel@tonic-gate uchar_t expo[MAX_KEY_ATTR_BUFLEN];
497c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
507c478bd9Sstevel@tonic-gate uint32_t expo_len = sizeof (expo);
517c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
52*726fad2aSDina K Nimeh RSAbytekey k;
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate if (realpublic) {
55c64d15a5Smcpowers rv = soft_get_public_value(key, CKA_PUBLIC_EXPONENT, expo,
567c478bd9Sstevel@tonic-gate &expo_len);
577c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
587c478bd9Sstevel@tonic-gate goto clean1;
597c478bd9Sstevel@tonic-gate }
607c478bd9Sstevel@tonic-gate } else {
61c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_PRIVATE_EXPONENT, expo,
627c478bd9Sstevel@tonic-gate &expo_len);
637c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
647c478bd9Sstevel@tonic-gate goto clean1;
657c478bd9Sstevel@tonic-gate }
667c478bd9Sstevel@tonic-gate }
677c478bd9Sstevel@tonic-gate
68c64d15a5Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
697c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
707c478bd9Sstevel@tonic-gate goto clean1;
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate
73*726fad2aSDina K Nimeh k.modulus = modulus;
74*726fad2aSDina K Nimeh k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
75*726fad2aSDina K Nimeh k.pubexpo = expo;
76*726fad2aSDina K Nimeh k.pubexpo_bytes = expo_len;
77*726fad2aSDina K Nimeh k.rfunc = NULL;
787c478bd9Sstevel@tonic-gate
79*726fad2aSDina K Nimeh rv = rsa_encrypt(&k, in, in_len, out);
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate clean1:
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate return (rv);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_decrypt(soft_object_t * key,CK_BYTE_PTR in,uint32_t in_len,CK_BYTE_PTR out)887c478bd9Sstevel@tonic-gate soft_rsa_decrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
897c478bd9Sstevel@tonic-gate CK_BYTE_PTR out)
907c478bd9Sstevel@tonic-gate {
917c478bd9Sstevel@tonic-gate
927c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
957c478bd9Sstevel@tonic-gate uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
967c478bd9Sstevel@tonic-gate uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
977c478bd9Sstevel@tonic-gate uchar_t expo1[MAX_KEY_ATTR_BUFLEN];
987c478bd9Sstevel@tonic-gate uchar_t expo2[MAX_KEY_ATTR_BUFLEN];
997c478bd9Sstevel@tonic-gate uchar_t coef[MAX_KEY_ATTR_BUFLEN];
1007c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
1017c478bd9Sstevel@tonic-gate uint32_t prime1_len = sizeof (prime1);
1027c478bd9Sstevel@tonic-gate uint32_t prime2_len = sizeof (prime2);
1037c478bd9Sstevel@tonic-gate uint32_t expo1_len = sizeof (expo1);
1047c478bd9Sstevel@tonic-gate uint32_t expo2_len = sizeof (expo2);
1057c478bd9Sstevel@tonic-gate uint32_t coef_len = sizeof (coef);
106*726fad2aSDina K Nimeh RSAbytekey k;
1077c478bd9Sstevel@tonic-gate
108c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
1097c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1107c478bd9Sstevel@tonic-gate goto clean1;
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate
113c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_PRIME_1, prime1, &prime1_len);
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate if ((prime1_len == 0) && (rv == CKR_OK)) {
1167c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1177c478bd9Sstevel@tonic-gate goto clean1;
1187c478bd9Sstevel@tonic-gate } else {
1197c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1207c478bd9Sstevel@tonic-gate goto clean1;
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate
123c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_PRIME_2, prime2, &prime2_len);
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate if ((prime2_len == 0) && (rv == CKR_OK)) {
1267c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1277c478bd9Sstevel@tonic-gate goto clean1;
1287c478bd9Sstevel@tonic-gate } else {
1297c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1307c478bd9Sstevel@tonic-gate goto clean1;
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate
133c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_EXPONENT_1, expo1, &expo1_len);
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate if ((expo1_len == 0) && (rv == CKR_OK)) {
1367c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1377c478bd9Sstevel@tonic-gate goto clean1;
1387c478bd9Sstevel@tonic-gate } else {
1397c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1407c478bd9Sstevel@tonic-gate goto clean1;
1417c478bd9Sstevel@tonic-gate }
1427c478bd9Sstevel@tonic-gate
143c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_EXPONENT_2, expo2, &expo2_len);
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate if ((expo2_len == 0) && (rv == CKR_OK)) {
1467c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1477c478bd9Sstevel@tonic-gate goto clean1;
1487c478bd9Sstevel@tonic-gate } else {
1497c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1507c478bd9Sstevel@tonic-gate goto clean1;
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate
153c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_COEFFICIENT, coef, &coef_len);
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate if ((coef_len == 0) && (rv == CKR_OK)) {
1567c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1577c478bd9Sstevel@tonic-gate goto clean1;
1587c478bd9Sstevel@tonic-gate } else {
1597c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1607c478bd9Sstevel@tonic-gate goto clean1;
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate
163*726fad2aSDina K Nimeh k.modulus = modulus;
164*726fad2aSDina K Nimeh k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
165*726fad2aSDina K Nimeh k.prime1 = prime1;
166*726fad2aSDina K Nimeh k.prime1_bytes = prime1_len;
167*726fad2aSDina K Nimeh k.prime2 = prime2;
168*726fad2aSDina K Nimeh k.prime2_bytes = prime2_len;
169*726fad2aSDina K Nimeh k.expo1 = expo1;
170*726fad2aSDina K Nimeh k.expo1_bytes = expo1_len;
171*726fad2aSDina K Nimeh k.expo2 = expo2;
172*726fad2aSDina K Nimeh k.expo2_bytes = expo2_len;
173*726fad2aSDina K Nimeh k.coeff = coef;
174*726fad2aSDina K Nimeh k.coeff_bytes = coef_len;
175*726fad2aSDina K Nimeh k.rfunc = NULL;
1767c478bd9Sstevel@tonic-gate
177*726fad2aSDina K Nimeh rv = rsa_decrypt(&k, in, in_len, out);
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate clean1:
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate return (rv);
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate * Allocate a RSA context for the active encryption or decryption operation.
1867c478bd9Sstevel@tonic-gate * This function is called without the session lock held.
1877c478bd9Sstevel@tonic-gate */
1887c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_crypt_init_common(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p,boolean_t encrypt)1897c478bd9Sstevel@tonic-gate soft_rsa_crypt_init_common(soft_session_t *session_p,
1907c478bd9Sstevel@tonic-gate CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
1917c478bd9Sstevel@tonic-gate boolean_t encrypt)
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx;
1957c478bd9Sstevel@tonic-gate soft_object_t *tmp_key = NULL;
1967c478bd9Sstevel@tonic-gate CK_RV rv;
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate rsa_ctx = calloc(1, sizeof (soft_rsa_ctx_t));
1997c478bd9Sstevel@tonic-gate if (rsa_ctx == NULL) {
2007c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY);
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate * Make a copy of the encryption or decryption key, and save it
2057c478bd9Sstevel@tonic-gate * in the RSA crypto context since it will be used later for
2067c478bd9Sstevel@tonic-gate * encryption/decryption. We don't want to hold any object reference
2077c478bd9Sstevel@tonic-gate * on this original key while doing encryption/decryption.
2087c478bd9Sstevel@tonic-gate */
2097c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&key_p->object_mutex);
2107c478bd9Sstevel@tonic-gate rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
2117c478bd9Sstevel@tonic-gate NULL);
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate if ((rv != CKR_OK) || (tmp_key == NULL)) {
2147c478bd9Sstevel@tonic-gate /* Most likely we ran out of space. */
2157c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
2167c478bd9Sstevel@tonic-gate free(rsa_ctx);
2177c478bd9Sstevel@tonic-gate return (rv);
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate /* No need to hold the lock on the old object. */
2217c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
2227c478bd9Sstevel@tonic-gate rsa_ctx->key = tmp_key;
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
2257c478bd9Sstevel@tonic-gate if (encrypt) {
2267c478bd9Sstevel@tonic-gate /* Called by C_EncryptInit. */
2277c478bd9Sstevel@tonic-gate session_p->encrypt.context = rsa_ctx;
2287c478bd9Sstevel@tonic-gate session_p->encrypt.mech.mechanism = pMechanism->mechanism;
2297c478bd9Sstevel@tonic-gate } else {
2307c478bd9Sstevel@tonic-gate /* Called by C_DecryptInit. */
2317c478bd9Sstevel@tonic-gate session_p->decrypt.context = rsa_ctx;
2327c478bd9Sstevel@tonic-gate session_p->decrypt.mech.mechanism = pMechanism->mechanism;
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
2357c478bd9Sstevel@tonic-gate
2367c478bd9Sstevel@tonic-gate return (CKR_OK);
2377c478bd9Sstevel@tonic-gate }
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_encrypt_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncrypted,CK_ULONG_PTR pulEncryptedLen,CK_MECHANISM_TYPE mechanism)2407c478bd9Sstevel@tonic-gate soft_rsa_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
2417c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
2427c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedLen, CK_MECHANISM_TYPE mechanism)
2437c478bd9Sstevel@tonic-gate {
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->encrypt.context;
2467c478bd9Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
2477c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
2487c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
2497c478bd9Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
2507c478bd9Sstevel@tonic-gate CK_BYTE cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES];
2517c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
2527c478bd9Sstevel@tonic-gate
253c64d15a5Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
2547c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
2557c478bd9Sstevel@tonic-gate goto clean_exit;
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate if (pEncrypted == NULL) {
2597c478bd9Sstevel@tonic-gate /*
2607c478bd9Sstevel@tonic-gate * Application asks for the length of the output buffer
2617c478bd9Sstevel@tonic-gate * to hold the ciphertext.
2627c478bd9Sstevel@tonic-gate */
2637c478bd9Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2647c478bd9Sstevel@tonic-gate rv = CKR_OK;
2657c478bd9Sstevel@tonic-gate goto clean1;
2667c478bd9Sstevel@tonic-gate }
2677c478bd9Sstevel@tonic-gate
2687c478bd9Sstevel@tonic-gate if (mechanism == CKM_RSA_PKCS) {
2697c478bd9Sstevel@tonic-gate /*
2707c478bd9Sstevel@tonic-gate * Input data length needs to be <=
2717c478bd9Sstevel@tonic-gate * modulus length-MIN_PKCS1_PADLEN.
2727c478bd9Sstevel@tonic-gate */
2737c478bd9Sstevel@tonic-gate if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
2747c478bd9Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2757c478bd9Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
2767c478bd9Sstevel@tonic-gate goto clean_exit;
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate } else {
2797c478bd9Sstevel@tonic-gate /* Input data length needs to be <= modulus length. */
2807c478bd9Sstevel@tonic-gate if (ulDataLen > (CK_ULONG)modulus_len) {
2817c478bd9Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2827c478bd9Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
2837c478bd9Sstevel@tonic-gate goto clean_exit;
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
2887c478bd9Sstevel@tonic-gate if (*pulEncryptedLen < (CK_ULONG)modulus_len) {
2897c478bd9Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2907c478bd9Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
2917c478bd9Sstevel@tonic-gate goto clean1;
2927c478bd9Sstevel@tonic-gate }
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate if (mechanism == CKM_RSA_PKCS) {
2957c478bd9Sstevel@tonic-gate /*
2967c478bd9Sstevel@tonic-gate * Add PKCS padding to the input data to format a block
2977c478bd9Sstevel@tonic-gate * type "02" encryption block.
2987c478bd9Sstevel@tonic-gate */
299*726fad2aSDina K Nimeh rv = pkcs1_encode(PKCS1_ENCRYPT, pData, ulDataLen, plain_data,
3007c478bd9Sstevel@tonic-gate modulus_len);
3017c478bd9Sstevel@tonic-gate
3027c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
3037c478bd9Sstevel@tonic-gate goto clean_exit;
3047c478bd9Sstevel@tonic-gate } else {
3057c478bd9Sstevel@tonic-gate /* Pad zeros for the leading bytes of the input data. */
3067c478bd9Sstevel@tonic-gate (void) memset(plain_data, 0x0, modulus_len - ulDataLen);
3077c478bd9Sstevel@tonic-gate (void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
3087c478bd9Sstevel@tonic-gate ulDataLen);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, plain_data, modulus_len, cipher_data, 1);
3127c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
3137c478bd9Sstevel@tonic-gate (void) memcpy(pEncrypted, cipher_data, modulus_len);
3147c478bd9Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate
3177c478bd9Sstevel@tonic-gate clean_exit:
3187c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
3197c478bd9Sstevel@tonic-gate free(session_p->encrypt.context);
3207c478bd9Sstevel@tonic-gate session_p->encrypt.context = NULL;
3217c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
3227c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
3237c478bd9Sstevel@tonic-gate free(key);
3247c478bd9Sstevel@tonic-gate clean1:
3257c478bd9Sstevel@tonic-gate return (rv);
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_decrypt_common(soft_session_t * session_p,CK_BYTE_PTR pEncrypted,CK_ULONG ulEncryptedLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen,CK_MECHANISM_TYPE mechanism)3307c478bd9Sstevel@tonic-gate soft_rsa_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
3317c478bd9Sstevel@tonic-gate CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
3327c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulDataLen, CK_MECHANISM_TYPE mechanism)
3337c478bd9Sstevel@tonic-gate {
3347c478bd9Sstevel@tonic-gate
3357c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->decrypt.context;
3367c478bd9Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
3377c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
3387c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
3397c478bd9Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
3407c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
3417c478bd9Sstevel@tonic-gate
342c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
3437c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
3447c478bd9Sstevel@tonic-gate goto clean_exit;
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate if (ulEncryptedLen != (CK_ULONG)modulus_len) {
3487c478bd9Sstevel@tonic-gate rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
3497c478bd9Sstevel@tonic-gate goto clean_exit;
3507c478bd9Sstevel@tonic-gate }
3517c478bd9Sstevel@tonic-gate
3527c478bd9Sstevel@tonic-gate if (pData == NULL) {
3537c478bd9Sstevel@tonic-gate /*
3547c478bd9Sstevel@tonic-gate * Application asks for the length of the output buffer
3557c478bd9Sstevel@tonic-gate * to hold the recovered data.
3567c478bd9Sstevel@tonic-gate */
3577c478bd9Sstevel@tonic-gate *pulDataLen = modulus_len;
3587c478bd9Sstevel@tonic-gate rv = CKR_OK;
3597c478bd9Sstevel@tonic-gate goto clean1;
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate if (mechanism == CKM_RSA_X_509) {
3637c478bd9Sstevel@tonic-gate if (*pulDataLen < (CK_ULONG)modulus_len) {
3647c478bd9Sstevel@tonic-gate *pulDataLen = modulus_len;
3657c478bd9Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
3667c478bd9Sstevel@tonic-gate goto clean1;
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate rv = soft_rsa_decrypt(key, pEncrypted, modulus_len, plain_data);
3717c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
3727c478bd9Sstevel@tonic-gate goto clean_exit;
3737c478bd9Sstevel@tonic-gate }
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate if (mechanism == CKM_RSA_PKCS) {
376*726fad2aSDina K Nimeh size_t plain_len = modulus_len;
377*726fad2aSDina K Nimeh size_t num_padding;
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate /* Strip off the PKCS block formatting data. */
380*726fad2aSDina K Nimeh rv = pkcs1_decode(PKCS1_DECRYPT, plain_data, &plain_len);
3817c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
3827c478bd9Sstevel@tonic-gate goto clean_exit;
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate num_padding = modulus_len - plain_len;
3857c478bd9Sstevel@tonic-gate if (ulEncryptedLen - num_padding > *pulDataLen) {
3867c478bd9Sstevel@tonic-gate *pulDataLen = plain_len;
3877c478bd9Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
3887c478bd9Sstevel@tonic-gate goto clean1;
3897c478bd9Sstevel@tonic-gate }
3907c478bd9Sstevel@tonic-gate
3917c478bd9Sstevel@tonic-gate (void) memcpy(pData, &plain_data[num_padding], plain_len);
3927c478bd9Sstevel@tonic-gate *pulDataLen = plain_len;
3937c478bd9Sstevel@tonic-gate } else {
3947c478bd9Sstevel@tonic-gate (void) memcpy(pData, plain_data, modulus_len);
3957c478bd9Sstevel@tonic-gate *pulDataLen = modulus_len;
3967c478bd9Sstevel@tonic-gate }
3977c478bd9Sstevel@tonic-gate
3987c478bd9Sstevel@tonic-gate clean_exit:
3997c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
4007c478bd9Sstevel@tonic-gate free(session_p->decrypt.context);
4017c478bd9Sstevel@tonic-gate session_p->decrypt.context = NULL;
4027c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
4037c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
4047c478bd9Sstevel@tonic-gate free(key);
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate clean1:
4077c478bd9Sstevel@tonic-gate return (rv);
4087c478bd9Sstevel@tonic-gate }
4097c478bd9Sstevel@tonic-gate
4107c478bd9Sstevel@tonic-gate /*
4117c478bd9Sstevel@tonic-gate * Allocate a RSA context for the active sign or verify operation.
4127c478bd9Sstevel@tonic-gate * This function is called without the session lock held.
4137c478bd9Sstevel@tonic-gate */
4147c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_sign_verify_init_common(soft_session_t * session_p,CK_MECHANISM_PTR pMechanism,soft_object_t * key_p,boolean_t sign)4157c478bd9Sstevel@tonic-gate soft_rsa_sign_verify_init_common(soft_session_t *session_p,
4167c478bd9Sstevel@tonic-gate CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
4177c478bd9Sstevel@tonic-gate boolean_t sign)
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
4207c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx;
4217c478bd9Sstevel@tonic-gate CK_MECHANISM digest_mech;
4227c478bd9Sstevel@tonic-gate soft_object_t *tmp_key = NULL;
4237c478bd9Sstevel@tonic-gate
4247c478bd9Sstevel@tonic-gate if (sign) {
4257c478bd9Sstevel@tonic-gate if ((key_p->class != CKO_PRIVATE_KEY) ||
4267c478bd9Sstevel@tonic-gate (key_p->key_type != CKK_RSA))
4277c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
4287c478bd9Sstevel@tonic-gate } else {
4297c478bd9Sstevel@tonic-gate if ((key_p->class != CKO_PUBLIC_KEY) ||
4307c478bd9Sstevel@tonic-gate (key_p->key_type != CKK_RSA))
4317c478bd9Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate
4347c478bd9Sstevel@tonic-gate switch (pMechanism->mechanism) {
4357c478bd9Sstevel@tonic-gate case CKM_MD5_RSA_PKCS:
4367c478bd9Sstevel@tonic-gate digest_mech.mechanism = CKM_MD5;
4377c478bd9Sstevel@tonic-gate rv = soft_digest_init_internal(session_p, &digest_mech);
4387c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
4397c478bd9Sstevel@tonic-gate return (rv);
4407c478bd9Sstevel@tonic-gate break;
4417c478bd9Sstevel@tonic-gate
4427c478bd9Sstevel@tonic-gate case CKM_SHA1_RSA_PKCS:
4437c478bd9Sstevel@tonic-gate digest_mech.mechanism = CKM_SHA_1;
44460722cc8Sizick digest_mech.pParameter = pMechanism->pParameter;
44560722cc8Sizick digest_mech.ulParameterLen = pMechanism->ulParameterLen;
4467c478bd9Sstevel@tonic-gate rv = soft_digest_init_internal(session_p, &digest_mech);
4477c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
4487c478bd9Sstevel@tonic-gate return (rv);
4497c478bd9Sstevel@tonic-gate break;
450f66d273dSizick
451f66d273dSizick case CKM_SHA256_RSA_PKCS:
452f66d273dSizick digest_mech.mechanism = CKM_SHA256;
453f66d273dSizick rv = soft_digest_init_internal(session_p, &digest_mech);
454f66d273dSizick if (rv != CKR_OK)
455f66d273dSizick return (rv);
456f66d273dSizick break;
457f66d273dSizick
458f66d273dSizick case CKM_SHA384_RSA_PKCS:
459f66d273dSizick digest_mech.mechanism = CKM_SHA384;
460f66d273dSizick rv = soft_digest_init_internal(session_p, &digest_mech);
461f66d273dSizick if (rv != CKR_OK)
462f66d273dSizick return (rv);
463f66d273dSizick break;
464f66d273dSizick
465f66d273dSizick case CKM_SHA512_RSA_PKCS:
466f66d273dSizick digest_mech.mechanism = CKM_SHA512;
467f66d273dSizick rv = soft_digest_init_internal(session_p, &digest_mech);
468f66d273dSizick if (rv != CKR_OK)
469f66d273dSizick return (rv);
470f66d273dSizick break;
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate rsa_ctx = malloc(sizeof (soft_rsa_ctx_t));
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate if (rsa_ctx == NULL) {
4767c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
4777c478bd9Sstevel@tonic-gate goto clean_exit;
4787c478bd9Sstevel@tonic-gate }
4797c478bd9Sstevel@tonic-gate
4807c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&key_p->object_mutex);
4817c478bd9Sstevel@tonic-gate rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
4827c478bd9Sstevel@tonic-gate NULL);
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate if ((rv != CKR_OK) || (tmp_key == NULL)) {
4857c478bd9Sstevel@tonic-gate /* Most likely we ran out of space. */
4867c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
4877c478bd9Sstevel@tonic-gate free(rsa_ctx);
4887c478bd9Sstevel@tonic-gate goto clean_exit;
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate /* No need to hold the lock on the old object. */
4927c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
4937c478bd9Sstevel@tonic-gate rsa_ctx->key = tmp_key;
4947c478bd9Sstevel@tonic-gate
4957c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate if (sign) {
4987c478bd9Sstevel@tonic-gate session_p->sign.context = rsa_ctx;
4997c478bd9Sstevel@tonic-gate session_p->sign.mech.mechanism = pMechanism->mechanism;
5007c478bd9Sstevel@tonic-gate } else {
5017c478bd9Sstevel@tonic-gate session_p->verify.context = rsa_ctx;
5027c478bd9Sstevel@tonic-gate session_p->verify.mech.mechanism = pMechanism->mechanism;
5037c478bd9Sstevel@tonic-gate }
5047c478bd9Sstevel@tonic-gate
5057c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate return (CKR_OK);
5087c478bd9Sstevel@tonic-gate
5097c478bd9Sstevel@tonic-gate clean_exit:
5107c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
5117c478bd9Sstevel@tonic-gate if (session_p->digest.context != NULL) {
5127c478bd9Sstevel@tonic-gate free(session_p->digest.context);
5137c478bd9Sstevel@tonic-gate session_p->digest.context = NULL;
5147c478bd9Sstevel@tonic-gate session_p->digest.flags = 0;
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
5177c478bd9Sstevel@tonic-gate return (rv);
5187c478bd9Sstevel@tonic-gate
5197c478bd9Sstevel@tonic-gate }
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate
5227c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_sign_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSigned,CK_ULONG_PTR pulSignedLen,CK_MECHANISM_TYPE mechanism)5237c478bd9Sstevel@tonic-gate soft_rsa_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
5247c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
5257c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism)
5267c478bd9Sstevel@tonic-gate {
5277c478bd9Sstevel@tonic-gate
5287c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
5297c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
5307c478bd9Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
5317c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
5327c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
5337c478bd9Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
5347c478bd9Sstevel@tonic-gate CK_BYTE signed_data[MAX_RSA_KEYLENGTH_IN_BYTES];
5357c478bd9Sstevel@tonic-gate
536c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
5377c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
5387c478bd9Sstevel@tonic-gate goto clean_exit;
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate if (pSigned == NULL) {
5427c478bd9Sstevel@tonic-gate /* Application asks for the length of the output buffer. */
5437c478bd9Sstevel@tonic-gate *pulSignedLen = modulus_len;
5447c478bd9Sstevel@tonic-gate rv = CKR_OK;
5457c478bd9Sstevel@tonic-gate goto clean1;
5467c478bd9Sstevel@tonic-gate }
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate switch (mechanism) {
5497c478bd9Sstevel@tonic-gate
5507c478bd9Sstevel@tonic-gate case CKM_RSA_PKCS:
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate /*
5537c478bd9Sstevel@tonic-gate * Input data length needs to be <=
5547c478bd9Sstevel@tonic-gate * modulus length-MIN_PKCS1_PADLEN.
5557c478bd9Sstevel@tonic-gate */
5567c478bd9Sstevel@tonic-gate if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
5577c478bd9Sstevel@tonic-gate *pulSignedLen = modulus_len;
5587c478bd9Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
5597c478bd9Sstevel@tonic-gate goto clean_exit;
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate break;
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate case CKM_RSA_X_509:
5647c478bd9Sstevel@tonic-gate
5657c478bd9Sstevel@tonic-gate /* Input data length needs to be <= modulus length. */
5667c478bd9Sstevel@tonic-gate if (ulDataLen > (CK_ULONG)modulus_len) {
5677c478bd9Sstevel@tonic-gate *pulSignedLen = modulus_len;
5687c478bd9Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
5697c478bd9Sstevel@tonic-gate goto clean_exit;
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate break;
5727c478bd9Sstevel@tonic-gate }
5737c478bd9Sstevel@tonic-gate
5747c478bd9Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
5757c478bd9Sstevel@tonic-gate if (*pulSignedLen < (CK_ULONG)modulus_len) {
5767c478bd9Sstevel@tonic-gate *pulSignedLen = modulus_len;
5777c478bd9Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
5787c478bd9Sstevel@tonic-gate goto clean1;
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate switch (mechanism) {
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate case CKM_RSA_PKCS:
5847c478bd9Sstevel@tonic-gate case CKM_MD5_RSA_PKCS:
5857c478bd9Sstevel@tonic-gate case CKM_SHA1_RSA_PKCS:
586f66d273dSizick case CKM_SHA256_RSA_PKCS:
587f66d273dSizick case CKM_SHA384_RSA_PKCS:
588f66d273dSizick case CKM_SHA512_RSA_PKCS:
5897c478bd9Sstevel@tonic-gate /*
5907c478bd9Sstevel@tonic-gate * Add PKCS padding to the input data to format a block
5917c478bd9Sstevel@tonic-gate * type "01" encryption block.
5927c478bd9Sstevel@tonic-gate */
593*726fad2aSDina K Nimeh rv = pkcs1_encode(PKCS1_SIGN, pData, ulDataLen, plain_data,
5947c478bd9Sstevel@tonic-gate modulus_len);
5957c478bd9Sstevel@tonic-gate
5967c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
5977c478bd9Sstevel@tonic-gate goto clean_exit;
5987c478bd9Sstevel@tonic-gate }
5997c478bd9Sstevel@tonic-gate break;
6007c478bd9Sstevel@tonic-gate
6017c478bd9Sstevel@tonic-gate case CKM_RSA_X_509:
6027c478bd9Sstevel@tonic-gate
6037c478bd9Sstevel@tonic-gate /* Pad zeros for the leading bytes of the input data. */
6047c478bd9Sstevel@tonic-gate (void) memset(plain_data, 0x0, modulus_len - ulDataLen);
6057c478bd9Sstevel@tonic-gate (void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
6067c478bd9Sstevel@tonic-gate ulDataLen);
6077c478bd9Sstevel@tonic-gate break;
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate
6107c478bd9Sstevel@tonic-gate /*
6117c478bd9Sstevel@tonic-gate * Perform RSA encryption with the signer's RSA private key
6127c478bd9Sstevel@tonic-gate * for signature process.
6137c478bd9Sstevel@tonic-gate */
6147c478bd9Sstevel@tonic-gate rv = soft_rsa_decrypt(key, plain_data, modulus_len, signed_data);
6157c478bd9Sstevel@tonic-gate
6167c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
6177c478bd9Sstevel@tonic-gate (void) memcpy(pSigned, signed_data, modulus_len);
6187c478bd9Sstevel@tonic-gate *pulSignedLen = modulus_len;
6197c478bd9Sstevel@tonic-gate }
6207c478bd9Sstevel@tonic-gate
6217c478bd9Sstevel@tonic-gate clean_exit:
6227c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
6237c478bd9Sstevel@tonic-gate free(session_p->sign.context);
6247c478bd9Sstevel@tonic-gate session_p->sign.context = NULL;
6257c478bd9Sstevel@tonic-gate if (session_p->digest.context != NULL) {
6267c478bd9Sstevel@tonic-gate free(session_p->digest.context);
6277c478bd9Sstevel@tonic-gate session_p->digest.context = NULL;
6287c478bd9Sstevel@tonic-gate session_p->digest.flags = 0;
6297c478bd9Sstevel@tonic-gate }
6307c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
6317c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
6327c478bd9Sstevel@tonic-gate free(key);
6337c478bd9Sstevel@tonic-gate
6347c478bd9Sstevel@tonic-gate clean1:
6357c478bd9Sstevel@tonic-gate return (rv);
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate
6387c478bd9Sstevel@tonic-gate
6397c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_verify_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,CK_MECHANISM_TYPE mechanism)6407c478bd9Sstevel@tonic-gate soft_rsa_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
6417c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
6427c478bd9Sstevel@tonic-gate CK_ULONG ulSignatureLen, CK_MECHANISM_TYPE mechanism)
6437c478bd9Sstevel@tonic-gate {
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
6467c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
6477c478bd9Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
6487c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
6497c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
6507c478bd9Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
6517c478bd9Sstevel@tonic-gate
652c64d15a5Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
6537c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
6547c478bd9Sstevel@tonic-gate goto clean_exit;
6557c478bd9Sstevel@tonic-gate }
6567c478bd9Sstevel@tonic-gate
657*726fad2aSDina K Nimeh if (ulDataLen == 0) {
658*726fad2aSDina K Nimeh rv = CKR_DATA_LEN_RANGE;
659*726fad2aSDina K Nimeh goto clean_exit;
660*726fad2aSDina K Nimeh }
661*726fad2aSDina K Nimeh
6627c478bd9Sstevel@tonic-gate if (ulSignatureLen != (CK_ULONG)modulus_len) {
6637c478bd9Sstevel@tonic-gate rv = CKR_SIGNATURE_LEN_RANGE;
6647c478bd9Sstevel@tonic-gate goto clean_exit;
6657c478bd9Sstevel@tonic-gate }
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate /*
6687c478bd9Sstevel@tonic-gate * Perform RSA decryption with the signer's RSA public key
6697c478bd9Sstevel@tonic-gate * for verification process.
6707c478bd9Sstevel@tonic-gate */
6717c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
6727c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
6737c478bd9Sstevel@tonic-gate switch (mechanism) {
6747c478bd9Sstevel@tonic-gate
6757c478bd9Sstevel@tonic-gate case CKM_RSA_PKCS:
6767c478bd9Sstevel@tonic-gate case CKM_MD5_RSA_PKCS:
6777c478bd9Sstevel@tonic-gate case CKM_SHA1_RSA_PKCS:
678f66d273dSizick case CKM_SHA256_RSA_PKCS:
679f66d273dSizick case CKM_SHA384_RSA_PKCS:
680f66d273dSizick case CKM_SHA512_RSA_PKCS:
6817c478bd9Sstevel@tonic-gate {
6827c478bd9Sstevel@tonic-gate /*
6837c478bd9Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the
6847c478bd9Sstevel@tonic-gate * recovered data, then compare the recovered data with
6857c478bd9Sstevel@tonic-gate * the original data.
6867c478bd9Sstevel@tonic-gate */
687*726fad2aSDina K Nimeh size_t data_len = modulus_len;
6887c478bd9Sstevel@tonic-gate
689*726fad2aSDina K Nimeh rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
6907c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
6917c478bd9Sstevel@tonic-gate goto clean_exit;
6927c478bd9Sstevel@tonic-gate }
6937c478bd9Sstevel@tonic-gate
6947c478bd9Sstevel@tonic-gate if ((CK_ULONG)data_len != ulDataLen) {
695*726fad2aSDina K Nimeh rv = CKR_DATA_LEN_RANGE;
6967c478bd9Sstevel@tonic-gate goto clean_exit;
6977c478bd9Sstevel@tonic-gate } else if (memcmp(pData,
6987c478bd9Sstevel@tonic-gate &plain_data[modulus_len - data_len],
6997c478bd9Sstevel@tonic-gate ulDataLen) != 0) {
7007c478bd9Sstevel@tonic-gate rv = CKR_SIGNATURE_INVALID;
7017c478bd9Sstevel@tonic-gate goto clean_exit;
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate break;
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate
7067c478bd9Sstevel@tonic-gate case CKM_RSA_X_509:
7077c478bd9Sstevel@tonic-gate /*
7087c478bd9Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the
7097c478bd9Sstevel@tonic-gate * recovered plain_data, then compare the input data
7107c478bd9Sstevel@tonic-gate * with the recovered data.
7117c478bd9Sstevel@tonic-gate */
7127c478bd9Sstevel@tonic-gate if (memcmp(pData,
7137c478bd9Sstevel@tonic-gate plain_data + ulSignatureLen - ulDataLen,
7147c478bd9Sstevel@tonic-gate ulDataLen) != 0) {
7157c478bd9Sstevel@tonic-gate rv = CKR_SIGNATURE_INVALID;
7167c478bd9Sstevel@tonic-gate goto clean_exit;
7177c478bd9Sstevel@tonic-gate }
7187c478bd9Sstevel@tonic-gate break;
7197c478bd9Sstevel@tonic-gate }
7207c478bd9Sstevel@tonic-gate }
7217c478bd9Sstevel@tonic-gate
7227c478bd9Sstevel@tonic-gate if (rv == CKR_DATA_LEN_RANGE) {
7237c478bd9Sstevel@tonic-gate if ((mechanism == CKM_MD5_RSA_PKCS) ||
724f66d273dSizick (mechanism == CKM_SHA1_RSA_PKCS) ||
725f66d273dSizick (mechanism == CKM_SHA256_RSA_PKCS) ||
726f66d273dSizick (mechanism == CKM_SHA384_RSA_PKCS) ||
727f66d273dSizick (mechanism == CKM_SHA512_RSA_PKCS))
7287c478bd9Sstevel@tonic-gate rv = CKR_SIGNATURE_INVALID;
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate clean_exit:
7327c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
7337c478bd9Sstevel@tonic-gate free(session_p->verify.context);
7347c478bd9Sstevel@tonic-gate session_p->verify.context = NULL;
7357c478bd9Sstevel@tonic-gate if (session_p->digest.context != NULL) {
7367c478bd9Sstevel@tonic-gate free(session_p->digest.context);
7377c478bd9Sstevel@tonic-gate session_p->digest.context = NULL;
7387c478bd9Sstevel@tonic-gate session_p->digest.flags = 0;
7397c478bd9Sstevel@tonic-gate }
7407c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
7417c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
7427c478bd9Sstevel@tonic-gate free(key);
7437c478bd9Sstevel@tonic-gate return (rv);
7447c478bd9Sstevel@tonic-gate }
7457c478bd9Sstevel@tonic-gate
7467c478bd9Sstevel@tonic-gate CK_RV
soft_genRSAkey_set_attribute(soft_object_t * key,CK_ATTRIBUTE_TYPE type,uchar_t * buf,uint32_t buflen,boolean_t public)747*726fad2aSDina K Nimeh soft_genRSAkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
748*726fad2aSDina K Nimeh uchar_t *buf, uint32_t buflen, boolean_t public)
7497c478bd9Sstevel@tonic-gate {
7507c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
7517c478bd9Sstevel@tonic-gate biginteger_t *dst = NULL;
7527c478bd9Sstevel@tonic-gate biginteger_t src;
7537c478bd9Sstevel@tonic-gate
7547c478bd9Sstevel@tonic-gate switch (type) {
7557c478bd9Sstevel@tonic-gate
7567c478bd9Sstevel@tonic-gate case CKA_MODULUS:
7577c478bd9Sstevel@tonic-gate
7587c478bd9Sstevel@tonic-gate if (public)
7597c478bd9Sstevel@tonic-gate dst = OBJ_PUB_RSA_MOD(key);
7607c478bd9Sstevel@tonic-gate else
7617c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_MOD(key);
7627c478bd9Sstevel@tonic-gate break;
7637c478bd9Sstevel@tonic-gate
7647c478bd9Sstevel@tonic-gate case CKA_PUBLIC_EXPONENT:
7657c478bd9Sstevel@tonic-gate
7667c478bd9Sstevel@tonic-gate if (public)
7677c478bd9Sstevel@tonic-gate dst = OBJ_PUB_RSA_PUBEXPO(key);
7687c478bd9Sstevel@tonic-gate else
7697c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_PUBEXPO(key);
7707c478bd9Sstevel@tonic-gate break;
7717c478bd9Sstevel@tonic-gate
7727c478bd9Sstevel@tonic-gate case CKA_PRIVATE_EXPONENT:
7737c478bd9Sstevel@tonic-gate
7747c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_PRIEXPO(key);
7757c478bd9Sstevel@tonic-gate break;
7767c478bd9Sstevel@tonic-gate
7777c478bd9Sstevel@tonic-gate case CKA_PRIME_1:
7787c478bd9Sstevel@tonic-gate
7797c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_PRIME1(key);
7807c478bd9Sstevel@tonic-gate break;
7817c478bd9Sstevel@tonic-gate
7827c478bd9Sstevel@tonic-gate case CKA_PRIME_2:
7837c478bd9Sstevel@tonic-gate
7847c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_PRIME2(key);
7857c478bd9Sstevel@tonic-gate break;
7867c478bd9Sstevel@tonic-gate
7877c478bd9Sstevel@tonic-gate case CKA_EXPONENT_1:
7887c478bd9Sstevel@tonic-gate
7897c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_EXPO1(key);
7907c478bd9Sstevel@tonic-gate break;
7917c478bd9Sstevel@tonic-gate
7927c478bd9Sstevel@tonic-gate case CKA_EXPONENT_2:
7937c478bd9Sstevel@tonic-gate
7947c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_EXPO2(key);
7957c478bd9Sstevel@tonic-gate break;
7967c478bd9Sstevel@tonic-gate
7977c478bd9Sstevel@tonic-gate case CKA_COEFFICIENT:
7987c478bd9Sstevel@tonic-gate
7997c478bd9Sstevel@tonic-gate dst = OBJ_PRI_RSA_COEF(key);
8007c478bd9Sstevel@tonic-gate break;
8017c478bd9Sstevel@tonic-gate }
8027c478bd9Sstevel@tonic-gate
803*726fad2aSDina K Nimeh /* Note: no explanation found for why this is needed */
8047c478bd9Sstevel@tonic-gate while (buf[0] == 0) { /* remove proceeding 0x00 */
8057c478bd9Sstevel@tonic-gate buf++;
8067c478bd9Sstevel@tonic-gate buflen--;
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate
809*726fad2aSDina K Nimeh if ((rv = dup_bigint_attr(&src, buf, buflen)) != CKR_OK)
8107c478bd9Sstevel@tonic-gate goto cleanexit;
8117c478bd9Sstevel@tonic-gate
8127c478bd9Sstevel@tonic-gate /* Copy the attribute in the key object. */
8137c478bd9Sstevel@tonic-gate copy_bigint_attr(&src, dst);
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate cleanexit:
8167c478bd9Sstevel@tonic-gate return (rv);
8177c478bd9Sstevel@tonic-gate
8187c478bd9Sstevel@tonic-gate }
8197c478bd9Sstevel@tonic-gate
8207c478bd9Sstevel@tonic-gate
8217c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_genkey_pair(soft_object_t * pubkey,soft_object_t * prikey)8227c478bd9Sstevel@tonic-gate soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
8237c478bd9Sstevel@tonic-gate {
8247c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
825*726fad2aSDina K Nimeh CK_ATTRIBUTE template;
826*726fad2aSDina K Nimeh uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
8277c478bd9Sstevel@tonic-gate uint32_t modulus_len;
8287c478bd9Sstevel@tonic-gate uchar_t pub_expo[MAX_KEY_ATTR_BUFLEN];
8297c478bd9Sstevel@tonic-gate uint32_t pub_expo_len = sizeof (pub_expo);
830*726fad2aSDina K Nimeh uchar_t private_exponent[MAX_KEY_ATTR_BUFLEN];
831*726fad2aSDina K Nimeh uint32_t private_exponent_len = sizeof (private_exponent);
832*726fad2aSDina K Nimeh uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
833*726fad2aSDina K Nimeh uint32_t prime1_len = sizeof (prime1);
834*726fad2aSDina K Nimeh uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
835*726fad2aSDina K Nimeh uint32_t prime2_len = sizeof (prime2);
836*726fad2aSDina K Nimeh uchar_t exponent1[MAX_KEY_ATTR_BUFLEN];
837*726fad2aSDina K Nimeh uint32_t exponent1_len = sizeof (exponent1);
838*726fad2aSDina K Nimeh uchar_t exponent2[MAX_KEY_ATTR_BUFLEN];
839*726fad2aSDina K Nimeh uint32_t exponent2_len = sizeof (exponent2);
840*726fad2aSDina K Nimeh uchar_t coefficient[MAX_KEY_ATTR_BUFLEN];
841*726fad2aSDina K Nimeh uint32_t coefficient_len = sizeof (coefficient);
842*726fad2aSDina K Nimeh RSAbytekey k;
8437c478bd9Sstevel@tonic-gate
8447c478bd9Sstevel@tonic-gate if ((pubkey == NULL) || (prikey == NULL)) {
8457c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate
8487c478bd9Sstevel@tonic-gate template.pValue = malloc(sizeof (CK_ULONG));
8497c478bd9Sstevel@tonic-gate if (template.pValue == NULL) {
8507c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY);
8517c478bd9Sstevel@tonic-gate }
8527c478bd9Sstevel@tonic-gate template.ulValueLen = sizeof (CK_ULONG);
8537c478bd9Sstevel@tonic-gate
8547c478bd9Sstevel@tonic-gate rv = get_ulong_attr_from_object(OBJ_PUB_RSA_MOD_BITS(pubkey),
8557c478bd9Sstevel@tonic-gate &template);
8567c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
857*726fad2aSDina K Nimeh free(template.pValue);
8587c478bd9Sstevel@tonic-gate goto clean0;
8597c478bd9Sstevel@tonic-gate }
8607c478bd9Sstevel@tonic-gate
8617c478bd9Sstevel@tonic-gate #ifdef __sparcv9
8627c478bd9Sstevel@tonic-gate /* LINTED */
8637c478bd9Sstevel@tonic-gate modulus_len = (uint32_t)(*((CK_ULONG *)(template.pValue)));
8647c478bd9Sstevel@tonic-gate #else /* !__sparcv9 */
8657c478bd9Sstevel@tonic-gate modulus_len = *((CK_ULONG *)(template.pValue));
8667c478bd9Sstevel@tonic-gate #endif /* __sparcv9 */
8677c478bd9Sstevel@tonic-gate
868*726fad2aSDina K Nimeh free(template.pValue);
8697c478bd9Sstevel@tonic-gate
870c64d15a5Smcpowers rv = soft_get_public_value(pubkey, CKA_PUBLIC_EXPONENT, pub_expo,
8717c478bd9Sstevel@tonic-gate &pub_expo_len);
8727c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
8737c478bd9Sstevel@tonic-gate goto clean0;
8747c478bd9Sstevel@tonic-gate }
8757c478bd9Sstevel@tonic-gate
876*726fad2aSDina K Nimeh /* Inputs to RSA key pair generation */
877*726fad2aSDina K Nimeh k.modulus_bits = modulus_len; /* save modulus len in bits */
878*726fad2aSDina K Nimeh modulus_len = CRYPTO_BITS2BYTES(modulus_len); /* convert to bytes */
879*726fad2aSDina K Nimeh k.modulus = modulus;
880*726fad2aSDina K Nimeh k.pubexpo = pub_expo;
881*726fad2aSDina K Nimeh k.pubexpo_bytes = pub_expo_len;
882*726fad2aSDina K Nimeh k.rfunc = (IS_TOKEN_OBJECT(pubkey) || IS_TOKEN_OBJECT(prikey)) ?
883*726fad2aSDina K Nimeh pkcs11_get_random : pkcs11_get_urandom;
884*726fad2aSDina K Nimeh
885*726fad2aSDina K Nimeh /* Outputs from RSA key pair generation */
886*726fad2aSDina K Nimeh k.privexpo = private_exponent;
887*726fad2aSDina K Nimeh k.privexpo_bytes = private_exponent_len;
888*726fad2aSDina K Nimeh k.prime1 = prime1;
889*726fad2aSDina K Nimeh k.prime1_bytes = prime1_len;
890*726fad2aSDina K Nimeh k.prime2 = prime2;
891*726fad2aSDina K Nimeh k.prime2_bytes = prime2_len;
892*726fad2aSDina K Nimeh k.expo1 = exponent1;
893*726fad2aSDina K Nimeh k.expo1_bytes = exponent1_len;
894*726fad2aSDina K Nimeh k.expo2 = exponent2;
895*726fad2aSDina K Nimeh k.expo2_bytes = exponent2_len;
896*726fad2aSDina K Nimeh k.coeff = coefficient;
897*726fad2aSDina K Nimeh k.coeff_bytes = coefficient_len;
898*726fad2aSDina K Nimeh
899*726fad2aSDina K Nimeh rv = rsa_genkey_pair(&k);
900*726fad2aSDina K Nimeh
901*726fad2aSDina K Nimeh if (rv != CKR_OK) {
9027c478bd9Sstevel@tonic-gate goto clean0;
9037c478bd9Sstevel@tonic-gate }
9047c478bd9Sstevel@tonic-gate
9057c478bd9Sstevel@tonic-gate /*
9067c478bd9Sstevel@tonic-gate * Add modulus in public template, and add all eight key fields
9077c478bd9Sstevel@tonic-gate * in private template.
9087c478bd9Sstevel@tonic-gate */
909*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(pubkey, CKA_MODULUS,
910*726fad2aSDina K Nimeh modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_TRUE)) != CKR_OK) {
911*726fad2aSDina K Nimeh goto clean0;
9127c478bd9Sstevel@tonic-gate }
9137c478bd9Sstevel@tonic-gate
914*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_MODULUS,
915*726fad2aSDina K Nimeh modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_FALSE)) != CKR_OK) {
916*726fad2aSDina K Nimeh goto clean0;
9177c478bd9Sstevel@tonic-gate }
9187c478bd9Sstevel@tonic-gate
919*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIVATE_EXPONENT,
920*726fad2aSDina K Nimeh private_exponent, k.privexpo_bytes, B_FALSE)) != CKR_OK) {
921*726fad2aSDina K Nimeh goto clean0;
9227c478bd9Sstevel@tonic-gate }
9237c478bd9Sstevel@tonic-gate
924*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PUBLIC_EXPONENT,
925*726fad2aSDina K Nimeh pub_expo, k.pubexpo_bytes, B_FALSE)) != CKR_OK) {
926*726fad2aSDina K Nimeh goto clean0;
9277c478bd9Sstevel@tonic-gate }
9287c478bd9Sstevel@tonic-gate
929*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_1,
930*726fad2aSDina K Nimeh prime1, k.prime1_bytes, B_FALSE)) != CKR_OK) {
931*726fad2aSDina K Nimeh goto clean0;
9327c478bd9Sstevel@tonic-gate }
9337c478bd9Sstevel@tonic-gate
934*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_2,
935*726fad2aSDina K Nimeh prime2, k.prime2_bytes, B_FALSE)) != CKR_OK) {
936*726fad2aSDina K Nimeh goto clean0;
9377c478bd9Sstevel@tonic-gate }
9387c478bd9Sstevel@tonic-gate
939*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_1,
940*726fad2aSDina K Nimeh exponent1, k.expo1_bytes, B_FALSE)) != CKR_OK) {
941*726fad2aSDina K Nimeh goto clean0;
9427c478bd9Sstevel@tonic-gate }
9437c478bd9Sstevel@tonic-gate
944*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_2,
945*726fad2aSDina K Nimeh exponent2, k.expo2_bytes, B_FALSE)) != CKR_OK) {
946*726fad2aSDina K Nimeh goto clean0;
9477c478bd9Sstevel@tonic-gate }
9487c478bd9Sstevel@tonic-gate
949*726fad2aSDina K Nimeh if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_COEFFICIENT,
950*726fad2aSDina K Nimeh coefficient, k.coeff_bytes, B_FALSE)) != CKR_OK) {
951*726fad2aSDina K Nimeh goto clean0;
9527c478bd9Sstevel@tonic-gate }
9537c478bd9Sstevel@tonic-gate
9547c478bd9Sstevel@tonic-gate clean0:
9557c478bd9Sstevel@tonic-gate return (rv);
9567c478bd9Sstevel@tonic-gate }
9577c478bd9Sstevel@tonic-gate
95860722cc8Sizick
95960722cc8Sizick CK_ULONG
get_rsa_sha1_prefix(CK_MECHANISM_PTR mech,CK_BYTE_PTR * prefix)96060722cc8Sizick get_rsa_sha1_prefix(CK_MECHANISM_PTR mech, CK_BYTE_PTR *prefix) {
96160722cc8Sizick if (mech->pParameter == NULL) {
96260722cc8Sizick *prefix = (CK_BYTE *)SHA1_DER_PREFIX;
96360722cc8Sizick return (SHA1_DER_PREFIX_Len);
96460722cc8Sizick }
96560722cc8Sizick
96660722cc8Sizick *prefix = (CK_BYTE *)SHA1_DER_PREFIX_OID;
96760722cc8Sizick return (SHA1_DER_PREFIX_OID_Len);
96860722cc8Sizick }
96960722cc8Sizick
9707c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_digest_sign_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSigned,CK_ULONG_PTR pulSignedLen,CK_MECHANISM_TYPE mechanism,boolean_t Final)9717c478bd9Sstevel@tonic-gate soft_rsa_digest_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
9727c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
9737c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
9747c478bd9Sstevel@tonic-gate {
9757c478bd9Sstevel@tonic-gate
9767c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
977f66d273dSizick CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
978f66d273dSizick CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
979f66d273dSizick /* space enough for all mechs */
980f66d273dSizick CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
9817c478bd9Sstevel@tonic-gate CK_ULONG der_data_len;
9827c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
9837c478bd9Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
9847c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
9857c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
98660722cc8Sizick CK_ULONG der_len;
98760722cc8Sizick CK_BYTE_PTR der_prefix;
9887c478bd9Sstevel@tonic-gate
989c64d15a5Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
9907c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
9917c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
9927c478bd9Sstevel@tonic-gate free(session_p->digest.context);
9937c478bd9Sstevel@tonic-gate session_p->digest.context = NULL;
9947c478bd9Sstevel@tonic-gate session_p->digest.flags = 0;
9957c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
9967c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
9977c478bd9Sstevel@tonic-gate free(key);
9987c478bd9Sstevel@tonic-gate goto clean1;
9997c478bd9Sstevel@tonic-gate }
10007c478bd9Sstevel@tonic-gate
10017c478bd9Sstevel@tonic-gate /* Check arguments before performing message digest. */
10027c478bd9Sstevel@tonic-gate if (pSigned == NULL) {
10037c478bd9Sstevel@tonic-gate /* Application asks for the length of the output buffer. */
10047c478bd9Sstevel@tonic-gate *pulSignedLen = modulus_len;
10057c478bd9Sstevel@tonic-gate rv = CKR_OK;
10067c478bd9Sstevel@tonic-gate goto clean1;
10077c478bd9Sstevel@tonic-gate }
10087c478bd9Sstevel@tonic-gate
10097c478bd9Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
10107c478bd9Sstevel@tonic-gate if (*pulSignedLen < (CK_ULONG)modulus_len) {
10117c478bd9Sstevel@tonic-gate *pulSignedLen = modulus_len;
10127c478bd9Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
10137c478bd9Sstevel@tonic-gate goto clean1;
10147c478bd9Sstevel@tonic-gate }
10157c478bd9Sstevel@tonic-gate
10167c478bd9Sstevel@tonic-gate if (Final) {
10177c478bd9Sstevel@tonic-gate rv = soft_digest_final(session_p, hash, &hash_len);
10187c478bd9Sstevel@tonic-gate } else {
10197c478bd9Sstevel@tonic-gate rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
10207c478bd9Sstevel@tonic-gate }
10217c478bd9Sstevel@tonic-gate
10227c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
10237c478bd9Sstevel@tonic-gate /* free the signature key */
10247c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
10257c478bd9Sstevel@tonic-gate free(key);
10267c478bd9Sstevel@tonic-gate goto clean_exit;
10277c478bd9Sstevel@tonic-gate }
10287c478bd9Sstevel@tonic-gate
10297c478bd9Sstevel@tonic-gate /*
103060722cc8Sizick * Prepare the DER encoding of the DigestInfo value by setting it to:
103160722cc8Sizick * <MECH>_DER_PREFIX || H
10327c478bd9Sstevel@tonic-gate *
10337c478bd9Sstevel@tonic-gate * See rsa_impl.c for more details.
10347c478bd9Sstevel@tonic-gate */
1035f66d273dSizick switch (session_p->digest.mech.mechanism) {
1036f66d273dSizick case CKM_MD5:
10377c478bd9Sstevel@tonic-gate (void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
10387c478bd9Sstevel@tonic-gate (void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
10397c478bd9Sstevel@tonic-gate der_data_len = MD5_DER_PREFIX_Len + hash_len;
1040f66d273dSizick break;
1041f66d273dSizick case CKM_SHA_1:
104260722cc8Sizick der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
104360722cc8Sizick &der_prefix);
104460722cc8Sizick (void) memcpy(der_data, der_prefix, der_len);
104560722cc8Sizick (void) memcpy(der_data + der_len, hash, hash_len);
104660722cc8Sizick der_data_len = der_len + hash_len;
1047f66d273dSizick break;
1048f66d273dSizick case CKM_SHA256:
1049f66d273dSizick (void) memcpy(der_data, SHA256_DER_PREFIX,
1050f66d273dSizick SHA2_DER_PREFIX_Len);
1051f66d273dSizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1052f66d273dSizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1053f66d273dSizick break;
1054f66d273dSizick case CKM_SHA384:
1055f66d273dSizick (void) memcpy(der_data, SHA384_DER_PREFIX,
1056f66d273dSizick SHA2_DER_PREFIX_Len);
1057f66d273dSizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1058f66d273dSizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1059f66d273dSizick break;
1060f66d273dSizick case CKM_SHA512:
1061f66d273dSizick (void) memcpy(der_data, SHA512_DER_PREFIX,
1062f66d273dSizick SHA2_DER_PREFIX_Len);
1063f66d273dSizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1064f66d273dSizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1065f66d273dSizick break;
10667c478bd9Sstevel@tonic-gate }
10677c478bd9Sstevel@tonic-gate
10687c478bd9Sstevel@tonic-gate /*
10697c478bd9Sstevel@tonic-gate * Now, we are ready to sign the DER_ENCODED data
10707c478bd9Sstevel@tonic-gate * soft_rsa_sign_common() will free the signature key.
10717c478bd9Sstevel@tonic-gate */
10727c478bd9Sstevel@tonic-gate rv = soft_rsa_sign_common(session_p, der_data, der_data_len,
10737c478bd9Sstevel@tonic-gate pSigned, pulSignedLen, mechanism);
10747c478bd9Sstevel@tonic-gate
10757c478bd9Sstevel@tonic-gate clean_exit:
10767c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
10777c478bd9Sstevel@tonic-gate /* soft_digest_common() has freed the digest context */
10787c478bd9Sstevel@tonic-gate session_p->digest.flags = 0;
10797c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
10807c478bd9Sstevel@tonic-gate
10817c478bd9Sstevel@tonic-gate clean1:
10827c478bd9Sstevel@tonic-gate return (rv);
10837c478bd9Sstevel@tonic-gate }
10847c478bd9Sstevel@tonic-gate
10857c478bd9Sstevel@tonic-gate
10867c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_digest_verify_common(soft_session_t * session_p,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSigned,CK_ULONG ulSignedLen,CK_MECHANISM_TYPE mechanism,boolean_t Final)10877c478bd9Sstevel@tonic-gate soft_rsa_digest_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
10887c478bd9Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
10897c478bd9Sstevel@tonic-gate CK_ULONG ulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
10907c478bd9Sstevel@tonic-gate {
10917c478bd9Sstevel@tonic-gate
10927c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
1093f66d273dSizick CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space for all mechs */
1094f66d273dSizick CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
1095f66d273dSizick CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
10967c478bd9Sstevel@tonic-gate CK_ULONG der_data_len;
10977c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
10987c478bd9Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
109960722cc8Sizick CK_ULONG der_len;
110060722cc8Sizick CK_BYTE_PTR der_prefix;
11017c478bd9Sstevel@tonic-gate
11027c478bd9Sstevel@tonic-gate if (Final) {
11037c478bd9Sstevel@tonic-gate rv = soft_digest_final(session_p, hash, &hash_len);
11047c478bd9Sstevel@tonic-gate } else {
11057c478bd9Sstevel@tonic-gate rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
11067c478bd9Sstevel@tonic-gate }
11077c478bd9Sstevel@tonic-gate
11087c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
11097c478bd9Sstevel@tonic-gate /* free the verification key */
11107c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
11117c478bd9Sstevel@tonic-gate free(key);
11127c478bd9Sstevel@tonic-gate goto clean_exit;
11137c478bd9Sstevel@tonic-gate }
11147c478bd9Sstevel@tonic-gate
11157c478bd9Sstevel@tonic-gate /*
11167c478bd9Sstevel@tonic-gate * Prepare the DER encoding of the DigestInfo value as follows:
11177c478bd9Sstevel@tonic-gate * MD5: MD5_DER_PREFIX || H
11187c478bd9Sstevel@tonic-gate * SHA-1: SHA1_DER_PREFIX || H
1119f66d273dSizick * SHA2: SHA2_DER_PREFIX || H
11207c478bd9Sstevel@tonic-gate *
11217c478bd9Sstevel@tonic-gate * See rsa_impl.c for more details.
11227c478bd9Sstevel@tonic-gate */
1123f66d273dSizick switch (session_p->digest.mech.mechanism) {
1124f66d273dSizick case CKM_MD5:
11257c478bd9Sstevel@tonic-gate (void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
11267c478bd9Sstevel@tonic-gate (void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
11277c478bd9Sstevel@tonic-gate der_data_len = MD5_DER_PREFIX_Len + hash_len;
1128f66d273dSizick break;
1129f66d273dSizick case CKM_SHA_1:
113060722cc8Sizick der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
113160722cc8Sizick &der_prefix);
113260722cc8Sizick (void) memcpy(der_data, der_prefix, der_len);
113360722cc8Sizick (void) memcpy(der_data + der_len, hash, hash_len);
113460722cc8Sizick der_data_len = der_len + hash_len;
1135f66d273dSizick break;
1136f66d273dSizick case CKM_SHA256:
1137f66d273dSizick (void) memcpy(der_data, SHA256_DER_PREFIX,
1138f66d273dSizick SHA2_DER_PREFIX_Len);
1139f66d273dSizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1140f66d273dSizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1141f66d273dSizick break;
1142f66d273dSizick case CKM_SHA384:
1143f66d273dSizick (void) memcpy(der_data, SHA384_DER_PREFIX,
1144f66d273dSizick SHA2_DER_PREFIX_Len);
1145f66d273dSizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1146f66d273dSizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1147f66d273dSizick break;
1148f66d273dSizick case CKM_SHA512:
1149f66d273dSizick (void) memcpy(der_data, SHA512_DER_PREFIX,
1150f66d273dSizick SHA2_DER_PREFIX_Len);
1151f66d273dSizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1152f66d273dSizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1153f66d273dSizick break;
11547c478bd9Sstevel@tonic-gate }
11557c478bd9Sstevel@tonic-gate
11567c478bd9Sstevel@tonic-gate /*
11577c478bd9Sstevel@tonic-gate * Now, we are ready to verify the DER_ENCODED data using signature.
11587c478bd9Sstevel@tonic-gate * soft_rsa_verify_common() will free the verification key.
11597c478bd9Sstevel@tonic-gate */
11607c478bd9Sstevel@tonic-gate rv = soft_rsa_verify_common(session_p, der_data, der_data_len,
11617c478bd9Sstevel@tonic-gate pSigned, ulSignedLen, mechanism);
11627c478bd9Sstevel@tonic-gate
11637c478bd9Sstevel@tonic-gate clean_exit:
11647c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
11657c478bd9Sstevel@tonic-gate /* soft_digest_common() has freed the digest context */
11667c478bd9Sstevel@tonic-gate session_p->digest.flags = 0;
11677c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
11687c478bd9Sstevel@tonic-gate
11697c478bd9Sstevel@tonic-gate return (rv);
11707c478bd9Sstevel@tonic-gate
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate
11737c478bd9Sstevel@tonic-gate
11747c478bd9Sstevel@tonic-gate CK_RV
soft_rsa_verify_recover(soft_session_t * session_p,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)11757c478bd9Sstevel@tonic-gate soft_rsa_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
11767c478bd9Sstevel@tonic-gate CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
11777c478bd9Sstevel@tonic-gate {
11787c478bd9Sstevel@tonic-gate
11797c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK;
11807c478bd9Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
11817c478bd9Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
11827c478bd9Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
11837c478bd9Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
11847c478bd9Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
11857c478bd9Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
11867c478bd9Sstevel@tonic-gate
1187c64d15a5Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
11887c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
11897c478bd9Sstevel@tonic-gate goto clean_exit;
11907c478bd9Sstevel@tonic-gate }
11917c478bd9Sstevel@tonic-gate
11927c478bd9Sstevel@tonic-gate if (ulSignatureLen != (CK_ULONG)modulus_len) {
11937c478bd9Sstevel@tonic-gate rv = CKR_SIGNATURE_LEN_RANGE;
11947c478bd9Sstevel@tonic-gate goto clean_exit;
11957c478bd9Sstevel@tonic-gate }
11967c478bd9Sstevel@tonic-gate
11977c478bd9Sstevel@tonic-gate /*
11987c478bd9Sstevel@tonic-gate * Perform RSA decryption with the signer's RSA public key
11997c478bd9Sstevel@tonic-gate * for verification process.
12007c478bd9Sstevel@tonic-gate */
12017c478bd9Sstevel@tonic-gate rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
12027c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
12037c478bd9Sstevel@tonic-gate switch (mechanism) {
12047c478bd9Sstevel@tonic-gate
12057c478bd9Sstevel@tonic-gate case CKM_RSA_PKCS:
12067c478bd9Sstevel@tonic-gate {
12077c478bd9Sstevel@tonic-gate /*
12087c478bd9Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the
12097c478bd9Sstevel@tonic-gate * recovered data.
12107c478bd9Sstevel@tonic-gate */
1211*726fad2aSDina K Nimeh size_t data_len = modulus_len;
12127c478bd9Sstevel@tonic-gate
1213*726fad2aSDina K Nimeh rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
12147c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
12157c478bd9Sstevel@tonic-gate goto clean_exit;
12167c478bd9Sstevel@tonic-gate }
12177c478bd9Sstevel@tonic-gate
12187c478bd9Sstevel@tonic-gate /*
12197c478bd9Sstevel@tonic-gate * If application asks for the length of the output
12207c478bd9Sstevel@tonic-gate * buffer?
12217c478bd9Sstevel@tonic-gate */
12227c478bd9Sstevel@tonic-gate if (pData == NULL) {
12237c478bd9Sstevel@tonic-gate *pulDataLen = data_len;
12247c478bd9Sstevel@tonic-gate rv = CKR_OK;
12257c478bd9Sstevel@tonic-gate goto clean1;
12267c478bd9Sstevel@tonic-gate }
12277c478bd9Sstevel@tonic-gate
12287c478bd9Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
12297c478bd9Sstevel@tonic-gate if (*pulDataLen < (CK_ULONG)data_len) {
12307c478bd9Sstevel@tonic-gate *pulDataLen = data_len;
12317c478bd9Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
12327c478bd9Sstevel@tonic-gate goto clean1;
12337c478bd9Sstevel@tonic-gate }
12347c478bd9Sstevel@tonic-gate
12357c478bd9Sstevel@tonic-gate (void) memcpy(pData,
12367c478bd9Sstevel@tonic-gate &plain_data[modulus_len - data_len], data_len);
12377c478bd9Sstevel@tonic-gate *pulDataLen = data_len;
12387c478bd9Sstevel@tonic-gate
12397c478bd9Sstevel@tonic-gate break;
12407c478bd9Sstevel@tonic-gate }
12417c478bd9Sstevel@tonic-gate
12427c478bd9Sstevel@tonic-gate case CKM_RSA_X_509:
12437c478bd9Sstevel@tonic-gate /*
12447c478bd9Sstevel@tonic-gate * If application asks for the length of the output
12457c478bd9Sstevel@tonic-gate * buffer?
12467c478bd9Sstevel@tonic-gate */
12477c478bd9Sstevel@tonic-gate if (pData == NULL) {
12487c478bd9Sstevel@tonic-gate *pulDataLen = modulus_len;
12497c478bd9Sstevel@tonic-gate rv = CKR_OK;
12507c478bd9Sstevel@tonic-gate goto clean1;
12517c478bd9Sstevel@tonic-gate }
12527c478bd9Sstevel@tonic-gate
12537c478bd9Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
12547c478bd9Sstevel@tonic-gate if (*pulDataLen < (CK_ULONG)modulus_len) {
12557c478bd9Sstevel@tonic-gate *pulDataLen = modulus_len;
12567c478bd9Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
12577c478bd9Sstevel@tonic-gate goto clean1;
12587c478bd9Sstevel@tonic-gate }
12597c478bd9Sstevel@tonic-gate
12607c478bd9Sstevel@tonic-gate (void) memcpy(pData, plain_data, modulus_len);
12617c478bd9Sstevel@tonic-gate *pulDataLen = modulus_len;
12627c478bd9Sstevel@tonic-gate
12637c478bd9Sstevel@tonic-gate break;
12647c478bd9Sstevel@tonic-gate }
12657c478bd9Sstevel@tonic-gate }
12667c478bd9Sstevel@tonic-gate
12677c478bd9Sstevel@tonic-gate clean_exit:
12687c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
12697c478bd9Sstevel@tonic-gate free(session_p->verify.context);
12707c478bd9Sstevel@tonic-gate session_p->verify.context = NULL;
12717c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
12727c478bd9Sstevel@tonic-gate soft_cleanup_object(key);
12737c478bd9Sstevel@tonic-gate free(key);
12747c478bd9Sstevel@tonic-gate
12757c478bd9Sstevel@tonic-gate clean1:
12767c478bd9Sstevel@tonic-gate return (rv);
12777c478bd9Sstevel@tonic-gate }
1278