dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softRSA.c
blobd83dcd812f413c35a4bff8cd6633706fc65928a8
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <pthread.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <sys/types.h>
31 #include <security/cryptoki.h>
32 #include <cryptoutil.h>
33 #include "softGlobal.h"
34 #include "softSession.h"
35 #include "softObject.h"
36 #include "softOps.h"
37 #include "softRSA.h"
38 #include "softMAC.h"
39 #include "softCrypt.h"
41 CK_RV
42 soft_rsa_encrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
43 CK_BYTE_PTR out, int realpublic)
46 CK_RV rv = CKR_OK;
48 uchar_t expo[MAX_KEY_ATTR_BUFLEN];
49 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
50 uint32_t expo_len = sizeof (expo);
51 uint32_t modulus_len = sizeof (modulus);
52 RSAbytekey k;
54 if (realpublic) {
55 rv = soft_get_public_value(key, CKA_PUBLIC_EXPONENT, expo,
56 &expo_len);
57 if (rv != CKR_OK) {
58 goto clean1;
60 } else {
61 rv = soft_get_private_value(key, CKA_PRIVATE_EXPONENT, expo,
62 &expo_len);
63 if (rv != CKR_OK) {
64 goto clean1;
68 rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
69 if (rv != CKR_OK) {
70 goto clean1;
73 k.modulus = modulus;
74 k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
75 k.pubexpo = expo;
76 k.pubexpo_bytes = expo_len;
77 k.rfunc = NULL;
79 rv = rsa_encrypt(&k, in, in_len, out);
81 clean1:
83 return (rv);
87 CK_RV
88 soft_rsa_decrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
89 CK_BYTE_PTR out)
92 CK_RV rv = CKR_OK;
94 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
95 uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
96 uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
97 uchar_t expo1[MAX_KEY_ATTR_BUFLEN];
98 uchar_t expo2[MAX_KEY_ATTR_BUFLEN];
99 uchar_t coef[MAX_KEY_ATTR_BUFLEN];
100 uint32_t modulus_len = sizeof (modulus);
101 uint32_t prime1_len = sizeof (prime1);
102 uint32_t prime2_len = sizeof (prime2);
103 uint32_t expo1_len = sizeof (expo1);
104 uint32_t expo2_len = sizeof (expo2);
105 uint32_t coef_len = sizeof (coef);
106 RSAbytekey k;
108 rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
109 if (rv != CKR_OK) {
110 goto clean1;
113 rv = soft_get_private_value(key, CKA_PRIME_1, prime1, &prime1_len);
115 if ((prime1_len == 0) && (rv == CKR_OK)) {
116 rv = soft_rsa_encrypt(key, in, in_len, out, 0);
117 goto clean1;
118 } else {
119 if (rv != CKR_OK)
120 goto clean1;
123 rv = soft_get_private_value(key, CKA_PRIME_2, prime2, &prime2_len);
125 if ((prime2_len == 0) && (rv == CKR_OK)) {
126 rv = soft_rsa_encrypt(key, in, in_len, out, 0);
127 goto clean1;
128 } else {
129 if (rv != CKR_OK)
130 goto clean1;
133 rv = soft_get_private_value(key, CKA_EXPONENT_1, expo1, &expo1_len);
135 if ((expo1_len == 0) && (rv == CKR_OK)) {
136 rv = soft_rsa_encrypt(key, in, in_len, out, 0);
137 goto clean1;
138 } else {
139 if (rv != CKR_OK)
140 goto clean1;
143 rv = soft_get_private_value(key, CKA_EXPONENT_2, expo2, &expo2_len);
145 if ((expo2_len == 0) && (rv == CKR_OK)) {
146 rv = soft_rsa_encrypt(key, in, in_len, out, 0);
147 goto clean1;
148 } else {
149 if (rv != CKR_OK)
150 goto clean1;
153 rv = soft_get_private_value(key, CKA_COEFFICIENT, coef, &coef_len);
155 if ((coef_len == 0) && (rv == CKR_OK)) {
156 rv = soft_rsa_encrypt(key, in, in_len, out, 0);
157 goto clean1;
158 } else {
159 if (rv != CKR_OK)
160 goto clean1;
163 k.modulus = modulus;
164 k.modulus_bits = CRYPTO_BYTES2BITS(modulus_len);
165 k.prime1 = prime1;
166 k.prime1_bytes = prime1_len;
167 k.prime2 = prime2;
168 k.prime2_bytes = prime2_len;
169 k.expo1 = expo1;
170 k.expo1_bytes = expo1_len;
171 k.expo2 = expo2;
172 k.expo2_bytes = expo2_len;
173 k.coeff = coef;
174 k.coeff_bytes = coef_len;
175 k.rfunc = NULL;
177 rv = rsa_decrypt(&k, in, in_len, out);
179 clean1:
181 return (rv);
185 * Allocate a RSA context for the active encryption or decryption operation.
186 * This function is called without the session lock held.
188 CK_RV
189 soft_rsa_crypt_init_common(soft_session_t *session_p,
190 CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
191 boolean_t encrypt)
194 soft_rsa_ctx_t *rsa_ctx;
195 soft_object_t *tmp_key = NULL;
196 CK_RV rv;
198 rsa_ctx = calloc(1, sizeof (soft_rsa_ctx_t));
199 if (rsa_ctx == NULL) {
200 return (CKR_HOST_MEMORY);
204 * Make a copy of the encryption or decryption key, and save it
205 * in the RSA crypto context since it will be used later for
206 * encryption/decryption. We don't want to hold any object reference
207 * on this original key while doing encryption/decryption.
209 (void) pthread_mutex_lock(&key_p->object_mutex);
210 rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
211 NULL);
213 if ((rv != CKR_OK) || (tmp_key == NULL)) {
214 /* Most likely we ran out of space. */
215 (void) pthread_mutex_unlock(&key_p->object_mutex);
216 free(rsa_ctx);
217 return (rv);
220 /* No need to hold the lock on the old object. */
221 (void) pthread_mutex_unlock(&key_p->object_mutex);
222 rsa_ctx->key = tmp_key;
224 (void) pthread_mutex_lock(&session_p->session_mutex);
225 if (encrypt) {
226 /* Called by C_EncryptInit. */
227 session_p->encrypt.context = rsa_ctx;
228 session_p->encrypt.mech.mechanism = pMechanism->mechanism;
229 } else {
230 /* Called by C_DecryptInit. */
231 session_p->decrypt.context = rsa_ctx;
232 session_p->decrypt.mech.mechanism = pMechanism->mechanism;
234 (void) pthread_mutex_unlock(&session_p->session_mutex);
236 return (CKR_OK);
239 CK_RV
240 soft_rsa_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
241 CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
242 CK_ULONG_PTR pulEncryptedLen, CK_MECHANISM_TYPE mechanism)
245 soft_rsa_ctx_t *rsa_ctx = session_p->encrypt.context;
246 soft_object_t *key = rsa_ctx->key;
247 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
248 uint32_t modulus_len = sizeof (modulus);
249 CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
250 CK_BYTE cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES];
251 CK_RV rv = CKR_OK;
253 rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
254 if (rv != CKR_OK) {
255 goto clean_exit;
258 if (pEncrypted == NULL) {
260 * Application asks for the length of the output buffer
261 * to hold the ciphertext.
263 *pulEncryptedLen = modulus_len;
264 rv = CKR_OK;
265 goto clean1;
268 if (mechanism == CKM_RSA_PKCS) {
270 * Input data length needs to be <=
271 * modulus length-MIN_PKCS1_PADLEN.
273 if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
274 *pulEncryptedLen = modulus_len;
275 rv = CKR_DATA_LEN_RANGE;
276 goto clean_exit;
278 } else {
279 /* Input data length needs to be <= modulus length. */
280 if (ulDataLen > (CK_ULONG)modulus_len) {
281 *pulEncryptedLen = modulus_len;
282 rv = CKR_DATA_LEN_RANGE;
283 goto clean_exit;
287 /* Is the application-supplied buffer large enough? */
288 if (*pulEncryptedLen < (CK_ULONG)modulus_len) {
289 *pulEncryptedLen = modulus_len;
290 rv = CKR_BUFFER_TOO_SMALL;
291 goto clean1;
294 if (mechanism == CKM_RSA_PKCS) {
296 * Add PKCS padding to the input data to format a block
297 * type "02" encryption block.
299 rv = pkcs1_encode(PKCS1_ENCRYPT, pData, ulDataLen, plain_data,
300 modulus_len);
302 if (rv != CKR_OK)
303 goto clean_exit;
304 } else {
305 /* Pad zeros for the leading bytes of the input data. */
306 (void) memset(plain_data, 0x0, modulus_len - ulDataLen);
307 (void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
308 ulDataLen);
311 rv = soft_rsa_encrypt(key, plain_data, modulus_len, cipher_data, 1);
312 if (rv == CKR_OK) {
313 (void) memcpy(pEncrypted, cipher_data, modulus_len);
314 *pulEncryptedLen = modulus_len;
317 clean_exit:
318 (void) pthread_mutex_lock(&session_p->session_mutex);
319 free(session_p->encrypt.context);
320 session_p->encrypt.context = NULL;
321 (void) pthread_mutex_unlock(&session_p->session_mutex);
322 soft_cleanup_object(key);
323 free(key);
324 clean1:
325 return (rv);
329 CK_RV
330 soft_rsa_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
331 CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
332 CK_ULONG_PTR pulDataLen, CK_MECHANISM_TYPE mechanism)
335 soft_rsa_ctx_t *rsa_ctx = session_p->decrypt.context;
336 soft_object_t *key = rsa_ctx->key;
337 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
338 uint32_t modulus_len = sizeof (modulus);
339 CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
340 CK_RV rv = CKR_OK;
342 rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
343 if (rv != CKR_OK) {
344 goto clean_exit;
347 if (ulEncryptedLen != (CK_ULONG)modulus_len) {
348 rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
349 goto clean_exit;
352 if (pData == NULL) {
354 * Application asks for the length of the output buffer
355 * to hold the recovered data.
357 *pulDataLen = modulus_len;
358 rv = CKR_OK;
359 goto clean1;
362 if (mechanism == CKM_RSA_X_509) {
363 if (*pulDataLen < (CK_ULONG)modulus_len) {
364 *pulDataLen = modulus_len;
365 rv = CKR_BUFFER_TOO_SMALL;
366 goto clean1;
370 rv = soft_rsa_decrypt(key, pEncrypted, modulus_len, plain_data);
371 if (rv != CKR_OK) {
372 goto clean_exit;
375 if (mechanism == CKM_RSA_PKCS) {
376 size_t plain_len = modulus_len;
377 size_t num_padding;
379 /* Strip off the PKCS block formatting data. */
380 rv = pkcs1_decode(PKCS1_DECRYPT, plain_data, &plain_len);
381 if (rv != CKR_OK)
382 goto clean_exit;
384 num_padding = modulus_len - plain_len;
385 if (ulEncryptedLen - num_padding > *pulDataLen) {
386 *pulDataLen = plain_len;
387 rv = CKR_BUFFER_TOO_SMALL;
388 goto clean1;
391 (void) memcpy(pData, &plain_data[num_padding], plain_len);
392 *pulDataLen = plain_len;
393 } else {
394 (void) memcpy(pData, plain_data, modulus_len);
395 *pulDataLen = modulus_len;
398 clean_exit:
399 (void) pthread_mutex_lock(&session_p->session_mutex);
400 free(session_p->decrypt.context);
401 session_p->decrypt.context = NULL;
402 (void) pthread_mutex_unlock(&session_p->session_mutex);
403 soft_cleanup_object(key);
404 free(key);
406 clean1:
407 return (rv);
411 * Allocate a RSA context for the active sign or verify operation.
412 * This function is called without the session lock held.
414 CK_RV
415 soft_rsa_sign_verify_init_common(soft_session_t *session_p,
416 CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
417 boolean_t sign)
419 CK_RV rv = CKR_OK;
420 soft_rsa_ctx_t *rsa_ctx;
421 CK_MECHANISM digest_mech;
422 soft_object_t *tmp_key = NULL;
424 if (sign) {
425 if ((key_p->class != CKO_PRIVATE_KEY) ||
426 (key_p->key_type != CKK_RSA))
427 return (CKR_KEY_TYPE_INCONSISTENT);
428 } else {
429 if ((key_p->class != CKO_PUBLIC_KEY) ||
430 (key_p->key_type != CKK_RSA))
431 return (CKR_KEY_TYPE_INCONSISTENT);
434 switch (pMechanism->mechanism) {
435 case CKM_MD5_RSA_PKCS:
436 digest_mech.mechanism = CKM_MD5;
437 rv = soft_digest_init_internal(session_p, &digest_mech);
438 if (rv != CKR_OK)
439 return (rv);
440 break;
442 case CKM_SHA1_RSA_PKCS:
443 digest_mech.mechanism = CKM_SHA_1;
444 digest_mech.pParameter = pMechanism->pParameter;
445 digest_mech.ulParameterLen = pMechanism->ulParameterLen;
446 rv = soft_digest_init_internal(session_p, &digest_mech);
447 if (rv != CKR_OK)
448 return (rv);
449 break;
451 case CKM_SHA256_RSA_PKCS:
452 digest_mech.mechanism = CKM_SHA256;
453 rv = soft_digest_init_internal(session_p, &digest_mech);
454 if (rv != CKR_OK)
455 return (rv);
456 break;
458 case CKM_SHA384_RSA_PKCS:
459 digest_mech.mechanism = CKM_SHA384;
460 rv = soft_digest_init_internal(session_p, &digest_mech);
461 if (rv != CKR_OK)
462 return (rv);
463 break;
465 case CKM_SHA512_RSA_PKCS:
466 digest_mech.mechanism = CKM_SHA512;
467 rv = soft_digest_init_internal(session_p, &digest_mech);
468 if (rv != CKR_OK)
469 return (rv);
470 break;
473 rsa_ctx = malloc(sizeof (soft_rsa_ctx_t));
475 if (rsa_ctx == NULL) {
476 rv = CKR_HOST_MEMORY;
477 goto clean_exit;
480 (void) pthread_mutex_lock(&key_p->object_mutex);
481 rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
482 NULL);
484 if ((rv != CKR_OK) || (tmp_key == NULL)) {
485 /* Most likely we ran out of space. */
486 (void) pthread_mutex_unlock(&key_p->object_mutex);
487 free(rsa_ctx);
488 goto clean_exit;
491 /* No need to hold the lock on the old object. */
492 (void) pthread_mutex_unlock(&key_p->object_mutex);
493 rsa_ctx->key = tmp_key;
495 (void) pthread_mutex_lock(&session_p->session_mutex);
497 if (sign) {
498 session_p->sign.context = rsa_ctx;
499 session_p->sign.mech.mechanism = pMechanism->mechanism;
500 } else {
501 session_p->verify.context = rsa_ctx;
502 session_p->verify.mech.mechanism = pMechanism->mechanism;
505 (void) pthread_mutex_unlock(&session_p->session_mutex);
507 return (CKR_OK);
509 clean_exit:
510 (void) pthread_mutex_lock(&session_p->session_mutex);
511 if (session_p->digest.context != NULL) {
512 free(session_p->digest.context);
513 session_p->digest.context = NULL;
514 session_p->digest.flags = 0;
516 (void) pthread_mutex_unlock(&session_p->session_mutex);
517 return (rv);
522 CK_RV
523 soft_rsa_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
524 CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
525 CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism)
528 CK_RV rv = CKR_OK;
529 soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
530 soft_object_t *key = rsa_ctx->key;
531 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
532 uint32_t modulus_len = sizeof (modulus);
533 CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
534 CK_BYTE signed_data[MAX_RSA_KEYLENGTH_IN_BYTES];
536 rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
537 if (rv != CKR_OK) {
538 goto clean_exit;
541 if (pSigned == NULL) {
542 /* Application asks for the length of the output buffer. */
543 *pulSignedLen = modulus_len;
544 rv = CKR_OK;
545 goto clean1;
548 switch (mechanism) {
550 case CKM_RSA_PKCS:
553 * Input data length needs to be <=
554 * modulus length-MIN_PKCS1_PADLEN.
556 if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
557 *pulSignedLen = modulus_len;
558 rv = CKR_DATA_LEN_RANGE;
559 goto clean_exit;
561 break;
563 case CKM_RSA_X_509:
565 /* Input data length needs to be <= modulus length. */
566 if (ulDataLen > (CK_ULONG)modulus_len) {
567 *pulSignedLen = modulus_len;
568 rv = CKR_DATA_LEN_RANGE;
569 goto clean_exit;
571 break;
574 /* Is the application-supplied buffer large enough? */
575 if (*pulSignedLen < (CK_ULONG)modulus_len) {
576 *pulSignedLen = modulus_len;
577 rv = CKR_BUFFER_TOO_SMALL;
578 goto clean1;
581 switch (mechanism) {
583 case CKM_RSA_PKCS:
584 case CKM_MD5_RSA_PKCS:
585 case CKM_SHA1_RSA_PKCS:
586 case CKM_SHA256_RSA_PKCS:
587 case CKM_SHA384_RSA_PKCS:
588 case CKM_SHA512_RSA_PKCS:
590 * Add PKCS padding to the input data to format a block
591 * type "01" encryption block.
593 rv = pkcs1_encode(PKCS1_SIGN, pData, ulDataLen, plain_data,
594 modulus_len);
596 if (rv != CKR_OK) {
597 goto clean_exit;
599 break;
601 case CKM_RSA_X_509:
603 /* Pad zeros for the leading bytes of the input data. */
604 (void) memset(plain_data, 0x0, modulus_len - ulDataLen);
605 (void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
606 ulDataLen);
607 break;
611 * Perform RSA encryption with the signer's RSA private key
612 * for signature process.
614 rv = soft_rsa_decrypt(key, plain_data, modulus_len, signed_data);
616 if (rv == CKR_OK) {
617 (void) memcpy(pSigned, signed_data, modulus_len);
618 *pulSignedLen = modulus_len;
621 clean_exit:
622 (void) pthread_mutex_lock(&session_p->session_mutex);
623 free(session_p->sign.context);
624 session_p->sign.context = NULL;
625 if (session_p->digest.context != NULL) {
626 free(session_p->digest.context);
627 session_p->digest.context = NULL;
628 session_p->digest.flags = 0;
630 (void) pthread_mutex_unlock(&session_p->session_mutex);
631 soft_cleanup_object(key);
632 free(key);
634 clean1:
635 return (rv);
639 CK_RV
640 soft_rsa_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
641 CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
642 CK_ULONG ulSignatureLen, CK_MECHANISM_TYPE mechanism)
645 CK_RV rv = CKR_OK;
646 soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
647 soft_object_t *key = rsa_ctx->key;
648 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
649 uint32_t modulus_len = sizeof (modulus);
650 CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
652 rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
653 if (rv != CKR_OK) {
654 goto clean_exit;
657 if (ulDataLen == 0) {
658 rv = CKR_DATA_LEN_RANGE;
659 goto clean_exit;
662 if (ulSignatureLen != (CK_ULONG)modulus_len) {
663 rv = CKR_SIGNATURE_LEN_RANGE;
664 goto clean_exit;
668 * Perform RSA decryption with the signer's RSA public key
669 * for verification process.
671 rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
672 if (rv == CKR_OK) {
673 switch (mechanism) {
675 case CKM_RSA_PKCS:
676 case CKM_MD5_RSA_PKCS:
677 case CKM_SHA1_RSA_PKCS:
678 case CKM_SHA256_RSA_PKCS:
679 case CKM_SHA384_RSA_PKCS:
680 case CKM_SHA512_RSA_PKCS:
683 * Strip off the encoded padding bytes in front of the
684 * recovered data, then compare the recovered data with
685 * the original data.
687 size_t data_len = modulus_len;
689 rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
690 if (rv != CKR_OK) {
691 goto clean_exit;
694 if ((CK_ULONG)data_len != ulDataLen) {
695 rv = CKR_DATA_LEN_RANGE;
696 goto clean_exit;
697 } else if (memcmp(pData,
698 &plain_data[modulus_len - data_len],
699 ulDataLen) != 0) {
700 rv = CKR_SIGNATURE_INVALID;
701 goto clean_exit;
703 break;
706 case CKM_RSA_X_509:
708 * Strip off the encoded padding bytes in front of the
709 * recovered plain_data, then compare the input data
710 * with the recovered data.
712 if (memcmp(pData,
713 plain_data + ulSignatureLen - ulDataLen,
714 ulDataLen) != 0) {
715 rv = CKR_SIGNATURE_INVALID;
716 goto clean_exit;
718 break;
722 if (rv == CKR_DATA_LEN_RANGE) {
723 if ((mechanism == CKM_MD5_RSA_PKCS) ||
724 (mechanism == CKM_SHA1_RSA_PKCS) ||
725 (mechanism == CKM_SHA256_RSA_PKCS) ||
726 (mechanism == CKM_SHA384_RSA_PKCS) ||
727 (mechanism == CKM_SHA512_RSA_PKCS))
728 rv = CKR_SIGNATURE_INVALID;
731 clean_exit:
732 (void) pthread_mutex_lock(&session_p->session_mutex);
733 free(session_p->verify.context);
734 session_p->verify.context = NULL;
735 if (session_p->digest.context != NULL) {
736 free(session_p->digest.context);
737 session_p->digest.context = NULL;
738 session_p->digest.flags = 0;
740 (void) pthread_mutex_unlock(&session_p->session_mutex);
741 soft_cleanup_object(key);
742 free(key);
743 return (rv);
746 CK_RV
747 soft_genRSAkey_set_attribute(soft_object_t *key, CK_ATTRIBUTE_TYPE type,
748 uchar_t *buf, uint32_t buflen, boolean_t public)
750 CK_RV rv = CKR_OK;
751 biginteger_t *dst = NULL;
752 biginteger_t src;
754 switch (type) {
756 case CKA_MODULUS:
758 if (public)
759 dst = OBJ_PUB_RSA_MOD(key);
760 else
761 dst = OBJ_PRI_RSA_MOD(key);
762 break;
764 case CKA_PUBLIC_EXPONENT:
766 if (public)
767 dst = OBJ_PUB_RSA_PUBEXPO(key);
768 else
769 dst = OBJ_PRI_RSA_PUBEXPO(key);
770 break;
772 case CKA_PRIVATE_EXPONENT:
774 dst = OBJ_PRI_RSA_PRIEXPO(key);
775 break;
777 case CKA_PRIME_1:
779 dst = OBJ_PRI_RSA_PRIME1(key);
780 break;
782 case CKA_PRIME_2:
784 dst = OBJ_PRI_RSA_PRIME2(key);
785 break;
787 case CKA_EXPONENT_1:
789 dst = OBJ_PRI_RSA_EXPO1(key);
790 break;
792 case CKA_EXPONENT_2:
794 dst = OBJ_PRI_RSA_EXPO2(key);
795 break;
797 case CKA_COEFFICIENT:
799 dst = OBJ_PRI_RSA_COEF(key);
800 break;
803 /* Note: no explanation found for why this is needed */
804 while (buf[0] == 0) { /* remove proceeding 0x00 */
805 buf++;
806 buflen--;
809 if ((rv = dup_bigint_attr(&src, buf, buflen)) != CKR_OK)
810 goto cleanexit;
812 /* Copy the attribute in the key object. */
813 copy_bigint_attr(&src, dst);
815 cleanexit:
816 return (rv);
821 CK_RV
822 soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
824 CK_RV rv = CKR_OK;
825 CK_ATTRIBUTE template;
826 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
827 uint32_t modulus_len;
828 uchar_t pub_expo[MAX_KEY_ATTR_BUFLEN];
829 uint32_t pub_expo_len = sizeof (pub_expo);
830 uchar_t private_exponent[MAX_KEY_ATTR_BUFLEN];
831 uint32_t private_exponent_len = sizeof (private_exponent);
832 uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
833 uint32_t prime1_len = sizeof (prime1);
834 uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
835 uint32_t prime2_len = sizeof (prime2);
836 uchar_t exponent1[MAX_KEY_ATTR_BUFLEN];
837 uint32_t exponent1_len = sizeof (exponent1);
838 uchar_t exponent2[MAX_KEY_ATTR_BUFLEN];
839 uint32_t exponent2_len = sizeof (exponent2);
840 uchar_t coefficient[MAX_KEY_ATTR_BUFLEN];
841 uint32_t coefficient_len = sizeof (coefficient);
842 RSAbytekey k;
844 if ((pubkey == NULL) || (prikey == NULL)) {
845 return (CKR_ARGUMENTS_BAD);
848 template.pValue = malloc(sizeof (CK_ULONG));
849 if (template.pValue == NULL) {
850 return (CKR_HOST_MEMORY);
852 template.ulValueLen = sizeof (CK_ULONG);
854 rv = get_ulong_attr_from_object(OBJ_PUB_RSA_MOD_BITS(pubkey),
855 &template);
856 if (rv != CKR_OK) {
857 free(template.pValue);
858 goto clean0;
861 modulus_len = *((CK_ULONG *)(template.pValue));
863 free(template.pValue);
865 rv = soft_get_public_value(pubkey, CKA_PUBLIC_EXPONENT, pub_expo,
866 &pub_expo_len);
867 if (rv != CKR_OK) {
868 goto clean0;
871 /* Inputs to RSA key pair generation */
872 k.modulus_bits = modulus_len; /* save modulus len in bits */
873 modulus_len = CRYPTO_BITS2BYTES(modulus_len); /* convert to bytes */
874 k.modulus = modulus;
875 k.pubexpo = pub_expo;
876 k.pubexpo_bytes = pub_expo_len;
877 k.rfunc = (IS_TOKEN_OBJECT(pubkey) || IS_TOKEN_OBJECT(prikey)) ?
878 pkcs11_get_random : pkcs11_get_urandom;
880 /* Outputs from RSA key pair generation */
881 k.privexpo = private_exponent;
882 k.privexpo_bytes = private_exponent_len;
883 k.prime1 = prime1;
884 k.prime1_bytes = prime1_len;
885 k.prime2 = prime2;
886 k.prime2_bytes = prime2_len;
887 k.expo1 = exponent1;
888 k.expo1_bytes = exponent1_len;
889 k.expo2 = exponent2;
890 k.expo2_bytes = exponent2_len;
891 k.coeff = coefficient;
892 k.coeff_bytes = coefficient_len;
894 rv = rsa_genkey_pair(&k);
896 if (rv != CKR_OK) {
897 goto clean0;
901 * Add modulus in public template, and add all eight key fields
902 * in private template.
904 if ((rv = soft_genRSAkey_set_attribute(pubkey, CKA_MODULUS,
905 modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_TRUE)) != CKR_OK) {
906 goto clean0;
909 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_MODULUS,
910 modulus, CRYPTO_BITS2BYTES(k.modulus_bits), B_FALSE)) != CKR_OK) {
911 goto clean0;
914 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIVATE_EXPONENT,
915 private_exponent, k.privexpo_bytes, B_FALSE)) != CKR_OK) {
916 goto clean0;
919 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PUBLIC_EXPONENT,
920 pub_expo, k.pubexpo_bytes, B_FALSE)) != CKR_OK) {
921 goto clean0;
924 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_1,
925 prime1, k.prime1_bytes, B_FALSE)) != CKR_OK) {
926 goto clean0;
929 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_PRIME_2,
930 prime2, k.prime2_bytes, B_FALSE)) != CKR_OK) {
931 goto clean0;
934 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_1,
935 exponent1, k.expo1_bytes, B_FALSE)) != CKR_OK) {
936 goto clean0;
939 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_EXPONENT_2,
940 exponent2, k.expo2_bytes, B_FALSE)) != CKR_OK) {
941 goto clean0;
944 if ((rv = soft_genRSAkey_set_attribute(prikey, CKA_COEFFICIENT,
945 coefficient, k.coeff_bytes, B_FALSE)) != CKR_OK) {
946 goto clean0;
949 clean0:
950 return (rv);
954 CK_ULONG
955 get_rsa_sha1_prefix(CK_MECHANISM_PTR mech, CK_BYTE_PTR *prefix) {
956 if (mech->pParameter == NULL) {
957 *prefix = (CK_BYTE *)SHA1_DER_PREFIX;
958 return (SHA1_DER_PREFIX_Len);
961 *prefix = (CK_BYTE *)SHA1_DER_PREFIX_OID;
962 return (SHA1_DER_PREFIX_OID_Len);
965 CK_RV
966 soft_rsa_digest_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
967 CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
968 CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
971 CK_RV rv = CKR_OK;
972 CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space enough for all mechs */
973 CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
974 /* space enough for all mechs */
975 CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
976 CK_ULONG der_data_len;
977 soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
978 soft_object_t *key = rsa_ctx->key;
979 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
980 uint32_t modulus_len = sizeof (modulus);
981 CK_ULONG der_len;
982 CK_BYTE_PTR der_prefix;
984 rv = soft_get_private_value(key, CKA_MODULUS, modulus, &modulus_len);
985 if (rv != CKR_OK) {
986 (void) pthread_mutex_lock(&session_p->session_mutex);
987 free(session_p->digest.context);
988 session_p->digest.context = NULL;
989 session_p->digest.flags = 0;
990 (void) pthread_mutex_unlock(&session_p->session_mutex);
991 soft_cleanup_object(key);
992 free(key);
993 goto clean1;
996 /* Check arguments before performing message digest. */
997 if (pSigned == NULL) {
998 /* Application asks for the length of the output buffer. */
999 *pulSignedLen = modulus_len;
1000 rv = CKR_OK;
1001 goto clean1;
1004 /* Is the application-supplied buffer large enough? */
1005 if (*pulSignedLen < (CK_ULONG)modulus_len) {
1006 *pulSignedLen = modulus_len;
1007 rv = CKR_BUFFER_TOO_SMALL;
1008 goto clean1;
1011 if (Final) {
1012 rv = soft_digest_final(session_p, hash, &hash_len);
1013 } else {
1014 rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
1017 if (rv != CKR_OK) {
1018 /* free the signature key */
1019 soft_cleanup_object(key);
1020 free(key);
1021 goto clean_exit;
1025 * Prepare the DER encoding of the DigestInfo value by setting it to:
1026 * <MECH>_DER_PREFIX || H
1028 * See rsa_impl.c for more details.
1030 switch (session_p->digest.mech.mechanism) {
1031 case CKM_MD5:
1032 (void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
1033 (void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
1034 der_data_len = MD5_DER_PREFIX_Len + hash_len;
1035 break;
1036 case CKM_SHA_1:
1037 der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
1038 &der_prefix);
1039 (void) memcpy(der_data, der_prefix, der_len);
1040 (void) memcpy(der_data + der_len, hash, hash_len);
1041 der_data_len = der_len + hash_len;
1042 break;
1043 case CKM_SHA256:
1044 (void) memcpy(der_data, SHA256_DER_PREFIX,
1045 SHA2_DER_PREFIX_Len);
1046 (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1047 der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1048 break;
1049 case CKM_SHA384:
1050 (void) memcpy(der_data, SHA384_DER_PREFIX,
1051 SHA2_DER_PREFIX_Len);
1052 (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1053 der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1054 break;
1055 case CKM_SHA512:
1056 (void) memcpy(der_data, SHA512_DER_PREFIX,
1057 SHA2_DER_PREFIX_Len);
1058 (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1059 der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1060 break;
1064 * Now, we are ready to sign the DER_ENCODED data
1065 * soft_rsa_sign_common() will free the signature key.
1067 rv = soft_rsa_sign_common(session_p, der_data, der_data_len,
1068 pSigned, pulSignedLen, mechanism);
1070 clean_exit:
1071 (void) pthread_mutex_lock(&session_p->session_mutex);
1072 /* soft_digest_common() has freed the digest context */
1073 session_p->digest.flags = 0;
1074 (void) pthread_mutex_unlock(&session_p->session_mutex);
1076 clean1:
1077 return (rv);
1081 CK_RV
1082 soft_rsa_digest_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1083 CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
1084 CK_ULONG ulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
1087 CK_RV rv = CKR_OK;
1088 CK_BYTE hash[SHA512_DIGEST_LENGTH]; /* space for all mechs */
1089 CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
1090 CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
1091 CK_ULONG der_data_len;
1092 soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
1093 soft_object_t *key = rsa_ctx->key;
1094 CK_ULONG der_len;
1095 CK_BYTE_PTR der_prefix;
1097 if (Final) {
1098 rv = soft_digest_final(session_p, hash, &hash_len);
1099 } else {
1100 rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
1103 if (rv != CKR_OK) {
1104 /* free the verification key */
1105 soft_cleanup_object(key);
1106 free(key);
1107 goto clean_exit;
1111 * Prepare the DER encoding of the DigestInfo value as follows:
1112 * MD5: MD5_DER_PREFIX || H
1113 * SHA-1: SHA1_DER_PREFIX || H
1114 * SHA2: SHA2_DER_PREFIX || H
1116 * See rsa_impl.c for more details.
1118 switch (session_p->digest.mech.mechanism) {
1119 case CKM_MD5:
1120 (void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
1121 (void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
1122 der_data_len = MD5_DER_PREFIX_Len + hash_len;
1123 break;
1124 case CKM_SHA_1:
1125 der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
1126 &der_prefix);
1127 (void) memcpy(der_data, der_prefix, der_len);
1128 (void) memcpy(der_data + der_len, hash, hash_len);
1129 der_data_len = der_len + hash_len;
1130 break;
1131 case CKM_SHA256:
1132 (void) memcpy(der_data, SHA256_DER_PREFIX,
1133 SHA2_DER_PREFIX_Len);
1134 (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1135 der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1136 break;
1137 case CKM_SHA384:
1138 (void) memcpy(der_data, SHA384_DER_PREFIX,
1139 SHA2_DER_PREFIX_Len);
1140 (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1141 der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1142 break;
1143 case CKM_SHA512:
1144 (void) memcpy(der_data, SHA512_DER_PREFIX,
1145 SHA2_DER_PREFIX_Len);
1146 (void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1147 der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1148 break;
1152 * Now, we are ready to verify the DER_ENCODED data using signature.
1153 * soft_rsa_verify_common() will free the verification key.
1155 rv = soft_rsa_verify_common(session_p, der_data, der_data_len,
1156 pSigned, ulSignedLen, mechanism);
1158 clean_exit:
1159 (void) pthread_mutex_lock(&session_p->session_mutex);
1160 /* soft_digest_common() has freed the digest context */
1161 session_p->digest.flags = 0;
1162 (void) pthread_mutex_unlock(&session_p->session_mutex);
1164 return (rv);
1169 CK_RV
1170 soft_rsa_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
1171 CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1174 CK_RV rv = CKR_OK;
1175 soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
1176 CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
1177 soft_object_t *key = rsa_ctx->key;
1178 uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
1179 uint32_t modulus_len = sizeof (modulus);
1180 CK_BYTE plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
1182 rv = soft_get_public_value(key, CKA_MODULUS, modulus, &modulus_len);
1183 if (rv != CKR_OK) {
1184 goto clean_exit;
1187 if (ulSignatureLen != (CK_ULONG)modulus_len) {
1188 rv = CKR_SIGNATURE_LEN_RANGE;
1189 goto clean_exit;
1193 * Perform RSA decryption with the signer's RSA public key
1194 * for verification process.
1196 rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
1197 if (rv == CKR_OK) {
1198 switch (mechanism) {
1200 case CKM_RSA_PKCS:
1203 * Strip off the encoded padding bytes in front of the
1204 * recovered data.
1206 size_t data_len = modulus_len;
1208 rv = pkcs1_decode(PKCS1_VERIFY, plain_data, &data_len);
1209 if (rv != CKR_OK) {
1210 goto clean_exit;
1214 * If application asks for the length of the output
1215 * buffer?
1217 if (pData == NULL) {
1218 *pulDataLen = data_len;
1219 rv = CKR_OK;
1220 goto clean1;
1223 /* Is the application-supplied buffer large enough? */
1224 if (*pulDataLen < (CK_ULONG)data_len) {
1225 *pulDataLen = data_len;
1226 rv = CKR_BUFFER_TOO_SMALL;
1227 goto clean1;
1230 (void) memcpy(pData,
1231 &plain_data[modulus_len - data_len], data_len);
1232 *pulDataLen = data_len;
1234 break;
1237 case CKM_RSA_X_509:
1239 * If application asks for the length of the output
1240 * buffer?
1242 if (pData == NULL) {
1243 *pulDataLen = modulus_len;
1244 rv = CKR_OK;
1245 goto clean1;
1248 /* Is the application-supplied buffer large enough? */
1249 if (*pulDataLen < (CK_ULONG)modulus_len) {
1250 *pulDataLen = modulus_len;
1251 rv = CKR_BUFFER_TOO_SMALL;
1252 goto clean1;
1255 (void) memcpy(pData, plain_data, modulus_len);
1256 *pulDataLen = modulus_len;
1258 break;
1262 clean_exit:
1263 (void) pthread_mutex_lock(&session_p->session_mutex);
1264 free(session_p->verify.context);
1265 session_p->verify.context = NULL;
1266 (void) pthread_mutex_unlock(&session_p->session_mutex);
1267 soft_cleanup_object(key);
1268 free(key);
1270 clean1:
1271 return (rv);