test(mbedtls): Add out-of-bounds test for the ECDSA hardware driver

This commit is contained in:
harshal.patil
2026-06-12 16:54:33 +05:30
parent 792922eb69
commit 8a934fa932
2 changed files with 64 additions and 10 deletions
@@ -15,6 +15,8 @@
#include <mbedtls/ecdh.h>
#include <mbedtls/ecdsa.h>
#include <mbedtls/error.h>
#include <mbedtls/ecp.h>
#include <mbedtls/bignum.h>
#include "hal/efuse_ll.h"
#include "esp_efuse.h"
@@ -214,8 +216,18 @@ const uint8_t ecdsa384_pub_y_km[] = {
};
#endif /* SOC_KEY_MANAGER_SUPPORTED */
/* Curve order N in big-endian, taken from mbedtls instead of a hard-coded table. */
static void ecdsa_get_curve_order_be(mbedtls_ecp_group_id id, uint8_t *n_be, size_t len)
{
mbedtls_ecp_group grp;
mbedtls_ecp_group_init(&grp);
TEST_ASSERT_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
TEST_ASSERT_EQUAL(0, mbedtls_mpi_write_binary(&grp.N, n_be, len));
mbedtls_ecp_group_free(&grp);
}
void test_ecdsa_verify(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8_t *r_comp, const uint8_t *s_comp,
const uint8_t *pub_x, const uint8_t *pub_y)
const uint8_t *pub_x, const uint8_t *pub_y, int expected_ret)
{
size_t hash_len = HASH_LEN;
int64_t elapsed_time;
@@ -247,7 +259,8 @@ void test_ecdsa_verify(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8
#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */
ccomp_timer_start();
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), hash, hash_len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s));
int actual_ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), hash, hash_len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s);
TEST_ASSERT_EQUAL(expected_ret, actual_ret);
elapsed_time = ccomp_timer_stop();
if (id == MBEDTLS_ECP_DP_SECP192R1) {
@@ -274,7 +287,7 @@ TEST_CASE("mbedtls ECDSA signature verification performance on SECP192R1", "[mbe
}
#endif
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP192R1, sha, ecdsa192_r, ecdsa192_s,
ecdsa192_pub_x, ecdsa192_pub_y);
ecdsa192_pub_x, ecdsa192_pub_y, 0);
}
TEST_CASE("mbedtls ECDSA signature verification performance on SECP256R1", "[mbedtls]")
@@ -285,7 +298,7 @@ TEST_CASE("mbedtls ECDSA signature verification performance on SECP256R1", "[mbe
}
#endif
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, ecdsa256_r, ecdsa256_s,
ecdsa256_pub_x, ecdsa256_pub_y);
ecdsa256_pub_x, ecdsa256_pub_y, 0);
}
#ifdef SOC_ECDSA_SUPPORT_CURVE_P384
@@ -297,10 +310,51 @@ TEST_CASE("mbedtls ECDSA signature verification performance on SECP384R1", "[mbe
}
#endif
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, ecdsa384_r, ecdsa384_s,
ecdsa384_pub_x, ecdsa384_pub_y);
ecdsa384_pub_x, ecdsa384_pub_y, 0);
}
#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */
TEST_CASE("mbedtls ECDSA signature verification rejects out-of-range r, s on SECP256R1", "[mbedtls]")
{
#if SOC_ECDSA_SUPPORTED
if (!ecdsa_ll_is_supported()) {
TEST_IGNORE_MESSAGE("ECDSA is not supported");
}
#endif
static const uint8_t zero32[32] = { 0 };
uint8_t p256_n_be[32];
ecdsa_get_curve_order_be(MBEDTLS_ECP_DP_SECP256R1, p256_n_be, sizeof(p256_n_be));
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, zero32, zero32, ecdsa256_pub_x, ecdsa256_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=0, s=0 */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, zero32, p256_n_be, ecdsa256_pub_x, ecdsa256_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=0, s=N */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, p256_n_be, zero32, ecdsa256_pub_x, ecdsa256_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=N, s=0 */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, p256_n_be, p256_n_be, ecdsa256_pub_x, ecdsa256_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=N, s=N */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, ecdsa256_r, zero32, ecdsa256_pub_x, ecdsa256_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=valid, s=0 */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, ecdsa256_r, p256_n_be, ecdsa256_pub_x, ecdsa256_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=valid, s=N */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP256R1, sha, p256_n_be, ecdsa256_s, ecdsa256_pub_x, ecdsa256_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=N, s=valid */
}
#ifdef SOC_ECDSA_SUPPORT_CURVE_P384
TEST_CASE("mbedtls ECDSA signature verification rejects out-of-range r, s on SECP384R1", "[mbedtls]")
{
#if SOC_ECDSA_SUPPORTED
if (!ecdsa_ll_is_supported()) {
TEST_IGNORE_MESSAGE("ECDSA is not supported");
}
#endif
static const uint8_t zero48[48] = { 0 };
uint8_t p384_n_be[48];
ecdsa_get_curve_order_be(MBEDTLS_ECP_DP_SECP384R1, p384_n_be, sizeof(p384_n_be));
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, zero48, zero48, ecdsa384_pub_x, ecdsa384_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=0, s=0 */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, zero48, p384_n_be, ecdsa384_pub_x, ecdsa384_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=0, s=N */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, p384_n_be, zero48, ecdsa384_pub_x, ecdsa384_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=N, s=0 */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, p384_n_be, p384_n_be, ecdsa384_pub_x, ecdsa384_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=N, s=N */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, ecdsa384_r, zero48, ecdsa384_pub_x, ecdsa384_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=valid, s=0 */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, ecdsa384_r, p384_n_be, ecdsa384_pub_x, ecdsa384_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=valid, s=N */
test_ecdsa_verify(MBEDTLS_ECP_DP_SECP384R1, sha, p384_n_be, ecdsa384_s, ecdsa384_pub_x, ecdsa384_pub_y, MBEDTLS_ERR_ECP_VERIFY_FAILED); /* r=N, s=valid */
}
#endif /* SOC_ECDSA_SUPPORT_CURVE_P384 */
#endif /* CONFIG_MBEDTLS_HARDWARE_ECC */
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
@@ -413,13 +467,13 @@ void test_ecdsa_sign(mbedtls_ecp_group_id id, const uint8_t *hash, const uint8_t
if (id == MBEDTLS_ECP_DP_SECP192R1) {
// Skip the initial zeroes
test_ecdsa_verify(id, sha, &r_be[MAX_HASH_LEN - ECDSA_P192_HASH_COMPONENT_LEN], &s_be[MAX_HASH_LEN - ECDSA_P192_HASH_COMPONENT_LEN], pub_x, pub_y);
test_ecdsa_verify(id, sha, &r_be[MAX_HASH_LEN - ECDSA_P192_HASH_COMPONENT_LEN], &s_be[MAX_HASH_LEN - ECDSA_P192_HASH_COMPONENT_LEN], pub_x, pub_y, 0);
} else if (id == MBEDTLS_ECP_DP_SECP256R1) {
test_ecdsa_verify(id, sha, &r_be[MAX_HASH_LEN - ECDSA_P256_HASH_COMPONENT_LEN], &s_be[MAX_HASH_LEN - ECDSA_P256_HASH_COMPONENT_LEN], pub_x, pub_y);
test_ecdsa_verify(id, sha, &r_be[MAX_HASH_LEN - ECDSA_P256_HASH_COMPONENT_LEN], &s_be[MAX_HASH_LEN - ECDSA_P256_HASH_COMPONENT_LEN], pub_x, pub_y, 0);
}
#if SOC_ECDSA_SUPPORT_CURVE_P384
else if (id == MBEDTLS_ECP_DP_SECP384R1) {
test_ecdsa_verify(id, sha, r_be, s_be, pub_x, pub_y);
test_ecdsa_verify(id, sha, r_be, s_be, pub_x, pub_y, 0);
}
#endif