From 75ace520112070cdf5fd5ccc1356697eb1866ef0 Mon Sep 17 00:00:00 2001 From: Jacob Wang Date: Mon, 21 Mar 2022 19:34:42 +0800 Subject: [PATCH] Backport fixes for CVE-2022-0778 Signed-off-by: Jacob Wang --- ...ossible-infinite-loop-in-BN_mod_sqrt.patch | 79 ++++++++++++++++ 0002-Add-documentation-of-BN_mod_sqrt.patch | 61 ++++++++++++ ...-a-negative-testcase-for-BN_mod_sqrt.patch | 58 ++++++++++++ 0004-Fix-incorrect-use-of-BN_CTX-API.patch | 94 +++++++++++++++++++ openssl.spec | 16 +++- 5 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 0001-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch create mode 100644 0002-Add-documentation-of-BN_mod_sqrt.patch create mode 100644 0003-Add-a-negative-testcase-for-BN_mod_sqrt.patch create mode 100644 0004-Fix-incorrect-use-of-BN_CTX-API.patch diff --git a/0001-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch b/0001-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch new file mode 100644 index 0000000..512608c --- /dev/null +++ b/0001-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch @@ -0,0 +1,79 @@ +From 2893bbe2adc04fa509e673878819214e79ee279e Mon Sep 17 00:00:00 2001 +From: Jin Jiu +Date: Wed, 16 Mar 2022 10:06:06 +0800 +Subject: [PATCH 1/4] Fix possible infinite loop in BN_mod_sqrt() + +The calculation in some cases does not finish for non-prime p. + +This fixes CVE-2022-0778. + +Based on patch by David Benjamin . + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +--- + crypto/bn/bn_sqrt.c | 34 ++++++++++++++++++++-------------- + 1 file changed, 20 insertions(+), 14 deletions(-) + +diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c +index 1723d5d..65a7ba5 100644 +--- a/crypto/bn/bn_sqrt.c ++++ b/crypto/bn/bn_sqrt.c +@@ -1,7 +1,7 @@ + /* +- * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. ++ * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * +- * Licensed under the OpenSSL license (the "License"). You may not use ++ * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html +@@ -14,7 +14,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + /* + * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks + * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number +- * Theory", algorithm 1.5.1). 'p' must be prime! ++ * Theory", algorithm 1.5.1). 'p' must be prime, otherwise an error or ++ * an incorrect "result" will be returned. + */ + { + BIGNUM *ret = in; +@@ -301,18 +302,23 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + goto vrfy; + } + +- /* find smallest i such that b^(2^i) = 1 */ +- i = 1; +- if (!BN_mod_sqr(t, b, p, ctx)) +- goto end; +- while (!BN_is_one(t)) { +- i++; +- if (i == e) { +- BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); +- goto end; ++ /* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */ ++ for (i = 1; i < e; i++) { ++ if (i == 1) { ++ if (!BN_mod_sqr(t, b, p, ctx)) ++ goto end; ++ ++ } else { ++ if (!BN_mod_mul(t, t, t, p, ctx)) ++ goto end; + } +- if (!BN_mod_mul(t, t, t, p, ctx)) +- goto end; ++ if (BN_is_one(t)) ++ break; ++ } ++ /* If not found, a is not a square or p is not prime. */ ++ if (i >= e) { ++ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); ++ goto end; + } + + /* t := y^2^(e - i - 1) */ +-- +1.8.3.1 + diff --git a/0002-Add-documentation-of-BN_mod_sqrt.patch b/0002-Add-documentation-of-BN_mod_sqrt.patch new file mode 100644 index 0000000..29b054b --- /dev/null +++ b/0002-Add-documentation-of-BN_mod_sqrt.patch @@ -0,0 +1,61 @@ +From f41ac37e755e8e8cc955ae8d7a1174c1d94cd2d0 Mon Sep 17 00:00:00 2001 +From: Jin Jiu +Date: Wed, 16 Mar 2022 10:11:54 +0800 +Subject: [PATCH 2/4] Add documentation of BN_mod_sqrt() + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +--- + doc/man3/BN_add.pod | 15 +++++++++++++-- + 1 file changed, 13 insertions(+), 2 deletions(-) + +diff --git a/doc/man3/BN_add.pod b/doc/man3/BN_add.pod +index 0f0e495..c186b06 100644 +--- a/doc/man3/BN_add.pod ++++ b/doc/man3/BN_add.pod +@@ -3,7 +3,7 @@ + =head1 NAME + + BN_add, BN_sub, BN_mul, BN_sqr, BN_div, BN_mod, BN_nnmod, BN_mod_add, +-BN_mod_sub, BN_mod_mul, BN_mod_sqr, BN_exp, BN_mod_exp, BN_gcd - ++BN_mod_sub, BN_mod_mul, BN_mod_sqr, BN_mod_sqrt, BN_exp, BN_mod_exp, BN_gcd - + arithmetic operations on BIGNUMs + + =head1 SYNOPSIS +@@ -36,6 +36,8 @@ arithmetic operations on BIGNUMs + + int BN_mod_sqr(BIGNUM *r, BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); + ++ BIGNUM *BN_mod_sqrt(BIGNUM *in, BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); ++ + int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BN_CTX *ctx); + + int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, +@@ -87,6 +89,12 @@ L. + BN_mod_sqr() takes the square of I modulo B and places the + result in I. + ++BN_mod_sqrt() returns the modular square root of I such that ++C. The modulus I

