From deec39b63f6f6f9405a15f5920ac714f86b82cf9 Mon Sep 17 00:00:00 2001 From: metsw24-max Date: Fri, 22 May 2026 15:47:08 +0530 Subject: [PATCH] ecdh (Botan): bounds-check public point length before reading load_public_key() previously verified only that key.p was non-empty and began with the 0x04 uncompressed-point prefix before computing &key.p[1] and &key.p[1 + curve_order] for the two coordinates. For any non-25519 curve, an input whose key.p is shorter than 2 * curve_order + 1 bytes causes botan_mp_from_bin() to read past the end of the std::vector storage backing key.p (heap-buffer-overflow read). The matching sibling routines pgp::ecdsa::load_public_key and pgp::sm2::load_public_key already reject this exact case with keydata.p.size() != 2 * curve_order + 1; mirror that check here so the Botan ECDH backend cannot dereference past the supplied buffer when validating an attacker-controlled public key during packet parsing. --- src/lib/crypto/ecdh.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lib/crypto/ecdh.cpp b/src/lib/crypto/ecdh.cpp index 64988e73b..54755c604 100644 --- a/src/lib/crypto/ecdh.cpp +++ b/src/lib/crypto/ecdh.cpp @@ -99,8 +99,12 @@ load_public_key(rnp::botan::Pubkey &pubkey, const ec::Key &key) } const size_t curve_order = curve->bytes(); - rnp::bn px(&key.p[1], curve_order); - rnp::bn py(&key.p[1 + curve_order], curve_order); + if (key.p.size() != 2 * curve_order + 1) { + RNP_LOG("Invalid ECDH public key length"); + return false; + } + rnp::bn px(&key.p[1], curve_order); + rnp::bn py(&key.p[1 + curve_order], curve_order); if (!px || !py) { return false;