diff --git a/components/driver/include/driver/periph_ctrl.h b/components/driver/include/driver/periph_ctrl.h index b41810090..f93909c1d 100644 --- a/components/driver/include/driver/periph_ctrl.h +++ b/components/driver/include/driver/periph_ctrl.h @@ -53,6 +53,9 @@ typedef enum { PERIPH_WIFI_MODULE, PERIPH_BT_MODULE, PERIPH_WIFI_BT_COMMON_MODULE, + PERIPH_AES_MODULE, + PERIPH_SHA_MODULE, + PERIPH_RSA_MODULE, } periph_module_t; /** diff --git a/components/driver/periph_ctrl.c b/components/driver/periph_ctrl.c index 67431a427..653d2973e 100644 --- a/components/driver/periph_ctrl.c +++ b/components/driver/periph_ctrl.c @@ -23,7 +23,7 @@ static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED; /* Static functions to return register address & mask for clk_en / rst of each peripheral */ static uint32_t get_clk_en_mask(periph_module_t periph); -static uint32_t get_rst_en_mask(periph_module_t periph); +static uint32_t get_rst_en_mask(periph_module_t periph, bool enable); static uint32_t get_clk_en_reg(periph_module_t periph); static uint32_t get_rst_en_reg(periph_module_t periph); @@ -31,7 +31,7 @@ void periph_module_enable(periph_module_t periph) { portENTER_CRITICAL(&periph_spinlock); DPORT_SET_PERI_REG_MASK(get_clk_en_reg(periph), get_clk_en_mask(periph)); - DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph)); + DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, true)); portEXIT_CRITICAL(&periph_spinlock); } @@ -39,15 +39,15 @@ void periph_module_disable(periph_module_t periph) { portENTER_CRITICAL(&periph_spinlock); DPORT_CLEAR_PERI_REG_MASK(get_clk_en_reg(periph), get_clk_en_mask(periph)); - DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph)); + DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, false)); portEXIT_CRITICAL(&periph_spinlock); } void periph_module_reset(periph_module_t periph) { portENTER_CRITICAL(&periph_spinlock); - DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph)); - DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph)); + DPORT_SET_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, false)); + DPORT_CLEAR_PERI_REG_MASK(get_rst_en_reg(periph), get_rst_en_mask(periph, false)); portEXIT_CRITICAL(&periph_spinlock); } @@ -114,12 +114,18 @@ static uint32_t get_clk_en_mask(periph_module_t periph) return DPORT_WIFI_CLK_BT_EN_M; case PERIPH_WIFI_BT_COMMON_MODULE: return DPORT_WIFI_CLK_WIFI_BT_COMMON_M; + case PERIPH_AES_MODULE: + return DPORT_PERI_EN_AES; + case PERIPH_SHA_MODULE: + return DPORT_PERI_EN_SHA; + case PERIPH_RSA_MODULE: + return DPORT_PERI_EN_RSA; default: return 0; } } -static uint32_t get_rst_en_mask(periph_module_t periph) +static uint32_t get_rst_en_mask(periph_module_t periph, bool enable) { switch(periph) { case PERIPH_RMT_MODULE: @@ -174,6 +180,30 @@ static uint32_t get_rst_en_mask(periph_module_t periph) return DPORT_CAN_RST; case PERIPH_EMAC_MODULE: return DPORT_EMAC_RST; + case PERIPH_AES_MODULE: + if (enable == true) { + // Clear reset on digital signature & secure boot units, otherwise AES unit is held in reset also. + return (DPORT_PERI_EN_AES | DPORT_PERI_EN_DIGITAL_SIGNATURE | DPORT_PERI_EN_SECUREBOOT); + } else { + //Don't return other units to reset, as this pulls reset on RSA & SHA units, respectively. + return DPORT_PERI_EN_AES; + } + case PERIPH_SHA_MODULE: + if (enable == true) { + // Clear reset on secure boot, otherwise SHA is held in reset + return (DPORT_PERI_EN_SHA | DPORT_PERI_EN_SECUREBOOT); + } else { + // Don't assert reset on secure boot, otherwise AES is held in reset + return DPORT_PERI_EN_SHA; + } + case PERIPH_RSA_MODULE: + if (enable == true) { + // Also clear reset on digital signature, otherwise RSA is held in reset + return (DPORT_PERI_EN_RSA | DPORT_PERI_EN_DIGITAL_SIGNATURE); + } else { + // Don't reset digital signature unit, as this resets AES also + return DPORT_PERI_EN_RSA; + } case PERIPH_WIFI_MODULE: case PERIPH_BT_MODULE: case PERIPH_WIFI_BT_COMMON_MODULE: @@ -203,12 +233,20 @@ static bool is_wifi_clk_peripheral(periph_module_t periph) static uint32_t get_clk_en_reg(periph_module_t periph) { - return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG : DPORT_PERIP_CLK_EN_REG; + if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) { + return DPORT_PERI_CLK_EN_REG; + } else { + return is_wifi_clk_peripheral(periph) ? DPORT_WIFI_CLK_EN_REG : DPORT_PERIP_CLK_EN_REG; + } } static uint32_t get_rst_en_reg(periph_module_t periph) { - return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG : DPORT_PERIP_RST_EN_REG; + if (periph == PERIPH_AES_MODULE || periph == PERIPH_SHA_MODULE || periph == PERIPH_RSA_MODULE) { + return DPORT_PERI_RST_EN_REG; + } else { + return is_wifi_clk_peripheral(periph) ? DPORT_CORE_RST_EN_REG : DPORT_PERIP_RST_EN_REG; + } } diff --git a/components/esp32/hwcrypto/aes.c b/components/esp32/hwcrypto/aes.c index 125f54337..9bc665e32 100644 --- a/components/esp32/hwcrypto/aes.c +++ b/components/esp32/hwcrypto/aes.c @@ -36,6 +36,7 @@ #include "soc/cpu.h" #include +#include "driver/periph_ctrl.h" /* AES uses a spinlock mux not a lock as the underlying block operation @@ -50,9 +51,9 @@ static portMUX_TYPE aes_spinlock = portMUX_INITIALIZER_UNLOCKED; void esp_aes_acquire_hardware( void ) { - /* newlib locks lazy initialize on ESP-IDF */ portENTER_CRITICAL(&aes_spinlock); +#if defined(DPORT_PROTECT_STALL_OTHER_CPU_USE) DPORT_STALL_OTHER_CPU_START(); { /* Enable AES hardware */ @@ -65,10 +66,15 @@ void esp_aes_acquire_hardware( void ) | DPORT_PERI_EN_SECUREBOOT); } DPORT_STALL_OTHER_CPU_END(); +#else + /* Enable AES hardware */ + periph_module_enable(PERIPH_AES_MODULE); +#endif } void esp_aes_release_hardware( void ) { +#if defined(DPORT_PROTECT_STALL_OTHER_CPU_USE) DPORT_STALL_OTHER_CPU_START(); { /* Disable AES hardware */ @@ -78,7 +84,10 @@ void esp_aes_release_hardware( void ) _DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES); } DPORT_STALL_OTHER_CPU_END(); - +#else + /* Disable AES hardware */ + periph_module_disable(PERIPH_AES_MODULE); +#endif portEXIT_CRITICAL(&aes_spinlock); } diff --git a/components/esp32/hwcrypto/sha.c b/components/esp32/hwcrypto/sha.c index c23580461..1d951023a 100644 --- a/components/esp32/hwcrypto/sha.c +++ b/components/esp32/hwcrypto/sha.c @@ -35,6 +35,7 @@ #include "rom/ets_sys.h" #include "soc/dport_reg.h" #include "soc/hwcrypto_reg.h" +#include "driver/periph_ctrl.h" inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type) { return SHA_1_LOAD_REG + sha_type * 0x10; @@ -159,6 +160,7 @@ static void esp_sha_lock_engine_inner(sha_engine_state *engine) _lock_acquire(&state_change_lock); if (sha_engines_all_idle()) { +#if defined(DPORT_PROTECT_STALL_OTHER_CPU_USE) DPORT_STALL_OTHER_CPU_START(); { /* Enable SHA hardware */ @@ -170,6 +172,11 @@ static void esp_sha_lock_engine_inner(sha_engine_state *engine) ets_sha_enable(); } DPORT_STALL_OTHER_CPU_END(); +#else + /* Enable SHA hardware */ + periph_module_enable(PERIPH_SHA_MODULE); + ets_sha_enable(); +#endif } assert( !engine->in_use && "in_use flag should be cleared" ); @@ -189,6 +196,7 @@ void esp_sha_unlock_engine(esp_sha_type sha_type) engine->in_use = false; if (sha_engines_all_idle()) { +#if defined(DPORT_PROTECT_STALL_OTHER_CPU_USE) /* Disable SHA hardware */ /* Don't assert reset on secure boot, otherwise AES is held in reset */ DPORT_STALL_OTHER_CPU_START(); @@ -197,6 +205,9 @@ void esp_sha_unlock_engine(esp_sha_type sha_type) _DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA); } DPORT_STALL_OTHER_CPU_END(); +#else + periph_module_disable(PERIPH_SHA_MODULE); +#endif } _lock_release(&state_change_lock); diff --git a/components/esp32/include/esp_dport_access.h b/components/esp32/include/esp_dport_access.h index 3acf80688..4d97b496f 100644 --- a/components/esp32/include/esp_dport_access.h +++ b/components/esp32/include/esp_dport_access.h @@ -35,6 +35,7 @@ void esp_dport_access_int_abort(void); #define DPORT_STALL_OTHER_CPU_START() #define DPORT_STALL_OTHER_CPU_END() #else +#define DPORT_PROTECT_STALL_OTHER_CPU_USE #define DPORT_STALL_OTHER_CPU_START() esp_dport_access_stall_other_cpu_start() #define DPORT_STALL_OTHER_CPU_END() esp_dport_access_stall_other_cpu_end() #endif diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index f18652c7b..e6581cbb5 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -40,6 +40,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" +#include "driver/periph_ctrl.h" static const __attribute__((unused)) char *TAG = "bignum"; @@ -75,7 +76,7 @@ void esp_mpi_acquire_hardware( void ) { /* newlib locks lazy initialize on ESP-IDF */ _lock_acquire(&mpi_lock); - +#if defined(DPORT_PROTECT_STALL_OTHER_CPU_USE) DPORT_STALL_OTHER_CPU_START(); { _DPORT_REG_SET_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA); @@ -87,7 +88,10 @@ void esp_mpi_acquire_hardware( void ) _DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); } DPORT_STALL_OTHER_CPU_END(); - +#else + periph_module_enable(PERIPH_RSA_MODULE); + DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); +#endif while(DPORT_REG_READ(RSA_CLEAN_REG) != 1); // Note: from enabling RSA clock to here takes about 1.3us @@ -98,6 +102,7 @@ void esp_mpi_acquire_hardware( void ) void esp_mpi_release_hardware( void ) { +#if defined(DPORT_PROTECT_STALL_OTHER_CPU_USE) DPORT_STALL_OTHER_CPU_START(); { _DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); @@ -107,7 +112,11 @@ void esp_mpi_release_hardware( void ) _DPORT_REG_CLR_BIT(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA); } DPORT_STALL_OTHER_CPU_END(); - +#else + /* Disable RSA hardware */ + DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); + periph_module_disable(PERIPH_RSA_MODULE); +#endif _lock_release(&mpi_lock); }