From cebbedbac2b9c2562f62d960172a4010e859ed24 Mon Sep 17 00:00:00 2001 From: "nilesh.kale" Date: Tue, 13 May 2025 17:36:57 +0530 Subject: [PATCH] feat: enable support for deterministic mode for esp32h2 --- components/hal/ecdsa_hal.c | 15 +++-- components/hal/esp32c5/include/hal/ecdsa_ll.h | 13 +--- components/hal/esp32h2/include/hal/ecdsa_ll.h | 30 ++++++++++ components/hal/esp32p4/include/hal/ecdsa_ll.h | 10 +++- .../test_apps/crypto/main/ecdsa/test_ecdsa.c | 28 ++++++--- components/mbedtls/port/ecdsa/ecdsa_alt.c | 59 +++++++++++++------ .../test_apps/main/test_mbedtls_ecdsa.c | 12 +++- .../esp32h2/include/soc/Kconfig.soc_caps.in | 8 +++ components/soc/esp32h2/include/soc/soc_caps.h | 2 + 9 files changed, 128 insertions(+), 49 deletions(-) diff --git a/components/hal/ecdsa_hal.c b/components/hal/ecdsa_hal.c index 5c10802e2c..8f5d463a26 100644 --- a/components/hal/ecdsa_hal.c +++ b/components/hal/ecdsa_hal.c @@ -47,10 +47,13 @@ static void configure_ecdsa_periph(ecdsa_hal_config_t *conf) } #if SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE - ecdsa_ll_set_k_type(conf->sign_type); - - if (conf->sign_type == ECDSA_K_TYPE_DETERMINISITIC) { - ecdsa_ll_set_deterministic_loop(conf->loop_number); + if (ecdsa_ll_is_deterministic_mode_supported()) { + ecdsa_ll_set_k_type(conf->sign_type); +#if !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP + if (conf->sign_type == ECDSA_K_TYPE_DETERMINISITIC) { + ecdsa_ll_set_deterministic_loop(conf->loop_number); + } +#endif /* !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP */ } #endif } @@ -224,11 +227,11 @@ void ecdsa_hal_export_pubkey(ecdsa_hal_config_t *conf, uint8_t *pub_x, uint8_t * } #endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */ -#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE +#if SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE && !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP bool ecdsa_hal_det_signature_k_check(void) { return (ecdsa_ll_check_k_value() == 0); } -#endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ +#endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE && !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP */ diff --git a/components/hal/esp32c5/include/hal/ecdsa_ll.h b/components/hal/esp32c5/include/hal/ecdsa_ll.h index 58bb389aeb..225a86d40a 100644 --- a/components/hal/esp32c5/include/hal/ecdsa_ll.h +++ b/components/hal/esp32c5/include/hal/ecdsa_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -415,17 +415,6 @@ static inline int ecdsa_ll_get_operation_result(void) return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_OPERATION_RESULT); } -/** - * @brief Check if the k value is greater than the curve order. - * - * @return 0, k value is not greater than the curve order. In this case, the k value is the set k value. - * @return 1, k value is greater than than the curve order. In this case, the k value is the set (k mod n). - */ -static inline int ecdsa_ll_check_k_value(void) -{ - return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_K_VALUE_WARNING); -} - #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/ecdsa_ll.h b/components/hal/esp32h2/include/hal/ecdsa_ll.h index ff83a3709d..65299c1219 100644 --- a/components/hal/esp32h2/include/hal/ecdsa_ll.h +++ b/components/hal/esp32h2/include/hal/ecdsa_ll.h @@ -211,6 +211,26 @@ static inline void ecdsa_ll_set_z_mode(ecdsa_ll_sha_mode_t mode) } } +/** + * @brief Set the signature generation type of ECDSA operation + * + * @param type Type of the ECDSA signature + */ +static inline void ecdsa_ll_set_k_type(ecdsa_sign_type_t type) +{ + switch (type) { + case ECDSA_K_TYPE_TRNG: + REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_DETERMINISTIC_K); + break; + case ECDSA_K_TYPE_DETERMINISITIC: + REG_SET_BIT(ECDSA_CONF_REG, ECDSA_DETERMINISTIC_K); + break; + default: + HAL_ASSERT(false && "Unsupported K type"); + break; + } +} + /** * @brief Set the stage of ECDSA operation * @@ -388,6 +408,16 @@ static inline bool ecdsa_ll_is_configurable_curve_supported(void) return ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102); } +/** + * @brief Check if the ECDSA deterministic mode is supported + * The ECDSA deterministic mode is only available in chip version + * above 1.2 in ESP32-H2 + */ +static inline bool ecdsa_ll_is_deterministic_mode_supported(void) +{ + return ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/ecdsa_ll.h b/components/hal/esp32p4/include/hal/ecdsa_ll.h index f3429cf1b2..1e8a713f75 100644 --- a/components/hal/esp32p4/include/hal/ecdsa_ll.h +++ b/components/hal/esp32p4/include/hal/ecdsa_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -432,6 +432,14 @@ static inline int ecdsa_ll_check_k_value(void) return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_K_VALUE_WARNING); } +/** + * @brief Check if the ECDSA deterministic mode is supported + */ +static inline bool ecdsa_ll_is_deterministic_mode_supported(void) +{ + return true; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c index 5fa292c42f..c7ddbeecd7 100644 --- a/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c +++ b/components/hal/test_apps/crypto/main/ecdsa/test_ecdsa.c @@ -151,9 +151,9 @@ void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, b uint8_t zeroes[32] = {0}; uint16_t len; -#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE +#if !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP uint16_t det_loop_number = 1; -#endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ +#endif /* !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP */ ecdsa_hal_config_t conf = { .mode = ECDSA_MODE_SIGN_GEN, @@ -184,11 +184,11 @@ void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, b bool process_again = false; do { -#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE - if (k_type == ECDSA_K_TYPE_DETERMINISITIC) { +#if !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP + if (ecdsa_ll_is_deterministic_mode_supported() && k_type == ECDSA_K_TYPE_DETERMINISITIC) { conf.loop_number = det_loop_number++; } -#endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ +#endif /* !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP */ ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len); @@ -196,8 +196,8 @@ void test_ecdsa_sign(bool is_p256, uint8_t* sha, uint8_t* r_le, uint8_t* s_le, b || !memcmp(r_le, zeroes, len) || !memcmp(s_le, zeroes, len); -#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE - if (k_type == ECDSA_K_TYPE_DETERMINISITIC) { +#if SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE && !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP + if (ecdsa_ll_is_deterministic_mode_supported() && k_type == ECDSA_K_TYPE_DETERMINISITIC) { process_again |= !ecdsa_hal_det_signature_k_check(); } #endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ @@ -329,12 +329,22 @@ TEST(ecdsa, ecdsa_SECP256R1_corrupt_signature) #ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE TEST(ecdsa, ecdsa_SECP192R1_det_sign_and_verify) { - test_ecdsa_sign_and_verify(0, sha, ecdsa192_pub_x, ecdsa192_pub_y, false, ECDSA_K_TYPE_DETERMINISITIC); + if (!ecdsa_ll_is_deterministic_mode_supported()) { + ESP_LOGI(TAG, "Skipping test because ECDSA deterministic mode is not supported."); + } else if (!esp_efuse_is_ecdsa_p192_curve_supported()) { + ESP_LOGI(TAG, "Skipping test because ECDSA 192-curve operations are disabled."); + } else { + test_ecdsa_sign_and_verify(0, sha, ecdsa192_pub_x, ecdsa192_pub_y, false, ECDSA_K_TYPE_DETERMINISITIC); + } } TEST(ecdsa, ecdsa_SECP256R1_det_sign_and_verify) { - test_ecdsa_sign_and_verify(1, sha, ecdsa256_pub_x, ecdsa256_pub_y, false, ECDSA_K_TYPE_DETERMINISITIC); + if (!ecdsa_ll_is_deterministic_mode_supported()) { + ESP_LOGI(TAG, "Skipping test because ECDSA deterministic mode is not supported."); + } else { + test_ecdsa_sign_and_verify(1, sha, ecdsa256_pub_x, ecdsa256_pub_y, false, ECDSA_K_TYPE_DETERMINISITIC); + } } #endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index 198ef085d6..96a14e7930 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -337,9 +337,9 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s bool process_again = false; -#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE - uint16_t deterministic_loop_number = 1; -#endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ +#if !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP + uint16_t deterministic_loop_number __attribute__((unused)) = 1; +#endif /* !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP */ do { ecdsa_hal_config_t conf = { @@ -347,10 +347,12 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s .curve = curve, .sha_mode = ECDSA_Z_USER_PROVIDED, .sign_type = k_type, -#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE - .loop_number = deterministic_loop_number++, -#endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ }; +#if !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP + if (ecdsa_ll_is_deterministic_mode_supported()) { + conf.loop_number = deterministic_loop_number++; + } +#endif /* !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP */ if (use_km_key) { conf.use_km_key = 1; @@ -375,8 +377,8 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s || !memcmp(r_le, zeroes, len) || !memcmp(s_le, zeroes, len); -#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE - if (k_type == ECDSA_K_TYPE_DETERMINISITIC) { +#if SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE && !SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP + if (ecdsa_ll_is_deterministic_mode_supported() && k_type == ECDSA_K_TYPE_DETERMINISITIC) { process_again |= !ecdsa_hal_det_signature_k_check(); } #endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ @@ -472,12 +474,18 @@ int __wrap_mbedtls_ecdsa_sign_det_ext(mbedtls_ecp_group *grp, mbedtls_mpi *r, /* * Check `d` whether it contains the hardware key */ +#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) { - // Use hardware ECDSA peripheral - return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_DETERMINISITIC); - } else { - return __real_mbedtls_ecdsa_sign_det_ext(grp, r, s, d, buf, blen, md_alg, f_rng_blind, p_rng_blind); + if (ecdsa_ll_is_deterministic_mode_supported()) { + // Use hardware ECDSA peripheral + return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_DETERMINISITIC); + } else { + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } } +#endif + // Fallback to software implementation + return __real_mbedtls_ecdsa_sign_det_ext(grp, r, s, d, buf, blen, md_alg, f_rng_blind, p_rng_blind); } extern int __real_mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp, @@ -507,12 +515,18 @@ int __wrap_mbedtls_ecdsa_sign_det_restartable(mbedtls_ecp_group *grp, /* * Check `d` whether it contains the hardware key */ +#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) { - // Use hardware ECDSA peripheral - return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_DETERMINISITIC); - } else { - return __real_mbedtls_ecdsa_sign_det_restartable(grp, r, s, d, buf, blen, md_alg, f_rng_blind, p_rng_blind, NULL); + if (ecdsa_ll_is_deterministic_mode_supported()) { + // Use hardware ECDSA peripheral + return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_DETERMINISITIC); + } else { + return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + } } +#endif + // Fallback to software implementation + return __real_mbedtls_ecdsa_sign_det_ext(grp, r, s, d, buf, blen, md_alg, f_rng_blind, p_rng_blind); } #endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ @@ -582,15 +596,22 @@ int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx, mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); + ecdsa_sign_type_t k_type = ECDSA_K_TYPE_TRNG; +#if defined(SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE) && defined(CONFIG_MBEDTLS_ECDSA_DETERMINISTIC) + if (ecdsa_ll_is_deterministic_mode_supported()) { + k_type = ECDSA_K_TYPE_DETERMINISITIC; + } +#endif + /* * Check `d` whether it contains the hardware key */ if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) { // Use hardware ECDSA peripheral #if defined(SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE) && defined(CONFIG_MBEDTLS_ECDSA_DETERMINISTIC) - MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, ECDSA_K_TYPE_DETERMINISITIC)); + MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, k_type)); #else - MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, ECDSA_K_TYPE_TRNG)); + MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, k_type)); #endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ } diff --git a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c index 12eec80b23..2a4366b720 100644 --- a/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c +++ b/components/mbedtls/test_apps/main/test_mbedtls_ecdsa.c @@ -274,12 +274,20 @@ TEST_CASE("mbedtls ECDSA signature generation on SECP256R1", "[mbedtls][efuse_ke TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP192R1", "[mbedtls][efuse_key]") { - test_ecdsa_sign(MBEDTLS_ECP_DP_SECP192R1, sha, ecdsa192_sign_pub_x, ecdsa192_sign_pub_y, true, SECP192R1_EFUSE_BLOCK); + if (!ecdsa_ll_is_deterministic_mode_supported()) { + ESP_LOGI(TAG, "Skipping test because ECDSA deterministic mode is not supported."); + } else { + test_ecdsa_sign(MBEDTLS_ECP_DP_SECP192R1, sha, ecdsa192_sign_pub_x, ecdsa192_sign_pub_y, true, SECP192R1_EFUSE_BLOCK); + } } TEST_CASE("mbedtls ECDSA deterministic signature generation on SECP256R1", "[mbedtls][efuse_key]") { - test_ecdsa_sign(MBEDTLS_ECP_DP_SECP256R1, sha, ecdsa256_sign_pub_x, ecdsa256_sign_pub_y, true, SECP256R1_EFUSE_BLOCK); + if (!ecdsa_ll_is_deterministic_mode_supported()) { + ESP_LOGI(TAG, "Skipping test because ECDSA deterministic mode is not supported."); + } else { + test_ecdsa_sign(MBEDTLS_ECP_DP_SECP256R1, sha, ecdsa256_sign_pub_x, ecdsa256_sign_pub_y, true, SECP256R1_EFUSE_BLOCK); + } } #endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */ diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 73dc682277..5e8cb0e51f 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1303,6 +1303,14 @@ config SOC_ECDSA_USES_MPI bool default y +config SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE + bool + default y + +config SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP + bool + default y + config SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index f8ebaa02e2..8148712fc2 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -523,6 +523,8 @@ /*------------------------- ECDSA CAPS -------------------------*/ #define SOC_ECDSA_USES_MPI (1) +#define SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE (1) +#define SOC_ECDSA_SUPPORT_HW_DETERMINISTIC_LOOP (1) #define SOC_ECDSA_P192_CURVE_DEFAULT_DISABLED (1) /*-------------------------- UART CAPS ---------------------------------------*/