must be a ++prime, otherwise an error or an incorrect "result" will be returned. ++The result is stored into I which can be NULL. The result will be ++newly allocated in that case. ++ + BN_exp() raises I to the I

-th power and places the result in I + (C). This function is faster than repeated applications of + BN_mul(). +@@ -108,7 +116,10 @@ the arguments. + + =head1 RETURN VALUES + +-For all functions, 1 is returned for success, 0 on error. The return ++The BN_mod_sqrt() returns the result (possibly incorrect if I

is ++not a prime), or NULL. ++ ++For all remaining functions, 1 is returned for success, 0 on error. The return + value should always be checked (e.g., C). + The error codes can be obtained by L. + +-- +1.8.3.1 + diff --git a/0003-Add-a-negative-testcase-for-BN_mod_sqrt.patch b/0003-Add-a-negative-testcase-for-BN_mod_sqrt.patch new file mode 100644 index 0000000..6675a86 --- /dev/null +++ b/0003-Add-a-negative-testcase-for-BN_mod_sqrt.patch @@ -0,0 +1,58 @@ +From 2bb8c64d1dad921768f05f17c043fab80f537b53 Mon Sep 17 00:00:00 2001 +From: Jin Jiu +Date: Wed, 16 Mar 2022 10:15:24 +0800 +Subject: [PATCH 3/4] Add a negative testcase for BN_mod_sqrt + +Reviewed-by: Paul Dale +Reviewed-by: Matt Caswell +--- + test/bntest.c | 11 ++++++++++- + test/recipes/10-test_bn_data/bnmod.txt | 12 ++++++++++++ + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/test/bntest.c b/test/bntest.c +index c7481e1..174ade6 100644 +--- a/test/bntest.c ++++ b/test/bntest.c +@@ -1659,8 +1659,17 @@ static int file_modsqrt(STANZA *s) + || !TEST_ptr(ret2 = BN_new())) + goto err; + ++ if (BN_is_negative(mod_sqrt)) { ++ /* A negative testcase */ ++ if (!TEST_ptr_null(BN_mod_sqrt(ret, a, p, ctx))) ++ goto err; ++ ++ st = 1; ++ goto err; ++ } ++ + /* There are two possible answers. */ +- if (!TEST_true(BN_mod_sqrt(ret, a, p, ctx)) ++ if (!TEST_ptr(BN_mod_sqrt(ret, a, p, ctx)) + || !TEST_true(BN_sub(ret2, p, ret))) + goto err; + +diff --git a/test/recipes/10-test_bn_data/bnmod.txt b/test/recipes/10-test_bn_data/bnmod.txt +index 5ea4d03..e28cc6b 100644 +--- a/test/recipes/10-test_bn_data/bnmod.txt ++++ b/test/recipes/10-test_bn_data/bnmod.txt +@@ -2799,3 +2799,15 @@ P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f + ModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186 + A = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81 + P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f ++ ++# Negative testcases for BN_mod_sqrt() ++ ++# This one triggers an infinite loop with unfixed implementation ++# It should just fail. ++ModSqrt = -1 ++A = 20a7ee ++P = 460201 ++ ++ModSqrt = -1 ++A = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ed ++P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f +-- +1.8.3.1 + diff --git a/0004-Fix-incorrect-use-of-BN_CTX-API.patch b/0004-Fix-incorrect-use-of-BN_CTX-API.patch new file mode 100644 index 0000000..eb6b1a3 --- /dev/null +++ b/0004-Fix-incorrect-use-of-BN_CTX-API.patch @@ -0,0 +1,94 @@ +From 70413f268619416c5b0a4bb6fb511b0752143354 Mon Sep 17 00:00:00 2001 +From: Jin Jiu +Date: Wed, 16 Mar 2022 10:50:21 +0800 +Subject: [PATCH 4/4] Fix incorrect use of BN_CTX API + +In some edge cases BN_CTX_end was being called without first calling +BN_CTX_start. This creates a situation where the state of the big +number allocator is corrupted and may lead to crashes. + +Reviewed-by: Matt Caswell +Reviewed-by: Tomas Mraz +(Merged from https://github.com/openssl/openssl/pull/13813) +--- + crypto/bn/bn_sqrt.c | 5 ++++- + crypto/bn/bn_x931p.c | 2 +- + crypto/ec/ec_mult.c | 5 ++++- + 3 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c +index 65a7ba5..cc6c2ae 100644 +--- a/crypto/bn/bn_sqrt.c ++++ b/crypto/bn/bn_sqrt.c +@@ -23,6 +23,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + int r; + BIGNUM *A, *b, *q, *t, *x, *y; + int e, i, j; ++ int used_ctx = 0; + + if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { + if (BN_abs_is_word(p, 2)) { +@@ -58,6 +59,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + } + + BN_CTX_start(ctx); ++ used_ctx = 1; + A = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); +@@ -359,7 +361,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) + BN_clear_free(ret); + ret = NULL; + } +- BN_CTX_end(ctx); ++ if (used_ctx) ++ BN_CTX_end(ctx); + bn_check_top(ret); + return ret; + } +diff --git a/crypto/bn/bn_x931p.c b/crypto/bn/bn_x931p.c +index 0099502..a39b775 100644 +--- a/crypto/bn/bn_x931p.c ++++ b/crypto/bn/bn_x931p.c +@@ -174,7 +174,7 @@ int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) + * exceeded. + */ + if (!BN_priv_rand(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY)) +- goto err; ++ return 0; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); +diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c +index 9a1e397..9b76648 100644 +--- a/crypto/ec/ec_mult.c ++++ b/crypto/ec/ec_mult.c +@@ -828,6 +828,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) + EC_POINT **points = NULL; + EC_PRE_COMP *pre_comp; + int ret = 0; ++ int used_ctx = 0; + + /* if there is an old EC_PRE_COMP object, throw it away */ + EC_pre_comp_free(group); +@@ -847,6 +848,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) + } + + BN_CTX_start(ctx); ++ used_ctx = 1; + + order = EC_GROUP_get0_order(group); + if (order == NULL) +@@ -955,7 +957,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) + ret = 1; + + err: +- BN_CTX_end(ctx); ++ if (used_ctx) ++ BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + EC_ec_pre_comp_free(pre_comp); + if (points) { +-- +1.8.3.1 + diff --git a/openssl.spec b/openssl.spec index 7c0b1a3..d4e5a11 100644 --- a/openssl.spec +++ b/openssl.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.1 +%define anolis_release .0.2 # For the curious: # 0.9.5a soversion = 0 # 0.9.6 soversion = 1 @@ -84,6 +84,12 @@ Patch74: openssl-1.1.1-addrconfig.patch Patch75: openssl-1.1.1-tls13-curves.patch Patch81: openssl-1.1.1-read-buff.patch +# Anolis OS - Backport fixes for CVE-2022-0778 +Patch1000: 0001-Fix-possible-infinite-loop-in-BN_mod_sqrt.patch +Patch1001: 0002-Add-documentation-of-BN_mod_sqrt.patch +Patch1002: 0003-Add-a-negative-testcase-for-BN_mod_sqrt.patch +Patch1003: 0004-Fix-incorrect-use-of-BN_CTX-API.patch + License: OpenSSL and ASL 2.0 URL: http://www.openssl.org/ BuildRequires: gcc @@ -204,6 +210,11 @@ cp %{SOURCE13} test/ %patch80 -p1 -b .s390x-test-aes %patch81 -p1 -b .read-buff +# Anolis OS patches +%patch1000 -p1 +%patch1001 -p1 +%patch1002 -p1 +%patch1003 -p1 %build # Figure out which flags we want to use. @@ -492,6 +503,9 @@ export LD_LIBRARY_PATH %postun libs -p /sbin/ldconfig %changelog +* Mon Mar 21 2022 Jacob Wang - 1:1.1.1k-5.0.2 +- Backport fixes for CVE-2022-0778 + * Tue Jan 25 2022 Liwei Ge - 1:1.1.1k-5.0.1 - Support loongarch64 -- Gitee