diff --git a/crypto/fipsmodule/bn/bn_test.cc b/crypto/fipsmodule/bn/bn_test.cc index a9323061..29b4456e 100644 --- a/crypto/fipsmodule/bn/bn_test.cc +++ b/crypto/fipsmodule/bn/bn_test.cc @@ -1592,21 +1592,6 @@ TEST_F(BNTest, ExpZeroModOne) { ASSERT_TRUE(BN_mod_exp_mont_consttime(r.get(), zero.get(), zero.get(), BN_value_one(), ctx(), nullptr)); EXPECT_TRUE(BN_is_zero(r.get())); - - // Historically, OpenSSL's modular exponentiation functions tolerated negative - // moduli by ignoring the sign bit. This logic should do the same. - ASSERT_TRUE(BN_mod_exp(r.get(), a.get(), zero.get(), minus_one.get(), ctx())); - EXPECT_TRUE(BN_is_zero(r.get())); - ASSERT_TRUE(BN_mod_exp_mont_word(r.get(), 0, zero.get(), minus_one.get(), - ctx(), nullptr)); - EXPECT_TRUE(BN_is_zero(r.get())); - ASSERT_TRUE(BN_mod_exp_mont(r.get(), zero.get(), zero.get(), minus_one.get(), - ctx(), nullptr)); - EXPECT_TRUE(BN_is_zero(r.get())); - - ASSERT_TRUE(BN_mod_exp_mont_consttime(r.get(), zero.get(), zero.get(), - minus_one.get(), ctx(), nullptr)); - EXPECT_TRUE(BN_is_zero(r.get())); } TEST_F(BNTest, SmallPrime) { diff --git a/crypto/fipsmodule/bn/exponentiation.c b/crypto/fipsmodule/bn/exponentiation.c index 7035ea7b..41b20571 100644 --- a/crypto/fipsmodule/bn/exponentiation.c +++ b/crypto/fipsmodule/bn/exponentiation.c @@ -446,21 +446,18 @@ static int BN_window_bits_for_exponent_size(int b) { static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { - int i, j, bits, ret = 0, wstart, window; + int i, j, ret = 0, wstart, window; int start = 1; BIGNUM *aa; // Table of variables obtained from 'ctx' BIGNUM *val[TABLE_SIZE]; BN_RECP_CTX recp; - bits = BN_num_bits(p); + // This function is only called on even moduli. + assert(!BN_is_odd(m)); + int bits = BN_num_bits(p); if (bits == 0) { - // x**0 mod 1 is still zero. - if (BN_abs_is_word(m, 1)) { - BN_zero(r); - return 1; - } return BN_one(r); } @@ -586,6 +583,10 @@ err: int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { + if (m->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } if (a->neg || BN_ucmp(a, m) >= 0) { if (!BN_nnmod(r, a, m, ctx)) { return 0; @@ -606,6 +607,10 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); return 0; } + if (m->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } if (a->neg || BN_ucmp(a, m) >= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); return 0; @@ -970,6 +975,10 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); return 0; } + if (m->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } if (a->neg || BN_ucmp(a, m) >= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); return 0;