From d46e946d2603c64df6e1e4f9db0c70baaf1c4c03 Mon Sep 17 00:00:00 2001 From: Emilia Kasper Date: Mon, 31 Aug 2015 15:51:27 +0200 Subject: [PATCH] BN_mod_exp_mont_consttime: check for zero modulus. Don't dereference |d| when |top| is zero. Also test that various BIGNUM methods behave correctly on zero/even inputs. Follow-up to b11980d79a52ec08844f08bea0e66c04b691840b Reviewed-by: Rich Salz --- crypto/bn/bn_exp.c | 7 ++++--- crypto/bn/bntest.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index 27146c89e7..7e33ba9140 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -599,12 +599,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bn_check_top(p); bn_check_top(m); - top = m->top; - - if (!(m->d[0] & 1)) { + if (!BN_is_odd(m)) { BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS); return (0); } + + top = m->top; + bits = BN_num_bits(p); if (bits == 0) { ret = BN_one(rr); diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c index 9f888f90b0..6d55049e3d 100644 --- a/crypto/bn/bntest.c +++ b/crypto/bn/bntest.c @@ -441,6 +441,14 @@ int test_div(BIO *bp, BN_CTX *ctx) BN_init(&d); BN_init(&e); + BN_one(&a); + BN_zero(&b); + + if (BN_div(&d, &c, &a, &b, ctx)) { + fprintf(stderr, "Division by zero succeeded!\n"); + return 0; + } + for (i = 0; i < num0 + num1; i++) { if (i < num1) { BN_bntest_rand(&a, 400, 0, 0); @@ -781,6 +789,18 @@ int test_mont(BIO *bp, BN_CTX *ctx) if (mont == NULL) return 0; + BN_zero(&n); + if (BN_MONT_CTX_set(mont, &n, ctx)) { + fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n"); + return 0; + } + + BN_set_word(&n, 16); + if (BN_MONT_CTX_set(mont, &n, ctx)) { + fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n"); + return 0; + } + BN_bntest_rand(&a, 100, 0, 0); BN_bntest_rand(&b, 100, 0, 0); for (i = 0; i < num2; i++) { @@ -887,6 +907,14 @@ int test_mod_mul(BIO *bp, BN_CTX *ctx) d = BN_new(); e = BN_new(); + BN_one(a); + BN_one(b); + BN_zero(c); + if (BN_mod_mul(e, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n"); + return 0; + } + for (j = 0; j < 3; j++) { BN_bntest_rand(c, 1024, 0, 0); for (i = 0; i < num0; i++) { @@ -952,6 +980,14 @@ int test_mod_exp(BIO *bp, BN_CTX *ctx) d = BN_new(); e = BN_new(); + BN_one(a); + BN_one(b); + BN_zero(c); + if (BN_mod_exp(d, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n"); + return 0; + } + BN_bntest_rand(c, 30, 0, 1); /* must be odd for montgomery */ for (i = 0; i < num2; i++) { BN_bntest_rand(a, 20 + i * 5, 0, 0); @@ -999,6 +1035,22 @@ int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx) d = BN_new(); e = BN_new(); + BN_one(a); + BN_one(b); + BN_zero(c); + if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) { + fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus " + "succeeded\n"); + return 0; + } + + BN_set_word(c, 16); + if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) { + fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus " + "succeeded\n"); + return 0; + } + BN_bntest_rand(c, 30, 0, 1); /* must be odd for montgomery */ for (i = 0; i < num2; i++) { BN_bntest_rand(a, 20 + i * 5, 0, 0); -- 2.34.1