Просмотр исходного кода

feat(ecc): use RCC atomic block to enable/reset the ECC peripheral

harshal.patil 2 лет назад
Родитель
Сommit
1c6ff8ce9f

+ 2 - 0
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

+ 29 - 1
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);

+ 21 - 1
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);

+ 23 - 0
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);

+ 33 - 0
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);

+ 26 - 4
components/hal/test_apps/crypto/main/ecc/test_ecc.c

@@ -8,11 +8,12 @@
 #include <stdbool.h>
 #include <string.h>
 #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
 

+ 9 - 3
components/mbedtls/port/ecc/esp_ecc.c

@@ -8,20 +8,26 @@
 #include <stdio.h>
 
 #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();
 }