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