xref: /titanic_44/usr/src/lib/pkcs11/pkcs11_softtoken/common/softRSA.c (revision 54925bf60766fbb4f1f2d7c843721406a7b7a3fb)
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 		digest_mech.pParameter = pMechanism->pParameter;
549 		digest_mech.ulParameterLen = pMechanism->ulParameterLen;
550 		rv = soft_digest_init_internal(session_p, &digest_mech);
551 		if (rv != CKR_OK)
552 			return (rv);
553 		break;
554 
555 	case CKM_SHA256_RSA_PKCS:
556 		digest_mech.mechanism = CKM_SHA256;
557 		rv = soft_digest_init_internal(session_p, &digest_mech);
558 		if (rv != CKR_OK)
559 			return (rv);
560 		break;
561 
562 	case CKM_SHA384_RSA_PKCS:
563 		digest_mech.mechanism = CKM_SHA384;
564 		rv = soft_digest_init_internal(session_p, &digest_mech);
565 		if (rv != CKR_OK)
566 			return (rv);
567 		break;
568 
569 	case CKM_SHA512_RSA_PKCS:
570 		digest_mech.mechanism = CKM_SHA512;
571 		rv = soft_digest_init_internal(session_p, &digest_mech);
572 		if (rv != CKR_OK)
573 			return (rv);
574 		break;
575 	}
576 
577 	rsa_ctx = malloc(sizeof (soft_rsa_ctx_t));
578 
579 	if (rsa_ctx == NULL) {
580 		rv = CKR_HOST_MEMORY;
581 		goto clean_exit;
582 	}
583 
584 	(void) pthread_mutex_lock(&key_p->object_mutex);
585 	rv = soft_copy_object(key_p, &tmp_key, SOFT_COPY_OBJ_ORIG_SH,
586 	    NULL);
587 
588 	if ((rv != CKR_OK) || (tmp_key == NULL)) {
589 		/* Most likely we ran out of space. */
590 		(void) pthread_mutex_unlock(&key_p->object_mutex);
591 		free(rsa_ctx);
592 		goto clean_exit;
593 	}
594 
595 	/* No need to hold the lock on the old object. */
596 	(void) pthread_mutex_unlock(&key_p->object_mutex);
597 	rsa_ctx->key = tmp_key;
598 
599 	(void) pthread_mutex_lock(&session_p->session_mutex);
600 
601 	if (sign) {
602 		session_p->sign.context = rsa_ctx;
603 		session_p->sign.mech.mechanism = pMechanism->mechanism;
604 	} else {
605 		session_p->verify.context = rsa_ctx;
606 		session_p->verify.mech.mechanism = pMechanism->mechanism;
607 	}
608 
609 	(void) pthread_mutex_unlock(&session_p->session_mutex);
610 
611 	return (CKR_OK);
612 
613 clean_exit:
614 	(void) pthread_mutex_lock(&session_p->session_mutex);
615 	if (session_p->digest.context != NULL) {
616 		free(session_p->digest.context);
617 		session_p->digest.context = NULL;
618 		session_p->digest.flags = 0;
619 	}
620 	(void) pthread_mutex_unlock(&session_p->session_mutex);
621 	return (rv);
622 
623 }
624 
625 
626 CK_RV
627 soft_rsa_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
628     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
629     CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism)
630 {
631 
632 	CK_RV rv = CKR_OK;
633 	soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
634 	soft_object_t *key = rsa_ctx->key;
635 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
636 	uint32_t modulus_len = sizeof (modulus);
637 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
638 	CK_BYTE	signed_data[MAX_RSA_KEYLENGTH_IN_BYTES];
639 
640 	rv = soft_get_private_attr(key, CKA_MODULUS, modulus, &modulus_len);
641 	if (rv != CKR_OK) {
642 		goto clean_exit;
643 	}
644 
645 	if (pSigned == NULL) {
646 		/* Application asks for the length of the output buffer. */
647 		*pulSignedLen = modulus_len;
648 		rv = CKR_OK;
649 		goto clean1;
650 	}
651 
652 	switch (mechanism) {
653 
654 	case CKM_RSA_PKCS:
655 
656 		/*
657 		 * Input data length needs to be <=
658 		 * modulus length-MIN_PKCS1_PADLEN.
659 		 */
660 		if (ulDataLen > ((CK_ULONG)modulus_len - MIN_PKCS1_PADLEN)) {
661 			*pulSignedLen = modulus_len;
662 			rv = CKR_DATA_LEN_RANGE;
663 			goto clean_exit;
664 		}
665 		break;
666 
667 	case CKM_RSA_X_509:
668 
669 		/* Input data length needs to be <= modulus length. */
670 		if (ulDataLen > (CK_ULONG)modulus_len) {
671 			*pulSignedLen = modulus_len;
672 			rv = CKR_DATA_LEN_RANGE;
673 			goto clean_exit;
674 		}
675 		break;
676 	}
677 
678 	/* Is the application-supplied buffer large enough? */
679 	if (*pulSignedLen < (CK_ULONG)modulus_len) {
680 		*pulSignedLen = modulus_len;
681 		rv = CKR_BUFFER_TOO_SMALL;
682 		goto clean1;
683 	}
684 
685 	switch (mechanism) {
686 
687 	case CKM_RSA_PKCS:
688 	case CKM_MD5_RSA_PKCS:
689 	case CKM_SHA1_RSA_PKCS:
690 	case CKM_SHA256_RSA_PKCS:
691 	case CKM_SHA384_RSA_PKCS:
692 	case CKM_SHA512_RSA_PKCS:
693 		/*
694 		 * Add PKCS padding to the input data to format a block
695 		 * type "01" encryption block.
696 		 */
697 		rv = soft_sign_rsa_pkcs_encode(pData, ulDataLen, plain_data,
698 		    modulus_len);
699 
700 		if (rv != CKR_OK) {
701 			goto clean_exit;
702 		}
703 		break;
704 
705 	case CKM_RSA_X_509:
706 
707 		/* Pad zeros for the leading bytes of the input data. */
708 		(void) memset(plain_data, 0x0, modulus_len - ulDataLen);
709 		(void) memcpy(&plain_data[modulus_len - ulDataLen], pData,
710 		    ulDataLen);
711 		break;
712 	}
713 
714 	/*
715 	 * Perform RSA encryption with the signer's RSA private key
716 	 * for signature process.
717 	 */
718 	rv = soft_rsa_decrypt(key, plain_data, modulus_len, signed_data);
719 
720 	if (rv == CKR_OK) {
721 		(void) memcpy(pSigned, signed_data, modulus_len);
722 		*pulSignedLen = modulus_len;
723 	}
724 
725 clean_exit:
726 	(void) pthread_mutex_lock(&session_p->session_mutex);
727 	free(session_p->sign.context);
728 	session_p->sign.context = NULL;
729 	if (session_p->digest.context != NULL) {
730 		free(session_p->digest.context);
731 		session_p->digest.context = NULL;
732 		session_p->digest.flags = 0;
733 	}
734 	(void) pthread_mutex_unlock(&session_p->session_mutex);
735 	soft_cleanup_object(key);
736 	free(key);
737 
738 clean1:
739 	return (rv);
740 }
741 
742 
743 CK_RV
744 soft_rsa_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
745     CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,
746     CK_ULONG ulSignatureLen, CK_MECHANISM_TYPE mechanism)
747 {
748 
749 	CK_RV rv = CKR_OK;
750 	soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
751 	soft_object_t *key = rsa_ctx->key;
752 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
753 	uint32_t modulus_len = sizeof (modulus);
754 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
755 
756 	rv = soft_get_public_attr(key, CKA_MODULUS, modulus, &modulus_len);
757 	if (rv != CKR_OK) {
758 		goto clean_exit;
759 	}
760 
761 	if (ulSignatureLen != (CK_ULONG)modulus_len) {
762 		rv = CKR_SIGNATURE_LEN_RANGE;
763 		goto clean_exit;
764 	}
765 
766 	/*
767 	 * Perform RSA decryption with the signer's RSA public key
768 	 * for verification process.
769 	 */
770 	rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
771 	if (rv == CKR_OK) {
772 		switch (mechanism) {
773 
774 		case CKM_RSA_PKCS:
775 		case CKM_MD5_RSA_PKCS:
776 		case CKM_SHA1_RSA_PKCS:
777 		case CKM_SHA256_RSA_PKCS:
778 		case CKM_SHA384_RSA_PKCS:
779 		case CKM_SHA512_RSA_PKCS:
780 		{
781 			/*
782 			 * Strip off the encoded padding bytes in front of the
783 			 * recovered data, then compare the recovered data with
784 			 * the original data.
785 			 */
786 			int data_len = modulus_len;
787 
788 			rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
789 			if (rv != CKR_OK) {
790 				goto clean_exit;
791 			}
792 
793 			if ((CK_ULONG)data_len != ulDataLen) {
794 				rv = CKR_SIGNATURE_LEN_RANGE;
795 				goto clean_exit;
796 			} else if (memcmp(pData,
797 			    &plain_data[modulus_len - data_len],
798 			    ulDataLen) != 0) {
799 				rv = CKR_SIGNATURE_INVALID;
800 				goto clean_exit;
801 			}
802 			break;
803 		}
804 
805 		case CKM_RSA_X_509:
806 			/*
807 			 * Strip off the encoded padding bytes in front of the
808 			 * recovered plain_data, then compare the input data
809 			 * with the recovered data.
810 			 */
811 			if (memcmp(pData,
812 			    plain_data + ulSignatureLen - ulDataLen,
813 			    ulDataLen) != 0) {
814 				rv = CKR_SIGNATURE_INVALID;
815 				goto clean_exit;
816 			}
817 			break;
818 		}
819 	}
820 
821 	if (rv == CKR_DATA_LEN_RANGE) {
822 		if ((mechanism == CKM_MD5_RSA_PKCS) ||
823 		    (mechanism == CKM_SHA1_RSA_PKCS) ||
824 		    (mechanism == CKM_SHA256_RSA_PKCS) ||
825 		    (mechanism == CKM_SHA384_RSA_PKCS) ||
826 		    (mechanism == CKM_SHA512_RSA_PKCS))
827 			rv = CKR_SIGNATURE_INVALID;
828 	}
829 
830 clean_exit:
831 	(void) pthread_mutex_lock(&session_p->session_mutex);
832 	free(session_p->verify.context);
833 	session_p->verify.context = NULL;
834 	if (session_p->digest.context != NULL) {
835 		free(session_p->digest.context);
836 		session_p->digest.context = NULL;
837 		session_p->digest.flags = 0;
838 	}
839 	(void) pthread_mutex_unlock(&session_p->session_mutex);
840 	soft_cleanup_object(key);
841 	free(key);
842 	return (rv);
843 }
844 
845 CK_RV
846 soft_genRSAkey_set_attribute(soft_object_t *key, RSAkey *rsakey,
847     CK_ATTRIBUTE_TYPE type, uint32_t modulus_len, boolean_t public)
848 {
849 
850 	uchar_t	*buf, *buf1;
851 	uint32_t buflen;
852 	CK_RV rv = CKR_OK;
853 	biginteger_t *dst = NULL;
854 	biginteger_t src;
855 
856 	/*
857 	 * Allocate the buffer used to store the value of key fields
858 	 * for bignum2bytestring. Since bignum only deals with a buffer
859 	 * whose size is multiple of 4, modulus_len is rounded up to be
860 	 * multiple of 4.
861 	 */
862 	if ((buf1 = malloc((modulus_len + 3) & ~3)) == NULL) {
863 		rv = CKR_HOST_MEMORY;
864 		goto cleanexit;
865 	}
866 
867 	buf = buf1;
868 
869 	switch (type) {
870 
871 	case CKA_MODULUS:
872 
873 		buflen = rsakey->n.len * (int)sizeof (uint32_t);
874 		bignum2bytestring(buf, &rsakey->n, buflen);
875 		if (public)
876 			dst = OBJ_PUB_RSA_MOD(key);
877 		else
878 			dst = OBJ_PRI_RSA_MOD(key);
879 		break;
880 
881 	case CKA_PUBLIC_EXPONENT:
882 
883 		buflen = rsakey->e.len * (int)sizeof (uint32_t);
884 		bignum2bytestring(buf, &rsakey->e, buflen);
885 		if (public)
886 			dst = OBJ_PUB_RSA_PUBEXPO(key);
887 		else
888 			dst = OBJ_PRI_RSA_PUBEXPO(key);
889 		break;
890 
891 	case CKA_PRIVATE_EXPONENT:
892 
893 		buflen = rsakey->d.len * (int)sizeof (uint32_t);
894 		bignum2bytestring(buf, &rsakey->d, buflen);
895 		dst = OBJ_PRI_RSA_PRIEXPO(key);
896 		break;
897 
898 	case CKA_PRIME_1:
899 
900 		buflen = rsakey->q.len * (int)sizeof (uint32_t);
901 		bignum2bytestring(buf, &rsakey->q, buflen);
902 		dst = OBJ_PRI_RSA_PRIME1(key);
903 		break;
904 
905 	case CKA_PRIME_2:
906 
907 		buflen = rsakey->p.len * (int)sizeof (uint32_t);
908 		bignum2bytestring(buf, &rsakey->p, buflen);
909 		dst = OBJ_PRI_RSA_PRIME2(key);
910 		break;
911 
912 	case CKA_EXPONENT_1:
913 
914 		buflen = rsakey->dmodqminus1.len * (int)sizeof (uint32_t);
915 		bignum2bytestring(buf, &rsakey->dmodqminus1, buflen);
916 		dst = OBJ_PRI_RSA_EXPO1(key);
917 		break;
918 
919 	case CKA_EXPONENT_2:
920 
921 		buflen = rsakey->dmodpminus1.len * (int)sizeof (uint32_t);
922 		bignum2bytestring(buf, &rsakey->dmodpminus1, buflen);
923 		dst = OBJ_PRI_RSA_EXPO2(key);
924 		break;
925 
926 	case CKA_COEFFICIENT:
927 
928 		buflen = rsakey->pinvmodq.len * (int)sizeof (uint32_t);
929 		bignum2bytestring(buf, &rsakey->pinvmodq, buflen);
930 		dst = OBJ_PRI_RSA_COEF(key);
931 		break;
932 	}
933 
934 	while (buf[0] == 0) {	/* remove proceeding 0x00 */
935 		buf++;
936 		buflen--;
937 	}
938 
939 	src.big_value_len = buflen;
940 
941 	if ((src.big_value = malloc(buflen)) == NULL) {
942 		rv = CKR_HOST_MEMORY;
943 		goto cleanexit;
944 	}
945 	(void) memcpy(src.big_value, buf, buflen);
946 
947 	/* Copy the attribute in the key object. */
948 	copy_bigint_attr(&src, dst);
949 
950 cleanexit:
951 	free(buf1);
952 	return (rv);
953 
954 }
955 
956 
957 CK_RV
958 generate_rsa_key(RSAkey *key, int psize, int qsize, BIGNUM * pubexp,
959     boolean_t token_obj)
960 {
961 	CK_RV		rv = CKR_OK;
962 
963 /* EXPORT DELETE START */
964 
965 	BIGNUM		a, b, c, d, e, f, g, h;
966 	int		len, keylen, size;
967 	BIG_ERR_CODE	brv = BIG_OK;
968 
969 	size = psize + qsize;
970 	keylen = (size + 31) / 32;
971 	len = keylen * 2 + 1;
972 	key->size = size;
973 
974 	a.malloced = 0;
975 	b.malloced = 0;
976 	c.malloced = 0;
977 	d.malloced = 0;
978 	e.malloced = 0;
979 	f.malloced = 0;
980 	g.malloced = 0;
981 	h.malloced = 0;
982 
983 	if ((big_init(&a, len) != BIG_OK) ||
984 	    (big_init(&b, len) != BIG_OK) ||
985 	    (big_init(&c, len) != BIG_OK) ||
986 	    (big_init(&d, len) != BIG_OK) ||
987 	    (big_init(&e, len) != BIG_OK) ||
988 	    (big_init(&f, len) != BIG_OK) ||
989 	    (big_init(&g, len) != BIG_OK) ||
990 	    (big_init(&h, len) != BIG_OK)) {
991 		big_finish(&h);
992 		big_finish(&g);
993 		big_finish(&f);
994 		big_finish(&e);
995 		big_finish(&d);
996 		big_finish(&c);
997 		big_finish(&b);
998 		big_finish(&a);
999 
1000 		return (CKR_HOST_MEMORY);
1001 	}
1002 nextp:
1003 	if ((brv = random_bignum(&a, psize, token_obj)) != BIG_OK) {
1004 		goto ret;
1005 	}
1006 
1007 	if ((brv = big_nextprime_pos(&b, &a)) != BIG_OK) {
1008 		goto ret;
1009 	}
1010 	(void) big_sub_pos(&a, &b, &One);
1011 	if ((brv = big_ext_gcd_pos(&f, &d, &g, pubexp, &a)) != BIG_OK) {
1012 		goto ret;
1013 	}
1014 	if (big_cmp_abs(&f, &One) != 0) {
1015 		goto nextp;
1016 	}
1017 
1018 	if ((brv = random_bignum(&c, qsize, token_obj)) != BIG_OK) {
1019 		goto ret;
1020 	}
1021 
1022 nextq:
1023 	(void) big_add(&a, &c, &Two);
1024 
1025 	if (big_bitlength(&a) != qsize) {
1026 		goto nextp;
1027 	}
1028 	if (big_cmp_abs(&a, &b) == 0) {
1029 		goto nextp;
1030 	}
1031 	if ((brv = big_nextprime_pos(&c, &a)) != BIG_OK) {
1032 		goto ret;
1033 	}
1034 	if ((brv = big_mul(&g, &b, &c)) != BIG_OK) {
1035 		goto ret;
1036 	}
1037 	if (big_bitlength(&g) != size) {
1038 		goto nextp;
1039 	}
1040 
1041 	(void) big_sub_pos(&a, &b, &One);
1042 	(void) big_sub_pos(&d, &c, &One);
1043 
1044 	if ((brv = big_mul(&a, &a, &d)) != BIG_OK) {
1045 		goto ret;
1046 	}
1047 	if ((brv = big_ext_gcd_pos(&f, &d, &h, pubexp, &a)) != BIG_OK) {
1048 		goto ret;
1049 	}
1050 	if (big_cmp_abs(&f, &One) != 0) {
1051 		goto nextq;
1052 	} else {
1053 		(void) big_copy(&e, pubexp);
1054 	}
1055 	if (d.sign == -1) {
1056 		if ((brv = big_add(&d, &d, &a)) != BIG_OK) {
1057 			goto ret;
1058 		}
1059 	}
1060 	(void) big_copy(&(key->p), &b);
1061 	(void) big_copy(&(key->q), &c);
1062 	(void) big_copy(&(key->n), &g);
1063 	(void) big_copy(&(key->d), &d);
1064 	(void) big_copy(&(key->e), &e);
1065 
1066 	if ((brv = big_ext_gcd_pos(&a, &f, &h, &b, &c)) != BIG_OK) {
1067 		goto ret;
1068 	}
1069 	if (f.sign == -1) {
1070 		if ((brv = big_add(&f, &f, &c)) != BIG_OK) {
1071 			goto ret;
1072 		}
1073 	}
1074 	(void) big_copy(&(key->pinvmodq), &f);
1075 
1076 	(void) big_sub(&a, &b, &One);
1077 	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
1078 		goto ret;
1079 	}
1080 	(void) big_copy(&(key->dmodpminus1), &f);
1081 	(void) big_sub(&a, &c, &One);
1082 	if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
1083 		goto ret;
1084 	}
1085 	(void) big_copy(&(key->dmodqminus1), &f);
1086 
1087 	if ((brv = random_bignum(&h, size, token_obj)) != BIG_OK) {
1088 		goto ret;
1089 	}
1090 	if ((brv = big_div_pos(&a, &h, &h, &g)) != BIG_OK) {
1091 		goto ret;
1092 	}
1093 	if ((brv = big_modexp(&a, &h, &d, &g, NULL)) != BIG_OK) {
1094 		goto ret;
1095 	}
1096 
1097 	if ((brv = big_modexp(&b, &a, &e, &g, NULL)) != BIG_OK) {
1098 		goto ret;
1099 	}
1100 
1101 	if (big_cmp_abs(&b, &h) != 0) {
1102 		rv = generate_rsa_key(key, psize, qsize, pubexp, token_obj);
1103 		goto ret1;
1104 	} else {
1105 		brv = BIG_OK;
1106 	}
1107 
1108 ret:
1109 	rv = convert_rv(brv);
1110 ret1:
1111 	big_finish(&h);
1112 	big_finish(&g);
1113 	big_finish(&f);
1114 	big_finish(&e);
1115 	big_finish(&d);
1116 	big_finish(&c);
1117 	big_finish(&b);
1118 	big_finish(&a);
1119 
1120 /* EXPORT DELETE END */
1121 
1122 	return (rv);
1123 }
1124 
1125 
1126 CK_RV
1127 soft_rsa_genkey_pair(soft_object_t *pubkey, soft_object_t *prikey)
1128 {
1129 
1130 	CK_RV rv = CKR_OK;
1131 	uint32_t modulus_len;
1132 	uchar_t	pub_expo[MAX_KEY_ATTR_BUFLEN];
1133 	uint32_t pub_expo_len = sizeof (pub_expo);
1134 	BIGNUM	public_exponent = {0};
1135 	RSAkey	rsakey = {0};
1136 	CK_ATTRIBUTE template;
1137 
1138 	if ((pubkey == NULL) || (prikey == NULL)) {
1139 		return (CKR_ARGUMENTS_BAD);
1140 	}
1141 
1142 	template.pValue = malloc(sizeof (CK_ULONG));
1143 
1144 	if (template.pValue == NULL) {
1145 		return (CKR_HOST_MEMORY);
1146 	}
1147 
1148 	template.ulValueLen = sizeof (CK_ULONG);
1149 
1150 	rv = get_ulong_attr_from_object(OBJ_PUB_RSA_MOD_BITS(pubkey),
1151 	    &template);
1152 
1153 	if (rv != CKR_OK) {
1154 		goto clean0;
1155 	}
1156 
1157 #ifdef	__sparcv9
1158 	/* LINTED */
1159 	modulus_len = (uint32_t)(*((CK_ULONG *)(template.pValue)));
1160 #else	/* !__sparcv9 */
1161 	modulus_len = *((CK_ULONG *)(template.pValue));
1162 #endif	/* __sparcv9 */
1163 
1164 	/* Convert modulus length from bit length to byte length. */
1165 	modulus_len = (modulus_len + 7) / 8;
1166 
1167 	/* Modulus length needs to be between min key size and max key size. */
1168 	if ((modulus_len < MIN_RSA_KEYLENGTH_IN_BYTES) ||
1169 	    (modulus_len > MAX_RSA_KEYLENGTH_IN_BYTES)) {
1170 		rv = CKR_ATTRIBUTE_VALUE_INVALID;
1171 		goto clean0;
1172 	}
1173 
1174 	rv = soft_get_public_attr(pubkey, CKA_PUBLIC_EXPONENT, pub_expo,
1175 	    &pub_expo_len);
1176 	if (rv != CKR_OK) {
1177 		goto clean0;
1178 	}
1179 
1180 	/* Create a public exponent in bignum format. */
1181 	if (big_init(&public_exponent, (modulus_len + 3)/4) != BIG_OK) {
1182 		rv = CKR_HOST_MEMORY;
1183 		goto clean0;
1184 	}
1185 	bytestring2bignum(&public_exponent, pub_expo, pub_expo_len);
1186 
1187 	if (RSA_key_init(&rsakey, modulus_len * 4, modulus_len * 4) != BIG_OK) {
1188 		rv = CKR_HOST_MEMORY;
1189 		goto clean2;
1190 	}
1191 
1192 	/* Generate RSA key pair. */
1193 	if ((rv = generate_rsa_key(&rsakey, modulus_len * 4, modulus_len * 4,
1194 	    &public_exponent, (IS_TOKEN_OBJECT(pubkey) ||
1195 	    IS_TOKEN_OBJECT(prikey)))) != CKR_OK) {
1196 		goto clean3;
1197 	}
1198 
1199 	/*
1200 	 * Add modulus in public template, and add all eight key fields
1201 	 * in private template.
1202 	 */
1203 	if ((rv = soft_genRSAkey_set_attribute(pubkey, &rsakey,
1204 	    CKA_MODULUS, modulus_len, B_TRUE)) != CKR_OK) {
1205 		goto clean3;
1206 	}
1207 
1208 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1209 	    CKA_MODULUS, modulus_len, B_FALSE)) != CKR_OK) {
1210 		goto clean3;
1211 	}
1212 
1213 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1214 	    CKA_PRIVATE_EXPONENT, modulus_len, B_FALSE)) != CKR_OK) {
1215 		goto clean3;
1216 	}
1217 
1218 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1219 	    CKA_PUBLIC_EXPONENT, modulus_len, B_FALSE)) != CKR_OK) {
1220 		goto clean3;
1221 	}
1222 
1223 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1224 	    CKA_PRIME_1, modulus_len, B_FALSE)) != CKR_OK) {
1225 		goto clean3;
1226 	}
1227 
1228 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1229 	    CKA_PRIME_2, modulus_len, B_FALSE)) != CKR_OK) {
1230 		goto clean3;
1231 	}
1232 
1233 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1234 	    CKA_EXPONENT_1, modulus_len, B_FALSE)) != CKR_OK) {
1235 		goto clean3;
1236 	}
1237 
1238 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1239 	    CKA_EXPONENT_2, modulus_len, B_FALSE)) != CKR_OK) {
1240 		goto clean3;
1241 	}
1242 
1243 	if ((rv = soft_genRSAkey_set_attribute(prikey, &rsakey,
1244 	    CKA_COEFFICIENT, modulus_len, B_FALSE)) != CKR_OK) {
1245 		goto clean3;
1246 	}
1247 
1248 clean3:
1249 	RSA_key_finish(&rsakey);
1250 clean2:
1251 	big_finish(&public_exponent);
1252 clean0:
1253 	free(template.pValue);
1254 
1255 	return (rv);
1256 }
1257 
1258 
1259 CK_ULONG
1260 get_rsa_sha1_prefix(CK_MECHANISM_PTR mech, CK_BYTE_PTR *prefix) {
1261 	if (mech->pParameter == NULL) {
1262 		*prefix = (CK_BYTE *)SHA1_DER_PREFIX;
1263 		return (SHA1_DER_PREFIX_Len);
1264 	}
1265 
1266 	*prefix = (CK_BYTE *)SHA1_DER_PREFIX_OID;
1267 	return (SHA1_DER_PREFIX_OID_Len);
1268 }
1269 
1270 CK_RV
1271 soft_rsa_digest_sign_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1272     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
1273     CK_ULONG_PTR pulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
1274 {
1275 
1276 	CK_RV rv = CKR_OK;
1277 	CK_BYTE hash[SHA512_DIGEST_LENGTH];  /* space enough for all mechs */
1278 	CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
1279 	/* space enough for all mechs */
1280 	CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
1281 	CK_ULONG der_data_len;
1282 	soft_rsa_ctx_t *rsa_ctx = session_p->sign.context;
1283 	soft_object_t *key = rsa_ctx->key;
1284 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
1285 	uint32_t modulus_len = sizeof (modulus);
1286 	CK_ULONG der_len;
1287 	CK_BYTE_PTR der_prefix;
1288 
1289 	rv = soft_get_private_attr(key, CKA_MODULUS, modulus, &modulus_len);
1290 	if (rv != CKR_OK) {
1291 		(void) pthread_mutex_lock(&session_p->session_mutex);
1292 		free(session_p->digest.context);
1293 		session_p->digest.context = NULL;
1294 		session_p->digest.flags = 0;
1295 		(void) pthread_mutex_unlock(&session_p->session_mutex);
1296 		soft_cleanup_object(key);
1297 		free(key);
1298 		goto clean1;
1299 	}
1300 
1301 	/* Check arguments before performing message digest. */
1302 	if (pSigned == NULL) {
1303 		/* Application asks for the length of the output buffer. */
1304 		*pulSignedLen = modulus_len;
1305 		rv = CKR_OK;
1306 		goto clean1;
1307 	}
1308 
1309 	/* Is the application-supplied buffer large enough? */
1310 	if (*pulSignedLen < (CK_ULONG)modulus_len) {
1311 		*pulSignedLen = modulus_len;
1312 		rv = CKR_BUFFER_TOO_SMALL;
1313 		goto clean1;
1314 	}
1315 
1316 	if (Final) {
1317 		rv = soft_digest_final(session_p, hash, &hash_len);
1318 	} else {
1319 		rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
1320 	}
1321 
1322 	if (rv != CKR_OK) {
1323 		/* free the signature key */
1324 		soft_cleanup_object(key);
1325 		free(key);
1326 		goto clean_exit;
1327 	}
1328 
1329 	/*
1330 	 * Prepare the DER encoding of the DigestInfo value by setting it to:
1331 	 *	<MECH>_DER_PREFIX || H
1332 	 *
1333 	 * See rsa_impl.c for more details.
1334 	 */
1335 	switch (session_p->digest.mech.mechanism) {
1336 	case CKM_MD5:
1337 		(void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
1338 		(void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
1339 		der_data_len = MD5_DER_PREFIX_Len + hash_len;
1340 		break;
1341 	case CKM_SHA_1:
1342 		der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
1343 		    &der_prefix);
1344 		(void) memcpy(der_data, der_prefix, der_len);
1345 		(void) memcpy(der_data + der_len, hash, hash_len);
1346 		der_data_len = der_len + hash_len;
1347 		break;
1348 	case CKM_SHA256:
1349 		(void) memcpy(der_data, SHA256_DER_PREFIX,
1350 		    SHA2_DER_PREFIX_Len);
1351 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1352 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1353 		break;
1354 	case CKM_SHA384:
1355 		(void) memcpy(der_data, SHA384_DER_PREFIX,
1356 		    SHA2_DER_PREFIX_Len);
1357 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1358 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1359 		break;
1360 	case CKM_SHA512:
1361 		(void) memcpy(der_data, SHA512_DER_PREFIX,
1362 		    SHA2_DER_PREFIX_Len);
1363 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1364 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1365 		break;
1366 	}
1367 
1368 	/*
1369 	 * Now, we are ready to sign the DER_ENCODED data
1370 	 * soft_rsa_sign_common() will free the signature key.
1371 	 */
1372 	rv = soft_rsa_sign_common(session_p, der_data, der_data_len,
1373 	    pSigned, pulSignedLen, mechanism);
1374 
1375 clean_exit:
1376 	(void) pthread_mutex_lock(&session_p->session_mutex);
1377 	/* soft_digest_common() has freed the digest context */
1378 	session_p->digest.flags = 0;
1379 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1380 
1381 clean1:
1382 	return (rv);
1383 }
1384 
1385 
1386 CK_RV
1387 soft_rsa_digest_verify_common(soft_session_t *session_p, CK_BYTE_PTR pData,
1388     CK_ULONG ulDataLen, CK_BYTE_PTR pSigned,
1389     CK_ULONG ulSignedLen, CK_MECHANISM_TYPE mechanism, boolean_t Final)
1390 {
1391 
1392 	CK_RV rv = CKR_OK;
1393 	CK_BYTE hash[SHA512_DIGEST_LENGTH];  /* space for all mechs */
1394 	CK_ULONG hash_len = SHA512_DIGEST_LENGTH;
1395 	CK_BYTE der_data[SHA512_DIGEST_LENGTH + SHA2_DER_PREFIX_Len];
1396 	CK_ULONG der_data_len;
1397 	soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
1398 	soft_object_t *key = rsa_ctx->key;
1399 	CK_ULONG der_len;
1400 	CK_BYTE_PTR der_prefix;
1401 
1402 	if (Final) {
1403 		rv = soft_digest_final(session_p, hash, &hash_len);
1404 	} else {
1405 		rv = soft_digest(session_p, pData, ulDataLen, hash, &hash_len);
1406 	}
1407 
1408 	if (rv != CKR_OK) {
1409 		/* free the verification key */
1410 		soft_cleanup_object(key);
1411 		free(key);
1412 		goto clean_exit;
1413 	}
1414 
1415 	/*
1416 	 * Prepare the DER encoding of the DigestInfo value as follows:
1417 	 * MD5:		MD5_DER_PREFIX || H
1418 	 * SHA-1:	SHA1_DER_PREFIX || H
1419 	 * SHA2:	SHA2_DER_PREFIX || H
1420 	 *
1421 	 * See rsa_impl.c for more details.
1422 	 */
1423 	switch (session_p->digest.mech.mechanism) {
1424 	case CKM_MD5:
1425 		(void) memcpy(der_data, MD5_DER_PREFIX, MD5_DER_PREFIX_Len);
1426 		(void) memcpy(der_data + MD5_DER_PREFIX_Len, hash, hash_len);
1427 		der_data_len = MD5_DER_PREFIX_Len + hash_len;
1428 		break;
1429 	case CKM_SHA_1:
1430 		der_len = get_rsa_sha1_prefix(&(session_p->digest.mech),
1431 		    &der_prefix);
1432 		(void) memcpy(der_data, der_prefix, der_len);
1433 		(void) memcpy(der_data + der_len, hash, hash_len);
1434 		der_data_len = der_len + hash_len;
1435 		break;
1436 	case CKM_SHA256:
1437 		(void) memcpy(der_data, SHA256_DER_PREFIX,
1438 		    SHA2_DER_PREFIX_Len);
1439 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1440 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1441 		break;
1442 	case CKM_SHA384:
1443 		(void) memcpy(der_data, SHA384_DER_PREFIX,
1444 		    SHA2_DER_PREFIX_Len);
1445 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1446 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1447 		break;
1448 	case CKM_SHA512:
1449 		(void) memcpy(der_data, SHA512_DER_PREFIX,
1450 		    SHA2_DER_PREFIX_Len);
1451 		(void) memcpy(der_data + SHA2_DER_PREFIX_Len, hash, hash_len);
1452 		der_data_len = SHA2_DER_PREFIX_Len + hash_len;
1453 		break;
1454 	}
1455 
1456 	/*
1457 	 * Now, we are ready to verify the DER_ENCODED data using signature.
1458 	 * soft_rsa_verify_common() will free the verification key.
1459 	 */
1460 	rv = soft_rsa_verify_common(session_p, der_data, der_data_len,
1461 	    pSigned, ulSignedLen, mechanism);
1462 
1463 clean_exit:
1464 	(void) pthread_mutex_lock(&session_p->session_mutex);
1465 	/* soft_digest_common() has freed the digest context */
1466 	session_p->digest.flags = 0;
1467 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1468 
1469 	return (rv);
1470 
1471 }
1472 
1473 
1474 CK_RV
1475 soft_rsa_verify_recover(soft_session_t *session_p, CK_BYTE_PTR pSignature,
1476     CK_ULONG ulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
1477 {
1478 
1479 	CK_RV rv = CKR_OK;
1480 	soft_rsa_ctx_t *rsa_ctx = session_p->verify.context;
1481 	CK_MECHANISM_TYPE mechanism = session_p->verify.mech.mechanism;
1482 	soft_object_t *key = rsa_ctx->key;
1483 	uchar_t modulus[MAX_KEY_ATTR_BUFLEN];
1484 	uint32_t modulus_len = sizeof (modulus);
1485 	CK_BYTE	plain_data[MAX_RSA_KEYLENGTH_IN_BYTES];
1486 
1487 	rv = soft_get_public_attr(key, CKA_MODULUS, modulus, &modulus_len);
1488 	if (rv != CKR_OK) {
1489 		goto clean_exit;
1490 	}
1491 
1492 	if (ulSignatureLen != (CK_ULONG)modulus_len) {
1493 		rv = CKR_SIGNATURE_LEN_RANGE;
1494 		goto clean_exit;
1495 	}
1496 
1497 	/*
1498 	 * Perform RSA decryption with the signer's RSA public key
1499 	 * for verification process.
1500 	 */
1501 	rv = soft_rsa_encrypt(key, pSignature, modulus_len, plain_data, 1);
1502 	if (rv == CKR_OK) {
1503 		switch (mechanism) {
1504 
1505 		case CKM_RSA_PKCS:
1506 		{
1507 			/*
1508 			 * Strip off the encoded padding bytes in front of the
1509 			 * recovered data.
1510 			 */
1511 			int data_len = modulus_len;
1512 
1513 			rv = soft_verify_rsa_pkcs_decode(plain_data, &data_len);
1514 			if (rv != CKR_OK) {
1515 				goto clean_exit;
1516 			}
1517 
1518 			/*
1519 			 * If application asks for the length of the output
1520 			 * buffer?
1521 			 */
1522 			if (pData == NULL) {
1523 				*pulDataLen = data_len;
1524 				rv = CKR_OK;
1525 				goto clean1;
1526 			}
1527 
1528 			/* Is the application-supplied buffer large enough? */
1529 			if (*pulDataLen < (CK_ULONG)data_len) {
1530 				*pulDataLen = data_len;
1531 				rv = CKR_BUFFER_TOO_SMALL;
1532 				goto clean1;
1533 			}
1534 
1535 			(void) memcpy(pData,
1536 			    &plain_data[modulus_len - data_len], data_len);
1537 			*pulDataLen = data_len;
1538 
1539 			break;
1540 		}
1541 
1542 		case CKM_RSA_X_509:
1543 			/*
1544 			 * If application asks for the length of the output
1545 			 * buffer?
1546 			 */
1547 			if (pData == NULL) {
1548 				*pulDataLen = modulus_len;
1549 				rv = CKR_OK;
1550 				goto clean1;
1551 			}
1552 
1553 			/* Is the application-supplied buffer large enough? */
1554 			if (*pulDataLen < (CK_ULONG)modulus_len) {
1555 				*pulDataLen = modulus_len;
1556 				rv = CKR_BUFFER_TOO_SMALL;
1557 				goto clean1;
1558 			}
1559 
1560 			(void) memcpy(pData, plain_data, modulus_len);
1561 			*pulDataLen = modulus_len;
1562 
1563 			break;
1564 		}
1565 	}
1566 
1567 clean_exit:
1568 	(void) pthread_mutex_lock(&session_p->session_mutex);
1569 	free(session_p->verify.context);
1570 	session_p->verify.context = NULL;
1571 	(void) pthread_mutex_unlock(&session_p->session_mutex);
1572 	soft_cleanup_object(key);
1573 	free(key);
1574 
1575 clean1:
1576 	return (rv);
1577 }
1578