xref: /onnv-gate/usr/src/common/openssl/crypto/rsa/rsa_eay.c (revision 2864:0fad37eee08f)
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  */
582139Sjp161948 /* ====================================================================
592139Sjp161948  * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
602139Sjp161948  *
612139Sjp161948  * Redistribution and use in source and binary forms, with or without
622139Sjp161948  * modification, are permitted provided that the following conditions
632139Sjp161948  * are met:
642139Sjp161948  *
652139Sjp161948  * 1. Redistributions of source code must retain the above copyright
662139Sjp161948  *    notice, this list of conditions and the following disclaimer.
672139Sjp161948  *
682139Sjp161948  * 2. Redistributions in binary form must reproduce the above copyright
692139Sjp161948  *    notice, this list of conditions and the following disclaimer in
702139Sjp161948  *    the documentation and/or other materials provided with the
712139Sjp161948  *    distribution.
722139Sjp161948  *
732139Sjp161948  * 3. All advertising materials mentioning features or use of this
742139Sjp161948  *    software must display the following acknowledgment:
752139Sjp161948  *    "This product includes software developed by the OpenSSL Project
762139Sjp161948  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
772139Sjp161948  *
782139Sjp161948  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
792139Sjp161948  *    endorse or promote products derived from this software without
802139Sjp161948  *    prior written permission. For written permission, please contact
812139Sjp161948  *    openssl-core@openssl.org.
822139Sjp161948  *
832139Sjp161948  * 5. Products derived from this software may not be called "OpenSSL"
842139Sjp161948  *    nor may "OpenSSL" appear in their names without prior written
852139Sjp161948  *    permission of the OpenSSL Project.
862139Sjp161948  *
872139Sjp161948  * 6. Redistributions of any form whatsoever must retain the following
882139Sjp161948  *    acknowledgment:
892139Sjp161948  *    "This product includes software developed by the OpenSSL Project
902139Sjp161948  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
912139Sjp161948  *
922139Sjp161948  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
932139Sjp161948  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
942139Sjp161948  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
952139Sjp161948  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
962139Sjp161948  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
972139Sjp161948  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
982139Sjp161948  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
992139Sjp161948  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1002139Sjp161948  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1012139Sjp161948  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1022139Sjp161948  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1032139Sjp161948  * OF THE POSSIBILITY OF SUCH DAMAGE.
1042139Sjp161948  * ====================================================================
1052139Sjp161948  *
1062139Sjp161948  * This product includes cryptographic software written by Eric Young
1072139Sjp161948  * (eay@cryptsoft.com).  This product includes software written by Tim
1082139Sjp161948  * Hudson (tjh@cryptsoft.com).
1092139Sjp161948  *
1102139Sjp161948  */
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);
1282139Sjp161948 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 */
1442139Sjp161948 	0, /* rsa_verify */
1452139Sjp161948 	NULL /* rsa_keygen */
1460Sstevel@tonic-gate 	};
1470Sstevel@tonic-gate 
RSA_PKCS1_SSLeay(void)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 
1532139Sjp161948 /* Usage example;
1542139Sjp161948  *    MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
1552139Sjp161948  */
1562139Sjp161948 #define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \
1572139Sjp161948 	if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \
1582139Sjp161948 			!BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \
1592139Sjp161948 				CRYPTO_LOCK_RSA, \
1602139Sjp161948 				(rsa)->m, (ctx))) \
1612139Sjp161948 		err_instr
1622139Sjp161948 
RSA_eay_public_encrypt(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)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 	{
1662139Sjp161948 	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 
171*2864Sjp161948 	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
172*2864Sjp161948 		{
173*2864Sjp161948 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
174*2864Sjp161948 		return -1;
175*2864Sjp161948 		}
176*2864Sjp161948 
177*2864Sjp161948 	if (BN_ucmp(rsa->n, rsa->e) <= 0)
178*2864Sjp161948 		{
179*2864Sjp161948 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
180*2864Sjp161948 		return -1;
181*2864Sjp161948 		}
182*2864Sjp161948 
183*2864Sjp161948 	/* for large moduli, enforce exponent limit */
184*2864Sjp161948 	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
185*2864Sjp161948 		{
186*2864Sjp161948 		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
187*2864Sjp161948 			{
188*2864Sjp161948 			RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
189*2864Sjp161948 			return -1;
190*2864Sjp161948 			}
191*2864Sjp161948 		}
192*2864Sjp161948 
1930Sstevel@tonic-gate 	if ((ctx=BN_CTX_new()) == NULL) goto err;
1942139Sjp161948 	BN_CTX_start(ctx);
1952139Sjp161948 	f = BN_CTX_get(ctx);
1962139Sjp161948 	ret = BN_CTX_get(ctx);
1970Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
1982139Sjp161948 	buf = OPENSSL_malloc(num);
1992139Sjp161948 	if (!f || !ret || !buf)
2000Sstevel@tonic-gate 		{
2010Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
2020Sstevel@tonic-gate 		goto err;
2030Sstevel@tonic-gate 		}
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate 	switch (padding)
2060Sstevel@tonic-gate 		{
2070Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
2080Sstevel@tonic-gate 		i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
2090Sstevel@tonic-gate 		break;
2100Sstevel@tonic-gate #ifndef OPENSSL_NO_SHA
2110Sstevel@tonic-gate 	case RSA_PKCS1_OAEP_PADDING:
2120Sstevel@tonic-gate 	        i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
2130Sstevel@tonic-gate 		break;
2140Sstevel@tonic-gate #endif
2150Sstevel@tonic-gate 	case RSA_SSLV23_PADDING:
2160Sstevel@tonic-gate 		i=RSA_padding_add_SSLv23(buf,num,from,flen);
2170Sstevel@tonic-gate 		break;
2180Sstevel@tonic-gate 	case RSA_NO_PADDING:
2190Sstevel@tonic-gate 		i=RSA_padding_add_none(buf,num,from,flen);
2200Sstevel@tonic-gate 		break;
2210Sstevel@tonic-gate 	default:
2220Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
2230Sstevel@tonic-gate 		goto err;
2240Sstevel@tonic-gate 		}
2250Sstevel@tonic-gate 	if (i <= 0) goto err;
2260Sstevel@tonic-gate 
2272139Sjp161948 	if (BN_bin2bn(buf,num,f) == NULL) goto err;
2280Sstevel@tonic-gate 
2292139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
2300Sstevel@tonic-gate 		{
2310Sstevel@tonic-gate 		/* usually the padding functions would catch this */
2320Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
2330Sstevel@tonic-gate 		goto err;
2340Sstevel@tonic-gate 		}
2350Sstevel@tonic-gate 
2362139Sjp161948 	MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
2372139Sjp161948 
2382139Sjp161948 	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
2390Sstevel@tonic-gate 		rsa->_method_mod_n)) goto err;
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate 	/* put in leading 0 bytes if the number is less than the
2420Sstevel@tonic-gate 	 * length of the modulus */
2432139Sjp161948 	j=BN_num_bytes(ret);
2442139Sjp161948 	i=BN_bn2bin(ret,&(to[num-j]));
2450Sstevel@tonic-gate 	for (k=0; k<(num-i); k++)
2460Sstevel@tonic-gate 		to[k]=0;
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 	r=num;
2490Sstevel@tonic-gate err:
2502139Sjp161948 	if (ctx != NULL)
2512139Sjp161948 		{
2522139Sjp161948 		BN_CTX_end(ctx);
2532139Sjp161948 		BN_CTX_free(ctx);
2542139Sjp161948 		}
2550Sstevel@tonic-gate 	if (buf != NULL)
2560Sstevel@tonic-gate 		{
2570Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
2580Sstevel@tonic-gate 		OPENSSL_free(buf);
2590Sstevel@tonic-gate 		}
2600Sstevel@tonic-gate 	return(r);
2610Sstevel@tonic-gate 	}
2620Sstevel@tonic-gate 
rsa_get_blinding(RSA * rsa,BIGNUM ** r,int * local,BN_CTX * ctx)2632139Sjp161948 static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx)
2642139Sjp161948 {
2652139Sjp161948 	BN_BLINDING *ret;
2660Sstevel@tonic-gate 
2672139Sjp161948 	if (rsa->blinding == NULL)
2682139Sjp161948 		{
2692139Sjp161948 		if (rsa->blinding == NULL)
2702139Sjp161948 			{
2712139Sjp161948 			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
2722139Sjp161948 			if (rsa->blinding == NULL)
2732139Sjp161948 				rsa->blinding = RSA_setup_blinding(rsa, ctx);
2742139Sjp161948 			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
2752139Sjp161948 			}
2762139Sjp161948 		}
2770Sstevel@tonic-gate 
2782139Sjp161948 	ret = rsa->blinding;
2792139Sjp161948 	if (ret == NULL)
2802139Sjp161948 		return NULL;
2810Sstevel@tonic-gate 
2822139Sjp161948 	if (BN_BLINDING_get_thread_id(ret) != CRYPTO_thread_id())
2830Sstevel@tonic-gate 		{
2842139Sjp161948 		*local = 0;
2852139Sjp161948 		if (rsa->mt_blinding == NULL)
2862139Sjp161948 			{
2872139Sjp161948 			CRYPTO_w_lock(CRYPTO_LOCK_RSA);
2882139Sjp161948 			if (rsa->mt_blinding == NULL)
2892139Sjp161948 				rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
2902139Sjp161948 			CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
2912139Sjp161948 			}
2922139Sjp161948 		ret = rsa->mt_blinding;
2930Sstevel@tonic-gate 		}
2940Sstevel@tonic-gate 	else
2952139Sjp161948 		*local = 1;
2962139Sjp161948 
2972139Sjp161948 	return ret;
2982139Sjp161948 }
2990Sstevel@tonic-gate 
rsa_blinding_convert(BN_BLINDING * b,int local,BIGNUM * f,BIGNUM * r,BN_CTX * ctx)3002139Sjp161948 static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
3012139Sjp161948 	BIGNUM *r, BN_CTX *ctx)
3022139Sjp161948 {
3032139Sjp161948 	if (local)
3042139Sjp161948 		return BN_BLINDING_convert_ex(f, NULL, b, ctx);
3052139Sjp161948 	else
3062139Sjp161948 		{
3072139Sjp161948 		int ret;
3082139Sjp161948 		CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
3092139Sjp161948 		ret = BN_BLINDING_convert_ex(f, r, b, ctx);
3102139Sjp161948 		CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
3112139Sjp161948 		return ret;
3122139Sjp161948 		}
3132139Sjp161948 }
3142139Sjp161948 
rsa_blinding_invert(BN_BLINDING * b,int local,BIGNUM * f,BIGNUM * r,BN_CTX * ctx)3152139Sjp161948 static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
3162139Sjp161948 	BIGNUM *r, BN_CTX *ctx)
3172139Sjp161948 {
3182139Sjp161948 	if (local)
3192139Sjp161948 		return BN_BLINDING_invert_ex(f, NULL, b, ctx);
3202139Sjp161948 	else
3212139Sjp161948 		{
3222139Sjp161948 		int ret;
3232139Sjp161948 		CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
3242139Sjp161948 		ret = BN_BLINDING_invert_ex(f, r, b, ctx);
3252139Sjp161948 		CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
3262139Sjp161948 		return ret;
3272139Sjp161948 		}
3282139Sjp161948 }
3290Sstevel@tonic-gate 
3300Sstevel@tonic-gate /* signing */
RSA_eay_private_encrypt(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)3310Sstevel@tonic-gate static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
3320Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
3330Sstevel@tonic-gate 	{
3342139Sjp161948 	BIGNUM *f, *ret, *br, *res;
3350Sstevel@tonic-gate 	int i,j,k,num=0,r= -1;
3360Sstevel@tonic-gate 	unsigned char *buf=NULL;
3370Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
3380Sstevel@tonic-gate 	int local_blinding = 0;
3390Sstevel@tonic-gate 	BN_BLINDING *blinding = NULL;
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate 	if ((ctx=BN_CTX_new()) == NULL) goto err;
3422139Sjp161948 	BN_CTX_start(ctx);
3432139Sjp161948 	f   = BN_CTX_get(ctx);
3442139Sjp161948 	br  = BN_CTX_get(ctx);
3452139Sjp161948 	ret = BN_CTX_get(ctx);
3462139Sjp161948 	num = BN_num_bytes(rsa->n);
3472139Sjp161948 	buf = OPENSSL_malloc(num);
3482139Sjp161948 	if(!f || !ret || !buf)
3490Sstevel@tonic-gate 		{
3500Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
3510Sstevel@tonic-gate 		goto err;
3520Sstevel@tonic-gate 		}
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate 	switch (padding)
3550Sstevel@tonic-gate 		{
3560Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
3570Sstevel@tonic-gate 		i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
3580Sstevel@tonic-gate 		break;
3592139Sjp161948 	case RSA_X931_PADDING:
3602139Sjp161948 		i=RSA_padding_add_X931(buf,num,from,flen);
3612139Sjp161948 		break;
3620Sstevel@tonic-gate 	case RSA_NO_PADDING:
3630Sstevel@tonic-gate 		i=RSA_padding_add_none(buf,num,from,flen);
3640Sstevel@tonic-gate 		break;
3650Sstevel@tonic-gate 	case RSA_SSLV23_PADDING:
3660Sstevel@tonic-gate 	default:
3670Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
3680Sstevel@tonic-gate 		goto err;
3690Sstevel@tonic-gate 		}
3700Sstevel@tonic-gate 	if (i <= 0) goto err;
3710Sstevel@tonic-gate 
3722139Sjp161948 	if (BN_bin2bn(buf,num,f) == NULL) goto err;
3730Sstevel@tonic-gate 
3742139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
3750Sstevel@tonic-gate 		{
3760Sstevel@tonic-gate 		/* usually the padding functions would catch this */
3770Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
3780Sstevel@tonic-gate 		goto err;
3790Sstevel@tonic-gate 		}
3800Sstevel@tonic-gate 
3810Sstevel@tonic-gate 	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
3820Sstevel@tonic-gate 		{
3832139Sjp161948 		blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
3840Sstevel@tonic-gate 		if (blinding == NULL)
3850Sstevel@tonic-gate 			{
3860Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
3870Sstevel@tonic-gate 			goto err;
3880Sstevel@tonic-gate 			}
3890Sstevel@tonic-gate 		}
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 	if (blinding != NULL)
3922139Sjp161948 		if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
3932139Sjp161948 			goto err;
3940Sstevel@tonic-gate 
3950Sstevel@tonic-gate 	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
3960Sstevel@tonic-gate 		((rsa->p != NULL) &&
3970Sstevel@tonic-gate 		(rsa->q != NULL) &&
3980Sstevel@tonic-gate 		(rsa->dmp1 != NULL) &&
3990Sstevel@tonic-gate 		(rsa->dmq1 != NULL) &&
4000Sstevel@tonic-gate 		(rsa->iqmp != NULL)) )
4012139Sjp161948 		{
4022139Sjp161948 		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
4032139Sjp161948 		}
4040Sstevel@tonic-gate 	else
4050Sstevel@tonic-gate 		{
4062139Sjp161948 		BIGNUM local_d;
4072139Sjp161948 		BIGNUM *d = NULL;
4082139Sjp161948 
4092139Sjp161948 		if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
4102139Sjp161948 			{
4112139Sjp161948 			BN_init(&local_d);
4122139Sjp161948 			d = &local_d;
4132139Sjp161948 			BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
4142139Sjp161948 			}
4152139Sjp161948 		else
4162139Sjp161948 			d = rsa->d;
4172139Sjp161948 
4182139Sjp161948 		MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
4192139Sjp161948 
4202139Sjp161948 		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
4212139Sjp161948 				rsa->_method_mod_n)) goto err;
4220Sstevel@tonic-gate 		}
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate 	if (blinding)
4252139Sjp161948 		if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
4262139Sjp161948 			goto err;
4272139Sjp161948 
4282139Sjp161948 	if (padding == RSA_X931_PADDING)
4292139Sjp161948 		{
4302139Sjp161948 		BN_sub(f, rsa->n, ret);
4312139Sjp161948 		if (BN_cmp(ret, f))
4322139Sjp161948 			res = f;
4332139Sjp161948 		else
4342139Sjp161948 			res = ret;
4352139Sjp161948 		}
4362139Sjp161948 	else
4372139Sjp161948 		res = ret;
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate 	/* put in leading 0 bytes if the number is less than the
4400Sstevel@tonic-gate 	 * length of the modulus */
4412139Sjp161948 	j=BN_num_bytes(res);
4422139Sjp161948 	i=BN_bn2bin(res,&(to[num-j]));
4430Sstevel@tonic-gate 	for (k=0; k<(num-i); k++)
4440Sstevel@tonic-gate 		to[k]=0;
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate 	r=num;
4470Sstevel@tonic-gate err:
4482139Sjp161948 	if (ctx != NULL)
4492139Sjp161948 		{
4502139Sjp161948 		BN_CTX_end(ctx);
4512139Sjp161948 		BN_CTX_free(ctx);
4522139Sjp161948 		}
4530Sstevel@tonic-gate 	if (buf != NULL)
4540Sstevel@tonic-gate 		{
4550Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
4560Sstevel@tonic-gate 		OPENSSL_free(buf);
4570Sstevel@tonic-gate 		}
4580Sstevel@tonic-gate 	return(r);
4590Sstevel@tonic-gate 	}
4600Sstevel@tonic-gate 
RSA_eay_private_decrypt(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)4610Sstevel@tonic-gate static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
4620Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
4630Sstevel@tonic-gate 	{
4642139Sjp161948 	BIGNUM *f, *ret, *br;
4650Sstevel@tonic-gate 	int j,num=0,r= -1;
4660Sstevel@tonic-gate 	unsigned char *p;
4670Sstevel@tonic-gate 	unsigned char *buf=NULL;
4680Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
4690Sstevel@tonic-gate 	int local_blinding = 0;
4700Sstevel@tonic-gate 	BN_BLINDING *blinding = NULL;
4710Sstevel@tonic-gate 
4722139Sjp161948 	if((ctx = BN_CTX_new()) == NULL) goto err;
4732139Sjp161948 	BN_CTX_start(ctx);
4742139Sjp161948 	f   = BN_CTX_get(ctx);
4752139Sjp161948 	br  = BN_CTX_get(ctx);
4762139Sjp161948 	ret = BN_CTX_get(ctx);
4772139Sjp161948 	num = BN_num_bytes(rsa->n);
4782139Sjp161948 	buf = OPENSSL_malloc(num);
4792139Sjp161948 	if(!f || !ret || !buf)
4800Sstevel@tonic-gate 		{
4810Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
4820Sstevel@tonic-gate 		goto err;
4830Sstevel@tonic-gate 		}
4840Sstevel@tonic-gate 
4850Sstevel@tonic-gate 	/* This check was for equality but PGP does evil things
4860Sstevel@tonic-gate 	 * and chops off the top '0' bytes */
4870Sstevel@tonic-gate 	if (flen > num)
4880Sstevel@tonic-gate 		{
4890Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
4900Sstevel@tonic-gate 		goto err;
4910Sstevel@tonic-gate 		}
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate 	/* make data into a big number */
4942139Sjp161948 	if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
4950Sstevel@tonic-gate 
4962139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
4970Sstevel@tonic-gate 		{
4980Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
4990Sstevel@tonic-gate 		goto err;
5000Sstevel@tonic-gate 		}
5010Sstevel@tonic-gate 
5020Sstevel@tonic-gate 	if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
5030Sstevel@tonic-gate 		{
5042139Sjp161948 		blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
5050Sstevel@tonic-gate 		if (blinding == NULL)
5060Sstevel@tonic-gate 			{
5070Sstevel@tonic-gate 			RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
5080Sstevel@tonic-gate 			goto err;
5090Sstevel@tonic-gate 			}
5100Sstevel@tonic-gate 		}
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate 	if (blinding != NULL)
5132139Sjp161948 		if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
5142139Sjp161948 			goto err;
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate 	/* do the decrypt */
5170Sstevel@tonic-gate 	if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
5180Sstevel@tonic-gate 		((rsa->p != NULL) &&
5190Sstevel@tonic-gate 		(rsa->q != NULL) &&
5200Sstevel@tonic-gate 		(rsa->dmp1 != NULL) &&
5210Sstevel@tonic-gate 		(rsa->dmq1 != NULL) &&
5220Sstevel@tonic-gate 		(rsa->iqmp != NULL)) )
5232139Sjp161948 		{
5242139Sjp161948 		if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
5252139Sjp161948 		}
5260Sstevel@tonic-gate 	else
5270Sstevel@tonic-gate 		{
5282139Sjp161948 		BIGNUM local_d;
5292139Sjp161948 		BIGNUM *d = NULL;
5302139Sjp161948 
5312139Sjp161948 		if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
5322139Sjp161948 			{
5332139Sjp161948 			d = &local_d;
5342139Sjp161948 			BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
5352139Sjp161948 			}
5362139Sjp161948 		else
5372139Sjp161948 			d = rsa->d;
5382139Sjp161948 
5392139Sjp161948 		MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
5402139Sjp161948 		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
5412139Sjp161948 				rsa->_method_mod_n))
5422139Sjp161948 		  goto err;
5430Sstevel@tonic-gate 		}
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 	if (blinding)
5462139Sjp161948 		if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
5472139Sjp161948 			goto err;
5480Sstevel@tonic-gate 
5490Sstevel@tonic-gate 	p=buf;
5502139Sjp161948 	j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
5510Sstevel@tonic-gate 
5520Sstevel@tonic-gate 	switch (padding)
5530Sstevel@tonic-gate 		{
5540Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
5550Sstevel@tonic-gate 		r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
5560Sstevel@tonic-gate 		break;
5570Sstevel@tonic-gate #ifndef OPENSSL_NO_SHA
5580Sstevel@tonic-gate         case RSA_PKCS1_OAEP_PADDING:
5590Sstevel@tonic-gate 	        r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
5600Sstevel@tonic-gate                 break;
5610Sstevel@tonic-gate #endif
5620Sstevel@tonic-gate  	case RSA_SSLV23_PADDING:
5630Sstevel@tonic-gate 		r=RSA_padding_check_SSLv23(to,num,buf,j,num);
5640Sstevel@tonic-gate 		break;
5650Sstevel@tonic-gate 	case RSA_NO_PADDING:
5660Sstevel@tonic-gate 		r=RSA_padding_check_none(to,num,buf,j,num);
5670Sstevel@tonic-gate 		break;
5680Sstevel@tonic-gate 	default:
5690Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
5700Sstevel@tonic-gate 		goto err;
5710Sstevel@tonic-gate 		}
5720Sstevel@tonic-gate 	if (r < 0)
5730Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
5740Sstevel@tonic-gate 
5750Sstevel@tonic-gate err:
5762139Sjp161948 	if (ctx != NULL)
5772139Sjp161948 		{
5782139Sjp161948 		BN_CTX_end(ctx);
5792139Sjp161948 		BN_CTX_free(ctx);
5802139Sjp161948 		}
5810Sstevel@tonic-gate 	if (buf != NULL)
5820Sstevel@tonic-gate 		{
5830Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
5840Sstevel@tonic-gate 		OPENSSL_free(buf);
5850Sstevel@tonic-gate 		}
5860Sstevel@tonic-gate 	return(r);
5870Sstevel@tonic-gate 	}
5880Sstevel@tonic-gate 
5890Sstevel@tonic-gate /* signature verification */
RSA_eay_public_decrypt(int flen,const unsigned char * from,unsigned char * to,RSA * rsa,int padding)5900Sstevel@tonic-gate static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
5910Sstevel@tonic-gate 	     unsigned char *to, RSA *rsa, int padding)
5920Sstevel@tonic-gate 	{
5932139Sjp161948 	BIGNUM *f,*ret;
5940Sstevel@tonic-gate 	int i,num=0,r= -1;
5950Sstevel@tonic-gate 	unsigned char *p;
5960Sstevel@tonic-gate 	unsigned char *buf=NULL;
5970Sstevel@tonic-gate 	BN_CTX *ctx=NULL;
5980Sstevel@tonic-gate 
599*2864Sjp161948 	if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
600*2864Sjp161948 		{
601*2864Sjp161948 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
602*2864Sjp161948 		return -1;
603*2864Sjp161948 		}
604*2864Sjp161948 
605*2864Sjp161948 	if (BN_ucmp(rsa->n, rsa->e) <= 0)
606*2864Sjp161948 		{
607*2864Sjp161948 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
608*2864Sjp161948 		return -1;
609*2864Sjp161948 		}
610*2864Sjp161948 
611*2864Sjp161948 	/* for large moduli, enforce exponent limit */
612*2864Sjp161948 	if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
613*2864Sjp161948 		{
614*2864Sjp161948 		if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
615*2864Sjp161948 			{
616*2864Sjp161948 			RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
617*2864Sjp161948 			return -1;
618*2864Sjp161948 			}
619*2864Sjp161948 		}
620*2864Sjp161948 
6212139Sjp161948 	if((ctx = BN_CTX_new()) == NULL) goto err;
6222139Sjp161948 	BN_CTX_start(ctx);
6232139Sjp161948 	f = BN_CTX_get(ctx);
6242139Sjp161948 	ret = BN_CTX_get(ctx);
6250Sstevel@tonic-gate 	num=BN_num_bytes(rsa->n);
6262139Sjp161948 	buf = OPENSSL_malloc(num);
6272139Sjp161948 	if(!f || !ret || !buf)
6280Sstevel@tonic-gate 		{
6290Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
6300Sstevel@tonic-gate 		goto err;
6310Sstevel@tonic-gate 		}
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate 	/* This check was for equality but PGP does evil things
6340Sstevel@tonic-gate 	 * and chops off the top '0' bytes */
6350Sstevel@tonic-gate 	if (flen > num)
6360Sstevel@tonic-gate 		{
6370Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
6380Sstevel@tonic-gate 		goto err;
6390Sstevel@tonic-gate 		}
6400Sstevel@tonic-gate 
6412139Sjp161948 	if (BN_bin2bn(from,flen,f) == NULL) goto err;
6420Sstevel@tonic-gate 
6432139Sjp161948 	if (BN_ucmp(f, rsa->n) >= 0)
6440Sstevel@tonic-gate 		{
6450Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
6460Sstevel@tonic-gate 		goto err;
6470Sstevel@tonic-gate 		}
6480Sstevel@tonic-gate 
6492139Sjp161948 	MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
6502139Sjp161948 
6512139Sjp161948 	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
6520Sstevel@tonic-gate 		rsa->_method_mod_n)) goto err;
6530Sstevel@tonic-gate 
6542139Sjp161948 	if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
6552139Sjp161948 		BN_sub(ret, rsa->n, ret);
6562139Sjp161948 
6570Sstevel@tonic-gate 	p=buf;
6582139Sjp161948 	i=BN_bn2bin(ret,p);
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate 	switch (padding)
6610Sstevel@tonic-gate 		{
6620Sstevel@tonic-gate 	case RSA_PKCS1_PADDING:
6630Sstevel@tonic-gate 		r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
6640Sstevel@tonic-gate 		break;
6652139Sjp161948 	case RSA_X931_PADDING:
6662139Sjp161948 		r=RSA_padding_check_X931(to,num,buf,i,num);
6672139Sjp161948 		break;
6680Sstevel@tonic-gate 	case RSA_NO_PADDING:
6690Sstevel@tonic-gate 		r=RSA_padding_check_none(to,num,buf,i,num);
6700Sstevel@tonic-gate 		break;
6710Sstevel@tonic-gate 	default:
6720Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
6730Sstevel@tonic-gate 		goto err;
6740Sstevel@tonic-gate 		}
6750Sstevel@tonic-gate 	if (r < 0)
6760Sstevel@tonic-gate 		RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate err:
6792139Sjp161948 	if (ctx != NULL)
6802139Sjp161948 		{
6812139Sjp161948 		BN_CTX_end(ctx);
6822139Sjp161948 		BN_CTX_free(ctx);
6832139Sjp161948 		}
6840Sstevel@tonic-gate 	if (buf != NULL)
6850Sstevel@tonic-gate 		{
6860Sstevel@tonic-gate 		OPENSSL_cleanse(buf,num);
6870Sstevel@tonic-gate 		OPENSSL_free(buf);
6880Sstevel@tonic-gate 		}
6890Sstevel@tonic-gate 	return(r);
6900Sstevel@tonic-gate 	}
6910Sstevel@tonic-gate 
RSA_eay_mod_exp(BIGNUM * r0,const BIGNUM * I,RSA * rsa,BN_CTX * ctx)6922139Sjp161948 static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
6930Sstevel@tonic-gate 	{
6942139Sjp161948 	BIGNUM *r1,*m1,*vrfy;
6952139Sjp161948 	BIGNUM local_dmp1, local_dmq1;
6962139Sjp161948 	BIGNUM *dmp1, *dmq1;
6970Sstevel@tonic-gate 	int ret=0;
6980Sstevel@tonic-gate 
6992139Sjp161948 	BN_CTX_start(ctx);
7002139Sjp161948 	r1 = BN_CTX_get(ctx);
7012139Sjp161948 	m1 = BN_CTX_get(ctx);
7022139Sjp161948 	vrfy = BN_CTX_get(ctx);
7030Sstevel@tonic-gate 
7042139Sjp161948 	MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
7052139Sjp161948 	MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
7062139Sjp161948 	MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
7072139Sjp161948 
7082139Sjp161948 	if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
7092139Sjp161948 	if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
7100Sstevel@tonic-gate 		{
7112139Sjp161948 		dmq1 = &local_dmq1;
7122139Sjp161948 		BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
7130Sstevel@tonic-gate 		}
7142139Sjp161948 	else
7152139Sjp161948 		dmq1 = rsa->dmq1;
7162139Sjp161948 	if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
7170Sstevel@tonic-gate 		rsa->_method_mod_q)) goto err;
7180Sstevel@tonic-gate 
7192139Sjp161948 	if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
7202139Sjp161948 	if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
7212139Sjp161948 		{
7222139Sjp161948 		dmp1 = &local_dmp1;
7232139Sjp161948 		BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
7242139Sjp161948 		}
7252139Sjp161948 	else
7262139Sjp161948 		dmp1 = rsa->dmp1;
7272139Sjp161948 	if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
7280Sstevel@tonic-gate 		rsa->_method_mod_p)) goto err;
7290Sstevel@tonic-gate 
7302139Sjp161948 	if (!BN_sub(r0,r0,m1)) goto err;
7310Sstevel@tonic-gate 	/* This will help stop the size of r0 increasing, which does
7320Sstevel@tonic-gate 	 * affect the multiply if it optimised for a power of 2 size */
7332139Sjp161948 	if (BN_is_negative(r0))
7340Sstevel@tonic-gate 		if (!BN_add(r0,r0,rsa->p)) goto err;
7350Sstevel@tonic-gate 
7362139Sjp161948 	if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
7372139Sjp161948 	if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
7380Sstevel@tonic-gate 	/* If p < q it is occasionally possible for the correction of
7390Sstevel@tonic-gate          * adding 'p' if r0 is negative above to leave the result still
7400Sstevel@tonic-gate 	 * negative. This can break the private key operations: the following
7410Sstevel@tonic-gate 	 * second correction should *always* correct this rare occurrence.
7420Sstevel@tonic-gate 	 * This will *never* happen with OpenSSL generated keys because
7430Sstevel@tonic-gate          * they ensure p > q [steve]
7440Sstevel@tonic-gate          */
7452139Sjp161948 	if (BN_is_negative(r0))
7460Sstevel@tonic-gate 		if (!BN_add(r0,r0,rsa->p)) goto err;
7472139Sjp161948 	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
7482139Sjp161948 	if (!BN_add(r0,r1,m1)) goto err;
7490Sstevel@tonic-gate 
7500Sstevel@tonic-gate 	if (rsa->e && rsa->n)
7510Sstevel@tonic-gate 		{
7522139Sjp161948 		if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
7530Sstevel@tonic-gate 		/* If 'I' was greater than (or equal to) rsa->n, the operation
7540Sstevel@tonic-gate 		 * will be equivalent to using 'I mod n'. However, the result of
7550Sstevel@tonic-gate 		 * the verify will *always* be less than 'n' so we don't check
7560Sstevel@tonic-gate 		 * for absolute equality, just congruency. */
7572139Sjp161948 		if (!BN_sub(vrfy, vrfy, I)) goto err;
7582139Sjp161948 		if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
7592139Sjp161948 		if (BN_is_negative(vrfy))
7602139Sjp161948 			if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
7612139Sjp161948 		if (!BN_is_zero(vrfy))
7622139Sjp161948 			{
7630Sstevel@tonic-gate 			/* 'I' and 'vrfy' aren't congruent mod n. Don't leak
7640Sstevel@tonic-gate 			 * miscalculated CRT output, just do a raw (slower)
7650Sstevel@tonic-gate 			 * mod_exp and return that instead. */
7662139Sjp161948 
7672139Sjp161948 			BIGNUM local_d;
7682139Sjp161948 			BIGNUM *d = NULL;
7692139Sjp161948 
7702139Sjp161948 			if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
7712139Sjp161948 				{
7722139Sjp161948 				d = &local_d;
7732139Sjp161948 				BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
7742139Sjp161948 				}
7752139Sjp161948 			else
7762139Sjp161948 				d = rsa->d;
7772139Sjp161948 			if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
7782139Sjp161948 						   rsa->_method_mod_n)) goto err;
7792139Sjp161948 			}
7800Sstevel@tonic-gate 		}
7810Sstevel@tonic-gate 	ret=1;
7820Sstevel@tonic-gate err:
7832139Sjp161948 	BN_CTX_end(ctx);
7840Sstevel@tonic-gate 	return(ret);
7850Sstevel@tonic-gate 	}
7860Sstevel@tonic-gate 
RSA_eay_init(RSA * rsa)7870Sstevel@tonic-gate static int RSA_eay_init(RSA *rsa)
7880Sstevel@tonic-gate 	{
7890Sstevel@tonic-gate 	rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
7900Sstevel@tonic-gate 	return(1);
7910Sstevel@tonic-gate 	}
7920Sstevel@tonic-gate 
RSA_eay_finish(RSA * rsa)7930Sstevel@tonic-gate static int RSA_eay_finish(RSA *rsa)
7940Sstevel@tonic-gate 	{
7950Sstevel@tonic-gate 	if (rsa->_method_mod_n != NULL)
7960Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_n);
7970Sstevel@tonic-gate 	if (rsa->_method_mod_p != NULL)
7980Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_p);
7990Sstevel@tonic-gate 	if (rsa->_method_mod_q != NULL)
8000Sstevel@tonic-gate 		BN_MONT_CTX_free(rsa->_method_mod_q);
8010Sstevel@tonic-gate 	return(1);
8020Sstevel@tonic-gate 	}
8030Sstevel@tonic-gate 
8040Sstevel@tonic-gate #endif
805