Skip to content

Commit 11b50d3

Browse files
authored
OpenSSL CVE-2022-0778 Fix possible infinite loop in BN_mod_sqrt() (#423)
OpenSSL CVE-2022-0778 Fix possible infinite loop in BN_mod_sqrt() This commit fixes the issue released as OpenSSL CVE-2022-0778 that affects AWS-LC as well. A bug in BN_mod_sqrt() can cause the function to enter an infinite loop. The issue is now fixed and two test cases are added to verify that the function returns a failure instead of hanging. Co-authored-by: Dusan Kostic <[email protected]>
1 parent 5159ff5 commit 11b50d3

File tree

3 files changed

+32
-22
lines changed

3 files changed

+32
-22
lines changed

crypto/fipsmodule/bn/bn_tests.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11149,7 +11149,8 @@ P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
1114911149

1115011150
# NotModSquare tests.
1115111151
#
11152-
# These test vectors are such that NotModSquare is not a square modulo P.
11152+
# These test vectors are such that NotModSquare is not a square modulo P or
11153+
# P is not a prime number so BN_mod_sqrt function can't compute correctly.
1115311154

1115411155
NotModSquare = 03
1115511156
P = 07
@@ -11163,6 +11164,11 @@ P = 07
1116311164
NotModSquare = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951e
1116411165
P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
1116511166

11167+
NotModSquare = 20a7ee
11168+
P = 460201
11169+
11170+
NotModSquare = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ed
11171+
P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
1116611172

1116711173
# ModInv tests.
1116811174
#

crypto/fipsmodule/bn/sqrt.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
6363
// Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm
6464
// (cf. Henri Cohen, "A Course in Algebraic Computational Number Theory",
65-
// algorithm 1.5.1). |p| is assumed to be a prime.
65+
// algorithm 1.5.1). |p| must be prime, otherwise an error or
66+
// an incorrect "result" will be returned.
6667

6768
BIGNUM *ret = in;
6869
int err = 1;
@@ -359,23 +360,26 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
359360
goto vrfy;
360361
}
361362

362-
363-
// find smallest i such that b^(2^i) = 1
364-
i = 1;
365-
if (!BN_mod_sqr(t, b, p, ctx)) {
366-
goto end;
367-
}
368-
while (!BN_is_one(t)) {
369-
i++;
370-
if (i == e) {
371-
OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
372-
goto end;
363+
// Find the smallest i, 0 < i < e, such that b^(2^i) = 1.
364+
for (i = 1; i < e; i++) {
365+
if (i == 1) {
366+
if (!BN_mod_sqr(t, b, p, ctx)) {
367+
goto end;
368+
}
369+
} else {
370+
if (!BN_mod_mul(t, t, t, p, ctx)) {
371+
goto end;
372+
}
373373
}
374-
if (!BN_mod_mul(t, t, t, p, ctx)) {
375-
goto end;
374+
if (BN_is_one(t)) {
375+
break;
376376
}
377377
}
378-
378+
// If not found, a is not a square or p is not prime.
379+
if (i >= e) {
380+
OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
381+
goto end;
382+
}
379383

380384
// t := y^2^(e - i - 1)
381385
if (!BN_copy(t, y)) {

0 commit comments

Comments
 (0)