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