diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index 1a1f1ce8ae..f7ceba2fa6 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -130,6 +130,9 @@ __attribute__((weak)) void esp_clk_init(void) // Re calculate the ccount to make time calculation correct. esp_cpu_set_cycle_count((uint64_t)esp_cpu_get_cycle_count() * new_freq_mhz / old_freq_mhz); + + // Set crypto clock (`clk_sec`) to use 160M SPLL clock + REG_SET_FIELD(PCR_SEC_CONF_REG, PCR_SEC_CLK_SEL, 0x2); } static void select_rtc_slow_clk(soc_rtc_slow_clk_src_t rtc_slow_clk_src) diff --git a/components/hal/esp32c5/include/hal/mpi_ll.h b/components/hal/esp32c5/include/hal/mpi_ll.h new file mode 100644 index 0000000000..d96317076a --- /dev/null +++ b/components/hal/esp32c5/include/hal/mpi_ll.h @@ -0,0 +1,180 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include +#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" + +#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) +{ + 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; +} + +static inline void mpi_ll_clear_power_control_bit(void) +{ + REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); +} + +static inline void mpi_ll_set_power_control_bit(void) +{ + REG_SET_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); +} + +static inline void mpi_ll_enable_interrupt(void) +{ + REG_WRITE(RSA_INT_ENA_REG, 1); +} + +static inline void mpi_ll_disable_interrupt(void) +{ + REG_WRITE(RSA_INT_ENA_REG, 0); +} + +static inline void mpi_ll_clear_interrupt(void) +{ + REG_WRITE(RSA_INT_CLR_REG, 1); +} + +static inline bool mpi_ll_check_memory_init_complete(void) +{ + return REG_READ(RSA_QUERY_CLEAN_REG) == 0; +} + +static inline void mpi_ll_start_op(mpi_op_t op) +{ + REG_WRITE(MPI_LL_OPERATIONS[op], 1); +} + +static inline bool mpi_ll_get_int_status(void) +{ + return REG_READ(RSA_QUERY_IDLE_REG) == 0; +} + +/* Copy MPI bignum (p) to hardware memory block at 'mem_base'. + + If num_words is higher than the number of words (n) in the bignum then + these additional words will be zeroed in the memory buffer. +*/ +static inline void mpi_ll_write_to_mem_block(mpi_param_t param, size_t offset, const uint32_t* p, size_t n, size_t num_words) +{ + uint32_t mem_base = MPI_LL_BLOCK_BASES[param] + offset; + uint32_t* pbase = (uint32_t*) mem_base; + uint32_t copy_words = MIN(num_words, n); + + /* Copy MPI data to memory block registers */ + for (int i = 0; i < copy_words; i++) { + pbase[i] = p[i]; + } + + /* Zero any remaining memory block data */ + for (int i = copy_words; i < num_words; i++) { + pbase[i] = 0; + } +} + +static inline void mpi_ll_write_m_prime(uint32_t Mprime) +{ + REG_WRITE(RSA_M_PRIME_REG, Mprime); +} + +static inline void mpi_ll_write_rinv(uint32_t rinv) +{ + REG_WRITE(MPI_LL_BLOCK_BASES[MPI_PARAM_Z], rinv); +} + +static inline void mpi_ll_write_at_offset(mpi_param_t param, int offset, uint32_t value) +{ + uint32_t mem_base = MPI_LL_BLOCK_BASES[param] + offset; + REG_WRITE(mem_base, value); +} + +/* Read MPI bignum (p) back from hardware memory block. + + Reads z_words words from block. +*/ +static inline void mpi_ll_read_from_mem_block(uint32_t* p, size_t n, size_t num_words) +{ + uint32_t mem_base = MPI_LL_BLOCK_BASES[MPI_PARAM_Z]; + /* Copy data from memory block registers */ + const size_t REG_WIDTH = sizeof(uint32_t); + for (size_t i = 0; i < num_words; i++) { + p[i] = REG_READ(mem_base + (i * REG_WIDTH)); + } + /* Zero any remaining limbs in the bignum, if the buffer is bigger + than num_words */ + for (size_t i = num_words; i < n; i++) { + p[i] = 0; + } +} + +static inline void mpi_ll_set_mode(size_t length) +{ + REG_WRITE(RSA_MODE_REG, length); +} + +static inline void mpi_ll_disable_constant_time(void) +{ + REG_WRITE(RSA_CONSTANT_TIME_REG, 0); +} + +static inline void mpi_ll_enable_constant_time(void) +{ + REG_WRITE(RSA_CONSTANT_TIME_REG, 1); +} + +static inline void mpi_ll_disable_search(void) +{ + REG_WRITE(RSA_SEARCH_ENABLE_REG, 0); +} + +static inline void mpi_ll_enable_search(void) +{ + REG_WRITE(RSA_SEARCH_ENABLE_REG, 1); +} + +static inline void mpi_ll_set_search_position(size_t pos) +{ + REG_WRITE(RSA_SEARCH_POS_REG, pos); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in index 3193adcca2..9cafd7c754 100644 --- a/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/beta3/include/soc/Kconfig.soc_caps.in @@ -55,6 +55,14 @@ config SOC_SYSTIMER_SUPPORTED bool default y +config SOC_MPI_SUPPORTED + bool + default y + +config SOC_RSA_SUPPORTED + bool + default y + config SOC_ECC_SUPPORTED bool default y @@ -339,6 +347,14 @@ config SOC_RMT_SUPPORT_XTAL bool default y +config SOC_MPI_MEM_BLOCKS_NUM + int + default 4 + +config SOC_MPI_OPERATIONS_NUM + int + default 3 + config SOC_RSA_MAX_BIT_LEN int default 3072 diff --git a/components/soc/esp32c5/beta3/include/soc/soc_caps.h b/components/soc/esp32c5/beta3/include/soc/soc_caps.h index 2e898fcabb..9877fd2457 100644 --- a/components/soc/esp32c5/beta3/include/soc/soc_caps.h +++ b/components/soc/esp32c5/beta3/include/soc/soc_caps.h @@ -46,9 +46,9 @@ #define SOC_I2C_SUPPORTED 1 #define SOC_SYSTIMER_SUPPORTED 1 // TODO: [ESP32C5] IDF-8707 // #define SOC_AES_SUPPORTED 1 // TODO: [ESP32C5] IDF-8627 -// #define SOC_MPI_SUPPORTED 1 +#define SOC_MPI_SUPPORTED 1 // #define SOC_SHA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8624 -// #define SOC_RSA_SUPPORTED 1 // TODO: [ESP32C5] IDF-8620 +#define SOC_RSA_SUPPORTED 1 // #define SOC_HMAC_SUPPORTED 1 // TODO: [ESP32C5] IDF-8616 // #define SOC_DIG_SIGN_SUPPORTED 1 // TODO: [ESP32C5] IDF-8619 #define SOC_ECC_SUPPORTED 1 @@ -341,8 +341,8 @@ // #define SOC_PARLIO_TX_RX_SHARE_INTERRUPT 1 /*!< TX and RX unit share the same interrupt source number */ /*--------------------------- MPI CAPS ---------------------------------------*/ -// #define SOC_MPI_MEM_BLOCKS_NUM (4) -// #define SOC_MPI_OPERATIONS_NUM (3) +#define SOC_MPI_MEM_BLOCKS_NUM (4) +#define SOC_MPI_OPERATIONS_NUM (3) /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (3072) diff --git a/components/soc/esp32c5/beta3/mpi_periph.c b/components/soc/esp32c5/beta3/mpi_periph.c new file mode 100644 index 0000000000..7193e88f64 --- /dev/null +++ b/components/soc/esp32c5/beta3/mpi_periph.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/rsa_reg.h" +#include "soc/mpi_periph.h" + +const uint32_t MPI_LL_BLOCK_BASES[4] = { + RSA_X_MEM, + RSA_Y_MEM, + RSA_Z_MEM, + RSA_M_MEM, +}; + +const uint32_t MPI_LL_OPERATIONS[3] = { + RSA_SET_START_MULT_REG, + RSA_SET_START_MODMULT_REG, + RSA_SET_START_MODEXP_REG, +};