Skip to content

Commit

Permalink
Require inputs to |BN_mod_inverse_*| to be reduced.
Browse files Browse the repository at this point in the history
  • Loading branch information
briansmith committed Jul 31, 2016
1 parent 52879da commit 0ab853a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 36 deletions.
75 changes: 75 additions & 0 deletions crypto/bn/bn_test.cc
Expand Up @@ -912,6 +912,80 @@ static bool TestExpModRejectUnreduced(BN_CTX *ctx) {
return true;
}

static bool TestModInvRejectUnreduced(RAND *rng, BN_CTX *ctx) {
ScopedBIGNUM r(BN_new());
if (!r) {
return false;
}

static const BN_ULONG kBases[] = { 2, 4, 6 };
static const BN_ULONG kModuli[] = { 1, 3 };

for (BN_ULONG mod_value : kModuli) {
ScopedBIGNUM mod(BN_new());
ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
if (!mod ||
!BN_set_word(mod.get(), mod_value) ||
!mont ||
!BN_MONT_CTX_set(mont.get(), mod.get(), ctx)) {
return false;
}
for (BN_ULONG base_value : kBases) {
ScopedBIGNUM base(BN_new());
if (!base ||
!BN_set_word(base.get(), base_value)) {
return false;
}

int no_inverse;

if (base_value >= mod_value &&
BN_mod_inverse(r.get(), base.get(), mod.get(), ctx) != NULL) {
fprintf(stderr, "BN_mod_inverse(%d, %d) succeeded!\n",
(int)base_value, (int)mod_value);
return false;
}
if (base_value >= mod_value &&
BN_mod_inverse_no_branch(r.get(), &no_inverse, base.get(), mod.get(),
ctx) != NULL) {
fprintf(stderr, "BN_mod_inverse(%d, %d) succeeded!\n",
(int)base_value, (int)mod_value);
return false;
}
if (base_value >= mod_value &&
BN_mod_inverse_blinded(r.get(), &no_inverse, base.get(), mont.get(),
rng, ctx)) {
fprintf(stderr, "BN_mod_inverse(%d, %d) succeeded!\n",
(int)base_value, (int)mod_value);
return false;
}

BN_set_negative(base.get(), 1);

if (BN_mod_inverse(r.get(), base.get(), mod.get(), ctx) != NULL) {
fprintf(stderr, "BN_mod_inverse(%d, %d) succeeded!\n",
-(int)base_value, (int)mod_value);
return false;
}
if (BN_mod_inverse_no_branch(r.get(), &no_inverse, base.get(), mod.get(),
ctx) != NULL) {
fprintf(stderr, "BN_mod_inverse_no_branch(%d, %d) succeeded!\n",
-(int)base_value, (int)mod_value);
return false;
}
if (BN_mod_inverse_blinded(r.get(), &no_inverse, base.get(), mont.get(),
rng, ctx)) {
fprintf(stderr, "BN_mod_inverse_blinded(%d, %d) succeeded!\n",
-(int)base_value, (int)mod_value);
return false;
}

}
}

return true;
}

static bool TestCmpWord() {
static const BN_ULONG kMaxWord = (BN_ULONG)-1;

Expand Down Expand Up @@ -996,6 +1070,7 @@ extern "C" int bssl_bn_test_main(RAND *rng) {
!TestBadModulus(ctx.get()) ||
!TestExpModZero(rng) ||
!TestExpModRejectUnreduced(ctx.get()) ||
!TestModInvRejectUnreduced(rng, ctx.get()) ||
!TestCmpWord()) {
return 1;
}
Expand Down
25 changes: 14 additions & 11 deletions crypto/bn/bn_tests.txt
Expand Up @@ -10366,14 +10366,17 @@ ModInv = 00
A = 00
M = 01

ModInv = 00
A = 01
M = 01

ModInv = 00
A = 02
M = 01

ModInv = 00
A = 03
M = 01
# Unreduced input is not allowed in *ring*.
# ModInv = 00
# A = 01
# M = 01

# Unreduced input is not allowed in *ring*.
# ModInv = 00
# A = 02
# M = 01

# Unreduced input is not allowed in *ring*.
# ModInv = 00
# A = 03
# M = 01
28 changes: 7 additions & 21 deletions crypto/bn/gcd.c
Expand Up @@ -151,6 +151,10 @@ static BIGNUM *bn_mod_inverse_ex(BIGNUM *out, int *out_no_inverse,
goto err;
}
A->neg = 0;
if (B->neg || (BN_ucmp(B, A) >= 0)) {
OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
goto err;
}
sign = -1;
/* From B = a mod |n|, A = |n| it follows that
*
Expand Down Expand Up @@ -298,23 +302,7 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
return BN_mod_inverse_no_branch(out, &no_inverse, a, n, ctx);
}

if (!a->neg && BN_ucmp(a, n) < 0) {
return bn_mod_inverse_ex(out, &no_inverse, a, n, ctx);
}

BIGNUM a_reduced;
BN_init(&a_reduced);
BIGNUM *ret = NULL;

if (!BN_nnmod(&a_reduced, a, n, ctx)) {
goto err;
}

ret = bn_mod_inverse_ex(out, &no_inverse, &a_reduced, n, ctx);

err:
BN_free(&a_reduced);
return ret;
return bn_mod_inverse_ex(out, &no_inverse, a, n, ctx);
}

int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
Expand Down Expand Up @@ -384,10 +372,8 @@ BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
A->neg = 0;

if (B->neg || (BN_ucmp(B, A) >= 0)) {
BN_set_flags(B, BN_FLG_CONSTTIME);
if (!BN_nnmod(B, B, A, ctx)) {
goto err;
}
OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
goto err;
}
sign = -1;
/* From B = a mod |n|, A = |n| it follows that
Expand Down
7 changes: 3 additions & 4 deletions crypto/bn/montgomery.c
Expand Up @@ -193,10 +193,9 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
tmod.top = 2;
}

if (BN_mod_inverse(Ri, R, &tmod, ctx) == NULL) {
goto err;
}
if (!BN_lshift(Ri, Ri, BN_MONT_CTX_N0_LIMBS * BN_BITS2)) {
if (!BN_mod(Ri, R, &tmod, ctx) ||
BN_mod_inverse(Ri, Ri, &tmod, ctx) == NULL ||
!BN_lshift(Ri, Ri, BN_MONT_CTX_N0_LIMBS * BN_BITS2)) {
goto err; /* R*Ri */
}
const BIGNUM *Ri_dividend;
Expand Down

0 comments on commit 0ab853a

Please sign in to comment.