xref: /onnv-gate/usr/src/common/openssl/crypto/rsa/rsa_eay.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate /* crypto/rsa/rsa_eay.c */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate  * All rights reserved.
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * This package is an SSL implementation written
60Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
110Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
130Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate  *
160Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate  * the code are not to be removed.
180Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate  * as the author of the parts of the library used.
200Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate  *
230Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate  * are met:
260Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate  *    must display the following acknowledgement:
330Sstevel@tonic-gate  *    "This product includes cryptographic software written by
340Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate  *    being used are not cryptographic related :-).
370Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate  *
410Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate  * SUCH DAMAGE.
520Sstevel@tonic-gate  *
530Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
550Sstevel@tonic-gate  * copied and put under another distribution licence
560Sstevel@tonic-gate  * [including the GNU Public Licence.]
570Sstevel@tonic-gate  */
58*2139Sjp161948 /* ====================================================================
59*2139Sjp161948  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
60*2139Sjp161948  *
61*2139Sjp161948  * Redistribution and use in source and binary forms, with or without
62*2139Sjp161948  * modification, are permitted provided that the following conditions
63*2139Sjp161948  * are met:
64*2139Sjp161948  *
65*2139Sjp161948  * 1. Redistributions of source code must retain the above copyright
66*2139Sjp161948  *    notice, this list of conditions and the following disclaimer.
67*2139Sjp161948  *
68*2139Sjp161948  * 2. Redistributions in binary form must reproduce the above copyright
69*2139Sjp161948  *    notice, this list of conditions and the following disclaimer in
70*2139Sjp161948  *    the documentation and/or other materials provided with the
71*2139Sjp161948  *    distribution.
72*2139Sjp161948  *
73*2139Sjp161948  * 3. All advertising materials mentioning features or use of this
74*2139Sjp161948  *    software must display the following acknowledgment:
75*2139Sjp161948  *    "This product includes software developed by the OpenSSL Project
76*2139Sjp161948  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77*2139Sjp161948  *
78*2139Sjp161948  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79*2139Sjp161948  *    endorse or promote products derived from this software without
80*2139Sjp161948  *    prior written permission. For written permission, please contact
81*2139Sjp161948  *    openssl-core@openssl.org.
82*2139Sjp161948  *
83*2139Sjp161948  * 5. Products derived from this software may not be called "OpenSSL"
84*2139Sjp161948  *    nor may "OpenSSL" appear in their names without prior written
85*2139Sjp161948  *    permission of the OpenSSL Project.
86*2139Sjp161948  *
87*2139Sjp161948  * 6. Redistributions of any form whatsoever must retain the following
88*2139Sjp161948  *    acknowledgment:
89*2139Sjp161948  *    "This product includes software developed by the OpenSSL Project
90*2139Sjp161948  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91*2139Sjp161948  *
92*2139Sjp161948  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93*2139Sjp161948  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94*2139Sjp161948  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95*2139Sjp161948  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96*2139Sjp161948  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97*2139Sjp161948  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98*2139Sjp161948  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99*2139Sjp161948  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100*2139Sjp161948  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101*2139Sjp161948  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102*2139Sjp161948  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103*2139Sjp161948  * OF THE POSSIBILITY OF SUCH DAMAGE.
104*2139Sjp161948  * ====================================================================
105*2139Sjp161948  *
106*2139Sjp161948  * This product includes cryptographic software written by Eric Young
107*2139Sjp161948  * (eay@cryptsoft.com).  This product includes software written by Tim
108*2139Sjp161948  * Hudson (tjh@cryptsoft.com).
109*2139Sjp161948  *
110*2139Sjp161948  */
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate #include <stdio.h>
1130Sstevel@tonic-gate #include "cryptlib.h"
1140Sstevel@tonic-gate #include <openssl/bn.h>
1150Sstevel@tonic-gate #include <openssl/rsa.h>
1160Sstevel@tonic-gate #include <openssl/rand.h>
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate #ifndef RSA_NULL
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
1210Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
1220Sstevel@tonic-gate static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
1230Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
1240Sstevel@tonic-gate static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
1250Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
1260Sstevel@tonic-gate static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
1270Sstevel@tonic-gate 		unsigned char *to, RSA *rsa,int padding);
128*2139Sjp161948 static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
1290Sstevel@tonic-gate static int RSA_eay_init(RSA *rsa);
1300Sstevel@tonic-gate static int RSA_eay_finish(RSA *rsa);
1310Sstevel@tonic-gate static RSA_METHOD rsa_pkcs1_eay_meth={
1320Sstevel@tonic-gate 	"Eric Young's PKCS#1 RSA",
1330Sstevel@tonic-gate 	RSA_eay_public_encrypt,
1340Sstevel@tonic-gate 	RSA_eay_public_decrypt, /* signature verification */
1350Sstevel@tonic-gate 	RSA_eay_private_encrypt, /* signing */
1360Sstevel@tonic-gate 	RSA_eay_private_decrypt,
1370Sstevel@tonic-gate 	RSA_eay_mod_exp,
1380Sstevel@tonic-gate 	BN_mod_exp_mont, /* XXX probably we should not use Montgomery if  e == 3 */
1390Sstevel@tonic-gate 	RSA_eay_init,
1400Sstevel@tonic-gate 	RSA_eay_finish,
1410Sstevel@tonic-gate 	0, /* flags */
1420Sstevel@tonic-gate 	NULL,
1430Sstevel@tonic-gate 	0, /* rsa_sign */
144*2139Sjp161948 	0, /* rsa_verify */
145*2139Sjp161948 	NULL /* rsa_keygen */
1460Sstevel@tonic-gate 	};
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate const RSA_METHOD *RSA_PKCS1_SSLeay(void)
1490Sstevel@tonic-gate 	{
1500Sstevel@tonic-gate 	return(&rsa_pkcs1_eay_meth);
1510Sstevel@tonic-gate 	}
1520Sstevel@tonic-gate 
153*2139Sjp161948 /* Usage example;
154*2139Sjp161948  *    MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
155*2139Sjp161948  */
156*2139Sjp161948 #define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \
157*2139Sjp161948 	if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \
158*2139Sjp161948 			!BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \
159*2139Sjp161948 				CRYPTO_LOCK_RSA, \
160*2139Sjp161948 				(rsa)->m, (ctx))) \
161*2139Sjp161948 		err_instr
162*2139Sjp161948 
1630Sstevel@tonic-gate static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
1640Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
1650Sstevel@tonic-gate 	{
166*2139Sjp161948 	BIGNUM *f,*ret;
1670Sstevel@tonic-gate 	int i,j,k,num=0,r= -1;
1680Sstevel@tonic-gate 	unsigned char *buf=NULL;
1690Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 	if ((ctx=BN_CTX_new()) == NULL) goto err;
172*2139Sjp161948 	BN_CTX_start(ctx);
173*2139Sjp161948 	f = BN_CTX_get(ctx);
174*2139Sjp161948 	ret = BN_CTX_get(ctx);
1750Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
176*2139Sjp161948 	buf = OPENSSL_malloc(num);
177*2139Sjp161948 	if (!f || !ret || !buf)
1780Sstevel@tonic-gate 		{
1790Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
1800Sstevel@tonic-gate 		goto err;
1810Sstevel@tonic-gate 		}
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 	switch (padding)
1840Sstevel@tonic-gate 		{
1850Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
1860Sstevel@tonic-gate 		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
1870Sstevel@tonic-gate 		break;
1880Sstevel@tonic-gate #ifndef OPENSSL_NO_SHA
1890Sstevel@tonic-gate 	case RSA_PKCS1_OAEP_PADDING:
1900Sstevel@tonic-gate 	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
1910Sstevel@tonic-gate 		break;
1920Sstevel@tonic-gate #endif
1930Sstevel@tonic-gate 	case RSA_SSLV23_PADDING:
1940Sstevel@tonic-gate 		i=RSA_padding_add_SSLv23(buf,num,from,flen);
1950Sstevel@tonic-gate 		break;
1960Sstevel@tonic-gate 	case RSA_NO_PADDING:
1970Sstevel@tonic-gate 		i=RSA_padding_add_none(buf,num,from,flen);
1980Sstevel@tonic-gate 		break;
1990Sstevel@tonic-gate 	default:
2000Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
2010Sstevel@tonic-gate 		goto err;
2020Sstevel@tonic-gate 		}
2030Sstevel@tonic-gate 	if (i <= 0) goto err;
2040Sstevel@tonic-gate 
205*2139Sjp161948 	if (BN_bin2bn(buf,num,f) == NULL) goto err;
2060Sstevel@tonic-gate 
207*2139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
2080Sstevel@tonic-gate 		{
2090Sstevel@tonic-gate 		/* usually the padding functions would catch this */
2100Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
2110Sstevel@tonic-gate 		goto err;
2120Sstevel@tonic-gate 		}
2130Sstevel@tonic-gate 
214*2139Sjp161948 	MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
215*2139Sjp161948 
216*2139Sjp161948 	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
2170Sstevel@tonic-gate 		rsa->_method_mod_n)) goto err;
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	/* put in leading 0 bytes if the number is less than the
2200Sstevel@tonic-gate 	 * length of the modulus */
221*2139Sjp161948 	j=BN_num_bytes(ret);
222*2139Sjp161948 	i=BN_bn2bin(ret,&(to[num-j]));
2230Sstevel@tonic-gate 	for (k=0; k<(num-i); k++)
2240Sstevel@tonic-gate 		to[k]=0;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate 	r=num;
2270Sstevel@tonic-gate err:
228*2139Sjp161948 	if (ctx != NULL)
229*2139Sjp161948 		{
230*2139Sjp161948 		BN_CTX_end(ctx);
231*2139Sjp161948 		BN_CTX_free(ctx);
232*2139Sjp161948 		}
2330Sstevel@tonic-gate 	if (buf != NULL)
2340Sstevel@tonic-gate 		{
2350Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
2360Sstevel@tonic-gate 		OPENSSL_free(buf);
2370Sstevel@tonic-gate 		}
2380Sstevel@tonic-gate 	return(r);
2390Sstevel@tonic-gate 	}
2400Sstevel@tonic-gate 
241*2139Sjp161948 static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx)
242*2139Sjp161948 {
243*2139Sjp161948 	BN_BLINDING *ret;
2440Sstevel@tonic-gate 
245*2139Sjp161948 	if (rsa->blinding == NULL)
246*2139Sjp161948 		{
247*2139Sjp161948 		if (rsa->blinding == NULL)
248*2139Sjp161948 			{
249*2139Sjp161948 			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
250*2139Sjp161948 			if (rsa->blinding == NULL)
251*2139Sjp161948 				rsa->blinding = RSA_setup_blinding(rsa, ctx);
252*2139Sjp161948 			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
253*2139Sjp161948 			}
254*2139Sjp161948 		}
2550Sstevel@tonic-gate 
256*2139Sjp161948 	ret = rsa->blinding;
257*2139Sjp161948 	if (ret == NULL)
258*2139Sjp161948 		return NULL;
2590Sstevel@tonic-gate 
260*2139Sjp161948 	if (BN_BLINDING_get_thread_id(ret) != CRYPTO_thread_id())
2610Sstevel@tonic-gate 		{
262*2139Sjp161948 		*local = 0;
263*2139Sjp161948 		if (rsa->mt_blinding == NULL)
264*2139Sjp161948 			{
265*2139Sjp161948 			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
266*2139Sjp161948 			if (rsa->mt_blinding == NULL)
267*2139Sjp161948 				rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
268*2139Sjp161948 			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
269*2139Sjp161948 			}
270*2139Sjp161948 		ret = rsa->mt_blinding;
2710Sstevel@tonic-gate 		}
2720Sstevel@tonic-gate 	else
273*2139Sjp161948 		*local = 1;
274*2139Sjp161948 
275*2139Sjp161948 	return ret;
276*2139Sjp161948 }
2770Sstevel@tonic-gate 
278*2139Sjp161948 static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
279*2139Sjp161948 	BIGNUM *r, BN_CTX *ctx)
280*2139Sjp161948 {
281*2139Sjp161948 	if (local)
282*2139Sjp161948 		return BN_BLINDING_convert_ex(f, NULL, b, ctx);
283*2139Sjp161948 	else
284*2139Sjp161948 		{
285*2139Sjp161948 		int ret;
286*2139Sjp161948 		CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
287*2139Sjp161948 		ret = BN_BLINDING_convert_ex(f, r, b, ctx);
288*2139Sjp161948 		CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
289*2139Sjp161948 		return ret;
290*2139Sjp161948 		}
291*2139Sjp161948 }
292*2139Sjp161948 
293*2139Sjp161948 static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
294*2139Sjp161948 	BIGNUM *r, BN_CTX *ctx)
295*2139Sjp161948 {
296*2139Sjp161948 	if (local)
297*2139Sjp161948 		return BN_BLINDING_invert_ex(f, NULL, b, ctx);
298*2139Sjp161948 	else
299*2139Sjp161948 		{
300*2139Sjp161948 		int ret;
301*2139Sjp161948 		CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
302*2139Sjp161948 		ret = BN_BLINDING_invert_ex(f, r, b, ctx);
303*2139Sjp161948 		CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
304*2139Sjp161948 		return ret;
305*2139Sjp161948 		}
306*2139Sjp161948 }
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate /* signing */
3090Sstevel@tonic-gate static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
3100Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
3110Sstevel@tonic-gate 	{
312*2139Sjp161948 	BIGNUM *f, *ret, *br, *res;
3130Sstevel@tonic-gate 	int i,j,k,num=0,r= -1;
3140Sstevel@tonic-gate 	unsigned char *buf=NULL;
3150Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
3160Sstevel@tonic-gate 	int local_blinding = 0;
3170Sstevel@tonic-gate 	BN_BLINDING *blinding = NULL;
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	if ((ctx=BN_CTX_new()) == NULL) goto err;
320*2139Sjp161948 	BN_CTX_start(ctx);
321*2139Sjp161948 	f   = BN_CTX_get(ctx);
322*2139Sjp161948 	br  = BN_CTX_get(ctx);
323*2139Sjp161948 	ret = BN_CTX_get(ctx);
324*2139Sjp161948 	num = BN_num_bytes(rsa->n);
325*2139Sjp161948 	buf = OPENSSL_malloc(num);
326*2139Sjp161948 	if(!f || !ret || !buf)
3270Sstevel@tonic-gate 		{
3280Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
3290Sstevel@tonic-gate 		goto err;
3300Sstevel@tonic-gate 		}
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 	switch (padding)
3330Sstevel@tonic-gate 		{
3340Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
3350Sstevel@tonic-gate 		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
3360Sstevel@tonic-gate 		break;
337*2139Sjp161948 	case RSA_X931_PADDING:
338*2139Sjp161948 		i=RSA_padding_add_X931(buf,num,from,flen);
339*2139Sjp161948 		break;
3400Sstevel@tonic-gate 	case RSA_NO_PADDING:
3410Sstevel@tonic-gate 		i=RSA_padding_add_none(buf,num,from,flen);
3420Sstevel@tonic-gate 		break;
3430Sstevel@tonic-gate 	case RSA_SSLV23_PADDING:
3440Sstevel@tonic-gate 	default:
3450Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
3460Sstevel@tonic-gate 		goto err;
3470Sstevel@tonic-gate 		}
3480Sstevel@tonic-gate 	if (i <= 0) goto err;
3490Sstevel@tonic-gate 
350*2139Sjp161948 	if (BN_bin2bn(buf,num,f) == NULL) goto err;
3510Sstevel@tonic-gate 
352*2139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
3530Sstevel@tonic-gate 		{
3540Sstevel@tonic-gate 		/* usually the padding functions would catch this */
3550Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
3560Sstevel@tonic-gate 		goto err;
3570Sstevel@tonic-gate 		}
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
3600Sstevel@tonic-gate 		{
361*2139Sjp161948 		blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
3620Sstevel@tonic-gate 		if (blinding == NULL)
3630Sstevel@tonic-gate 			{
3640Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
3650Sstevel@tonic-gate 			goto err;
3660Sstevel@tonic-gate 			}
3670Sstevel@tonic-gate 		}
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate 	if (blinding != NULL)
370*2139Sjp161948 		if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
371*2139Sjp161948 			goto err;
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
3740Sstevel@tonic-gate 		((rsa->p != NULL) &&
3750Sstevel@tonic-gate 		(rsa->q != NULL) &&
3760Sstevel@tonic-gate 		(rsa->dmp1 != NULL) &&
3770Sstevel@tonic-gate 		(rsa->dmq1 != NULL) &&
3780Sstevel@tonic-gate 		(rsa->iqmp != NULL)) )
379*2139Sjp161948 		{
380*2139Sjp161948 		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
381*2139Sjp161948 		}
3820Sstevel@tonic-gate 	else
3830Sstevel@tonic-gate 		{
384*2139Sjp161948 		BIGNUM local_d;
385*2139Sjp161948 		BIGNUM *d = NULL;
386*2139Sjp161948 
387*2139Sjp161948 		if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
388*2139Sjp161948 			{
389*2139Sjp161948 			BN_init(&local_d);
390*2139Sjp161948 			d = &local_d;
391*2139Sjp161948 			BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
392*2139Sjp161948 			}
393*2139Sjp161948 		else
394*2139Sjp161948 			d = rsa->d;
395*2139Sjp161948 
396*2139Sjp161948 		MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
397*2139Sjp161948 
398*2139Sjp161948 		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
399*2139Sjp161948 				rsa->_method_mod_n)) goto err;
4000Sstevel@tonic-gate 		}
4010Sstevel@tonic-gate 
4020Sstevel@tonic-gate 	if (blinding)
403*2139Sjp161948 		if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
404*2139Sjp161948 			goto err;
405*2139Sjp161948 
406*2139Sjp161948 	if (padding == RSA_X931_PADDING)
407*2139Sjp161948 		{
408*2139Sjp161948 		BN_sub(f, rsa->n, ret);
409*2139Sjp161948 		if (BN_cmp(ret, f))
410*2139Sjp161948 			res = f;
411*2139Sjp161948 		else
412*2139Sjp161948 			res = ret;
413*2139Sjp161948 		}
414*2139Sjp161948 	else
415*2139Sjp161948 		res = ret;
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	/* put in leading 0 bytes if the number is less than the
4180Sstevel@tonic-gate 	 * length of the modulus */
419*2139Sjp161948 	j=BN_num_bytes(res);
420*2139Sjp161948 	i=BN_bn2bin(res,&(to[num-j]));
4210Sstevel@tonic-gate 	for (k=0; k<(num-i); k++)
4220Sstevel@tonic-gate 		to[k]=0;
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate 	r=num;
4250Sstevel@tonic-gate err:
426*2139Sjp161948 	if (ctx != NULL)
427*2139Sjp161948 		{
428*2139Sjp161948 		BN_CTX_end(ctx);
429*2139Sjp161948 		BN_CTX_free(ctx);
430*2139Sjp161948 		}
4310Sstevel@tonic-gate 	if (buf != NULL)
4320Sstevel@tonic-gate 		{
4330Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
4340Sstevel@tonic-gate 		OPENSSL_free(buf);
4350Sstevel@tonic-gate 		}
4360Sstevel@tonic-gate 	return(r);
4370Sstevel@tonic-gate 	}
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
4400Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
4410Sstevel@tonic-gate 	{
442*2139Sjp161948 	BIGNUM *f, *ret, *br;
4430Sstevel@tonic-gate 	int j,num=0,r= -1;
4440Sstevel@tonic-gate 	unsigned char *p;
4450Sstevel@tonic-gate 	unsigned char *buf=NULL;
4460Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
4470Sstevel@tonic-gate 	int local_blinding = 0;
4480Sstevel@tonic-gate 	BN_BLINDING *blinding = NULL;
4490Sstevel@tonic-gate 
450*2139Sjp161948 	if((ctx = BN_CTX_new()) == NULL) goto err;
451*2139Sjp161948 	BN_CTX_start(ctx);
452*2139Sjp161948 	f   = BN_CTX_get(ctx);
453*2139Sjp161948 	br  = BN_CTX_get(ctx);
454*2139Sjp161948 	ret = BN_CTX_get(ctx);
455*2139Sjp161948 	num = BN_num_bytes(rsa->n);
456*2139Sjp161948 	buf = OPENSSL_malloc(num);
457*2139Sjp161948 	if(!f || !ret || !buf)
4580Sstevel@tonic-gate 		{
4590Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
4600Sstevel@tonic-gate 		goto err;
4610Sstevel@tonic-gate 		}
4620Sstevel@tonic-gate 
4630Sstevel@tonic-gate 	/* This check was for equality but PGP does evil things
4640Sstevel@tonic-gate 	 * and chops off the top '0' bytes */
4650Sstevel@tonic-gate 	if (flen > num)
4660Sstevel@tonic-gate 		{
4670Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
4680Sstevel@tonic-gate 		goto err;
4690Sstevel@tonic-gate 		}
4700Sstevel@tonic-gate 
4710Sstevel@tonic-gate 	/* make data into a big number */
472*2139Sjp161948 	if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
4730Sstevel@tonic-gate 
474*2139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
4750Sstevel@tonic-gate 		{
4760Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
4770Sstevel@tonic-gate 		goto err;
4780Sstevel@tonic-gate 		}
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
4810Sstevel@tonic-gate 		{
482*2139Sjp161948 		blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
4830Sstevel@tonic-gate 		if (blinding == NULL)
4840Sstevel@tonic-gate 			{
4850Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
4860Sstevel@tonic-gate 			goto err;
4870Sstevel@tonic-gate 			}
4880Sstevel@tonic-gate 		}
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 	if (blinding != NULL)
491*2139Sjp161948 		if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
492*2139Sjp161948 			goto err;
4930Sstevel@tonic-gate 
4940Sstevel@tonic-gate 	/* do the decrypt */
4950Sstevel@tonic-gate 	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
4960Sstevel@tonic-gate 		((rsa->p != NULL) &&
4970Sstevel@tonic-gate 		(rsa->q != NULL) &&
4980Sstevel@tonic-gate 		(rsa->dmp1 != NULL) &&
4990Sstevel@tonic-gate 		(rsa->dmq1 != NULL) &&
5000Sstevel@tonic-gate 		(rsa->iqmp != NULL)) )
501*2139Sjp161948 		{
502*2139Sjp161948 		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
503*2139Sjp161948 		}
5040Sstevel@tonic-gate 	else
5050Sstevel@tonic-gate 		{
506*2139Sjp161948 		BIGNUM local_d;
507*2139Sjp161948 		BIGNUM *d = NULL;
508*2139Sjp161948 
509*2139Sjp161948 		if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
510*2139Sjp161948 			{
511*2139Sjp161948 			d = &local_d;
512*2139Sjp161948 			BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
513*2139Sjp161948 			}
514*2139Sjp161948 		else
515*2139Sjp161948 			d = rsa->d;
516*2139Sjp161948 
517*2139Sjp161948 		MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
518*2139Sjp161948 		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
519*2139Sjp161948 				rsa->_method_mod_n))
520*2139Sjp161948 		  goto err;
5210Sstevel@tonic-gate 		}
5220Sstevel@tonic-gate 
5230Sstevel@tonic-gate 	if (blinding)
524*2139Sjp161948 		if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
525*2139Sjp161948 			goto err;
5260Sstevel@tonic-gate 
5270Sstevel@tonic-gate 	p=buf;
528*2139Sjp161948 	j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
5290Sstevel@tonic-gate 
5300Sstevel@tonic-gate 	switch (padding)
5310Sstevel@tonic-gate 		{
5320Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
5330Sstevel@tonic-gate 		r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
5340Sstevel@tonic-gate 		break;
5350Sstevel@tonic-gate #ifndef OPENSSL_NO_SHA
5360Sstevel@tonic-gate         case RSA_PKCS1_OAEP_PADDING:
5370Sstevel@tonic-gate 	        r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
5380Sstevel@tonic-gate                 break;
5390Sstevel@tonic-gate #endif
5400Sstevel@tonic-gate  	case RSA_SSLV23_PADDING:
5410Sstevel@tonic-gate 		r=RSA_padding_check_SSLv23(to,num,buf,j,num);
5420Sstevel@tonic-gate 		break;
5430Sstevel@tonic-gate 	case RSA_NO_PADDING:
5440Sstevel@tonic-gate 		r=RSA_padding_check_none(to,num,buf,j,num);
5450Sstevel@tonic-gate 		break;
5460Sstevel@tonic-gate 	default:
5470Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
5480Sstevel@tonic-gate 		goto err;
5490Sstevel@tonic-gate 		}
5500Sstevel@tonic-gate 	if (r < 0)
5510Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
5520Sstevel@tonic-gate 
5530Sstevel@tonic-gate err:
554*2139Sjp161948 	if (ctx != NULL)
555*2139Sjp161948 		{
556*2139Sjp161948 		BN_CTX_end(ctx);
557*2139Sjp161948 		BN_CTX_free(ctx);
558*2139Sjp161948 		}
5590Sstevel@tonic-gate 	if (buf != NULL)
5600Sstevel@tonic-gate 		{
5610Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
5620Sstevel@tonic-gate 		OPENSSL_free(buf);
5630Sstevel@tonic-gate 		}
5640Sstevel@tonic-gate 	return(r);
5650Sstevel@tonic-gate 	}
5660Sstevel@tonic-gate 
5670Sstevel@tonic-gate /* signature verification */
5680Sstevel@tonic-gate static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
5690Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
5700Sstevel@tonic-gate 	{
571*2139Sjp161948 	BIGNUM *f,*ret;
5720Sstevel@tonic-gate 	int i,num=0,r= -1;
5730Sstevel@tonic-gate 	unsigned char *p;
5740Sstevel@tonic-gate 	unsigned char *buf=NULL;
5750Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
5760Sstevel@tonic-gate 
577*2139Sjp161948 	if((ctx = BN_CTX_new()) == NULL) goto err;
578*2139Sjp161948 	BN_CTX_start(ctx);
579*2139Sjp161948 	f = BN_CTX_get(ctx);
580*2139Sjp161948 	ret = BN_CTX_get(ctx);
5810Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
582*2139Sjp161948 	buf = OPENSSL_malloc(num);
583*2139Sjp161948 	if(!f || !ret || !buf)
5840Sstevel@tonic-gate 		{
5850Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
5860Sstevel@tonic-gate 		goto err;
5870Sstevel@tonic-gate 		}
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate 	/* This check was for equality but PGP does evil things
5900Sstevel@tonic-gate 	 * and chops off the top '0' bytes */
5910Sstevel@tonic-gate 	if (flen > num)
5920Sstevel@tonic-gate 		{
5930Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
5940Sstevel@tonic-gate 		goto err;
5950Sstevel@tonic-gate 		}
5960Sstevel@tonic-gate 
597*2139Sjp161948 	if (BN_bin2bn(from,flen,f) == NULL) goto err;
5980Sstevel@tonic-gate 
599*2139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
6000Sstevel@tonic-gate 		{
6010Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
6020Sstevel@tonic-gate 		goto err;
6030Sstevel@tonic-gate 		}
6040Sstevel@tonic-gate 
605*2139Sjp161948 	MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
606*2139Sjp161948 
607*2139Sjp161948 	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
6080Sstevel@tonic-gate 		rsa->_method_mod_n)) goto err;
6090Sstevel@tonic-gate 
610*2139Sjp161948 	if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
611*2139Sjp161948 		BN_sub(ret, rsa->n, ret);
612*2139Sjp161948 
6130Sstevel@tonic-gate 	p=buf;
614*2139Sjp161948 	i=BN_bn2bin(ret,p);
6150Sstevel@tonic-gate 
6160Sstevel@tonic-gate 	switch (padding)
6170Sstevel@tonic-gate 		{
6180Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
6190Sstevel@tonic-gate 		r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
6200Sstevel@tonic-gate 		break;
621*2139Sjp161948 	case RSA_X931_PADDING:
622*2139Sjp161948 		r=RSA_padding_check_X931(to,num,buf,i,num);
623*2139Sjp161948 		break;
6240Sstevel@tonic-gate 	case RSA_NO_PADDING:
6250Sstevel@tonic-gate 		r=RSA_padding_check_none(to,num,buf,i,num);
6260Sstevel@tonic-gate 		break;
6270Sstevel@tonic-gate 	default:
6280Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
6290Sstevel@tonic-gate 		goto err;
6300Sstevel@tonic-gate 		}
6310Sstevel@tonic-gate 	if (r < 0)
6320Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
6330Sstevel@tonic-gate 
6340Sstevel@tonic-gate err:
635*2139Sjp161948 	if (ctx != NULL)
636*2139Sjp161948 		{
637*2139Sjp161948 		BN_CTX_end(ctx);
638*2139Sjp161948 		BN_CTX_free(ctx);
639*2139Sjp161948 		}
6400Sstevel@tonic-gate 	if (buf != NULL)
6410Sstevel@tonic-gate 		{
6420Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
6430Sstevel@tonic-gate 		OPENSSL_free(buf);
6440Sstevel@tonic-gate 		}
6450Sstevel@tonic-gate 	return(r);
6460Sstevel@tonic-gate 	}
6470Sstevel@tonic-gate 
648*2139Sjp161948 static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
6490Sstevel@tonic-gate 	{
650*2139Sjp161948 	BIGNUM *r1,*m1,*vrfy;
651*2139Sjp161948 	BIGNUM local_dmp1, local_dmq1;
652*2139Sjp161948 	BIGNUM *dmp1, *dmq1;
6530Sstevel@tonic-gate 	int ret=0;
6540Sstevel@tonic-gate 
655*2139Sjp161948 	BN_CTX_start(ctx);
656*2139Sjp161948 	r1 = BN_CTX_get(ctx);
657*2139Sjp161948 	m1 = BN_CTX_get(ctx);
658*2139Sjp161948 	vrfy = BN_CTX_get(ctx);
6590Sstevel@tonic-gate 
660*2139Sjp161948 	MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
661*2139Sjp161948 	MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
662*2139Sjp161948 	MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
663*2139Sjp161948 
664*2139Sjp161948 	if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
665*2139Sjp161948 	if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
6660Sstevel@tonic-gate 		{
667*2139Sjp161948 		dmq1 = &local_dmq1;
668*2139Sjp161948 		BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
6690Sstevel@tonic-gate 		}
670*2139Sjp161948 	else
671*2139Sjp161948 		dmq1 = rsa->dmq1;
672*2139Sjp161948 	if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
6730Sstevel@tonic-gate 		rsa->_method_mod_q)) goto err;
6740Sstevel@tonic-gate 
675*2139Sjp161948 	if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
676*2139Sjp161948 	if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
677*2139Sjp161948 		{
678*2139Sjp161948 		dmp1 = &local_dmp1;
679*2139Sjp161948 		BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
680*2139Sjp161948 		}
681*2139Sjp161948 	else
682*2139Sjp161948 		dmp1 = rsa->dmp1;
683*2139Sjp161948 	if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
6840Sstevel@tonic-gate 		rsa->_method_mod_p)) goto err;
6850Sstevel@tonic-gate 
686*2139Sjp161948 	if (!BN_sub(r0,r0,m1)) goto err;
6870Sstevel@tonic-gate 	/* This will help stop the size of r0 increasing, which does
6880Sstevel@tonic-gate 	 * affect the multiply if it optimised for a power of 2 size */
689*2139Sjp161948 	if (BN_is_negative(r0))
6900Sstevel@tonic-gate 		if (!BN_add(r0,r0,rsa->p)) goto err;
6910Sstevel@tonic-gate 
692*2139Sjp161948 	if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
693*2139Sjp161948 	if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
6940Sstevel@tonic-gate 	/* If p < q it is occasionally possible for the correction of
6950Sstevel@tonic-gate          * adding 'p' if r0 is negative above to leave the result still
6960Sstevel@tonic-gate 	 * negative. This can break the private key operations: the following
6970Sstevel@tonic-gate 	 * second correction should *always* correct this rare occurrence.
6980Sstevel@tonic-gate 	 * This will *never* happen with OpenSSL generated keys because
6990Sstevel@tonic-gate          * they ensure p > q [steve]
7000Sstevel@tonic-gate          */
701*2139Sjp161948 	if (BN_is_negative(r0))
7020Sstevel@tonic-gate 		if (!BN_add(r0,r0,rsa->p)) goto err;
703*2139Sjp161948 	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
704*2139Sjp161948 	if (!BN_add(r0,r1,m1)) goto err;
7050Sstevel@tonic-gate 
7060Sstevel@tonic-gate 	if (rsa->e && rsa->n)
7070Sstevel@tonic-gate 		{
708*2139Sjp161948 		if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
7090Sstevel@tonic-gate 		/* If 'I' was greater than (or equal to) rsa->n, the operation
7100Sstevel@tonic-gate 		 * will be equivalent to using 'I mod n'. However, the result of
7110Sstevel@tonic-gate 		 * the verify will *always* be less than 'n' so we don't check
7120Sstevel@tonic-gate 		 * for absolute equality, just congruency. */
713*2139Sjp161948 		if (!BN_sub(vrfy, vrfy, I)) goto err;
714*2139Sjp161948 		if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
715*2139Sjp161948 		if (BN_is_negative(vrfy))
716*2139Sjp161948 			if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
717*2139Sjp161948 		if (!BN_is_zero(vrfy))
718*2139Sjp161948 			{
7190Sstevel@tonic-gate 			/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
7200Sstevel@tonic-gate 			 * miscalculated CRT output, just do a raw (slower)
7210Sstevel@tonic-gate 			 * mod_exp and return that instead. */
722*2139Sjp161948 
723*2139Sjp161948 			BIGNUM local_d;
724*2139Sjp161948 			BIGNUM *d = NULL;
725*2139Sjp161948 
726*2139Sjp161948 			if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
727*2139Sjp161948 				{
728*2139Sjp161948 				d = &local_d;
729*2139Sjp161948 				BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
730*2139Sjp161948 				}
731*2139Sjp161948 			else
732*2139Sjp161948 				d = rsa->d;
733*2139Sjp161948 			if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
734*2139Sjp161948 						   rsa->_method_mod_n)) goto err;
735*2139Sjp161948 			}
7360Sstevel@tonic-gate 		}
7370Sstevel@tonic-gate 	ret=1;
7380Sstevel@tonic-gate err:
739*2139Sjp161948 	BN_CTX_end(ctx);
7400Sstevel@tonic-gate 	return(ret);
7410Sstevel@tonic-gate 	}
7420Sstevel@tonic-gate 
7430Sstevel@tonic-gate static int RSA_eay_init(RSA *rsa)
7440Sstevel@tonic-gate 	{
7450Sstevel@tonic-gate 	rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
7460Sstevel@tonic-gate 	return(1);
7470Sstevel@tonic-gate 	}
7480Sstevel@tonic-gate 
7490Sstevel@tonic-gate static int RSA_eay_finish(RSA *rsa)
7500Sstevel@tonic-gate 	{
7510Sstevel@tonic-gate 	if (rsa->_method_mod_n != NULL)
7520Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_n);
7530Sstevel@tonic-gate 	if (rsa->_method_mod_p != NULL)
7540Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_p);
7550Sstevel@tonic-gate 	if (rsa->_method_mod_q != NULL)
7560Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_q);
7570Sstevel@tonic-gate 	return(1);
7580Sstevel@tonic-gate 	}
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate #endif
761