From: Matt Caswell Date: Wed, 27 Sep 2017 10:13:47 +0000 (+0100) Subject: Ensure we test all parameters for BN_FLG_CONSTTIME X-Git-Tag: OpenSSL_1_1_1-pre1~573 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=e913d11f444e0b46ec1ebbf3340813693f4d869d Ensure we test all parameters for BN_FLG_CONSTTIME RSA_setup_blinding() calls BN_BLINDING_create_param() which later calls BN_mod_exp() as follows: BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx) ret->mod will have BN_FLG_CONSTTIME set, but ret->e does not. In BN_mod_exp() we only test the third param for the existence of this flag. We should test all the inputs. Thanks to Samuel Weiser (samuel.weiser@iaik.tugraz.at) for reporting this issue. This typically only happens once at key load, so this is unlikely to be exploitable in any real scenario. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/4477) --- diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index 72d6cad910..f9353aaae0 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -43,7 +43,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) int i, bits, ret = 0; BIGNUM *v, *rr; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -133,7 +134,9 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, if (BN_is_odd(m)) { # ifdef MONT_EXP_WORD if (a->top == 1 && !a->neg - && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) { + && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(a, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(m, BN_FLG_CONSTTIME) == 0)) { BN_ULONG A = a->d[0]; ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL); } else @@ -165,7 +168,9 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_RECP_CTX recp; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -299,7 +304,9 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, BIGNUM *val[TABLE_SIZE]; BN_MONT_CTX *mont = NULL; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); } @@ -1111,7 +1118,8 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, #define BN_TO_MONTGOMERY_WORD(r, w, mont) \ (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; @@ -1241,7 +1249,9 @@ int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, /* Table of variables obtained from 'ctx' */ BIGNUM *val[TABLE_SIZE]; - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0;