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 new file mode 100644 index 0000000000..2cdf09ff03 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/esp_crypto_lock_internal.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_private/periph_ctrl.h" +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_RCC_IS_INDEPENDENT +#define MPI_RCC_ATOMIC() +#else /* !SOC_RCC_IS_INDEPENDENT */ +#define MPI_RCC_ATOMIC() PERIPH_RCC_ATOMIC() +#endif /* SOC_RCC_IS_INDEPENDENT */ + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32/include/hal/mpi_ll.h b/components/hal/esp32/include/hal/mpi_ll.h index 921f38feeb..265527dfb6 100644 --- a/components/hal/esp32/include/hal/mpi_ll.h +++ b/components/hal/esp32/include/hal/mpi_ll.h @@ -19,6 +19,40 @@ extern "C" { #endif +/** + * @brief Enable the bus clock for MPI peripheral module + * + * @param enable true to enable the module, false to disable the module + */ +static inline void mpi_ll_enable_bus_clock(bool enable) +{ + if (enable) { + DPORT_SET_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA); + } else { + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA); + } +} + +/// 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 mpi_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the MPI peripheral module + */ +static inline void mpi_ll_reset_register(void) +{ + DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA); + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA); + + // Clear reset on digital signature also, otherwise RSA is held in reset + DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_DIGITAL_SIGNATURE); +} + +/// 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 mpi_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_reset_register(__VA_ARGS__) + /* Round up number of words to nearest 512 bit (16 word) block count. */ diff --git a/components/hal/esp32c3/include/hal/mpi_ll.h b/components/hal/esp32c3/include/hal/mpi_ll.h index 6fe5fc2a54..ea009559ef 100644 --- a/components/hal/esp32c3/include/hal/mpi_ll.h +++ b/components/hal/esp32c3/include/hal/mpi_ll.h @@ -12,6 +12,7 @@ #include "hal/mpi_types.h" #include "soc/hwcrypto_periph.h" #include "soc/system_reg.h" +#include "soc/system_struct.h" #include "soc/mpi_periph.h" #ifdef __cplusplus @@ -19,6 +20,36 @@ extern "C" { #endif +/** + * @brief Enable the bus clock for MPI peripheral module + * + * @param enable true to enable the module, false to disable the module + */ +static inline void mpi_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en1.reg_crypto_rsa_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 mpi_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the MPI peripheral module + */ +static inline void mpi_ll_reset_register(void) +{ + SYSTEM.perip_rst_en1.reg_crypto_rsa_rst = 1; + SYSTEM.perip_rst_en1.reg_crypto_rsa_rst = 0; + + // Clear reset on digital signature also, otherwise RSA is held in reset + SYSTEM.perip_rst_en1.reg_crypto_ds_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 mpi_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_reset_register(__VA_ARGS__) + static inline size_t mpi_ll_calculate_hardware_words(size_t words) { return words; diff --git a/components/hal/esp32c6/include/hal/mpi_ll.h b/components/hal/esp32c6/include/hal/mpi_ll.h index 07b2e8ad0f..032ac17b47 100644 --- a/components/hal/esp32c6/include/hal/mpi_ll.h +++ b/components/hal/esp32c6/include/hal/mpi_ll.h @@ -11,6 +11,7 @@ #include "hal/assert.h" #include "hal/mpi_types.h" #include "soc/pcr_reg.h" +#include "soc/pcr_struct.h" #include "soc/rsa_reg.h" #include "soc/mpi_periph.h" @@ -19,6 +20,28 @@ extern "C" { #endif +/** + * @brief Enable the bus clock for MPI peripheral module + * + * @param enable true to enable the module, false to disable the module + */ +static inline void mpi_ll_enable_bus_clock(bool enable) +{ + PCR.rsa_conf.rsa_clk_en = enable; +} + +/** + * @brief Reset the MPI peripheral module + */ +static inline void mpi_ll_reset_register(void) +{ + PCR.rsa_conf.rsa_rst_en = 1; + PCR.rsa_conf.rsa_rst_en = 0; + + // Clear reset on digital signature also, otherwise RSA is held in reset + PCR.ds_conf.ds_rst_en = 0; +} + static inline size_t mpi_ll_calculate_hardware_words(size_t words) { return words; diff --git a/components/hal/esp32h2/include/hal/mpi_ll.h b/components/hal/esp32h2/include/hal/mpi_ll.h index 9e57434486..0eed1020d9 100644 --- a/components/hal/esp32h2/include/hal/mpi_ll.h +++ b/components/hal/esp32h2/include/hal/mpi_ll.h @@ -11,6 +11,7 @@ #include "hal/assert.h" #include "hal/mpi_types.h" #include "soc/pcr_reg.h" +#include "soc/pcr_struct.h" #include "soc/rsa_reg.h" #include "soc/mpi_periph.h" @@ -19,6 +20,29 @@ extern "C" { #endif +/** + * @brief Enable the bus clock for MPI peripheral module + * + * @param enable true to enable the module, false to disable the module + */ +static inline void mpi_ll_enable_bus_clock(bool enable) +{ + PCR.rsa_conf.rsa_clk_en = enable; +} + +/** + * @brief Reset the MPI peripheral module + */ +static inline void mpi_ll_reset_register(void) +{ + PCR.rsa_conf.rsa_rst_en = 1; + PCR.rsa_conf.rsa_rst_en = 0; + + // Clear reset on digital signature also, otherwise RSA is held in reset + PCR.ds_conf.ds_rst_en = 0; + PCR.ecdsa_conf.ecdsa_rst_en = 0; +} + static inline size_t mpi_ll_calculate_hardware_words(size_t words) { return words; diff --git a/components/hal/esp32p4/include/hal/mpi_ll.h b/components/hal/esp32p4/include/hal/mpi_ll.h index f2421660da..00360a8ddc 100644 --- a/components/hal/esp32p4/include/hal/mpi_ll.h +++ b/components/hal/esp32p4/include/hal/mpi_ll.h @@ -10,13 +10,46 @@ #include #include "hal/assert.h" #include "hal/mpi_types.h" -#include "soc/rsa_reg.h" +#include "soc/hp_sys_clkrst_struct.h" #include "soc/mpi_periph.h" +#include "soc/rsa_reg.h" #ifdef __cplusplus extern "C" { #endif +/** + * @brief Enable the bus clock for MPI peripheral module + * + * @param enable true to enable the module, false to disable the module + */ +static inline void mpi_ll_enable_bus_clock(bool enable) +{ + HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_rsa_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 mpi_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the MPI peripheral module + */ +static inline void mpi_ll_reset_register(void) +{ + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_rsa = 1; + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_rsa = 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 digital signature and ECDSA, otherwise RSA is held in reset + HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ds = 0; + 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 mpi_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_reset_register(__VA_ARGS__) static inline size_t mpi_ll_calculate_hardware_words(size_t words) { diff --git a/components/hal/esp32s2/include/hal/mpi_ll.h b/components/hal/esp32s2/include/hal/mpi_ll.h index 9f9ff1d02e..a85ee4561d 100644 --- a/components/hal/esp32s2/include/hal/mpi_ll.h +++ b/components/hal/esp32s2/include/hal/mpi_ll.h @@ -19,6 +19,40 @@ extern "C" { #endif +/** + * @brief Enable the bus clock for MPI peripheral module + * + * @param enable true to enable the module, false to disable the module + */ +static inline void mpi_ll_enable_bus_clock(bool enable) +{ + if (enable) { + SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_RSA_CLK_EN); + } else { + CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN1_REG, DPORT_CRYPTO_RSA_CLK_EN); + } +} + +/// 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 mpi_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the MPI peripheral module + */ +static inline void mpi_ll_reset_register(void) +{ + SET_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_RSA_RST); + CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_RSA_RST); + + // Clear reset on digital signature also, otherwise RSA is held in reset + CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN1_REG, DPORT_CRYPTO_DS_RST); +} + +/// 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 mpi_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_reset_register(__VA_ARGS__) + static inline size_t mpi_ll_calculate_hardware_words(size_t words) { return words; diff --git a/components/hal/esp32s3/include/hal/mpi_ll.h b/components/hal/esp32s3/include/hal/mpi_ll.h index 11592ec639..a79da6f7c2 100644 --- a/components/hal/esp32s3/include/hal/mpi_ll.h +++ b/components/hal/esp32s3/include/hal/mpi_ll.h @@ -13,12 +13,43 @@ #include "soc/hwcrypto_periph.h" #include "soc/dport_reg.h" #include "soc/mpi_periph.h" +#include "soc/system_struct.h" #ifdef __cplusplus extern "C" { #endif +/** + * @brief Enable the bus clock for MPI peripheral module + * + * @param enable true to enable the module, false to disable the module + */ +static inline void mpi_ll_enable_bus_clock(bool enable) +{ + SYSTEM.perip_clk_en1.crypto_rsa_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 mpi_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_enable_bus_clock(__VA_ARGS__) + +/** + * @brief Reset the MPI peripheral module + */ +static inline void mpi_ll_reset_register(void) +{ + SYSTEM.perip_rst_en1.crypto_rsa_rst = 1; + SYSTEM.perip_rst_en1.crypto_rsa_rst = 0; + + // Clear reset on digital signature also, otherwise RSA is held in reset + SYSTEM.perip_rst_en1.crypto_ds_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 mpi_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; mpi_ll_reset_register(__VA_ARGS__) + static inline size_t mpi_ll_calculate_hardware_words(size_t words) { return words; diff --git a/components/hal/test_apps/crypto/main/mpi/test_mpi.c b/components/hal/test_apps/crypto/main/mpi/test_mpi.c index 8e1969b13b..029abe5343 100644 --- a/components/hal/test_apps/crypto/main/mpi/test_mpi.c +++ b/components/hal/test_apps/crypto/main/mpi/test_mpi.c @@ -6,8 +6,8 @@ #include #include +#include "esp_private/esp_crypto_lock_internal.h" #include "esp_log.h" -#include "esp_private/periph_ctrl.h" #include "esp_heap_caps.h" #include "memory_checks.h" #include "unity_fixture.h" @@ -17,15 +17,18 @@ #endif #include "hal/mpi_hal.h" +#include "hal/mpi_ll.h" #include "mpi_params.h" #define _DEBUG_ 0 - static void esp_mpi_enable_hardware_hw_op( void ) { /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); + MPI_RCC_ATOMIC() { + mpi_ll_enable_bus_clock(true); + mpi_ll_reset_register(); + } mpi_hal_enable_hardware_hw_op(); } @@ -36,7 +39,9 @@ static void esp_mpi_disable_hardware_hw_op( void ) mpi_hal_disable_hardware_hw_op(); /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); + MPI_RCC_ATOMIC() { + mpi_ll_enable_bus_clock(false); + } } diff --git a/components/mbedtls/port/bignum/bignum_alt.c b/components/mbedtls/port/bignum/bignum_alt.c index f8ae1a1605..e7dbc254de 100644 --- a/components/mbedtls/port/bignum/bignum_alt.c +++ b/components/mbedtls/port/bignum/bignum_alt.c @@ -4,19 +4,22 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "esp_crypto_lock.h" -#include "esp_private/periph_ctrl.h" #include "bignum_impl.h" #include "mbedtls/bignum.h" +#include "esp_private/esp_crypto_lock_internal.h" #include "hal/mpi_hal.h" - +#include "hal/mpi_ll.h" void esp_mpi_enable_hardware_hw_op( void ) { esp_crypto_mpi_lock_acquire(); /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); + MPI_RCC_ATOMIC() { + mpi_ll_enable_bus_clock(true); + mpi_ll_reset_register(); + } mpi_hal_enable_hardware_hw_op(); } @@ -27,7 +30,9 @@ void esp_mpi_disable_hardware_hw_op( void ) mpi_hal_disable_hardware_hw_op(); /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); + MPI_RCC_ATOMIC() { + mpi_ll_enable_bus_clock(false); + } esp_crypto_mpi_lock_release(); }