From 5569cd218167b0ebb7efeea496cecbf1efcc6214 Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Fri, 28 Nov 2025 11:56:25 +0530 Subject: [PATCH] feat(mbedtls): add ECC P-384 mbedtls support and test_cases --- components/mbedtls/port/ecc/ecc_alt.c | 17 ++- components/mbedtls/port/include/ecc_impl.h | 15 ++- components/mbedtls/test_apps/main/test_ecp.c | 107 ++++++++++++++++++- 3 files changed, 127 insertions(+), 12 deletions(-) diff --git a/components/mbedtls/port/ecc/ecc_alt.c b/components/mbedtls/port/ecc/ecc_alt.c index 4ffa065c24..7b70da59cf 100644 --- a/components/mbedtls/port/ecc/ecc_alt.c +++ b/components/mbedtls/port/ecc/ecc_alt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,14 +7,13 @@ #include #include "soc/hwcrypto_periph.h" #include "ecc_impl.h" +#include "hal/ecc_ll.h" #include "mbedtls/ecp.h" #include "mbedtls/platform_util.h" #if defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) -#define MAX_SIZE 32 // 256 bits - static int esp_mbedtls_ecp_point_multiply(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_mpi *m, const mbedtls_ecp_point *P) { @@ -54,7 +53,11 @@ int ecp_mul_restartable_internal( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, mbedtls_ecp_restart_ctx *rs_ctx ) { int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; - if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) { + if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1 +#if SOC_ECC_SUPPORT_CURVE_P384 + && (grp->id != MBEDTLS_ECP_DP_SECP384R1 || !ecc_ll_is_p384_curve_operations_supported()) +#endif + ) { #if defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) return ecp_mul_restartable_internal_soft(grp, R, m, P, f_rng, p_rng, rs_ctx); #else @@ -85,7 +88,11 @@ int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; } - if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) { + if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1 +#if SOC_ECC_SUPPORT_CURVE_P384 + && (grp->id != MBEDTLS_ECP_DP_SECP384R1 || !ecc_ll_is_p384_curve_operations_supported()) +#endif + ) { #if defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK) return mbedtls_ecp_check_pubkey_soft(grp, pt); #else diff --git a/components/mbedtls/port/include/ecc_impl.h b/components/mbedtls/port/include/ecc_impl.h index c52c988195..d7900ee49f 100644 --- a/components/mbedtls/port/include/ecc_impl.h +++ b/components/mbedtls/port/include/ecc_impl.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,13 @@ extern "C" { #define P256_LEN (256/8) #define P192_LEN (192/8) +#define P384_LEN (384/8) + +#if SOC_ECC_SUPPORT_CURVE_P384 +#define MAX_SIZE P384_LEN +#else +#define MAX_SIZE P256_LEN +#endif /* Note: x & y are stored in little endian order (same as CPU byte order, and order used internally by most libraries). @@ -22,9 +29,9 @@ extern "C" { Note this is opposite to most byte string formats used to represent keys, which are often big endian */ typedef struct { - uint8_t x[P256_LEN]; /* Little endian order */ - uint8_t y[P256_LEN]; /* Little endian order */ - unsigned len; /* P192_LEN or P256_LEN */ + uint8_t x[MAX_SIZE]; /* Little endian order */ + uint8_t y[MAX_SIZE]; /* Little endian order */ + unsigned len; /* P192_LEN, P256_LEN, or P384_LEN */ } ecc_point_t; /** diff --git a/components/mbedtls/test_apps/main/test_ecp.c b/components/mbedtls/test_apps/main/test_ecp.c index a40525a76d..a03005a43d 100644 --- a/components/mbedtls/test_apps/main/test_ecp.c +++ b/components/mbedtls/test_apps/main/test_ecp.c @@ -3,7 +3,7 @@ * Focus on testing functionality where we use ESP32 hardware * accelerated crypto features. * - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -22,6 +22,9 @@ #include "test_utils.h" #include "ccomp_timer.h" #include "unity.h" +#if CONFIG_MBEDTLS_HARDWARE_ECC +#include "hal/ecc_ll.h" +#endif /* Note: negative value here so that assert message prints a grep-able error hex value (mbedTLS uses -N for error codes) */ @@ -202,6 +205,70 @@ const uint8_t ecc_p256_small_mul_res_y[] = { 0x17, 0xFD, 0xF6, 0x64, 0x41, 0x9E, 0x50, 0x0C }; +#if SOC_ECC_SUPPORT_CURVE_P384 +const uint8_t ecc_p384_point_x[] = { + 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, + 0x8e, 0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, + 0x6e, 0x1d, 0x3b, 0x62, 0x8b, 0xa7, 0x9b, 0x98, + 0x59, 0xf7, 0x41, 0xe0, 0x82, 0x54, 0x2a, 0x38, + 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29, 0x6c, + 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7 +}; + +const uint8_t ecc_p384_point_y[] = { + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, + 0x5d, 0x9e, 0x98, 0xbf, 0x92, 0x92, 0xdc, 0x29, + 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, + 0x0a, 0x60, 0xb1, 0xce, 0x1d, 0x7e, 0x81, 0x9d, + 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f +}; + +const uint8_t ecc_p384_scalar[] = { + 0x68, 0xd1, 0x09, 0xa7, 0xc7, 0x7e, 0xeb, 0xbd, + 0x43, 0x18, 0x7e, 0xdd, 0x69, 0x23, 0x7e, 0x0a, + 0xef, 0x07, 0xc2, 0x0e, 0xc5, 0x3d, 0xe7, 0xcb, + 0xd4, 0x36, 0xad, 0x9b, 0xdc, 0xf8, 0x6c, 0x5c, + 0x0c, 0x3d, 0xce, 0x45, 0xcd, 0x6f, 0x7f, 0x18, + 0x40, 0xc5, 0x29, 0xf3, 0xcd, 0x12, 0x1d, 0xc2 +}; + +const uint8_t ecc_p384_mul_res_x[] = { + 0x74, 0x1d, 0xc3, 0xba, 0xac, 0x60, 0x37, 0xfc, + 0x57, 0x85, 0x90, 0x95, 0x64, 0xe6, 0xd1, 0xef, + 0x86, 0xdf, 0x42, 0xe0, 0xaf, 0x11, 0x24, 0x1f, + 0xe9, 0x97, 0x6e, 0x0c, 0xd9, 0xe5, 0xa0, 0x5d, + 0xd9, 0x91, 0x96, 0x71, 0xef, 0x96, 0xe9, 0x7e, + 0x90, 0xba, 0xa8, 0x33, 0xe2, 0x2e, 0xf0, 0x7b +}; + +const uint8_t ecc_p384_mul_res_y[] = { + 0xc3, 0xe0, 0x66, 0x50, 0xd9, 0x1e, 0xa9, 0x42, + 0xcb, 0x0d, 0xec, 0xb6, 0x29, 0xe2, 0xae, 0x75, + 0xc6, 0xa2, 0xb9, 0xa6, 0xcf, 0x2c, 0x97, 0x01, + 0xcc, 0xff, 0x7c, 0x1c, 0xd1, 0x01, 0xde, 0xbc, + 0x40, 0x56, 0x8c, 0x18, 0x21, 0x9d, 0xbd, 0xc0, + 0x2d, 0x41, 0x5b, 0x92, 0x52, 0x5a, 0x40, 0x57 +}; + +const uint8_t ecc_p384_small_mul_res_x[] = { + 0x35, 0x49, 0x60, 0x41, 0xea, 0x25, 0x3b, 0x0d, + 0x15, 0x3c, 0x9b, 0xfb, 0xc1, 0x8a, 0x9e, 0x41, + 0xaf, 0x34, 0x8a, 0xfd, 0x8b, 0x1c, 0x33, 0xa5, + 0xca, 0x5d, 0x7f, 0xbb, 0xfa, 0x2d, 0x5d, 0x9d, + 0x43, 0x6e, 0xd1, 0x01, 0x1b, 0x3d, 0x9d, 0x93, + 0xe4, 0xb4, 0x5d, 0x2a, 0x4b, 0x23, 0x27, 0xf1 +}; + +const uint8_t ecc_p384_small_mul_res_y[] = { + 0x73, 0xce, 0x1e, 0xaa, 0x4f, 0xfd, 0xdc, 0x1d, + 0x69, 0xd9, 0xe0, 0x9d, 0x16, 0x46, 0x19, 0xae, + 0x8d, 0xd2, 0xce, 0x26, 0x6f, 0x9d, 0xb6, 0xc3, + 0x30, 0xa5, 0x05, 0x7c, 0x7d, 0x62, 0xde, 0x8f, + 0x8e, 0xc3, 0xce, 0x9b, 0xa7, 0xc1, 0x71, 0xb9, + 0xb0, 0x2a, 0xda, 0x1c, 0xb3, 0x42, 0x61, 0x58 +}; +#endif /* SOC_ECC_SUPPORT_CURVE_P384 */ static int rng_wrapper(void *ctx, unsigned char *buf, size_t len) { @@ -213,8 +280,8 @@ static void test_ecp_mul(mbedtls_ecp_group_id id, const uint8_t *x_coord, const const uint8_t *result_x_coord, const uint8_t *result_y_coord) { int64_t elapsed_time; - uint8_t x[32]; - uint8_t y[32]; + uint8_t x[48]; + uint8_t y[48]; int size; int ret; @@ -259,6 +326,12 @@ static void test_ecp_mul(mbedtls_ecp_group_id id, const uint8_t *x_coord, const TEST_PERFORMANCE_CCOMP_LESS_THAN(ECP_P192_POINT_MULTIPLY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); } else if (id == MBEDTLS_ECP_DP_SECP256R1) { TEST_PERFORMANCE_CCOMP_LESS_THAN(ECP_P256_POINT_MULTIPLY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); +#if SOC_ECC_SUPPORT_CURVE_P384 + } else if (id == MBEDTLS_ECP_DP_SECP384R1) { + if (ecc_ll_is_p384_curve_operations_supported()) { + TEST_PERFORMANCE_CCOMP_LESS_THAN(ECP_P384_POINT_MULTIPLY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); + } +#endif } mbedtls_ecp_point_free(&R); @@ -285,6 +358,19 @@ TEST_CASE("mbedtls ECP point multiply with SECP256R1", "[mbedtls]") ecc_p256_small_mul_res_x, ecc_p256_small_mul_res_y); } +#if SOC_ECC_SUPPORT_CURVE_P384 +TEST_CASE("mbedtls ECP point multiply with SECP384R1", "[mbedtls]") +{ + if (ecc_ll_is_p384_curve_operations_supported()) { + test_ecp_mul(MBEDTLS_ECP_DP_SECP384R1, ecc_p384_point_x, ecc_p384_point_y, ecc_p384_scalar, + ecc_p384_mul_res_x, ecc_p384_mul_res_y); + + test_ecp_mul(MBEDTLS_ECP_DP_SECP384R1, ecc_p384_point_x, ecc_p384_point_y, NULL, + ecc_p384_small_mul_res_x, ecc_p384_small_mul_res_y); + } +} +#endif /* SOC_ECC_SUPPORT_CURVE_P384 */ + static void test_ecp_verify(mbedtls_ecp_group_id id, const uint8_t *x_coord, const uint8_t *y_coord) { int64_t elapsed_time; @@ -315,6 +401,12 @@ static void test_ecp_verify(mbedtls_ecp_group_id id, const uint8_t *x_coord, con TEST_PERFORMANCE_CCOMP_LESS_THAN(ECP_P192_POINT_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); } else if (id == MBEDTLS_ECP_DP_SECP256R1) { TEST_PERFORMANCE_CCOMP_LESS_THAN(ECP_P256_POINT_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); +#if SOC_ECC_SUPPORT_CURVE_P384 + } else if (id == MBEDTLS_ECP_DP_SECP384R1) { + if (ecc_ll_is_p384_curve_operations_supported()) { + TEST_PERFORMANCE_CCOMP_LESS_THAN(ECP_P384_POINT_VERIFY_OP, "%" NEWLIB_NANO_COMPAT_FORMAT" us", NEWLIB_NANO_COMPAT_CAST(elapsed_time)); + } +#endif } mbedtls_ecp_point_free(&P); @@ -330,4 +422,13 @@ TEST_CASE("mbedtls ECP point verify with SECP256R1", "[mbedtls]") { test_ecp_verify(MBEDTLS_ECP_DP_SECP256R1, ecc_p256_mul_res_x, ecc_p256_mul_res_y); } + +#if SOC_ECC_SUPPORT_CURVE_P384 +TEST_CASE("mbedtls ECP point verify with SECP384R1", "[mbedtls]") +{ + if (ecc_ll_is_p384_curve_operations_supported()) { + test_ecp_verify(MBEDTLS_ECP_DP_SECP384R1, ecc_p384_mul_res_x, ecc_p384_mul_res_y); + } +} +#endif /* SOC_ECC_SUPPORT_CURVE_P384 */ #endif /* CONFIG_MBEDTLS_HARDWARE_ECC */