xref: /onnv-gate/usr/src/common/openssl/crypto/rsa/rsa_eay.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /* crypto/rsa/rsa_eay.c */
2*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3*0Sstevel@tonic-gate  * All rights reserved.
4*0Sstevel@tonic-gate  *
5*0Sstevel@tonic-gate  * This package is an SSL implementation written
6*0Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
7*0Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
10*0Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
11*0Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
12*0Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13*0Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
14*0Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15*0Sstevel@tonic-gate  *
16*0Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
17*0Sstevel@tonic-gate  * the code are not to be removed.
18*0Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
19*0Sstevel@tonic-gate  * as the author of the parts of the library used.
20*0Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
21*0Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
22*0Sstevel@tonic-gate  *
23*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
24*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
25*0Sstevel@tonic-gate  * are met:
26*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
27*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
28*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
29*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
30*0Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
31*0Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
32*0Sstevel@tonic-gate  *    must display the following acknowledgement:
33*0Sstevel@tonic-gate  *    "This product includes cryptographic software written by
34*0Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
35*0Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
36*0Sstevel@tonic-gate  *    being used are not cryptographic related :-).
37*0Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
38*0Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
39*0Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40*0Sstevel@tonic-gate  *
41*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42*0Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43*0Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44*0Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45*0Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46*0Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47*0Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48*0Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49*0Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50*0Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51*0Sstevel@tonic-gate  * SUCH DAMAGE.
52*0Sstevel@tonic-gate  *
53*0Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
54*0Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55*0Sstevel@tonic-gate  * copied and put under another distribution licence
56*0Sstevel@tonic-gate  * [including the GNU Public Licence.]
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate #include <stdio.h>
60*0Sstevel@tonic-gate #include "cryptlib.h"
61*0Sstevel@tonic-gate #include <openssl/bn.h>
62*0Sstevel@tonic-gate #include <openssl/rsa.h>
63*0Sstevel@tonic-gate #include <openssl/rand.h>
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate #ifndef RSA_NULL
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
68*0Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
69*0Sstevel@tonic-gate static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
70*0Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
71*0Sstevel@tonic-gate static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
72*0Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
73*0Sstevel@tonic-gate static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
74*0Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
75*0Sstevel@tonic-gate static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa);
76*0Sstevel@tonic-gate static int RSA_eay_init(RSA *rsa);
77*0Sstevel@tonic-gate static int RSA_eay_finish(RSA *rsa);
78*0Sstevel@tonic-gate static RSA_METHOD rsa_pkcs1_eay_meth={
79*0Sstevel@tonic-gate 	"Eric Young's PKCS#1 RSA",
80*0Sstevel@tonic-gate 	RSA_eay_public_encrypt,
81*0Sstevel@tonic-gate 	RSA_eay_public_decrypt, /* signature verification */
82*0Sstevel@tonic-gate 	RSA_eay_private_encrypt, /* signing */
83*0Sstevel@tonic-gate 	RSA_eay_private_decrypt,
84*0Sstevel@tonic-gate 	RSA_eay_mod_exp,
85*0Sstevel@tonic-gate 	BN_mod_exp_mont, /* XXX probably we should not use Montgomery if  e == 3 */
86*0Sstevel@tonic-gate 	RSA_eay_init,
87*0Sstevel@tonic-gate 	RSA_eay_finish,
88*0Sstevel@tonic-gate 	0, /* flags */
89*0Sstevel@tonic-gate 	NULL,
90*0Sstevel@tonic-gate 	0, /* rsa_sign */
91*0Sstevel@tonic-gate 	0  /* rsa_verify */
92*0Sstevel@tonic-gate 	};
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate const RSA_METHOD *RSA_PKCS1_SSLeay(void)
95*0Sstevel@tonic-gate 	{
96*0Sstevel@tonic-gate 	return(&rsa_pkcs1_eay_meth);
97*0Sstevel@tonic-gate 	}
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
100*0Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
101*0Sstevel@tonic-gate 	{
102*0Sstevel@tonic-gate 	BIGNUM f,ret;
103*0Sstevel@tonic-gate 	int i,j,k,num=0,r= -1;
104*0Sstevel@tonic-gate 	unsigned char *buf=NULL;
105*0Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate 	BN_init(&f);
108*0Sstevel@tonic-gate 	BN_init(&ret);
109*0Sstevel@tonic-gate 	if ((ctx=BN_CTX_new()) == NULL) goto err;
110*0Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
111*0Sstevel@tonic-gate 	if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
112*0Sstevel@tonic-gate 		{
113*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
114*0Sstevel@tonic-gate 		goto err;
115*0Sstevel@tonic-gate 		}
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate 	switch (padding)
118*0Sstevel@tonic-gate 		{
119*0Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
120*0Sstevel@tonic-gate 		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
121*0Sstevel@tonic-gate 		break;
122*0Sstevel@tonic-gate #ifndef OPENSSL_NO_SHA
123*0Sstevel@tonic-gate 	case RSA_PKCS1_OAEP_PADDING:
124*0Sstevel@tonic-gate 	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
125*0Sstevel@tonic-gate 		break;
126*0Sstevel@tonic-gate #endif
127*0Sstevel@tonic-gate 	case RSA_SSLV23_PADDING:
128*0Sstevel@tonic-gate 		i=RSA_padding_add_SSLv23(buf,num,from,flen);
129*0Sstevel@tonic-gate 		break;
130*0Sstevel@tonic-gate 	case RSA_NO_PADDING:
131*0Sstevel@tonic-gate 		i=RSA_padding_add_none(buf,num,from,flen);
132*0Sstevel@tonic-gate 		break;
133*0Sstevel@tonic-gate 	default:
134*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
135*0Sstevel@tonic-gate 		goto err;
136*0Sstevel@tonic-gate 		}
137*0Sstevel@tonic-gate 	if (i <= 0) goto err;
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate 	if (BN_bin2bn(buf,num,&f) == NULL) goto err;
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate 	if (BN_ucmp(&f, rsa->n) >= 0)
142*0Sstevel@tonic-gate 		{
143*0Sstevel@tonic-gate 		/* usually the padding functions would catch this */
144*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
145*0Sstevel@tonic-gate 		goto err;
146*0Sstevel@tonic-gate 		}
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
149*0Sstevel@tonic-gate 		{
150*0Sstevel@tonic-gate 		BN_MONT_CTX* bn_mont_ctx;
151*0Sstevel@tonic-gate 		if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
152*0Sstevel@tonic-gate 			goto err;
153*0Sstevel@tonic-gate 		if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
154*0Sstevel@tonic-gate 			{
155*0Sstevel@tonic-gate 			BN_MONT_CTX_free(bn_mont_ctx);
156*0Sstevel@tonic-gate 			goto err;
157*0Sstevel@tonic-gate 			}
158*0Sstevel@tonic-gate 		if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
159*0Sstevel@tonic-gate 			{
160*0Sstevel@tonic-gate 			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
161*0Sstevel@tonic-gate 			if (rsa->_method_mod_n == NULL)
162*0Sstevel@tonic-gate 				{
163*0Sstevel@tonic-gate 				rsa->_method_mod_n = bn_mont_ctx;
164*0Sstevel@tonic-gate 				bn_mont_ctx = NULL;
165*0Sstevel@tonic-gate 				}
166*0Sstevel@tonic-gate 			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
167*0Sstevel@tonic-gate 			}
168*0Sstevel@tonic-gate 		if (bn_mont_ctx)
169*0Sstevel@tonic-gate 			BN_MONT_CTX_free(bn_mont_ctx);
170*0Sstevel@tonic-gate 		}
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate 	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
173*0Sstevel@tonic-gate 		rsa->_method_mod_n)) goto err;
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	/* put in leading 0 bytes if the number is less than the
176*0Sstevel@tonic-gate 	 * length of the modulus */
177*0Sstevel@tonic-gate 	j=BN_num_bytes(&ret);
178*0Sstevel@tonic-gate 	i=BN_bn2bin(&ret,&(to[num-j]));
179*0Sstevel@tonic-gate 	for (k=0; k<(num-i); k++)
180*0Sstevel@tonic-gate 		to[k]=0;
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate 	r=num;
183*0Sstevel@tonic-gate err:
184*0Sstevel@tonic-gate 	if (ctx != NULL) BN_CTX_free(ctx);
185*0Sstevel@tonic-gate 	BN_clear_free(&f);
186*0Sstevel@tonic-gate 	BN_clear_free(&ret);
187*0Sstevel@tonic-gate 	if (buf != NULL)
188*0Sstevel@tonic-gate 		{
189*0Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
190*0Sstevel@tonic-gate 		OPENSSL_free(buf);
191*0Sstevel@tonic-gate 		}
192*0Sstevel@tonic-gate 	return(r);
193*0Sstevel@tonic-gate 	}
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate static int rsa_eay_blinding(RSA *rsa, BN_CTX *ctx)
196*0Sstevel@tonic-gate 	{
197*0Sstevel@tonic-gate 	int ret = 1;
198*0Sstevel@tonic-gate 	CRYPTO_w_lock(CRYPTO_LOCK_RSA);
199*0Sstevel@tonic-gate 	/* Check again inside the lock - the macro's check is racey */
200*0Sstevel@tonic-gate 	if(rsa->blinding == NULL)
201*0Sstevel@tonic-gate 		ret = RSA_blinding_on(rsa, ctx);
202*0Sstevel@tonic-gate 	CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
203*0Sstevel@tonic-gate 	return ret;
204*0Sstevel@tonic-gate 	}
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate #define BLINDING_HELPER(rsa, ctx, err_instr) \
207*0Sstevel@tonic-gate 	do { \
208*0Sstevel@tonic-gate 		if((!((rsa)->flags & RSA_FLAG_NO_BLINDING)) && \
209*0Sstevel@tonic-gate 		    ((rsa)->blinding == NULL) && \
210*0Sstevel@tonic-gate 		    !rsa_eay_blinding(rsa, ctx)) \
211*0Sstevel@tonic-gate 		    err_instr \
212*0Sstevel@tonic-gate 	} while(0)
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate static BN_BLINDING *setup_blinding(RSA *rsa, BN_CTX *ctx)
215*0Sstevel@tonic-gate 	{
216*0Sstevel@tonic-gate 	BIGNUM *A, *Ai;
217*0Sstevel@tonic-gate 	BN_BLINDING *ret = NULL;
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate 	/* added in OpenSSL 0.9.6j and 0.9.7b */
220*0Sstevel@tonic-gate 
221*0Sstevel@tonic-gate 	/* NB: similar code appears in RSA_blinding_on (rsa_lib.c);
222*0Sstevel@tonic-gate 	 * this should be placed in a new function of its own, but for reasons
223*0Sstevel@tonic-gate 	 * of binary compatibility can't */
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 	BN_CTX_start(ctx);
226*0Sstevel@tonic-gate 	A = BN_CTX_get(ctx);
227*0Sstevel@tonic-gate 	if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
228*0Sstevel@tonic-gate 		{
229*0Sstevel@tonic-gate 		/* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */
230*0Sstevel@tonic-gate 		RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0);
231*0Sstevel@tonic-gate 		if (!BN_pseudo_rand_range(A,rsa->n)) goto err;
232*0Sstevel@tonic-gate 		}
233*0Sstevel@tonic-gate 	else
234*0Sstevel@tonic-gate 		{
235*0Sstevel@tonic-gate 		if (!BN_rand_range(A,rsa->n)) goto err;
236*0Sstevel@tonic-gate 		}
237*0Sstevel@tonic-gate 	if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
238*0Sstevel@tonic-gate 
239*0Sstevel@tonic-gate 	if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_n))
240*0Sstevel@tonic-gate 		goto err;
241*0Sstevel@tonic-gate 	ret = BN_BLINDING_new(A,Ai,rsa->n);
242*0Sstevel@tonic-gate 	BN_free(Ai);
243*0Sstevel@tonic-gate err:
244*0Sstevel@tonic-gate 	BN_CTX_end(ctx);
245*0Sstevel@tonic-gate 	return ret;
246*0Sstevel@tonic-gate 	}
247*0Sstevel@tonic-gate 
248*0Sstevel@tonic-gate /* signing */
249*0Sstevel@tonic-gate static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
250*0Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
251*0Sstevel@tonic-gate 	{
252*0Sstevel@tonic-gate 	BIGNUM f,ret;
253*0Sstevel@tonic-gate 	int i,j,k,num=0,r= -1;
254*0Sstevel@tonic-gate 	unsigned char *buf=NULL;
255*0Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
256*0Sstevel@tonic-gate 	int local_blinding = 0;
257*0Sstevel@tonic-gate 	BN_BLINDING *blinding = NULL;
258*0Sstevel@tonic-gate 
259*0Sstevel@tonic-gate 	BN_init(&f);
260*0Sstevel@tonic-gate 	BN_init(&ret);
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate 	if ((ctx=BN_CTX_new()) == NULL) goto err;
263*0Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
264*0Sstevel@tonic-gate 	if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
265*0Sstevel@tonic-gate 		{
266*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
267*0Sstevel@tonic-gate 		goto err;
268*0Sstevel@tonic-gate 		}
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 	switch (padding)
271*0Sstevel@tonic-gate 		{
272*0Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
273*0Sstevel@tonic-gate 		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
274*0Sstevel@tonic-gate 		break;
275*0Sstevel@tonic-gate 	case RSA_NO_PADDING:
276*0Sstevel@tonic-gate 		i=RSA_padding_add_none(buf,num,from,flen);
277*0Sstevel@tonic-gate 		break;
278*0Sstevel@tonic-gate 	case RSA_SSLV23_PADDING:
279*0Sstevel@tonic-gate 	default:
280*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
281*0Sstevel@tonic-gate 		goto err;
282*0Sstevel@tonic-gate 		}
283*0Sstevel@tonic-gate 	if (i <= 0) goto err;
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 	if (BN_bin2bn(buf,num,&f) == NULL) goto err;
286*0Sstevel@tonic-gate 
287*0Sstevel@tonic-gate 	if (BN_ucmp(&f, rsa->n) >= 0)
288*0Sstevel@tonic-gate 		{
289*0Sstevel@tonic-gate 		/* usually the padding functions would catch this */
290*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
291*0Sstevel@tonic-gate 		goto err;
292*0Sstevel@tonic-gate 		}
293*0Sstevel@tonic-gate 
294*0Sstevel@tonic-gate 	BLINDING_HELPER(rsa, ctx, goto err;);
295*0Sstevel@tonic-gate 	blinding = rsa->blinding;
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate 	/* Now unless blinding is disabled, 'blinding' is non-NULL.
298*0Sstevel@tonic-gate 	 * But the BN_BLINDING object may be owned by some other thread
299*0Sstevel@tonic-gate 	 * (we don't want to keep it constant and we don't want to use
300*0Sstevel@tonic-gate 	 * lots of locking to avoid race conditions, so only a single
301*0Sstevel@tonic-gate 	 * thread can use it; other threads have to use local blinding
302*0Sstevel@tonic-gate 	 * factors) */
303*0Sstevel@tonic-gate 	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
304*0Sstevel@tonic-gate 		{
305*0Sstevel@tonic-gate 		if (blinding == NULL)
306*0Sstevel@tonic-gate 			{
307*0Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
308*0Sstevel@tonic-gate 			goto err;
309*0Sstevel@tonic-gate 			}
310*0Sstevel@tonic-gate 		}
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 	if (blinding != NULL)
313*0Sstevel@tonic-gate 		{
314*0Sstevel@tonic-gate 		if (blinding->thread_id != CRYPTO_thread_id())
315*0Sstevel@tonic-gate 			{
316*0Sstevel@tonic-gate 			/* we need a local one-time blinding factor */
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate 			blinding = setup_blinding(rsa, ctx);
319*0Sstevel@tonic-gate 			if (blinding == NULL)
320*0Sstevel@tonic-gate 				goto err;
321*0Sstevel@tonic-gate 			local_blinding = 1;
322*0Sstevel@tonic-gate 			}
323*0Sstevel@tonic-gate 		}
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate 	if (blinding)
326*0Sstevel@tonic-gate 		if (!BN_BLINDING_convert(&f, blinding, ctx)) goto err;
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate 	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
329*0Sstevel@tonic-gate 		((rsa->p != NULL) &&
330*0Sstevel@tonic-gate 		(rsa->q != NULL) &&
331*0Sstevel@tonic-gate 		(rsa->dmp1 != NULL) &&
332*0Sstevel@tonic-gate 		(rsa->dmq1 != NULL) &&
333*0Sstevel@tonic-gate 		(rsa->iqmp != NULL)) )
334*0Sstevel@tonic-gate 		{ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
335*0Sstevel@tonic-gate 	else
336*0Sstevel@tonic-gate 		{
337*0Sstevel@tonic-gate 		if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
338*0Sstevel@tonic-gate 		}
339*0Sstevel@tonic-gate 
340*0Sstevel@tonic-gate 	if (blinding)
341*0Sstevel@tonic-gate 		if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err;
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate 	/* put in leading 0 bytes if the number is less than the
344*0Sstevel@tonic-gate 	 * length of the modulus */
345*0Sstevel@tonic-gate 	j=BN_num_bytes(&ret);
346*0Sstevel@tonic-gate 	i=BN_bn2bin(&ret,&(to[num-j]));
347*0Sstevel@tonic-gate 	for (k=0; k<(num-i); k++)
348*0Sstevel@tonic-gate 		to[k]=0;
349*0Sstevel@tonic-gate 
350*0Sstevel@tonic-gate 	r=num;
351*0Sstevel@tonic-gate err:
352*0Sstevel@tonic-gate 	if (ctx != NULL) BN_CTX_free(ctx);
353*0Sstevel@tonic-gate 	BN_clear_free(&ret);
354*0Sstevel@tonic-gate 	BN_clear_free(&f);
355*0Sstevel@tonic-gate 	if (local_blinding)
356*0Sstevel@tonic-gate 		BN_BLINDING_free(blinding);
357*0Sstevel@tonic-gate 	if (buf != NULL)
358*0Sstevel@tonic-gate 		{
359*0Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
360*0Sstevel@tonic-gate 		OPENSSL_free(buf);
361*0Sstevel@tonic-gate 		}
362*0Sstevel@tonic-gate 	return(r);
363*0Sstevel@tonic-gate 	}
364*0Sstevel@tonic-gate 
365*0Sstevel@tonic-gate static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
366*0Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
367*0Sstevel@tonic-gate 	{
368*0Sstevel@tonic-gate 	BIGNUM f,ret;
369*0Sstevel@tonic-gate 	int j,num=0,r= -1;
370*0Sstevel@tonic-gate 	unsigned char *p;
371*0Sstevel@tonic-gate 	unsigned char *buf=NULL;
372*0Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
373*0Sstevel@tonic-gate 	int local_blinding = 0;
374*0Sstevel@tonic-gate 	BN_BLINDING *blinding = NULL;
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate 	BN_init(&f);
377*0Sstevel@tonic-gate 	BN_init(&ret);
378*0Sstevel@tonic-gate 	ctx=BN_CTX_new();
379*0Sstevel@tonic-gate 	if (ctx == NULL) goto err;
380*0Sstevel@tonic-gate 
381*0Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate 	if ((buf=(unsigned char *)OPENSSL_malloc(num)) == NULL)
384*0Sstevel@tonic-gate 		{
385*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
386*0Sstevel@tonic-gate 		goto err;
387*0Sstevel@tonic-gate 		}
388*0Sstevel@tonic-gate 
389*0Sstevel@tonic-gate 	/* This check was for equality but PGP does evil things
390*0Sstevel@tonic-gate 	 * and chops off the top '0' bytes */
391*0Sstevel@tonic-gate 	if (flen > num)
392*0Sstevel@tonic-gate 		{
393*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
394*0Sstevel@tonic-gate 		goto err;
395*0Sstevel@tonic-gate 		}
396*0Sstevel@tonic-gate 
397*0Sstevel@tonic-gate 	/* make data into a big number */
398*0Sstevel@tonic-gate 	if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err;
399*0Sstevel@tonic-gate 
400*0Sstevel@tonic-gate 	if (BN_ucmp(&f, rsa->n) >= 0)
401*0Sstevel@tonic-gate 		{
402*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
403*0Sstevel@tonic-gate 		goto err;
404*0Sstevel@tonic-gate 		}
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate 	BLINDING_HELPER(rsa, ctx, goto err;);
407*0Sstevel@tonic-gate 	blinding = rsa->blinding;
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate 	/* Now unless blinding is disabled, 'blinding' is non-NULL.
410*0Sstevel@tonic-gate 	 * But the BN_BLINDING object may be owned by some other thread
411*0Sstevel@tonic-gate 	 * (we don't want to keep it constant and we don't want to use
412*0Sstevel@tonic-gate 	 * lots of locking to avoid race conditions, so only a single
413*0Sstevel@tonic-gate 	 * thread can use it; other threads have to use local blinding
414*0Sstevel@tonic-gate 	 * factors) */
415*0Sstevel@tonic-gate 	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
416*0Sstevel@tonic-gate 		{
417*0Sstevel@tonic-gate 		if (blinding == NULL)
418*0Sstevel@tonic-gate 			{
419*0Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
420*0Sstevel@tonic-gate 			goto err;
421*0Sstevel@tonic-gate 			}
422*0Sstevel@tonic-gate 		}
423*0Sstevel@tonic-gate 
424*0Sstevel@tonic-gate 	if (blinding != NULL)
425*0Sstevel@tonic-gate 		{
426*0Sstevel@tonic-gate 		if (blinding->thread_id != CRYPTO_thread_id())
427*0Sstevel@tonic-gate 			{
428*0Sstevel@tonic-gate 			/* we need a local one-time blinding factor */
429*0Sstevel@tonic-gate 
430*0Sstevel@tonic-gate 			blinding = setup_blinding(rsa, ctx);
431*0Sstevel@tonic-gate 			if (blinding == NULL)
432*0Sstevel@tonic-gate 				goto err;
433*0Sstevel@tonic-gate 			local_blinding = 1;
434*0Sstevel@tonic-gate 			}
435*0Sstevel@tonic-gate 		}
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate 	if (blinding)
438*0Sstevel@tonic-gate 		if (!BN_BLINDING_convert(&f, blinding, ctx)) goto err;
439*0Sstevel@tonic-gate 
440*0Sstevel@tonic-gate 	/* do the decrypt */
441*0Sstevel@tonic-gate 	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
442*0Sstevel@tonic-gate 		((rsa->p != NULL) &&
443*0Sstevel@tonic-gate 		(rsa->q != NULL) &&
444*0Sstevel@tonic-gate 		(rsa->dmp1 != NULL) &&
445*0Sstevel@tonic-gate 		(rsa->dmq1 != NULL) &&
446*0Sstevel@tonic-gate 		(rsa->iqmp != NULL)) )
447*0Sstevel@tonic-gate 		{ if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
448*0Sstevel@tonic-gate 	else
449*0Sstevel@tonic-gate 		{
450*0Sstevel@tonic-gate 		if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
451*0Sstevel@tonic-gate 			goto err;
452*0Sstevel@tonic-gate 		}
453*0Sstevel@tonic-gate 
454*0Sstevel@tonic-gate 	if (blinding)
455*0Sstevel@tonic-gate 		if (!BN_BLINDING_invert(&ret, blinding, ctx)) goto err;
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 	p=buf;
458*0Sstevel@tonic-gate 	j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */
459*0Sstevel@tonic-gate 
460*0Sstevel@tonic-gate 	switch (padding)
461*0Sstevel@tonic-gate 		{
462*0Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
463*0Sstevel@tonic-gate 		r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
464*0Sstevel@tonic-gate 		break;
465*0Sstevel@tonic-gate #ifndef OPENSSL_NO_SHA
466*0Sstevel@tonic-gate         case RSA_PKCS1_OAEP_PADDING:
467*0Sstevel@tonic-gate 	        r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
468*0Sstevel@tonic-gate                 break;
469*0Sstevel@tonic-gate #endif
470*0Sstevel@tonic-gate  	case RSA_SSLV23_PADDING:
471*0Sstevel@tonic-gate 		r=RSA_padding_check_SSLv23(to,num,buf,j,num);
472*0Sstevel@tonic-gate 		break;
473*0Sstevel@tonic-gate 	case RSA_NO_PADDING:
474*0Sstevel@tonic-gate 		r=RSA_padding_check_none(to,num,buf,j,num);
475*0Sstevel@tonic-gate 		break;
476*0Sstevel@tonic-gate 	default:
477*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
478*0Sstevel@tonic-gate 		goto err;
479*0Sstevel@tonic-gate 		}
480*0Sstevel@tonic-gate 	if (r < 0)
481*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
482*0Sstevel@tonic-gate 
483*0Sstevel@tonic-gate err:
484*0Sstevel@tonic-gate 	if (ctx != NULL) BN_CTX_free(ctx);
485*0Sstevel@tonic-gate 	BN_clear_free(&f);
486*0Sstevel@tonic-gate 	BN_clear_free(&ret);
487*0Sstevel@tonic-gate 	if (local_blinding)
488*0Sstevel@tonic-gate 		BN_BLINDING_free(blinding);
489*0Sstevel@tonic-gate 	if (buf != NULL)
490*0Sstevel@tonic-gate 		{
491*0Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
492*0Sstevel@tonic-gate 		OPENSSL_free(buf);
493*0Sstevel@tonic-gate 		}
494*0Sstevel@tonic-gate 	return(r);
495*0Sstevel@tonic-gate 	}
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate /* signature verification */
498*0Sstevel@tonic-gate static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
499*0Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
500*0Sstevel@tonic-gate 	{
501*0Sstevel@tonic-gate 	BIGNUM f,ret;
502*0Sstevel@tonic-gate 	int i,num=0,r= -1;
503*0Sstevel@tonic-gate 	unsigned char *p;
504*0Sstevel@tonic-gate 	unsigned char *buf=NULL;
505*0Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate 	BN_init(&f);
508*0Sstevel@tonic-gate 	BN_init(&ret);
509*0Sstevel@tonic-gate 	ctx=BN_CTX_new();
510*0Sstevel@tonic-gate 	if (ctx == NULL) goto err;
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
513*0Sstevel@tonic-gate 	buf=(unsigned char *)OPENSSL_malloc(num);
514*0Sstevel@tonic-gate 	if (buf == NULL)
515*0Sstevel@tonic-gate 		{
516*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
517*0Sstevel@tonic-gate 		goto err;
518*0Sstevel@tonic-gate 		}
519*0Sstevel@tonic-gate 
520*0Sstevel@tonic-gate 	/* This check was for equality but PGP does evil things
521*0Sstevel@tonic-gate 	 * and chops off the top '0' bytes */
522*0Sstevel@tonic-gate 	if (flen > num)
523*0Sstevel@tonic-gate 		{
524*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
525*0Sstevel@tonic-gate 		goto err;
526*0Sstevel@tonic-gate 		}
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate 	if (BN_bin2bn(from,flen,&f) == NULL) goto err;
529*0Sstevel@tonic-gate 
530*0Sstevel@tonic-gate 	if (BN_ucmp(&f, rsa->n) >= 0)
531*0Sstevel@tonic-gate 		{
532*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
533*0Sstevel@tonic-gate 		goto err;
534*0Sstevel@tonic-gate 		}
535*0Sstevel@tonic-gate 
536*0Sstevel@tonic-gate 	/* do the decrypt */
537*0Sstevel@tonic-gate 	if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
538*0Sstevel@tonic-gate 		{
539*0Sstevel@tonic-gate 		BN_MONT_CTX* bn_mont_ctx;
540*0Sstevel@tonic-gate 		if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
541*0Sstevel@tonic-gate 			goto err;
542*0Sstevel@tonic-gate 		if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->n,ctx))
543*0Sstevel@tonic-gate 			{
544*0Sstevel@tonic-gate 			BN_MONT_CTX_free(bn_mont_ctx);
545*0Sstevel@tonic-gate 			goto err;
546*0Sstevel@tonic-gate 			}
547*0Sstevel@tonic-gate 		if (rsa->_method_mod_n == NULL) /* other thread may have finished first */
548*0Sstevel@tonic-gate 			{
549*0Sstevel@tonic-gate 			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
550*0Sstevel@tonic-gate 			if (rsa->_method_mod_n == NULL)
551*0Sstevel@tonic-gate 				{
552*0Sstevel@tonic-gate 				rsa->_method_mod_n = bn_mont_ctx;
553*0Sstevel@tonic-gate 				bn_mont_ctx = NULL;
554*0Sstevel@tonic-gate 				}
555*0Sstevel@tonic-gate 			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
556*0Sstevel@tonic-gate 			}
557*0Sstevel@tonic-gate 		if (bn_mont_ctx)
558*0Sstevel@tonic-gate 			BN_MONT_CTX_free(bn_mont_ctx);
559*0Sstevel@tonic-gate 		}
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate 	if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
562*0Sstevel@tonic-gate 		rsa->_method_mod_n)) goto err;
563*0Sstevel@tonic-gate 
564*0Sstevel@tonic-gate 	p=buf;
565*0Sstevel@tonic-gate 	i=BN_bn2bin(&ret,p);
566*0Sstevel@tonic-gate 
567*0Sstevel@tonic-gate 	switch (padding)
568*0Sstevel@tonic-gate 		{
569*0Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
570*0Sstevel@tonic-gate 		r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
571*0Sstevel@tonic-gate 		break;
572*0Sstevel@tonic-gate 	case RSA_NO_PADDING:
573*0Sstevel@tonic-gate 		r=RSA_padding_check_none(to,num,buf,i,num);
574*0Sstevel@tonic-gate 		break;
575*0Sstevel@tonic-gate 	default:
576*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
577*0Sstevel@tonic-gate 		goto err;
578*0Sstevel@tonic-gate 		}
579*0Sstevel@tonic-gate 	if (r < 0)
580*0Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
581*0Sstevel@tonic-gate 
582*0Sstevel@tonic-gate err:
583*0Sstevel@tonic-gate 	if (ctx != NULL) BN_CTX_free(ctx);
584*0Sstevel@tonic-gate 	BN_clear_free(&f);
585*0Sstevel@tonic-gate 	BN_clear_free(&ret);
586*0Sstevel@tonic-gate 	if (buf != NULL)
587*0Sstevel@tonic-gate 		{
588*0Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
589*0Sstevel@tonic-gate 		OPENSSL_free(buf);
590*0Sstevel@tonic-gate 		}
591*0Sstevel@tonic-gate 	return(r);
592*0Sstevel@tonic-gate 	}
593*0Sstevel@tonic-gate 
594*0Sstevel@tonic-gate static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
595*0Sstevel@tonic-gate 	{
596*0Sstevel@tonic-gate 	BIGNUM r1,m1,vrfy;
597*0Sstevel@tonic-gate 	int ret=0;
598*0Sstevel@tonic-gate 	BN_CTX *ctx;
599*0Sstevel@tonic-gate 
600*0Sstevel@tonic-gate 	BN_init(&m1);
601*0Sstevel@tonic-gate 	BN_init(&r1);
602*0Sstevel@tonic-gate 	BN_init(&vrfy);
603*0Sstevel@tonic-gate 	if ((ctx=BN_CTX_new()) == NULL) goto err;
604*0Sstevel@tonic-gate 
605*0Sstevel@tonic-gate 	if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
606*0Sstevel@tonic-gate 		{
607*0Sstevel@tonic-gate 		if (rsa->_method_mod_p == NULL)
608*0Sstevel@tonic-gate 			{
609*0Sstevel@tonic-gate 			BN_MONT_CTX* bn_mont_ctx;
610*0Sstevel@tonic-gate 			if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
611*0Sstevel@tonic-gate 				goto err;
612*0Sstevel@tonic-gate 			if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->p,ctx))
613*0Sstevel@tonic-gate 				{
614*0Sstevel@tonic-gate 				BN_MONT_CTX_free(bn_mont_ctx);
615*0Sstevel@tonic-gate 				goto err;
616*0Sstevel@tonic-gate 				}
617*0Sstevel@tonic-gate 			if (rsa->_method_mod_p == NULL) /* other thread may have finished first */
618*0Sstevel@tonic-gate 				{
619*0Sstevel@tonic-gate 				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
620*0Sstevel@tonic-gate 				if (rsa->_method_mod_p == NULL)
621*0Sstevel@tonic-gate 					{
622*0Sstevel@tonic-gate 					rsa->_method_mod_p = bn_mont_ctx;
623*0Sstevel@tonic-gate 					bn_mont_ctx = NULL;
624*0Sstevel@tonic-gate 					}
625*0Sstevel@tonic-gate 				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
626*0Sstevel@tonic-gate 				}
627*0Sstevel@tonic-gate 			if (bn_mont_ctx)
628*0Sstevel@tonic-gate 				BN_MONT_CTX_free(bn_mont_ctx);
629*0Sstevel@tonic-gate 			}
630*0Sstevel@tonic-gate 
631*0Sstevel@tonic-gate 		if (rsa->_method_mod_q == NULL)
632*0Sstevel@tonic-gate 			{
633*0Sstevel@tonic-gate 			BN_MONT_CTX* bn_mont_ctx;
634*0Sstevel@tonic-gate 			if ((bn_mont_ctx=BN_MONT_CTX_new()) == NULL)
635*0Sstevel@tonic-gate 				goto err;
636*0Sstevel@tonic-gate 			if (!BN_MONT_CTX_set(bn_mont_ctx,rsa->q,ctx))
637*0Sstevel@tonic-gate 				{
638*0Sstevel@tonic-gate 				BN_MONT_CTX_free(bn_mont_ctx);
639*0Sstevel@tonic-gate 				goto err;
640*0Sstevel@tonic-gate 				}
641*0Sstevel@tonic-gate 			if (rsa->_method_mod_q == NULL) /* other thread may have finished first */
642*0Sstevel@tonic-gate 				{
643*0Sstevel@tonic-gate 				CRYPTO_w_lock(CRYPTO_LOCK_RSA);
644*0Sstevel@tonic-gate 				if (rsa->_method_mod_q == NULL)
645*0Sstevel@tonic-gate 					{
646*0Sstevel@tonic-gate 					rsa->_method_mod_q = bn_mont_ctx;
647*0Sstevel@tonic-gate 					bn_mont_ctx = NULL;
648*0Sstevel@tonic-gate 					}
649*0Sstevel@tonic-gate 				CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
650*0Sstevel@tonic-gate 				}
651*0Sstevel@tonic-gate 			if (bn_mont_ctx)
652*0Sstevel@tonic-gate 				BN_MONT_CTX_free(bn_mont_ctx);
653*0Sstevel@tonic-gate 			}
654*0Sstevel@tonic-gate 		}
655*0Sstevel@tonic-gate 
656*0Sstevel@tonic-gate 	if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
657*0Sstevel@tonic-gate 	if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
658*0Sstevel@tonic-gate 		rsa->_method_mod_q)) goto err;
659*0Sstevel@tonic-gate 
660*0Sstevel@tonic-gate 	if (!BN_mod(&r1,I,rsa->p,ctx)) goto err;
661*0Sstevel@tonic-gate 	if (!rsa->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx,
662*0Sstevel@tonic-gate 		rsa->_method_mod_p)) goto err;
663*0Sstevel@tonic-gate 
664*0Sstevel@tonic-gate 	if (!BN_sub(r0,r0,&m1)) goto err;
665*0Sstevel@tonic-gate 	/* This will help stop the size of r0 increasing, which does
666*0Sstevel@tonic-gate 	 * affect the multiply if it optimised for a power of 2 size */
667*0Sstevel@tonic-gate 	if (r0->neg)
668*0Sstevel@tonic-gate 		if (!BN_add(r0,r0,rsa->p)) goto err;
669*0Sstevel@tonic-gate 
670*0Sstevel@tonic-gate 	if (!BN_mul(&r1,r0,rsa->iqmp,ctx)) goto err;
671*0Sstevel@tonic-gate 	if (!BN_mod(r0,&r1,rsa->p,ctx)) goto err;
672*0Sstevel@tonic-gate 	/* If p < q it is occasionally possible for the correction of
673*0Sstevel@tonic-gate          * adding 'p' if r0 is negative above to leave the result still
674*0Sstevel@tonic-gate 	 * negative. This can break the private key operations: the following
675*0Sstevel@tonic-gate 	 * second correction should *always* correct this rare occurrence.
676*0Sstevel@tonic-gate 	 * This will *never* happen with OpenSSL generated keys because
677*0Sstevel@tonic-gate          * they ensure p > q [steve]
678*0Sstevel@tonic-gate          */
679*0Sstevel@tonic-gate 	if (r0->neg)
680*0Sstevel@tonic-gate 		if (!BN_add(r0,r0,rsa->p)) goto err;
681*0Sstevel@tonic-gate 	if (!BN_mul(&r1,r0,rsa->q,ctx)) goto err;
682*0Sstevel@tonic-gate 	if (!BN_add(r0,&r1,&m1)) goto err;
683*0Sstevel@tonic-gate 
684*0Sstevel@tonic-gate 	if (rsa->e && rsa->n)
685*0Sstevel@tonic-gate 		{
686*0Sstevel@tonic-gate 		if (!rsa->meth->bn_mod_exp(&vrfy,r0,rsa->e,rsa->n,ctx,NULL)) goto err;
687*0Sstevel@tonic-gate 		/* If 'I' was greater than (or equal to) rsa->n, the operation
688*0Sstevel@tonic-gate 		 * will be equivalent to using 'I mod n'. However, the result of
689*0Sstevel@tonic-gate 		 * the verify will *always* be less than 'n' so we don't check
690*0Sstevel@tonic-gate 		 * for absolute equality, just congruency. */
691*0Sstevel@tonic-gate 		if (!BN_sub(&vrfy, &vrfy, I)) goto err;
692*0Sstevel@tonic-gate 		if (!BN_mod(&vrfy, &vrfy, rsa->n, ctx)) goto err;
693*0Sstevel@tonic-gate 		if (vrfy.neg)
694*0Sstevel@tonic-gate 			if (!BN_add(&vrfy, &vrfy, rsa->n)) goto err;
695*0Sstevel@tonic-gate 		if (!BN_is_zero(&vrfy))
696*0Sstevel@tonic-gate 			/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
697*0Sstevel@tonic-gate 			 * miscalculated CRT output, just do a raw (slower)
698*0Sstevel@tonic-gate 			 * mod_exp and return that instead. */
699*0Sstevel@tonic-gate 			if (!rsa->meth->bn_mod_exp(r0,I,rsa->d,rsa->n,ctx,NULL)) goto err;
700*0Sstevel@tonic-gate 		}
701*0Sstevel@tonic-gate 	ret=1;
702*0Sstevel@tonic-gate err:
703*0Sstevel@tonic-gate 	BN_clear_free(&m1);
704*0Sstevel@tonic-gate 	BN_clear_free(&r1);
705*0Sstevel@tonic-gate 	BN_clear_free(&vrfy);
706*0Sstevel@tonic-gate 	BN_CTX_free(ctx);
707*0Sstevel@tonic-gate 	return(ret);
708*0Sstevel@tonic-gate 	}
709*0Sstevel@tonic-gate 
710*0Sstevel@tonic-gate static int RSA_eay_init(RSA *rsa)
711*0Sstevel@tonic-gate 	{
712*0Sstevel@tonic-gate 	rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
713*0Sstevel@tonic-gate 	return(1);
714*0Sstevel@tonic-gate 	}
715*0Sstevel@tonic-gate 
716*0Sstevel@tonic-gate static int RSA_eay_finish(RSA *rsa)
717*0Sstevel@tonic-gate 	{
718*0Sstevel@tonic-gate 	if (rsa->_method_mod_n != NULL)
719*0Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_n);
720*0Sstevel@tonic-gate 	if (rsa->_method_mod_p != NULL)
721*0Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_p);
722*0Sstevel@tonic-gate 	if (rsa->_method_mod_q != NULL)
723*0Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_q);
724*0Sstevel@tonic-gate 	return(1);
725*0Sstevel@tonic-gate 	}
726*0Sstevel@tonic-gate 
727*0Sstevel@tonic-gate #endif
728