diff --git a/tests/api/test_ecc.c b/tests/api/test_ecc.c index 90d5ced882..848d4fb23a 100644 --- a/tests/api/test_ecc.c +++ b/tests/api/test_ecc.c @@ -760,6 +760,16 @@ int test_wc_ecc_import_x963(void) WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_ecc_import_x963(x963, x963Len + 1, &pubKey), WC_NO_ERR_TRACE(ECC_BAD_ARG_E)); +#ifdef HAVE_COMP_KEY + /* A bare compressed format byte (0x02) with no x coordinate must be + * rejected. inLen == 1 is odd, so the early even-length check does not + * catch this -- the compressed-point length validation must. */ + { + byte trunc[1] = { 0x02 }; + ExpectIntEQ(wc_ecc_import_x963(trunc, 1, &pubKey), + WC_NO_ERR_TRACE(ECC_BAD_ARG_E)); + } +#endif DoExpectIntEQ(wc_FreeRng(&rng), 0); wc_ecc_free(&key); @@ -1481,6 +1491,17 @@ int test_wc_ecc_pointFns(void) WC_NO_ERR_TRACE(ECC_BAD_ARG_E)); ExpectIntEQ(wc_ecc_import_point_der(der, derSz + 1, idx, point), WC_NO_ERR_TRACE(ECC_BAD_ARG_E)); +#ifdef HAVE_COMP_KEY + /* A bare format byte (0x02) with no x coordinate must be rejected. + * The failing import zeroes point's coordinates, so re-import the + * valid DER afterward to restore state for subsequent tests. */ + { + byte trunc[1] = { 0x02 }; + ExpectIntEQ(wc_ecc_import_point_der(trunc, 1, idx, point), + WC_NO_ERR_TRACE(ECC_BAD_ARG_E)); + } + ExpectIntEQ(wc_ecc_import_point_der(der, derSz, idx, point), 0); +#endif /* Copy */ ExpectIntEQ(wc_ecc_copy_point(point, cpypt), 0); diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 11276ce6e9..3e0a371e38 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -9628,7 +9628,18 @@ 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. + * When shortKeySize is set, callers may pass the uncompressed + * length (2*size + 1) even for compressed data. + * Reject truncated inputs (e.g. a bare 0x02/0x03 byte). */ + if (inLen == (word32)ecc_sets[curve_idx].size + 1) { + compressed = 1; + } else if (shortKeySize && + inLen == (word32)ecc_sets[curve_idx].size * 2 + 1) { + compressed = 1; + } else { + err = ECC_BAD_ARG_E; + } #else err = NOT_COMPILED_IN; #endif @@ -10902,7 +10913,20 @@ static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key, if (pointType == ECC_POINT_COMP_EVEN || pointType == ECC_POINT_COMP_ODD) { #ifdef HAVE_COMP_KEY - compressed = 1; + /* Compressed point must be at least 2 bytes (format + x coordinate). + * When curve_id is known, verify exact expected length. */ + if (inLen < 2) { + err = ECC_BAD_ARG_E; + } else if (curve_id > ECC_CURVE_DEF) { + int expSz = wc_ecc_get_curve_size_from_id(curve_id); + if (expSz <= 0 || inLen != (word32)expSz + 1) { + err = ECC_BAD_ARG_E; + } else { + compressed = 1; + } + } else { + compressed = 1; + } #else err = NOT_COMPILED_IN; #endif