X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Frsa%2Frsa_lib.c;h=e334e506fb7bc5aa50cc4a8c9403bb4870713d18;hp=e3368c1ee5ea12b490f2b91af39b676c779d5637;hb=d76b8c89ec218b3ce6c83e27220d2df4d0213599;hpb=79aa04ef27f69a1149d4d0e72d2d2953b6241ef0 diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index e3368c1ee5..e334e506fb 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -62,38 +62,29 @@ #include #include #include +#include +#ifndef OPENSSL_NO_ENGINE #include +#endif -const char *RSA_version="RSA" OPENSSL_VERSION_PTEXT; +const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT; static const RSA_METHOD *default_RSA_meth=NULL; RSA *RSA_new(void) { - return(RSA_new_method(NULL)); + RSA *r=RSA_new_method(NULL); + + return r; } -void RSA_set_default_openssl_method(const RSA_METHOD *meth) +void RSA_set_default_method(const RSA_METHOD *meth) { - ENGINE *e; - /* We'll need to notify the "openssl" ENGINE of this - * change too. We won't bother locking things down at - * our end as there was never any locking in these - * functions! */ - if(default_RSA_meth != meth) - { - default_RSA_meth = meth; - e = ENGINE_by_id("openssl"); - if(e) - { - ENGINE_set_RSA(e, meth); - ENGINE_free(e); - } - } + default_RSA_meth = meth; } -const RSA_METHOD *RSA_get_default_openssl_method(void) -{ +const RSA_METHOD *RSA_get_default_method(void) + { if (default_RSA_meth == NULL) { #ifdef RSA_NULL @@ -108,76 +99,70 @@ const RSA_METHOD *RSA_get_default_openssl_method(void) } return default_RSA_meth; -} + } const RSA_METHOD *RSA_get_method(const RSA *rsa) -{ - return ENGINE_get_RSA(rsa->engine); -} + { + return rsa->meth; + } -#if 0 -RSA_METHOD *RSA_set_method(RSA *rsa, RSA_METHOD *meth) -{ - RSA_METHOD *mtmp; +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) + { + /* NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. */ + const RSA_METHOD *mtmp; mtmp = rsa->meth; if (mtmp->finish) mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE + if (rsa->engine) + { + ENGINE_finish(rsa->engine); + rsa->engine = NULL; + } +#endif rsa->meth = meth; if (meth->init) meth->init(rsa); - return mtmp; -} -#else -int RSA_set_method(RSA *rsa, ENGINE *engine) -{ - ENGINE *mtmp; - const RSA_METHOD *meth; - mtmp = rsa->engine; - meth = ENGINE_get_RSA(mtmp); - if (!ENGINE_init(engine)) - return 0; - if (meth->finish) meth->finish(rsa); - rsa->engine = engine; - meth = ENGINE_get_RSA(engine); - if (meth->init) meth->init(rsa); - /* SHOULD ERROR CHECK THIS!!! */ - ENGINE_finish(mtmp); return 1; -} -#endif + } -#if 0 -RSA *RSA_new_method(RSA_METHOD *meth) -#else RSA *RSA_new_method(ENGINE *engine) -#endif { - const RSA_METHOD *meth; RSA *ret; ret=(RSA *)OPENSSL_malloc(sizeof(RSA)); if (ret == NULL) { RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE); - return(NULL); + return NULL; } + ret->meth = RSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE if (engine) { - if(ENGINE_init(engine)) - ret->engine = engine; - else - ret->engine = NULL; + if (!ENGINE_init(engine)) + { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; } else - ret->engine=ENGINE_get_default_RSA(); - - if(ret->engine == NULL) + ret->engine = ENGINE_get_default_RSA(); + if(ret->engine) { - RSAerr(RSA_F_RSA_NEW_METHOD,ERR_LIB_ENGINE); - OPENSSL_free(ret); - return NULL; + ret->meth = ENGINE_get_RSA(ret->engine); + if(!ret->meth) + { + RSAerr(RSA_F_RSA_NEW_METHOD, + ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } } - - meth = ENGINE_get_RSA(ret->engine); +#endif ret->pad=0; ret->version=0; @@ -194,11 +179,16 @@ RSA *RSA_new_method(ENGINE *engine) ret->_method_mod_p=NULL; ret->_method_mod_q=NULL; ret->blinding=NULL; + ret->mt_blinding=NULL; ret->bignum_data=NULL; - ret->flags=meth->flags; + ret->flags=ret->meth->flags; CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); - if ((meth->init != NULL) && !meth->init(ret)) + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); OPENSSL_free(ret); ret=NULL; @@ -208,7 +198,6 @@ RSA *RSA_new_method(ENGINE *engine) void RSA_free(RSA *r) { - const RSA_METHOD *meth; int i; if (r == NULL) return; @@ -226,10 +215,12 @@ void RSA_free(RSA *r) } #endif - meth = ENGINE_get_RSA(r->engine); - if (meth->finish != NULL) - meth->finish(r); - ENGINE_finish(r->engine); + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); @@ -242,11 +233,12 @@ void RSA_free(RSA *r) if (r->dmq1 != NULL) BN_clear_free(r->dmq1); if (r->iqmp != NULL) BN_clear_free(r->iqmp); if (r->blinding != NULL) BN_BLINDING_free(r->blinding); + if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding); if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data); OPENSSL_free(r); } -int RSA_up(RSA *r) +int RSA_up_ref(RSA *r) { int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); #ifdef REF_PRINT @@ -255,7 +247,7 @@ int RSA_up(RSA *r) #ifdef REF_CHECK if (i < 2) { - fprintf(stderr, "RSA_up, bad reference count\n"); + fprintf(stderr, "RSA_up_ref, bad reference count\n"); abort(); } #endif @@ -287,34 +279,30 @@ int RSA_size(const RSA *r) int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - return(ENGINE_get_RSA(rsa->engine)->rsa_pub_enc(flen, - from, to, rsa, padding)); + return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding)); } int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - return(ENGINE_get_RSA(rsa->engine)->rsa_priv_enc(flen, - from, to, rsa, padding)); + return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); } int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - return(ENGINE_get_RSA(rsa->engine)->rsa_priv_dec(flen, - from, to, rsa, padding)); + return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding)); } int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { - return(ENGINE_get_RSA(rsa->engine)->rsa_pub_dec(flen, - from, to, rsa, padding)); + return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); } int RSA_flags(const RSA *r) { - return((r == NULL)?0:ENGINE_get_RSA(r->engine)->flags); + return((r == NULL)?0:r->meth->flags); } void RSA_blinding_off(RSA *rsa) @@ -324,42 +312,121 @@ void RSA_blinding_off(RSA *rsa) BN_BLINDING_free(rsa->blinding); rsa->blinding=NULL; } - rsa->flags&= ~RSA_FLAG_BLINDING; + rsa->flags &= ~RSA_FLAG_BLINDING; + rsa->flags |= RSA_FLAG_NO_BLINDING; } -int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx) +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { - BIGNUM *A,*Ai; - BN_CTX *ctx; int ret=0; - if (p_ctx == NULL) + if (rsa->blinding != NULL) + RSA_blinding_off(rsa); + + rsa->blinding = RSA_setup_blinding(rsa, ctx); + if (rsa->blinding == NULL) + goto err; + + rsa->flags |= RSA_FLAG_BLINDING; + rsa->flags &= ~RSA_FLAG_NO_BLINDING; + ret=1; +err: + return(ret); + } + +static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, + const BIGNUM *q, BN_CTX *ctx) +{ + BIGNUM *ret = NULL, *r0, *r1, *r2; + + if (d == NULL || p == NULL || q == NULL) + return NULL; + + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + if (r2 == NULL) + goto err; + + if (!BN_sub(r1, p, BN_value_one())) goto err; + if (!BN_sub(r2, q, BN_value_one())) goto err; + if (!BN_mul(r0, r1, r2, ctx)) goto err; + + ret = BN_mod_inverse(NULL, d, r0, ctx); +err: + BN_CTX_end(ctx); + return ret; +} + +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) +{ + BIGNUM local_n; + BIGNUM *e,*n; + BN_CTX *ctx; + BN_BLINDING *ret = NULL; + + if (in_ctx == NULL) { - if ((ctx=BN_CTX_new()) == NULL) goto err; + if ((ctx = BN_CTX_new()) == NULL) return 0; } else - ctx=p_ctx; - - if (rsa->blinding != NULL) - BN_BLINDING_free(rsa->blinding); + ctx = in_ctx; BN_CTX_start(ctx); - A = BN_CTX_get(ctx); - if (!BN_rand_range(A,rsa->n)) goto err; - if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; - - if (!ENGINE_get_RSA(rsa->engine)->bn_mod_exp(A,A, - rsa->e,rsa->n,ctx,rsa->_method_mod_n)) - goto err; - rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n); - rsa->flags|=RSA_FLAG_BLINDING; - BN_free(Ai); - ret=1; + e = BN_CTX_get(ctx); + if (e == NULL) + { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa->e == NULL) + { + e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); + if (e == NULL) + { + RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + } + else + e = rsa->e; + + + if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) + { + /* if PRNG is not properly seeded, resort to secret + * exponent as unpredictable seed */ + RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0); + } + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) + { + /* Set BN_FLG_CONSTTIME flag */ + n = &local_n; + BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); + } + else + n = rsa->n; + + ret = BN_BLINDING_create_param(NULL, e, n, ctx, + rsa->meth->bn_mod_exp, rsa->_method_mod_n); + if (ret == NULL) + { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); + goto err; + } + CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: BN_CTX_end(ctx); - if (ctx != p_ctx) BN_CTX_free(ctx); - return(ret); - } + if (in_ctx == NULL) + BN_CTX_free(ctx); + if(rsa->e == NULL) + BN_free(e); + + return ret; +} int RSA_memory_lock(RSA *r) { @@ -382,7 +449,7 @@ int RSA_memory_lock(RSA *r) j+= (*t[i])->top; if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL) { - RSAerr(RSA_F_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); + RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE); return(0); } bn=(BIGNUM *)p; @@ -405,4 +472,3 @@ int RSA_memory_lock(RSA *r) r->bignum_data=p; return(1); } -