X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=crypto%2Frsa%2Frsa_eay.c;h=d82dd15493bd1802b9bae7d6d579cbae65a05bed;hb=003144a8e8ed5c6c4aaee6e227773bb3d6bc0f9d;hp=6a68770031d6d651b3903d24a8529ce2eda2715e;hpb=975842f9fb216e453b67c19ffe4509837fb59ccb;p=oweals%2Fopenssl.git diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c index 6a68770031..d82dd15493 100644 --- a/crypto/rsa/rsa_eay.c +++ b/crypto/rsa/rsa_eay.c @@ -79,15 +79,17 @@ static int RSA_eay_finish(RSA *rsa); static RSA_METHOD rsa_pkcs1_eay_meth={ "Eric Young's PKCS#1 RSA", RSA_eay_public_encrypt, - RSA_eay_public_decrypt, - RSA_eay_private_encrypt, + RSA_eay_public_decrypt, /* signature verification */ + RSA_eay_private_encrypt, /* signing */ RSA_eay_private_decrypt, RSA_eay_mod_exp, BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */ RSA_eay_init, RSA_eay_finish, - 0, + 0, /* flags */ NULL, + 0, /* rsa_sign */ + 0 /* rsa_verify */ }; const RSA_METHOD *RSA_PKCS1_SSLeay(void) @@ -98,13 +100,11 @@ const RSA_METHOD *RSA_PKCS1_SSLeay(void) static int RSA_eay_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - const RSA_METHOD *meth; BIGNUM f,ret; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; - meth = ENGINE_get_RSA(rsa->engine); BN_init(&f); BN_init(&ret); if ((ctx=BN_CTX_new()) == NULL) goto err; @@ -120,7 +120,7 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from, case RSA_PKCS1_PADDING: i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen); break; -#ifndef NO_SHA +#ifndef OPENSSL_NO_SHA case RSA_PKCS1_OAEP_PADDING: i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0); break; @@ -139,6 +139,13 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from, if (BN_bin2bn(buf,num,&f) == NULL) goto err; + if (BN_ucmp(&f, rsa->n) >= 0) + { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC)) { BN_MONT_CTX* bn_mont_ctx; @@ -163,7 +170,7 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from, BN_MONT_CTX_free(bn_mont_ctx); } - if (!meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx, + if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; /* put in leading 0 bytes if the number is less than the @@ -186,16 +193,15 @@ err: return(r); } +/* signing */ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - const RSA_METHOD *meth; BIGNUM f,ret; int i,j,k,num=0,r= -1; unsigned char *buf=NULL; BN_CTX *ctx=NULL; - meth = ENGINE_get_RSA(rsa->engine); BN_init(&f); BN_init(&ret); @@ -223,6 +229,13 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, if (i <= 0) goto err; if (BN_bin2bn(buf,num,&f) == NULL) goto err; + + if (BN_ucmp(&f, rsa->n) >= 0) + { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL)) RSA_blinding_on(rsa,ctx); @@ -235,10 +248,10 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) - { if (!meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } + { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } else { - if (!meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; + if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; } if (rsa->flags & RSA_FLAG_BLINDING) @@ -267,14 +280,12 @@ err: static int RSA_eay_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - const RSA_METHOD *meth; BIGNUM f,ret; int j,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; - meth = ENGINE_get_RSA(rsa->engine); BN_init(&f); BN_init(&ret); ctx=BN_CTX_new(); @@ -299,6 +310,12 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, /* make data into a big number */ if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err; + if (BN_ucmp(&f, rsa->n) >= 0) + { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL)) RSA_blinding_on(rsa,ctx); if (rsa->flags & RSA_FLAG_BLINDING) @@ -311,10 +328,10 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL)) ) - { if (!meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } + { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; } else { - if (!meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) + if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err; } @@ -329,7 +346,7 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, case RSA_PKCS1_PADDING: r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num); break; -#ifndef NO_SHA +#ifndef OPENSSL_NO_SHA case RSA_PKCS1_OAEP_PADDING: r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0); break; @@ -359,17 +376,16 @@ err: return(r); } +/* signature verification */ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - const RSA_METHOD *meth; BIGNUM f,ret; int i,num=0,r= -1; unsigned char *p; unsigned char *buf=NULL; BN_CTX *ctx=NULL; - meth = ENGINE_get_RSA(rsa->engine); BN_init(&f); BN_init(&ret); ctx=BN_CTX_new(); @@ -392,6 +408,13 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, } if (BN_bin2bn(from,flen,&f) == NULL) goto err; + + if (BN_ucmp(&f, rsa->n) >= 0) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + /* do the decrypt */ if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC)) { @@ -417,7 +440,7 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, BN_MONT_CTX_free(bn_mont_ctx); } - if (!meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx, + if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx, rsa->_method_mod_n)) goto err; p=buf; @@ -452,15 +475,14 @@ err: static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) { - const RSA_METHOD *meth; - BIGNUM r1,m1; + BIGNUM r1,m1,vrfy; int ret=0; BN_CTX *ctx; - meth = ENGINE_get_RSA(rsa->engine); if ((ctx=BN_CTX_new()) == NULL) goto err; BN_init(&m1); BN_init(&r1); + BN_init(&vrfy); if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { @@ -514,11 +536,11 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) } if (!BN_mod(&r1,I,rsa->q,ctx)) goto err; - if (!meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx, + if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx, rsa->_method_mod_q)) goto err; if (!BN_mod(&r1,I,rsa->p,ctx)) goto err; - if (!meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx, + if (!rsa->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx, rsa->_method_mod_p)) goto err; if (!BN_sub(r0,r0,&m1)) goto err; @@ -541,10 +563,28 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) if (!BN_mul(&r1,r0,rsa->q,ctx)) goto err; if (!BN_add(r0,&r1,&m1)) goto err; + if (rsa->e && rsa->n) + { + if (!rsa->meth->bn_mod_exp(&vrfy,r0,rsa->e,rsa->n,ctx,NULL)) goto err; + /* If 'I' was greater than (or equal to) rsa->n, the operation + * will be equivalent to using 'I mod n'. However, the result of + * the verify will *always* be less than 'n' so we don't check + * for absolute equality, just congruency. */ + if (!BN_sub(&vrfy, &vrfy, I)) goto err; + if (!BN_mod(&vrfy, &vrfy, rsa->n, ctx)) goto err; + if (vrfy.neg) + if (!BN_add(&vrfy, &vrfy, rsa->n)) goto err; + if (!BN_is_zero(&vrfy)) + /* 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) + * mod_exp and return that instead. */ + if (!rsa->meth->bn_mod_exp(r0,I,rsa->d,rsa->n,ctx,NULL)) goto err; + } ret=1; err: BN_clear_free(&m1); BN_clear_free(&r1); + BN_clear_free(&vrfy); BN_CTX_free(ctx); return(ret); }