Kaynağa Gözat

esp32c6: Add support for ECC peripheral

Sachin Parekh 3 yıl önce
ebeveyn
işleme
69c8df5e49

+ 8 - 0
components/hal/esp32c6/include/hal/clk_gate_ll.h

@@ -60,6 +60,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
             return PCR_AES_CLK_EN;
         case PERIPH_SHA_MODULE:
             return PCR_SHA_CLK_EN;
+        case PERIPH_ECC_MODULE:
+            return PCR_ECC_CLK_EN;
         case PERIPH_RSA_MODULE:
             return PCR_RSA_CLK_EN;
         case PERIPH_HMAC_MODULE:
@@ -124,6 +126,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
             return PCR_GDMA_RST_EN;
         case PERIPH_MCPWM0_MODULE:
             return PCR_PWM_RST_EN;
+        case PERIPH_ECC_MODULE:
+            return PCR_ECC_RST_EN;
         case PERIPH_AES_MODULE:
         if (enable == true) {
             // Clear reset on digital signature, otherwise AES unit is held in reset also.
@@ -220,6 +224,8 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
             return PCR_AES_CONF_REG;
         case PERIPH_SHA_MODULE:
             return PCR_SHA_CONF_REG;
+        case PERIPH_ECC_MODULE:
+            return PCR_ECC_CONF_REG;
         case PERIPH_RSA_MODULE:
             return PCR_RSA_CONF_REG;
         case PERIPH_HMAC_MODULE:
@@ -274,6 +280,8 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
             return PCR_AES_CONF_REG;
         case PERIPH_SHA_MODULE:
             return PCR_SHA_CONF_REG;
+        case PERIPH_ECC_MODULE:
+            return PCR_ECC_CONF_REG;
         case PERIPH_RSA_MODULE:
             return PCR_RSA_CONF_REG;
         case PERIPH_HMAC_MODULE:

+ 147 - 0
components/hal/esp32c6/include/hal/ecc_ll.h

@@ -0,0 +1,147 @@
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+#pragma once
+
+#include <stdbool.h>
+#include <string.h>
+#include "hal/assert.h"
+#include "soc/ecc_mult_reg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+    ECC_PARAM_PX = 0x0,
+    ECC_PARAM_PY,
+    ECC_PARAM_K,
+} ecc_ll_param_t;
+
+static inline void ecc_ll_enable_interrupt(void)
+{
+    REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1);
+}
+
+static inline void ecc_ll_disable_interrupt(void)
+{
+    REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 0);
+}
+
+static inline void ecc_ll_clear_interrupt(void)
+{
+    REG_SET_FIELD(ECC_MULT_INT_CLR_REG, ECC_MULT_CALC_DONE_INT_CLR, 1);
+}
+
+static inline void ecc_ll_set_mode(ecc_mode_t mode)
+{
+    switch(mode) {
+        case ECC_MODE_POINT_MUL:
+            REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0);
+            break;
+        case ECC_MODE_INVERSE_MUL:
+            REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 1);
+            break;
+        case ECC_MODE_VERIFY:
+            REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2);
+            break;
+        case ECC_MODE_VERIFY_THEN_POINT_MUL:
+            REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 3);
+            break;
+        default:
+            HAL_ASSERT(false && "Unsupported mode");
+            break;
+    }
+}
+
+static inline void ecc_ll_set_curve(ecc_curve_t curve)
+{
+    switch(curve) {
+        case ECC_CURVE_SECP256R1:
+            REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
+            break;
+        case ECC_CURVE_SECP192R1:
+            REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
+            break;
+        default:
+            HAL_ASSERT(false && "Unsupported curve");
+            return;
+    }
+}
+
+static inline void ecc_ll_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len)
+{
+    uint32_t reg;
+    uint32_t word;
+    switch (param) {
+        case ECC_PARAM_PX:
+            reg = ECC_MULT_PX_MEM;
+            break;
+        case ECC_PARAM_PY:
+            reg = ECC_MULT_PY_MEM;
+            break;
+        case ECC_PARAM_K:
+            reg = ECC_MULT_K_MEM;
+            break;
+        default:
+            HAL_ASSERT(false && "Invalid parameter");
+            return;
+    }
+
+    for (int i = 0; i < len; i += 4) {
+        memcpy(&word, buf + i, 4);
+        REG_WRITE(reg + i, word);
+    }
+}
+
+static inline void ecc_ll_start_calc(void)
+{
+    REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_START);
+}
+
+static inline int ecc_ll_is_calc_finished(void)
+{
+    return REG_GET_FIELD(ECC_MULT_INT_RAW_REG, ECC_MULT_CALC_DONE_INT_RAW);
+}
+
+static inline ecc_mode_t ecc_ll_get_mode(void)
+{
+    return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE);
+}
+
+static inline int ecc_ll_get_verification_result(void)
+{
+    return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_VERIFICATION_RESULT);
+}
+
+static inline ecc_curve_t ecc_ll_get_curve(void)
+{
+    return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
+}
+
+static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len)
+{
+    uint32_t reg;
+    switch (param) {
+        case ECC_PARAM_PX:
+            reg = ECC_MULT_PX_MEM;
+            break;
+        case ECC_PARAM_PY:
+            reg = ECC_MULT_PY_MEM;
+            break;
+        case ECC_PARAM_K:
+            reg = ECC_MULT_K_MEM;
+            break;
+        default:
+            HAL_ASSERT(false && "Invalid parameter");
+            return;
+    }
+
+    memcpy(buf, (void *)reg, len);
+}
+
+#ifdef __cplusplus
+}
+#endif

