10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
56557Sfr41279 * Common Development and Distribution License (the "License").
66557Sfr41279 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*12573SDina.Nimeh@Sun.COM
220Sstevel@tonic-gate /*
23*12573SDina.Nimeh@Sun.COM * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate * This file contains RSA helper routines common to
280Sstevel@tonic-gate * the PKCS11 soft token code and the kernel RSA code.
290Sstevel@tonic-gate */
300Sstevel@tonic-gate
310Sstevel@tonic-gate #include <sys/types.h>
32*12573SDina.Nimeh@Sun.COM #include <bignum.h>
330Sstevel@tonic-gate
340Sstevel@tonic-gate #ifdef _KERNEL
350Sstevel@tonic-gate #include <sys/param.h>
360Sstevel@tonic-gate #else
370Sstevel@tonic-gate #include <strings.h>
389127SDina.Nimeh@Sun.COM #include <cryptoutil.h>
390Sstevel@tonic-gate #endif
400Sstevel@tonic-gate
41*12573SDina.Nimeh@Sun.COM #include <sys/crypto/common.h>
42*12573SDina.Nimeh@Sun.COM #include "rsa_impl.h"
43*12573SDina.Nimeh@Sun.COM
440Sstevel@tonic-gate /*
45676Sizick * DER encoding T of the DigestInfo values for MD5, SHA1, and SHA2
460Sstevel@tonic-gate * from PKCS#1 v2.1: RSA Cryptography Standard Section 9.2 Note 1
470Sstevel@tonic-gate *
480Sstevel@tonic-gate * MD5: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10 || H
490Sstevel@tonic-gate * SHA-1: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H
50676Sizick * SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H.
51676Sizick * SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30 || H.
52676Sizick * SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H.
530Sstevel@tonic-gate *
540Sstevel@tonic-gate * Where H is the digested output from MD5 or SHA1. We define the constant
550Sstevel@tonic-gate * byte array (the prefix) here and use it rather than doing the DER
560Sstevel@tonic-gate * encoding of the OID in a separate routine.
570Sstevel@tonic-gate */
580Sstevel@tonic-gate const CK_BYTE MD5_DER_PREFIX[MD5_DER_PREFIX_Len] = {0x30, 0x20, 0x30, 0x0c,
590Sstevel@tonic-gate 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00,
600Sstevel@tonic-gate 0x04, 0x10};
610Sstevel@tonic-gate
620Sstevel@tonic-gate const CK_BYTE SHA1_DER_PREFIX[SHA1_DER_PREFIX_Len] = {0x30, 0x21, 0x30,
630Sstevel@tonic-gate 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
640Sstevel@tonic-gate
65872Sizick const CK_BYTE SHA1_DER_PREFIX_OID[SHA1_DER_PREFIX_OID_Len] = {0x30, 0x1f, 0x30,
66872Sizick 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14};
67872Sizick
68676Sizick const CK_BYTE SHA256_DER_PREFIX[SHA2_DER_PREFIX_Len] = {0x30, 0x31, 0x30, 0x0d,
69676Sizick 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
70676Sizick 0x00, 0x04, 0x20};
71676Sizick
72676Sizick const CK_BYTE SHA384_DER_PREFIX[SHA2_DER_PREFIX_Len] = {0x30, 0x41, 0x30, 0x0d,
73676Sizick 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
74676Sizick 0x00, 0x04, 0x30};
75676Sizick
76676Sizick const CK_BYTE SHA512_DER_PREFIX[SHA2_DER_PREFIX_Len] = {0x30, 0x51, 0x30, 0x0d,
77676Sizick 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
78676Sizick 0x00, 0x04, 0x40};
79676Sizick
809536SDina.Nimeh@Sun.COM const CK_BYTE DEFAULT_PUB_EXPO[DEFAULT_PUB_EXPO_Len] = { 0x01, 0x00, 0x01 };
816557Sfr41279
82*12573SDina.Nimeh@Sun.COM
83*12573SDina.Nimeh@Sun.COM static CK_RV
convert_rv(BIG_ERR_CODE err)84*12573SDina.Nimeh@Sun.COM convert_rv(BIG_ERR_CODE err)
85*12573SDina.Nimeh@Sun.COM {
86*12573SDina.Nimeh@Sun.COM switch (err) {
87*12573SDina.Nimeh@Sun.COM
88*12573SDina.Nimeh@Sun.COM case BIG_OK:
89*12573SDina.Nimeh@Sun.COM return (CKR_OK);
90*12573SDina.Nimeh@Sun.COM
91*12573SDina.Nimeh@Sun.COM case BIG_NO_MEM:
92*12573SDina.Nimeh@Sun.COM return (CKR_HOST_MEMORY);
93*12573SDina.Nimeh@Sun.COM
94*12573SDina.Nimeh@Sun.COM case BIG_NO_RANDOM:
95*12573SDina.Nimeh@Sun.COM return (CKR_DEVICE_ERROR);
96*12573SDina.Nimeh@Sun.COM
97*12573SDina.Nimeh@Sun.COM case BIG_INVALID_ARGS:
98*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
99*12573SDina.Nimeh@Sun.COM
100*12573SDina.Nimeh@Sun.COM case BIG_DIV_BY_0:
101*12573SDina.Nimeh@Sun.COM default:
102*12573SDina.Nimeh@Sun.COM return (CKR_GENERAL_ERROR);
103*12573SDina.Nimeh@Sun.COM }
104*12573SDina.Nimeh@Sun.COM }
105*12573SDina.Nimeh@Sun.COM
1066557Sfr41279 /* psize and qsize are in bits */
107*12573SDina.Nimeh@Sun.COM static BIG_ERR_CODE
RSA_key_init(RSAkey * key,int psize,int qsize)1080Sstevel@tonic-gate RSA_key_init(RSAkey *key, int psize, int qsize)
1090Sstevel@tonic-gate {
1100Sstevel@tonic-gate BIG_ERR_CODE err = BIG_OK;
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate /* EXPORT DELETE START */
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate int plen, qlen, nlen;
1150Sstevel@tonic-gate
1166557Sfr41279 plen = BITLEN2BIGNUMLEN(psize);
1176557Sfr41279 qlen = BITLEN2BIGNUMLEN(qsize);
1180Sstevel@tonic-gate nlen = plen + qlen;
1190Sstevel@tonic-gate key->size = psize + qsize;
1200Sstevel@tonic-gate if ((err = big_init(&(key->p), plen)) != BIG_OK)
1210Sstevel@tonic-gate return (err);
1220Sstevel@tonic-gate if ((err = big_init(&(key->q), qlen)) != BIG_OK)
1230Sstevel@tonic-gate goto ret1;
1240Sstevel@tonic-gate if ((err = big_init(&(key->n), nlen)) != BIG_OK)
1250Sstevel@tonic-gate goto ret2;
1260Sstevel@tonic-gate if ((err = big_init(&(key->d), nlen)) != BIG_OK)
1270Sstevel@tonic-gate goto ret3;
1280Sstevel@tonic-gate if ((err = big_init(&(key->e), nlen)) != BIG_OK)
1290Sstevel@tonic-gate goto ret4;
1300Sstevel@tonic-gate if ((err = big_init(&(key->dmodpminus1), plen)) != BIG_OK)
1310Sstevel@tonic-gate goto ret5;
1320Sstevel@tonic-gate if ((err = big_init(&(key->dmodqminus1), qlen)) != BIG_OK)
1330Sstevel@tonic-gate goto ret6;
1340Sstevel@tonic-gate if ((err = big_init(&(key->pinvmodq), qlen)) != BIG_OK)
1350Sstevel@tonic-gate goto ret7;
1360Sstevel@tonic-gate if ((err = big_init(&(key->p_rr), plen)) != BIG_OK)
1370Sstevel@tonic-gate goto ret8;
1380Sstevel@tonic-gate if ((err = big_init(&(key->q_rr), qlen)) != BIG_OK)
1390Sstevel@tonic-gate goto ret9;
1400Sstevel@tonic-gate if ((err = big_init(&(key->n_rr), nlen)) != BIG_OK)
1410Sstevel@tonic-gate goto ret10;
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate return (BIG_OK);
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate ret10:
1460Sstevel@tonic-gate big_finish(&(key->q_rr));
1470Sstevel@tonic-gate ret9:
1480Sstevel@tonic-gate big_finish(&(key->p_rr));
1490Sstevel@tonic-gate ret8:
1500Sstevel@tonic-gate big_finish(&(key->pinvmodq));
1510Sstevel@tonic-gate ret7:
1520Sstevel@tonic-gate big_finish(&(key->dmodqminus1));
1530Sstevel@tonic-gate ret6:
1540Sstevel@tonic-gate big_finish(&(key->dmodpminus1));
1550Sstevel@tonic-gate ret5:
1560Sstevel@tonic-gate big_finish(&(key->e));
1570Sstevel@tonic-gate ret4:
1580Sstevel@tonic-gate big_finish(&(key->d));
1590Sstevel@tonic-gate ret3:
1600Sstevel@tonic-gate big_finish(&(key->n));
1610Sstevel@tonic-gate ret2:
1620Sstevel@tonic-gate big_finish(&(key->q));
1630Sstevel@tonic-gate ret1:
1640Sstevel@tonic-gate big_finish(&(key->p));
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate /* EXPORT DELETE END */
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate return (err);
1690Sstevel@tonic-gate }
1700Sstevel@tonic-gate
171*12573SDina.Nimeh@Sun.COM static void
RSA_key_finish(RSAkey * key)1720Sstevel@tonic-gate RSA_key_finish(RSAkey *key)
1730Sstevel@tonic-gate {
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate /* EXPORT DELETE START */
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate big_finish(&(key->n_rr));
1780Sstevel@tonic-gate big_finish(&(key->q_rr));
1790Sstevel@tonic-gate big_finish(&(key->p_rr));
1800Sstevel@tonic-gate big_finish(&(key->pinvmodq));
1810Sstevel@tonic-gate big_finish(&(key->dmodqminus1));
1820Sstevel@tonic-gate big_finish(&(key->dmodpminus1));
1830Sstevel@tonic-gate big_finish(&(key->e));
1840Sstevel@tonic-gate big_finish(&(key->d));
1850Sstevel@tonic-gate big_finish(&(key->n));
1860Sstevel@tonic-gate big_finish(&(key->q));
1870Sstevel@tonic-gate big_finish(&(key->p));
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate /* EXPORT DELETE END */
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate /*
194*12573SDina.Nimeh@Sun.COM * Generate RSA key
1950Sstevel@tonic-gate */
196*12573SDina.Nimeh@Sun.COM static CK_RV
generate_rsa_key(RSAkey * key,int psize,int qsize,BIGNUM * pubexp,int (* rfunc)(void *,size_t))197*12573SDina.Nimeh@Sun.COM generate_rsa_key(RSAkey *key, int psize, int qsize, BIGNUM *pubexp,
198*12573SDina.Nimeh@Sun.COM int (*rfunc)(void *, size_t))
1990Sstevel@tonic-gate {
200*12573SDina.Nimeh@Sun.COM CK_RV rv = CKR_OK;
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate /* EXPORT DELETE START */
2030Sstevel@tonic-gate
204*12573SDina.Nimeh@Sun.COM int (*rf)(void *, size_t);
205*12573SDina.Nimeh@Sun.COM BIGNUM a, b, c, d, e, f, g, h;
206*12573SDina.Nimeh@Sun.COM int len, keylen, size;
207*12573SDina.Nimeh@Sun.COM BIG_ERR_CODE brv = BIG_OK;
208*12573SDina.Nimeh@Sun.COM
209*12573SDina.Nimeh@Sun.COM size = psize + qsize;
210*12573SDina.Nimeh@Sun.COM keylen = BITLEN2BIGNUMLEN(size);
211*12573SDina.Nimeh@Sun.COM len = keylen * 2 + 1;
212*12573SDina.Nimeh@Sun.COM key->size = size;
213*12573SDina.Nimeh@Sun.COM
214*12573SDina.Nimeh@Sun.COM /*
215*12573SDina.Nimeh@Sun.COM * Note: It is not really necessary to compute e, it is in pubexp:
216*12573SDina.Nimeh@Sun.COM * (void) big_copy(&(key->e), pubexp);
217*12573SDina.Nimeh@Sun.COM */
218*12573SDina.Nimeh@Sun.COM
219*12573SDina.Nimeh@Sun.COM a.malloced = 0;
220*12573SDina.Nimeh@Sun.COM b.malloced = 0;
221*12573SDina.Nimeh@Sun.COM c.malloced = 0;
222*12573SDina.Nimeh@Sun.COM d.malloced = 0;
223*12573SDina.Nimeh@Sun.COM e.malloced = 0;
224*12573SDina.Nimeh@Sun.COM f.malloced = 0;
225*12573SDina.Nimeh@Sun.COM g.malloced = 0;
226*12573SDina.Nimeh@Sun.COM h.malloced = 0;
2270Sstevel@tonic-gate
228*12573SDina.Nimeh@Sun.COM if ((big_init(&a, len) != BIG_OK) ||
229*12573SDina.Nimeh@Sun.COM (big_init(&b, len) != BIG_OK) ||
230*12573SDina.Nimeh@Sun.COM (big_init(&c, len) != BIG_OK) ||
231*12573SDina.Nimeh@Sun.COM (big_init(&d, len) != BIG_OK) ||
232*12573SDina.Nimeh@Sun.COM (big_init(&e, len) != BIG_OK) ||
233*12573SDina.Nimeh@Sun.COM (big_init(&f, len) != BIG_OK) ||
234*12573SDina.Nimeh@Sun.COM (big_init(&g, len) != BIG_OK) ||
235*12573SDina.Nimeh@Sun.COM (big_init(&h, len) != BIG_OK)) {
236*12573SDina.Nimeh@Sun.COM big_finish(&h);
237*12573SDina.Nimeh@Sun.COM big_finish(&g);
238*12573SDina.Nimeh@Sun.COM big_finish(&f);
239*12573SDina.Nimeh@Sun.COM big_finish(&e);
240*12573SDina.Nimeh@Sun.COM big_finish(&d);
241*12573SDina.Nimeh@Sun.COM big_finish(&c);
242*12573SDina.Nimeh@Sun.COM big_finish(&b);
243*12573SDina.Nimeh@Sun.COM big_finish(&a);
244*12573SDina.Nimeh@Sun.COM
245*12573SDina.Nimeh@Sun.COM return (CKR_HOST_MEMORY);
246*12573SDina.Nimeh@Sun.COM }
247*12573SDina.Nimeh@Sun.COM
248*12573SDina.Nimeh@Sun.COM rf = rfunc;
249*12573SDina.Nimeh@Sun.COM if (rf == NULL) {
250*12573SDina.Nimeh@Sun.COM #ifdef _KERNEL
251*12573SDina.Nimeh@Sun.COM rf = (int (*)(void *, size_t))random_get_pseudo_bytes;
252*12573SDina.Nimeh@Sun.COM #else
253*12573SDina.Nimeh@Sun.COM rf = pkcs11_get_urandom;
254*12573SDina.Nimeh@Sun.COM #endif
255*12573SDina.Nimeh@Sun.COM }
256*12573SDina.Nimeh@Sun.COM
257*12573SDina.Nimeh@Sun.COM nextp:
258*12573SDina.Nimeh@Sun.COM if ((brv = big_random(&a, psize, rf)) != BIG_OK) {
259*12573SDina.Nimeh@Sun.COM goto ret;
260*12573SDina.Nimeh@Sun.COM }
261*12573SDina.Nimeh@Sun.COM
262*12573SDina.Nimeh@Sun.COM if ((brv = big_nextprime_pos(&b, &a)) != BIG_OK) {
263*12573SDina.Nimeh@Sun.COM goto ret;
264*12573SDina.Nimeh@Sun.COM }
265*12573SDina.Nimeh@Sun.COM /* b now contains the potential prime p */
266*12573SDina.Nimeh@Sun.COM
267*12573SDina.Nimeh@Sun.COM (void) big_sub_pos(&a, &b, &big_One);
268*12573SDina.Nimeh@Sun.COM if ((brv = big_ext_gcd_pos(&f, &d, &g, pubexp, &a)) != BIG_OK) {
269*12573SDina.Nimeh@Sun.COM goto ret;
270*12573SDina.Nimeh@Sun.COM }
271*12573SDina.Nimeh@Sun.COM if (big_cmp_abs(&f, &big_One) != 0) {
272*12573SDina.Nimeh@Sun.COM goto nextp;
273*12573SDina.Nimeh@Sun.COM }
274*12573SDina.Nimeh@Sun.COM
275*12573SDina.Nimeh@Sun.COM if ((brv = big_random(&c, qsize, rf)) != BIG_OK) {
276*12573SDina.Nimeh@Sun.COM goto ret;
2770Sstevel@tonic-gate }
2780Sstevel@tonic-gate
279*12573SDina.Nimeh@Sun.COM nextq:
280*12573SDina.Nimeh@Sun.COM (void) big_add(&a, &c, &big_Two);
281*12573SDina.Nimeh@Sun.COM
282*12573SDina.Nimeh@Sun.COM if (big_bitlength(&a) != qsize) {
283*12573SDina.Nimeh@Sun.COM goto nextp;
284*12573SDina.Nimeh@Sun.COM }
285*12573SDina.Nimeh@Sun.COM if (big_cmp_abs(&a, &b) == 0) {
286*12573SDina.Nimeh@Sun.COM goto nextp;
287*12573SDina.Nimeh@Sun.COM }
288*12573SDina.Nimeh@Sun.COM if ((brv = big_nextprime_pos(&c, &a)) != BIG_OK) {
289*12573SDina.Nimeh@Sun.COM goto ret;
290*12573SDina.Nimeh@Sun.COM }
291*12573SDina.Nimeh@Sun.COM /* c now contains the potential prime q */
292*12573SDina.Nimeh@Sun.COM
293*12573SDina.Nimeh@Sun.COM if ((brv = big_mul(&g, &b, &c)) != BIG_OK) {
294*12573SDina.Nimeh@Sun.COM goto ret;
295*12573SDina.Nimeh@Sun.COM }
296*12573SDina.Nimeh@Sun.COM if (big_bitlength(&g) != size) {
297*12573SDina.Nimeh@Sun.COM goto nextp;
298*12573SDina.Nimeh@Sun.COM }
299*12573SDina.Nimeh@Sun.COM /* g now contains the potential modulus n */
300*12573SDina.Nimeh@Sun.COM
301*12573SDina.Nimeh@Sun.COM (void) big_sub_pos(&a, &b, &big_One);
302*12573SDina.Nimeh@Sun.COM (void) big_sub_pos(&d, &c, &big_One);
303*12573SDina.Nimeh@Sun.COM
304*12573SDina.Nimeh@Sun.COM if ((brv = big_mul(&a, &a, &d)) != BIG_OK) {
305*12573SDina.Nimeh@Sun.COM goto ret;
306*12573SDina.Nimeh@Sun.COM }
307*12573SDina.Nimeh@Sun.COM if ((brv = big_ext_gcd_pos(&f, &d, &h, pubexp, &a)) != BIG_OK) {
308*12573SDina.Nimeh@Sun.COM goto ret;
309*12573SDina.Nimeh@Sun.COM }
310*12573SDina.Nimeh@Sun.COM if (big_cmp_abs(&f, &big_One) != 0) {
311*12573SDina.Nimeh@Sun.COM goto nextq;
312*12573SDina.Nimeh@Sun.COM } else {
313*12573SDina.Nimeh@Sun.COM (void) big_copy(&e, pubexp);
314*12573SDina.Nimeh@Sun.COM }
315*12573SDina.Nimeh@Sun.COM if (d.sign == -1) {
316*12573SDina.Nimeh@Sun.COM if ((brv = big_add(&d, &d, &a)) != BIG_OK) {
317*12573SDina.Nimeh@Sun.COM goto ret;
318*12573SDina.Nimeh@Sun.COM }
319*12573SDina.Nimeh@Sun.COM }
320*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->p), &b);
321*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->q), &c);
322*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->n), &g);
323*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->d), &d);
324*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->e), &e);
325*12573SDina.Nimeh@Sun.COM
326*12573SDina.Nimeh@Sun.COM if ((brv = big_ext_gcd_pos(&a, &f, &h, &b, &c)) != BIG_OK) {
327*12573SDina.Nimeh@Sun.COM goto ret;
3280Sstevel@tonic-gate }
329*12573SDina.Nimeh@Sun.COM if (f.sign == -1) {
330*12573SDina.Nimeh@Sun.COM if ((brv = big_add(&f, &f, &c)) != BIG_OK) {
331*12573SDina.Nimeh@Sun.COM goto ret;
332*12573SDina.Nimeh@Sun.COM }
333*12573SDina.Nimeh@Sun.COM }
334*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->pinvmodq), &f);
335*12573SDina.Nimeh@Sun.COM
336*12573SDina.Nimeh@Sun.COM (void) big_sub(&a, &b, &big_One);
337*12573SDina.Nimeh@Sun.COM if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
338*12573SDina.Nimeh@Sun.COM goto ret;
339*12573SDina.Nimeh@Sun.COM }
340*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->dmodpminus1), &f);
341*12573SDina.Nimeh@Sun.COM (void) big_sub(&a, &c, &big_One);
342*12573SDina.Nimeh@Sun.COM if ((brv = big_div_pos(&a, &f, &d, &a)) != BIG_OK) {
343*12573SDina.Nimeh@Sun.COM goto ret;
344*12573SDina.Nimeh@Sun.COM }
345*12573SDina.Nimeh@Sun.COM (void) big_copy(&(key->dmodqminus1), &f);
3460Sstevel@tonic-gate
347*12573SDina.Nimeh@Sun.COM /* pairwise consistency check: decrypt and encrypt restores value */
348*12573SDina.Nimeh@Sun.COM if ((brv = big_random(&h, size, rf)) != BIG_OK) {
349*12573SDina.Nimeh@Sun.COM goto ret;
350*12573SDina.Nimeh@Sun.COM }
351*12573SDina.Nimeh@Sun.COM if ((brv = big_div_pos(&a, &h, &h, &g)) != BIG_OK) {
352*12573SDina.Nimeh@Sun.COM goto ret;
353*12573SDina.Nimeh@Sun.COM }
354*12573SDina.Nimeh@Sun.COM if ((brv = big_modexp(&a, &h, &d, &g, NULL)) != BIG_OK) {
355*12573SDina.Nimeh@Sun.COM goto ret;
356*12573SDina.Nimeh@Sun.COM }
357*12573SDina.Nimeh@Sun.COM
358*12573SDina.Nimeh@Sun.COM if ((brv = big_modexp(&b, &a, &e, &g, NULL)) != BIG_OK) {
359*12573SDina.Nimeh@Sun.COM goto ret;
360*12573SDina.Nimeh@Sun.COM }
361*12573SDina.Nimeh@Sun.COM
362*12573SDina.Nimeh@Sun.COM if (big_cmp_abs(&b, &h) != 0) {
363*12573SDina.Nimeh@Sun.COM /* this should not happen */
364*12573SDina.Nimeh@Sun.COM rv = generate_rsa_key(key, psize, qsize, pubexp, rf);
365*12573SDina.Nimeh@Sun.COM goto ret1;
366*12573SDina.Nimeh@Sun.COM } else {
367*12573SDina.Nimeh@Sun.COM brv = BIG_OK;
368*12573SDina.Nimeh@Sun.COM }
369*12573SDina.Nimeh@Sun.COM
370*12573SDina.Nimeh@Sun.COM ret:
371*12573SDina.Nimeh@Sun.COM rv = convert_rv(brv);
372*12573SDina.Nimeh@Sun.COM ret1:
373*12573SDina.Nimeh@Sun.COM big_finish(&h);
374*12573SDina.Nimeh@Sun.COM big_finish(&g);
375*12573SDina.Nimeh@Sun.COM big_finish(&f);
376*12573SDina.Nimeh@Sun.COM big_finish(&e);
377*12573SDina.Nimeh@Sun.COM big_finish(&d);
378*12573SDina.Nimeh@Sun.COM big_finish(&c);
379*12573SDina.Nimeh@Sun.COM big_finish(&b);
380*12573SDina.Nimeh@Sun.COM big_finish(&a);
3810Sstevel@tonic-gate
3820Sstevel@tonic-gate /* EXPORT DELETE END */
3830Sstevel@tonic-gate
384*12573SDina.Nimeh@Sun.COM return (rv);
3850Sstevel@tonic-gate }
3860Sstevel@tonic-gate
3870Sstevel@tonic-gate CK_RV
rsa_genkey_pair(RSAbytekey * bkey)388*12573SDina.Nimeh@Sun.COM rsa_genkey_pair(RSAbytekey *bkey)
3890Sstevel@tonic-gate {
390*12573SDina.Nimeh@Sun.COM /*
391*12573SDina.Nimeh@Sun.COM * NOTE: Whomever originally wrote this function swapped p and q.
392*12573SDina.Nimeh@Sun.COM * This table shows the mapping between name convention used here
393*12573SDina.Nimeh@Sun.COM * versus what is used in most texts that describe RSA key generation.
394*12573SDina.Nimeh@Sun.COM * This function: Standard convention:
395*12573SDina.Nimeh@Sun.COM * -------------- --------------------
396*12573SDina.Nimeh@Sun.COM * modulus, n -same-
397*12573SDina.Nimeh@Sun.COM * prime 1, q prime 1, p
398*12573SDina.Nimeh@Sun.COM * prime 2, p prime 2, q
399*12573SDina.Nimeh@Sun.COM * private exponent, d -same-
400*12573SDina.Nimeh@Sun.COM * public exponent, e -same-
401*12573SDina.Nimeh@Sun.COM * exponent 1, d mod (q-1) d mod (p-1)
402*12573SDina.Nimeh@Sun.COM * exponent 2, d mod (p-1) d mod (q-1)
403*12573SDina.Nimeh@Sun.COM * coefficient, p^-1 mod q q^-1 mod p
404*12573SDina.Nimeh@Sun.COM *
405*12573SDina.Nimeh@Sun.COM * Also notice the struct member for coefficient is named .pinvmodq
406*12573SDina.Nimeh@Sun.COM * rather than .qinvmodp, reflecting the switch.
407*12573SDina.Nimeh@Sun.COM *
408*12573SDina.Nimeh@Sun.COM * The code here wasn't unswapped, because "it works". Further,
409*12573SDina.Nimeh@Sun.COM * p and q are interchangeable as long as exponent 1 and 2 and
410*12573SDina.Nimeh@Sun.COM * the coefficient are kept straight too. This note is here to
411*12573SDina.Nimeh@Sun.COM * make the reader aware of the switcheroo.
412*12573SDina.Nimeh@Sun.COM */
413*12573SDina.Nimeh@Sun.COM CK_RV rv = CKR_OK;
4140Sstevel@tonic-gate
4150Sstevel@tonic-gate /* EXPORT DELETE START */
4160Sstevel@tonic-gate
417*12573SDina.Nimeh@Sun.COM BIGNUM public_exponent = {0};
418*12573SDina.Nimeh@Sun.COM RSAkey rsakey;
419*12573SDina.Nimeh@Sun.COM uint32_t modulus_bytes;
420*12573SDina.Nimeh@Sun.COM
421*12573SDina.Nimeh@Sun.COM if (bkey == NULL)
422*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
423*12573SDina.Nimeh@Sun.COM
424*12573SDina.Nimeh@Sun.COM /* Must have modulus bits set */
425*12573SDina.Nimeh@Sun.COM if (bkey->modulus_bits == 0)
426*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
427*12573SDina.Nimeh@Sun.COM
428*12573SDina.Nimeh@Sun.COM /* Must have public exponent set */
429*12573SDina.Nimeh@Sun.COM if (bkey->pubexpo_bytes == 0 || bkey->pubexpo == NULL)
430*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
4310Sstevel@tonic-gate
432*12573SDina.Nimeh@Sun.COM /* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
433*12573SDina.Nimeh@Sun.COM modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
434*12573SDina.Nimeh@Sun.COM
435*12573SDina.Nimeh@Sun.COM /* Modulus length needs to be between min key size and max key size. */
436*12573SDina.Nimeh@Sun.COM if ((modulus_bytes < MIN_RSA_KEYLENGTH_IN_BYTES) ||
437*12573SDina.Nimeh@Sun.COM (modulus_bytes > MAX_RSA_KEYLENGTH_IN_BYTES)) {
438*12573SDina.Nimeh@Sun.COM return (CKR_KEY_SIZE_RANGE);
439*12573SDina.Nimeh@Sun.COM }
440*12573SDina.Nimeh@Sun.COM
441*12573SDina.Nimeh@Sun.COM /*
442*12573SDina.Nimeh@Sun.COM * Initialize the RSA key.
443*12573SDina.Nimeh@Sun.COM */
444*12573SDina.Nimeh@Sun.COM if (RSA_key_init(&rsakey, modulus_bytes * 4, modulus_bytes * 4) !=
445*12573SDina.Nimeh@Sun.COM BIG_OK) {
446*12573SDina.Nimeh@Sun.COM return (CKR_HOST_MEMORY);
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate
449*12573SDina.Nimeh@Sun.COM /* Create a public exponent in bignum format. */
450*12573SDina.Nimeh@Sun.COM if (big_init(&public_exponent,
451*12573SDina.Nimeh@Sun.COM CHARLEN2BIGNUMLEN(bkey->pubexpo_bytes)) != BIG_OK) {
452*12573SDina.Nimeh@Sun.COM rv = CKR_HOST_MEMORY;
453*12573SDina.Nimeh@Sun.COM goto clean1;
454*12573SDina.Nimeh@Sun.COM }
455*12573SDina.Nimeh@Sun.COM bytestring2bignum(&public_exponent, bkey->pubexpo, bkey->pubexpo_bytes);
456*12573SDina.Nimeh@Sun.COM
457*12573SDina.Nimeh@Sun.COM /* Generate RSA key pair. */
458*12573SDina.Nimeh@Sun.COM if ((rv = generate_rsa_key(&rsakey,
459*12573SDina.Nimeh@Sun.COM modulus_bytes * 4, modulus_bytes * 4, &public_exponent,
460*12573SDina.Nimeh@Sun.COM bkey->rfunc)) != CKR_OK) {
461*12573SDina.Nimeh@Sun.COM big_finish(&public_exponent);
462*12573SDina.Nimeh@Sun.COM goto clean1;
463*12573SDina.Nimeh@Sun.COM }
464*12573SDina.Nimeh@Sun.COM big_finish(&public_exponent);
465*12573SDina.Nimeh@Sun.COM
466*12573SDina.Nimeh@Sun.COM /* modulus_bytes = rsakey.n.len * (int)sizeof (BIG_CHUNK_TYPE); */
467*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->modulus, &(rsakey.n), modulus_bytes);
468*12573SDina.Nimeh@Sun.COM
469*12573SDina.Nimeh@Sun.COM bkey->privexpo_bytes = rsakey.d.len * (int)sizeof (BIG_CHUNK_TYPE);
470*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->privexpo, &(rsakey.d), bkey->privexpo_bytes);
4710Sstevel@tonic-gate
472*12573SDina.Nimeh@Sun.COM bkey->pubexpo_bytes = rsakey.e.len * (int)sizeof (BIG_CHUNK_TYPE);
473*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->pubexpo, &(rsakey.e), bkey->pubexpo_bytes);
474*12573SDina.Nimeh@Sun.COM
475*12573SDina.Nimeh@Sun.COM bkey->prime1_bytes = rsakey.q.len * (int)sizeof (BIG_CHUNK_TYPE);
476*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->prime1, &(rsakey.q), bkey->prime1_bytes);
477*12573SDina.Nimeh@Sun.COM
478*12573SDina.Nimeh@Sun.COM bkey->prime2_bytes = rsakey.p.len * (int)sizeof (BIG_CHUNK_TYPE);
479*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->prime2, &(rsakey.p), bkey->prime2_bytes);
480*12573SDina.Nimeh@Sun.COM
481*12573SDina.Nimeh@Sun.COM bkey->expo1_bytes =
482*12573SDina.Nimeh@Sun.COM rsakey.dmodqminus1.len * (int)sizeof (BIG_CHUNK_TYPE);
483*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->expo1, &(rsakey.dmodqminus1),
484*12573SDina.Nimeh@Sun.COM bkey->expo1_bytes);
485*12573SDina.Nimeh@Sun.COM
486*12573SDina.Nimeh@Sun.COM bkey->expo2_bytes =
487*12573SDina.Nimeh@Sun.COM rsakey.dmodpminus1.len * (int)sizeof (BIG_CHUNK_TYPE);
488*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->expo2,
489*12573SDina.Nimeh@Sun.COM &(rsakey.dmodpminus1), bkey->expo2_bytes);
490*12573SDina.Nimeh@Sun.COM
491*12573SDina.Nimeh@Sun.COM bkey->coeff_bytes =
492*12573SDina.Nimeh@Sun.COM rsakey.pinvmodq.len * (int)sizeof (BIG_CHUNK_TYPE);
493*12573SDina.Nimeh@Sun.COM bignum2bytestring(bkey->coeff, &(rsakey.pinvmodq), bkey->coeff_bytes);
494*12573SDina.Nimeh@Sun.COM
495*12573SDina.Nimeh@Sun.COM clean1:
496*12573SDina.Nimeh@Sun.COM RSA_key_finish(&rsakey);
4970Sstevel@tonic-gate
4980Sstevel@tonic-gate /* EXPORT DELETE END */
4990Sstevel@tonic-gate
500*12573SDina.Nimeh@Sun.COM return (rv);
5010Sstevel@tonic-gate }
5020Sstevel@tonic-gate
5030Sstevel@tonic-gate /*
504*12573SDina.Nimeh@Sun.COM * RSA encrypt operation
5050Sstevel@tonic-gate */
5060Sstevel@tonic-gate CK_RV
rsa_encrypt(RSAbytekey * bkey,uchar_t * in,uint32_t in_len,uchar_t * out)507*12573SDina.Nimeh@Sun.COM rsa_encrypt(RSAbytekey *bkey, uchar_t *in, uint32_t in_len, uchar_t *out)
5080Sstevel@tonic-gate {
509*12573SDina.Nimeh@Sun.COM CK_RV rv = CKR_OK;
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate /* EXPORT DELETE START */
5120Sstevel@tonic-gate
513*12573SDina.Nimeh@Sun.COM BIGNUM msg;
514*12573SDina.Nimeh@Sun.COM RSAkey rsakey;
515*12573SDina.Nimeh@Sun.COM uint32_t modulus_bytes;
516*12573SDina.Nimeh@Sun.COM
517*12573SDina.Nimeh@Sun.COM if (bkey == NULL)
518*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
519*12573SDina.Nimeh@Sun.COM
520*12573SDina.Nimeh@Sun.COM /* Must have modulus and public exponent set */
521*12573SDina.Nimeh@Sun.COM if (bkey->modulus_bits == 0 || bkey->modulus == NULL ||
522*12573SDina.Nimeh@Sun.COM bkey->pubexpo_bytes == 0 || bkey->pubexpo == NULL)
523*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
5240Sstevel@tonic-gate
525*12573SDina.Nimeh@Sun.COM /* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
526*12573SDina.Nimeh@Sun.COM modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
527*12573SDina.Nimeh@Sun.COM
528*12573SDina.Nimeh@Sun.COM if (bkey->pubexpo_bytes > modulus_bytes) {
529*12573SDina.Nimeh@Sun.COM return (CKR_KEY_SIZE_RANGE);
530*12573SDina.Nimeh@Sun.COM }
531*12573SDina.Nimeh@Sun.COM
532*12573SDina.Nimeh@Sun.COM /* psize and qsize for RSA_key_init is in bits. */
533*12573SDina.Nimeh@Sun.COM if (RSA_key_init(&rsakey, modulus_bytes * 4, modulus_bytes * 4) !=
534*12573SDina.Nimeh@Sun.COM BIG_OK) {
535*12573SDina.Nimeh@Sun.COM return (CKR_HOST_MEMORY);
5360Sstevel@tonic-gate }
5370Sstevel@tonic-gate
538*12573SDina.Nimeh@Sun.COM /* Size for big_init is in BIG_CHUNK_TYPE words. */
539*12573SDina.Nimeh@Sun.COM if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
540*12573SDina.Nimeh@Sun.COM rv = CKR_HOST_MEMORY;
541*12573SDina.Nimeh@Sun.COM goto clean2;
542*12573SDina.Nimeh@Sun.COM }
543*12573SDina.Nimeh@Sun.COM bytestring2bignum(&msg, in, in_len);
544*12573SDina.Nimeh@Sun.COM
545*12573SDina.Nimeh@Sun.COM /* Convert public exponent and modulus to big integer format. */
546*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.e), bkey->pubexpo, bkey->pubexpo_bytes);
547*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.n), bkey->modulus, modulus_bytes);
548*12573SDina.Nimeh@Sun.COM
549*12573SDina.Nimeh@Sun.COM if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
550*12573SDina.Nimeh@Sun.COM rv = CKR_DATA_LEN_RANGE;
551*12573SDina.Nimeh@Sun.COM goto clean3;
552*12573SDina.Nimeh@Sun.COM }
553*12573SDina.Nimeh@Sun.COM
554*12573SDina.Nimeh@Sun.COM /* Perform RSA computation on big integer input data. */
555*12573SDina.Nimeh@Sun.COM if (big_modexp(&msg, &msg, &(rsakey.e), &(rsakey.n), NULL) !=
556*12573SDina.Nimeh@Sun.COM BIG_OK) {
557*12573SDina.Nimeh@Sun.COM rv = CKR_HOST_MEMORY;
558*12573SDina.Nimeh@Sun.COM goto clean3;
559*12573SDina.Nimeh@Sun.COM }
560*12573SDina.Nimeh@Sun.COM
561*12573SDina.Nimeh@Sun.COM /* Convert the big integer output data to octet string. */
562*12573SDina.Nimeh@Sun.COM bignum2bytestring(out, &msg, modulus_bytes);
563*12573SDina.Nimeh@Sun.COM
564*12573SDina.Nimeh@Sun.COM clean3:
565*12573SDina.Nimeh@Sun.COM big_finish(&msg);
566*12573SDina.Nimeh@Sun.COM clean2:
567*12573SDina.Nimeh@Sun.COM RSA_key_finish(&rsakey);
5680Sstevel@tonic-gate
5690Sstevel@tonic-gate /* EXPORT DELETE END */
5700Sstevel@tonic-gate
571*12573SDina.Nimeh@Sun.COM return (rv);
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate
574*12573SDina.Nimeh@Sun.COM /*
575*12573SDina.Nimeh@Sun.COM * RSA decrypt operation
576*12573SDina.Nimeh@Sun.COM */
5770Sstevel@tonic-gate CK_RV
rsa_decrypt(RSAbytekey * bkey,uchar_t * in,uint32_t in_len,uchar_t * out)578*12573SDina.Nimeh@Sun.COM rsa_decrypt(RSAbytekey *bkey, uchar_t *in, uint32_t in_len, uchar_t *out)
5790Sstevel@tonic-gate {
580*12573SDina.Nimeh@Sun.COM CK_RV rv = CKR_OK;
5810Sstevel@tonic-gate
5820Sstevel@tonic-gate /* EXPORT DELETE START */
5830Sstevel@tonic-gate
584*12573SDina.Nimeh@Sun.COM BIGNUM msg;
585*12573SDina.Nimeh@Sun.COM RSAkey rsakey;
586*12573SDina.Nimeh@Sun.COM uint32_t modulus_bytes;
587*12573SDina.Nimeh@Sun.COM
588*12573SDina.Nimeh@Sun.COM if (bkey == NULL)
589*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
5900Sstevel@tonic-gate
591*12573SDina.Nimeh@Sun.COM /* Must have modulus, prime1, prime2, expo1, expo2, and coeff set */
592*12573SDina.Nimeh@Sun.COM if (bkey->modulus_bits == 0 || bkey->modulus == NULL ||
593*12573SDina.Nimeh@Sun.COM bkey->prime1_bytes == 0 || bkey->prime1 == NULL ||
594*12573SDina.Nimeh@Sun.COM bkey->prime2_bytes == 0 || bkey->prime2 == NULL ||
595*12573SDina.Nimeh@Sun.COM bkey->expo1_bytes == 0 || bkey->expo1 == NULL ||
596*12573SDina.Nimeh@Sun.COM bkey->expo2_bytes == 0 || bkey->expo2 == NULL ||
597*12573SDina.Nimeh@Sun.COM bkey->coeff_bytes == 0 || bkey->coeff == NULL)
598*12573SDina.Nimeh@Sun.COM return (CKR_ARGUMENTS_BAD);
599*12573SDina.Nimeh@Sun.COM
600*12573SDina.Nimeh@Sun.COM /* Note: modulus_bits may not be same as (8 * sizeof (modulus)) */
601*12573SDina.Nimeh@Sun.COM modulus_bytes = CRYPTO_BITS2BYTES(bkey->modulus_bits);
602*12573SDina.Nimeh@Sun.COM
603*12573SDina.Nimeh@Sun.COM /* psize and qsize for RSA_key_init is in bits. */
604*12573SDina.Nimeh@Sun.COM if (RSA_key_init(&rsakey, CRYPTO_BYTES2BITS(bkey->prime2_bytes),
605*12573SDina.Nimeh@Sun.COM CRYPTO_BYTES2BITS(bkey->prime1_bytes)) != BIG_OK) {
606*12573SDina.Nimeh@Sun.COM return (CKR_HOST_MEMORY);
607*12573SDina.Nimeh@Sun.COM }
608*12573SDina.Nimeh@Sun.COM
609*12573SDina.Nimeh@Sun.COM /* Size for big_init is in BIG_CHUNK_TYPE words. */
610*12573SDina.Nimeh@Sun.COM if (big_init(&msg, CHARLEN2BIGNUMLEN(in_len)) != BIG_OK) {
611*12573SDina.Nimeh@Sun.COM rv = CKR_HOST_MEMORY;
612*12573SDina.Nimeh@Sun.COM goto clean3;
6130Sstevel@tonic-gate }
614*12573SDina.Nimeh@Sun.COM /* Convert octet string input data to big integer format. */
615*12573SDina.Nimeh@Sun.COM bytestring2bignum(&msg, in, in_len);
616*12573SDina.Nimeh@Sun.COM
617*12573SDina.Nimeh@Sun.COM /* Convert octet string modulus to big integer format. */
618*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.n), bkey->modulus, modulus_bytes);
619*12573SDina.Nimeh@Sun.COM
620*12573SDina.Nimeh@Sun.COM if (big_cmp_abs(&msg, &(rsakey.n)) > 0) {
621*12573SDina.Nimeh@Sun.COM rv = CKR_DATA_LEN_RANGE;
622*12573SDina.Nimeh@Sun.COM goto clean4;
623*12573SDina.Nimeh@Sun.COM }
624*12573SDina.Nimeh@Sun.COM
625*12573SDina.Nimeh@Sun.COM /* Convert the rest of private key attributes to big integer format. */
626*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.q), bkey->prime1, bkey->prime1_bytes);
627*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.p), bkey->prime2, bkey->prime2_bytes);
628*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.dmodqminus1),
629*12573SDina.Nimeh@Sun.COM bkey->expo1, bkey->expo1_bytes);
630*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.dmodpminus1),
631*12573SDina.Nimeh@Sun.COM bkey->expo2, bkey->expo2_bytes);
632*12573SDina.Nimeh@Sun.COM bytestring2bignum(&(rsakey.pinvmodq),
633*12573SDina.Nimeh@Sun.COM bkey->coeff, bkey->coeff_bytes);
6340Sstevel@tonic-gate
635*12573SDina.Nimeh@Sun.COM if ((big_cmp_abs(&(rsakey.dmodpminus1), &(rsakey.p)) > 0) ||
636*12573SDina.Nimeh@Sun.COM (big_cmp_abs(&(rsakey.dmodqminus1), &(rsakey.q)) > 0) ||
637*12573SDina.Nimeh@Sun.COM (big_cmp_abs(&(rsakey.pinvmodq), &(rsakey.q)) > 0)) {
638*12573SDina.Nimeh@Sun.COM rv = CKR_KEY_SIZE_RANGE;
639*12573SDina.Nimeh@Sun.COM goto clean4;
6400Sstevel@tonic-gate }
6410Sstevel@tonic-gate
642*12573SDina.Nimeh@Sun.COM /* Perform RSA computation on big integer input data. */
643*12573SDina.Nimeh@Sun.COM if (big_modexp_crt(&msg, &msg, &(rsakey.dmodpminus1),
644*12573SDina.Nimeh@Sun.COM &(rsakey.dmodqminus1), &(rsakey.p), &(rsakey.q),
645*12573SDina.Nimeh@Sun.COM &(rsakey.pinvmodq), NULL, NULL) != BIG_OK) {
646*12573SDina.Nimeh@Sun.COM rv = CKR_HOST_MEMORY;
647*12573SDina.Nimeh@Sun.COM goto clean4;
648*12573SDina.Nimeh@Sun.COM }
649*12573SDina.Nimeh@Sun.COM
650*12573SDina.Nimeh@Sun.COM /* Convert the big integer output data to octet string. */
651*12573SDina.Nimeh@Sun.COM bignum2bytestring(out, &msg, modulus_bytes);
652*12573SDina.Nimeh@Sun.COM
653*12573SDina.Nimeh@Sun.COM clean4:
654*12573SDina.Nimeh@Sun.COM big_finish(&msg);
655*12573SDina.Nimeh@Sun.COM clean3:
656*12573SDina.Nimeh@Sun.COM RSA_key_finish(&rsakey);
657*12573SDina.Nimeh@Sun.COM
6580Sstevel@tonic-gate /* EXPORT DELETE END */
6590Sstevel@tonic-gate
660*12573SDina.Nimeh@Sun.COM return (rv);
6610Sstevel@tonic-gate }
662