diff options
Diffstat (limited to 'crypto/rsa/rsa_lib.c')
-rw-r--r-- | crypto/rsa/rsa_lib.c | 139 |
1 files changed, 104 insertions, 35 deletions
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index cba2dd66cd..de45088d76 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -67,7 +67,7 @@ #include <openssl/engine.h> #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; @@ -179,9 +179,19 @@ 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=ret->meth->flags; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) + { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return(NULL); + } + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { #ifndef OPENSSL_NO_ENGINE @@ -232,6 +242,7 @@ 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); } @@ -314,59 +325,117 @@ void RSA_blinding_off(RSA *rsa) 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 = NULL; - 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; + ctx = in_ctx; - /* XXXXX: Shouldn't this be RSA_blinding_off(rsa)? */ - if (rsa->blinding != NULL) + BN_CTX_start(ctx); + e = BN_CTX_get(ctx); + if (e == NULL) { - BN_BLINDING_free(rsa->blinding); - rsa->blinding = NULL; + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + goto err; } - /* NB: similar code appears in setup_blinding (rsa_eay.c); - * this should be placed in a new function of its own, but for reasons - * of binary compatibility can't */ + 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; - BN_CTX_start(ctx); - A = BN_CTX_get(ctx); + if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) { - /* if PRNG is not properly seeded, resort to secret exponent as unpredictable seed */ + /* 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 (!BN_pseudo_rand_range(A,rsa->n)) goto err; } - else + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - if (!BN_rand_range(A,rsa->n)) goto err; + /* Set BN_FLG_CONSTTIME flag */ + n = &local_n; + BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); } - if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err; + else + n = rsa->n; - if (!rsa->meth->bn_mod_exp(A,A,rsa->e,rsa->n,ctx,rsa->_method_mod_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; - if ((rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n)) == NULL) goto err; - /* to make things thread-safe without excessive locking, - * rsa->blinding will be used just by the current thread: */ - rsa->blinding->thread_id = CRYPTO_thread_id(); - rsa->flags |= RSA_FLAG_BLINDING; - rsa->flags &= ~RSA_FLAG_NO_BLINDING; - ret=1; + } + CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); err: - if (Ai != NULL) BN_free(Ai); 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) { @@ -389,7 +458,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; |