From dc9c45ed87e0c170450a127d2205b36bf05b0d59 Mon Sep 17 00:00:00 2001 From: Mark Atwood Date: Mon, 16 Mar 2026 11:18:32 -0700 Subject: [PATCH] ecc: reject compressed EC points with incorrect length wc_ecc_import_point_der_ex accepts a single byte 0x02 or 0x03 as a valid compressed EC point. It treats the missing X coordinate as zero, decompresses it (producing a valid on-curve point), and wc_ecc_check_key passes. This allows ECDH key agreement with a crafted 1-byte peer public key. Add length validation for compressed points: after identifying 0x02/0x03 format byte, verify that inLen == ecc_sets[curve_idx].size + 1 using unsigned comparison to avoid underflow. Only set compressed = 1 after the length check passes, keeping state consistent on the error path. Reproducer: call EC_POINT_oct2point with a 1-byte buffer containing 0x02 for any NIST curve. Before this fix it succeeds; after, it returns ECC_BAD_ARG_E. Co-Authored-By: Claude Opus 4.6 (1M context) --- wolfcrypt/src/ecc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 1376cff2a03..3e54fc861cf 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -9469,7 +9469,14 @@ int wc_ecc_import_point_der_ex(const byte* in, word32 inLen, if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) { #ifdef HAVE_COMP_KEY - compressed = 1; + /* Compressed point must be exactly 1 + field_element_size bytes. + * Reject truncated inputs (e.g. a bare 0x02/0x03 byte). */ + if (inLen == (word32)ecc_sets[curve_idx].size + 1) { + compressed = 1; + } + else { + err = ECC_BAD_ARG_E; + } #else err = NOT_COMPILED_IN; #endif