X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Frsa%2Frsa_ossl.c;h=5c3c0bf95ecc3d79eb95ce30007905baeb893b30;hp=09a65b80b1f1203719b07a26c44c7a01d71f2f27;hb=9862e9aa98ee1e38fbcef8d1dd5db0e750eb5e8d;hpb=bf1605518a085256320ff4a36054445f842d5c1c diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index 09a65b80b1..5c3c0bf95e 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -110,8 +110,8 @@ #include "internal/cryptlib.h" #include "internal/bn_int.h" -#include #include +#include "rsa_locl.h" #ifndef RSA_NULL @@ -220,7 +220,7 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, @@ -248,26 +248,18 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) { BN_BLINDING *ret; - int got_write_lock = 0; - CRYPTO_THREADID cur; - CRYPTO_r_lock(CRYPTO_LOCK_RSA); + CRYPTO_THREAD_write_lock(rsa->lock); if (rsa->blinding == NULL) { - CRYPTO_r_unlock(CRYPTO_LOCK_RSA); - CRYPTO_w_lock(CRYPTO_LOCK_RSA); - got_write_lock = 1; - - if (rsa->blinding == NULL) - rsa->blinding = RSA_setup_blinding(rsa, ctx); + rsa->blinding = RSA_setup_blinding(rsa, ctx); } ret = rsa->blinding; if (ret == NULL) goto err; - CRYPTO_THREADID_current(&cur); - if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) { + if (BN_BLINDING_is_current_thread(ret)) { /* rsa->blinding is ours! */ *local = 1; @@ -282,23 +274,13 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) *local = 0; if (rsa->mt_blinding == NULL) { - if (!got_write_lock) { - CRYPTO_r_unlock(CRYPTO_LOCK_RSA); - CRYPTO_w_lock(CRYPTO_LOCK_RSA); - got_write_lock = 1; - } - - if (rsa->mt_blinding == NULL) - rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); } ret = rsa->mt_blinding; } err: - if (got_write_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_RSA); - else - CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_THREAD_unlock(rsa->lock); return ret; } @@ -315,9 +297,11 @@ static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, * Shared blinding: store the unblinding factor outside BN_BLINDING. */ int ret; - CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); + + BN_BLINDING_lock(b); ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); - CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); + BN_BLINDING_unlock(b); + return ret; } } @@ -426,12 +410,13 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - } else + } else { d = rsa->d; + } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) { + (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) { BN_free(local_d); goto err; } @@ -441,6 +426,7 @@ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, BN_free(local_d); goto err; } + /* We MUST free local_d before any further use of rsa->d */ BN_free(local_d); } @@ -558,12 +544,13 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - } else + } else { d = rsa->d; + } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) { + (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) { BN_free(local_d); goto err; } @@ -572,6 +559,7 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, BN_free(local_d); goto err; } + /* We MUST free local_d before any further use of rsa->d */ BN_free(local_d); } @@ -670,7 +658,7 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, @@ -712,20 +700,10 @@ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { BIGNUM *r1, *m1, *vrfy; - BIGNUM *local_dmp1, *local_dmq1, *local_c, *local_r1; - BIGNUM *dmp1, *dmq1, *c, *pr1; int ret = 0; BN_CTX_start(ctx); - local_dmp1 = BN_new(); - local_dmq1 = BN_new(); - local_c = BN_new(); - local_r1 = BN_new(); - if (local_dmp1 == NULL - || local_dmq1 == NULL || local_c == NULL || local_r1 == NULL) - goto err; - r1 = BN_CTX_get(ctx); m1 = BN_CTX_get(ctx); vrfy = BN_CTX_get(ctx); @@ -735,7 +713,7 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) BIGNUM *p = NULL, *q = NULL; /* - * Make sure BN_mod_inverse in Montgomery intialization uses the + * Make sure BN_mod_inverse in Montgomery initialization uses the * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) */ if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { @@ -757,62 +735,96 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx) + (&rsa->_method_mod_p, rsa->lock, p, ctx) || !BN_MONT_CTX_set_locked(&rsa->_method_mod_q, - CRYPTO_LOCK_RSA, q, ctx)) { + rsa->lock, q, ctx)) { BN_free(local_p); BN_free(local_q); goto err; } } + /* + * We MUST free local_p and local_q before any further use of rsa->p and + * rsa->q + */ BN_free(local_p); BN_free(local_q); } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked - (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) goto err; /* compute I mod q */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - c = local_c; - BN_with_flags(c, I, BN_FLG_CONSTTIME); - if (!BN_mod(r1, c, rsa->q, ctx)) - goto err; - } else { - if (!BN_mod(r1, I, rsa->q, ctx)) + { + BIGNUM *local_c = NULL; + const BIGNUM *c; + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + local_c = BN_new(); + if (local_c == NULL) + goto err; + BN_with_flags(local_c, I, BN_FLG_CONSTTIME); + c = local_c; + } else { + c = I; + } + if (!BN_mod(r1, c, rsa->q, ctx)) { + BN_free(local_c); goto err; - } + } - /* compute r1^dmq1 mod q */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - dmq1 = local_dmq1; - BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); - } else - dmq1 = rsa->dmq1; - if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) - goto err; + { + BIGNUM *local_dmq1 = NULL, *dmq1; + /* compute r1^dmq1 mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmq1 = local_dmq1 = BN_new(); + if (local_dmq1 == NULL) { + BN_free(local_c); + goto err; + } + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + } else { + dmq1 = rsa->dmq1; + } + if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, + rsa->_method_mod_q)) { + BN_free(local_c); + BN_free(local_dmq1); + goto err; + } + /* We MUST free local_dmq1 before any further use of rsa->dmq1 */ + BN_free(local_dmq1); + } - /* compute I mod p */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - c = local_c; - BN_with_flags(c, I, BN_FLG_CONSTTIME); - if (!BN_mod(r1, c, rsa->p, ctx)) - goto err; - } else { - if (!BN_mod(r1, I, rsa->p, ctx)) + /* compute I mod p */ + if (!BN_mod(r1, c, rsa->p, ctx)) { + BN_free(local_c); goto err; + } + /* We MUST free local_c before any further use of I */ + BN_free(local_c); } - /* compute r1^dmp1 mod p */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - dmp1 = local_dmp1; - BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); - } else - dmp1 = rsa->dmp1; - if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) - goto err; + { + BIGNUM *local_dmp1 = NULL, *dmp1; + /* compute r1^dmp1 mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmp1 = local_dmp1 = BN_new(); + if (local_dmp1 == NULL) + goto err; + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + } else { + dmp1 = rsa->dmp1; + } + if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, + rsa->_method_mod_p)) { + BN_free(local_dmp1); + goto err; + } + /* We MUST free local_dmp1 before any further use of rsa->dmp1 */ + BN_free(local_dmp1); + } if (!BN_sub(r0, r0, m1)) goto err; @@ -827,14 +839,24 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (!BN_mul(r1, r0, rsa->iqmp, ctx)) goto err; - /* Turn BN_FLG_CONSTTIME flag on before division operation */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - pr1 = local_r1; - BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); - } else - pr1 = r1; - if (!BN_mod(r0, pr1, rsa->p, ctx)) - goto err; + { + BIGNUM *local_r1 = NULL, *pr1; + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + pr1 = local_r1 = BN_new(); + if (local_r1 == NULL) + goto err; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + } else { + pr1 = r1; + } + if (!BN_mod(r0, pr1, rsa->p, ctx)) { + BN_free(local_r1); + goto err; + } + /* We MUST free local_r1 before any further use of r1 */ + BN_free(local_r1); + } /* * If p < q it is occasionally possible for the correction of adding 'p' @@ -883,23 +905,20 @@ static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) if (d == NULL) goto err; BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - } else + } else { d = rsa->d; + } if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(local_d); goto err; } - + /* We MUST free local_d before any further use of rsa->d */ BN_free(local_d); } } ret = 1; err: - BN_free(local_dmp1); - BN_free(local_dmq1); - BN_free(local_c); - BN_free(local_r1); BN_CTX_end(ctx); return (ret); }