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
56557Sfr41279 * Common Development and Distribution License (the "License").
66557Sfr41279 * 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>
32*12573SDina.Nimeh@Sun.COM #include <cryptoutil.h>
330Sstevel@tonic-gate #include "softGlobal.h"
340Sstevel@tonic-gate #include "softSession.h"
350Sstevel@tonic-gate #include "softObject.h"
360Sstevel@tonic-gate #include "softOps.h"
370Sstevel@tonic-gate #include "softRSA.h"
380Sstevel@tonic-gate #include "softMAC.h"
390Sstevel@tonic-gate #include "softCrypt.h"
400Sstevel@tonic-gate
410Sstevel@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)420Sstevel@tonic-gate soft_rsa_encrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
430Sstevel@tonic-gate CK_BYTE_PTR out, int realpublic)
440Sstevel@tonic-gate {
450Sstevel@tonic-gate
460Sstevel@tonic-gate CK_RV rv = CKR_OK;
470Sstevel@tonic-gate
480Sstevel@tonic-gate /* EXPORT DELETE START */
490Sstevel@tonic-gate
500Sstevel@tonic-gate uchar_t expo[MAX_KEY_ATTR_BUFLEN];
510Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
520Sstevel@tonic-gate uint32_t expo_len = sizeof (expo);
530Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
54*12573SDina.Nimeh@Sun.COM RSAbytekey k;
550Sstevel@tonic-gate
560Sstevel@tonic-gate if (realpublic) {
577260Smcpowers rv = soft_get_public_value(key, CKA_PUBLIC_EXPONENT, expo,
580Sstevel@tonic-gate &expo_len);
590Sstevel@tonic-gate if (rv != CKR_OK) {
600Sstevel@tonic-gate goto clean1;
610Sstevel@tonic-gate }
620Sstevel@tonic-gate } else {
637260Smcpowers rv = soft_get_private_value(key, CKA_PRIVATE_EXPONENT, expo,
640Sstevel@tonic-gate &expo_len);
650Sstevel@tonic-gate if (rv != CKR_OK) {
660Sstevel@tonic-gate goto clean1;
670Sstevel@tonic-gate }
680Sstevel@tonic-gate }
690Sstevel@tonic-gate
707260Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
710Sstevel@tonic-gate if (rv != CKR_OK) {
720Sstevel@tonic-gate goto clean1;
730Sstevel@tonic-gate }
740Sstevel@tonic-gate
75*12573SDina.Nimeh@Sun.COM k.modulus = modulus;
76*12573SDina.Nimeh@Sun.COM k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
77*12573SDina.Nimeh@Sun.COM k.pubexpo = expo;
78*12573SDina.Nimeh@Sun.COM k.pubexpo_bytes = expo_len;
79*12573SDina.Nimeh@Sun.COM k.rfunc = NULL;
800Sstevel@tonic-gate
81*12573SDina.Nimeh@Sun.COM rv = rsa_encrypt(&k, in, in_len, out);
820Sstevel@tonic-gate
830Sstevel@tonic-gate clean1:
840Sstevel@tonic-gate
850Sstevel@tonic-gate /* EXPORT DELETE END */
860Sstevel@tonic-gate
870Sstevel@tonic-gate return (rv);
880Sstevel@tonic-gate }
890Sstevel@tonic-gate
900Sstevel@tonic-gate
910Sstevel@tonic-gate CK_RV
soft_rsa_decrypt(soft_object_t * key,CK_BYTE_PTR in,uint32_t in_len,CK_BYTE_PTR out)920Sstevel@tonic-gate soft_rsa_decrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
930Sstevel@tonic-gate CK_BYTE_PTR out)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate
960Sstevel@tonic-gate CK_RV rv = CKR_OK;
970Sstevel@tonic-gate
980Sstevel@tonic-gate /* EXPORT DELETE START */
990Sstevel@tonic-gate
1000Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
1010Sstevel@tonic-gate uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
1020Sstevel@tonic-gate uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
1030Sstevel@tonic-gate uchar_t expo1[MAX_KEY_ATTR_BUFLEN];
1040Sstevel@tonic-gate uchar_t expo2[MAX_KEY_ATTR_BUFLEN];
1050Sstevel@tonic-gate uchar_t coef[MAX_KEY_ATTR_BUFLEN];
1060Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
1070Sstevel@tonic-gate uint32_t prime1_len = sizeof (prime1);
1080Sstevel@tonic-gate uint32_t prime2_len = sizeof (prime2);
1090Sstevel@tonic-gate uint32_t expo1_len = sizeof (expo1);
1100Sstevel@tonic-gate uint32_t expo2_len = sizeof (expo2);
1110Sstevel@tonic-gate uint32_t coef_len = sizeof (coef);
112*12573SDina.Nimeh@Sun.COM RSAbytekey k;
1130Sstevel@tonic-gate
1147260Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
1150Sstevel@tonic-gate if (rv != CKR_OK) {
1160Sstevel@tonic-gate goto clean1;
1170Sstevel@tonic-gate }
1180Sstevel@tonic-gate
1197260Smcpowers rv = soft_get_private_value(key, CKA_PRIME_1, prime1, &prime1_len);
1200Sstevel@tonic-gate
1210Sstevel@tonic-gate if ((prime1_len == 0) && (rv == CKR_OK)) {
1220Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1230Sstevel@tonic-gate goto clean1;
1240Sstevel@tonic-gate } else {
1250Sstevel@tonic-gate if (rv != CKR_OK)
1260Sstevel@tonic-gate goto clean1;
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate
1297260Smcpowers rv = soft_get_private_value(key, CKA_PRIME_2, prime2, &prime2_len);
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate if ((prime2_len == 0) && (rv == CKR_OK)) {
1320Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1330Sstevel@tonic-gate goto clean1;
1340Sstevel@tonic-gate } else {
1350Sstevel@tonic-gate if (rv != CKR_OK)
1360Sstevel@tonic-gate goto clean1;
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate
1397260Smcpowers rv = soft_get_private_value(key, CKA_EXPONENT_1, expo1, &expo1_len);
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate if ((expo1_len == 0) && (rv == CKR_OK)) {
1420Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1430Sstevel@tonic-gate goto clean1;
1440Sstevel@tonic-gate } else {
1450Sstevel@tonic-gate if (rv != CKR_OK)
1460Sstevel@tonic-gate goto clean1;
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate
1497260Smcpowers rv = soft_get_private_value(key, CKA_EXPONENT_2, expo2, &expo2_len);
1500Sstevel@tonic-gate
1510Sstevel@tonic-gate if ((expo2_len == 0) && (rv == CKR_OK)) {
1520Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1530Sstevel@tonic-gate goto clean1;
1540Sstevel@tonic-gate } else {
1550Sstevel@tonic-gate if (rv != CKR_OK)
1560Sstevel@tonic-gate goto clean1;
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate
1597260Smcpowers rv = soft_get_private_value(key, CKA_COEFFICIENT, coef, &coef_len);
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate if ((coef_len == 0) && (rv == CKR_OK)) {
1620Sstevel@tonic-gate rv = soft_rsa_encrypt(key, in, in_len, out, 0);
1630Sstevel@tonic-gate goto clean1;
1640Sstevel@tonic-gate } else {
1650Sstevel@tonic-gate if (rv != CKR_OK)
1660Sstevel@tonic-gate goto clean1;
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate
169*12573SDina.Nimeh@Sun.COM k.modulus = modulus;
170*12573SDina.Nimeh@Sun.COM k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
171*12573SDina.Nimeh@Sun.COM k.prime1 = prime1;
172*12573SDina.Nimeh@Sun.COM k.prime1_bytes = prime1_len;
173*12573SDina.Nimeh@Sun.COM k.prime2 = prime2;
174*12573SDina.Nimeh@Sun.COM k.prime2_bytes = prime2_len;
175*12573SDina.Nimeh@Sun.COM k.expo1 = expo1;
176*12573SDina.Nimeh@Sun.COM k.expo1_bytes = expo1_len;
177*12573SDina.Nimeh@Sun.COM k.expo2 = expo2;
178*12573SDina.Nimeh@Sun.COM k.expo2_bytes = expo2_len;
179*12573SDina.Nimeh@Sun.COM k.coeff = coef;
180*12573SDina.Nimeh@Sun.COM k.coeff_bytes = coef_len;
181*12573SDina.Nimeh@Sun.COM k.rfunc = NULL;
1820Sstevel@tonic-gate
183*12573SDina.Nimeh@Sun.COM rv = rsa_decrypt(&k, in, in_len, out);
1840Sstevel@tonic-gate
1850Sstevel@tonic-gate clean1:
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate /* EXPORT DELETE END */
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate return (rv);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate /*
1930Sstevel@tonic-gate * Allocate a RSA context for the active encryption or decryption operation.
1940Sstevel@tonic-gate * This function is called without the session lock held.
1950Sstevel@tonic-gate */
1960Sstevel@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)1970Sstevel@tonic-gate soft_rsa_crypt_init_common(soft_session_t *session_p,
1980Sstevel@tonic-gate CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
1990Sstevel@tonic-gate boolean_t encrypt)
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx;
2030Sstevel@tonic-gate soft_object_t *tmp_key = NULL;
2040Sstevel@tonic-gate CK_RV rv;
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate rsa_ctx = calloc(1, sizeof (soft_rsa_ctx_t));
2070Sstevel@tonic-gate if (rsa_ctx == NULL) {
2080Sstevel@tonic-gate return (CKR_HOST_MEMORY);
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate /*
2120Sstevel@tonic-gate * Make a copy of the encryption or decryption key, and save it
2130Sstevel@tonic-gate * in the RSA crypto context since it will be used later for
2140Sstevel@tonic-gate * encryption/decryption. We don't want to hold any object reference
2150Sstevel@tonic-gate * on this original key while doing encryption/decryption.
2160Sstevel@tonic-gate */
2170Sstevel@tonic-gate (void) pthread_mutex_lock(&key_p->object_mutex);
2180Sstevel@tonic-gate rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
2190Sstevel@tonic-gate NULL);
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate if ((rv != CKR_OK) || (tmp_key == NULL)) {
2220Sstevel@tonic-gate /* Most likely we ran out of space. */
2230Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
2240Sstevel@tonic-gate free(rsa_ctx);
2250Sstevel@tonic-gate return (rv);
2260Sstevel@tonic-gate }
2270Sstevel@tonic-gate
2280Sstevel@tonic-gate /* No need to hold the lock on the old object. */
2290Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
2300Sstevel@tonic-gate rsa_ctx->key = tmp_key;
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
2330Sstevel@tonic-gate if (encrypt) {
2340Sstevel@tonic-gate /* Called by C_EncryptInit. */
2350Sstevel@tonic-gate session_p->encrypt.context = rsa_ctx;
2360Sstevel@tonic-gate session_p->encrypt.mech.mechanism = pMechanism->mechanism;
2370Sstevel@tonic-gate } else {
2380Sstevel@tonic-gate /* Called by C_DecryptInit. */
2390Sstevel@tonic-gate session_p->decrypt.context = rsa_ctx;
2400Sstevel@tonic-gate session_p->decrypt.mech.mechanism = pMechanism->mechanism;
2410Sstevel@tonic-gate }
2420Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
2430Sstevel@tonic-gate
2440Sstevel@tonic-gate return (CKR_OK);
2450Sstevel@tonic-gate }
2460Sstevel@tonic-gate
2470Sstevel@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)2480Sstevel@tonic-gate soft_rsa_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
2490Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
2500Sstevel@tonic-gate CK_ULONG_PTR pulEncryptedLen, CK_MECHANISM_TYPE mechanism)
2510Sstevel@tonic-gate {
2520Sstevel@tonic-gate
2530Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->encrypt.context;
2540Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
2550Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
2560Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
2570Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
2580Sstevel@tonic-gate CK_BYTE cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES];
2590Sstevel@tonic-gate CK_RV rv = CKR_OK;
2600Sstevel@tonic-gate
2617260Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
2620Sstevel@tonic-gate if (rv != CKR_OK) {
2630Sstevel@tonic-gate goto clean_exit;
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate if (pEncrypted == NULL) {
2670Sstevel@tonic-gate /*
2680Sstevel@tonic-gate * Application asks for the length of the output buffer
2690Sstevel@tonic-gate * to hold the ciphertext.
2700Sstevel@tonic-gate */
2710Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2720Sstevel@tonic-gate rv = CKR_OK;
2730Sstevel@tonic-gate goto clean1;
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate if (mechanism == CKM_RSA_PKCS) {
2770Sstevel@tonic-gate /*
2780Sstevel@tonic-gate * Input data length needs to be <=
2790Sstevel@tonic-gate * modulus length-MIN_PKCS1_PADLEN.
2800Sstevel@tonic-gate */
2810Sstevel@tonic-gate if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
2820Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2830Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
2840Sstevel@tonic-gate goto clean_exit;
2850Sstevel@tonic-gate }
2860Sstevel@tonic-gate } else {
2870Sstevel@tonic-gate /* Input data length needs to be <= modulus length. */
2880Sstevel@tonic-gate if (ulDataLen > (CK_ULONG)modulus_len) {
2890Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2900Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
2910Sstevel@tonic-gate goto clean_exit;
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
2960Sstevel@tonic-gate if (*pulEncryptedLen < (CK_ULONG)modulus_len) {
2970Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
2980Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
2990Sstevel@tonic-gate goto clean1;
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate if (mechanism == CKM_RSA_PKCS) {
3030Sstevel@tonic-gate /*
3040Sstevel@tonic-gate * Add PKCS padding to the input data to format a block
3050Sstevel@tonic-gate * type "02" encryption block.
3060Sstevel@tonic-gate */
307*12573SDina.Nimeh@Sun.COM rv = pkcs1_encode(PKCS1_ENCRYPT, pData, ulDataLen, plain_data,
3080Sstevel@tonic-gate modulus_len);
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate if (rv != CKR_OK)
3110Sstevel@tonic-gate goto clean_exit;
3120Sstevel@tonic-gate } else {
3130Sstevel@tonic-gate /* Pad zeros for the leading bytes of the input data. */
3140Sstevel@tonic-gate (void) memset(plain_data, 0x0, modulus_len - ulDataLen);
3150Sstevel@tonic-gate (void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
3160Sstevel@tonic-gate ulDataLen);
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate
3190Sstevel@tonic-gate rv = soft_rsa_encrypt(key, plain_data, modulus_len, cipher_data, 1);
3200Sstevel@tonic-gate if (rv == CKR_OK) {
3210Sstevel@tonic-gate (void) memcpy(pEncrypted, cipher_data, modulus_len);
3220Sstevel@tonic-gate *pulEncryptedLen = modulus_len;
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate clean_exit:
3260Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
3270Sstevel@tonic-gate free(session_p->encrypt.context);
3280Sstevel@tonic-gate session_p->encrypt.context = NULL;
3290Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
3300Sstevel@tonic-gate soft_cleanup_object(key);
3310Sstevel@tonic-gate free(key);
3320Sstevel@tonic-gate clean1:
3330Sstevel@tonic-gate return (rv);
3340Sstevel@tonic-gate }
3350Sstevel@tonic-gate
3360Sstevel@tonic-gate
3370Sstevel@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)3380Sstevel@tonic-gate soft_rsa_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
3390Sstevel@tonic-gate CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
3400Sstevel@tonic-gate CK_ULONG_PTR pulDataLen, CK_MECHANISM_TYPE mechanism)
3410Sstevel@tonic-gate {
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->decrypt.context;
3440Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
3450Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
3460Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
3470Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
3480Sstevel@tonic-gate CK_RV rv = CKR_OK;
3490Sstevel@tonic-gate
3507260Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
3510Sstevel@tonic-gate if (rv != CKR_OK) {
3520Sstevel@tonic-gate goto clean_exit;
3530Sstevel@tonic-gate }
3540Sstevel@tonic-gate
3550Sstevel@tonic-gate if (ulEncryptedLen != (CK_ULONG)modulus_len) {
3560Sstevel@tonic-gate rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
3570Sstevel@tonic-gate goto clean_exit;
3580Sstevel@tonic-gate }
3590Sstevel@tonic-gate
3600Sstevel@tonic-gate if (pData == NULL) {
3610Sstevel@tonic-gate /*
3620Sstevel@tonic-gate * Application asks for the length of the output buffer
3630Sstevel@tonic-gate * to hold the recovered data.
3640Sstevel@tonic-gate */
3650Sstevel@tonic-gate *pulDataLen = modulus_len;
3660Sstevel@tonic-gate rv = CKR_OK;
3670Sstevel@tonic-gate goto clean1;
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate if (mechanism == CKM_RSA_X_509) {
3710Sstevel@tonic-gate if (*pulDataLen < (CK_ULONG)modulus_len) {
3720Sstevel@tonic-gate *pulDataLen = modulus_len;
3730Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
3740Sstevel@tonic-gate goto clean1;
3750Sstevel@tonic-gate }
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate rv = soft_rsa_decrypt(key, pEncrypted, modulus_len, plain_data);
3790Sstevel@tonic-gate if (rv != CKR_OK) {
3800Sstevel@tonic-gate goto clean_exit;
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate
3830Sstevel@tonic-gate if (mechanism == CKM_RSA_PKCS) {
384*12573SDina.Nimeh@Sun.COM size_t plain_len = modulus_len;
385*12573SDina.Nimeh@Sun.COM size_t num_padding;
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate /* Strip off the PKCS block formatting data. */
388*12573SDina.Nimeh@Sun.COM rv = pkcs1_decode(PKCS1_DECRYPT, plain_data, &plain_len);
3890Sstevel@tonic-gate if (rv != CKR_OK)
3900Sstevel@tonic-gate goto clean_exit;
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate num_padding = modulus_len - plain_len;
3930Sstevel@tonic-gate if (ulEncryptedLen - num_padding > *pulDataLen) {
3940Sstevel@tonic-gate *pulDataLen = plain_len;
3950Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
3960Sstevel@tonic-gate goto clean1;
3970Sstevel@tonic-gate }
3980Sstevel@tonic-gate
3990Sstevel@tonic-gate (void) memcpy(pData, &plain_data[num_padding], plain_len);
4000Sstevel@tonic-gate *pulDataLen = plain_len;
4010Sstevel@tonic-gate } else {
4020Sstevel@tonic-gate (void) memcpy(pData, plain_data, modulus_len);
4030Sstevel@tonic-gate *pulDataLen = modulus_len;
4040Sstevel@tonic-gate }
4050Sstevel@tonic-gate
4060Sstevel@tonic-gate clean_exit:
4070Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
4080Sstevel@tonic-gate free(session_p->decrypt.context);
4090Sstevel@tonic-gate session_p->decrypt.context = NULL;
4100Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
4110Sstevel@tonic-gate soft_cleanup_object(key);
4120Sstevel@tonic-gate free(key);
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate clean1:
4150Sstevel@tonic-gate return (rv);
4160Sstevel@tonic-gate }
4170Sstevel@tonic-gate
4180Sstevel@tonic-gate /*
4190Sstevel@tonic-gate * Allocate a RSA context for the active sign or verify operation.
4200Sstevel@tonic-gate * This function is called without the session lock held.
4210Sstevel@tonic-gate */
4220Sstevel@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)4230Sstevel@tonic-gate soft_rsa_sign_verify_init_common(soft_session_t *session_p,
4240Sstevel@tonic-gate CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
4250Sstevel@tonic-gate boolean_t sign)
4260Sstevel@tonic-gate {
4270Sstevel@tonic-gate CK_RV rv = CKR_OK;
4280Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx;
4290Sstevel@tonic-gate CK_MECHANISM digest_mech;
4300Sstevel@tonic-gate soft_object_t *tmp_key = NULL;
4310Sstevel@tonic-gate
4320Sstevel@tonic-gate if (sign) {
4330Sstevel@tonic-gate if ((key_p->class != CKO_PRIVATE_KEY) ||
4340Sstevel@tonic-gate (key_p->key_type != CKK_RSA))
4350Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
4360Sstevel@tonic-gate } else {
4370Sstevel@tonic-gate if ((key_p->class != CKO_PUBLIC_KEY) ||
4380Sstevel@tonic-gate (key_p->key_type != CKK_RSA))
4390Sstevel@tonic-gate return (CKR_KEY_TYPE_INCONSISTENT);
4400Sstevel@tonic-gate }
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate switch (pMechanism->mechanism) {
4430Sstevel@tonic-gate case CKM_MD5_RSA_PKCS:
4440Sstevel@tonic-gate digest_mech.mechanism = CKM_MD5;
4450Sstevel@tonic-gate rv = soft_digest_init_internal(session_p, &digest_mech);
4460Sstevel@tonic-gate if (rv != CKR_OK)
4470Sstevel@tonic-gate return (rv);
4480Sstevel@tonic-gate break;
4490Sstevel@tonic-gate
4500Sstevel@tonic-gate case CKM_SHA1_RSA_PKCS:
4510Sstevel@tonic-gate digest_mech.mechanism = CKM_SHA_1;
452872Sizick digest_mech.pParameter = pMechanism->pParameter;
453872Sizick digest_mech.ulParameterLen = pMechanism->ulParameterLen;
4540Sstevel@tonic-gate rv = soft_digest_init_internal(session_p, &digest_mech);
4550Sstevel@tonic-gate if (rv != CKR_OK)
4560Sstevel@tonic-gate return (rv);
4570Sstevel@tonic-gate break;
458676Sizick
459676Sizick case CKM_SHA256_RSA_PKCS:
460676Sizick digest_mech.mechanism = CKM_SHA256;
461676Sizick rv = soft_digest_init_internal(session_p, &digest_mech);
462676Sizick if (rv != CKR_OK)
463676Sizick return (rv);
464676Sizick break;
465676Sizick
466676Sizick case CKM_SHA384_RSA_PKCS:
467676Sizick digest_mech.mechanism = CKM_SHA384;
468676Sizick rv = soft_digest_init_internal(session_p, &digest_mech);
469676Sizick if (rv != CKR_OK)
470676Sizick return (rv);
471676Sizick break;
472676Sizick
473676Sizick case CKM_SHA512_RSA_PKCS:
474676Sizick digest_mech.mechanism = CKM_SHA512;
475676Sizick rv = soft_digest_init_internal(session_p, &digest_mech);
476676Sizick if (rv != CKR_OK)
477676Sizick return (rv);
478676Sizick break;
4790Sstevel@tonic-gate }
4800Sstevel@tonic-gate
4810Sstevel@tonic-gate rsa_ctx = malloc(sizeof (soft_rsa_ctx_t));
4820Sstevel@tonic-gate
4830Sstevel@tonic-gate if (rsa_ctx == NULL) {
4840Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
4850Sstevel@tonic-gate goto clean_exit;
4860Sstevel@tonic-gate }
4870Sstevel@tonic-gate
4880Sstevel@tonic-gate (void) pthread_mutex_lock(&key_p->object_mutex);
4890Sstevel@tonic-gate rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
4900Sstevel@tonic-gate NULL);
4910Sstevel@tonic-gate
4920Sstevel@tonic-gate if ((rv != CKR_OK) || (tmp_key == NULL)) {
4930Sstevel@tonic-gate /* Most likely we ran out of space. */
4940Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
4950Sstevel@tonic-gate free(rsa_ctx);
4960Sstevel@tonic-gate goto clean_exit;
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate
4990Sstevel@tonic-gate /* No need to hold the lock on the old object. */
5000Sstevel@tonic-gate (void) pthread_mutex_unlock(&key_p->object_mutex);
5010Sstevel@tonic-gate rsa_ctx->key = tmp_key;
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
5040Sstevel@tonic-gate
5050Sstevel@tonic-gate if (sign) {
5060Sstevel@tonic-gate session_p->sign.context = rsa_ctx;
5070Sstevel@tonic-gate session_p->sign.mech.mechanism = pMechanism->mechanism;
5080Sstevel@tonic-gate } else {
5090Sstevel@tonic-gate session_p->verify.context = rsa_ctx;
5100Sstevel@tonic-gate session_p->verify.mech.mechanism = pMechanism->mechanism;
5110Sstevel@tonic-gate }
5120Sstevel@tonic-gate
5130Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate return (CKR_OK);
5160Sstevel@tonic-gate
5170Sstevel@tonic-gate clean_exit:
5180Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
5190Sstevel@tonic-gate if (session_p->digest.context != NULL) {
5200Sstevel@tonic-gate free(session_p->digest.context);
5210Sstevel@tonic-gate session_p->digest.context = NULL;
5220Sstevel@tonic-gate session_p->digest.flags = 0;
5230Sstevel@tonic-gate }
5240Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
5250Sstevel@tonic-gate return (rv);
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate }
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate
5300Sstevel@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)5310Sstevel@tonic-gate soft_rsa_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
5320Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
5330Sstevel@tonic-gate CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism)
5340Sstevel@tonic-gate {
5350Sstevel@tonic-gate
5360Sstevel@tonic-gate CK_RV rv = CKR_OK;
5370Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
5380Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
5390Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
5400Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
5410Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
5420Sstevel@tonic-gate CK_BYTE signed_data[MAX_RSA_KEYLENGTH_IN_BYTES];
5430Sstevel@tonic-gate
5447260Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
5450Sstevel@tonic-gate if (rv != CKR_OK) {
5460Sstevel@tonic-gate goto clean_exit;
5470Sstevel@tonic-gate }
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate if (pSigned == NULL) {
5500Sstevel@tonic-gate /* Application asks for the length of the output buffer. */
5510Sstevel@tonic-gate *pulSignedLen = modulus_len;
5520Sstevel@tonic-gate rv = CKR_OK;
5530Sstevel@tonic-gate goto clean1;
5540Sstevel@tonic-gate }
5550Sstevel@tonic-gate
5560Sstevel@tonic-gate switch (mechanism) {
5570Sstevel@tonic-gate
5580Sstevel@tonic-gate case CKM_RSA_PKCS:
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate /*
5610Sstevel@tonic-gate * Input data length needs to be <=
5620Sstevel@tonic-gate * modulus length-MIN_PKCS1_PADLEN.
5630Sstevel@tonic-gate */
5640Sstevel@tonic-gate if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
5650Sstevel@tonic-gate *pulSignedLen = modulus_len;
5660Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
5670Sstevel@tonic-gate goto clean_exit;
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate break;
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate case CKM_RSA_X_509:
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate /* Input data length needs to be <= modulus length. */
5740Sstevel@tonic-gate if (ulDataLen > (CK_ULONG)modulus_len) {
5750Sstevel@tonic-gate *pulSignedLen = modulus_len;
5760Sstevel@tonic-gate rv = CKR_DATA_LEN_RANGE;
5770Sstevel@tonic-gate goto clean_exit;
5780Sstevel@tonic-gate }
5790Sstevel@tonic-gate break;
5800Sstevel@tonic-gate }
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
5830Sstevel@tonic-gate if (*pulSignedLen < (CK_ULONG)modulus_len) {
5840Sstevel@tonic-gate *pulSignedLen = modulus_len;
5850Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
5860Sstevel@tonic-gate goto clean1;
5870Sstevel@tonic-gate }
5880Sstevel@tonic-gate
5890Sstevel@tonic-gate switch (mechanism) {
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate case CKM_RSA_PKCS:
5920Sstevel@tonic-gate case CKM_MD5_RSA_PKCS:
5930Sstevel@tonic-gate case CKM_SHA1_RSA_PKCS:
594676Sizick case CKM_SHA256_RSA_PKCS:
595676Sizick case CKM_SHA384_RSA_PKCS:
596676Sizick case CKM_SHA512_RSA_PKCS:
5970Sstevel@tonic-gate /*
5980Sstevel@tonic-gate * Add PKCS padding to the input data to format a block
5990Sstevel@tonic-gate * type "01" encryption block.
6000Sstevel@tonic-gate */
601*12573SDina.Nimeh@Sun.COM rv = pkcs1_encode(PKCS1_SIGN, pData, ulDataLen, plain_data,
6020Sstevel@tonic-gate modulus_len);
6030Sstevel@tonic-gate
6040Sstevel@tonic-gate if (rv != CKR_OK) {
6050Sstevel@tonic-gate goto clean_exit;
6060Sstevel@tonic-gate }
6070Sstevel@tonic-gate break;
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate case CKM_RSA_X_509:
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate /* Pad zeros for the leading bytes of the input data. */
6120Sstevel@tonic-gate (void) memset(plain_data, 0x0, modulus_len - ulDataLen);
6130Sstevel@tonic-gate (void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
6140Sstevel@tonic-gate ulDataLen);
6150Sstevel@tonic-gate break;
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate
6180Sstevel@tonic-gate /*
6190Sstevel@tonic-gate * Perform RSA encryption with the signer's RSA private key
6200Sstevel@tonic-gate * for signature process.
6210Sstevel@tonic-gate */
6220Sstevel@tonic-gate rv = soft_rsa_decrypt(key, plain_data, modulus_len, signed_data);
6230Sstevel@tonic-gate
6240Sstevel@tonic-gate if (rv == CKR_OK) {
6250Sstevel@tonic-gate (void) memcpy(pSigned, signed_data, modulus_len);
6260Sstevel@tonic-gate *pulSignedLen = modulus_len;
6270Sstevel@tonic-gate }
6280Sstevel@tonic-gate
6290Sstevel@tonic-gate clean_exit:
6300Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
6310Sstevel@tonic-gate free(session_p->sign.context);
6320Sstevel@tonic-gate session_p->sign.context = NULL;
6330Sstevel@tonic-gate if (session_p->digest.context != NULL) {
6340Sstevel@tonic-gate free(session_p->digest.context);
6350Sstevel@tonic-gate session_p->digest.context = NULL;
6360Sstevel@tonic-gate session_p->digest.flags = 0;
6370Sstevel@tonic-gate }
6380Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
6390Sstevel@tonic-gate soft_cleanup_object(key);
6400Sstevel@tonic-gate free(key);
6410Sstevel@tonic-gate
6420Sstevel@tonic-gate clean1:
6430Sstevel@tonic-gate return (rv);
6440Sstevel@tonic-gate }
6450Sstevel@tonic-gate
6460Sstevel@tonic-gate
6470Sstevel@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)6480Sstevel@tonic-gate soft_rsa_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
6490Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
6500Sstevel@tonic-gate CK_ULONG ulSignatureLen, CK_MECHANISM_TYPE mechanism)
6510Sstevel@tonic-gate {
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate CK_RV rv = CKR_OK;
6540Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
6550Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
6560Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
6570Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
6580Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
6590Sstevel@tonic-gate
6607260Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
6610Sstevel@tonic-gate if (rv != CKR_OK) {
6620Sstevel@tonic-gate goto clean_exit;
6630Sstevel@tonic-gate }
6640Sstevel@tonic-gate
665*12573SDina.Nimeh@Sun.COM if (ulDataLen == 0) {
666*12573SDina.Nimeh@Sun.COM rv = CKR_DATA_LEN_RANGE;
667*12573SDina.Nimeh@Sun.COM goto clean_exit;
668*12573SDina.Nimeh@Sun.COM }
669*12573SDina.Nimeh@Sun.COM
6700Sstevel@tonic-gate if (ulSignatureLen != (CK_ULONG)modulus_len) {
6710Sstevel@tonic-gate rv = CKR_SIGNATURE_LEN_RANGE;
6720Sstevel@tonic-gate goto clean_exit;
6730Sstevel@tonic-gate }
6740Sstevel@tonic-gate
6750Sstevel@tonic-gate /*
6760Sstevel@tonic-gate * Perform RSA decryption with the signer's RSA public key
6770Sstevel@tonic-gate * for verification process.
6780Sstevel@tonic-gate */
6790Sstevel@tonic-gate rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
6800Sstevel@tonic-gate if (rv == CKR_OK) {
6810Sstevel@tonic-gate switch (mechanism) {
6820Sstevel@tonic-gate
6830Sstevel@tonic-gate case CKM_RSA_PKCS:
6840Sstevel@tonic-gate case CKM_MD5_RSA_PKCS:
6850Sstevel@tonic-gate case CKM_SHA1_RSA_PKCS:
686676Sizick case CKM_SHA256_RSA_PKCS:
687676Sizick case CKM_SHA384_RSA_PKCS:
688676Sizick case CKM_SHA512_RSA_PKCS:
6890Sstevel@tonic-gate {
6900Sstevel@tonic-gate /*
6910Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the
6920Sstevel@tonic-gate * recovered data, then compare the recovered data with
6930Sstevel@tonic-gate * the original data.
6940Sstevel@tonic-gate */
695*12573SDina.Nimeh@Sun.COM size_t data_len = modulus_len;
6960Sstevel@tonic-gate
697*12573SDina.Nimeh@Sun.COM rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
6980Sstevel@tonic-gate if (rv != CKR_OK) {
6990Sstevel@tonic-gate goto clean_exit;
7000Sstevel@tonic-gate }
7010Sstevel@tonic-gate
7020Sstevel@tonic-gate if ((CK_ULONG)data_len != ulDataLen) {
703*12573SDina.Nimeh@Sun.COM rv = CKR_DATA_LEN_RANGE;
7040Sstevel@tonic-gate goto clean_exit;
7050Sstevel@tonic-gate } else if (memcmp(pData,
7060Sstevel@tonic-gate &plain_data[modulus_len - data_len],
7070Sstevel@tonic-gate ulDataLen) != 0) {
7080Sstevel@tonic-gate rv = CKR_SIGNATURE_INVALID;
7090Sstevel@tonic-gate goto clean_exit;
7100Sstevel@tonic-gate }
7110Sstevel@tonic-gate break;
7120Sstevel@tonic-gate }
7130Sstevel@tonic-gate
7140Sstevel@tonic-gate case CKM_RSA_X_509:
7150Sstevel@tonic-gate /*
7160Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the
7170Sstevel@tonic-gate * recovered plain_data, then compare the input data
7180Sstevel@tonic-gate * with the recovered data.
7190Sstevel@tonic-gate */
7200Sstevel@tonic-gate if (memcmp(pData,
7210Sstevel@tonic-gate plain_data + ulSignatureLen - ulDataLen,
7220Sstevel@tonic-gate ulDataLen) != 0) {
7230Sstevel@tonic-gate rv = CKR_SIGNATURE_INVALID;
7240Sstevel@tonic-gate goto clean_exit;
7250Sstevel@tonic-gate }
7260Sstevel@tonic-gate break;
7270Sstevel@tonic-gate }
7280Sstevel@tonic-gate }
7290Sstevel@tonic-gate
7300Sstevel@tonic-gate if (rv == CKR_DATA_LEN_RANGE) {
7310Sstevel@tonic-gate if ((mechanism == CKM_MD5_RSA_PKCS) ||
732676Sizick (mechanism == CKM_SHA1_RSA_PKCS) ||
733676Sizick (mechanism == CKM_SHA256_RSA_PKCS) ||
734676Sizick (mechanism == CKM_SHA384_RSA_PKCS) ||
735676Sizick (mechanism == CKM_SHA512_RSA_PKCS))
7360Sstevel@tonic-gate rv = CKR_SIGNATURE_INVALID;
7370Sstevel@tonic-gate }
7380Sstevel@tonic-gate
7390Sstevel@tonic-gate clean_exit:
7400Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
7410Sstevel@tonic-gate free(session_p->verify.context);
7420Sstevel@tonic-gate session_p->verify.context = NULL;
7430Sstevel@tonic-gate if (session_p->digest.context != NULL) {
7440Sstevel@tonic-gate free(session_p->digest.context);
7450Sstevel@tonic-gate session_p->digest.context = NULL;
7460Sstevel@tonic-gate session_p->digest.flags = 0;
7470Sstevel@tonic-gate }
7480Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
7490Sstevel@tonic-gate soft_cleanup_object(key);
7500Sstevel@tonic-gate free(key);
7510Sstevel@tonic-gate return (rv);
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate
7540Sstevel@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)755*12573SDina.Nimeh@Sun.COM soft_genRSAkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
756*12573SDina.Nimeh@Sun.COM uchar_t *buf, uint32_t buflen, boolean_t public)
7570Sstevel@tonic-gate {
7580Sstevel@tonic-gate CK_RV rv = CKR_OK;
7590Sstevel@tonic-gate biginteger_t *dst = NULL;
7600Sstevel@tonic-gate biginteger_t src;
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate switch (type) {
7630Sstevel@tonic-gate
7640Sstevel@tonic-gate case CKA_MODULUS:
7650Sstevel@tonic-gate
7660Sstevel@tonic-gate if (public)
7670Sstevel@tonic-gate dst = OBJ_PUB_RSA_MOD(key);
7680Sstevel@tonic-gate else
7690Sstevel@tonic-gate dst = OBJ_PRI_RSA_MOD(key);
7700Sstevel@tonic-gate break;
7710Sstevel@tonic-gate
7720Sstevel@tonic-gate case CKA_PUBLIC_EXPONENT:
7730Sstevel@tonic-gate
7740Sstevel@tonic-gate if (public)
7750Sstevel@tonic-gate dst = OBJ_PUB_RSA_PUBEXPO(key);
7760Sstevel@tonic-gate else
7770Sstevel@tonic-gate dst = OBJ_PRI_RSA_PUBEXPO(key);
7780Sstevel@tonic-gate break;
7790Sstevel@tonic-gate
7800Sstevel@tonic-gate case CKA_PRIVATE_EXPONENT:
7810Sstevel@tonic-gate
7820Sstevel@tonic-gate dst = OBJ_PRI_RSA_PRIEXPO(key);
7830Sstevel@tonic-gate break;
7840Sstevel@tonic-gate
7850Sstevel@tonic-gate case CKA_PRIME_1:
7860Sstevel@tonic-gate
7870Sstevel@tonic-gate dst = OBJ_PRI_RSA_PRIME1(key);
7880Sstevel@tonic-gate break;
7890Sstevel@tonic-gate
7900Sstevel@tonic-gate case CKA_PRIME_2:
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate dst = OBJ_PRI_RSA_PRIME2(key);
7930Sstevel@tonic-gate break;
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate case CKA_EXPONENT_1:
7960Sstevel@tonic-gate
7970Sstevel@tonic-gate dst = OBJ_PRI_RSA_EXPO1(key);
7980Sstevel@tonic-gate break;
7990Sstevel@tonic-gate
8000Sstevel@tonic-gate case CKA_EXPONENT_2:
8010Sstevel@tonic-gate
8020Sstevel@tonic-gate dst = OBJ_PRI_RSA_EXPO2(key);
8030Sstevel@tonic-gate break;
8040Sstevel@tonic-gate
8050Sstevel@tonic-gate case CKA_COEFFICIENT:
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate dst = OBJ_PRI_RSA_COEF(key);
8080Sstevel@tonic-gate break;
8090Sstevel@tonic-gate }
8100Sstevel@tonic-gate
811*12573SDina.Nimeh@Sun.COM /* Note: no explanation found for why this is needed */
8120Sstevel@tonic-gate while (buf[0] == 0) { /* remove proceeding 0x00 */
8130Sstevel@tonic-gate buf++;
8140Sstevel@tonic-gate buflen--;
8150Sstevel@tonic-gate }
8160Sstevel@tonic-gate
817*12573SDina.Nimeh@Sun.COM if ((rv = dup_bigint_attr(&src, buf, buflen)) != CKR_OK)
8180Sstevel@tonic-gate goto cleanexit;
8190Sstevel@tonic-gate
8200Sstevel@tonic-gate /* Copy the attribute in the key object. */
8210Sstevel@tonic-gate copy_bigint_attr(&src, dst);
8220Sstevel@tonic-gate
8230Sstevel@tonic-gate cleanexit:
8240Sstevel@tonic-gate return (rv);
8250Sstevel@tonic-gate
8260Sstevel@tonic-gate }
8270Sstevel@tonic-gate
8280Sstevel@tonic-gate
8290Sstevel@tonic-gate CK_RV
soft_rsa_genkey_pair(soft_object_t * pubkey,soft_object_t * prikey)8300Sstevel@tonic-gate soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
8310Sstevel@tonic-gate {
8320Sstevel@tonic-gate CK_RV rv = CKR_OK;
833*12573SDina.Nimeh@Sun.COM CK_ATTRIBUTE template;
834*12573SDina.Nimeh@Sun.COM uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
8350Sstevel@tonic-gate uint32_t modulus_len;
836*12573SDina.Nimeh@Sun.COM uchar_t pub_expo[MAX_KEY_ATTR_BUFLEN];
8370Sstevel@tonic-gate uint32_t pub_expo_len = sizeof (pub_expo);
838*12573SDina.Nimeh@Sun.COM uchar_t private_exponent[MAX_KEY_ATTR_BUFLEN];
839*12573SDina.Nimeh@Sun.COM uint32_t private_exponent_len = sizeof (private_exponent);
840*12573SDina.Nimeh@Sun.COM uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
841*12573SDina.Nimeh@Sun.COM uint32_t prime1_len = sizeof (prime1);
842*12573SDina.Nimeh@Sun.COM uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
843*12573SDina.Nimeh@Sun.COM uint32_t prime2_len = sizeof (prime2);
844*12573SDina.Nimeh@Sun.COM uchar_t exponent1[MAX_KEY_ATTR_BUFLEN];
845*12573SDina.Nimeh@Sun.COM uint32_t exponent1_len = sizeof (exponent1);
846*12573SDina.Nimeh@Sun.COM uchar_t exponent2[MAX_KEY_ATTR_BUFLEN];
847*12573SDina.Nimeh@Sun.COM uint32_t exponent2_len = sizeof (exponent2);
848*12573SDina.Nimeh@Sun.COM uchar_t coefficient[MAX_KEY_ATTR_BUFLEN];
849*12573SDina.Nimeh@Sun.COM uint32_t coefficient_len = sizeof (coefficient);
850*12573SDina.Nimeh@Sun.COM RSAbytekey k;
8510Sstevel@tonic-gate
8520Sstevel@tonic-gate if ((pubkey == NULL) || (prikey == NULL)) {
8530Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
8540Sstevel@tonic-gate }
8550Sstevel@tonic-gate
8560Sstevel@tonic-gate template.pValue = malloc(sizeof (CK_ULONG));
8570Sstevel@tonic-gate if (template.pValue == NULL) {
8580Sstevel@tonic-gate return (CKR_HOST_MEMORY);
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate template.ulValueLen = sizeof (CK_ULONG);
8610Sstevel@tonic-gate
8620Sstevel@tonic-gate rv = get_ulong_attr_from_object(OBJ_PUB_RSA_MOD_BITS(pubkey),
8630Sstevel@tonic-gate &template);
8640Sstevel@tonic-gate if (rv != CKR_OK) {
865*12573SDina.Nimeh@Sun.COM free(template.pValue);
8660Sstevel@tonic-gate goto clean0;
8670Sstevel@tonic-gate }
8680Sstevel@tonic-gate
8690Sstevel@tonic-gate #ifdef __sparcv9
8700Sstevel@tonic-gate /* LINTED */
8710Sstevel@tonic-gate modulus_len = (uint32_t)(*((CK_ULONG *)(template.pValue)));
8720Sstevel@tonic-gate #else /* !__sparcv9 */
8730Sstevel@tonic-gate modulus_len = *((CK_ULONG *)(template.pValue));
8740Sstevel@tonic-gate #endif /* __sparcv9 */
8750Sstevel@tonic-gate
876*12573SDina.Nimeh@Sun.COM free(template.pValue);
8770Sstevel@tonic-gate
8787260Smcpowers rv = soft_get_public_value(pubkey, CKA_PUBLIC_EXPONENT, pub_expo,
8790Sstevel@tonic-gate &pub_expo_len);
8800Sstevel@tonic-gate if (rv != CKR_OK) {
8810Sstevel@tonic-gate goto clean0;
8820Sstevel@tonic-gate }
8830Sstevel@tonic-gate
884*12573SDina.Nimeh@Sun.COM /* Inputs to RSA key pair generation */
885*12573SDina.Nimeh@Sun.COM k.modulus_bits = modulus_len; /* save modulus len in bits */
886*12573SDina.Nimeh@Sun.COM modulus_len = CRYPTO_BITS2BYTES(modulus_len); /* convert to bytes */
887*12573SDina.Nimeh@Sun.COM k.modulus = modulus;
888*12573SDina.Nimeh@Sun.COM k.pubexpo = pub_expo;
889*12573SDina.Nimeh@Sun.COM k.pubexpo_bytes = pub_expo_len;
890*12573SDina.Nimeh@Sun.COM k.rfunc = (IS_TOKEN_OBJECT(pubkey) || IS_TOKEN_OBJECT(prikey)) ?
891*12573SDina.Nimeh@Sun.COM pkcs11_get_random : pkcs11_get_urandom;
8920Sstevel@tonic-gate
893*12573SDina.Nimeh@Sun.COM /* Outputs from RSA key pair generation */
894*12573SDina.Nimeh@Sun.COM k.privexpo = private_exponent;
895*12573SDina.Nimeh@Sun.COM k.privexpo_bytes = private_exponent_len;
896*12573SDina.Nimeh@Sun.COM k.prime1 = prime1;
897*12573SDina.Nimeh@Sun.COM k.prime1_bytes = prime1_len;
898*12573SDina.Nimeh@Sun.COM k.prime2 = prime2;
899*12573SDina.Nimeh@Sun.COM k.prime2_bytes = prime2_len;
900*12573SDina.Nimeh@Sun.COM k.expo1 = exponent1;
901*12573SDina.Nimeh@Sun.COM k.expo1_bytes = exponent1_len;
902*12573SDina.Nimeh@Sun.COM k.expo2 = exponent2;
903*12573SDina.Nimeh@Sun.COM k.expo2_bytes = exponent2_len;
904*12573SDina.Nimeh@Sun.COM k.coeff = coefficient;
905*12573SDina.Nimeh@Sun.COM k.coeff_bytes = coefficient_len;
9060Sstevel@tonic-gate
907*12573SDina.Nimeh@Sun.COM rv = rsa_genkey_pair(&k);
908*12573SDina.Nimeh@Sun.COM
909*12573SDina.Nimeh@Sun.COM if (rv != CKR_OK) {
910*12573SDina.Nimeh@Sun.COM goto clean0;
9110Sstevel@tonic-gate }
9120Sstevel@tonic-gate
9130Sstevel@tonic-gate /*
9140Sstevel@tonic-gate * Add modulus in public template, and add all eight key fields
9150Sstevel@tonic-gate * in private template.
9160Sstevel@tonic-gate */
917*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(pubkey, CKA_MODULUS,
918*12573SDina.Nimeh@Sun.COM modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_TRUE)) != CKR_OK) {
919*12573SDina.Nimeh@Sun.COM goto clean0;
9200Sstevel@tonic-gate }
9210Sstevel@tonic-gate
922*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_MODULUS,
923*12573SDina.Nimeh@Sun.COM modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_FALSE)) != CKR_OK) {
924*12573SDina.Nimeh@Sun.COM goto clean0;
9250Sstevel@tonic-gate }
9260Sstevel@tonic-gate
927*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIVATE_EXPONENT,
928*12573SDina.Nimeh@Sun.COM private_exponent, k.privexpo_bytes, B_FALSE)) != CKR_OK) {
929*12573SDina.Nimeh@Sun.COM goto clean0;
9300Sstevel@tonic-gate }
9310Sstevel@tonic-gate
932*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PUBLIC_EXPONENT,
933*12573SDina.Nimeh@Sun.COM pub_expo, k.pubexpo_bytes, B_FALSE)) != CKR_OK) {
934*12573SDina.Nimeh@Sun.COM goto clean0;
9350Sstevel@tonic-gate }
9360Sstevel@tonic-gate
937*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_1,
938*12573SDina.Nimeh@Sun.COM prime1, k.prime1_bytes, B_FALSE)) != CKR_OK) {
939*12573SDina.Nimeh@Sun.COM goto clean0;
9400Sstevel@tonic-gate }
9410Sstevel@tonic-gate
942*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_2,
943*12573SDina.Nimeh@Sun.COM prime2, k.prime2_bytes, B_FALSE)) != CKR_OK) {
944*12573SDina.Nimeh@Sun.COM goto clean0;
9450Sstevel@tonic-gate }
9460Sstevel@tonic-gate
947*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_1,
948*12573SDina.Nimeh@Sun.COM exponent1, k.expo1_bytes, B_FALSE)) != CKR_OK) {
949*12573SDina.Nimeh@Sun.COM goto clean0;
9500Sstevel@tonic-gate }
9510Sstevel@tonic-gate
952*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_2,
953*12573SDina.Nimeh@Sun.COM exponent2, k.expo2_bytes, B_FALSE)) != CKR_OK) {
954*12573SDina.Nimeh@Sun.COM goto clean0;
9550Sstevel@tonic-gate }
9560Sstevel@tonic-gate
957*12573SDina.Nimeh@Sun.COM if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_COEFFICIENT,
958*12573SDina.Nimeh@Sun.COM coefficient, k.coeff_bytes, B_FALSE)) != CKR_OK) {
959*12573SDina.Nimeh@Sun.COM goto clean0;
960*12573SDina.Nimeh@Sun.COM }
961*12573SDina.Nimeh@Sun.COM
9620Sstevel@tonic-gate clean0:
9630Sstevel@tonic-gate return (rv);
9640Sstevel@tonic-gate }
9650Sstevel@tonic-gate
966872Sizick
967872Sizick CK_ULONG
get_rsa_sha1_prefix(CK_MECHANISM_PTR mech,CK_BYTE_PTR * prefix)968872Sizick get_rsa_sha1_prefix(CK_MECHANISM_PTR mech, CK_BYTE_PTR *prefix) {
969872Sizick if (mech->pParameter == NULL) {
970872Sizick *prefix = (CK_BYTE *)SHA1_DER_PREFIX;
971872Sizick return (SHA1_DER_PREFIX_Len);
972872Sizick }
973872Sizick
974872Sizick *prefix = (CK_BYTE *)SHA1_DER_PREFIX_OID;
975872Sizick return (SHA1_DER_PREFIX_OID_Len);
976872Sizick }
977872Sizick
9780Sstevel@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)9790Sstevel@tonic-gate soft_rsa_digest_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
9800Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
9810Sstevel@tonic-gate CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
9820Sstevel@tonic-gate {
9830Sstevel@tonic-gate
9840Sstevel@tonic-gate CK_RV rv = CKR_OK;
985676Sizick CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
986676Sizick CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
987676Sizick /* space enough for all mechs */
988676Sizick CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
9890Sstevel@tonic-gate CK_ULONG der_data_len;
9900Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
9910Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
9920Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
9930Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
994872Sizick CK_ULONG der_len;
995872Sizick CK_BYTE_PTR der_prefix;
9960Sstevel@tonic-gate
9977260Smcpowers rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
9980Sstevel@tonic-gate if (rv != CKR_OK) {
9990Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
10000Sstevel@tonic-gate free(session_p->digest.context);
10010Sstevel@tonic-gate session_p->digest.context = NULL;
10020Sstevel@tonic-gate session_p->digest.flags = 0;
10030Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
10040Sstevel@tonic-gate soft_cleanup_object(key);
10050Sstevel@tonic-gate free(key);
10060Sstevel@tonic-gate goto clean1;
10070Sstevel@tonic-gate }
10080Sstevel@tonic-gate
10090Sstevel@tonic-gate /* Check arguments before performing message digest. */
10100Sstevel@tonic-gate if (pSigned == NULL) {
10110Sstevel@tonic-gate /* Application asks for the length of the output buffer. */
10120Sstevel@tonic-gate *pulSignedLen = modulus_len;
10130Sstevel@tonic-gate rv = CKR_OK;
10140Sstevel@tonic-gate goto clean1;
10150Sstevel@tonic-gate }
10160Sstevel@tonic-gate
10170Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
10180Sstevel@tonic-gate if (*pulSignedLen < (CK_ULONG)modulus_len) {
10190Sstevel@tonic-gate *pulSignedLen = modulus_len;
10200Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
10210Sstevel@tonic-gate goto clean1;
10220Sstevel@tonic-gate }
10230Sstevel@tonic-gate
10240Sstevel@tonic-gate if (Final) {
10250Sstevel@tonic-gate rv = soft_digest_final(session_p, hash, &hash_len);
10260Sstevel@tonic-gate } else {
10270Sstevel@tonic-gate rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
10280Sstevel@tonic-gate }
10290Sstevel@tonic-gate
10300Sstevel@tonic-gate if (rv != CKR_OK) {
10310Sstevel@tonic-gate /* free the signature key */
10320Sstevel@tonic-gate soft_cleanup_object(key);
10330Sstevel@tonic-gate free(key);
10340Sstevel@tonic-gate goto clean_exit;
10350Sstevel@tonic-gate }
10360Sstevel@tonic-gate
10370Sstevel@tonic-gate /*
1038872Sizick * Prepare the DER encoding of the DigestInfo value by setting it to:
1039872Sizick * <MECH>_DER_PREFIX || H
10400Sstevel@tonic-gate *
10410Sstevel@tonic-gate * See rsa_impl.c for more details.
10420Sstevel@tonic-gate */
1043676Sizick switch (session_p->digest.mech.mechanism) {
1044676Sizick case CKM_MD5:
10450Sstevel@tonic-gate (void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
10460Sstevel@tonic-gate (void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
10470Sstevel@tonic-gate der_data_len = MD5_DER_PREFIX_Len + hash_len;
1048676Sizick break;
1049676Sizick case CKM_SHA_1:
1050872Sizick der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
1051872Sizick &der_prefix);
1052872Sizick (void) memcpy(der_data, der_prefix, der_len);
1053872Sizick (void) memcpy(der_data + der_len, hash, hash_len);
1054872Sizick der_data_len = der_len + hash_len;
1055676Sizick break;
1056676Sizick case CKM_SHA256:
1057676Sizick (void) memcpy(der_data, SHA256_DER_PREFIX,
1058676Sizick SHA2_DER_PREFIX_Len);
1059676Sizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1060676Sizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1061676Sizick break;
1062676Sizick case CKM_SHA384:
1063676Sizick (void) memcpy(der_data, SHA384_DER_PREFIX,
1064676Sizick SHA2_DER_PREFIX_Len);
1065676Sizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1066676Sizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1067676Sizick break;
1068676Sizick case CKM_SHA512:
1069676Sizick (void) memcpy(der_data, SHA512_DER_PREFIX,
1070676Sizick SHA2_DER_PREFIX_Len);
1071676Sizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1072676Sizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1073676Sizick break;
10740Sstevel@tonic-gate }
10750Sstevel@tonic-gate
10760Sstevel@tonic-gate /*
10770Sstevel@tonic-gate * Now, we are ready to sign the DER_ENCODED data
10780Sstevel@tonic-gate * soft_rsa_sign_common() will free the signature key.
10790Sstevel@tonic-gate */
10800Sstevel@tonic-gate rv = soft_rsa_sign_common(session_p, der_data, der_data_len,
10810Sstevel@tonic-gate pSigned, pulSignedLen, mechanism);
10820Sstevel@tonic-gate
10830Sstevel@tonic-gate clean_exit:
10840Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
10850Sstevel@tonic-gate /* soft_digest_common() has freed the digest context */
10860Sstevel@tonic-gate session_p->digest.flags = 0;
10870Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
10880Sstevel@tonic-gate
10890Sstevel@tonic-gate clean1:
10900Sstevel@tonic-gate return (rv);
10910Sstevel@tonic-gate }
10920Sstevel@tonic-gate
10930Sstevel@tonic-gate
10940Sstevel@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)10950Sstevel@tonic-gate soft_rsa_digest_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
10960Sstevel@tonic-gate CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
10970Sstevel@tonic-gate CK_ULONG ulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
10980Sstevel@tonic-gate {
10990Sstevel@tonic-gate
11000Sstevel@tonic-gate CK_RV rv = CKR_OK;
1101676Sizick CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space for all mechs */
1102676Sizick CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
1103676Sizick CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
11040Sstevel@tonic-gate CK_ULONG der_data_len;
11050Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
11060Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
1107872Sizick CK_ULONG der_len;
1108872Sizick CK_BYTE_PTR der_prefix;
11090Sstevel@tonic-gate
11100Sstevel@tonic-gate if (Final) {
11110Sstevel@tonic-gate rv = soft_digest_final(session_p, hash, &hash_len);
11120Sstevel@tonic-gate } else {
11130Sstevel@tonic-gate rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
11140Sstevel@tonic-gate }
11150Sstevel@tonic-gate
11160Sstevel@tonic-gate if (rv != CKR_OK) {
11170Sstevel@tonic-gate /* free the verification key */
11180Sstevel@tonic-gate soft_cleanup_object(key);
11190Sstevel@tonic-gate free(key);
11200Sstevel@tonic-gate goto clean_exit;
11210Sstevel@tonic-gate }
11220Sstevel@tonic-gate
11230Sstevel@tonic-gate /*
11240Sstevel@tonic-gate * Prepare the DER encoding of the DigestInfo value as follows:
11250Sstevel@tonic-gate * MD5: MD5_DER_PREFIX || H
11260Sstevel@tonic-gate * SHA-1: SHA1_DER_PREFIX || H
1127676Sizick * SHA2: SHA2_DER_PREFIX || H
11280Sstevel@tonic-gate *
11290Sstevel@tonic-gate * See rsa_impl.c for more details.
11300Sstevel@tonic-gate */
1131676Sizick switch (session_p->digest.mech.mechanism) {
1132676Sizick case CKM_MD5:
11330Sstevel@tonic-gate (void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
11340Sstevel@tonic-gate (void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
11350Sstevel@tonic-gate der_data_len = MD5_DER_PREFIX_Len + hash_len;
1136676Sizick break;
1137676Sizick case CKM_SHA_1:
1138872Sizick der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
1139872Sizick &der_prefix);
1140872Sizick (void) memcpy(der_data, der_prefix, der_len);
1141872Sizick (void) memcpy(der_data + der_len, hash, hash_len);
1142872Sizick der_data_len = der_len + hash_len;
1143676Sizick break;
1144676Sizick case CKM_SHA256:
1145676Sizick (void) memcpy(der_data, SHA256_DER_PREFIX,
1146676Sizick SHA2_DER_PREFIX_Len);
1147676Sizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1148676Sizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1149676Sizick break;
1150676Sizick case CKM_SHA384:
1151676Sizick (void) memcpy(der_data, SHA384_DER_PREFIX,
1152676Sizick SHA2_DER_PREFIX_Len);
1153676Sizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1154676Sizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1155676Sizick break;
1156676Sizick case CKM_SHA512:
1157676Sizick (void) memcpy(der_data, SHA512_DER_PREFIX,
1158676Sizick SHA2_DER_PREFIX_Len);
1159676Sizick (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1160676Sizick der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1161676Sizick break;
11620Sstevel@tonic-gate }
11630Sstevel@tonic-gate
11640Sstevel@tonic-gate /*
11650Sstevel@tonic-gate * Now, we are ready to verify the DER_ENCODED data using signature.
11660Sstevel@tonic-gate * soft_rsa_verify_common() will free the verification key.
11670Sstevel@tonic-gate */
11680Sstevel@tonic-gate rv = soft_rsa_verify_common(session_p, der_data, der_data_len,
11690Sstevel@tonic-gate pSigned, ulSignedLen, mechanism);
11700Sstevel@tonic-gate
11710Sstevel@tonic-gate clean_exit:
11720Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
11730Sstevel@tonic-gate /* soft_digest_common() has freed the digest context */
11740Sstevel@tonic-gate session_p->digest.flags = 0;
11750Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
11760Sstevel@tonic-gate
11770Sstevel@tonic-gate return (rv);
11780Sstevel@tonic-gate
11790Sstevel@tonic-gate }
11800Sstevel@tonic-gate
11810Sstevel@tonic-gate
11820Sstevel@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)11830Sstevel@tonic-gate soft_rsa_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
11840Sstevel@tonic-gate CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
11850Sstevel@tonic-gate {
11860Sstevel@tonic-gate
11870Sstevel@tonic-gate CK_RV rv = CKR_OK;
11880Sstevel@tonic-gate soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
11890Sstevel@tonic-gate CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
11900Sstevel@tonic-gate soft_object_t *key = rsa_ctx->key;
11910Sstevel@tonic-gate uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
11920Sstevel@tonic-gate uint32_t modulus_len = sizeof (modulus);
11930Sstevel@tonic-gate CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
11940Sstevel@tonic-gate
11957260Smcpowers rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
11960Sstevel@tonic-gate if (rv != CKR_OK) {
11970Sstevel@tonic-gate goto clean_exit;
11980Sstevel@tonic-gate }
11990Sstevel@tonic-gate
12000Sstevel@tonic-gate if (ulSignatureLen != (CK_ULONG)modulus_len) {
12010Sstevel@tonic-gate rv = CKR_SIGNATURE_LEN_RANGE;
12020Sstevel@tonic-gate goto clean_exit;
12030Sstevel@tonic-gate }
12040Sstevel@tonic-gate
12050Sstevel@tonic-gate /*
12060Sstevel@tonic-gate * Perform RSA decryption with the signer's RSA public key
12070Sstevel@tonic-gate * for verification process.
12080Sstevel@tonic-gate */
12090Sstevel@tonic-gate rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
12100Sstevel@tonic-gate if (rv == CKR_OK) {
12110Sstevel@tonic-gate switch (mechanism) {
12120Sstevel@tonic-gate
12130Sstevel@tonic-gate case CKM_RSA_PKCS:
12140Sstevel@tonic-gate {
12150Sstevel@tonic-gate /*
12160Sstevel@tonic-gate * Strip off the encoded padding bytes in front of the
12170Sstevel@tonic-gate * recovered data.
12180Sstevel@tonic-gate */
1219*12573SDina.Nimeh@Sun.COM size_t data_len = modulus_len;
12200Sstevel@tonic-gate
1221*12573SDina.Nimeh@Sun.COM rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
12220Sstevel@tonic-gate if (rv != CKR_OK) {
12230Sstevel@tonic-gate goto clean_exit;
12240Sstevel@tonic-gate }
12250Sstevel@tonic-gate
12260Sstevel@tonic-gate /*
12270Sstevel@tonic-gate * If application asks for the length of the output
12280Sstevel@tonic-gate * buffer?
12290Sstevel@tonic-gate */
12300Sstevel@tonic-gate if (pData == NULL) {
12310Sstevel@tonic-gate *pulDataLen = data_len;
12320Sstevel@tonic-gate rv = CKR_OK;
12330Sstevel@tonic-gate goto clean1;
12340Sstevel@tonic-gate }
12350Sstevel@tonic-gate
12360Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
12370Sstevel@tonic-gate if (*pulDataLen < (CK_ULONG)data_len) {
12380Sstevel@tonic-gate *pulDataLen = data_len;
12390Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
12400Sstevel@tonic-gate goto clean1;
12410Sstevel@tonic-gate }
12420Sstevel@tonic-gate
12430Sstevel@tonic-gate (void) memcpy(pData,
12440Sstevel@tonic-gate &plain_data[modulus_len - data_len], data_len);
12450Sstevel@tonic-gate *pulDataLen = data_len;
12460Sstevel@tonic-gate
12470Sstevel@tonic-gate break;
12480Sstevel@tonic-gate }
12490Sstevel@tonic-gate
12500Sstevel@tonic-gate case CKM_RSA_X_509:
12510Sstevel@tonic-gate /*
12520Sstevel@tonic-gate * If application asks for the length of the output
12530Sstevel@tonic-gate * buffer?
12540Sstevel@tonic-gate */
12550Sstevel@tonic-gate if (pData == NULL) {
12560Sstevel@tonic-gate *pulDataLen = modulus_len;
12570Sstevel@tonic-gate rv = CKR_OK;
12580Sstevel@tonic-gate goto clean1;
12590Sstevel@tonic-gate }
12600Sstevel@tonic-gate
12610Sstevel@tonic-gate /* Is the application-supplied buffer large enough? */
12620Sstevel@tonic-gate if (*pulDataLen < (CK_ULONG)modulus_len) {
12630Sstevel@tonic-gate *pulDataLen = modulus_len;
12640Sstevel@tonic-gate rv = CKR_BUFFER_TOO_SMALL;
12650Sstevel@tonic-gate goto clean1;
12660Sstevel@tonic-gate }
12670Sstevel@tonic-gate
12680Sstevel@tonic-gate (void) memcpy(pData, plain_data, modulus_len);
12690Sstevel@tonic-gate *pulDataLen = modulus_len;
12700Sstevel@tonic-gate
12710Sstevel@tonic-gate break;
12720Sstevel@tonic-gate }
12730Sstevel@tonic-gate }
12740Sstevel@tonic-gate
12750Sstevel@tonic-gate clean_exit:
12760Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex);
12770Sstevel@tonic-gate free(session_p->verify.context);
12780Sstevel@tonic-gate session_p->verify.context = NULL;
12790Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex);
12800Sstevel@tonic-gate soft_cleanup_object(key);
12810Sstevel@tonic-gate free(key);
12820Sstevel@tonic-gate
12830Sstevel@tonic-gate clean1:
12840Sstevel@tonic-gate return (rv);
12850Sstevel@tonic-gate }
1286