Skip to content

Commit

Permalink
Make BN_mod_inverse() deal with repeated arguments
Browse files Browse the repository at this point in the history
BN_nnmod() can deal with the situation that the first and the second
arguments are the same, but it cannot deal with the first and the
second argument being equal. In that situation, if BN_mod(x, y, x, ctx)
results in a negative x, then the result of BN_nnmod() is zero. This
breaks the strange BN_mod_inverse(m, a, m, ctx).

Reported by Guido Vranken in
openssl/openssl#21110

Change-Id: I8584720660f214f172b3b33716a5e3b29e8f2fd8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60365
Reviewed-by: Bob Beck <[email protected]>
Reviewed-by: David Benjamin <[email protected]>
Commit-Queue: David Benjamin <[email protected]>
(cherry picked from commit b0341041b03ea71d8371a9692aedae263fc06ee9)
  • Loading branch information
botovq authored and WillChilds-Klein committed Oct 6, 2023
1 parent 3991c01 commit 49ecb77
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
8 changes: 8 additions & 0 deletions crypto/fipsmodule/bn/bn_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,14 @@ static void TestModInv(BIGNUMFileTest *t, BN_CTX *ctx) {
bn_mod_inverse_consttime(ret.get(), &no_inverse, a.get(), m.get(), ctx));
EXPECT_BIGNUMS_EQUAL("inv(A) (mod M) (constant-time)", mod_inv.get(),
ret.get());

ASSERT_TRUE(BN_copy(ret.get(), m.get()));
ASSERT_TRUE(BN_mod_inverse(ret.get(), a.get(), ret.get(), ctx));
EXPECT_BIGNUMS_EQUAL("inv(A) (mod M) (ret == m)", mod_inv.get(), ret.get());

ASSERT_TRUE(BN_copy(ret.get(), a.get()));
ASSERT_TRUE(BN_mod_inverse(ret.get(), ret.get(), m.get(), ctx));
EXPECT_BIGNUMS_EQUAL("inv(A) (mod M) (ret == a)", mod_inv.get(), ret.get());
}

static void TestGCD(BIGNUMFileTest *t, BN_CTX *ctx) {
Expand Down
11 changes: 5 additions & 6 deletions crypto/fipsmodule/bn/gcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,15 +263,14 @@ int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
// Now Y*a == A (mod |n|).

// Y*a == 1 (mod |n|)
if (!Y->neg && BN_ucmp(Y, n) < 0) {
if (!BN_copy(R, Y)) {
goto err;
}
} else {
if (!BN_nnmod(R, Y, n, ctx)) {
if (Y->neg || BN_ucmp(Y, n) >= 0) {
if (!BN_nnmod(Y, Y, n, ctx)) {
goto err;
}
}
if (!BN_copy(R, Y)) {
goto err;
}

ret = 1;

Expand Down

0 comments on commit 49ecb77

Please sign in to comment.