mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-06-13 17:39:57 +00:00
botan: patch CVE-2026-32877
Details: https://nvd.nist.gov/vuln/detail/CVE-2026-32877 Backport the patch that was identified by Debian[1]. The included test passed successfully (along with the other tests). [1]: https://security-tracker.debian.org/tracker/CVE-2026-32877 Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
committed by
Anuj Mittal
parent
ab0866131d
commit
c4b5bca1e8
@@ -0,0 +1,158 @@
|
||||
From a0048a6b97a349a3cb4a5f955d350ab2921719cc Mon Sep 17 00:00:00 2001
|
||||
From: Jack Lloyd <jack@randombit.net>
|
||||
Date: Sun, 15 Mar 2026 11:39:50 -0400
|
||||
Subject: [PATCH] In SM2 verify the C3 field is of the required length
|
||||
|
||||
Previously the decryption step assumed that C3 was equal in length to the MAC
|
||||
output. If C3 is shorter than expected, up to 31 bytes of arbitrary heap data
|
||||
would be compared with the computed MAC. This heap over-read would potentially
|
||||
result in denial of service.
|
||||
|
||||
CVE: CVE-2026-32877
|
||||
Upstream-Status: Backport [https://github.com/randombit/botan/commit/f3c31f96f58f1d1d482032d8f4286dc9ebbc6712]
|
||||
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
|
||||
---
|
||||
src/lib/pubkey/sm2/sm2_enc.cpp | 7 +++-
|
||||
src/tests/data/pubkey/sm2_invalid.vec | 60 +++++++++++++++++++++++++++
|
||||
src/tests/test_sm2.cpp | 31 ++++++++++++++
|
||||
3 files changed, 97 insertions(+), 1 deletion(-)
|
||||
create mode 100644 src/tests/data/pubkey/sm2_invalid.vec
|
||||
|
||||
diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp
|
||||
index 7a1b990..1141089 100644
|
||||
--- a/src/lib/pubkey/sm2/sm2_enc.cpp
|
||||
+++ b/src/lib/pubkey/sm2/sm2_enc.cpp
|
||||
@@ -133,6 +133,11 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption {
|
||||
.end_cons()
|
||||
.verify_end();
|
||||
|
||||
+ // Wrong length so certainly invalid, reject immediately
|
||||
+ if(C3.size() != m_hash->output_length()) {
|
||||
+ return secure_vector<uint8_t>();
|
||||
+ }
|
||||
+
|
||||
std::vector<uint8_t> recode_ctext;
|
||||
DER_Encoder(recode_ctext)
|
||||
.start_sequence()
|
||||
@@ -170,7 +175,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption {
|
||||
m_hash->update(y2_bytes);
|
||||
const auto u = m_hash->final();
|
||||
|
||||
- if(!CT::is_equal(u.data(), C3.data(), m_hash->output_length()).as_bool()) {
|
||||
+ if(!CT::is_equal<uint8_t>(u, C3).as_bool()) {
|
||||
return secure_vector<uint8_t>();
|
||||
}
|
||||
|
||||
diff --git a/src/tests/data/pubkey/sm2_invalid.vec b/src/tests/data/pubkey/sm2_invalid.vec
|
||||
new file mode 100644
|
||||
index 0000000..2517510
|
||||
--- /dev/null
|
||||
+++ b/src/tests/data/pubkey/sm2_invalid.vec
|
||||
@@ -0,0 +1,60 @@
|
||||
+
|
||||
+Key = 8C84F7F069CD09D59543ED980CFEB77E68C7D39B9B73D359EA67C0CDB2A86B6F
|
||||
+
|
||||
+
|
||||
+# Empty
|
||||
+Ctext =
|
||||
+
|
||||
+# Just the SEQUENCE marker
|
||||
+Ctext = 30
|
||||
+
|
||||
+# Truncated
|
||||
+Ctext = 3072022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E51
|
||||
+
|
||||
+# C3 MAC too short
|
||||
+Ctext = 3071022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF041F2E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F36826493860409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C3 MAC too long
|
||||
+Ctext = 3073022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04212E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F368264938696000409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C3 and C2 fields swapped
|
||||
+Ctext = 3072022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF0409CA311F43DB0E5E516F04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F368264938696
|
||||
+
|
||||
+# C3 MAC last bit flipped
|
||||
+Ctext = 3072022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386970409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C3 MAC first byte inverted
|
||||
+Ctext = 3072022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF0420D11B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C1 y off by one
|
||||
+Ctext = 3072022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27D004202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C1 x/y serialization boundary shift
|
||||
+Ctext = 3073022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E500200022100C055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E2704202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C1 is generator point
|
||||
+Ctext = 3072022032C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7022100BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A004202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C1 is origin (0,0)
|
||||
+Ctext = 303302010002010004202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C1 x equals field prime
|
||||
+Ctext = 3072022100FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# C2 last bit flipped
|
||||
+Ctext = 3072022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516E
|
||||
+
|
||||
+# C2 replaced with empty
|
||||
+Ctext = 3069022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960400
|
||||
+
|
||||
+# Trailing byte after SEQUENCE
|
||||
+Ctext = 3072022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F00
|
||||
+
|
||||
+# SEQUENCE with non-minimal long-form length
|
||||
+Ctext = 308172022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# INTEGER x1 with non-minimal leading zero
|
||||
+Ctext = 307302220000A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF04202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
+
|
||||
+# OCTET STRING C3 with non-minimal long-form length
|
||||
+Ctext = 3073022100A772DF5FFFDA85C05D9B82233B1E5F7DF7A87788504ABD4F74D265D49E5002C0022055C8A934A29DE58B31A063CDA81F12ABC712FB9ADC8988DA0FBD9FFF304E27CF0481202E1B8A86EF14243EE2E9D74E0D0E7498DFAC2F0EFA8C5883D74F3682649386960409CA311F43DB0E5E516F
|
||||
diff --git a/src/tests/test_sm2.cpp b/src/tests/test_sm2.cpp
|
||||
index 2ffb14a..c5d2360 100644
|
||||
--- a/src/tests/test_sm2.cpp
|
||||
+++ b/src/tests/test_sm2.cpp
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#if defined(BOTAN_HAS_SM2)
|
||||
#include "test_pubkey.h"
|
||||
+ #include <botan/pubkey.h>
|
||||
#include <botan/sm2.h>
|
||||
#endif
|
||||
|
||||
@@ -108,4 +109,34 @@ BOTAN_REGISTER_TEST("pubkey", "sm2_keygen", SM2_Keygen_Tests);
|
||||
|
||||
#endif
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+class SM2_Invalid_Ciphertexts : public Text_Based_Test {
|
||||
+ public:
|
||||
+ SM2_Invalid_Ciphertexts() : Text_Based_Test("pubkey/sm2_invalid.vec", "Key,Ctext") {}
|
||||
+
|
||||
+ bool clear_between_callbacks() const override { return false; }
|
||||
+
|
||||
+ Test::Result run_one_test(const std::string& /*header*/, const VarMap& vars) override {
|
||||
+ Test::Result result("SM2 invalid ciphertext");
|
||||
+
|
||||
+ const auto key = vars.get_req_bin("Key");
|
||||
+ const auto ctext = vars.get_req_bin("Ctext");
|
||||
+
|
||||
+ const auto group = Botan::EC_Group::from_name("sm2p256v1");
|
||||
+ const auto pkey = Botan::SM2_PrivateKey(group, Botan::EC_Scalar::deserialize(group, key).value());
|
||||
+
|
||||
+ Botan::PK_Decryptor_EME dec(pkey, rng(), "SM3");
|
||||
+
|
||||
+ result.test_throws<Botan::Exception>("Decryption should fail for invalid ciphertext",
|
||||
+ [&] { dec.decrypt(ctext); });
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+BOTAN_REGISTER_TEST("pubkey", "sm2_invalid_ctext", SM2_Invalid_Ciphertexts);
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
} // namespace Botan_Tests
|
||||
@@ -4,7 +4,9 @@ LICENSE = "BSD-2-Clause"
|
||||
LIC_FILES_CHKSUM = "file://license.txt;md5=3f911cecfc74a2d9f1ead9a07bd92a6e"
|
||||
SECTION = "libs"
|
||||
|
||||
SRC_URI = "https://botan.randombit.net/releases/Botan-${PV}.tar.xz"
|
||||
SRC_URI = "https://botan.randombit.net/releases/Botan-${PV}.tar.xz \
|
||||
file://CVE-2026-32877.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "fde194236f6d5434f136ea0a0627f6cc9d26af8b96e9f1e1c7d8c82cd90f4f24"
|
||||
|
||||
S = "${UNPACKDIR}/Botan-${PV}"
|
||||
|
||||
Reference in New Issue
Block a user