From 58e5f48368c834bc994eacd4d12e992fa93501c8 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Tue, 22 Oct 2024 15:17:16 +0530 Subject: [PATCH 1/5] feat(ecc): enable ECC constant time mode for ESP32-H2 ECO5 --- components/esp_hw_support/Kconfig | 29 ++++++++ components/esp_system/port/cpu_start.c | 12 ++++ components/hal/Kconfig | 2 +- components/hal/ecc_hal.c | 5 ++ components/hal/esp32c2/include/hal/ecc_ll.h | 8 ++- components/hal/esp32c6/include/hal/ecc_ll.h | 6 ++ components/hal/esp32h2/include/hal/ecc_ll.h | 14 ++++ components/hal/include/hal/ecc_hal.h | 7 ++ components/hal/test_apps/ecc/main/test_ecc.c | 69 +++++++++++++++++++ components/mbedtls/Kconfig | 3 +- components/mbedtls/port/ecc/esp_ecc.c | 8 +++ .../esp32h2/include/soc/Kconfig.soc_caps.in | 8 +++ components/soc/esp32h2/include/soc/soc_caps.h | 6 ++ 13 files changed, 173 insertions(+), 4 deletions(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 5243a01775..a82b83f5c0 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -331,4 +331,33 @@ menu "Hardware Settings" default 3 if ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH endmenu + + config ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL + bool "Forcefully enable ECC constant time point multiplication operations" + depends on SOC_ECC_CONSTANT_TIME_POINT_MUL + default N + help + If enabled, the app startup code will burn the ECC_FORCE_CONST_TIME efuse bit to force the + ECC peripheral to always perform constant time point multiplication operations, + irrespective of the ECC_MULT_SECURITY_MODE status bit that is present in the ECC_MULT_CONF_REG + register. By default, ESP-IDF configures the ECC peripheral to perform constant time point + multiplication operations, so enabling this config would provide security enhancement only in + the cases when trusted boot is not enabled and the attacker tries carrying out non-constant + time point multiplication operations by changing the default ESP-IDF configurations. + Performing constant time operations protect the ECC multiplication operations from timing attacks. + + orsource "./port/$IDF_TARGET/Kconfig.dcdc" + + orsource "./port/$IDF_TARGET/Kconfig.ldo" + + # Invisible bringup bypass options for esp_hw_support component + config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING + bool + default y if !SOC_CLK_TREE_SUPPORTED + default n + help + This option is only used for new chip bringup, when + clock support isn't done yet. So with this option, + we use xtal on FPGA as the clock source. + endmenu diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 4a62c6633c..e3bc566970 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -247,6 +247,18 @@ static void start_other_core(void) REG_CLR_BIT(SYSTEM_CORE_1_CONTROL_0_REG, SYSTEM_CONTROL_CORE_1_RESETING); } #endif + +#if CONFIG_ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL + if (!esp_efuse_read_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME)) { + ESP_EARLY_LOGD(TAG, "Forcefully enabling ECC constant time operations"); + esp_err_t err = esp_efuse_write_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME); + if (err != ESP_OK) { + ESP_EARLY_LOGE(TAG, "Enabling ECC constant time operations forcefully failed."); + return err; + } + } +#endif + ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1); bool cpus_up = false; diff --git a/components/hal/Kconfig b/components/hal/Kconfig index 264fbb6a96..aac591bd36 100644 --- a/components/hal/Kconfig +++ b/components/hal/Kconfig @@ -105,8 +105,8 @@ menu "Hardware Abstraction Layer (HAL) and Low Level (LL)" config HAL_ECDSA_GEN_SIG_CM bool "Enable countermeasure for ECDSA signature generation" + depends on IDF_TARGET_ESP32H2 && ESP32H2_REV_MIN_FULL < 102 default n - # ToDo - IDF-11051 help Enable this option to apply the countermeasure for ECDSA signature operation This countermeasure masks the real ECDSA sign operation diff --git a/components/hal/ecc_hal.c b/components/hal/ecc_hal.c index 18ca952f8e..a3cb192ab2 100644 --- a/components/hal/ecc_hal.c +++ b/components/hal/ecc_hal.c @@ -177,3 +177,8 @@ int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len) } #endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */ + +void ecc_hal_enable_constant_time_point_mul(bool enable) +{ + ecc_ll_enable_constant_time_point_mul(enable); +} diff --git a/components/hal/esp32c2/include/hal/ecc_ll.h b/components/hal/esp32c2/include/hal/ecc_ll.h index 214dd8e676..642619ef5a 100644 --- a/components/hal/esp32c2/include/hal/ecc_ll.h +++ b/components/hal/esp32c2/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -142,6 +142,12 @@ static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_ memcpy(buf, (void *)reg, len); } +static inline void ecc_ll_enable_constant_time_point_mul(bool enable) +{ + // Not supported for ESP32-C2 + (void) enable; //unused +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/ecc_ll.h b/components/hal/esp32c6/include/hal/ecc_ll.h index 8e58e7b05b..b7934c60bc 100644 --- a/components/hal/esp32c6/include/hal/ecc_ll.h +++ b/components/hal/esp32c6/include/hal/ecc_ll.h @@ -153,6 +153,12 @@ static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_ memcpy(buf, (void *)reg, len); } +static inline void ecc_ll_enable_constant_time_point_mul(bool enable) +{ + // Not supported for ESP32-C6 + (void) enable; //unused +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h2/include/hal/ecc_ll.h b/components/hal/esp32h2/include/hal/ecc_ll.h index 6b5c0be4c4..472ad39292 100644 --- a/components/hal/esp32h2/include/hal/ecc_ll.h +++ b/components/hal/esp32h2/include/hal/ecc_ll.h @@ -12,6 +12,8 @@ #include "soc/ecc_mult_reg.h" #include "soc/pcr_struct.h" #include "soc/pcr_reg.h" +#include "soc/chip_revision.h" +#include "hal/efuse_ll.h" #ifdef __cplusplus extern "C" { @@ -189,6 +191,18 @@ static inline ecc_mod_base_t ecc_ll_get_mod_base(void) return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE); } +static inline void ecc_ll_enable_constant_time_point_mul(bool enable) +{ + // ECC constant time point multiplication is supported only on rev 1.2 and above + if ((efuse_ll_get_chip_wafer_version_major() >= 1) && (efuse_ll_get_chip_wafer_version_minor() >= 2)) { + if (enable) { + REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_SECURITY_MODE); + } else { + REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_SECURITY_MODE); + } + } +} + static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len) { uint32_t reg; diff --git a/components/hal/include/hal/ecc_hal.h b/components/hal/include/hal/ecc_hal.h index 23cfbbbda1..3d85dd6104 100644 --- a/components/hal/include/hal/ecc_hal.h +++ b/components/hal/include/hal/ecc_hal.h @@ -195,6 +195,13 @@ int ecc_hal_read_mod_op_result(uint8_t *r, uint16_t len); #endif /* SOC_ECC_EXTENDED_MODES_SUPPORTED */ +/** + * @brief Enable constant time multiplication operations + * + * @param true: enable; false: disable + */ +void ecc_hal_enable_constant_time_point_mul(bool enable); + #ifdef __cplusplus } #endif diff --git a/components/hal/test_apps/ecc/main/test_ecc.c b/components/hal/test_apps/ecc/main/test_ecc.c index 9b8997b107..db3d46d7c1 100644 --- a/components/hal/test_apps/ecc/main/test_ecc.c +++ b/components/hal/test_apps/ecc/main/test_ecc.c @@ -59,6 +59,7 @@ static void ecc_point_mul(const uint8_t *k_le, const uint8_t *x_le, const uint8_ } else { ecc_hal_set_mode(ECC_MODE_POINT_MUL); } + ecc_hal_enable_constant_time_point_mul(true); ecc_hal_start_calc(); while (!ecc_hal_is_calc_finished()) { @@ -132,6 +133,74 @@ TEST_CASE("ECC point multiplication on SECP192R1 and SECP256R1", "[ecc][hal]") { test_ecc_point_mul_inner(false); } + +#if SOC_ECC_CONSTANT_TIME_POINT_MUL || (CONFIG_IDF_TARGET_ESP32H2 && CONFIG_ESP32H2_REV_MIN_FULL >= 102) + +#define CONST_TIME_DEVIATION_PERCENT 0.002 + +static void test_ecc_point_mul_inner_constant_time(void) +{ + uint8_t scalar_le[32]; + uint8_t x_le[32]; + uint8_t y_le[32]; + + /* P256 */ + ecc_be_to_le(ecc_p256_scalar, scalar_le, 32); + ecc_be_to_le(ecc_p256_point_x, x_le, 32); + ecc_be_to_le(ecc_p256_point_y, y_le, 32); + + uint8_t x_res_le[32]; + uint8_t y_res_le[32]; + + double deviation = 0; + uint32_t elapsed_time, mean_elapsed_time, total_elapsed_time = 0; + uint32_t max_time = 0, min_time = UINT32_MAX; + int loop_count = 10; + + for (int i = 0; i < loop_count; i++) { + ccomp_timer_start(); + ecc_point_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le); + elapsed_time = ccomp_timer_stop(); + + max_time = MAX(elapsed_time, max_time); + min_time = MIN(elapsed_time, min_time); + total_elapsed_time += elapsed_time; + } + mean_elapsed_time = total_elapsed_time / loop_count; + deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time); + + TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation); + + /* P192 */ + ecc_be_to_le(ecc_p192_scalar, scalar_le, 24); + ecc_be_to_le(ecc_p192_point_x, x_le, 24); + ecc_be_to_le(ecc_p192_point_y, y_le, 24); + + max_time = 0; + min_time = UINT32_MAX; + total_elapsed_time = 0; + + for (int i = 0; i < loop_count; i++) { + ccomp_timer_start(); + ecc_point_mul(scalar_le, x_le, y_le, 24, 0, x_res_le, y_res_le); + elapsed_time = ccomp_timer_stop(); + + max_time = MAX(elapsed_time, max_time); + min_time = MIN(elapsed_time, min_time); + total_elapsed_time += elapsed_time; + } + mean_elapsed_time = total_elapsed_time / loop_count; + deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time); + + TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation); +} + +TEST(ecc, ecc_point_multiplication_const_time_check_on_SECP192R1_and_SECP256R1) +{ + test_ecc_point_mul_inner_constant_time(); +} +#endif + #endif #if SOC_ECC_SUPPORT_POINT_VERIFY diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index d2b1677b79..e2c14fb4a7 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -549,11 +549,10 @@ menu "mbedTLS" menu "Enable Software Countermeasure for ECDSA signing using on-chip ECDSA peripheral" depends on MBEDTLS_HARDWARE_ECDSA_SIGN - depends on IDF_TARGET_ESP32H2 + depends on IDF_TARGET_ESP32H2 && ESP32H2_REV_MIN_FULL < 102 config MBEDTLS_HARDWARE_ECDSA_SIGN_MASKING_CM bool "Mask original ECDSA sign operation under dummy sign operations" select HAL_ECDSA_GEN_SIG_CM - # ToDo: IDF-11051 default y help The ECDSA peripheral before ECO5 does not offer constant time ECDSA sign operation. diff --git a/components/mbedtls/port/ecc/esp_ecc.c b/components/mbedtls/port/ecc/esp_ecc.c index ecd87a2567..87d904c4dd 100644 --- a/components/mbedtls/port/ecc/esp_ecc.c +++ b/components/mbedtls/port/ecc/esp_ecc.c @@ -39,6 +39,14 @@ int esp_ecc_point_multiply(const ecc_point_t *point, const uint8_t *scalar, ecc_ ecc_hal_write_mul_param(scalar, point->x, point->y, len); ecc_hal_set_mode(work_mode); + + /* + * Enable constant-time point multiplication operations for the ECC hardware accelerator, + * if supported for the given target. This protects the ECC multiplication operation from + * timing attacks. This increases the time taken (by almost 50%) for some point + * multiplication operations performed by the ECC hardware accelerator. + */ + ecc_hal_enable_constant_time_point_mul(true); ecc_hal_start_calc(); memset(result, 0, sizeof(ecc_point_t)); diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index fa1ff41f0d..3894179212 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1067,6 +1067,14 @@ config SOC_CRYPTO_DPA_PROTECTION_SUPPORTED bool default y +config SOC_ECC_CONSTANT_TIME_POINT_MUL + bool + default y + +config SOC_ECDSA_USES_MPI + bool + default y + config SOC_UART_NUM int default 2 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 4ddc2072e7..fd7ab31724 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -457,6 +457,12 @@ /*------------------------ Anti DPA (Security) CAPS --------------------------*/ #define SOC_CRYPTO_DPA_PROTECTION_SUPPORTED 1 +/*--------------------------- ECC CAPS ---------------------------------------*/ +#define SOC_ECC_CONSTANT_TIME_POINT_MUL 1 + +/*------------------------- ECDSA CAPS -------------------------*/ +#define SOC_ECDSA_USES_MPI (1) + /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-H2 has 2 UARTs #define SOC_UART_NUM (2) From 09ded7787ffb5ec08311add388905ff5a59d4c80 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 10 Dec 2024 17:57:26 +0530 Subject: [PATCH 2/5] fix(hal): Make the ECDSA countermeasure dynamically applicable This commit makes the ECDSA countermeasure dynamically applicable across different revisions of the ESP32H2 SoC. --- components/esp_hw_support/Kconfig | 14 ------------- components/esp_system/port/cpu_start.c | 8 ++++++- components/hal/Kconfig | 2 +- components/hal/ecdsa_hal.c | 7 ++++++- components/hal/test_apps/ecc/CMakeLists.txt | 2 ++ .../hal/test_apps/ecc/main/CMakeLists.txt | 2 +- components/hal/test_apps/ecc/main/test_ecc.c | 21 ++++++++++++------- .../hal/test_apps/ecc/sdkconfig.defaults | 1 + components/mbedtls/port/ecdsa/ecdsa_alt.c | 10 ++++++--- 9 files changed, 38 insertions(+), 29 deletions(-) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index a82b83f5c0..418fbbe87b 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -346,18 +346,4 @@ menu "Hardware Settings" time point multiplication operations by changing the default ESP-IDF configurations. Performing constant time operations protect the ECC multiplication operations from timing attacks. - orsource "./port/$IDF_TARGET/Kconfig.dcdc" - - orsource "./port/$IDF_TARGET/Kconfig.ldo" - - # Invisible bringup bypass options for esp_hw_support component - config ESP_BRINGUP_BYPASS_CPU_CLK_SETTING - bool - default y if !SOC_CLK_TREE_SUPPORTED - default n - help - This option is only used for new chip bringup, when - clock support isn't done yet. So with this option, - we use xtal on FPGA as the clock source. - endmenu diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index e3bc566970..1da903d7f7 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -249,7 +249,13 @@ static void start_other_core(void) #endif #if CONFIG_ESP_CRYPTO_FORCE_ECC_CONSTANT_TIME_POINT_MUL - if (!esp_efuse_read_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME)) { + bool force_constant_time = true; +#if CONFIG_IDF_TARGET_ESP32H2 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + force_constant_time = false; + } +#endif + if (!esp_efuse_read_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME) && force_constant_time) { ESP_EARLY_LOGD(TAG, "Forcefully enabling ECC constant time operations"); esp_err_t err = esp_efuse_write_field_bit(ESP_EFUSE_ECC_FORCE_CONST_TIME); if (err != ESP_OK) { diff --git a/components/hal/Kconfig b/components/hal/Kconfig index aac591bd36..dcd91df039 100644 --- a/components/hal/Kconfig +++ b/components/hal/Kconfig @@ -105,7 +105,7 @@ menu "Hardware Abstraction Layer (HAL) and Low Level (LL)" config HAL_ECDSA_GEN_SIG_CM bool "Enable countermeasure for ECDSA signature generation" - depends on IDF_TARGET_ESP32H2 && ESP32H2_REV_MIN_FULL < 102 + depends on IDF_TARGET_ESP32H2 default n help Enable this option to apply the countermeasure for ECDSA signature operation diff --git a/components/hal/ecdsa_hal.c b/components/hal/ecdsa_hal.c index 31c782ba85..0148841161 100644 --- a/components/hal/ecdsa_hal.c +++ b/components/hal/ecdsa_hal.c @@ -12,6 +12,7 @@ #if CONFIG_HAL_ECDSA_GEN_SIG_CM #include "esp_fault.h" #include "esp_random.h" +#include "soc/chip_revision.h" #endif #define ECDSA_HAL_P192_COMPONENT_LEN 24 @@ -108,7 +109,11 @@ void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *hash, configure_ecdsa_periph(conf); #if CONFIG_HAL_ECDSA_GEN_SIG_CM - ecdsa_hal_gen_signature_with_countermeasure(hash, r_out, s_out, len); + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + ecdsa_hal_gen_signature_with_countermeasure(hash, r_out, s_out, len); + } else { + ecdsa_hal_gen_signature_inner(hash, r_out, s_out, len); + } #else /* CONFIG_HAL_ECDSA_GEN_SIG_CM */ ecdsa_hal_gen_signature_inner(hash, r_out, s_out, len); #endif /* !CONFIG_HAL_ECDSA_GEN_SIG_CM */ diff --git a/components/hal/test_apps/ecc/CMakeLists.txt b/components/hal/test_apps/ecc/CMakeLists.txt index 5ca38f39c4..067ea13764 100644 --- a/components/hal/test_apps/ecc/CMakeLists.txt +++ b/components/hal/test_apps/ecc/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.16) set(COMPONENTS main) +set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/unit-test-app/components") include($ENV{IDF_PATH}/tools/cmake/project.cmake) + project(ecc_test) diff --git a/components/hal/test_apps/ecc/main/CMakeLists.txt b/components/hal/test_apps/ecc/main/CMakeLists.txt index 668d5be1ed..98c0c07f90 100644 --- a/components/hal/test_apps/ecc/main/CMakeLists.txt +++ b/components/hal/test_apps/ecc/main/CMakeLists.txt @@ -2,5 +2,5 @@ set(srcs "app_main.c" "test_ecc.c") idf_component_register(SRCS ${srcs} - REQUIRES unity + REQUIRES unity test_utils WHOLE_ARCHIVE) diff --git a/components/hal/test_apps/ecc/main/test_ecc.c b/components/hal/test_apps/ecc/main/test_ecc.c index db3d46d7c1..8f191bebdb 100644 --- a/components/hal/test_apps/ecc/main/test_ecc.c +++ b/components/hal/test_apps/ecc/main/test_ecc.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: CC0-1.0 */ @@ -7,6 +7,8 @@ #include #include #include +#include "ccomp_timer.h" +#include "sys/param.h" #include "sdkconfig.h" #include "esp_log.h" #include "test_params.h" @@ -136,7 +138,7 @@ TEST_CASE("ECC point multiplication on SECP192R1 and SECP256R1", "[ecc][hal]") #if SOC_ECC_CONSTANT_TIME_POINT_MUL || (CONFIG_IDF_TARGET_ESP32H2 && CONFIG_ESP32H2_REV_MIN_FULL >= 102) -#define CONST_TIME_DEVIATION_PERCENT 0.002 +#define CONST_TIME_DEVIATION_THRESHOLD 2 // 0.2 % static void test_ecc_point_mul_inner_constant_time(void) { @@ -152,11 +154,14 @@ static void test_ecc_point_mul_inner_constant_time(void) uint8_t x_res_le[32]; uint8_t y_res_le[32]; - double deviation = 0; + uint32_t deviation = 0; uint32_t elapsed_time, mean_elapsed_time, total_elapsed_time = 0; uint32_t max_time = 0, min_time = UINT32_MAX; int loop_count = 10; + // performing the operation once to warm up the cache + ecc_point_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le); + for (int i = 0; i < loop_count; i++) { ccomp_timer_start(); ecc_point_mul(scalar_le, x_le, y_le, 32, 0, x_res_le, y_res_le); @@ -167,9 +172,9 @@ static void test_ecc_point_mul_inner_constant_time(void) total_elapsed_time += elapsed_time; } mean_elapsed_time = total_elapsed_time / loop_count; - deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time); + deviation = (((max_time - mean_elapsed_time) * 1000) / mean_elapsed_time); - TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation); + TEST_ASSERT_LESS_THAN(CONST_TIME_DEVIATION_THRESHOLD, deviation); /* P192 */ ecc_be_to_le(ecc_p192_scalar, scalar_le, 24); @@ -190,12 +195,12 @@ static void test_ecc_point_mul_inner_constant_time(void) total_elapsed_time += elapsed_time; } mean_elapsed_time = total_elapsed_time / loop_count; - deviation = ((double)(max_time - mean_elapsed_time) / mean_elapsed_time); + deviation = (((max_time - mean_elapsed_time) * 1000) / mean_elapsed_time); - TEST_ASSERT_LESS_THAN_DOUBLE(CONST_TIME_DEVIATION_PERCENT, deviation); + TEST_ASSERT_LESS_THAN(CONST_TIME_DEVIATION_THRESHOLD, deviation); } -TEST(ecc, ecc_point_multiplication_const_time_check_on_SECP192R1_and_SECP256R1) +TEST_CASE("ECC point multiplication constant time check on SECP192R1 and SECP256R1", "[ecc][hal]") { test_ecc_point_mul_inner_constant_time(); } diff --git a/components/hal/test_apps/ecc/sdkconfig.defaults b/components/hal/test_apps/ecc/sdkconfig.defaults index a4ba403514..bad2274c40 100644 --- a/components/hal/test_apps/ecc/sdkconfig.defaults +++ b/components/hal/test_apps/ecc/sdkconfig.defaults @@ -1,2 +1,3 @@ CONFIG_ESP_TASK_WDT_EN=y CONFIG_ESP_TASK_WDT_INIT=n +CONFIG_ESP_CRYPTO_DPA_PROTECTION_AT_STARTUP=n diff --git a/components/mbedtls/port/ecdsa/ecdsa_alt.c b/components/mbedtls/port/ecdsa/ecdsa_alt.c index 8f9158c372..c8b396cf00 100644 --- a/components/mbedtls/port/ecdsa/ecdsa_alt.c +++ b/components/mbedtls/port/ecdsa/ecdsa_alt.c @@ -23,6 +23,8 @@ #if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM #include "esp_timer.h" +#include "soc/chip_revision.h" +#include "hal/efuse_hal.h" #if CONFIG_ESP_CRYPTO_DPA_PROTECTION_LEVEL_HIGH /* @@ -176,9 +178,11 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s #endif ecdsa_hal_gen_signature(&conf, sha_le, r_le, s_le, len); #if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM - sig_time = esp_timer_get_time() - sig_time; - if (sig_time < ECDSA_CM_FIXED_SIG_TIME) { - esp_rom_delay_us(ECDSA_CM_FIXED_SIG_TIME - sig_time); + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + sig_time = esp_timer_get_time() - sig_time; + if (sig_time < ECDSA_CM_FIXED_SIG_TIME) { + esp_rom_delay_us(ECDSA_CM_FIXED_SIG_TIME - sig_time); + } } #endif process_again = !ecdsa_hal_get_operation_result() From 151b6e9be5126571e102cf577b091f5583abd6b6 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 14 Jan 2025 19:53:37 +0530 Subject: [PATCH 3/5] fix(soc): Fixed ECDSA register compatibility --- components/hal/ecdsa_hal.c | 6 +- components/hal/esp32h2/include/hal/ecc_ll.h | 4 +- components/hal/esp32h2/include/hal/ecdsa_ll.h | 17 +- components/hal/include/hal/ecdsa_hal.h | 2 +- components/hal/test_apps/ecc/main/test_ecc.c | 8 +- components/mbedtls/Kconfig | 2 +- components/soc/CMakeLists.txt | 4 + components/soc/esp32h2/ecdsa_reg_addr.c | 28 + .../soc/esp32h2/include/soc/ecdsa_reg.h | 583 ++++++++++++------ .../include/soc/ecdsa_rev_0_0_struct.h | 321 ++++++++++ .../include/soc/ecdsa_rev_1_2_struct.h | 368 +++++++++++ .../soc/esp32h2/include/soc/ecdsa_struct.h | 319 +--------- components/soc/esp32h2/include/soc/soc_caps.h | 1 - .../soc/esp32h2/ld/esp32h2.peripherals.ld | 2 +- 14 files changed, 1162 insertions(+), 503 deletions(-) create mode 100644 components/soc/esp32h2/ecdsa_reg_addr.c create mode 100644 components/soc/esp32h2/include/soc/ecdsa_rev_0_0_struct.h create mode 100644 components/soc/esp32h2/include/soc/ecdsa_rev_1_2_struct.h diff --git a/components/hal/ecdsa_hal.c b/components/hal/ecdsa_hal.c index 0148841161..b6644cedd4 100644 --- a/components/hal/ecdsa_hal.c +++ b/components/hal/ecdsa_hal.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 */ @@ -109,11 +109,15 @@ void ecdsa_hal_gen_signature(ecdsa_hal_config_t *conf, const uint8_t *hash, configure_ecdsa_periph(conf); #if CONFIG_HAL_ECDSA_GEN_SIG_CM +#if CONFIG_IDF_TARGET_ESP32H2 if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { ecdsa_hal_gen_signature_with_countermeasure(hash, r_out, s_out, len); } else { ecdsa_hal_gen_signature_inner(hash, r_out, s_out, len); } +#else + ecdsa_hal_gen_signature_with_countermeasure(hash, r_out, s_out, len); +#endif #else /* CONFIG_HAL_ECDSA_GEN_SIG_CM */ ecdsa_hal_gen_signature_inner(hash, r_out, s_out, len); #endif /* !CONFIG_HAL_ECDSA_GEN_SIG_CM */ diff --git a/components/hal/esp32h2/include/hal/ecc_ll.h b/components/hal/esp32h2/include/hal/ecc_ll.h index 472ad39292..5a421c6437 100644 --- a/components/hal/esp32h2/include/hal/ecc_ll.h +++ b/components/hal/esp32h2/include/hal/ecc_ll.h @@ -13,7 +13,7 @@ #include "soc/pcr_struct.h" #include "soc/pcr_reg.h" #include "soc/chip_revision.h" -#include "hal/efuse_ll.h" +#include "hal/efuse_hal.h" #ifdef __cplusplus extern "C" { @@ -194,7 +194,7 @@ static inline ecc_mod_base_t ecc_ll_get_mod_base(void) static inline void ecc_ll_enable_constant_time_point_mul(bool enable) { // ECC constant time point multiplication is supported only on rev 1.2 and above - if ((efuse_ll_get_chip_wafer_version_major() >= 1) && (efuse_ll_get_chip_wafer_version_minor() >= 2)) { + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)){ if (enable) { REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_SECURITY_MODE); } else { diff --git a/components/hal/esp32h2/include/hal/ecdsa_ll.h b/components/hal/esp32h2/include/hal/ecdsa_ll.h index 95861185b6..bd352b2e95 100644 --- a/components/hal/esp32h2/include/hal/ecdsa_ll.h +++ b/components/hal/esp32h2/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 */ @@ -10,6 +10,7 @@ #include "hal/assert.h" #include "soc/ecdsa_reg.h" #include "hal/ecdsa_types.h" +#include "hal/ecc_ll.h" #ifdef __cplusplus extern "C" { @@ -30,7 +31,7 @@ typedef enum { * @brief Interrupt types in ECDSA */ typedef enum { - ECDSA_INT_CALC_DONE, + ECDSA_INT_PREP_DONE, ECDSA_INT_SHA_RELEASE, } ecdsa_ll_intr_type_t; @@ -77,8 +78,8 @@ typedef enum { static inline void ecdsa_ll_enable_intr(ecdsa_ll_intr_type_t type) { switch (type) { - case ECDSA_INT_CALC_DONE: - REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_CALC_DONE_INT_ENA, 1); + case ECDSA_INT_PREP_DONE: + REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_PREP_DONE_INT_ENA, 1); break; case ECDSA_INT_SHA_RELEASE: REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_SHA_RELEASE_INT_ENA, 1); @@ -97,8 +98,8 @@ static inline void ecdsa_ll_enable_intr(ecdsa_ll_intr_type_t type) static inline void ecdsa_ll_disable_intr(ecdsa_ll_intr_type_t type) { switch (type) { - case ECDSA_INT_CALC_DONE: - REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_CALC_DONE_INT_ENA, 0); + case ECDSA_INT_PREP_DONE: + REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_PREP_DONE_INT_ENA, 0); break; case ECDSA_INT_SHA_RELEASE: REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_SHA_RELEASE_INT_ENA, 0); @@ -117,8 +118,8 @@ static inline void ecdsa_ll_disable_intr(ecdsa_ll_intr_type_t type) static inline void ecdsa_ll_clear_intr(ecdsa_ll_intr_type_t type) { switch (type) { - case ECDSA_INT_CALC_DONE: - REG_SET_FIELD(ECDSA_INT_CLR_REG, ECDSA_CALC_DONE_INT_CLR, 1); + case ECDSA_INT_PREP_DONE: + REG_SET_FIELD(ECDSA_INT_CLR_REG, ECDSA_PREP_DONE_INT_CLR, 1); break; case ECDSA_INT_SHA_RELEASE: REG_SET_FIELD(ECDSA_INT_CLR_REG, ECDSA_SHA_RELEASE_INT_CLR, 1); diff --git a/components/hal/include/hal/ecdsa_hal.h b/components/hal/include/hal/ecdsa_hal.h index 3dfd48233b..fe9298abf2 100644 --- a/components/hal/include/hal/ecdsa_hal.h +++ b/components/hal/include/hal/ecdsa_hal.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 */ diff --git a/components/hal/test_apps/ecc/main/test_ecc.c b/components/hal/test_apps/ecc/main/test_ecc.c index 8f191bebdb..9734df67bc 100644 --- a/components/hal/test_apps/ecc/main/test_ecc.c +++ b/components/hal/test_apps/ecc/main/test_ecc.c @@ -136,12 +136,18 @@ TEST_CASE("ECC point multiplication on SECP192R1 and SECP256R1", "[ecc][hal]") test_ecc_point_mul_inner(false); } -#if SOC_ECC_CONSTANT_TIME_POINT_MUL || (CONFIG_IDF_TARGET_ESP32H2 && CONFIG_ESP32H2_REV_MIN_FULL >= 102) +#if SOC_ECC_CONSTANT_TIME_POINT_MUL #define CONST_TIME_DEVIATION_THRESHOLD 2 // 0.2 % static void test_ecc_point_mul_inner_constant_time(void) { +#if CONFIG_IDF_TARGET_ESP32H2 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + TEST_IGNORE_MESSAGE("Skipping test, not supported on ESP32-H2 +#include "soc/ecdsa_reg.h" + +// Initializing the memory address with the base address of the old ECDSA version +uint32_t ECDSA_R_MEM = (DR_REG_ECDSA_BASE + 0xA00); +uint32_t ECDSA_S_MEM = (DR_REG_ECDSA_BASE + 0xA20); +uint32_t ECDSA_Z_MEM = (DR_REG_ECDSA_BASE + 0xA40); +uint32_t ECDSA_QAX_MEM = (DR_REG_ECDSA_BASE + 0xA60); +uint32_t ECDSA_QAY_MEM = (DR_REG_ECDSA_BASE + 0xA80); + +void ecdsa_compatible_mem_reg_addr_init(void) +{ + // set the memory registers based on the DATE register value + ECDSA_R_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA00, 0x340)); + ECDSA_S_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA20, 0x360)); + ECDSA_Z_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA40, 0x380)); + ECDSA_QAX_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA60, 0x3A0)); + ECDSA_QAY_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA80, 0x3C0)); +} diff --git a/components/soc/esp32h2/include/soc/ecdsa_reg.h b/components/soc/esp32h2/include/soc/ecdsa_reg.h index 62f2e1ad96..854cca0a46 100644 --- a/components/soc/esp32h2/include/soc/ecdsa_reg.h +++ b/components/soc/esp32h2/include/soc/ecdsa_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,204 +11,382 @@ extern "C" { #endif -/** ECDSA_CONF_REG register - * ECDSA configure register - */ -#define ECDSA_CONF_REG (DR_REG_ECDSA_BASE + 0x4) -/** ECDSA_WORK_MODE : R/W; bitpos: [0]; default: 0; - * The work mode bits of ECDSA Accelerator. 0: Signature Verify mode. 1: Signature - * Generate Mode. - */ -#define ECDSA_WORK_MODE (BIT(0)) -#define ECDSA_WORK_MODE_M (ECDSA_WORK_MODE_V << ECDSA_WORK_MODE_S) -#define ECDSA_WORK_MODE_V 0x00000001U -#define ECDSA_WORK_MODE_S 0 -/** ECDSA_ECC_CURVE : R/W; bitpos: [1]; default: 0; - * The ecc curve select bit of ECDSA Accelerator. 0: P-192. 1: P-256. - */ -#define ECDSA_ECC_CURVE (BIT(1)) -#define ECDSA_ECC_CURVE_M (ECDSA_ECC_CURVE_V << ECDSA_ECC_CURVE_S) -#define ECDSA_ECC_CURVE_V 0x00000001U -#define ECDSA_ECC_CURVE_S 1 -/** ECDSA_SOFTWARE_SET_K : R/W; bitpos: [2]; default: 0; - * The source of k select bit. 0: k is automatically generated by TRNG. 1: k is - * written by software. - */ -#define ECDSA_SOFTWARE_SET_K (BIT(2)) -#define ECDSA_SOFTWARE_SET_K_M (ECDSA_SOFTWARE_SET_K_V << ECDSA_SOFTWARE_SET_K_S) -#define ECDSA_SOFTWARE_SET_K_V 0x00000001U -#define ECDSA_SOFTWARE_SET_K_S 2 -/** ECDSA_SOFTWARE_SET_Z : R/W; bitpos: [3]; default: 0; - * The source of z select bit. 0: z is generated from SHA result. 1: z is written by - * software. - */ -#define ECDSA_SOFTWARE_SET_Z (BIT(3)) -#define ECDSA_SOFTWARE_SET_Z_M (ECDSA_SOFTWARE_SET_Z_V << ECDSA_SOFTWARE_SET_Z_S) -#define ECDSA_SOFTWARE_SET_Z_V 0x00000001U -#define ECDSA_SOFTWARE_SET_Z_S 3 -/** ECDSA_CLK_REG register - * ECDSA clock gate register - */ -#define ECDSA_CLK_REG (DR_REG_ECDSA_BASE + 0x8) -/** ECDSA_CLK_GATE_FORCE_ON : R/W; bitpos: [0]; default: 0; - * Write 1 to force on register clock gate. - */ -#define ECDSA_CLK_GATE_FORCE_ON (BIT(0)) -#define ECDSA_CLK_GATE_FORCE_ON_M (ECDSA_CLK_GATE_FORCE_ON_V << ECDSA_CLK_GATE_FORCE_ON_S) -#define ECDSA_CLK_GATE_FORCE_ON_V 0x00000001U -#define ECDSA_CLK_GATE_FORCE_ON_S 0 - -/** ECDSA_INT_RAW_REG register - * ECDSA interrupt raw register, valid in level. - */ -#define ECDSA_INT_RAW_REG (DR_REG_ECDSA_BASE + 0xc) -/** ECDSA_CALC_DONE_INT_RAW : RO/WTC/SS; bitpos: [0]; default: 0; - * The raw interrupt status bit for the ecdsa_calc_done_int interrupt - */ -#define ECDSA_CALC_DONE_INT_RAW (BIT(0)) -#define ECDSA_CALC_DONE_INT_RAW_M (ECDSA_CALC_DONE_INT_RAW_V << ECDSA_CALC_DONE_INT_RAW_S) -#define ECDSA_CALC_DONE_INT_RAW_V 0x00000001U -#define ECDSA_CALC_DONE_INT_RAW_S 0 -/** ECDSA_SHA_RELEASE_INT_RAW : RO/WTC/SS; bitpos: [1]; default: 0; - * The raw interrupt status bit for the ecdsa_sha_release_int interrupt - */ -#define ECDSA_SHA_RELEASE_INT_RAW (BIT(1)) -#define ECDSA_SHA_RELEASE_INT_RAW_M (ECDSA_SHA_RELEASE_INT_RAW_V << ECDSA_SHA_RELEASE_INT_RAW_S) -#define ECDSA_SHA_RELEASE_INT_RAW_V 0x00000001U -#define ECDSA_SHA_RELEASE_INT_RAW_S 1 - -/** ECDSA_INT_ST_REG register - * ECDSA interrupt status register. - */ -#define ECDSA_INT_ST_REG (DR_REG_ECDSA_BASE + 0x10) -/** ECDSA_CALC_DONE_INT_ST : RO; bitpos: [0]; default: 0; - * The masked interrupt status bit for the ecdsa_calc_done_int interrupt - */ -#define ECDSA_CALC_DONE_INT_ST (BIT(0)) -#define ECDSA_CALC_DONE_INT_ST_M (ECDSA_CALC_DONE_INT_ST_V << ECDSA_CALC_DONE_INT_ST_S) -#define ECDSA_CALC_DONE_INT_ST_V 0x00000001U -#define ECDSA_CALC_DONE_INT_ST_S 0 -/** ECDSA_SHA_RELEASE_INT_ST : RO; bitpos: [1]; default: 0; - * The masked interrupt status bit for the ecdsa_sha_release_int interrupt - */ -#define ECDSA_SHA_RELEASE_INT_ST (BIT(1)) -#define ECDSA_SHA_RELEASE_INT_ST_M (ECDSA_SHA_RELEASE_INT_ST_V << ECDSA_SHA_RELEASE_INT_ST_S) -#define ECDSA_SHA_RELEASE_INT_ST_V 0x00000001U -#define ECDSA_SHA_RELEASE_INT_ST_S 1 - -/** ECDSA_INT_ENA_REG register - * ECDSA interrupt enable register. - */ -#define ECDSA_INT_ENA_REG (DR_REG_ECDSA_BASE + 0x14) -/** ECDSA_CALC_DONE_INT_ENA : R/W; bitpos: [0]; default: 0; - * The interrupt enable bit for the ecdsa_calc_done_int interrupt - */ -#define ECDSA_CALC_DONE_INT_ENA (BIT(0)) -#define ECDSA_CALC_DONE_INT_ENA_M (ECDSA_CALC_DONE_INT_ENA_V << ECDSA_CALC_DONE_INT_ENA_S) -#define ECDSA_CALC_DONE_INT_ENA_V 0x00000001U -#define ECDSA_CALC_DONE_INT_ENA_S 0 -/** ECDSA_SHA_RELEASE_INT_ENA : R/W; bitpos: [1]; default: 0; - * The interrupt enable bit for the ecdsa_sha_release_int interrupt - */ -#define ECDSA_SHA_RELEASE_INT_ENA (BIT(1)) -#define ECDSA_SHA_RELEASE_INT_ENA_M (ECDSA_SHA_RELEASE_INT_ENA_V << ECDSA_SHA_RELEASE_INT_ENA_S) -#define ECDSA_SHA_RELEASE_INT_ENA_V 0x00000001U -#define ECDSA_SHA_RELEASE_INT_ENA_S 1 - -/** ECDSA_INT_CLR_REG register - * ECDSA interrupt clear register. - */ -#define ECDSA_INT_CLR_REG (DR_REG_ECDSA_BASE + 0x18) -/** ECDSA_CALC_DONE_INT_CLR : WT; bitpos: [0]; default: 0; - * Set this bit to clear the ecdsa_calc_done_int interrupt - */ -#define ECDSA_CALC_DONE_INT_CLR (BIT(0)) -#define ECDSA_CALC_DONE_INT_CLR_M (ECDSA_CALC_DONE_INT_CLR_V << ECDSA_CALC_DONE_INT_CLR_S) -#define ECDSA_CALC_DONE_INT_CLR_V 0x00000001U -#define ECDSA_CALC_DONE_INT_CLR_S 0 -/** ECDSA_SHA_RELEASE_INT_CLR : WT; bitpos: [1]; default: 0; - * Set this bit to clear the ecdsa_sha_release_int interrupt - */ -#define ECDSA_SHA_RELEASE_INT_CLR (BIT(1)) -#define ECDSA_SHA_RELEASE_INT_CLR_M (ECDSA_SHA_RELEASE_INT_CLR_V << ECDSA_SHA_RELEASE_INT_CLR_S) -#define ECDSA_SHA_RELEASE_INT_CLR_V 0x00000001U -#define ECDSA_SHA_RELEASE_INT_CLR_S 1 - -/** ECDSA_START_REG register - * ECDSA start register - */ -#define ECDSA_START_REG (DR_REG_ECDSA_BASE + 0x1c) -/** ECDSA_START : WT; bitpos: [0]; default: 0; - * Write 1 to start caculation of ECDSA Accelerator. This bit will be self-cleared - * after configuration. - */ -#define ECDSA_START (BIT(0)) -#define ECDSA_START_M (ECDSA_START_V << ECDSA_START_S) -#define ECDSA_START_V 0x00000001U -#define ECDSA_START_S 0 -/** ECDSA_LOAD_DONE : WT; bitpos: [1]; default: 0; - * Write 1 to input load done signal of ECDSA Accelerator. This bit will be - * self-cleared after configuration. - */ -#define ECDSA_LOAD_DONE (BIT(1)) -#define ECDSA_LOAD_DONE_M (ECDSA_LOAD_DONE_V << ECDSA_LOAD_DONE_S) -#define ECDSA_LOAD_DONE_V 0x00000001U -#define ECDSA_LOAD_DONE_S 1 -/** ECDSA_GET_DONE : WT; bitpos: [2]; default: 0; - * Write 1 to input get done signal of ECDSA Accelerator. This bit will be - * self-cleared after configuration. - */ -#define ECDSA_GET_DONE (BIT(2)) -#define ECDSA_GET_DONE_M (ECDSA_GET_DONE_V << ECDSA_GET_DONE_S) -#define ECDSA_GET_DONE_V 0x00000001U -#define ECDSA_GET_DONE_S 2 - -/** ECDSA_STATE_REG register - * ECDSA status register - */ -#define ECDSA_STATE_REG (DR_REG_ECDSA_BASE + 0x20) -/** ECDSA_BUSY : RO; bitpos: [1:0]; default: 0; - * The status bits of ECDSA Accelerator. ECDSA is at 0: IDLE, 1: LOAD, 2: GET, 3: BUSY - * state. - */ -#define ECDSA_BUSY 0x00000003U -#define ECDSA_BUSY_M (ECDSA_BUSY_V << ECDSA_BUSY_S) -#define ECDSA_BUSY_V 0x00000003U -#define ECDSA_BUSY_S 0 - -/** ECDSA_RESULT_REG register - * ECDSA result register - */ -#define ECDSA_RESULT_REG (DR_REG_ECDSA_BASE + 0x24) -/** ECDSA_OPERATION_RESULT : RO/SS; bitpos: [0]; default: 0; - * The operation result bit of ECDSA Accelerator, only valid when ECDSA calculation is - * done. - */ -#define ECDSA_OPERATION_RESULT (BIT(0)) -#define ECDSA_OPERATION_RESULT_M (ECDSA_OPERATION_RESULT_V << ECDSA_OPERATION_RESULT_S) -#define ECDSA_OPERATION_RESULT_V 0x00000001U -#define ECDSA_OPERATION_RESULT_S 0 +/** Version register */ /** ECDSA_DATE_REG register - * Version control register + * Version control + * register */ #define ECDSA_DATE_REG (DR_REG_ECDSA_BASE + 0xfc) -/** ECDSA_DATE : R/W; bitpos: [27:0]; default: 35684752; - * ECDSA version control register +/* ECDSA_DATE : R/W; bitpos: [28:0]; default: 35684752 (0x21FFB30) for rev 0.0; + * ECDSA_DATE : R/W; bitpos: [28:0]; default: 37761312 (0x2403120) for rev 1.2; + * ECDSA version control + * register */ #define ECDSA_DATE 0x0FFFFFFFU #define ECDSA_DATE_M (ECDSA_DATE_V << ECDSA_DATE_S) #define ECDSA_DATE_V 0x0FFFFFFFU #define ECDSA_DATE_S 0 +/** + * @brief Get the correct value of a field according to the register version + * @note ESP32-H2 v1.2 updated the register ECDSA_DATE_REG to a new version, + * At the same time the value of some registers was changed + * This macro can help to get the correct value of a field according to the register version + ** @param old: the value of the field for the old version where DATE == 0x021FFB30 (rev 0.0) + * @param new: the value of the field for the new version where DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_REG_GET_OFFSET(old, new) (REG_GET_FIELD(ECDSA_DATE_REG, ECDSA_DATE) >= 0x02403120 ? (new) : (old)) + +/** Configuration registers */ + +/** ECDSA_CONF_REG register + * ECDSA configure + * register + */ +#define ECDSA_CONF_REG (DR_REG_ECDSA_BASE + 0x4) + +/* ECDSA_WORK_MODE : R/W; + * bitpos: [0]; default: 0; for DATE == 0x21FFB30 (rev 0.0) + * bitpos: [1:0]; default: 0; for DATE == 0x2403120 (rev 1.2) + * The work mode bits of ECDSA Accelerator. + * 0: Signature Generate Mode. + * 1: Signature Verify Mode. + * 2: Export public key Mode. (only available for DATE == 0x2403120 (rev 1.2)) + * 3: Invalid mode. (only available for DATE == 0x2403120 (rev 1.2)) + */ +#define ECDSA_WORK_MODE ECDSA_REG_GET_OFFSET(BIT(0), 0x00000003U) +#define ECDSA_WORK_MODE_M (ECDSA_WORK_MODE_V << ECDSA_WORK_MODE_S) +#define ECDSA_WORK_MODE_V ECDSA_REG_GET_OFFSET(0x00000001U, 0x00000003U) +#define ECDSA_WORK_MODE_S 0 + +/* ECDSA_ECC_CURVE : R/W; + * bitpos: [1]; default: 0; for DATE == 0x21FFB30 (rev 0.0) + * bitpos: [2]; default: 0; for DATE == 0x2403120 (rev 1.2) + * The ecc curve select bit of ECDSA Accelerator. + * 0: P-192. 1: P-256. + */ +#define ECDSA_ECC_CURVE ECDSA_REG_GET_OFFSET(BIT(1), BIT(2)) +#define ECDSA_ECC_CURVE_M (ECDSA_ECC_CURVE_V << ECDSA_ECC_CURVE_S) +#define ECDSA_ECC_CURVE_V 0x00000001U +#define ECDSA_ECC_CURVE_S ECDSA_REG_GET_OFFSET(1, 2) +/* ECDSA_SOFTWARE_SET_K : R/W; bitpos: [2]; default: 0; + * The source of k select bit. 0: k is automatically generated by TRNG. 1: + * k is written by + * software. + */ +#define ECDSA_SOFTWARE_SET_K ECDSA_REG_GET_OFFSET(BIT(2), BIT(3)) +#define ECDSA_SOFTWARE_SET_K_M (ECDSA_SOFTWARE_SET_K_V << ECDSA_SOFTWARE_SET_K_S) +#define ECDSA_SOFTWARE_SET_K_V 0x00000001U +#define ECDSA_SOFTWARE_SET_K_S ECDSA_REG_GET_OFFSET(2, 3) + +/* ECDSA_SOFTWARE_SET_Z : R/W; bitpos: [3]; default: 0; + * The source of z select bit. 0: z is generated from SHA result. 1: z is + * written by + * software. + */ +#define ECDSA_SOFTWARE_SET_Z ECDSA_REG_GET_OFFSET(BIT(3), BIT(4)) +#define ECDSA_SOFTWARE_SET_Z_M (ECDSA_SOFTWARE_SET_Z_V << ECDSA_SOFTWARE_SET_Z_S) +#define ECDSA_SOFTWARE_SET_Z_V 0x00000001U +#define ECDSA_SOFTWARE_SET_Z_S ECDSA_REG_GET_OFFSET(3, 4) + +/* ECDSA_K_DETERMINISTIC : R/W; bitpos: [5]; default: 0; + * The source of k select bit. 0: k is generated from TRNG. 1: k is + * written by + * software. + */ +#define ECDSA_DETERMINISTIC_K (BIT(5)) +#define ECDSA_DETERMINISTIC_K_M (ECDSA_DETERMINISTIC_K_V << ECDSA_DETERMINISTIC_K_S) +#define ECDSA_DETERMINISTIC_K_V 0x00000001U +#define ECDSA_DETERMINISTIC_K_S 5 + + +/** Clock and reset registers */ + +/** ECDSA_CLK_REG register + * ECDSA clock gate + * register + */ +#define ECDSA_CLK_REG (DR_REG_ECDSA_BASE + 0x8) +/* ECDSA_CLK_GATE_FORCE_ON : R/W; bitpos: [0]; default: 0; + * Write 1 to force on register clock + * gate. + */ +#define ECDSA_CLK_GATE_FORCE_ON (BIT(0)) +#define ECDSA_CLK_GATE_FORCE_ON_M (ECDSA_CLK_GATE_FORCE_ON_V << ECDSA_CLK_GATE_FORCE_ON_S) +#define ECDSA_CLK_GATE_FORCE_ON_V 0x00000001U +#define ECDSA_CLK_GATE_FORCE_ON_S 0 + + +/** Interrupt registers */ + +/** ECDSA_INT_RAW_REG register + * ECDSA interrupt raw register, valid in + * level. + */ +#define ECDSA_INT_RAW_REG (DR_REG_ECDSA_BASE + 0xc) + +/* ECDSA_PREP_DONE_INT_RAW : RO/WTC/SS; bitpos: [0]; default: 0; + * The raw interrupt status bit for the ecdsa_prep_done_int + * interrupt + * This bit was named as ECDSA_CALC_DONE_INT_RAW in rev 0.0 and changed to ECDSA_PREP_DONE_INT_RAW in rev 1.2 + * functionality is the same + */ +#define ECDSA_PREP_DONE_INT_RAW (BIT(0)) +#define ECDSA_PREP_DONE_INT_RAW_M (ECDSA_PREP_DONE_INT_RAW_V << ECDSA_PREP_DONE_INT_RAW_S) +#define ECDSA_PREP_DONE_INT_RAW_V 0x00000001U +#define ECDSA_PREP_DONE_INT_RAW_S 0 + +/* ECDSA_PROC_DONE_INT_RAW : RO/WTC/SS; bitpos: [1]; default: 0; + * The raw interrupt status bit for the ecdsa_proc_done_int + * interrupt + * This bit is only available for DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_PROC_DONE_INT_RAW (BIT(1)) +#define ECDSA_PROC_DONE_INT_RAW_M (ECDSA_PROC_DONE_INT_RAW_V << ECDSA_PROC_DONE_INT_RAW_S) +#define ECDSA_PROC_DONE_INT_RAW_V 0x00000001U +#define ECDSA_PROC_DONE_INT_RAW_S 1 + +/* ECDSA_POST_DONE_INT_RAW : RO/WTC/SS; bitpos: [2]; default: 0; + * The raw interrupt status bit for the ecdsa_post_done_int + * interrupt + * This bit is only available for DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_POST_DONE_INT_RAW (BIT(2)) +#define ECDSA_POST_DONE_INT_RAW_M (ECDSA_POST_DONE_INT_RAW_V << ECDSA_POST_DONE_INT_RAW_S) +#define ECDSA_POST_DONE_INT_RAW_V 0x00000001U +#define ECDSA_POST_DONE_INT_RAW_S 2 + +/* ECDSA_SHA_RELEASE_INT_RAW : RO/WTC/SS; bitpos: [1]; default: 0; + * The raw interrupt status bit for the ecdsa_sha_release_int + * interrupt + * This bit is only available for DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_SHA_RELEASE_INT_RAW ECDSA_REG_GET_OFFSET(BIT(1), BIT(3)) +#define ECDSA_SHA_RELEASE_INT_RAW_M (ECDSA_SHA_RELEASE_INT_RAW_V << ECDSA_SHA_RELEASE_INT_RAW_S) +#define ECDSA_SHA_RELEASE_INT_RAW_V 0x00000001U +#define ECDSA_SHA_RELEASE_INT_RAW_S ECDSA_REG_GET_OFFSET(1, 3) + +/** ECDSA_INT_ST_REG register + * ECDSA interrupt status + * register. + */ +#define ECDSA_INT_ST_REG (DR_REG_ECDSA_BASE + 0x10) + +/* ECDSA_PREP_DONE_INT_ST : RO; bitpos: [0]; default: 0; + * The masked interrupt status bit for the ecdsa_prep_done_int + * interrupt + * This bit was named as ECDSA_CALC_DONE_INT_ST in rev 0.0 and changed to ECDSA_PREP_DONE_INT_ST in rev 1.2 + * functionality is the same + */ +#define ECDSA_PREP_DONE_INT_ST (BIT(0)) +#define ECDSA_PREP_DONE_INT_ST_M (ECDSA_PREP_DONE_INT_ST_V << ECDSA_PREP_DONE_INT_ST_S) +#define ECDSA_PREP_DONE_INT_ST_V 0x00000001U +#define ECDSA_PREP_DONE_INT_ST_S 0 + +/* ECDSA_PROC_DONE_INT_ST : RO; bitpos: [1]; default: 0; + * The masked interrupt status bit for the ecdsa_proc_done_int + * interrupt + * This bit is only available for DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_PROC_DONE_INT_ST (BIT(1)) +#define ECDSA_PROC_DONE_INT_ST_M (ECDSA_PROC_DONE_INT_ST_V << ECDSA_PROC_DONE_INT_ST_S) +#define ECDSA_PROC_DONE_INT_ST_V 0x00000001U +#define ECDSA_PROC_DONE_INT_ST_S 1 + +/* ECDSA_POST_DONE_INT_ST : RO; bitpos: [2]; default: 0; + * The masked interrupt status bit for the ecdsa_post_done_int + * interrupt + * This bit is only available for DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_POST_DONE_INT_ST (BIT(2)) +#define ECDSA_POST_DONE_INT_ST_M (ECDSA_POST_DONE_INT_ST_V << ECDSA_POST_DONE_INT_ST_S) +#define ECDSA_POST_DONE_INT_ST_V 0x00000001U +#define ECDSA_POST_DONE_INT_ST_S 2 + +/* ECDSA_SHA_RELEASE_INT_ST : RO; + * bitpos: [1] for DATE == 0x21FFB30 (rev 0.0) ; default: 0; + * bitpos: [3] for DATE == 0x2403120 (rev 1.2) ; default: 0; + * The masked interrupt status bit for the ecdsa_sha_release_int + * interrupt + */ +#define ECDSA_SHA_RELEASE_INT_ST ECDSA_REG_GET_OFFSET(BIT(1), BIT(3)) +#define ECDSA_SHA_RELEASE_INT_ST_M (ECDSA_SHA_RELEASE_INT_ST_V << ECDSA_SHA_RELEASE_INT_ST_S) +#define ECDSA_SHA_RELEASE_INT_ST_V 0x00000001U +#define ECDSA_SHA_RELEASE_INT_ST_S ECDSA_REG_GET_OFFSET(1, 3) + +/** ECDSA_INT_ENA_REG register + * ECDSA interrupt enable + * register. + */ +#define ECDSA_INT_ENA_REG (DR_REG_ECDSA_BASE + 0x14) + +/* ECDSA_PREP_DONE_INT_ENA : R/W; bitpos: [0]; default: 0; + * The interrupt enable bit for the ecdsa_prep_done_int + * interrupt + * This bit was named as ECDSA_CALC_DONE_INT_ENA in rev 0.0 and changed to ECDSA_PREP_DONE_INT_ENA in rev 1.2 + * functionality is the same + */ +#define ECDSA_PREP_DONE_INT_ENA (BIT(0)) +#define ECDSA_PREP_DONE_INT_ENA_M (ECDSA_PREP_DONE_INT_ENA_V << ECDSA_PREP_DONE_INT_ENA_S) +#define ECDSA_PREP_DONE_INT_ENA_V 0x00000001U +#define ECDSA_PREP_DONE_INT_ENA_S 0 + +/* ECDSA_PROC_DONE_INT_ENA : R/W; bitpos: [1]; default: 0; + * The interrupt enable bit for the ecdsa_proc_done_int + * interrupt + * This bit is only available for DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_PROC_DONE_INT_ENA (BIT(1)) +#define ECDSA_PROC_DONE_INT_ENA_M (ECDSA_PROC_DONE_INT_ENA_V << ECDSA_PROC_DONE_INT_ENA_S) +#define ECDSA_PROC_DONE_INT_ENA_V 0x00000001U +#define ECDSA_PROC_DONE_INT_ENA_S 1 + +/* ECDSA_POST_DONE_INT_ENA : R/W; bitpos: [2]; default: 0; + * The interrupt enable bit for the ecdsa_post_done_int + * interrupt + * This bit is only available for DATE == 0x2403120 (rev 1.2) + */ +#define ECDSA_POST_DONE_INT_ENA (BIT(2)) +#define ECDSA_POST_DONE_INT_ENA_M (ECDSA_POST_DONE_INT_ENA_V << ECDSA_POST_DONE_INT_ENA_S) +#define ECDSA_POST_DONE_INT_ENA_V 0x00000001U +#define ECDSA_POST_DONE_INT_ENA_S 2 + +/* ECDSA_SHA_RELEASE_INT_ENA : R/W; + * bitpos: [1] for DATE == 0x21FFB30 (rev 0.0); default: 0; + * bitpos: [3] for DATE == 0x2403120 (rev 1.2); default: 0; + * The interrupt enable bit for the ecdsa_sha_release_int + * interrupt + */ +#define ECDSA_SHA_RELEASE_INT_ENA (ECDSA_REG_GET_OFFSET(BIT(1), BIT(3))) +#define ECDSA_SHA_RELEASE_INT_ENA_M (ECDSA_SHA_RELEASE_INT_ENA_V << ECDSA_SHA_RELEASE_INT_ENA_S) +#define ECDSA_SHA_RELEASE_INT_ENA_V 0x00000001U +#define ECDSA_SHA_RELEASE_INT_ENA_S (ECDSA_REG_GET_OFFSET(1, 3)) + +/** ECDSA_INT_CLR_REG register + * ECDSA interrupt clear + * register. + */ +#define ECDSA_INT_CLR_REG (DR_REG_ECDSA_BASE + 0x18) + + +/* ECDSA_PREP_DONE_INT_CLR : WT; bitpos: [0]; default: 0; + * Set this bit to clear the ecdsa_prep_done_int interrupt + * This bit was named as ECDSA_CALC_DONE_INT_CLR in rev 0.0 and changed to ECDSA_PREP_DONE_INT_CLR in rev 1.2 + * functionality is the same + */ +#define ECDSA_PREP_DONE_INT_CLR (BIT(0)) +#define ECDSA_PREP_DONE_INT_CLR_M (ECDSA_PREP_DONE_INT_CLR_V << ECDSA_PREP_DONE_INT_CLR_S) +#define ECDSA_PREP_DONE_INT_CLR_V 0x00000001U +#define ECDSA_PREP_DONE_INT_CLR_S 0 + +#define ECDSA_PROC_DONE_INT_CLR (BIT(1)) +#define ECDSA_PROC_DONE_INT_CLR_M (ECDSA_PROC_DONE_INT_CLR_V << ECDSA_PROC_DONE_INT_CLR_S) +#define ECDSA_PROC_DONE_INT_CLR_V 0x00000001U +#define ECDSA_PROC_DONE_INT_CLR_S 1 + +/* This bit is only available for DATE == 0x2403120 (rev 1.2) + * ECDSA_POST_DONE_INT_CLR : WT; bitpos: [2]; default: 0; + * Set this bit to clear the ecdsa_post_done_int interrupt + */ + +#define ECDSA_POST_DONE_INT_CLR (BIT(2)) +#define ECDSA_POST_DONE_INT_CLR_M (ECDSA_POST_DONE_INT_CLR_V << ECDSA_POST_DONE_INT_CLR_S) +#define ECDSA_POST_DONE_INT_CLR_V 0x00000001U +#define ECDSA_POST_DONE_INT_CLR_S 2 + +/* ECDSA_SHA_RELEASE_INT_CLR : WT; + * bitpos: [1] for DATE == 0x21FFB30 (rev 0.0); default: 0; + * bitpos: [3] for DATE == 0x2403120 (rev 1.2); default: 0; + * Set this bit to clear the ecdsa_sha_release_int + * interrupt + */ +#define ECDSA_SHA_RELEASE_INT_CLR (ECDSA_REG_GET_OFFSET(BIT(1), BIT(3))) +#define ECDSA_SHA_RELEASE_INT_CLR_M (ECDSA_SHA_RELEASE_INT_CLR_V << ECDSA_SHA_RELEASE_INT_CLR_S) +#define ECDSA_SHA_RELEASE_INT_CLR_V 0x00000001U +#define ECDSA_SHA_RELEASE_INT_CLR_S (ECDSA_REG_GET_OFFSET(1, 3)) + +/** ECDSA_START_REG register + * ECDSA start + * register + */ +#define ECDSA_START_REG (DR_REG_ECDSA_BASE + 0x1c) +/* ECDSA_START : WT; bitpos: [0]; default: 0; + * Write 1 to start calculation of ECDSA Accelerator. This bit will be + * self-cleared after + * configuration. + */ +#define ECDSA_START (BIT(0)) +#define ECDSA_START_M (ECDSA_START_V << ECDSA_START_S) +#define ECDSA_START_V 0x00000001U +#define ECDSA_START_S 0 +/* ECDSA_LOAD_DONE : WT; bitpos: [1]; default: 0; + * Write 1 to input load done signal of ECDSA Accelerator. This bit will + * be self-cleared after + * configuration. + */ +#define ECDSA_LOAD_DONE (BIT(1)) +#define ECDSA_LOAD_DONE_M (ECDSA_LOAD_DONE_V << ECDSA_LOAD_DONE_S) +#define ECDSA_LOAD_DONE_V 0x00000001U +#define ECDSA_LOAD_DONE_S 1 +/* ECDSA_GET_DONE : WT; bitpos: [2]; default: 0; + * Write 1 to input get done signal of ECDSA Accelerator. This bit will be + * self-cleared after + * configuration. + */ +#define ECDSA_GET_DONE (BIT(2)) +#define ECDSA_GET_DONE_M (ECDSA_GET_DONE_V << ECDSA_GET_DONE_S) +#define ECDSA_GET_DONE_V 0x00000001U +#define ECDSA_GET_DONE_S 2 + +/** Status registers */ + +/** ECDSA_STATE_REG register + * ECDSA status + * register + */ +#define ECDSA_STATE_REG (DR_REG_ECDSA_BASE + 0x20) +/* ECDSA_BUSY : RO; bitpos: [2:0]; default: 0; + * The status bits of ECDSA Accelerator. ECDSA is at 0: IDLE, 1: LOAD, 2: + * GET, 3: BUSY + * state. + */ +#define ECDSA_BUSY 0x00000003U +#define ECDSA_BUSY_M (ECDSA_BUSY_V << ECDSA_BUSY_S) +#define ECDSA_BUSY_V 0x00000003U +#define ECDSA_BUSY_S 0 + + +/** Result registers */ + +/** ECDSA_RESULT_REG register + * ECDSA result + * register + */ +#define ECDSA_RESULT_REG (DR_REG_ECDSA_BASE + 0x24) +/* ECDSA_OPERATION_RESULT : RO/SS; bitpos: [0]; default: 0; + * The operation result bit of ECDSA Accelerator, only valid when ECDSA + * calculation is + * done. + */ +#define ECDSA_OPERATION_RESULT (BIT(0)) +#define ECDSA_OPERATION_RESULT_M (ECDSA_OPERATION_RESULT_V << ECDSA_OPERATION_RESULT_S) +#define ECDSA_OPERATION_RESULT_V 0x00000001U +#define ECDSA_OPERATION_RESULT_S 0 + + +/** SHA register */ + /** ECDSA_SHA_MODE_REG register - * ECDSA control SHA register + * ECDSA control SHA + * register */ #define ECDSA_SHA_MODE_REG (DR_REG_ECDSA_BASE + 0x200) -/** ECDSA_SHA_MODE : R/W; bitpos: [2:0]; default: 0; - * The work mode bits of SHA Calculator in ECDSA Accelerator. 1: SHA-224. 2: SHA-256. - * Others: invalid. +/* ECDSA_SHA_MODE : R/W; bitpos: [3:0]; default: 0; + * The work mode bits of SHA Calculator in ECDSA Accelerator. 1: SHA-224. + * 2: SHA-256. Others: + * invalid. */ #define ECDSA_SHA_MODE 0x00000007U #define ECDSA_SHA_MODE_M (ECDSA_SHA_MODE_V << ECDSA_SHA_MODE_S) @@ -216,7 +394,8 @@ extern "C" { #define ECDSA_SHA_MODE_S 0 /** ECDSA_SHA_START_REG register - * ECDSA control SHA register + * ECDSA control SHA + * register */ #define ECDSA_SHA_START_REG (DR_REG_ECDSA_BASE + 0x210) /** ECDSA_SHA_START : WT; bitpos: [0]; default: 0; @@ -229,12 +408,14 @@ extern "C" { #define ECDSA_SHA_START_S 0 /** ECDSA_SHA_CONTINUE_REG register - * ECDSA control SHA register + * ECDSA control SHA + * register */ #define ECDSA_SHA_CONTINUE_REG (DR_REG_ECDSA_BASE + 0x214) -/** ECDSA_SHA_CONTINUE : WT; bitpos: [0]; default: 0; - * Write 1 to start the latter caculation of SHA Calculator in ECDSA Accelerator. This - * bit will be self-cleared after configuration. +/* ECDSA_SHA_CONTINUE : WT; bitpos: [0]; default: 0; + * Write 1 to start the latter calculation of SHA Calculator in ECDSA + * Accelerator. This bit will be self-cleared after + * configuration. */ #define ECDSA_SHA_CONTINUE (BIT(0)) #define ECDSA_SHA_CONTINUE_M (ECDSA_SHA_CONTINUE_V << ECDSA_SHA_CONTINUE_S) @@ -242,18 +423,21 @@ extern "C" { #define ECDSA_SHA_CONTINUE_S 0 /** ECDSA_SHA_BUSY_REG register - * ECDSA status register + * ECDSA status + * register */ #define ECDSA_SHA_BUSY_REG (DR_REG_ECDSA_BASE + 0x218) -/** ECDSA_SHA_BUSY : RO; bitpos: [0]; default: 0; - * The busy status bit of SHA Calculator in ECDSA Accelerator. 1:SHA is in - * calculation. 0: SHA is idle. +/* ECDSA_SHA_BUSY : RO; bitpos: [0]; default: 0; + * The busy status bit of SHA Calculator in ECDSA Accelerator. 1:SHA is in + * calculation. 0: SHA is + * idle. */ #define ECDSA_SHA_BUSY (BIT(0)) #define ECDSA_SHA_BUSY_M (ECDSA_SHA_BUSY_V << ECDSA_SHA_BUSY_S) #define ECDSA_SHA_BUSY_V 0x00000001U #define ECDSA_SHA_BUSY_S 0 + /** ECDSA_MESSAGE_MEM register * The memory that stores message. */ @@ -263,33 +447,34 @@ extern "C" { /** ECDSA_R_MEM register * The memory that stores r. */ -#define ECDSA_R_MEM (DR_REG_ECDSA_BASE + 0xa00) +extern uint32_t ECDSA_R_MEM; #define ECDSA_R_MEM_SIZE_BYTES 32 /** ECDSA_S_MEM register * The memory that stores s. */ -#define ECDSA_S_MEM (DR_REG_ECDSA_BASE + 0xa20) +extern uint32_t ECDSA_S_MEM; #define ECDSA_S_MEM_SIZE_BYTES 32 /** ECDSA_Z_MEM register * The memory that stores software written z. */ -#define ECDSA_Z_MEM (DR_REG_ECDSA_BASE + 0xa40) +extern uint32_t ECDSA_Z_MEM; #define ECDSA_Z_MEM_SIZE_BYTES 32 /** ECDSA_QAX_MEM register * The memory that stores x coordinates of QA or software written k. */ -#define ECDSA_QAX_MEM (DR_REG_ECDSA_BASE + 0xa60) +extern uint32_t ECDSA_QAX_MEM; #define ECDSA_QAX_MEM_SIZE_BYTES 32 /** ECDSA_QAY_MEM register * The memory that stores y coordinates of QA. */ -#define ECDSA_QAY_MEM (DR_REG_ECDSA_BASE + 0xa80) +extern uint32_t ECDSA_QAY_MEM; #define ECDSA_QAY_MEM_SIZE_BYTES 32 + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32h2/include/soc/ecdsa_rev_0_0_struct.h b/components/soc/esp32h2/include/soc/ecdsa_rev_0_0_struct.h new file mode 100644 index 0000000000..2bab26ed70 --- /dev/null +++ b/components/soc/esp32h2/include/soc/ecdsa_rev_0_0_struct.h @@ -0,0 +1,321 @@ +/** + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** Group: Data Memory */ + +/** Group: Configuration registers */ +/** Type of conf register + * ECDSA configure register + */ +typedef union { + struct { + /** work_mode : R/W; bitpos: [0]; default: 0; + * The work mode bits of ECDSA Accelerator. 0: Signature Verify Mode. 1: Signature + * Generate Mode. + */ + uint32_t work_mode:1; + /** ecc_curve : R/W; bitpos: [1]; default: 0; + * The ecc curve select bit of ECDSA Accelerator. 0: P-192. 1: P-256. + */ + uint32_t ecc_curve:1; + /** software_set_k : R/W; bitpos: [2]; default: 0; + * The source of k select bit. 0: k is automatically generated by TRNG. 1: k is + * written by software. + */ + uint32_t software_set_k:1; + /** software_set_z : R/W; bitpos: [3]; default: 0; + * The source of z select bit. 0: z is generated from SHA result. 1: z is written by + * software. + */ + uint32_t software_set_z:1; + uint32_t reserved_4:28; + }; + uint32_t val; +} ecdsa_rev_0_0_conf_reg_t; + +/** Type of start register + * ECDSA start register + */ +typedef union { + struct { + /** start : WT; bitpos: [0]; default: 0; + * Write 1 to start caculation of ECDSA Accelerator. This bit will be self-cleared + * after configuration. + */ + uint32_t start:1; + /** load_done : WT; bitpos: [1]; default: 0; + * Write 1 to input load done signal of ECDSA Accelerator. This bit will be + * self-cleared after configuration. + */ + uint32_t load_done:1; + /** get_done : WT; bitpos: [2]; default: 0; + * Write 1 to input get done signal of ECDSA Accelerator. This bit will be + * self-cleared after configuration. + */ + uint32_t get_done:1; + uint32_t reserved_3:29; + }; + uint32_t val; +} ecdsa_rev_0_0_start_reg_t; + + +/** Group: Clock and reset registers */ +/** Type of clk register + * ECDSA clock gate register + */ +typedef union { + struct { + /** clk_gate_force_on : R/W; bitpos: [0]; default: 0; + * Write 1 to force on register clock gate. + */ + uint32_t clk_gate_force_on:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_rev_0_0_clk_reg_t; + + +/** Group: Interrupt registers */ +/** Type of int_raw register + * ECDSA interrupt raw register, valid in level. + */ +typedef union { + struct { + /** calc_done_int_raw : RO/WTC/SS; bitpos: [0]; default: 0; + * The raw interrupt status bit for the ecdsa_calc_done_int interrupt + */ + uint32_t calc_done_int_raw:1; + /** sha_release_int_raw : RO/WTC/SS; bitpos: [1]; default: 0; + * The raw interrupt status bit for the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_raw:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} ecdsa_rev_0_0_int_raw_reg_t; + +/** Type of int_st register + * ECDSA interrupt status register. + */ +typedef union { + struct { + /** calc_done_int_st : RO; bitpos: [0]; default: 0; + * The masked interrupt status bit for the ecdsa_calc_done_int interrupt + */ + uint32_t calc_done_int_st:1; + /** sha_release_int_st : RO; bitpos: [1]; default: 0; + * The masked interrupt status bit for the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_st:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} ecdsa_rev_0_0_int_st_reg_t; + +/** Type of int_ena register + * ECDSA interrupt enable register. + */ +typedef union { + struct { + /** calc_done_int_ena : R/W; bitpos: [0]; default: 0; + * The interrupt enable bit for the ecdsa_calc_done_int interrupt + */ + uint32_t calc_done_int_ena:1; + /** sha_release_int_ena : R/W; bitpos: [1]; default: 0; + * The interrupt enable bit for the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_ena:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} ecdsa_rev_0_0_int_ena_reg_t; + +/** Type of int_clr register + * ECDSA interrupt clear register. + */ +typedef union { + struct { + /** calc_done_int_clr : WT; bitpos: [0]; default: 0; + * Set this bit to clear the ecdsa_calc_done_int interrupt + */ + uint32_t calc_done_int_clr:1; + /** sha_release_int_clr : WT; bitpos: [1]; default: 0; + * Set this bit to clear the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_clr:1; + uint32_t reserved_2:30; + }; + uint32_t val; +} ecdsa_rev_0_0_int_clr_reg_t; + + +/** Group: Status registers */ +/** Type of state register + * ECDSA status register + */ +typedef union { + struct { + /** busy : RO; bitpos: [1:0]; default: 0; + * The status bits of ECDSA Accelerator. ECDSA is at 0: IDLE, 1: LOAD, 2: GET, 3: BUSY + * state. + */ + uint32_t busy:2; + uint32_t reserved_2:30; + }; + uint32_t val; +} ecdsa_rev_0_0_state_reg_t; + + +/** Group: Result registers */ +/** Type of result register + * ECDSA result register + */ +typedef union { + struct { + /** operation_result : RO/SS; bitpos: [0]; default: 0; + * The operation result bit of ECDSA Accelerator, only valid when ECDSA calculation is + * done. + */ + uint32_t operation_result:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_rev_0_0_result_reg_t; + + +/** Group: SHA register */ +/** Type of sha_mode register + * ECDSA control SHA register + */ +typedef union { + struct { + /** sha_mode : R/W; bitpos: [2:0]; default: 0; + * The work mode bits of SHA Calculator in ECDSA Accelerator. 1: SHA-224. 2: SHA-256. + * Others: invalid. + */ + uint32_t sha_mode:3; + uint32_t reserved_3:29; + }; + uint32_t val; +} ecdsa_rev_0_0_sha_mode_reg_t; + +/** Type of sha_start register + * ECDSA control SHA register + */ +typedef union { + struct { + /** sha_start : WT; bitpos: [0]; default: 0; + * Write 1 to start the first caculation of SHA Calculator in ECDSA Accelerator. This + * bit will be self-cleared after configuration. + */ + uint32_t sha_start:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_rev_0_0_sha_start_reg_t; + +/** Type of sha_continue register + * ECDSA control SHA register + */ +typedef union { + struct { + /** sha_continue : WT; bitpos: [0]; default: 0; + * Write 1 to start the latter caculation of SHA Calculator in ECDSA Accelerator. This + * bit will be self-cleared after configuration. + */ + uint32_t sha_continue:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_rev_0_0_sha_continue_reg_t; + +/** Type of sha_busy register + * ECDSA status register + */ +typedef union { + struct { + /** sha_busy : RO; bitpos: [0]; default: 0; + * The busy status bit of SHA Calculator in ECDSA Accelerator. 1:SHA is in + * calculation. 0: SHA is idle. + */ + uint32_t sha_busy:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_rev_0_0_sha_busy_reg_t; + + +/** Group: Version register */ +/** Type of date register + * Version control register + */ +typedef union { + struct { + /** date : R/W; bitpos: [27:0]; default: 35684752; + * ECDSA version control register + */ + uint32_t ecdsa_date:28; + uint32_t reserved_28:4; + }; + uint32_t val; +} ecdsa_rev_0_0_date_reg_t; + +/** + * ECDSA message register + */ +typedef struct { + volatile uint32_t message[8]; +} ecdsa_rev_0_0_message_reg_t; + +/** + * ECDSA memory register + */ +typedef struct { + volatile uint32_t r[8]; + volatile uint32_t s[8]; + volatile uint32_t z[8]; + volatile uint32_t qax[8]; + volatile uint32_t qay[8]; +} ecdsa_rev_0_0_mem_reg_t; + +typedef struct { + uint32_t reserved_000; + volatile ecdsa_rev_0_0_conf_reg_t conf; + volatile ecdsa_rev_0_0_clk_reg_t clk; + volatile ecdsa_rev_0_0_int_raw_reg_t int_raw; + volatile ecdsa_rev_0_0_int_st_reg_t int_st; + volatile ecdsa_rev_0_0_int_ena_reg_t int_ena; + volatile ecdsa_rev_0_0_int_clr_reg_t int_clr; + volatile ecdsa_rev_0_0_start_reg_t start; + volatile ecdsa_rev_0_0_state_reg_t state; + volatile ecdsa_rev_0_0_result_reg_t result; + uint32_t reserved_028[53]; + volatile ecdsa_rev_0_0_date_reg_t date; + uint32_t reserved_100[64]; + volatile ecdsa_rev_0_0_sha_mode_reg_t sha_mode; + uint32_t reserved_204[3]; + volatile ecdsa_rev_0_0_sha_start_reg_t sha_start; + volatile ecdsa_rev_0_0_sha_continue_reg_t sha_continue; + volatile ecdsa_rev_0_0_sha_busy_reg_t sha_busy; + uint32_t reserved_21c[25]; + volatile ecdsa_rev_0_0_message_reg_t message; + uint32_t reserved_2a0[472]; + volatile ecdsa_rev_0_0_mem_reg_t mem; +} ecdsa_dev_rev_0_0_t; + +#ifndef __cplusplus +_Static_assert(sizeof(ecdsa_dev_rev_0_0_t) == 0xaa0, "Invalid size of ecdsa_dev_rev_0_0_t structure"); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/ecdsa_rev_1_2_struct.h b/components/soc/esp32h2/include/soc/ecdsa_rev_1_2_struct.h new file mode 100644 index 0000000000..16b5021d4d --- /dev/null +++ b/components/soc/esp32h2/include/soc/ecdsa_rev_1_2_struct.h @@ -0,0 +1,368 @@ +/** + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#ifdef __cplusplus +extern "C" { +#endif + +/** Group: Data Memory */ + +/** Group: Configuration registers */ +/** Type of conf register + * ECDSA configure register + */ +typedef union { + struct { + /** work_mode : R/W; bitpos: [1:0]; default: 0; + * The work mode bits of ECDSA Accelerator. + * 0: Signature Verify Mode. + * 1: Signature Generate Mode. + * 2: Export Public Key Mode. + * 3: invalid. + */ + uint32_t work_mode:2; + + /** ecc_curve : R/W; bitpos: [2]; default: 0; + * The ecc curve select bit of ECDSA Accelerator. 0: P-192. 1: P-256. + */ + uint32_t ecc_curve:1; + /** software_set_k : R/W; bitpos: [3]; default: 0; + * The source of k select bit. 0: k is automatically generated by TRNG. 1: k is + * written by software. + */ + uint32_t software_set_k:1; + + /** software_set_z : R/W; bitpos: [4]; default: 0; + * The source of z select bit. 0: z is generated from SHA result. 1: z is written by + * software. + */ + uint32_t software_set_z:1; + + /** ecdsa_deterministic_k : R/W; bitpos: [5]; default: 0; + * The source of hardware generated k. 0: k is generated by TRNG. 1: k is generated by + * deterministic derivation algorithm. + */ + + uint32_t ecdsa_deterministic_k:1; + + uint32_t reserved_6:26; + }; + uint32_t val; +} ecdsa_conf_reg_t; + +/** Type of start register + * ECDSA start register + */ +typedef union { + struct { + /** start : WT; bitpos: [0]; default: 0; + * Write 1 to start calculation of ECDSA Accelerator. This bit will be self-cleared + * after configuration. + */ + uint32_t start:1; + /** load_done : WT; bitpos: [1]; default: 0; + * Write 1 to input load done signal of ECDSA Accelerator. This bit will be + * self-cleared after configuration. + */ + uint32_t load_done:1; + /** get_done : WT; bitpos: [2]; default: 0; + * Write 1 to input get done signal of ECDSA Accelerator. This bit will be + * self-cleared after configuration. + */ + uint32_t get_done:1; + uint32_t reserved_3:29; + }; + uint32_t val; +} ecdsa_start_reg_t; + + +/** Group: Clock and reset registers */ +/** Type of clk register + * ECDSA clock gate register + */ +typedef union { + struct { + /** clk_gate_force_on : R/W; bitpos: [0]; default: 0; + * Write 1 to force on register clock gate. + */ + uint32_t clk_gate_force_on:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_clk_reg_t; + + +/** Group: Interrupt registers */ +/** Type of int_raw register + * ECDSA interrupt raw register, valid in level. + */ +typedef union { + struct { + /** prep_done_int_raw : RO/WTC/SS; bitpos: [0]; default: 0; + * The raw interrupt status bit for the ecdsa_prep_done_int interrupt + */ + uint32_t prep_done_int_raw:1; + /** proc_done_int_raw : RO/WTC/SS; bitpos: [1]; default: 0; + * The raw interrupt status bit for the ecdsa_proc_done_int interrupt + */ + uint32_t proc_done_int_raw:1; + /** post_done_int_raw : RO/WTC/SS; bitpos: [2]; default: 0; + * The raw interrupt status bit for the ecdsa_post_done_int interrupt + */ + uint32_t post_done_int_raw:1; + /** sha_release_int_raw : RO/WTC/SS; bitpos: [3]; default: 0; + * The raw interrupt status bit for the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_raw:1; + + uint32_t reserved_4:28; + }; + uint32_t val; +} ecdsa_int_raw_reg_t; + +/** Type of int_st register + * ECDSA interrupt status register. + */ +typedef union { + struct { + /** prep_done_int_st : RO; bitpos: [0]; default: 0; + * The masked interrupt status bit for the ecdsa_prep_done_int interrupt + */ + uint32_t prep_done_int_st:1; + /** proc_done_int_st : RO; bitpos: [1]; default: 0; + * The masked interrupt status bit for the ecdsa_proc_done_int interrupt + */ + uint32_t proc_done_int_st:1; + /** post_done_int_st : RO; bitpos: [2]; default: 0; + * The masked interrupt status bit for the ecdsa_post_done_int interrupt + */ + uint32_t post_done_int_st:1; + /** sha_release_int_st : RO; bitpos: [3]; default: 0; + * The masked interrupt status bit for the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_st:1; + uint32_t reserved_4:28; + }; + uint32_t val; +} ecdsa_int_st_reg_t; + +/** Type of int_ena register + * ECDSA interrupt enable register. + */ +typedef union { + struct { + /** prep_done_int_ena : R/W; bitpos: [0]; default: 0; + * The interrupt enable bit for the ecdsa_prep_done_int interrupt + */ + uint32_t prep_done_int_ena:1; + /** sha_release_int_ena : R/W; bitpos: [1]; default: 0; + * The interrupt enable bit for the ecdsa_sha_release_int interrupt + */ + uint32_t proc_done_int_ena:1; + /** post_done_int_ena : R/W; bitpos: [2]; default: 0; + * The interrupt enable bit for the ecdsa_post_done_int interrupt + */ + uint32_t post_done_int_ena:1; + /** sha_release_int_ena : R/W; bitpos: [3]; default: 0; + * The interrupt enable bit for the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_ena:1; + uint32_t reserved_4:28; + }; + uint32_t val; +} ecdsa_int_ena_reg_t; + +/** Type of int_clr register + * ECDSA interrupt clear register. + */ +typedef union { + struct { + /** prep_done_int_clr : WT; bitpos: [0]; default: 0; + * Set this bit to clear the ecdsa_prep_done_int interrupt + */ + uint32_t prep_done_int_clr:1; + /** proc_done_int_clr : WT; bitpos: [1]; default: 0; + * Set this bit to clear the ecdsa_proc_done_int interrupt + */ + uint32_t proc_done_int_clr:1; + /** post_done_int_clr : WT; bitpos: [2]; default: 0; + * Set this bit to clear the ecdsa_post_done_int interrupt + */ + uint32_t post_done_int_clr:1; + /** sha_release_int_clr : WT; bitpos: [3]; default: 0; + * Set this bit to clear the ecdsa_sha_release_int interrupt + */ + uint32_t sha_release_int_clr:1; + uint32_t reserved_4:28; + }; + uint32_t val; +} ecdsa_int_clr_reg_t; + + +/** Group: Status registers */ +/** Type of state register + * ECDSA status register + */ +typedef union { + struct { + /** busy : RO; bitpos: [1:0]; default: 0; + * The status bits of ECDSA Accelerator. ECDSA is at 0: IDLE, 1: LOAD, 2: GET, 3: BUSY + * state. + */ + uint32_t busy:2; + uint32_t reserved_2:30; + }; + uint32_t val; +} ecdsa_state_reg_t; + + +/** Group: Result registers */ +/** Type of result register + * ECDSA result register + */ +typedef union { + struct { + /** operation_result : RO/SS; bitpos: [0]; default: 0; + * The operation result bit of ECDSA Accelerator, only valid when ECDSA calculation is + * done. + */ + uint32_t operation_result:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_result_reg_t; + + +/** Group: SHA register */ +/** Type of sha_mode register + * ECDSA control SHA register + */ +typedef union { + struct { + /** sha_mode : R/W; bitpos: [2:0]; default: 0; + * The work mode bits of SHA Calculator in ECDSA Accelerator. 1: SHA-224. 2: SHA-256. + * Others: invalid. + */ + uint32_t sha_mode:3; + uint32_t reserved_3:29; + }; + uint32_t val; +} ecdsa_sha_mode_reg_t; + +/** Type of sha_start register + * ECDSA control SHA register + */ +typedef union { + struct { + /** sha_start : WT; bitpos: [0]; default: 0; + * Write 1 to start the first calculation of SHA Calculator in ECDSA Accelerator. This + * bit will be self-cleared after configuration. + */ + uint32_t sha_start:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_sha_start_reg_t; + +/** Type of sha_continue register + * ECDSA control SHA register + */ +typedef union { + struct { + /** sha_continue : WT; bitpos: [0]; default: 0; + * Write 1 to start the latter calculation of SHA Calculator in ECDSA Accelerator. This + * bit will be self-cleared after configuration. + */ + uint32_t sha_continue:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_sha_continue_reg_t; + +/** Type of sha_busy register + * ECDSA status register + */ +typedef union { + struct { + /** sha_busy : RO; bitpos: [0]; default: 0; + * The busy status bit of SHA Calculator in ECDSA Accelerator. 1:SHA is in + * calculation. 0: SHA is idle. + */ + uint32_t sha_busy:1; + uint32_t reserved_1:31; + }; + uint32_t val; +} ecdsa_sha_busy_reg_t; + + +/** Group: Version register */ +/** Type of date register + * Version control register + */ +typedef union { + struct { + /** ECDSA_DATE : R/W; bitpos: [27:0]; default: 37761312; + * ECDSA version control register + */ + uint32_t ecdsa_date:28; + uint32_t reserved_28:4; + }; + uint32_t val; +} ecdsa_date_reg_t; + +/** + * ECDSA message register + */ +typedef struct { + volatile uint32_t message[8]; +} ecdsa_message_reg_t; + +/** + * ECDSA memory register + */ +typedef struct { + volatile uint32_t r[8]; + volatile uint32_t s[8]; + volatile uint32_t z[8]; + volatile uint32_t qax[8]; + volatile uint32_t qay[8]; +} ecdsa_mem_reg_t; + +typedef struct { + uint32_t reserved_000; + volatile ecdsa_conf_reg_t conf; + volatile ecdsa_clk_reg_t clk; + volatile ecdsa_int_raw_reg_t int_raw; + volatile ecdsa_int_st_reg_t int_st; + volatile ecdsa_int_ena_reg_t int_ena; + volatile ecdsa_int_clr_reg_t int_clr; + volatile ecdsa_start_reg_t start; + volatile ecdsa_state_reg_t state; + volatile ecdsa_result_reg_t result; + uint32_t reserved_028[53]; + volatile ecdsa_date_reg_t date; + uint32_t reserved_100[64]; + volatile ecdsa_sha_mode_reg_t sha_mode; + uint32_t reserved_204[3]; + volatile ecdsa_sha_start_reg_t sha_start; + volatile ecdsa_sha_continue_reg_t sha_continue; + volatile ecdsa_sha_busy_reg_t sha_busy; + uint32_t reserved_21c[25]; + volatile ecdsa_message_reg_t message; + uint32_t reserved_2a0[40]; + volatile ecdsa_mem_reg_t mem; + uint32_t reserved_300[432]; +} ecdsa_dev_rev_1_2_t; + +#ifndef __cplusplus +_Static_assert(sizeof(ecdsa_dev_rev_1_2_t) == 0xaa0, "Invalid size of ecdsa_dev_rev_1_2_t structure"); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32h2/include/soc/ecdsa_struct.h b/components/soc/esp32h2/include/soc/ecdsa_struct.h index dcdd806f8f..9457cb32b0 100644 --- a/components/soc/esp32h2/include/soc/ecdsa_struct.h +++ b/components/soc/esp32h2/include/soc/ecdsa_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,300 +10,43 @@ extern "C" { #endif -/** Group: Data Memory */ +#include "soc/ecdsa_rev_0_0_struct.h" +#include "soc/ecdsa_rev_1_2_struct.h" -/** Group: Configuration registers */ -/** Type of conf register - * ECDSA configure register +/** + * @brief Compatible ecdsa struct wrapper + * */ typedef union { - struct { - /** work_mode : R/W; bitpos: [0]; default: 0; - * The work mode bits of ECDSA Accelerator. 0: Signature Verify Mode. 1: Signature - * Generate Mode. - */ - uint32_t work_mode:1; - /** ecc_curve : R/W; bitpos: [1]; default: 0; - * The ecc curve select bit of ECDSA Accelerator. 0: P-192. 1: P-256. - */ - uint32_t ecc_curve:1; - /** software_set_k : R/W; bitpos: [2]; default: 0; - * The source of k select bit. 0: k is automatically generated by TRNG. 1: k is - * written by software. - */ - uint32_t software_set_k:1; - /** software_set_z : R/W; bitpos: [3]; default: 0; - * The source of z select bit. 0: z is generated from SHA result. 1: z is written by - * software. - */ - uint32_t software_set_z:1; - uint32_t reserved_4:28; - }; - uint32_t val; -} ecdsa_conf_reg_t; - -/** Type of start register - * ECDSA start register - */ -typedef union { - struct { - /** start : WT; bitpos: [0]; default: 0; - * Write 1 to start caculation of ECDSA Accelerator. This bit will be self-cleared - * after configuration. - */ - uint32_t start:1; - /** load_done : WT; bitpos: [1]; default: 0; - * Write 1 to input load done signal of ECDSA Accelerator. This bit will be - * self-cleared after configuration. - */ - uint32_t load_done:1; - /** get_done : WT; bitpos: [2]; default: 0; - * Write 1 to input get done signal of ECDSA Accelerator. This bit will be - * self-cleared after configuration. - */ - uint32_t get_done:1; - uint32_t reserved_3:29; - }; - uint32_t val; -} ecdsa_start_reg_t; - - -/** Group: Clock and reset registers */ -/** Type of clk register - * ECDSA clock gate register - */ -typedef union { - struct { - /** clk_gate_force_on : R/W; bitpos: [0]; default: 0; - * Write 1 to force on register clock gate. - */ - uint32_t clk_gate_force_on:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} ecdsa_clk_reg_t; - - -/** Group: Interrupt registers */ -/** Type of int_raw register - * ECDSA interrupt raw register, valid in level. - */ -typedef union { - struct { - /** calc_done_int_raw : RO/WTC/SS; bitpos: [0]; default: 0; - * The raw interrupt status bit for the ecdsa_calc_done_int interrupt - */ - uint32_t calc_done_int_raw:1; - /** sha_release_int_raw : RO/WTC/SS; bitpos: [1]; default: 0; - * The raw interrupt status bit for the ecdsa_sha_release_int interrupt - */ - uint32_t sha_release_int_raw:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} ecdsa_int_raw_reg_t; - -/** Type of int_st register - * ECDSA interrupt status register. - */ -typedef union { - struct { - /** calc_done_int_st : RO; bitpos: [0]; default: 0; - * The masked interrupt status bit for the ecdsa_calc_done_int interrupt - */ - uint32_t calc_done_int_st:1; - /** sha_release_int_st : RO; bitpos: [1]; default: 0; - * The masked interrupt status bit for the ecdsa_sha_release_int interrupt - */ - uint32_t sha_release_int_st:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} ecdsa_int_st_reg_t; - -/** Type of int_ena register - * ECDSA interrupt enable register. - */ -typedef union { - struct { - /** calc_done_int_ena : R/W; bitpos: [0]; default: 0; - * The interrupt enable bit for the ecdsa_calc_done_int interrupt - */ - uint32_t calc_done_int_ena:1; - /** sha_release_int_ena : R/W; bitpos: [1]; default: 0; - * The interrupt enable bit for the ecdsa_sha_release_int interrupt - */ - uint32_t sha_release_int_ena:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} ecdsa_int_ena_reg_t; - -/** Type of int_clr register - * ECDSA interrupt clear register. - */ -typedef union { - struct { - /** calc_done_int_clr : WT; bitpos: [0]; default: 0; - * Set this bit to clear the ecdsa_calc_done_int interrupt - */ - uint32_t calc_done_int_clr:1; - /** sha_release_int_clr : WT; bitpos: [1]; default: 0; - * Set this bit to clear the ecdsa_sha_release_int interrupt - */ - uint32_t sha_release_int_clr:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} ecdsa_int_clr_reg_t; - - -/** Group: Status registers */ -/** Type of state register - * ECDSA status register - */ -typedef union { - struct { - /** busy : RO; bitpos: [1:0]; default: 0; - * The status bits of ECDSA Accelerator. ECDSA is at 0: IDLE, 1: LOAD, 2: GET, 3: BUSY - * state. - */ - uint32_t busy:2; - uint32_t reserved_2:30; - }; - uint32_t val; -} ecdsa_state_reg_t; - - -/** Group: Result registers */ -/** Type of result register - * ECDSA result register - */ -typedef union { - struct { - /** operation_result : RO/SS; bitpos: [0]; default: 0; - * The operation result bit of ECDSA Accelerator, only valid when ECDSA calculation is - * done. - */ - uint32_t operation_result:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} ecdsa_result_reg_t; - - -/** Group: SHA register */ -/** Type of sha_mode register - * ECDSA control SHA register - */ -typedef union { - struct { - /** sha_mode : R/W; bitpos: [2:0]; default: 0; - * The work mode bits of SHA Calculator in ECDSA Accelerator. 1: SHA-224. 2: SHA-256. - * Others: invalid. - */ - uint32_t sha_mode:3; - uint32_t reserved_3:29; - }; - uint32_t val; -} ecdsa_sha_mode_reg_t; - -/** Type of sha_start register - * ECDSA control SHA register - */ -typedef union { - struct { - /** sha_start : WT; bitpos: [0]; default: 0; - * Write 1 to start the first caculation of SHA Calculator in ECDSA Accelerator. This - * bit will be self-cleared after configuration. - */ - uint32_t sha_start:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} ecdsa_sha_start_reg_t; - -/** Type of sha_continue register - * ECDSA control SHA register - */ -typedef union { - struct { - /** sha_continue : WT; bitpos: [0]; default: 0; - * Write 1 to start the latter caculation of SHA Calculator in ECDSA Accelerator. This - * bit will be self-cleared after configuration. - */ - uint32_t sha_continue:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} ecdsa_sha_continue_reg_t; - -/** Type of sha_busy register - * ECDSA status register - */ -typedef union { - struct { - /** sha_busy : RO; bitpos: [0]; default: 0; - * The busy status bit of SHA Calculator in ECDSA Accelerator. 1:SHA is in - * calculation. 0: SHA is idle. - */ - uint32_t sha_busy:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} ecdsa_sha_busy_reg_t; - - -/** Group: Version register */ -/** Type of date register - * Version control register - */ -typedef union { - struct { - /** date : R/W; bitpos: [27:0]; default: 35684752; - * ECDSA version control register - */ - uint32_t date:28; - uint32_t reserved_28:4; - }; - uint32_t val; -} ecdsa_date_reg_t; - - -typedef struct { - uint32_t reserved_000; - volatile ecdsa_conf_reg_t conf; - volatile ecdsa_clk_reg_t clk; - volatile ecdsa_int_raw_reg_t int_raw; - volatile ecdsa_int_st_reg_t int_st; - volatile ecdsa_int_ena_reg_t int_ena; - volatile ecdsa_int_clr_reg_t int_clr; - volatile ecdsa_start_reg_t start; - volatile ecdsa_state_reg_t state; - volatile ecdsa_result_reg_t result; - uint32_t reserved_028[53]; - volatile ecdsa_date_reg_t date; - uint32_t reserved_100[64]; - volatile ecdsa_sha_mode_reg_t sha_mode; - uint32_t reserved_204[3]; - volatile ecdsa_sha_start_reg_t sha_start; - volatile ecdsa_sha_continue_reg_t sha_continue; - volatile ecdsa_sha_busy_reg_t sha_busy; - uint32_t reserved_21c[25]; - volatile uint32_t message[8]; - uint32_t reserved_2a0[472]; - volatile uint32_t r[8]; - volatile uint32_t s[8]; - volatile uint32_t z[8]; - volatile uint32_t qax[8]; - volatile uint32_t qay[8]; + volatile ecdsa_dev_rev_0_0_t rev_0_0; + volatile ecdsa_dev_rev_1_2_t rev_1_2; } ecdsa_dev_t; extern ecdsa_dev_t ECDSA; -#ifndef __cplusplus -_Static_assert(sizeof(ecdsa_dev_t) == 0xaa0, "Invalid size of ecdsa_dev_t structure"); -#endif +/* Note: For ECDSA register on ESP32-H2, you need to use the ECDSA struct through + * ECDSA_REG_GET and ECDSA_REG_SET to access the ECDSA peripheral register and its fields respectively. + * For e.g., ECDSA_REG_SET(ECDSA.clk.clk_gate_force_on, enable) is used to set the register value. + * The ECDSA struct should not be referenced directly. + */ + +/** The ECDSA date version of chip revision 1.2*/ +#define ECDSA_REV1_2_DATE (0x2403120) + +/** + * @brief Set the register value compatibly + * @param reg The register to set + * @param val The value to set + */ +#define ECDSA_REG_SET(reg, val) (ECDSA.rev_1_2.date.ecdsa_date >= ECDSA_REV1_2_DATE ? \ + (ECDSA.rev_1_2.reg = (val)) : (ECDSA.rev_0_0.reg = (val))) + +/** + * @brief Get the register value compatibly + * @param reg The register to get + */ +#define ECDSA_REG_GET(reg) (ECDSA.rev_1_2.date.ecdsa_date >= ECDSA_REV1_2_DATE ? \ + (ECDSA.rev_1_2.reg) : (ECDSA.rev_0_0.reg)) #ifdef __cplusplus } diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index fd7ab31724..55957bc7ce 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -462,7 +462,6 @@ /*------------------------- ECDSA CAPS -------------------------*/ #define SOC_ECDSA_USES_MPI (1) - /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-H2 has 2 UARTs #define SOC_UART_NUM (2) diff --git a/components/soc/esp32h2/ld/esp32h2.peripherals.ld b/components/soc/esp32h2/ld/esp32h2.peripherals.ld index c742ca9925..30d37d8ef2 100644 --- a/components/soc/esp32h2/ld/esp32h2.peripherals.ld +++ b/components/soc/esp32h2/ld/esp32h2.peripherals.ld @@ -40,7 +40,7 @@ PROVIDE ( RSA = 0x6008A000 ); PROVIDE ( ECC = 0x6008B000 ); PROVIDE ( DS = 0x6008C000 ); PROVIDE ( HMAC = 0x6008D000 ); - +PROVIDE ( ECDSA = 0x6008E000 ); PROVIDE ( IO_MUX = 0x60090000 ); PROVIDE ( GPIO = 0x60091000 ); PROVIDE ( GPIO_EXT = 0x60091f00 ); From fdd16ba44f28f7392940a800d9ae25ce21480dc4 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Fri, 17 Jan 2025 17:06:29 +0800 Subject: [PATCH 4/5] refactor(ecdsa): rely on efuse to get chip revision --- components/soc/CMakeLists.txt | 4 --- components/soc/esp32h2/ecdsa_reg_addr.c | 28 ------------------- components/soc/esp32h2/include/soc/chip_rev.h | 13 +++++++++ .../soc/esp32h2/include/soc/ecdsa_reg.h | 13 +++++---- 4 files changed, 20 insertions(+), 38 deletions(-) delete mode 100644 components/soc/esp32h2/ecdsa_reg_addr.c create mode 100644 components/soc/esp32h2/include/soc/chip_rev.h diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index a5dff6c617..46212a3229 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -19,10 +19,6 @@ if(target STREQUAL "esp32") list(APPEND srcs "${target}/dport_access.c") endif() -if(target STREQUAL "esp32h2") - list(APPEND srcs "${target_folder}/ecdsa_reg_addr.c") -endif() - if(CONFIG_SOC_ADC_SUPPORTED) list(APPEND srcs "${target}/adc_periph.c") endif() diff --git a/components/soc/esp32h2/ecdsa_reg_addr.c b/components/soc/esp32h2/ecdsa_reg_addr.c deleted file mode 100644 index eb5ed02960..0000000000 --- a/components/soc/esp32h2/ecdsa_reg_addr.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -// This file initialises the memory register addresses for the ECDSA accelerator -// This software initialization is required due to incompatibility between the old and new ECDSA versions -// for the ESP32-H2 ECDSA accelerator -#include -#include "soc/ecdsa_reg.h" - -// Initializing the memory address with the base address of the old ECDSA version -uint32_t ECDSA_R_MEM = (DR_REG_ECDSA_BASE + 0xA00); -uint32_t ECDSA_S_MEM = (DR_REG_ECDSA_BASE + 0xA20); -uint32_t ECDSA_Z_MEM = (DR_REG_ECDSA_BASE + 0xA40); -uint32_t ECDSA_QAX_MEM = (DR_REG_ECDSA_BASE + 0xA60); -uint32_t ECDSA_QAY_MEM = (DR_REG_ECDSA_BASE + 0xA80); - -void ecdsa_compatible_mem_reg_addr_init(void) -{ - // set the memory registers based on the DATE register value - ECDSA_R_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA00, 0x340)); - ECDSA_S_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA20, 0x360)); - ECDSA_Z_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA40, 0x380)); - ECDSA_QAX_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA60, 0x3A0)); - ECDSA_QAY_MEM = (DR_REG_ECDSA_BASE + ECDSA_REG_GET_OFFSET(0xA80, 0x3C0)); -} diff --git a/components/soc/esp32h2/include/soc/chip_rev.h b/components/soc/esp32h2/include/soc/chip_rev.h new file mode 100644 index 0000000000..87da4a43c0 --- /dev/null +++ b/components/soc/esp32h2/include/soc/chip_rev.h @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "soc/efuse_struct.h" + +#define ESP_SOC_GET_CHIP_REV (EFUSE.rd_mac_sys_3.wafer_version_major * 100 + EFUSE.rd_mac_sys_3.wafer_version_minor) + +#define REG_COMPATIBLE_ADDR(rev, before_addr, after_addr) ((ESP_SOC_GET_CHIP_REV >= (rev)) ? (after_addr) : (before_addr)) diff --git a/components/soc/esp32h2/include/soc/ecdsa_reg.h b/components/soc/esp32h2/include/soc/ecdsa_reg.h index 854cca0a46..c98c16e8ee 100644 --- a/components/soc/esp32h2/include/soc/ecdsa_reg.h +++ b/components/soc/esp32h2/include/soc/ecdsa_reg.h @@ -7,6 +7,8 @@ #include #include "soc/soc.h" +#include "soc/chip_rev.h" + #ifdef __cplusplus extern "C" { #endif @@ -447,34 +449,33 @@ extern "C" { /** ECDSA_R_MEM register * The memory that stores r. */ -extern uint32_t ECDSA_R_MEM; +#define ECDSA_R_MEM (DR_REG_ECDSA_BASE + REG_COMPATIBLE_ADDR(102, 0xa00, 0x340)) #define ECDSA_R_MEM_SIZE_BYTES 32 /** ECDSA_S_MEM register * The memory that stores s. */ -extern uint32_t ECDSA_S_MEM; +#define ECDSA_S_MEM (DR_REG_ECDSA_BASE + REG_COMPATIBLE_ADDR(102, 0xa20, 0x360)) #define ECDSA_S_MEM_SIZE_BYTES 32 /** ECDSA_Z_MEM register * The memory that stores software written z. */ -extern uint32_t ECDSA_Z_MEM; +#define ECDSA_Z_MEM (DR_REG_ECDSA_BASE + REG_COMPATIBLE_ADDR(102, 0xa40, 0x380)) #define ECDSA_Z_MEM_SIZE_BYTES 32 /** ECDSA_QAX_MEM register * The memory that stores x coordinates of QA or software written k. */ -extern uint32_t ECDSA_QAX_MEM; +#define ECDSA_QAX_MEM (DR_REG_ECDSA_BASE + REG_COMPATIBLE_ADDR(102, 0xa60, 0x3a0)) #define ECDSA_QAX_MEM_SIZE_BYTES 32 /** ECDSA_QAY_MEM register * The memory that stores y coordinates of QA. */ -extern uint32_t ECDSA_QAY_MEM; +#define ECDSA_QAY_MEM (DR_REG_ECDSA_BASE + REG_COMPATIBLE_ADDR(102, 0xa80, 0x3c0)) #define ECDSA_QAY_MEM_SIZE_BYTES 32 - #ifdef __cplusplus } #endif From 390a6a071974f9b29bc1e2a6652c7a056ea8b8af Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Wed, 15 Jan 2025 12:15:44 +0530 Subject: [PATCH 5/5] feat(docs): Update minimizing binary size The ESP32-H2 software countermeasure may not be necessary for ESP32-H2 v1.2 and above, this commit updates the relevant documentation --- components/hal/Kconfig | 2 ++ components/mbedtls/Kconfig | 4 ++- docs/en/api-guides/performance/size.rst | 37 +++++++++++++------------ 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/components/hal/Kconfig b/components/hal/Kconfig index dcd91df039..2c8e44d657 100644 --- a/components/hal/Kconfig +++ b/components/hal/Kconfig @@ -111,5 +111,7 @@ menu "Hardware Abstraction Layer (HAL) and Low Level (LL)" Enable this option to apply the countermeasure for ECDSA signature operation This countermeasure masks the real ECDSA sign operation under dummy sign operations to add randomness in the generated power signature. + This countermeasure is only necessary for ESP32-H2 < v1.2. + endmenu diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index f376e351d9..fed9a21960 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -555,13 +555,14 @@ menu "mbedTLS" select HAL_ECDSA_GEN_SIG_CM default y help - The ECDSA peripheral before ECO5 does not offer constant time ECDSA sign operation. + The ECDSA peripheral before ESP32-H2 v1.2 does not offer constant time ECDSA sign operation. This time can be observed through power profiling of the device, making the ECDSA private key vulnerable to side-channel timing attacks. This countermeasure masks the real ECDSA sign operation under dummy sign operations to add randomness in the generated power signature. It is highly recommended to also enable Secure Boot for the device in addition to this countermeasure so that only trusted software can execute on the device. + This countermeasure can be safely disabled for ESP32-H2 v1.2 and above. config MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM bool "Make ECDSA signature operation pseudo constant time for software" @@ -574,6 +575,7 @@ menu "mbedTLS" of an arbitrary message. The signature time would appear to be constant to the external entity after enabling this option. + This countermeasure can be safely disabled for ESP32-H2 v1.2 and above. endmenu diff --git a/docs/en/api-guides/performance/size.rst b/docs/en/api-guides/performance/size.rst index 6b499af0f9..460da4867d 100644 --- a/docs/en/api-guides/performance/size.rst +++ b/docs/en/api-guides/performance/size.rst @@ -401,23 +401,26 @@ Under *Component Config* -> *mbedTLS* there are multiple mbedTLS features which These include: -- :ref:`CONFIG_MBEDTLS_HAVE_TIME` -- :ref:`CONFIG_MBEDTLS_ECDSA_DETERMINISTIC` -- :ref:`CONFIG_MBEDTLS_SHA512_C` -- :ref:`CONFIG_MBEDTLS_SHA3_C` -- :ref:`CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS` -- :ref:`CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS` -- :ref:`CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION` -- :ref:`CONFIG_MBEDTLS_SSL_ALPN` -- :ref:`CONFIG_MBEDTLS_SSL_RENEGOTIATION` -- :ref:`CONFIG_MBEDTLS_CCM_C` -- :ref:`CONFIG_MBEDTLS_GCM_C` -- :ref:`CONFIG_MBEDTLS_ECP_C` (Alternatively: Leave this option enabled but disable some of the elliptic curves listed in the sub-menu.) -- :ref:`CONFIG_MBEDTLS_ECP_NIST_OPTIM` -- :ref:`CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM` -- Change :ref:`CONFIG_MBEDTLS_TLS_MODE` if both server & client functionalities are not needed -- Consider disabling some ciphersuites listed in the "TLS Key Exchange Methods" sub-menu (i.e. :ref:`CONFIG_MBEDTLS_KEY_EXCHANGE_RSA`) -- Consider disabling :ref:`CONFIG_MBEDTLS_ERROR_STRINGS` if the application is pulling in mbedTLS error strings because of :cpp:func:`mbedtls_strerror` usage +.. list:: + + - :ref:`CONFIG_MBEDTLS_HAVE_TIME` + - :ref:`CONFIG_MBEDTLS_ECDSA_DETERMINISTIC` + - :ref:`CONFIG_MBEDTLS_SHA512_C` + - :ref:`CONFIG_MBEDTLS_SHA3_C` + - :ref:`CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS` + - :ref:`CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS` + - :ref:`CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION` + - :ref:`CONFIG_MBEDTLS_SSL_ALPN` + - :ref:`CONFIG_MBEDTLS_SSL_RENEGOTIATION` + - :ref:`CONFIG_MBEDTLS_CCM_C` + - :ref:`CONFIG_MBEDTLS_GCM_C` + - :ref:`CONFIG_MBEDTLS_ECP_C` (Alternatively: Leave this option enabled but disable some of the elliptic curves listed in the sub-menu.) + - :ref:`CONFIG_MBEDTLS_ECP_NIST_OPTIM` + - :ref:`CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM` + - Change :ref:`CONFIG_MBEDTLS_TLS_MODE` if both server & client functionalities are not needed. + - Consider disabling some cipher suites listed in the ``TLS Key Exchange Methods`` sub-menu (i.e., :ref:`CONFIG_MBEDTLS_KEY_EXCHANGE_RSA`). + - Consider disabling :ref:`CONFIG_MBEDTLS_ERROR_STRINGS` if the application is already pulling in mbedTLS error strings through using :cpp:func:`mbedtls_strerror`. + :esp32h2: - For {IDF_TARGET_NAME} v1.2 and above, consider disabling :ref:`CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_MASKING_CM` and :ref:`CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN_CONSTANT_TIME_CM` as the software countermeasures for the ECDSA sign operation are not required. The help text for each option has some more information.