diff --git a/components/esp_hw_support/include/esp_private/esp_crypto_lock_internal.h b/components/esp_hw_support/include/esp_private/esp_crypto_lock_internal.h index 2cdf09ff03..178dd48543 100644 --- a/components/esp_hw_support/include/esp_private/esp_crypto_lock_internal.h +++ b/components/esp_hw_support/include/esp_private/esp_crypto_lock_internal.h @@ -15,8 +15,10 @@ extern "C" { #if SOC_RCC_IS_INDEPENDENT #define MPI_RCC_ATOMIC() +#define ECC_RCC_ATOMIC() #else /* !SOC_RCC_IS_INDEPENDENT */ #define MPI_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#define ECC_RCC_ATOMIC() PERIPH_RCC_ATOMIC() #endif /* SOC_RCC_IS_INDEPENDENT */ #ifdef __cplusplus diff --git a/components/hal/esp32c2/include/hal/ecc_ll.h b/components/hal/esp32c2/include/hal/ecc_ll.h index 27b5d87dbb..2fcca34ea0 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-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ #include "hal/assert.h" #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" +#include "soc/system_struct.h" #ifdef __cplusplus extern "C" { @@ -21,6 +22,33 @@ typedef enum { ECC_PARAM_K, } ecc_ll_param_t; +/** + * @brief Enable the bus clock for ECC peripheral module + * + * @param true to enable the module, false to disable the module + */ +static inline void ecc_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en1.crypto_ecc_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define ecc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; ecc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the ECC peripheral module + */ +static inline void ecc_ll_reset_register(void) +{ + SYSTEM.perip_rst_en1.crypto_ecc_rst = 1; + SYSTEM.perip_rst_en1.crypto_ecc_rst = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define ecc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; ecc_ll_reset_register(__VA_ARGS__) + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32c6/include/hal/ecc_ll.h b/components/hal/esp32c6/include/hal/ecc_ll.h index 5a4a2a17ca..c5e8799dcf 100644 --- a/components/hal/esp32c6/include/hal/ecc_ll.h +++ b/components/hal/esp32c6/include/hal/ecc_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,7 @@ #include "hal/assert.h" #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" +#include "soc/pcr_struct.h" #ifdef __cplusplus extern "C" { @@ -21,6 +22,25 @@ typedef enum { ECC_PARAM_K, } ecc_ll_param_t; +/** + * @brief Enable the bus clock for ECC peripheral module + * + * @param true to enable the module, false to disable the module + */ +static inline void ecc_ll_enable_bus_clock(bool enable) +{ + PCR.ecc_conf.ecc_clk_en = enable; +} + +/** + * @brief Reset the ECC peripheral module + */ +static inline void ecc_ll_reset_register(void) +{ + PCR.ecc_conf.ecc_rst_en = 1; + PCR.ecc_conf.ecc_rst_en = 0; +} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32h2/include/hal/ecc_ll.h b/components/hal/esp32h2/include/hal/ecc_ll.h index d3ddd45924..47d4e8b9e6 100644 --- a/components/hal/esp32h2/include/hal/ecc_ll.h +++ b/components/hal/esp32h2/include/hal/ecc_ll.h @@ -10,6 +10,7 @@ #include "hal/assert.h" #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" +#include "soc/pcr_struct.h" #ifdef __cplusplus extern "C" { @@ -24,6 +25,28 @@ typedef enum { ECC_PARAM_QZ, } ecc_ll_param_t; +/** + * @brief Enable the bus clock for ECC peripheral module + * + * @param true to enable the module, false to disable the module + */ +static inline void ecc_ll_enable_bus_clock(bool enable) +{ + PCR.ecc_conf.ecc_clk_en = enable; +} + +/** + * @brief Reset the ECC peripheral module + */ +static inline void ecc_ll_reset_register(void) +{ + PCR.ecc_conf.ecc_rst_en = 1; + PCR.ecc_conf.ecc_rst_en = 0; + + // Clear reset on ECDSA, otherwise ECC is held in reset + PCR.ecdsa_conf.ecdsa_rst_en = 0; +} + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/esp32p4/include/hal/ecc_ll.h b/components/hal/esp32p4/include/hal/ecc_ll.h index d3ddd45924..be25321fe4 100644 --- a/components/hal/esp32p4/include/hal/ecc_ll.h +++ b/components/hal/esp32p4/include/hal/ecc_ll.h @@ -10,6 +10,7 @@ #include "hal/assert.h" #include "hal/ecc_types.h" #include "soc/ecc_mult_reg.h" +#include "soc/hp_sys_clkrst_struct.h" #ifdef __cplusplus extern "C" { @@ -24,6 +25,38 @@ typedef enum { ECC_PARAM_QZ, } ecc_ll_param_t; +/** + * @brief Enable the bus clock for ECC peripheral module + * + * @param true to enable the module, false to disable the module + */ +static inline void ecc_ll_enable_bus_clock(bool enable) +{ + HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_ecc_clk_en = enable; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define ecc_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; ecc_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the ECC peripheral module + */ +static inline void ecc_ll_reset_register(void) +{ + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecc = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecc = 0; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0; + + // Clear reset on ECDSA, otherwise ECC is held in reset + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecdsa = 0; +} + +/// use a macro to wrap the function, force the caller to use it in a critical section +/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance +#define ecc_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; ecc_ll_reset_register(__VA_ARGS__) + static inline void ecc_ll_enable_interrupt(void) { REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1); diff --git a/components/hal/test_apps/crypto/main/ecc/test_ecc.c b/components/hal/test_apps/crypto/main/ecc/test_ecc.c index 605bd77e50..a6bc8c3fdc 100644 --- a/components/hal/test_apps/crypto/main/ecc/test_ecc.c +++ b/components/hal/test_apps/crypto/main/ecc/test_ecc.c @@ -8,11 +8,12 @@ #include #include #include "sdkconfig.h" +#include "esp_private/esp_crypto_lock_internal.h" #include "esp_log.h" #include "ecc_params.h" #include "soc/soc_caps.h" #include "hal/ecc_hal.h" -#include "hal/clk_gate_ll.h" +#include "hal/ecc_ll.h" #include "memory_checks.h" #include "unity_fixture.h" @@ -43,7 +44,17 @@ static void ecc_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len static void ecc_enable_and_reset(void) { - periph_ll_enable_clk_clear_rst(PERIPH_ECC_MODULE); + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(true); + ecc_ll_reset_register(); + } +} + +static void ecc_disable(void) +{ + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(false); + } } @@ -80,6 +91,7 @@ static void ecc_point_mul(const uint8_t *k_le, const uint8_t *x_le, const uint8_ } ecc_hal_read_mul_result(res_x_le, res_y_le, len); + ecc_disable(); } static void test_ecc_point_mul_inner(bool verify_first) @@ -161,7 +173,10 @@ static int ecc_point_verify(const uint8_t *x_le, const uint8_t *y_le, uint8_t le ; } - return ecc_hal_read_verify_result(); + int ret = ecc_hal_read_verify_result(); + ecc_disable(); + + return ret; } TEST(ecc, ecc_point_verification_on_SECP192R1_and_SECP256R1) @@ -222,6 +237,7 @@ static void ecc_point_inv_mul(const uint8_t *num_le, const uint8_t *deno_le, uin } ecc_hal_read_mul_result(zero, res_le, len); + ecc_disable(); } TEST(ecc, ecc_inverse_multiplication_or_mod_division_using_SECP192R1_and_SECP256R1_order_of_curve) @@ -254,6 +270,7 @@ static void ecc_jacob_mul(uint8_t *k_le, uint8_t *x_le, uint8_t *y_le, uint8_t l } ecc_hal_read_jacob_mul_result(res_x_le, res_y_le, res_z_le, len); + ecc_disable(); } static void test_ecc_jacob_mul_inner(bool verify_first) @@ -314,7 +331,10 @@ static int ecc_jacob_verify(const uint8_t *x_le, const uint8_t *y_le, const uint ; } - return ecc_hal_read_verify_result(); + int ret = ecc_hal_read_verify_result(); + ecc_disable(); + + return ret; } TEST(ecc, ecc_jacobian_point_verification_on_SECP192R1_and_SECP256R1) @@ -355,6 +375,7 @@ static void ecc_point_addition(uint8_t *px_le, uint8_t *py_le, uint8_t *qx_le, u } ecc_hal_read_point_add_result(x_res_le, y_res_le, z_res_le, len, jacob_output); + ecc_disable(); } TEST(ecc, ecc_point_addition_on_SECP192R1_and_SECP256R1) @@ -426,6 +447,7 @@ static void ecc_mod_op(ecc_mode_t mode, const uint8_t *a, const uint8_t *b, uint } ecc_hal_read_mod_op_result(res_le, len); + ecc_disable(); } #endif diff --git a/components/mbedtls/port/ecc/esp_ecc.c b/components/mbedtls/port/ecc/esp_ecc.c index 939f0070ff..b9fe0a8871 100644 --- a/components/mbedtls/port/ecc/esp_ecc.c +++ b/components/mbedtls/port/ecc/esp_ecc.c @@ -8,20 +8,26 @@ #include #include "esp_crypto_lock.h" -#include "esp_private/periph_ctrl.h" +#include "esp_private/esp_crypto_lock_internal.h" #include "ecc_impl.h" #include "hal/ecc_hal.h" +#include "hal/ecc_ll.h" static void esp_ecc_acquire_hardware(void) { esp_crypto_ecc_lock_acquire(); - periph_module_enable(PERIPH_ECC_MODULE); + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(true); + ecc_ll_reset_register(); + } } static void esp_ecc_release_hardware(void) { - periph_module_disable(PERIPH_ECC_MODULE); + ECC_RCC_ATOMIC() { + ecc_ll_enable_bus_clock(false); + } esp_crypto_ecc_lock_release(); }