+ 9 - 0
components/idf_test/include/esp32c6/idf_performance_target.h

@@ -5,3 +5,12 @@
  */
 
 #pragma once
+
+// ECC peripheral output at 160MHz
+#define IDF_PERFORMANCE_MAX_ECP_P192_POINT_MULTIPLY_OP                          5000
+#define IDF_PERFORMANCE_MAX_ECP_P192_POINT_VERIFY_OP                            60
+#define IDF_PERFORMANCE_MAX_ECP_P256_POINT_MULTIPLY_OP                          8400
+#define IDF_PERFORMANCE_MAX_ECP_P256_POINT_VERIFY_OP                            70
+
+#define IDF_PERFORMANCE_MAX_ECDSA_P192_VERIFY_OP                                18000
+#define IDF_PERFORMANCE_MAX_ECDSA_P256_VERIFY_OP                                27000

+ 4 - 0
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -67,6 +67,10 @@ config SOC_SUPPORT_COEXISTENCE
     bool
     default y
 
+config SOC_ECC_SUPPORTED
+    bool
+    default y
+
 config SOC_FLASH_ENC_SUPPORTED
     bool
     default y

+ 1 - 0
components/soc/esp32c6/include/soc/periph_defs.h

@@ -35,6 +35,7 @@ typedef enum {
     PERIPH_RSA_MODULE,
     PERIPH_AES_MODULE,
     PERIPH_SHA_MODULE,
+    PERIPH_ECC_MODULE,
     PERIPH_HMAC_MODULE,
     PERIPH_DS_MODULE,
     PERIPH_GDMA_MODULE,

+ 1 - 0
components/soc/esp32c6/include/soc/soc_caps.h

@@ -53,6 +53,7 @@
 // #define SOC_SHA_SUPPORTED               1 // TODO: IDF-5353
 // #define SOC_HMAC_SUPPORTED              1 // TODO: IDF-5355
 // #define SOC_DIG_SIGN_SUPPORTED          1 // TODO: IDF-5360
+#define SOC_ECC_SUPPORTED               1
 #define SOC_FLASH_ENC_SUPPORTED         1
 #define SOC_SECURE_BOOT_SUPPORTED       1
 // #define SOC_MEMPROT_SUPPORTED           1 // TODO: IDF-5684