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