xref: /titanic_50/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c (revision f66d273d14eede3a1bb803a39414588d8f143a98)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <pthread.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <sys/types.h>
34 #include <security/cryptoki.h>
35 #include <bignum.h>
36 #include "softGlobal.h"
37 #include "softSession.h"
38 #include "softObject.h"
39 #include "softOps.h"
40 #include "softRSA.h"
41 #include "softMAC.h"
42 #include "softRandom.h"
43 #include "softCrypt.h"
44 
45 CK_RV
46 soft_rsa_encrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
47     CK_BYTE_PTR out, int realpublic)
48 {
49 
50 	CK_RV rv = CKR_OK;
51 
52 /* EXPORT DELETE START */
53 
54 	uchar_t expo[MAX_KEY_ATTR_BUFLEN];
55 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
56 	uint32_t expo_len = sizeof (expo);
57 	uint32_t modulus_len = sizeof (modulus);
58 	BIGNUM msg;
59 	RSAkey *rsakey;
60 
61 	if (realpublic) {
62 		rv = soft_get_public_attr(key, CKA_PUBLIC_EXPONENT, expo,
63 		    &expo_len);
64 		if (rv != CKR_OK) {
65 			goto clean1;
66 		}
67 	} else {
68 		rv = soft_get_private_attr(key, CKA_PRIVATE_EXPONENT, expo,
69 		    &expo_len);
70 		if (rv != CKR_OK) {
71 			goto clean1;
72 		}
73 	}
74 
75 	rv = soft_get_public_attr(key, CKA_MODULUS, modulus, &modulus_len);
76 	if (rv != CKR_OK) {
77 		goto clean1;
78 	}
79 
80 	if (expo_len > modulus_len) {
81 		rv = CKR_KEY_SIZE_RANGE;
82 		goto clean1;
83 	}
84 
85 	rsakey = calloc(1, sizeof (RSAkey));
86 	if (rsakey == NULL) {
87 		rv = CKR_HOST_MEMORY;
88 		goto clean1;
89 	}
90 
91 	if (RSA_key_init(rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
92 		rv = CKR_HOST_MEMORY;
93 		goto clean4;
94 	}
95 
96 	/* Size for big_init is in (32-bit) words. */
97 	if (big_init(&msg, (in_len + (int)sizeof (uint32_t) - 1) /
98 	    (int)sizeof (uint32_t)) != BIG_OK) {
99 		rv = CKR_HOST_MEMORY;
100 		goto clean5;
101 	}
102 
103 	/* Convert octet string exponent to big integer format. */
104 	bytestring2bignum(&(rsakey->e), expo, expo_len);
105 
106 	/* Convert octet string modulus to big integer format. */
107 	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
108 
109 	/* Convert octet string input data to big integer format. */
110 	bytestring2bignum(&msg, (uchar_t *)in, in_len);
111 
112 	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
113 		rv = CKR_DATA_LEN_RANGE;
114 		goto clean6;
115 	}
116 
117 	/* Perform RSA computation on big integer input data. */
118 	if (big_modexp(&msg, &msg, &(rsakey->e), &(rsakey->n), NULL) !=
119 	    BIG_OK) {
120 		rv = CKR_HOST_MEMORY;
121 		goto clean6;
122 	}
123 
124 	/* Convert the big integer output data to octet string. */
125 	bignum2bytestring((uchar_t *)out, &msg, modulus_len);
126 
127 clean6:
128 	big_finish(&msg);
129 clean5:
130 	RSA_key_finish(rsakey);
131 clean4:
132 	free(rsakey);
133 clean1:
134 
135 /* EXPORT DELETE END */
136 
137 	return (rv);
138 }
139 
140 
141 CK_RV
142 soft_rsa_decrypt(soft_object_t *key, CK_BYTE_PTR in, uint32_t in_len,
143     CK_BYTE_PTR out)
144 {
145 
146 	CK_RV rv = CKR_OK;
147 
148 /* EXPORT DELETE START */
149 
150 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
151 	uchar_t prime1[MAX_KEY_ATTR_BUFLEN];
152 	uchar_t prime2[MAX_KEY_ATTR_BUFLEN];
153 	uchar_t expo1[MAX_KEY_ATTR_BUFLEN];
154 	uchar_t expo2[MAX_KEY_ATTR_BUFLEN];
155 	uchar_t coef[MAX_KEY_ATTR_BUFLEN];
156 	uint32_t modulus_len = sizeof (modulus);
157 	uint32_t prime1_len = sizeof (prime1);
158 	uint32_t prime2_len = sizeof (prime2);
159 	uint32_t expo1_len = sizeof (expo1);
160 	uint32_t expo2_len = sizeof (expo2);
161 	uint32_t coef_len = sizeof (coef);
162 	BIGNUM msg;
163 	RSAkey *rsakey;
164 
165 	rv = soft_get_private_attr(key, CKA_MODULUS, modulus, &modulus_len);
166 	if (rv != CKR_OK) {
167 		goto clean1;
168 	}
169 
170 	rv = soft_get_private_attr(key, CKA_PRIME_1, prime1, &prime1_len);
171 
172 	if ((prime1_len == 0) && (rv == CKR_OK)) {
173 		rv = soft_rsa_encrypt(key, in, in_len, out, 0);
174 		goto clean1;
175 	} else {
176 		if (rv != CKR_OK)
177 			goto clean1;
178 	}
179 
180 	rv = soft_get_private_attr(key, CKA_PRIME_2, prime2, &prime2_len);
181 
182 	if ((prime2_len == 0) && (rv == CKR_OK)) {
183 		rv = soft_rsa_encrypt(key, in, in_len, out, 0);
184 		goto clean1;
185 	} else {
186 		if (rv != CKR_OK)
187 			goto clean1;
188 	}
189 
190 	rv = soft_get_private_attr(key, CKA_EXPONENT_1, expo1, &expo1_len);
191 
192 	if ((expo1_len == 0) && (rv == CKR_OK)) {
193 		rv = soft_rsa_encrypt(key, in, in_len, out, 0);
194 		goto clean1;
195 	} else {
196 		if (rv != CKR_OK)
197 			goto clean1;
198 	}
199 
200 	rv = soft_get_private_attr(key, CKA_EXPONENT_2, expo2, &expo2_len);
201 
202 	if ((expo2_len == 0) && (rv == CKR_OK)) {
203 		rv = soft_rsa_encrypt(key, in, in_len, out, 0);
204 		goto clean1;
205 	} else {
206 		if (rv != CKR_OK)
207 			goto clean1;
208 	}
209 
210 	rv = soft_get_private_attr(key, CKA_COEFFICIENT, coef, &coef_len);
211 
212 	if ((coef_len == 0) && (rv == CKR_OK)) {
213 		rv = soft_rsa_encrypt(key, in, in_len, out, 0);
214 		goto clean1;
215 	} else {
216 		if (rv != CKR_OK)
217 			goto clean1;
218 	}
219 
220 	rsakey = calloc(1, sizeof (RSAkey));
221 	if (rsakey == NULL) {
222 		rv = CKR_HOST_MEMORY;
223 		goto clean1;
224 	}
225 
226 	/* psize and qsize for RSA_key_init is in bits. */
227 	if (RSA_key_init(rsakey, prime2_len * 8, prime1_len * 8) != BIG_OK) {
228 		rv = CKR_HOST_MEMORY;
229 		goto clean8;
230 	}
231 
232 	/* Size for big_init is in (32-bit) words. */
233 	if (big_init(&msg, (in_len + (int)sizeof (uint32_t) - 1) /
234 	    (int)sizeof (uint32_t)) != BIG_OK) {
235 		rv = CKR_HOST_MEMORY;
236 		goto clean9;
237 	}
238 
239 	/* Convert octet string input data to big integer format. */
240 	bytestring2bignum(&msg, (uchar_t *)in, in_len);
241 
242 	/* Convert octet string modulus to big integer format. */
243 	bytestring2bignum(&(rsakey->n), modulus, modulus_len);
244 
245 	if (big_cmp_abs(&msg, &(rsakey->n)) > 0) {
246 		rv = CKR_DATA_LEN_RANGE;
247 		goto clean10;
248 	}
249 
250 	/* Convert the rest of private key attributes to big integer format. */
251 	bytestring2bignum(&(rsakey->dmodpminus1), expo2, expo2_len);
252 	bytestring2bignum(&(rsakey->dmodqminus1), expo1, expo1_len);
253 	bytestring2bignum(&(rsakey->p), prime2, prime2_len);
254 	bytestring2bignum(&(rsakey->q), prime1, prime1_len);
255 	bytestring2bignum(&(rsakey->pinvmodq), coef, coef_len);
256 
257 	if ((big_cmp_abs(&(rsakey->dmodpminus1), &(rsakey->p)) > 0) ||
258 	    (big_cmp_abs(&(rsakey->dmodqminus1), &(rsakey->q)) > 0) ||
259 	    (big_cmp_abs(&(rsakey->pinvmodq), &(rsakey->q)) > 0)) {
260 		rv = CKR_KEY_SIZE_RANGE;
261 		goto clean10;
262 	}
263 
264 	/* Perform RSA computation on big integer input data. */
265 	if (big_modexp_crt(&msg, &msg, &(rsakey->dmodpminus1),
266 	    &(rsakey->dmodqminus1), &(rsakey->p), &(rsakey->q),
267 	    &(rsakey->pinvmodq), NULL, NULL) != BIG_OK) {
268 		rv = CKR_HOST_MEMORY;
269 		goto clean10;
270 	}
271 
272 	/* Convert the big integer output data to octet string. */
273 	bignum2bytestring((uchar_t *)out, &msg, modulus_len);
274 
275 clean10:
276 	big_finish(&msg);
277 clean9:
278 	RSA_key_finish(rsakey);
279 clean8:
280 	free(rsakey);
281 clean1:
282 
283 /* EXPORT DELETE END */
284 
285 	return (rv);
286 }
287 
288 /*
289  * Allocate a RSA context for the active encryption or decryption operation.
290  * This function is called without the session lock held.
291  */
292 CK_RV
293 soft_rsa_crypt_init_common(soft_session_t *session_p,
294     CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
295     boolean_t encrypt)
296 {
297 
298 	soft_rsa_ctx_t *rsa_ctx;
299 	soft_object_t *tmp_key = NULL;
300 	CK_RV rv;
301 
302 	rsa_ctx = calloc(1, sizeof (soft_rsa_ctx_t));
303 	if (rsa_ctx == NULL) {
304 		return (CKR_HOST_MEMORY);
305 	}
306 
307 	/*
308 	 * Make a copy of the encryption or decryption key, and save it
309 	 * in the RSA crypto context since it will be used later for
310 	 * encryption/decryption. We don't want to hold any object reference
311 	 * on this original key while doing encryption/decryption.
312 	 */
313 	(void) pthread_mutex_lock(&key_p->object_mutex);
314 	rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
315 	    NULL);
316 
317 	if ((rv != CKR_OK) || (tmp_key == NULL)) {
318 		/* Most likely we ran out of space. */
319 		(void) pthread_mutex_unlock(&key_p->object_mutex);
320 		free(rsa_ctx);
321 		return (rv);
322 	}
323 
324 	/* No need to hold the lock on the old object. */
325 	(void) pthread_mutex_unlock(&key_p->object_mutex);
326 	rsa_ctx->key = tmp_key;
327 
328 	(void) pthread_mutex_lock(&session_p->session_mutex);
329 	if (encrypt) {
330 		/* Called by C_EncryptInit. */
331 		session_p->encrypt.context = rsa_ctx;
332 		session_p->encrypt.mech.mechanism = pMechanism->mechanism;
333 	} else {
334 		/* Called by C_DecryptInit. */
335 		session_p->decrypt.context = rsa_ctx;
336 		session_p->decrypt.mech.mechanism = pMechanism->mechanism;
337 	}
338 	(void) pthread_mutex_unlock(&session_p->session_mutex);
339 
340 	return (CKR_OK);
341 }
342 
343 CK_RV
344 soft_rsa_encrypt_common(soft_session_t *session_p, CK_BYTE_PTR pData,
345     CK_ULONG ulDataLen, CK_BYTE_PTR pEncrypted,
346     CK_ULONG_PTR pulEncryptedLen, CK_MECHANISM_TYPE mechanism)
347 {
348 
349 	soft_rsa_ctx_t *rsa_ctx = session_p->encrypt.context;
350 	soft_object_t *key = rsa_ctx->key;
351 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
352 	uint32_t modulus_len = sizeof (modulus);
353 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
354 	CK_BYTE	cipher_data[MAX_RSA_KEYLENGTH_IN_BYTES];
355 	CK_RV rv = CKR_OK;
356 
357 	rv = soft_get_public_attr(key, CKA_MODULUS, modulus, &modulus_len);
358 	if (rv != CKR_OK) {
359 		goto clean_exit;
360 	}
361 
362 	if (pEncrypted == NULL) {
363 		/*
364 		 * Application asks for the length of the output buffer
365 		 * to hold the ciphertext.
366 		 */
367 		*pulEncryptedLen = modulus_len;
368 		rv = CKR_OK;
369 		goto clean1;
370 	}
371 
372 	if (mechanism == CKM_RSA_PKCS) {
373 		/*
374 		 * Input data length needs to be <=
375 		 * modulus length-MIN_PKCS1_PADLEN.
376 		 */
377 		if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
378 			*pulEncryptedLen = modulus_len;
379 			rv = CKR_DATA_LEN_RANGE;
380 			goto clean_exit;
381 		}
382 	} else {
383 		/* Input data length needs to be <= modulus length. */
384 		if (ulDataLen > (CK_ULONG)modulus_len) {
385 			*pulEncryptedLen = modulus_len;
386 			rv = CKR_DATA_LEN_RANGE;
387 			goto clean_exit;
388 		}
389 	}
390 
391 	/* Is the application-supplied buffer large enough? */
392 	if (*pulEncryptedLen < (CK_ULONG)modulus_len) {
393 		*pulEncryptedLen = modulus_len;
394 		rv = CKR_BUFFER_TOO_SMALL;
395 		goto clean1;
396 	}
397 
398 	if (mechanism == CKM_RSA_PKCS) {
399 		/*
400 		 * Add PKCS padding to the input data to format a block
401 		 * type "02" encryption block.
402 		 */
403 		rv = soft_encrypt_rsa_pkcs_encode(pData, ulDataLen, plain_data,
404 		    modulus_len);
405 
406 		if (rv != CKR_OK)
407 			goto clean_exit;
408 	} else {
409 		/* Pad zeros for the leading bytes of the input data. */
410 		(void) memset(plain_data, 0x0, modulus_len - ulDataLen);
411 		(void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
412 		    ulDataLen);
413 	}
414 
415 	rv = soft_rsa_encrypt(key, plain_data, modulus_len, cipher_data, 1);
416 	if (rv == CKR_OK) {
417 		(void) memcpy(pEncrypted, cipher_data, modulus_len);
418 		*pulEncryptedLen = modulus_len;
419 	}
420 
421 clean_exit:
422 	(void) pthread_mutex_lock(&session_p->session_mutex);
423 	free(session_p->encrypt.context);
424 	session_p->encrypt.context = NULL;
425 	(void) pthread_mutex_unlock(&session_p->session_mutex);
426 	soft_cleanup_object(key);
427 	free(key);
428 clean1:
429 	return (rv);
430 }
431 
432 
433 CK_RV
434 soft_rsa_decrypt_common(soft_session_t *session_p, CK_BYTE_PTR pEncrypted,
435     CK_ULONG ulEncryptedLen, CK_BYTE_PTR pData,
436     CK_ULONG_PTR pulDataLen, CK_MECHANISM_TYPE mechanism)
437 {
438 
439 	soft_rsa_ctx_t *rsa_ctx = session_p->decrypt.context;
440 	soft_object_t *key = rsa_ctx->key;
441 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
442 	uint32_t modulus_len = sizeof (modulus);
443 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
444 	CK_RV rv = CKR_OK;
445 
446 	rv = soft_get_private_attr(key, CKA_MODULUS, modulus, &modulus_len);
447 	if (rv != CKR_OK) {
448 		goto clean_exit;
449 	}
450 
451 	if (ulEncryptedLen != (CK_ULONG)modulus_len) {
452 		rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
453 		goto clean_exit;
454 	}
455 
456 	if (pData == NULL) {
457 		/*
458 		 * Application asks for the length of the output buffer
459 		 * to hold the recovered data.
460 		 */
461 		*pulDataLen = modulus_len;
462 		rv = CKR_OK;
463 		goto clean1;
464 	}
465 
466 	if (mechanism == CKM_RSA_X_509) {
467 		if (*pulDataLen < (CK_ULONG)modulus_len) {
468 			*pulDataLen = modulus_len;
469 			rv = CKR_BUFFER_TOO_SMALL;
470 			goto clean1;
471 		}
472 	}
473 
474 	rv = soft_rsa_decrypt(key, pEncrypted, modulus_len, plain_data);
475 	if (rv != CKR_OK) {
476 		goto clean_exit;
477 	}
478 
479 	if (mechanism == CKM_RSA_PKCS) {
480 		int plain_len = modulus_len;
481 		uint32_t num_padding;
482 
483 		/* Strip off the PKCS block formatting data. */
484 		rv = soft_decrypt_rsa_pkcs_decode(plain_data, &plain_len);
485 		if (rv != CKR_OK)
486 			goto clean_exit;
487 
488 		num_padding = modulus_len - plain_len;
489 		if (ulEncryptedLen - num_padding > *pulDataLen) {
490 			*pulDataLen = plain_len;
491 			rv = CKR_BUFFER_TOO_SMALL;
492 			goto clean1;
493 		}
494 
495 		(void) memcpy(pData, &plain_data[num_padding], plain_len);
496 		*pulDataLen = plain_len;
497 	} else {
498 		(void) memcpy(pData, plain_data, modulus_len);
499 		*pulDataLen = modulus_len;
500 	}
501 
502 clean_exit:
503 	(void) pthread_mutex_lock(&session_p->session_mutex);
504 	free(session_p->decrypt.context);
505 	session_p->decrypt.context = NULL;
506 	(void) pthread_mutex_unlock(&session_p->session_mutex);
507 	soft_cleanup_object(key);
508 	free(key);
509 
510 clean1:
511 	return (rv);
512 }
513 
514 /*
515  * Allocate a RSA context for the active sign or verify operation.
516  * This function is called without the session lock held.
517  */
518 CK_RV
519 soft_rsa_sign_verify_init_common(soft_session_t *session_p,
520     CK_MECHANISM_PTR pMechanism, soft_object_t *key_p,
521     boolean_t sign)
522 {
523 	CK_RV rv = CKR_OK;
524 	soft_rsa_ctx_t *rsa_ctx;
525 	CK_MECHANISM digest_mech;
526 	soft_object_t *tmp_key = NULL;
527 
528 	if (sign) {
529 		if ((key_p->class != CKO_PRIVATE_KEY) ||
530 		    (key_p->key_type != CKK_RSA))
531 			return (CKR_KEY_TYPE_INCONSISTENT);
532 	} else {
533 		if ((key_p->class != CKO_PUBLIC_KEY) ||
534 		    (key_p->key_type != CKK_RSA))
535 			return (CKR_KEY_TYPE_INCONSISTENT);
536 	}
537 
538 	switch (pMechanism->mechanism) {
539 	case CKM_MD5_RSA_PKCS:
540 		digest_mech.mechanism = CKM_MD5;
541 		rv = soft_digest_init_internal(session_p, &digest_mech);
542 		if (rv != CKR_OK)
543 			return (rv);
544 		break;
545 
546 	case CKM_SHA1_RSA_PKCS:
547 		digest_mech.mechanism = CKM_SHA_1;
548 		rv = soft_digest_init_internal(session_p, &digest_mech);
549 		if (rv != CKR_OK)
550 			return (rv);
551 		break;
552 
553 	case CKM_SHA256_RSA_PKCS:
554 		digest_mech.mechanism = CKM_SHA256;
555 		rv = soft_digest_init_internal(session_p, &digest_mech);
556 		if (rv != CKR_OK)
557 			return (rv);
558 		break;
559 
560 	case CKM_SHA384_RSA_PKCS:
561 		digest_mech.mechanism = CKM_SHA384;
562 		rv = soft_digest_init_internal(session_p, &digest_mech);
563 		if (rv != CKR_OK)
564 			return (rv);
565 		break;
566 
567 	case CKM_SHA512_RSA_PKCS:
568 		digest_mech.mechanism = CKM_SHA512;
569 		rv = soft_digest_init_internal(session_p, &digest_mech);
570 		if (rv != CKR_OK)
571 			return (rv);
572 		break;
573 	}
574 
575 	rsa_ctx = malloc(sizeof (soft_rsa_ctx_t));
576 
577 	if (rsa_ctx == NULL) {
578 		rv = CKR_HOST_MEMORY;
579 		goto clean_exit;
580 	}
581 
582 	(void) pthread_mutex_lock(&key_p->object_mutex);
583 	rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
584 	    NULL);
585 
586 	if ((rv != CKR_OK) || (tmp_key == NULL)) {
587 		/* Most likely we ran out of space. */
588 		(void) pthread_mutex_unlock(&key_p->object_mutex);
589 		free(rsa_ctx);
590 		goto clean_exit;
591 	}
592 
593 	/* No need to hold the lock on the old object. */
594 	(void) pthread_mutex_unlock(&key_p->object_mutex);
595 	rsa_ctx->key = tmp_key;
596 
597 	(void) pthread_mutex_lock(&session_p->session_mutex);
598 
599 	if (sign) {
600 		session_p->sign.context = rsa_ctx;
601 		session_p->sign.mech.mechanism = pMechanism->mechanism;
602 	} else {
603 		session_p->verify.context = rsa_ctx;
604 		session_p->verify.mech.mechanism = pMechanism->mechanism;
605 	}
606 
607 	(void) pthread_mutex_unlock(&session_p->session_mutex);
608 
609 	return (CKR_OK);
610 
611 clean_exit:
612 	(void) pthread_mutex_lock(&session_p->session_mutex);
613 	if (session_p->digest.context != NULL) {
614 		free(session_p->digest.context);
615 		session_p->digest.context = NULL;
616 		session_p->digest.flags = 0;
617 	}
618 	(void) pthread_mutex_unlock(&session_p->session_mutex);
619 	return (rv);
620 
621 }
622 
623 
624 CK_RV
625 soft_rsa_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
626     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
627     CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism)
628 {
629 
630 	CK_RV rv = CKR_OK;
631 	soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
632 	soft_object_t *key = rsa_ctx->key;
633 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
634 	uint32_t modulus_len = sizeof (modulus);
635 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
636 	CK_BYTE	signed_data[MAX_RSA_KEYLENGTH_IN_BYTES];
637 
638 	rv = soft_get_private_attr(key, CKA_MODULUS, modulus, &modulus_len);
639 	if (rv != CKR_OK) {
640 		goto clean_exit;
641 	}
642 
643 	if (pSigned == NULL) {
644 		/* Application asks for the length of the output buffer. */
645 		*pulSignedLen = modulus_len;
646 		rv = CKR_OK;
647 		goto clean1;
648 	}
649 
650 	switch (mechanism) {
651 
652 	case CKM_RSA_PKCS:
653 
654 		/*
655 		 * Input data length needs to be <=
656 		 * modulus length-MIN_PKCS1_PADLEN.
657 		 */
658 		if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
659 			*pulSignedLen = modulus_len;
660 			rv = CKR_DATA_LEN_RANGE;
661 			goto clean_exit;
662 		}
663 		break;
664 
665 	case CKM_RSA_X_509:
666 
667 		/* Input data length needs to be <= modulus length. */
668 		if (ulDataLen > (CK_ULONG)modulus_len) {
669 			*pulSignedLen = modulus_len;
670 			rv = CKR_DATA_LEN_RANGE;
671 			goto clean_exit;
672 		}
673 		break;
674 	}
675 
676 	/* Is the application-supplied buffer large enough? */
677 	if (*pulSignedLen < (CK_ULONG)modulus_len) {
678 		*pulSignedLen = modulus_len;
679 		rv = CKR_BUFFER_TOO_SMALL;
680 		goto clean1;
681 	}
682 
683 	switch (mechanism) {
684 
685 	case CKM_RSA_PKCS:
686 	case CKM_MD5_RSA_PKCS:
687 	case CKM_SHA1_RSA_PKCS:
688 	case CKM_SHA256_RSA_PKCS:
689 	case CKM_SHA384_RSA_PKCS:
690 	case CKM_SHA512_RSA_PKCS:
691 		/*
692 		 * Add PKCS padding to the input data to format a block
693 		 * type "01" encryption block.
694 		 */
695 		rv = soft_sign_rsa_pkcs_encode(pData, ulDataLen, plain_data,
696 		    modulus_len);
697 
698 		if (rv != CKR_OK) {
699 			goto clean_exit;
700 		}
701 		break;
702 
703 	case CKM_RSA_X_509:
704 
705 		/* Pad zeros for the leading bytes of the input data. */
706 		(void) memset(plain_data, 0x0, modulus_len - ulDataLen);
707 		(void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
708 		    ulDataLen);
709 		break;
710 	}
711 
712 	/*
713 	 * Perform RSA encryption with the signer's RSA private key
714 	 * for signature process.
715 	 */
716 	rv = soft_rsa_decrypt(key, plain_data, modulus_len, signed_data);
717 
718 	if (rv == CKR_OK) {
719 		(void) memcpy(pSigned, signed_data, modulus_len);
720 		*pulSignedLen = modulus_len;
721 	}
722 
723 clean_exit:
724 	(void) pthread_mutex_lock(&session_p->session_mutex);
725 	free(session_p->sign.context);
726 	session_p->sign.context = NULL;
727 	if (session_p->digest.context != NULL) {
728 		free(session_p->digest.context);
729 		session_p->digest.context = NULL;
730 		session_p->digest.flags = 0;
731 	}
732 	(void) pthread_mutex_unlock(&session_p->session_mutex);
733 	soft_cleanup_object(key);
734 	free(key);
735 
736 clean1:
737 	return (rv);
738 }
739 
740 
741 CK_RV
742 soft_rsa_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
743     CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
744     CK_ULONG ulSignatureLen, CK_MECHANISM_TYPE mechanism)
745 {
746 
747 	CK_RV rv = CKR_OK;
748 	soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
749 	soft_object_t *key = rsa_ctx->key;
750 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
751 	uint32_t modulus_len = sizeof (modulus);
752 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
753 
754 	rv = soft_get_public_attr(key, CKA_MODULUS, modulus, &modulus_len);
755 	if (rv != CKR_OK) {
756 		goto clean_exit;
757 	}
758 
759 	if (ulSignatureLen != (CK_ULONG)modulus_len) {
760 		rv = CKR_SIGNATURE_LEN_RANGE;
761 		goto clean_exit;
762 	}
763 
764 	/*
765 	 * Perform RSA decryption with the signer's RSA public key
766 	 * for verification process.
767 	 */
768 	rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
769 	if (rv == CKR_OK) {
770 		switch (mechanism) {
771 
772 		case CKM_RSA_PKCS:
773 		case CKM_MD5_RSA_PKCS:
774 		case CKM_SHA1_RSA_PKCS:
775 		case CKM_SHA256_RSA_PKCS:
776 		case CKM_SHA384_RSA_PKCS:
777 		case CKM_SHA512_RSA_PKCS:
778 		{
779 			/*
780 			 * Strip off the encoded padding bytes in front of the
781 			 * recovered data, then compare the recovered data with
782 			 * the original data.
783 			 */
784 			int data_len = modulus_len;
785 
786 			rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
787 			if (rv != CKR_OK) {
788 				goto clean_exit;
789 			}
790 
791 			if ((CK_ULONG)data_len != ulDataLen) {
792 				rv = CKR_SIGNATURE_LEN_RANGE;
793 				goto clean_exit;
794 			} else if (memcmp(pData,
795 			    &plain_data[modulus_len - data_len],
796 			    ulDataLen) != 0) {
797 				rv = CKR_SIGNATURE_INVALID;
798 				goto clean_exit;
799 			}
800 			break;
801 		}
802 
803 		case CKM_RSA_X_509:
804 			/*
805 			 * Strip off the encoded padding bytes in front of the
806 			 * recovered plain_data, then compare the input data
807 			 * with the recovered data.
808 			 */
809 			if (memcmp(pData,
810 			    plain_data + ulSignatureLen - ulDataLen,
811 			    ulDataLen) != 0) {
812 				rv = CKR_SIGNATURE_INVALID;
813 				goto clean_exit;
814 			}
815 			break;
816 		}
817 	}
818 
819 	if (rv == CKR_DATA_LEN_RANGE) {
820 		if ((mechanism == CKM_MD5_RSA_PKCS) ||
821 		    (mechanism == CKM_SHA1_RSA_PKCS) ||
822 		    (mechanism == CKM_SHA256_RSA_PKCS) ||
823 		    (mechanism == CKM_SHA384_RSA_PKCS) ||
824 		    (mechanism == CKM_SHA512_RSA_PKCS))
825 			rv = CKR_SIGNATURE_INVALID;
826 	}
827 
828 clean_exit:
829 	(void) pthread_mutex_lock(&session_p->session_mutex);
830 	free(session_p->verify.context);
831 	session_p->verify.context = NULL;
832 	if (session_p->digest.context != NULL) {
833 		free(session_p->digest.context);
834 		session_p->digest.context = NULL;
835 		session_p->digest.flags = 0;
836 	}
837 	(void) pthread_mutex_unlock(&session_p->session_mutex);
838 	soft_cleanup_object(key);
839 	free(key);
840 	return (rv);
841 }
842 
843 CK_RV
844 soft_genRSAkey_set_attribute(soft_object_t *key, RSAkey *rsakey,
845     CK_ATTRIBUTE_TYPE type, uint32_t modulus_len, boolean_t public)
846 {
847 
848 	uchar_t	*buf, *buf1;
849 	uint32_t buflen;
850 	CK_RV rv = CKR_OK;
851 	biginteger_t *dst = NULL;
852 	biginteger_t src;
853 
854 	/*
855 	 * Allocate the buffer used to store the value of key fields
856 	 * for bignum2bytestring. Since bignum only deals with a buffer
857 	 * whose size is multiple of 4, modulus_len is rounded up to be
858 	 * multiple of 4.
859 	 */
860 	if ((buf1 = malloc((modulus_len + 3) & ~3)) == NULL) {
861 		rv = CKR_HOST_MEMORY;
862 		goto cleanexit;
863 	}
864 
865 	buf = buf1;
866 
867 	switch (type) {
868 
869 	case CKA_MODULUS:
870 
871 		buflen = rsakey->n.len * (int)sizeof (uint32_t);
872 		bignum2bytestring(buf, &rsakey->n, buflen);
873 		if (public)
874 			dst = OBJ_PUB_RSA_MOD(key);
875 		else
876 			dst = OBJ_PRI_RSA_MOD(key);
877 		break;
878 
879 	case CKA_PUBLIC_EXPONENT:
880 
881 		buflen = rsakey->e.len * (int)sizeof (uint32_t);
882 		bignum2bytestring(buf, &rsakey->e, buflen);
883 		if (public)
884 			dst = OBJ_PUB_RSA_PUBEXPO(key);
885 		else
886 			dst = OBJ_PRI_RSA_PUBEXPO(key);
887 		break;
888 
889 	case CKA_PRIVATE_EXPONENT:
890 
891 		buflen = rsakey->d.len * (int)sizeof (uint32_t);
892 		bignum2bytestring(buf, &rsakey->d, buflen);
893 		dst = OBJ_PRI_RSA_PRIEXPO(key);
894 		break;
895 
896 	case CKA_PRIME_1:
897 
898 		buflen = rsakey->q.len * (int)sizeof (uint32_t);
899 		bignum2bytestring(buf, &rsakey->q, buflen);
900 		dst = OBJ_PRI_RSA_PRIME1(key);
901 		break;
902 
903 	case CKA_PRIME_2:
904 
905 		buflen = rsakey->p.len * (int)sizeof (uint32_t);
906 		bignum2bytestring(buf, &rsakey->p, buflen);
907 		dst = OBJ_PRI_RSA_PRIME2(key);
908 		break;
909 
910 	case CKA_EXPONENT_1:
911 
912 		buflen = rsakey->dmodqminus1.len * (int)sizeof (uint32_t);
913 		bignum2bytestring(buf, &rsakey->dmodqminus1, buflen);
914 		dst = OBJ_PRI_RSA_EXPO1(key);
915 		break;
916 
917 	case CKA_EXPONENT_2:
918 
919 		buflen = rsakey->dmodpminus1.len * (int)sizeof (uint32_t);
920 		bignum2bytestring(buf, &rsakey->dmodpminus1, buflen);
921 		dst = OBJ_PRI_RSA_EXPO2(key);
922 		break;
923 
924 	case CKA_COEFFICIENT:
925 
926 		buflen = rsakey->pinvmodq.len * (int)sizeof (uint32_t);
927 		bignum2bytestring(buf, &rsakey->pinvmodq, buflen);
928 		dst = OBJ_PRI_RSA_COEF(key);
929 		break;
930 	}
931 
932 	while (buf[0] == 0) {	/* remove proceeding 0x00 */
933 		buf++;
934 		buflen--;
935 	}
936 
937 	src.big_value_len = buflen;
938 
939 	if ((src.big_value = malloc(buflen)) == NULL) {
940 		rv = CKR_HOST_MEMORY;
941 		goto cleanexit;
942 	}
943 	(void) memcpy(src.big_value, buf, buflen);
944 
945 	/* Copy the attribute in the key object. */
946 	copy_bigint_attr(&src, dst);
947 
948 cleanexit:
949 	free(buf1);
950 	return (rv);
951 
952 }
953 
954 
955 CK_RV
956 generate_rsa_key(RSAkey *key, int psize, int qsize, BIGNUM * pubexp,
957     boolean_t token_obj)
958 {
959 	CK_RV		rv = CKR_OK;
960 
961 /* EXPORT DELETE START */
962 
963 	BIGNUM		a, b, c, d, e, f, g, h;
964 	int		len, keylen, size;
965 	BIG_ERR_CODE	brv = BIG_OK;
966 
967 	size = psize + qsize;
968 	keylen = (size + 31) / 32;
969 	len = keylen * 2 + 1;
970 	key->size = size;
971 
972 	a.malloced = 0;
973 	b.malloced = 0;
974 	c.malloced = 0;
975 	d.malloced = 0;
976 	e.malloced = 0;
977 	f.malloced = 0;
978 	g.malloced = 0;
979 	h.malloced = 0;
980 
981 	if ((big_init(&a, len) != BIG_OK) ||
982 	    (big_init(&b, len) != BIG_OK) ||
983 	    (big_init(&c, len) != BIG_OK) ||
984 	    (big_init(&d, len) != BIG_OK) ||
985 	    (big_init(&e, len) != BIG_OK) ||
986 	    (big_init(&f, len) != BIG_OK) ||
987 	    (big_init(&g, len) != BIG_OK) ||
988 	    (big_init(&h, len) != BIG_OK)) {
989 		big_finish(&h);
990 		big_finish(&g);
991 		big_finish(&f);
992 		big_finish(&e);
993 		big_finish(&d);
994 		big_finish(&c);
995 		big_finish(&b);
996 		big_finish(&a);
997 
998 		return (CKR_HOST_MEMORY);
999 	}
1000 nextp:
1001 	if ((brv = random_bignum(&a, psize, token_obj)) != BIG_OK) {
1002 		goto ret;
1003 	}
1004 
1005 	if ((brv = big_nextprime_pos(&b, &a)) != BIG_OK) {
1006 		goto ret;
1007 	}
1008 	(void) big_sub_pos(&a, &b, &One);
1009 	if ((brv = big_ext_gcd_pos(&f, &d, &g, pubexp, &a)) != BIG_OK) {
1010 		goto ret;
1011 	}
1012 	if (big_cmp_abs(&f, &One) != 0) {
1013 		goto nextp;
1014 	}
1015 
1016 	if ((brv = random_bignum(&c, qsize, token_obj)) != BIG_OK) {
1017 		goto ret;
1018 	}
1019 
1020 nextq:
1021 	(void) big_add(&a, &c, &Two);
1022 
1023 	if (big_bitlength(&a) != qsize) {
1024 		goto nextp;
1025 	}
1026 	if (big_cmp_abs(&a, &b) == 0) {
1027 		goto nextp;
1028 	}
1029 	if ((brv = big_nextprime_pos(&c, &a)) != BIG_OK) {
1030 		goto ret;
1031 	}
1032 	if ((brv = big_mul(&g, &b, &c)) != BIG_OK) {
1033 		goto ret;
1034 	}
1035 	if (big_bitlength(&g) != size) {
1036 		goto nextp;
1037 	}
1038 
1039 	(void) big_sub_pos(&a, &b, &One);
1040 	(void) big_sub_pos(&d, &c, &One);
1041 
1042 	if ((brv = big_mul(&a, &a, &d)) != BIG_OK) {
1043 		goto ret;
1044 	}
1045 	if ((brv = big_ext_gcd_pos(&f, &d, &h, pubexp, &a)) != BIG_OK) {
1046 		goto ret;
1047 	}
1048 	if (big_cmp_abs(&f, &One) != 0) {
1049 		goto nextq;
1050 	} else {
1051 		(void) big_copy(&e, pubexp);
1052 	}
1053 	if (d.sign == -1) {
1054 		if ((brv = big_add(&d, &d, &a)) != BIG_OK) {
1055 			goto ret;
1056 		}
1057 	}
1058 	(void) big_copy(&(key->p), &b);
1059 	(void) big_copy(&(key->q), &c);
1060 	(void) big_copy(&(key->n), &g);
1061 	(void) big_copy(&(key->d), &d);
1062 	(void) big_copy(&(key->e), &e);
1063 
1064 	if ((brv = big_ext_gcd_pos(&a, &f, &h, &b, &c)) != BIG_OK) {
1065 		goto ret;
1066 	}
1067 	if (f.sign == -1) {
1068 		if ((brv = big_add(&f, &f, &c)) != BIG_OK) {
1069 			goto ret;
1070 		}
1071 	}
1072 	(void) big_copy(&(key->pinvmodq), &f);
1073 
1074 	(void) big_sub(&a, &b, &One);
1075 	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
1076 		goto ret;
1077 	}
1078 	(void) big_copy(&(key->dmodpminus1), &f);
1079 	(void) big_sub(&a, &c, &One);
1080 	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
1081 		goto ret;
1082 	}
1083 	(void) big_copy(&(key->dmodqminus1), &f);
1084 
1085 	if ((brv = random_bignum(&h, size, token_obj)) != BIG_OK) {
1086 		goto ret;
1087 	}
1088 	if ((brv = big_div_pos(&a, &h, &h, &g)) != BIG_OK) {
1089 		goto ret;
1090 	}
1091 	if ((brv = big_modexp(&a, &h, &d, &g, NULL)) != BIG_OK) {
1092 		goto ret;
1093 	}
1094 
1095 	if ((brv = big_modexp(&b, &a, &e, &g, NULL)) != BIG_OK) {
1096 		goto ret;
1097 	}
1098 
1099 	if (big_cmp_abs(&b, &h) != 0) {
1100 		rv = generate_rsa_key(key, psize, qsize, pubexp, token_obj);
1101 		goto ret1;
1102 	} else {
1103 		brv = BIG_OK;
1104 	}
1105 
1106 ret:
1107 	rv = convert_rv(brv);
1108 ret1:
1109 	big_finish(&h);
1110 	big_finish(&g);
1111 	big_finish(&f);
1112 	big_finish(&e);
1113 	big_finish(&d);
1114 	big_finish(&c);
1115 	big_finish(&b);
1116 	big_finish(&a);
1117 
1118 /* EXPORT DELETE END */
1119 
1120 	return (rv);
1121 }
1122 
1123 
1124 CK_RV
1125 soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
1126 {
1127 
1128 	CK_RV rv = CKR_OK;
1129 	uint32_t modulus_len;
1130 	uchar_t	pub_expo[MAX_KEY_ATTR_BUFLEN];
1131 	uint32_t pub_expo_len = sizeof (pub_expo);
1132 	BIGNUM	public_exponent = {0};
1133 	RSAkey	rsakey = {0};
1134 	CK_ATTRIBUTE template;
1135 
1136 	if ((pubkey == NULL) || (prikey == NULL)) {
1137 		return (CKR_ARGUMENTS_BAD);
1138 	}
1139 
1140 	template.pValue = malloc(sizeof (CK_ULONG));
1141 
1142 	if (template.pValue == NULL) {
1143 		return (CKR_HOST_MEMORY);
1144 	}
1145 
1146 	template.ulValueLen = sizeof (CK_ULONG);
1147 
1148 	rv = get_ulong_attr_from_object(OBJ_PUB_RSA_MOD_BITS(pubkey),
1149 	    &template);
1150 
1151 	if (rv != CKR_OK) {
1152 		goto clean0;
1153 	}
1154 
1155 #ifdef	__sparcv9
1156 	/* LINTED */
1157 	modulus_len = (uint32_t)(*((CK_ULONG *)(template.pValue)));
1158 #else	/* !__sparcv9 */
1159 	modulus_len = *((CK_ULONG *)(template.pValue));
1160 #endif	/* __sparcv9 */
1161 
1162 	/* Convert modulus length from bit length to byte length. */
1163 	modulus_len = (modulus_len + 7) / 8;
1164 
1165 	/* Modulus length needs to be between min key size and max key size. */
1166 	if ((modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES) ||
1167 	    (modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES)) {
1168 		rv = CKR_ATTRIBUTE_VALUE_INVALID;
1169 		goto clean0;
1170 	}
1171 
1172 	rv = soft_get_public_attr(pubkey, CKA_PUBLIC_EXPONENT, pub_expo,
1173 	    &pub_expo_len);
1174 	if (rv != CKR_OK) {
1175 		goto clean0;
1176 	}
1177 
1178 	/* Create a public exponent in bignum format. */
1179 	if (big_init(&public_exponent, (modulus_len + 3)/4) != BIG_OK) {
1180 		rv = CKR_HOST_MEMORY;
1181 		goto clean0;
1182 	}
1183 	bytestring2bignum(&public_exponent, pub_expo, pub_expo_len);
1184 
1185 	if (RSA_key_init(&rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
1186 		rv = CKR_HOST_MEMORY;
1187 		goto clean2;
1188 	}
1189 
1190 	/* Generate RSA key pair. */
1191 	if ((rv = generate_rsa_key(&rsakey, modulus_len * 4, modulus_len * 4,
1192 	    &public_exponent, (IS_TOKEN_OBJECT(pubkey) ||
1193 	    IS_TOKEN_OBJECT(prikey)))) != CKR_OK) {
1194 		goto clean3;
1195 	}
1196 
1197 	/*
1198 	 * Add modulus in public template, and add all eight key fields
1199 	 * in private template.
1200 	 */
1201 	if ((rv = soft_genRSAkey_set_attribute(pubkey, &rsakey,
1202 	    CKA_MODULUS, modulus_len, B_TRUE)) != CKR_OK) {
1203 		goto clean3;
1204 	}
1205 
1206 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1207 	    CKA_MODULUS, modulus_len, B_FALSE)) != CKR_OK) {
1208 		goto clean3;
1209 	}
1210 
1211 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1212 	    CKA_PRIVATE_EXPONENT, modulus_len, B_FALSE)) != CKR_OK) {
1213 		goto clean3;
1214 	}
1215 
1216 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1217 	    CKA_PUBLIC_EXPONENT, modulus_len, B_FALSE)) != CKR_OK) {
1218 		goto clean3;
1219 	}
1220 
1221 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1222 	    CKA_PRIME_1, modulus_len, B_FALSE)) != CKR_OK) {
1223 		goto clean3;
1224 	}
1225 
1226 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1227 	    CKA_PRIME_2, modulus_len, B_FALSE)) != CKR_OK) {
1228 		goto clean3;
1229 	}
1230 
1231 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1232 	    CKA_EXPONENT_1, modulus_len, B_FALSE)) != CKR_OK) {
1233 		goto clean3;
1234 	}
1235 
1236 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1237 	    CKA_EXPONENT_2, modulus_len, B_FALSE)) != CKR_OK) {
1238 		goto clean3;
1239 	}
1240 
1241 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1242 	    CKA_COEFFICIENT, modulus_len, B_FALSE)) != CKR_OK) {
1243 		goto clean3;
1244 	}
1245 
1246 clean3:
1247 	RSA_key_finish(&rsakey);
1248 clean2:
1249 	big_finish(&public_exponent);
1250 clean0:
1251 	free(template.pValue);
1252 
1253 	return (rv);
1254 }
1255 
1256 CK_RV
1257 soft_rsa_digest_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1258     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
1259     CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
1260 {
1261 
1262 	CK_RV rv = CKR_OK;
1263 	CK_BYTE hash[SHA512_DIGEST_LENGTH];  /* space enough for all mechs */
1264 	CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
1265 	/* space enough for all mechs */
1266 	CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
1267 	CK_ULONG der_data_len;
1268 	soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
1269 	soft_object_t *key = rsa_ctx->key;
1270 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
1271 	uint32_t modulus_len = sizeof (modulus);
1272 
1273 	rv = soft_get_private_attr(key, CKA_MODULUS, modulus, &modulus_len);
1274 	if (rv != CKR_OK) {
1275 		(void) pthread_mutex_lock(&session_p->session_mutex);
1276 		free(session_p->digest.context);
1277 		session_p->digest.context = NULL;
1278 		session_p->digest.flags = 0;
1279 		(void) pthread_mutex_unlock(&session_p->session_mutex);
1280 		soft_cleanup_object(key);
1281 		free(key);
1282 		goto clean1;
1283 	}
1284 
1285 	/* Check arguments before performing message digest. */
1286 	if (pSigned == NULL) {
1287 		/* Application asks for the length of the output buffer. */
1288 		*pulSignedLen = modulus_len;
1289 		rv = CKR_OK;
1290 		goto clean1;
1291 	}
1292 
1293 	/* Is the application-supplied buffer large enough? */
1294 	if (*pulSignedLen < (CK_ULONG)modulus_len) {
1295 		*pulSignedLen = modulus_len;
1296 		rv = CKR_BUFFER_TOO_SMALL;
1297 		goto clean1;
1298 	}
1299 
1300 	if (Final) {
1301 		rv = soft_digest_final(session_p, hash, &hash_len);
1302 	} else {
1303 		rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
1304 	}
1305 
1306 	if (rv != CKR_OK) {
1307 		/* free the signature key */
1308 		soft_cleanup_object(key);
1309 		free(key);
1310 		goto clean_exit;
1311 	}
1312 
1313 	/*
1314 	 * Prepare the DER encoding of the DigestInfo value as follows:
1315 	 * MD5:		MD5_DER_PREFIX || H
1316 	 * SHA-1:	SHA1_DER_PREFIX || H
1317 	 * SHA2:	SHA2_DER_PREFIX || H
1318 	 *
1319 	 * See rsa_impl.c for more details.
1320 	 */
1321 	switch (session_p->digest.mech.mechanism) {
1322 	case CKM_MD5:
1323 		(void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
1324 		(void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
1325 		der_data_len = MD5_DER_PREFIX_Len + hash_len;
1326 		break;
1327 	case CKM_SHA_1:
1328 		(void) memcpy(der_data, SHA1_DER_PREFIX, SHA1_DER_PREFIX_Len);
1329 		(void) memcpy(der_data + SHA1_DER_PREFIX_Len, hash, hash_len);
1330 		der_data_len = SHA1_DER_PREFIX_Len + hash_len;
1331 		break;
1332 	case CKM_SHA256:
1333 		(void) memcpy(der_data, SHA256_DER_PREFIX,
1334 		    SHA2_DER_PREFIX_Len);
1335 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1336 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1337 		break;
1338 	case CKM_SHA384:
1339 		(void) memcpy(der_data, SHA384_DER_PREFIX,
1340 		    SHA2_DER_PREFIX_Len);
1341 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1342 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1343 		break;
1344 	case CKM_SHA512:
1345 		(void) memcpy(der_data, SHA512_DER_PREFIX,
1346 		    SHA2_DER_PREFIX_Len);
1347 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1348 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1349 		break;
1350 	}
1351 
1352 	/*
1353 	 * Now, we are ready to sign the DER_ENCODED data
1354 	 * soft_rsa_sign_common() will free the signature key.
1355 	 */
1356 	rv = soft_rsa_sign_common(session_p, der_data, der_data_len,
1357 	    pSigned, pulSignedLen, mechanism);
1358 
1359 clean_exit:
1360 	(void) pthread_mutex_lock(&session_p->session_mutex);
1361 	/* soft_digest_common() has freed the digest context */
1362 	session_p->digest.flags = 0;
1363 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1364 
1365 clean1:
1366 	return (rv);
1367 }
1368 
1369 
1370 CK_RV
1371 soft_rsa_digest_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1372     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
1373     CK_ULONG ulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
1374 {
1375 
1376 	CK_RV rv = CKR_OK;
1377 	CK_BYTE hash[SHA512_DIGEST_LENGTH];  /* space for all mechs */
1378 	CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
1379 	CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
1380 	CK_ULONG der_data_len;
1381 	soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
1382 	soft_object_t *key = rsa_ctx->key;
1383 
1384 	if (Final) {
1385 		rv = soft_digest_final(session_p, hash, &hash_len);
1386 	} else {
1387 		rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
1388 	}
1389 
1390 	if (rv != CKR_OK) {
1391 		/* free the verification key */
1392 		soft_cleanup_object(key);
1393 		free(key);
1394 		goto clean_exit;
1395 	}
1396 
1397 	/*
1398 	 * Prepare the DER encoding of the DigestInfo value as follows:
1399 	 * MD5:		MD5_DER_PREFIX || H
1400 	 * SHA-1:	SHA1_DER_PREFIX || H
1401 	 * SHA2:	SHA2_DER_PREFIX || H
1402 	 *
1403 	 * See rsa_impl.c for more details.
1404 	 */
1405 	switch (session_p->digest.mech.mechanism) {
1406 	case CKM_MD5:
1407 		(void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
1408 		(void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
1409 		der_data_len = MD5_DER_PREFIX_Len + hash_len;
1410 		break;
1411 	case CKM_SHA_1:
1412 		(void) memcpy(der_data, SHA1_DER_PREFIX, SHA1_DER_PREFIX_Len);
1413 		(void) memcpy(der_data + SHA1_DER_PREFIX_Len, hash, hash_len);
1414 		der_data_len = SHA1_DER_PREFIX_Len + hash_len;
1415 		break;
1416 	case CKM_SHA256:
1417 		(void) memcpy(der_data, SHA256_DER_PREFIX,
1418 		    SHA2_DER_PREFIX_Len);
1419 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1420 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1421 		break;
1422 	case CKM_SHA384:
1423 		(void) memcpy(der_data, SHA384_DER_PREFIX,
1424 		    SHA2_DER_PREFIX_Len);
1425 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1426 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1427 		break;
1428 	case CKM_SHA512:
1429 		(void) memcpy(der_data, SHA512_DER_PREFIX,
1430 		    SHA2_DER_PREFIX_Len);
1431 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1432 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1433 		break;
1434 	}
1435 
1436 	/*
1437 	 * Now, we are ready to verify the DER_ENCODED data using signature.
1438 	 * soft_rsa_verify_common() will free the verification key.
1439 	 */
1440 	rv = soft_rsa_verify_common(session_p, der_data, der_data_len,
1441 	    pSigned, ulSignedLen, mechanism);
1442 
1443 clean_exit:
1444 	(void) pthread_mutex_lock(&session_p->session_mutex);
1445 	/* soft_digest_common() has freed the digest context */
1446 	session_p->digest.flags = 0;
1447 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1448 
1449 	return (rv);
1450 
1451 }
1452 
1453 
1454 CK_RV
1455 soft_rsa_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
1456     CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1457 {
1458 
1459 	CK_RV rv = CKR_OK;
1460 	soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
1461 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
1462 	soft_object_t *key = rsa_ctx->key;
1463 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
1464 	uint32_t modulus_len = sizeof (modulus);
1465 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
1466 
1467 	rv = soft_get_public_attr(key, CKA_MODULUS, modulus, &modulus_len);
1468 	if (rv != CKR_OK) {
1469 		goto clean_exit;
1470 	}
1471 
1472 	if (ulSignatureLen != (CK_ULONG)modulus_len) {
1473 		rv = CKR_SIGNATURE_LEN_RANGE;
1474 		goto clean_exit;
1475 	}
1476 
1477 	/*
1478 	 * Perform RSA decryption with the signer's RSA public key
1479 	 * for verification process.
1480 	 */
1481 	rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
1482 	if (rv == CKR_OK) {
1483 		switch (mechanism) {
1484 
1485 		case CKM_RSA_PKCS:
1486 		{
1487 			/*
1488 			 * Strip off the encoded padding bytes in front of the
1489 			 * recovered data.
1490 			 */
1491 			int data_len = modulus_len;
1492 
1493 			rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
1494 			if (rv != CKR_OK) {
1495 				goto clean_exit;
1496 			}
1497 
1498 			/*
1499 			 * If application asks for the length of the output
1500 			 * buffer?
1501 			 */
1502 			if (pData == NULL) {
1503 				*pulDataLen = data_len;
1504 				rv = CKR_OK;
1505 				goto clean1;
1506 			}
1507 
1508 			/* Is the application-supplied buffer large enough? */
1509 			if (*pulDataLen < (CK_ULONG)data_len) {
1510 				*pulDataLen = data_len;
1511 				rv = CKR_BUFFER_TOO_SMALL;
1512 				goto clean1;
1513 			}
1514 
1515 			(void) memcpy(pData,
1516 			    &plain_data[modulus_len - data_len], data_len);
1517 			*pulDataLen = data_len;
1518 
1519 			break;
1520 		}
1521 
1522 		case CKM_RSA_X_509:
1523 			/*
1524 			 * If application asks for the length of the output
1525 			 * buffer?
1526 			 */
1527 			if (pData == NULL) {
1528 				*pulDataLen = modulus_len;
1529 				rv = CKR_OK;
1530 				goto clean1;
1531 			}
1532 
1533 			/* Is the application-supplied buffer large enough? */
1534 			if (*pulDataLen < (CK_ULONG)modulus_len) {
1535 				*pulDataLen = modulus_len;
1536 				rv = CKR_BUFFER_TOO_SMALL;
1537 				goto clean1;
1538 			}
1539 
1540 			(void) memcpy(pData, plain_data, modulus_len);
1541 			*pulDataLen = modulus_len;
1542 
1543 			break;
1544 		}
1545 	}
1546 
1547 clean_exit:
1548 	(void) pthread_mutex_lock(&session_p->session_mutex);
1549 	free(session_p->verify.context);
1550 	session_p->verify.context = NULL;
1551 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1552 	soft_cleanup_object(key);
1553 	free(key);
1554 
1555 clean1:
1556 	return (rv);
1557 }
1558