diff --git a/components/esp_hw_support/include/soc/esp32/esp_crypto_lock.h b/components/esp_hw_support/include/soc/esp32/esp_crypto_lock.h new file mode 100644 index 0000000000..340278c911 --- /dev/null +++ b/components/esp_hw_support/include/soc/esp32/esp_crypto_lock.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Acquire lock for the mpi cryptography peripheral. + * + */ +void esp_crypto_mpi_lock_acquire(void); + +/** + * @brief Release lock for the mpi cryptography peripheral. + * + */ +void esp_crypto_mpi_lock_release(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32/CMakeLists.txt b/components/esp_hw_support/port/esp32/CMakeLists.txt index 81d3206176..27a9809b21 100644 --- a/components/esp_hw_support/port/esp32/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32/CMakeLists.txt @@ -11,6 +11,7 @@ set(srcs if(NOT BOOTLOADER_BUILD) list(APPEND srcs "cache_sram_mmu.c" + "esp_crypto_lock.c" "sar_periph_ctrl.c") endif() diff --git a/components/esp_hw_support/port/esp32/esp_crypto_lock.c b/components/esp_hw_support/port/esp32/esp_crypto_lock.c new file mode 100644 index 0000000000..3eb303c92b --- /dev/null +++ b/components/esp_hw_support/port/esp32/esp_crypto_lock.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "esp_crypto_lock.h" + +/* Lock overview: +MPI/RSA: independent +*/ + +/* Lock for the MPI/RSA peripheral */ + +static _lock_t s_crypto_mpi_lock; + +void esp_crypto_mpi_lock_acquire(void) +{ + _lock_acquire(&s_crypto_mpi_lock); +} + +void esp_crypto_mpi_lock_release(void) +{ + _lock_release(&s_crypto_mpi_lock); +} diff --git a/components/hal/.build-test-rules.yml b/components/hal/.build-test-rules.yml index 4e02657514..453b1e3a40 100644 --- a/components/hal/.build-test-rules.yml +++ b/components/hal/.build-test-rules.yml @@ -7,3 +7,8 @@ components/hal/test_apps/ecc: - if: IDF_TARGET == "esp32c2" temporary: true reason: C2 ECC peripheral has a bug in ECC point verification, if value of K is zero the verification fails + +components/hal/test_apps/mpi: + disable: + - if: SOC_MPI_SUPPORTED != 1 + reason: Hardware MPI support not available for such targets. diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 43f0508f1e..247723916e 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -1,3 +1,4 @@ + idf_build_get_property(target IDF_TARGET) # On Linux, there is currently no HAL, hence this simple component registration @@ -117,6 +118,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "ecdsa_hal.c") endif() + if(CONFIG_SOC_MPI_SUPPORTED) + list(APPEND srcs "mpi_hal.c") + endif() + if(CONFIG_SOC_SHA_SUPPORTED) list(APPEND srcs "sha_hal.c") endif() diff --git a/components/hal/esp32/include/hal/mpi_ll.h b/components/hal/esp32/include/hal/mpi_ll.h new file mode 100644 index 0000000000..5d333151fa --- /dev/null +++ b/components/hal/esp32/include/hal/mpi_ll.h @@ -0,0 +1,150 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/dport_reg.h" +#include "soc/hwcrypto_periph.h" +#include "soc/mpi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Round up number of words to nearest + 512 bit (16 word) block count. +*/ +static inline size_t mpi_ll_calculate_hardware_words(size_t words) +{ + return (words + 0xF) & ~0xF; +} + +static inline void mpi_ll_clear_power_control_bit(void) +{ + DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); +} + +static inline void mpi_ll_set_power_control_bit(void) +{ + DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); +} + +static inline void mpi_ll_enable_interrupt(void) +{ + DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); +} + +static inline void mpi_ll_disable_interrupt(void) +{ + DPORT_REG_WRITE(RSA_INTERRUPT_REG, 0); +} + +static inline void mpi_ll_clear_interrupt(void) +{ + DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); +} + +static inline bool mpi_ll_check_memory_init_complete(void) +{ + return DPORT_REG_READ(RSA_CLEAN_REG) == 0; +} + +static inline void mpi_ll_start_op(mpi_op_t op) +{ + DPORT_REG_WRITE(MPI_LL_OPERATIONS[op], 1); +} + +static inline bool mpi_ll_get_int_status(void) +{ + return DPORT_REG_READ(RSA_INTERRUPT_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. + +*/ + +/* Please see detailed note inside the function body below. + * Relevant: IDF-6029 + https://github.com/espressif/esp-idf/issues/8710 + https://github.com/espressif/esp-idf/issues/10403 + */ +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 copy_words = MIN(num_words, n); + + /* Copy MPI data to memory block registers */ + for (uint32_t i = 0; i < copy_words; i++) { + DPORT_REG_WRITE(mem_base + i * 4, p[i]); + } + + /* Zero any remaining memory block data */ + for (uint32_t i = copy_words; i < num_words; i++) { + DPORT_REG_WRITE(mem_base + i * 4, 0); + } +#if _INTERNAL_DEBUG_PURPOSE + /* + * With Xtensa GCC 11.2.0 (from ESP-IDF v5.x), it was observed that above zero initialization + * loop gets optimized to `memset` call from the ROM library. This was causing an issue that + * specific write (store) operation to the MPI peripheral block was getting lost erroneously. + * Following data re-verify loop could catch it during runtime. + * + * As a workaround, we are using DPORT_WRITE_REG (volatile writes) wrappers to write to + * the MPI peripheral. + * + */ + + //for (uint32_t i = copy_words; i < hw_words; i++) { assert(pbase[i] == 0); } +#endif +} + +static inline void mpi_ll_write_m_prime(uint32_t Mprime) +{ + DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime); +} + +static inline void mpi_ll_write_rinv(uint32_t rinv) +{ + DPORT_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; + DPORT_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) +{ + assert(n >= num_words); + uint32_t mem_base = MPI_LL_BLOCK_BASES[MPI_PARAM_Z]; + /* Copy data from memory block registers */ + esp_dport_access_read_buffer(p, mem_base, num_words); + + /* 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) +{ + DPORT_REG_WRITE(RSA_MULT_MODE_REG, length); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c3/include/hal/mpi_ll.h b/components/hal/esp32c3/include/hal/mpi_ll.h new file mode 100644 index 0000000000..da1697abfa --- /dev/null +++ b/components/hal/esp32c3/include/hal/mpi_ll.h @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/hwcrypto_periph.h" +#include "soc/system_reg.h" +#include "soc/mpi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +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(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); +} + +static inline void mpi_ll_set_power_control_bit(void) +{ + REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); +} + +static inline void mpi_ll_enable_interrupt(void) +{ + REG_WRITE(RSA_INTERRUPT_REG, 1); +} + +static inline void mpi_ll_disable_interrupt(void) +{ + REG_WRITE(RSA_INTERRUPT_REG, 0); +} + +static inline void mpi_ll_clear_interrupt(void) +{ + REG_WRITE(RSA_CLEAR_INTERRUPT_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_INTERRUPT_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_DASH_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_LENGTH_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/hal/esp32c6/include/hal/mpi_ll.h b/components/hal/esp32c6/include/hal/mpi_ll.h new file mode 100644 index 0000000000..8e8a433c75 --- /dev/null +++ b/components/hal/esp32c6/include/hal/mpi_ll.h @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/pcr_reg.h" +#include "soc/rsa_reg.h" +#include "soc/mpi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +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' of mpi_param_t 'param'. + + 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/hal/esp32h2/include/hal/mpi_ll.h b/components/hal/esp32h2/include/hal/mpi_ll.h new file mode 100644 index 0000000000..7ca607c140 --- /dev/null +++ b/components/hal/esp32h2/include/hal/mpi_ll.h @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/pcr_reg.h" +#include "soc/rsa_reg.h" +#include "soc/mpi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +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/hal/esp32s2/include/hal/mpi_ll.h b/components/hal/esp32s2/include/hal/mpi_ll.h new file mode 100644 index 0000000000..01f758ffb1 --- /dev/null +++ b/components/hal/esp32s2/include/hal/mpi_ll.h @@ -0,0 +1,151 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/hwcrypto_periph.h" +#include "soc/dport_reg.h" +#include "soc/mpi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +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(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_MEM_PD); +} + +static inline void mpi_ll_set_power_control_bit(void) +{ + REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); +} + +static inline void mpi_ll_enable_interrupt(void) +{ + REG_WRITE(RSA_INTERRUPT_REG, 1); +} + +static inline void mpi_ll_disable_interrupt(void) +{ + REG_WRITE(RSA_INTERRUPT_REG, 0); +} + +static inline void mpi_ll_clear_interrupt(void) +{ + REG_WRITE(RSA_CLEAR_INTERRUPT_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_INTERRUPT_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_DASH_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 */ + esp_dport_access_read_buffer(p, mem_base, num_words); + + /* 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_LENGTH_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_OPEN_REG, 0); +} + +static inline void mpi_ll_enable_search(void) +{ + REG_WRITE(RSA_SEARCH_OPEN_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/hal/esp32s3/include/hal/mpi_ll.h b/components/hal/esp32s3/include/hal/mpi_ll.h new file mode 100644 index 0000000000..018ff06757 --- /dev/null +++ b/components/hal/esp32s3/include/hal/mpi_ll.h @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#include "hal/assert.h" +#include "soc/hwcrypto_periph.h" +#include "soc/dport_reg.h" +#include "soc/mpi_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +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(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); +} + +static inline void mpi_ll_set_power_control_bit(void) +{ + REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); +} + +static inline void mpi_ll_enable_interrupt(void) +{ + REG_WRITE(RSA_INTERRUPT_REG, 1); +} + +static inline void mpi_ll_disable_interrupt(void) +{ + REG_WRITE(RSA_INTERRUPT_REG, 0); +} + +static inline void mpi_ll_clear_interrupt(void) +{ + REG_WRITE(RSA_CLEAR_INTERRUPT_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_INTERRUPT_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_DASH_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]; + esp_dport_access_read_buffer(p, mem_base, num_words); + /* 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_LENGTH_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_OPEN_REG, 0); +} + +static inline void mpi_ll_enable_search(void) +{ + REG_WRITE(RSA_SEARCH_OPEN_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/hal/include/hal/mpi_hal.h b/components/hal/include/hal/mpi_hal.h new file mode 100644 index 0000000000..c06779f20c --- /dev/null +++ b/components/hal/include/hal/mpi_hal.h @@ -0,0 +1,146 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The HAL is not public api, don't use in application code. + * See readme.md in soc/README.md + ******************************************************************************/ + +#pragma once + +#include +#include +#include "hal/mpi_types.h" + +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Calculate the number of words needed to represent the input word in hardware. + * + * @param words The number of words to be represented. + * @return size_t Number of words required. + */ +size_t mpi_hal_calc_hardware_words(size_t words); + +/** + * @brief Clear the MPI power control bit and intitialise the MPI hardware. + * + */ +void mpi_hal_enable_hardware_hw_op(void); + +/** + * @brief Set the MPI power control bit to disable the MPI hardware. + * + */ +void mpi_hal_disable_hardware_hw_op(void); + +/** + * @brief Enable/disables MPI operation complete interrupt. + * + * @param enable true: enable, false: disable. + */ +void mpi_hal_interrupt_enable(bool enable); + +/** + * @brief Clears the MPI operation complete interrupt status. + * + */ +void mpi_hal_clear_interrupt(void); + +/** + * @brief Configure RSA length. + * + * @param num_words Number of words representing the RSA length. + */ +void mpi_hal_set_mode(size_t num_words); + +/** + * @brief Copy the large number (array of words) representation of the parameter 'param' to hardware memory block. + * + * @param param Type of parameter (enum). + * @param offset Offset to copy in the memory from the base address of the parameter. + * @param p Pointer to large number (array of words) representation of the parameter. + * @param n Number of words needed to represent the large number as an array of words. + * @param num_words Maximum hardware words needed. + */ +void mpi_hal_write_to_mem_block(mpi_param_t param, size_t offset, const uint32_t* p, size_t n, size_t num_words); + +/** + * @brief Write a word-sized value to hardware memory block of a parameter. + * + * @param param Type of parameter (enum). + * @param offset Offset to copy in the memory from the base address of the parameter. + * @param value Value to be written in the memory. + */ +void mpi_hal_write_at_offset(mpi_param_t param, int offset, uint32_t value); + +/** + * @brief Write the modular multiplicative inverse of M. + * + * @param Mprime Modular multiplicative inverse of M. + */ +void mpi_hal_write_m_prime(uint32_t Mprime); + +/** + * @brief Write first word of the parametr Rinv. + * + * @param rinv Value of first word of rinv. + */ +void mpi_hal_write_rinv(uint32_t rinv); + +#if !CONFIG_IDF_TARGET_ESP32 +/** + * @brief Enable/Disable constant time acceleration option. + * + * @param enable true: enable, false: disable. + */ +void mpi_hal_enable_constant_time(bool enable); + +/** + * @brief Enable/Disable search time acceleration option. + * + * @param enable + */ +void mpi_hal_enable_search(bool enable); + +/** + * @brief Configures the starting address to start search. + * + * @param position Address to start search. + */ +void mpi_hal_set_search_position(size_t position); +#endif /* !CONFIG_IDF_TARGET_ESP32 */ + +/** + * @brief Begin an MPI operation. + * + * @param op Operation type (enum). + */ +void mpi_hal_start_op(mpi_op_t op); + +/** + * @brief Wait for an MPI operation to complete. + * + */ +void mpi_hal_wait_op_complete(void); + +/** + * @brief Wait for an MPI operation to complete and Read result from last MPI operation into parameter Z. + * + * @param p Pointer to large number (array of words) representation of the parameter. + * @param n Number of words needed to represent the large number as an array of words. + * @param z_words Calculated number of words of parameter Z. + */ +void mpi_hal_read_result_hw_op(uint32_t* p, size_t n, size_t z_words); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/mpi_types.h b/components/hal/include/hal/mpi_types.h new file mode 100644 index 0000000000..25a5eeef20 --- /dev/null +++ b/components/hal/include/hal/mpi_types.h @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +typedef enum { + MPI_MULT = 0x0, // (X * Y) + MPI_MODMULT, // (X * Y) Mod M + MPI_MODEXP, // (X ^ Y) Mod M +} mpi_op_t; + +typedef enum { + MPI_PARAM_X = 0x0, + MPI_PARAM_Y, + MPI_PARAM_Z, + MPI_PARAM_M, +} mpi_param_t; diff --git a/components/hal/mpi_hal.c b/components/hal/mpi_hal.c new file mode 100644 index 0000000000..22935268fb --- /dev/null +++ b/components/hal/mpi_hal.c @@ -0,0 +1,126 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "hal/mpi_hal.h" +#include "hal/mpi_ll.h" +#include "sdkconfig.h" + + +size_t mpi_hal_calc_hardware_words(size_t words) +{ + return mpi_ll_calculate_hardware_words(words); +} + +void mpi_hal_enable_hardware_hw_op(void) +{ + mpi_ll_clear_power_control_bit(); + while (mpi_ll_check_memory_init_complete()) { + } + // Note: from enabling RSA clock to here takes about 1.3us + +#if !CONFIG_IDF_TARGET_ESP32 + mpi_ll_disable_interrupt(); +#endif +} + +void mpi_hal_disable_hardware_hw_op(void) +{ + mpi_ll_set_power_control_bit(); +} + +void mpi_hal_interrupt_enable(bool enable) +{ + if (enable){ + mpi_ll_enable_interrupt(); + } + else { + mpi_ll_disable_interrupt(); + } +} + +void mpi_hal_clear_interrupt(void) +{ + mpi_ll_clear_interrupt(); +} + +void mpi_hal_set_mode(size_t num_words) +{ + mpi_ll_set_mode(num_words); +} + +void mpi_hal_write_to_mem_block(mpi_param_t param, size_t offset, const uint32_t* p, size_t n, size_t num_words) +{ + mpi_ll_write_to_mem_block(param, offset, p, n, num_words); +} + +void mpi_hal_write_at_offset(mpi_param_t param, int offset, uint32_t value) +{ + mpi_ll_write_at_offset(param, offset, value); +} + +void mpi_hal_write_m_prime(uint32_t Mprime) +{ + mpi_ll_write_m_prime(Mprime); +} + +void mpi_hal_write_rinv(uint32_t rinv) +{ + mpi_ll_write_rinv(rinv); +} + +// Acceleration options +#if !CONFIG_IDF_TARGET_ESP32 +void mpi_hal_enable_constant_time(bool enable) +{ + if (enable){ + mpi_ll_enable_constant_time(); + } + else { + mpi_ll_disable_constant_time(); + } +} + +void mpi_hal_enable_search(bool enable) +{ + if (enable){ + mpi_ll_enable_search(); + } + else { + mpi_ll_disable_search(); + } +} + +void mpi_hal_set_search_position(size_t position) +{ + mpi_ll_set_search_position(position); +} +#endif /* !CONFIG_IDF_TARGET_ESP32 */ + +/* Begin an RSA operation. +*/ +void mpi_hal_start_op(mpi_op_t op) +{ + /* Clear interrupt status */ + mpi_hal_clear_interrupt(); + mpi_ll_start_op(op); +} + +/* Wait for an RSA operation to complete. +*/ +void mpi_hal_wait_op_complete(void) +{ + while (mpi_ll_get_int_status()) + { } + + /* Clear interrupt status */ + mpi_hal_clear_interrupt(); +} + +void mpi_hal_read_result_hw_op(uint32_t* p, size_t n, size_t z_words) +{ + /* Wait for an RSA operation to complete. */ + mpi_hal_wait_op_complete(); + mpi_ll_read_from_mem_block(p, n, z_words); +} diff --git a/components/hal/test_apps/mpi/CMakeLists.txt b/components/hal/test_apps/mpi/CMakeLists.txt new file mode 100644 index 0000000000..b1cc26cf58 --- /dev/null +++ b/components/hal/test_apps/mpi/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(mpi_test) diff --git a/components/hal/test_apps/mpi/README.md b/components/hal/test_apps/mpi/README.md new file mode 100644 index 0000000000..7bf5d8ff56 --- /dev/null +++ b/components/hal/test_apps/mpi/README.md @@ -0,0 +1,33 @@ +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | + +## MPI peripheral test + +This application contains basic test cases for the MPI peripheral without using any OS functionality or higher abstraction layer. + +This contains tests for the following features of MPI peripheral: + +- MPI Modular Multiplication +- MPI Multiplication +- MPI Modular Exponentiation + +# Building + +```bash +idf.py set-target +idf.py build +``` + +# Running the app manually + +```bash +idf.py flash monitor +``` + +Enter the test that you want to run locally + +# Running tests + +```bash +pytest --target +``` diff --git a/components/hal/test_apps/mpi/main/CMakeLists.txt b/components/hal/test_apps/mpi/main/CMakeLists.txt new file mode 100644 index 0000000000..c1e569ffca --- /dev/null +++ b/components/hal/test_apps/mpi/main/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs "app_main.c" + "test_mpi.c") + +idf_component_register(SRCS ${srcs} + REQUIRES unity + WHOLE_ARCHIVE) diff --git a/components/hal/test_apps/mpi/main/app_main.c b/components/hal/test_apps/mpi/main/app_main.c new file mode 100644 index 0000000000..ecde0a6c5d --- /dev/null +++ b/components/hal/test_apps/mpi/main/app_main.c @@ -0,0 +1,13 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/hal/test_apps/mpi/main/test_mpi.c b/components/hal/test_apps/mpi/main/test_mpi.c new file mode 100644 index 0000000000..9a7d67adf2 --- /dev/null +++ b/components/hal/test_apps/mpi/main/test_mpi.c @@ -0,0 +1,145 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include + +#include "esp_log.h" +#include "esp_private/periph_ctrl.h" +#include "unity.h" + +#if CONFIG_IDF_TARGET_ESP32 +#define ESP_MPI_USE_MONT_EXP +#endif + +#include "hal/mpi_hal.h" +#include "test_params.h" + +#define _DEBUG_ 0 + + +static void esp_mpi_enable_hardware_hw_op( void ) +{ + /* Enable RSA hardware */ + periph_module_enable(PERIPH_RSA_MODULE); + + mpi_hal_enable_hardware_hw_op(); +} + + +static void esp_mpi_disable_hardware_hw_op( void ) +{ + mpi_hal_disable_hardware_hw_op(); + + /* Disable RSA hardware */ + periph_module_disable(PERIPH_RSA_MODULE); +} + + +static void mpi_mul_mpi_mod_hw_op(void) +{ + esp_mpi_enable_hardware_hw_op(); + for(int i = 0; i < TEST_CASES_NUM; i++){ +#if CONFIG_IDF_TARGET_ESP32 + mpi_hal_set_mode((test_cases_num_words[i] / 16) - 1); +#else + mpi_hal_set_mode(test_cases_num_words[i] - 1); +#endif + /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ + mpi_hal_write_to_mem_block(MPI_PARAM_M, 0, test_cases_M_p[i], test_cases_M_n[i], test_cases_num_words[i]); + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, test_cases_X_p[i], test_cases_X_n[i], test_cases_num_words[i]); + +#if !CONFIG_IDF_TARGET_ESP32 + mpi_hal_write_to_mem_block(MPI_PARAM_Y, 0, test_cases_Y_p[i], test_cases_Y_n[i], test_cases_num_words[i]); +#endif + + mpi_hal_write_to_mem_block(MPI_PARAM_Z, 0, test_cases_Rinv_p[i], test_cases_Rinv_n[i], test_cases_num_words[i]); + mpi_hal_write_m_prime(test_cases_Mprime[i]); + +#if CONFIG_IDF_TARGET_ESP32 + mpi_hal_start_op(MPI_MULT); + mpi_hal_wait_op_complete(); + /* execute second stage */ + /* Load Y to X input memory block, rerun */ + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, test_cases_Y_p[i], test_cases_Y_n[i], test_cases_num_words[i]); + mpi_hal_start_op(MPI_MULT); +#else + mpi_hal_start_op(MPI_MODMULT); +#endif + uint32_t* Z_p = (uint32_t*)calloc(test_cases_Z_words[i], sizeof(uint32_t)); + mpi_hal_read_result_hw_op(Z_p, test_cases_Z_words[i], test_cases_Z_words[i]); + + printf("Test Case %d: ", i+1); + +#if _DEBUG_ + printf("\n"); + ESP_LOG_BUFFER_HEX("Expected Z:", test_cases_Z_p[i], test_cases_Z_words[i]*4); + ESP_LOG_BUFFER_HEX("Got Z:", Z_p, test_cases_Z_words[i]*4); +#endif + + TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(test_cases_Z_p[i], Z_p, test_cases_Z_words[i], "Result"); + printf("PASS\n"); + } + esp_mpi_disable_hardware_hw_op(); +} + + +static void mpi_exp_mpi_mod_hw_op(void) +{ + + for (int i = 0; i < EXP_TEST_CASES_NUM; i++) { + if (i == 14 || i == 16 || i == 18 || i == 22) // cases when Y == 0 (in Z = X ^ Y mod M) should be handled in the software level + continue; +#ifdef ESP_MPI_USE_MONT_EXP // CONFIG_IDF_TARGET_ESP32 + printf("Support for montgomery exponentiation to be added.\n"); + break; +#else + esp_mpi_enable_hardware_hw_op(); + + mpi_hal_set_mode(exp_test_cases_num_words[i] - 1); + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, exp_test_cases_X_p[i], exp_test_cases_X_n[i], exp_test_cases_num_words[i]); + mpi_hal_write_to_mem_block(MPI_PARAM_Y, 0, exp_test_cases_Y_p[i], exp_test_cases_Y_n[i], exp_test_cases_num_words[i]); + mpi_hal_write_to_mem_block(MPI_PARAM_M, 0, exp_test_cases_M_p[i], exp_test_cases_M_n[i], exp_test_cases_num_words[i]); + mpi_hal_write_to_mem_block(MPI_PARAM_Z, 0, exp_test_cases_Rinv_p[i], exp_test_cases_Rinv_n[i], exp_test_cases_num_words[i]); + + mpi_hal_write_m_prime(exp_test_cases_Mprime[i]); + + /* Enable acceleration options */ + mpi_hal_enable_constant_time(false); + mpi_hal_enable_search(true); + mpi_hal_set_search_position(exp_test_cases_y_bits[i] - 1); + + /* Execute first stage montgomery multiplication */ + mpi_hal_start_op(MPI_MODEXP); + + mpi_hal_enable_search(false); +#endif + uint32_t* Z_p = (uint32_t*)calloc(exp_test_cases_m_words[i], sizeof(uint32_t)); + /* Read back the result */ + mpi_hal_read_result_hw_op(Z_p, exp_test_cases_m_words[i], exp_test_cases_m_words[i]); + esp_mpi_disable_hardware_hw_op(); + + printf("Test Case %d: ", i+1); + +#if _DEBUG_ + printf("\n"); + ESP_LOG_BUFFER_HEX("Expected Z:", test_cases_Z_p[i], test_cases_Z_words[i]*4); + ESP_LOG_BUFFER_HEX("Got Z:", Z_p, test_cases_Z_words[i]*4); +#endif + + TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(exp_test_cases_Z_p[i], Z_p, exp_test_cases_m_words[i], "Result"); + printf("PASS\n"); + } +} + +TEST_CASE("Test MPI multiplication", "[mpi][hal]") +{ + mpi_mul_mpi_mod_hw_op(); +} + +TEST_CASE("Test MPI exponentiation", "[mpi][hal]") +{ + mpi_exp_mpi_mod_hw_op(); +} diff --git a/components/hal/test_apps/mpi/main/test_params.h b/components/hal/test_apps/mpi/main/test_params.h new file mode 100644 index 0000000000..ed3959b62a --- /dev/null +++ b/components/hal/test_apps/mpi/main/test_params.h @@ -0,0 +1,382 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#define TEST_CASES_NUM 11 + +const uint32_t M_p_1[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_1[] = { 0x10 }; +const uint32_t Y_p_1[] = { 0x100 }; +const uint32_t Rinv_p_1[] = { 0x1 }; +const uint32_t Z_p_1[] = { 0x1000 }; + +const uint32_t M_p_2[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_2[] = { 0x10 }; +const uint32_t Y_p_2[] = { 0x100 }; +const uint32_t Rinv_p_2[] = { 0x1 }; +const uint32_t Z_p_2[] = { 0x1000 }; + +const uint32_t M_p_3[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_3[] = { 0x10 }; +const uint32_t Y_p_3[] = { 0x100 }; +const uint32_t Rinv_p_3[] = { 0x1 }; +const uint32_t Z_p_3[] = { 0x1000 }; + +const uint32_t M_p_4[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_4[] = { 0x10 }; +const uint32_t Y_p_4[] = { 0x100 }; +const uint32_t Rinv_p_4[] = { 0x1 }; +const uint32_t Z_p_4[] = { 0x1000 }; + +const uint32_t M_p_5[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_5[] = { 0x10 }; +const uint32_t Y_p_5[] = { 0x100 }; +const uint32_t Rinv_p_5[] = { 0x1 }; +const uint32_t Z_p_5[] = { 0x1000 }; + +const uint32_t M_p_6[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_6[] = { 0x10 }; +const uint32_t Y_p_6[] = { 0x100 }; +const uint32_t Rinv_p_6[] = { 0x1 }; +const uint32_t Z_p_6[] = { 0x1000 }; + +const uint32_t M_p_7[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_7[] = { 0x0, 0xd3101957, 0xecee5346, 0xb54d2f52, 0x442296ec, 0x19cd3ca8, 0x8550f006, 0x41c3f1e1, 0xa488720b, 0xcc4cb107, 0x85fb0e86, 0xcf2ed8f6, 0x4f108e15, 0x60ffaadb, 0x46be39b8, 0x8d3e3bd7, 0x60006fa }; +const uint32_t Y_p_7[] = { 0xbf474ca7 }; +const uint32_t Rinv_p_7[] = { 0x1 }; +const uint32_t Z_p_7[] = { 0x0, 0x67275bc1, 0x404ee63b, 0x2e2c03aa, 0x2e4998f4, 0x20653a31, 0x1dffabd1, 0x6aa51a39, 0xde0e2bad, 0xd7762fc2, 0x88e65fef, 0x2a4e310f, 0x2b9b939a, 0x3051d823, 0x31bc0b75, 0xd3d97e42, 0xcaf58a48, 0x47bb102 }; + +const uint32_t M_p_8[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_8[] = { 0x80000000, 0xd64787bc, 0x19d05e3d, 0xbd83a839, 0xd2f4a5db, 0x9a770400, 0xaea5e366, 0xafab037d, 0x2f72be37, 0x41e9e9f0, 0xfa4a3585, 0x148ba01f, 0x40d718ca, 0x7be1c5, 0xc033696c, 0x9fdf9e27, 0x5c9d44c0, 0xad60775d, 0xaa67e3aa, 0xe76bd66f, 0x5738985c, 0xdf079b6b, 0x99626884, 0x5361ec05, 0x756ed496, 0xf5e04245, 0xc87d1791, 0xdf9abc30, 0xc44768ea, 0xeaf3bbeb, 0xc01eeb01, 0xc229831e, 0x49493a }; +const uint32_t Y_p_8[] = { 0xb878cc29 }; +const uint32_t Rinv_p_8[] = { 0x1 }; +const uint32_t Z_p_8[] = { 0x80000000, 0x6dfaf330, 0xcc7839bf, 0x29754f1f, 0x6c9121d6, 0xc430620, 0x80e52130, 0x619ccf81, 0x39521993, 0x3f9293c8, 0x165fc8a8, 0x98d8c9d3, 0xa7b1fd46, 0x66d156e7, 0xcb373706, 0x819f0d65, 0xd52d2cbe, 0xb1e5f6e3, 0x78ae1381, 0xc5f8e002, 0x435c6bf7, 0xc912fdbc, 0x7aa2a247, 0xba1e460, 0xd28d4e10, 0x12b0ab73, 0xbff58710, 0x64b6e727, 0x55daff98, 0x66604e0d, 0xf1fe7bda, 0xbda2c86c, 0x13066d5, 0x34cf37 }; + +const uint32_t M_p_9[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_9[] = { 0xcae9a34d, 0xa031f21e, 0x1e85b5df, 0xe071513a, 0xe81a1521, 0x74ca15f3, 0xdde2beb6, 0x7af1fedf, 0xc8632240, 0x3b9f880f, 0xcf78b817, 0x4cabb724, 0x19816423, 0x7f123142, 0xe07ee72c, 0xddf79c5c, 0x634f9e8c, 0xf7ee8c0c, 0x4a8a9a45, 0x37ae1b48, 0x2d288558, 0xe33fa325, 0x77937f, 0x5091386c, 0xa9d3bfa7, 0x3102f8b4, 0x2bc44d25, 0xfc66ca47, 0x3d25e64e, 0xfdd30308, 0x85468786, 0x24bf61 }; +const uint32_t Y_p_9[] = { 0x10001 }; +const uint32_t Rinv_p_9[] = { 0x1 }; +const uint32_t Z_p_9[] = { 0x6e36a34d, 0x9250bd08, 0xd4655611, 0x31ab6fbf, 0xfd3bf593, 0x8abdfe0d, 0x9c993380, 0x79d1dcc2, 0xeaa39d32, 0xc3af5072, 0x878ff3b6, 0x3d0869d, 0x7da4b0cf, 0xb0544ac3, 0xc7ab663e, 0x7a547cdb, 0x1dc7c84, 0x83faef5c, 0xe4d09234, 0x52f665d2, 0xb280bd06, 0x8664d04d, 0x93f776bf, 0x88fd38e3, 0x697b1038, 0x29b7a288, 0x78e97e28, 0xc6adf60b, 0x2374e2b5, 0xdb402e, 0xccd855a, 0xbf8644a8, 0x24 }; + +const uint32_t M_p_10[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_10[] = { 0x35893620, 0x6f4b348d, 0x95c4fc96, 0xef12340b, 0xa7dec5d5, 0x56fe1e8e, 0x9486fc80, 0x6f8819d6, 0x467ada31, 0x856a2147, 0x780e9b54, 0xe9da7683, 0x46a906b7, 0x22137235, 0xc417edd0, 0x5d88b669 }; +const uint32_t Y_p_10[] = { 0x6f48ea08, 0xf5a8c50d, 0xc169d74b, 0xa74206ce, 0xeb9f2d2f, 0xbbccba7f, 0xd33605ae, 0xf5a3b2a5, 0xe2bf4411, 0x275aa977, 0xb2f0e2dd, 0xf38d18d2, 0x239eadae, 0xf71896fc, 0x9546432d, 0x9ae7fbc9 }; +const uint32_t Rinv_p_10[] = { 0x1 }; +const uint32_t Z_p_10[] = { 0x30c2f100, 0xadeea408, 0x678bd2f4, 0x99540c47, 0xeba56331, 0x72d75ec6, 0x8fd72c77, 0x3a8b12c3, 0x49eb461a, 0xd332b1ff, 0xcdf59485, 0x4b0a83bb, 0xe4432ee7, 0x74a9bbeb, 0xaf573efb, 0xbc97b670, 0x8c3442f3, 0x8fbf01de, 0xd646884e, 0x76095187, 0x98628219, 0x93746469, 0xf900c0c9, 0x2b2be5a7, 0xa2949bc8, 0x3d832701, 0xc4c9270a, 0xbb7cd629, 0x339aee72, 0x3b5e6aee, 0xeb21810e, 0x38990016 }; + +const uint32_t M_p_11[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; +const uint32_t X_p_11[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4 }; +const uint32_t Y_p_11[] = { 0x1234 }; +const uint32_t Rinv_p_11[] = { 0x1 }; +const uint32_t Z_p_11[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48d0 }; + +const uint32_t* test_cases_M_p[TEST_CASES_NUM] = { + M_p_1, M_p_2, M_p_3, M_p_4, M_p_5, M_p_6, M_p_7, M_p_8, M_p_9, M_p_10, M_p_11, +}; + +const uint32_t* test_cases_X_p[TEST_CASES_NUM] = { + X_p_1, X_p_2, X_p_3, X_p_4, X_p_5, X_p_6, X_p_7, X_p_8, X_p_9, X_p_10, X_p_11, +}; + +const uint32_t* test_cases_Y_p[TEST_CASES_NUM] = { + Y_p_1, Y_p_2, Y_p_3, Y_p_4, Y_p_5, Y_p_6, Y_p_7, Y_p_8, Y_p_9, Y_p_10, Y_p_11, +}; + +const uint32_t* test_cases_Rinv_p[TEST_CASES_NUM] = { + Rinv_p_1, Rinv_p_2, Rinv_p_3, Rinv_p_4, Rinv_p_5, Rinv_p_6, Rinv_p_7, Rinv_p_8, Rinv_p_9, Rinv_p_10, Rinv_p_11, +}; + +const uint32_t* test_cases_Z_p[TEST_CASES_NUM] = { + Z_p_1, Z_p_2, Z_p_3, Z_p_4, Z_p_5, Z_p_6, Z_p_7, Z_p_8, Z_p_9, Z_p_10, Z_p_11, +}; + +const uint32_t test_cases_Mprime[TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +size_t test_cases_M_n[TEST_CASES_NUM] = { + 16, 32, 48, 64, 80, 96, 32, 96, 48, 64, 96, +}; + +size_t test_cases_X_n[TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 17, 33, 32, 16, 65, +}; + +size_t test_cases_Y_n[TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, +}; + +size_t test_cases_Rinv_n[TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +size_t test_cases_Z_n[TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 18, 34, 33, 32, 65, +}; + +size_t test_cases_Z_words[TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 18, 34, 33, 32, 65, +}; + +size_t test_cases_num_words[TEST_CASES_NUM] = { + 16, 32, 48, 64, 80, 96, 32, 96, 48, 64, 96, +}; + + + +#define EXP_TEST_CASES_NUM 33 + +const uint32_t exp_M_p_1[] = { 0xffffffff,}; +const uint32_t exp_X_p_1[] = { 0x1000,}; +const uint32_t exp_Y_p_1[] = { 0x2, }; +const uint32_t exp_Rinv_p_1[] = { 0x1, }; +const uint32_t exp_Z_p_1[] = { 0x1000000, }; + +const uint32_t exp_M_p_2[] = { 0xfffffff,}; +const uint32_t exp_X_p_2[] = { 0x1234,}; +const uint32_t exp_Y_p_2[] = { 0x2, }; +const uint32_t exp_Rinv_p_2[] = { 0x100, }; +const uint32_t exp_Z_p_2[] = { 0x14b5a90, }; + +const uint32_t exp_M_p_3[] = { 0xffffffff,}; +const uint32_t exp_X_p_3[] = { 0x1111,}; +const uint32_t exp_Y_p_3[] = { 0x2, }; +const uint32_t exp_Rinv_p_3[] = { 0x1, }; +const uint32_t exp_Z_p_3[] = { 0x1234321, }; + +const uint32_t exp_M_p_4[] = { 0x3,}; +const uint32_t exp_X_p_4[] = { 0x5,}; +const uint32_t exp_Y_p_4[] = { 0x1, }; +const uint32_t exp_Rinv_p_4[] = { 0x1, }; +const uint32_t exp_Z_p_4[] = { 0x2, }; + +const uint32_t exp_M_p_5[] = { 0x33,}; +const uint32_t exp_X_p_5[] = { 0x55,}; +const uint32_t exp_Y_p_5[] = { 0x1, }; +const uint32_t exp_Rinv_p_5[] = { 0x1, }; +const uint32_t exp_Z_p_5[] = { 0x22, }; + +const uint32_t exp_M_p_6[] = { 0x333,}; +const uint32_t exp_X_p_6[] = { 0x555,}; +const uint32_t exp_Y_p_6[] = { 0x1, }; +const uint32_t exp_Rinv_p_6[] = { 0x10, }; +const uint32_t exp_Z_p_6[] = { 0x222, }; + +const uint32_t exp_M_p_7[] = { 0x3333,}; +const uint32_t exp_X_p_7[] = { 0x5555,}; +const uint32_t exp_Y_p_7[] = { 0x1, }; +const uint32_t exp_Rinv_p_7[] = { 0x1, }; +const uint32_t exp_Z_p_7[] = { 0x2222, }; + +const uint32_t exp_M_p_8[] = { 0x33,}; +const uint32_t exp_X_p_8[] = { 0x5555,}; +const uint32_t exp_Y_p_8[] = { 0x1, }; +const uint32_t exp_Rinv_p_8[] = { 0x1, }; +const uint32_t exp_Z_p_8[] = { 0x11, }; + +const uint32_t exp_M_p_9[] = { 0x77,}; +const uint32_t exp_X_p_9[] = { 0x1111,}; +const uint32_t exp_Y_p_9[] = { 0x1, }; +const uint32_t exp_Rinv_p_9[] = { 0x56, }; +const uint32_t exp_Z_p_9[] = { 0x55, }; + +const uint32_t exp_M_p_10[] = { 0xbb,}; +const uint32_t exp_X_p_10[] = { 0x1111,}; +const uint32_t exp_Y_p_10[] = { 0x2, }; +const uint32_t exp_Rinv_p_10[] = { 0x89, }; +const uint32_t exp_Z_p_10[] = { 0x88, }; + +const uint32_t exp_M_p_11[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff,}; +const uint32_t exp_X_p_11[] = { 0x2,}; +const uint32_t exp_Y_p_11[] = { 0x128, }; +const uint32_t exp_Rinv_p_11[] = { 0x0, 0x10000, }; +const uint32_t exp_Z_p_11[] = { 0x1000000, 0x0, 0x0, 0x0, 0x0, }; + +const uint32_t exp_M_p_12[] = { 0xffffffff, 0xffff,}; +const uint32_t exp_X_p_12[] = { 0xdef12345, 0xabc,}; +const uint32_t exp_Y_p_12[] = { 0x1, }; +const uint32_t exp_Rinv_p_12[] = { 0x0, 0x1, }; +const uint32_t exp_Z_p_12[] = { 0xdef12345, 0xabc, }; + +const uint32_t exp_M_p_13[] = { 0xfffff,}; +const uint32_t exp_X_p_13[] = { 0xabcde,}; +const uint32_t exp_Y_p_13[] = { 0x1, }; +const uint32_t exp_Rinv_p_13[] = { 0x10, }; +const uint32_t exp_Z_p_13[] = { 0xabcde, }; + +const uint32_t exp_M_p_14[] = { 0x9,}; +const uint32_t exp_X_p_14[] = { 0x2,}; +const uint32_t exp_Y_p_14[] = { 0x2, }; +const uint32_t exp_Rinv_p_14[] = { 0x7, }; +const uint32_t exp_Z_p_14[] = { 0x4, }; + +const uint32_t exp_M_p_15[] = { 0x9,}; +const uint32_t exp_X_p_15[] = { 0x2,}; +const uint32_t exp_Y_p_15[] = { 0x0, }; +const uint32_t exp_Rinv_p_15[] = { 0x7, }; +const uint32_t exp_Z_p_15[] = { 0x0, }; + +const uint32_t exp_M_p_16[] = { 0x9,}; +const uint32_t exp_X_p_16[] = { 0x0,}; +const uint32_t exp_Y_p_16[] = { 0x2, }; +const uint32_t exp_Rinv_p_16[] = { 0x7, }; +const uint32_t exp_Z_p_16[] = { 0x0, }; + +const uint32_t exp_M_p_17[] = { 0x9,}; +const uint32_t exp_X_p_17[] = { 0x0,}; +const uint32_t exp_Y_p_17[] = { 0x0, }; +const uint32_t exp_Rinv_p_17[] = { 0x7, }; +const uint32_t exp_Z_p_17[] = { 0x0, }; + +const uint32_t exp_M_p_18[] = { 0x9,}; +const uint32_t exp_X_p_18[] = { 0x2,}; +const uint32_t exp_Y_p_18[] = { 0x2, }; +const uint32_t exp_Rinv_p_18[] = { 0x7, }; +const uint32_t exp_Z_p_18[] = { 0x4, }; + +const uint32_t exp_M_p_19[] = { 0x9,}; +const uint32_t exp_X_p_19[] = { 0x2,}; +const uint32_t exp_Y_p_19[] = { 0x0, }; +const uint32_t exp_Rinv_p_19[] = { 0x7, }; +const uint32_t exp_Z_p_19[] = { 0x0, }; + +const uint32_t exp_M_p_20[] = { 0x9,}; +const uint32_t exp_X_p_20[] = { 0x2,}; +const uint32_t exp_Y_p_20[] = { 0x7, }; +const uint32_t exp_Rinv_p_20[] = { 0x7, }; +const uint32_t exp_Z_p_20[] = { 0x2, }; + +const uint32_t exp_M_p_21[] = { 0x9,}; +const uint32_t exp_X_p_21[] = { 0x2,}; +const uint32_t exp_Y_p_21[] = { 0x1, }; +const uint32_t exp_Rinv_p_21[] = { 0x7, }; +const uint32_t exp_Z_p_21[] = { 0x2, }; + +const uint32_t exp_M_p_22[] = { 0x9,}; +const uint32_t exp_X_p_22[] = { 0x2,}; +const uint32_t exp_Y_p_22[] = { 0x1, }; +const uint32_t exp_Rinv_p_22[] = { 0x7, }; +const uint32_t exp_Z_p_22[] = { 0x2, }; + +const uint32_t exp_M_p_23[] = { 0x9,}; +const uint32_t exp_X_p_23[] = { 0x2,}; +const uint32_t exp_Y_p_23[] = { 0x0, }; +const uint32_t exp_Rinv_p_23[] = { 0x7, }; +const uint32_t exp_Z_p_23[] = { 0x0, }; + +const uint32_t exp_M_p_24[] = { 0x7,}; +const uint32_t exp_X_p_24[] = { 0x5,}; +const uint32_t exp_Y_p_24[] = { 0x7, }; +const uint32_t exp_Rinv_p_24[] = { 0x2, }; +const uint32_t exp_Z_p_24[] = { 0x5, }; + +const uint32_t exp_M_p_25[] = { 0x7,}; +const uint32_t exp_X_p_25[] = { 0x5,}; +const uint32_t exp_Y_p_25[] = { 0x7, }; +const uint32_t exp_Rinv_p_25[] = { 0x2, }; +const uint32_t exp_Z_p_25[] = { 0x5, }; + +const uint32_t exp_M_p_26[] = { 0x3,}; +const uint32_t exp_X_p_26[] = { 0x5,}; +const uint32_t exp_Y_p_26[] = { 0x7, }; +const uint32_t exp_Rinv_p_26[] = { 0x1, }; +const uint32_t exp_Z_p_26[] = { 0x2, }; + +const uint32_t exp_M_p_27[] = { 0x23456789, 0x1,}; +const uint32_t exp_X_p_27[] = { 0x23456789, 0x1,}; +const uint32_t exp_Y_p_27[] = { 0x23456789, 0x1, }; +const uint32_t exp_Rinv_p_27[] = { 0x34890700, }; +const uint32_t exp_Z_p_27[] = { 0x0, 0x0, }; + +const uint32_t exp_M_p_28[] = { 0x23456789, 0x1,}; +const uint32_t exp_X_p_28[] = { 0x23456788, 0x1,}; +const uint32_t exp_Y_p_28[] = { 0x23456788, 0x1, }; +const uint32_t exp_Rinv_p_28[] = { 0x34890700, }; +const uint32_t exp_Z_p_28[] = { 0x1, 0x0, }; + +const uint32_t exp_M_p_29[] = { 0x23456789, 0x1,}; +const uint32_t exp_X_p_29[] = { 0x2345678a, 0x1,}; +const uint32_t exp_Y_p_29[] = { 0x2345678a, 0x1, }; +const uint32_t exp_Rinv_p_29[] = { 0x34890700, }; +const uint32_t exp_Z_p_29[] = { 0x1, 0x0, }; + +const uint32_t exp_M_p_30[] = { 0x7,}; +const uint32_t exp_X_p_30[] = { 0x32,}; +const uint32_t exp_Y_p_30[] = { 0x3e9, }; +const uint32_t exp_Rinv_p_30[] = { 0x2, }; +const uint32_t exp_Z_p_30[] = { 0x1, }; + +const uint32_t exp_M_p_31[] = { 0xd2f86373, 0x7dc0eddd, 0x1a27c06f, 0xbe6e3437, 0xa3fa8342, 0x47be20c9, 0x4532cdf5, 0x728e8766, 0x31e46aa7, 0xdc5e8c72, 0xba39c6b2, 0x29c291b4, 0xab5f5cf4, 0xa90e51bb, 0xfc1e677d, 0x5347c68a, 0xd95f7d6, 0xae98132b, 0x135c643c, 0x2e9e82e9, 0x5a540609, 0x3274e472, 0xb24222d0, 0x9153bd76, 0x1a5c9640, 0xaa94b8bb, 0xeb740f69, 0xc3cdd261, 0x323b9c45, 0x957ff5dd, 0x8419a724, 0xcf5cf5c3,}; +const uint32_t exp_X_p_31[] = { 0x2,}; +const uint32_t exp_Y_p_31[] = { 0xa9e42102, 0x5ab4a0f, 0xc529b673, 0x1684435d, 0x33f2d8fb, 0xdb42b4e7, 0x103e8eb9, 0xbf8de4ed, 0x91537869, 0x11c88a96, 0xcdff05bd, 0x157f8be2, 0xf6c63d3d, 0x36e4ee76, 0xd15c29a7, 0x3e6071e0, 0x3e2b0c1d, 0x54444d19, 0x62699c34, 0xe9ffd47a, 0x1acf4cb1, 0x3617251a, 0x29a256a, 0x884c0e32, 0xcb883a85, 0xcf364770, 0xa5f2da4, 0x32166b1f, 0xda3deaf5, 0xb4fed79a, 0xa82ccab3, 0x471cc5f6, }; +const uint32_t exp_Rinv_p_31[] = { 0x6787f727, 0xc0dc79ce, 0x22066424, 0x4c6a2bf8, 0x5b81cb65, 0x169a350a, 0x47a07b05, 0x2a086619, 0xe5143481, 0xaddd2a07, 0xf3087ad4, 0xb7e7b5cd, 0xeff1c6f6, 0xa35ab988, 0x3cb3c643, 0xd53b3480, 0xcda6a846, 0xd51c411a, 0x840fea4, 0x2b55e639, 0x680557e2, 0x46c77daf, 0x1d110ae6, 0x9cf0f62b, 0x51257507, 0x63d1c63e, 0xdaccc4cf, 0xe3af579d, 0xe58ed7b0, 0x6950d5aa, 0x21471db1, 0x4ca3e886, }; +const uint32_t exp_Z_p_31[] = { 0xe0b8c80b, 0xba541503, 0x26937a8c, 0xd0372fac, 0xc4cb31b4, 0x40d71bbc, 0xefb6ac09, 0x15ad27f9, 0xcee9542a, 0xa247a4a2, 0xf204c903, 0x18728efd, 0x28b5313f, 0x21b6d67f, 0x7efb40c2, 0xf5df3fd7, 0xa49ed483, 0x8024b012, 0xbf355f2a, 0xd19d4b1f, 0xa308f006, 0x20cd0b86, 0x5e9db2bb, 0xf0c89b5c, 0x801c9b5a, 0x277ab525, 0x90ce4180, 0x7df883ab, 0xdad05b20, 0x6cb02835, 0x76a157ec, 0x5fa6cb1f, }; + +const uint32_t exp_M_p_32[] = { 0xd2f86373, 0x7dc0eddd, 0x1a27c06f, 0xbe6e3437, 0xa3fa8342, 0x47be20c9, 0x4532cdf5, 0x728e8766, 0x31e46aa7, 0xdc5e8c72, 0xba39c6b2, 0x29c291b4, 0xab5f5cf4, 0xa90e51bb, 0xfc1e677d, 0x5347c68a, 0xd95f7d6, 0xae98132b, 0x135c643c, 0x2e9e82e9, 0x5a540609, 0x3274e472, 0xb24222d0, 0x9153bd76, 0x1a5c9640, 0xaa94b8bb, 0xeb740f69, 0xc3cdd261, 0x323b9c45, 0x957ff5dd, 0x8419a724, 0xcf5cf5c3,}; +const uint32_t exp_X_p_32[] = { 0x2,}; +const uint32_t exp_Y_p_32[] = { 0xc0ac270d, 0x6a920e46, 0x8b4cdbf7, 0x96bc5489, 0xdc34fba7, 0xc94c1e56, 0x5eb67c32, 0xa5cb5328, 0x2c08454e, 0x185d67c0, 0x3e0fc930, 0xc1d9a7ce, 0xf73a0e3d, 0x53793857, 0x321e02fe, 0xaee0f18e, 0xb90d3299, 0xc5d34dc6, 0xb22d47a0, 0x9d109034, 0x659ac869, 0xb2a2de08, 0x9f7fc81, 0x229e03b5, 0x3e84ebc3, 0x60838601, 0xc82c0d5c, 0x1d4c659a, 0x8af97f04, 0xda8a3379, 0xc81a8696, 0x31fbcfdd, }; +const uint32_t exp_Rinv_p_32[] = { 0x6787f727, 0xc0dc79ce, 0x22066424, 0x4c6a2bf8, 0x5b81cb65, 0x169a350a, 0x47a07b05, 0x2a086619, 0xe5143481, 0xaddd2a07, 0xf3087ad4, 0xb7e7b5cd, 0xeff1c6f6, 0xa35ab988, 0x3cb3c643, 0xd53b3480, 0xcda6a846, 0xd51c411a, 0x840fea4, 0x2b55e639, 0x680557e2, 0x46c77daf, 0x1d110ae6, 0x9cf0f62b, 0x51257507, 0x63d1c63e, 0xdaccc4cf, 0xe3af579d, 0xe58ed7b0, 0x6950d5aa, 0x21471db1, 0x4ca3e886, }; +const uint32_t exp_Z_p_32[] = { 0x72837fbb, 0xa05c374, 0x63313198, 0xb1279b89, 0xfa1d0aed, 0xeb85c9fe, 0x9d459304, 0x6b756906, 0x4df3a615, 0xe70a90f6, 0xf9354188, 0xf3bc207, 0xa5b817c1, 0xdd4c5b68, 0x222da242, 0x8e683e34, 0xa6674536, 0xfc607769, 0x7a6dd910, 0x36c37489, 0x2ae01e97, 0x87ed74ef, 0xb7528452, 0x242a381f, 0xf886bd3e, 0xb8240556, 0x7ae70a33, 0x9c193652, 0x636c4ab6, 0x11be9d23, 0x1ea9b22b, 0x368a3229, }; + +const uint32_t exp_M_p_33[] = { 0xd2f86373, 0x7dc0eddd, 0x1a27c06f, 0xbe6e3437, 0xa3fa8342, 0x47be20c9, 0x4532cdf5, 0x728e8766, 0x31e46aa7, 0xdc5e8c72, 0xba39c6b2, 0x29c291b4, 0xab5f5cf4, 0xa90e51bb, 0xfc1e677d, 0x5347c68a, 0xd95f7d6, 0xae98132b, 0x135c643c, 0x2e9e82e9, 0x5a540609, 0x3274e472, 0xb24222d0, 0x9153bd76, 0x1a5c9640, 0xaa94b8bb, 0xeb740f69, 0xc3cdd261, 0x323b9c45, 0x957ff5dd, 0x8419a724, 0xcf5cf5c3,}; +const uint32_t exp_X_p_33[] = { 0xf17d532d, 0x9136fa85, 0x5daf568, 0x36bed5aa, 0x4e2e5ca1, 0x90ca0228, 0x5d795c60, 0x264a452a, 0xe88187b5, 0x400f8fd8, 0x834268f1, 0x876eb7ee, 0x5165b72c, 0x162dd5ba, 0x4034c1f2, 0x6e58383, 0xb26c5b24, 0x7bbe3afb, 0x9722db6b, 0xe6624ae8, 0x1546d7dd, 0xddc0b14f, 0xf10ed6c2, 0x5dcfd1f9, 0x43658bc4, 0x18084e67, 0xf2b57c8a, 0x445d45f1, 0xc1465fff, 0xa7efdf9e, 0x632d9e50, 0xbdad66c8,}; +const uint32_t exp_Y_p_33[] = { 0xa9e42102, 0x5ab4a0f, 0xc529b673, 0x1684435d, 0x33f2d8fb, 0xdb42b4e7, 0x103e8eb9, 0xbf8de4ed, 0x91537869, 0x11c88a96, 0xcdff05bd, 0x157f8be2, 0xf6c63d3d, 0x36e4ee76, 0xd15c29a7, 0x3e6071e0, 0x3e2b0c1d, 0x54444d19, 0x62699c34, 0xe9ffd47a, 0x1acf4cb1, 0x3617251a, 0x29a256a, 0x884c0e32, 0xcb883a85, 0xcf364770, 0xa5f2da4, 0x32166b1f, 0xda3deaf5, 0xb4fed79a, 0xa82ccab3, 0x471cc5f6, }; +const uint32_t exp_Rinv_p_33[] = { 0x6787f727, 0xc0dc79ce, 0x22066424, 0x4c6a2bf8, 0x5b81cb65, 0x169a350a, 0x47a07b05, 0x2a086619, 0xe5143481, 0xaddd2a07, 0xf3087ad4, 0xb7e7b5cd, 0xeff1c6f6, 0xa35ab988, 0x3cb3c643, 0xd53b3480, 0xcda6a846, 0xd51c411a, 0x840fea4, 0x2b55e639, 0x680557e2, 0x46c77daf, 0x1d110ae6, 0x9cf0f62b, 0x51257507, 0x63d1c63e, 0xdaccc4cf, 0xe3af579d, 0xe58ed7b0, 0x6950d5aa, 0x21471db1, 0x4ca3e886, }; +const uint32_t exp_Z_p_33[] = { 0xe0fc973d, 0xf77f5348, 0x3a34dcb9, 0x7c323908, 0xd6c67c28, 0x2844e745, 0x51819313, 0x5495d3fc, 0x5a52558f, 0x7b6f5c96, 0x1d74077e, 0xb987d7b1, 0xe2b04598, 0xe81a5a33, 0xfa3ec8e3, 0x4c28e076, 0x49e971eb, 0xfc954377, 0x81edfd23, 0xf59a8dd4, 0x9186e5e4, 0xf3136a00, 0x9cdba411, 0x1ca4bb10, 0x8a32ca07, 0xf17b5b75, 0x24083905, 0xcbaefcb, 0x284ae12, 0Xc030e665, 0X24600e91, 0X631b2a91 }; + +const uint32_t* exp_test_cases_M_p[EXP_TEST_CASES_NUM] = { + exp_M_p_1, exp_M_p_2, exp_M_p_3, exp_M_p_4, exp_M_p_5, exp_M_p_6, exp_M_p_7, exp_M_p_8, exp_M_p_9, exp_M_p_10, exp_M_p_11, exp_M_p_12, exp_M_p_13, exp_M_p_14, exp_M_p_15, exp_M_p_16, exp_M_p_17, exp_M_p_18, exp_M_p_19, exp_M_p_20, exp_M_p_21, exp_M_p_22, exp_M_p_23, exp_M_p_24, exp_M_p_25, exp_M_p_26, exp_M_p_27, exp_M_p_28, exp_M_p_29, exp_M_p_30, exp_M_p_31, exp_M_p_32, exp_M_p_33, +}; + +const uint32_t* exp_test_cases_X_p[EXP_TEST_CASES_NUM] = { + exp_X_p_1, exp_X_p_2, exp_X_p_3, exp_X_p_4, exp_X_p_5, exp_X_p_6, exp_X_p_7, exp_X_p_8, exp_X_p_9, exp_X_p_10, exp_X_p_11, exp_X_p_12, exp_X_p_13, exp_X_p_14, exp_X_p_15, exp_X_p_16, exp_X_p_17, exp_X_p_18, exp_X_p_19, exp_X_p_20, exp_X_p_21, exp_X_p_22, exp_X_p_23, exp_X_p_24, exp_X_p_25, exp_X_p_26, exp_X_p_27, exp_X_p_28, exp_X_p_29, exp_X_p_30, exp_X_p_31, exp_X_p_32, exp_X_p_33, +}; + +const uint32_t* exp_test_cases_Y_p[EXP_TEST_CASES_NUM] = { + exp_Y_p_1, exp_Y_p_2, exp_Y_p_3, exp_Y_p_4, exp_Y_p_5, exp_Y_p_6, exp_Y_p_7, exp_Y_p_8, exp_Y_p_9, exp_Y_p_10, exp_Y_p_11, exp_Y_p_12, exp_Y_p_13, exp_Y_p_14, exp_Y_p_15, exp_Y_p_16, exp_Y_p_17, exp_Y_p_18, exp_Y_p_19, exp_Y_p_20, exp_Y_p_21, exp_Y_p_22, exp_Y_p_23, exp_Y_p_24, exp_Y_p_25, exp_Y_p_26, exp_Y_p_27, exp_Y_p_28, exp_Y_p_29, exp_Y_p_30, exp_Y_p_31, exp_Y_p_32, exp_Y_p_33, +}; + +const uint32_t* exp_test_cases_Rinv_p[EXP_TEST_CASES_NUM] = { + exp_Rinv_p_1, exp_Rinv_p_2, exp_Rinv_p_3, exp_Rinv_p_4, exp_Rinv_p_5, exp_Rinv_p_6, exp_Rinv_p_7, exp_Rinv_p_8, exp_Rinv_p_9, exp_Rinv_p_10, exp_Rinv_p_11, exp_Rinv_p_12, exp_Rinv_p_13, exp_Rinv_p_14, exp_Rinv_p_15, exp_Rinv_p_16, exp_Rinv_p_17, exp_Rinv_p_18, exp_Rinv_p_19, exp_Rinv_p_20, exp_Rinv_p_21, exp_Rinv_p_22, exp_Rinv_p_23, exp_Rinv_p_24, exp_Rinv_p_25, exp_Rinv_p_26, exp_Rinv_p_27, exp_Rinv_p_28, exp_Rinv_p_29, exp_Rinv_p_30, exp_Rinv_p_31, exp_Rinv_p_32, exp_Rinv_p_33, +}; + +const uint32_t* exp_test_cases_Z_p[EXP_TEST_CASES_NUM] = { + exp_Z_p_1, exp_Z_p_2, exp_Z_p_3, exp_Z_p_4, exp_Z_p_5, exp_Z_p_6, exp_Z_p_7, exp_Z_p_8, exp_Z_p_9, exp_Z_p_10, exp_Z_p_11, exp_Z_p_12, exp_Z_p_13, exp_Z_p_14, exp_Z_p_15, exp_Z_p_16, exp_Z_p_17, exp_Z_p_18, exp_Z_p_19, exp_Z_p_20, exp_Z_p_21, exp_Z_p_22, exp_Z_p_23, exp_Z_p_24, exp_Z_p_25, exp_Z_p_26, exp_Z_p_27, exp_Z_p_28, exp_Z_p_29, exp_Z_p_30, exp_Z_p_31, exp_Z_p_32, exp_Z_p_33, +}; + +const uint32_t exp_test_cases_Mprime[EXP_TEST_CASES_NUM] = { + 0x1, 0x10000001, 0x1, 0x55555555, 0x5050505, 0x5005005, 0x50005, 0x5050505, 0xb90226b9, 0x5e75bb8d, 0x1, 0x1, 0x100001, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0xc71c71c7, 0x49249249, 0x49249249, 0x55555555, 0x60a2c147, 0x60a2c147, 0x60a2c147, 0x49249249, 0x2b458645, 0x2b458645, 0x2b458645, +}; + +size_t exp_test_cases_M_n[EXP_TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 32, 32, 32, +}; + +size_t exp_test_cases_X_n[EXP_TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 32, +}; + +size_t exp_test_cases_Y_n[EXP_TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 32, 32, 32, +}; + +size_t exp_test_cases_Rinv_n[EXP_TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 32, 32, +}; + +size_t exp_test_cases_Z_n[EXP_TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 32, 32, 32, +}; + +size_t exp_test_cases_num_words[EXP_TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 32, 32, 32, +}; + +size_t exp_test_cases_m_words[EXP_TEST_CASES_NUM] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 32, 32, 32, +}; + +size_t exp_test_cases_y_bits[EXP_TEST_CASES_NUM] = { + 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 9, 1, 1, 2, 0, 2, 0, 2, 0, 3, 1, 1, 0, 3, 3, 3, 33, 33, 33, 10, 1023, 1022, 1023, +}; diff --git a/components/hal/test_apps/mpi/pytest_mpi.py b/components/hal/test_apps/mpi/pytest_mpi.py new file mode 100644 index 0000000000..247537496a --- /dev/null +++ b/components/hal/test_apps/mpi/pytest_mpi.py @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.esp32c3 +@pytest.mark.esp32c6 +@pytest.mark.esp32h2 +@pytest.mark.generic +def test_bignum(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/hal/test_apps/mpi/sdkconfig.defaults b/components/hal/test_apps/mpi/sdkconfig.defaults new file mode 100644 index 0000000000..a4ba403514 --- /dev/null +++ b/components/hal/test_apps/mpi/sdkconfig.defaults @@ -0,0 +1,2 @@ +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=n diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 81a67bdc01..f19571e3e3 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -220,9 +220,8 @@ endif() # The other port-specific files don't override internal mbedTLS functions, they just add new functions. if(CONFIG_MBEDTLS_HARDWARE_MPI) - target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/esp_bignum.c" - "${COMPONENT_DIR}/port/${idf_target}/bignum.c" - ) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/bignum/esp_bignum.c" + "${COMPONENT_DIR}/port/bignum/bignum_alt.c") endif() if(CONFIG_MBEDTLS_HARDWARE_SHA) diff --git a/components/mbedtls/port/bignum/bignum_alt.c b/components/mbedtls/port/bignum/bignum_alt.c new file mode 100644 index 0000000000..f8ae1a1605 --- /dev/null +++ b/components/mbedtls/port/bignum/bignum_alt.c @@ -0,0 +1,227 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * 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 "hal/mpi_hal.h" + + +void esp_mpi_enable_hardware_hw_op( void ) +{ + esp_crypto_mpi_lock_acquire(); + + /* Enable RSA hardware */ + periph_module_enable(PERIPH_RSA_MODULE); + + mpi_hal_enable_hardware_hw_op(); +} + + +void esp_mpi_disable_hardware_hw_op( void ) +{ + mpi_hal_disable_hardware_hw_op(); + + /* Disable RSA hardware */ + periph_module_disable(PERIPH_RSA_MODULE); + + esp_crypto_mpi_lock_release(); +} + +size_t esp_mpi_hardware_words(size_t words) +{ + return mpi_hal_calc_hardware_words(words); +} + + +void esp_mpi_interrupt_enable(bool enable) +{ + mpi_hal_interrupt_enable(enable); +} + + +void esp_mpi_interrupt_clear(void) +{ + mpi_hal_clear_interrupt(); +} + + +/* Z = (X * Y) mod M */ +void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) +{ +#if CONFIG_IDF_TARGET_ESP32 + /* "mode" register loaded with number of 512-bit blocks, minus 1 */ + mpi_hal_set_mode((num_words / 16) - 1); +#else + mpi_hal_set_mode(num_words - 1); +#endif + + /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ + mpi_hal_write_to_mem_block(MPI_PARAM_M, 0, M->MBEDTLS_PRIVATE(p), M->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, X->MBEDTLS_PRIVATE(p), X->MBEDTLS_PRIVATE(n), num_words); + +#if !CONFIG_IDF_TARGET_ESP32 + mpi_hal_write_to_mem_block(MPI_PARAM_Y, 0, Y->MBEDTLS_PRIVATE(p), Y->MBEDTLS_PRIVATE(n), num_words); +#endif + + mpi_hal_write_to_mem_block(MPI_PARAM_Z, 0, Rinv->MBEDTLS_PRIVATE(p), Rinv->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_write_m_prime(Mprime); + +#if CONFIG_IDF_TARGET_ESP32 + mpi_hal_start_op(MPI_MULT); + mpi_hal_wait_op_complete(); + /* execute second stage */ + /* Load Y to X input memory block, rerun */ + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, Y->MBEDTLS_PRIVATE(p), Y->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_start_op(MPI_MULT); +#else + mpi_hal_start_op(MPI_MODMULT); +#endif + +} + + +/* Z = X * Y */ +void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) +{ + /* Copy X (right-extended) & Y (left-extended) to memory block */ + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, X->MBEDTLS_PRIVATE(p), X->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_write_to_mem_block(MPI_PARAM_Z, num_words * 4, Y->MBEDTLS_PRIVATE(p), Y->MBEDTLS_PRIVATE(n), num_words); + /* NB: as Y is left-exte, we don't zero the bottom words_mult words of Y block. + This is OK for now bec zeroing is done by hardware when we do esp_mpi_acquire_hardware(). + */ +#if CONFIG_IDF_TARGET_ESP32 + mpi_hal_write_m_prime(0); + /* "mode" register loaded with number of 512-bit blocks in result, + plus 7 (for range 9-12). (this is ((N~ / 32) - 1) + 8)) + */ + mpi_hal_set_mode(((num_words * 2) / 16) + 7); +#else + mpi_hal_set_mode(num_words * 2 - 1); +#endif + + mpi_hal_start_op(MPI_MULT); +} + + +/* Special-case of mbedtls_mpi_mult_mpi(), where we use hardware montgomery mod + multiplication to calculate an mbedtls_mpi_mult_mpi result where either + A or B are >2048 bits so can't use the standard multiplication method. + + Result (number of words, based on A bits + B bits) must still be less than 4096 bits. + + This case is simpler than the general case modulo multiply of + esp_mpi_mul_mpi_mod() because we can control the other arguments: + + * Modulus is chosen with M=(2^num_bits - 1) (ie M=R-1), so output + * Mprime and Rinv are therefore predictable as follows: + isn't actually modulo anything. + Mprime 1 + Rinv 1 + + (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv) +*/ + +void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) +{ + /* M = 2^num_words - 1, so block is entirely FF */ + for (int i = 0; i < num_words; i++) { + mpi_hal_write_at_offset(MPI_PARAM_M, i * 4, UINT32_MAX); + } + + /* Mprime = 1 */ + mpi_hal_write_m_prime(1); + +#if CONFIG_IDF_TARGET_ESP32 + /* "mode" register loaded with number of 512-bit blocks, minus 1 */ + mpi_hal_set_mode((num_words / 16) - 1); +#else + mpi_hal_set_mode(num_words - 1); +#endif + + /* Load X & Y */ + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, X->MBEDTLS_PRIVATE(p), X->MBEDTLS_PRIVATE(n), num_words); +#if !CONFIG_IDF_TARGET_ESP32 + mpi_hal_write_to_mem_block(MPI_PARAM_Y, 0, Y->MBEDTLS_PRIVATE(p), Y->MBEDTLS_PRIVATE(n), num_words); +#endif + /* Rinv = 1, write first word */ + mpi_hal_write_rinv(1); + + /* Zero out rest of the Rinv words */ + for (int i = 1; i < num_words; i++) { + mpi_hal_write_at_offset(MPI_PARAM_Z, i * 4, 0); + } + +#if CONFIG_IDF_TARGET_ESP32 + mpi_hal_start_op(MPI_MULT); + mpi_hal_wait_op_complete(); + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, Y->MBEDTLS_PRIVATE(p), Y->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_start_op(MPI_MULT); +#else + mpi_hal_start_op(MPI_MODMULT); +#endif +} + +#ifdef ESP_MPI_USE_MONT_EXP +int esp_mont_hw_op(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, mbedtls_mpi_uint Mprime, size_t hw_words, bool again) +{ + // Note Z may be the same pointer as X or Y + int ret = 0; + + // montgomery mult prepare + if (again == false) { + mpi_hal_write_to_mem_block(MPI_PARAM_M, 0, M->MBEDTLS_PRIVATE(p), M->MBEDTLS_PRIVATE(n), hw_words); + mpi_hal_write_m_prime(Mprime); + mpi_hal_set_mode((hw_words / 16) - 1); + } + + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, X->MBEDTLS_PRIVATE(p), X->MBEDTLS_PRIVATE(n), hw_words); + mpi_hal_write_to_mem_block(MPI_PARAM_Z, 0, Y->MBEDTLS_PRIVATE(p), Y->MBEDTLS_PRIVATE(n), hw_words); + + mpi_hal_start_op(MPI_MULT); + + Z->MBEDTLS_PRIVATE(s) = 1; // The sign of Z will be = M->s (but M->s is always 1) + MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, hw_words) ); + + /* Read back the result */ + mpi_hal_read_result_hw_op(Z->MBEDTLS_PRIVATE(p), Z->MBEDTLS_PRIVATE(n), hw_words); + + /* from HAC 14.36 - 3. If Z >= M then Z = Z - M */ + if (mbedtls_mpi_cmp_mpi(Z, M) >= 0) { + MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(Z, Z, M)); + } +cleanup: + return ret; +} + +#else +/* Z = (X ^ Y) mod M +*/ +void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) +{ + size_t y_bits = mbedtls_mpi_bitlen(Y); + mpi_hal_set_mode(num_words - 1); + + /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ + mpi_hal_write_to_mem_block(MPI_PARAM_X, 0, X->MBEDTLS_PRIVATE(p), X->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_write_to_mem_block(MPI_PARAM_Y, 0, Y->MBEDTLS_PRIVATE(p), Y->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_write_to_mem_block(MPI_PARAM_M, 0, M->MBEDTLS_PRIVATE(p), M->MBEDTLS_PRIVATE(n), num_words); + mpi_hal_write_to_mem_block(MPI_PARAM_Z, 0, Rinv->MBEDTLS_PRIVATE(p), Rinv->MBEDTLS_PRIVATE(n), num_words); + + mpi_hal_write_m_prime(Mprime); + + /* Enable acceleration options */ + mpi_hal_enable_constant_time(false); + mpi_hal_enable_search(true); + mpi_hal_set_search_position(y_bits - 1); + + /* Execute first stage montgomery multiplication */ + mpi_hal_start_op(MPI_MODEXP); + + mpi_hal_enable_search(false); +} +#endif //ESP_MPI_USE_MONT_EXP diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/bignum/esp_bignum.c similarity index 92% rename from components/mbedtls/port/esp_bignum.c rename to components/mbedtls/port/bignum/esp_bignum.c index 0cc987cbfa..8a84b6eec7 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/bignum/esp_bignum.c @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: Apache-2.0 * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileContributor: 2016-2023 Espressif Systems (Shanghai) CO LTD */ #include #include @@ -24,17 +24,16 @@ #include "esp_pm.h" #endif +#include "esp_private/periph_ctrl.h" + #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -#include "soc/hwcrypto_periph.h" -#include "soc/periph_defs.h" -#include "soc/soc_caps.h" - #include "bignum_impl.h" -#include +#include "mbedtls/bignum.h" +#include "hal/mpi_hal.h" /* Some implementation notes: * @@ -65,7 +64,7 @@ static esp_pm_lock_handle_t s_pm_sleep_lock; static IRAM_ATTR void esp_mpi_complete_isr(void *arg) { BaseType_t higher_woken; - esp_mpi_interrupt_clear(); + mpi_hal_clear_interrupt(); xSemaphoreGiveFromISR(op_complete_sem, &higher_woken); if (higher_woken) { @@ -76,8 +75,8 @@ static IRAM_ATTR void esp_mpi_complete_isr(void *arg) static esp_err_t esp_mpi_isr_initialise(void) { - esp_mpi_interrupt_clear(); - esp_mpi_interrupt_enable(true); + mpi_hal_clear_interrupt(); + mpi_hal_interrupt_enable(true); if (op_complete_sem == NULL) { op_complete_sem = xSemaphoreCreateBinary(); @@ -120,7 +119,7 @@ static int esp_mpi_wait_intr(void) esp_pm_lock_release(s_pm_sleep_lock); #endif // CONFIG_PM_ENABLE - esp_mpi_interrupt_enable(false); + mpi_hal_interrupt_enable(false); return 0; } @@ -208,8 +207,6 @@ cleanup: - - /* Z = (X * Y) mod M Not an mbedTLS function @@ -226,7 +223,7 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi size_t y_words = bits_to_words(y_bits); size_t m_words = bits_to_words(m_bits); size_t z_words = bits_to_words(z_bits); - size_t hw_words = esp_mpi_hardware_words(MAX(x_words, MAX(y_words, m_words))); /* longest operand */ + size_t hw_words = mpi_hal_calc_hardware_words(MAX(x_words, MAX(y_words, m_words))); /* longest operand */ mbedtls_mpi Rinv; mbedtls_mpi_uint Mprime; @@ -241,7 +238,8 @@ int esp_mpi_mul_mpi_mod(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Z, z_words)); - esp_mpi_read_result_hw_op(Z, z_words); + /* Read back the result */ + mpi_hal_read_result_hw_op(Z->MBEDTLS_PRIVATE(p), Z->MBEDTLS_PRIVATE(n), z_words); Z->MBEDTLS_PRIVATE(s) = X->MBEDTLS_PRIVATE(s) * Y->MBEDTLS_PRIVATE(s); cleanup: @@ -274,6 +272,7 @@ static size_t mbedtls_mpi_msb( const mbedtls_mpi *X ) return 0; } + /* * Montgomery exponentiation: Z = X ^ Y mod M (HAC 14.94) */ @@ -335,6 +334,7 @@ cleanup2: #endif //USE_MONT_EXPONENATIATION + /* * Z = X ^ Y mod M * @@ -358,7 +358,7 @@ static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_ /* "all numbers must be the same length", so choose longest number as cardinal length of operation... */ - size_t num_words = esp_mpi_hardware_words(MAX(m_words, MAX(x_words, y_words))); + size_t num_words = mpi_hal_calc_hardware_words(MAX(m_words, MAX(x_words, y_words))); if (num_words * 32 > SOC_RSA_MAX_BIT_LEN) { return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; @@ -420,7 +420,9 @@ static int esp_mpi_exp_mod( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_ } #endif //CONFIG_MBEDTLS_MPI_USE_INTERRUPT - esp_mpi_read_result_hw_op(Z, m_words); + /* Read back the result */ + mpi_hal_read_result_hw_op(Z->MBEDTLS_PRIVATE(p), Z->MBEDTLS_PRIVATE(n), m_words); + esp_mpi_disable_hardware_hw_op(); #endif @@ -479,7 +481,7 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi size_t x_words = bits_to_words(x_bits); size_t y_words = bits_to_words(y_bits); size_t z_words = bits_to_words(x_bits + y_bits); - size_t hw_words = esp_mpi_hardware_words(MAX(x_words, y_words)); // length of one operand in hardware + size_t hw_words = mpi_hal_calc_hardware_words(MAX(x_words, y_words)); // length of one operand in hardware /* Short-circuit eval if either argument is 0 or 1. @@ -534,7 +536,9 @@ int mbedtls_mpi_mul_mpi( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi esp_mpi_enable_hardware_hw_op(); esp_mpi_mul_mpi_hw_op(X, Y, hw_words); - esp_mpi_read_result_hw_op(Z, z_words); + + /* Read back the result */ + mpi_hal_read_result_hw_op(Z->MBEDTLS_PRIVATE(p), Z->MBEDTLS_PRIVATE(n), z_words); esp_mpi_disable_hardware_hw_op(); @@ -612,34 +616,19 @@ cleanup: return ret; } -/* Special-case of mbedtls_mpi_mult_mpi(), where we use hardware montgomery mod - multiplication to calculate an mbedtls_mpi_mult_mpi result where either - A or B are >2048 bits so can't use the standard multiplication method. - - Result (number of words, based on A bits + B bits) must still be less than 4096 bits. - - This case is simpler than the general case modulo multiply of - esp_mpi_mul_mpi_mod() because we can control the other arguments: - - * Modulus is chosen with M=(2^num_bits - 1) (ie M=R-1), so output - * Mprime and Rinv are therefore predictable as follows: - isn't actually modulo anything. - Mprime 1 - Rinv 1 - - (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv) -*/ static int mpi_mult_mpi_failover_mod_mult( mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t z_words) { int ret; - size_t hw_words = esp_mpi_hardware_words(z_words); + size_t hw_words = mpi_hal_calc_hardware_words(z_words); esp_mpi_enable_hardware_hw_op(); esp_mpi_mult_mpi_failover_mod_mult_hw_op(X, Y, hw_words ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, hw_words) ); - esp_mpi_read_result_hw_op(Z, hw_words); + + /* Read back the result */ + mpi_hal_read_result_hw_op(Z->MBEDTLS_PRIVATE(p), Z->MBEDTLS_PRIVATE(n), hw_words); Z->MBEDTLS_PRIVATE(s) = X->MBEDTLS_PRIVATE(s) * Y->MBEDTLS_PRIVATE(s); /* diff --git a/components/mbedtls/port/esp32/bignum.c b/components/mbedtls/port/esp32/bignum.c deleted file mode 100644 index ce6b1ca41d..0000000000 --- a/components/mbedtls/port/esp32/bignum.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Multi-precision integer library - * ESP32 hardware accelerated parts based on mbedTLS implementation - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD - */ -#include "soc/hwcrypto_periph.h" -#include "soc/dport_reg.h" -#include "esp_private/periph_ctrl.h" -#include -#include "bignum_impl.h" -#include -#include - -static _lock_t mpi_lock; - -/* Round up number of words to nearest - 512 bit (16 word) block count. -*/ -size_t esp_mpi_hardware_words(size_t words) -{ - return (words + 0xF) & ~0xF; -} - -void esp_mpi_enable_hardware_hw_op( void ) -{ - /* newlib locks lazy initialize on ESP-IDF */ - _lock_acquire(&mpi_lock); - - /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); - DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); - - while (DPORT_REG_READ(RSA_CLEAN_REG) != 1) - { } - // Note: from enabling RSA clock to here takes about 1.3us -} - -void esp_mpi_disable_hardware_hw_op( void ) -{ - DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); - - /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); - - _lock_release(&mpi_lock); -} - - -void esp_mpi_interrupt_enable( bool enable ) -{ - DPORT_REG_WRITE(RSA_INTERRUPT_REG, enable); -} - -void esp_mpi_interrupt_clear( void ) -{ - DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); -} - -/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. - - If hw_words is higher than the number of words in the bignum then - these additional words will be zeroed in the memory buffer. - -*/ - -/* Please see detailed note inside the function body below. - * Relevant: IDF-6029 - https://github.com/espressif/esp-idf/issues/8710 - https://github.com/espressif/esp-idf/issues/10403 - */ -static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t hw_words) -{ - uint32_t copy_words = MIN(hw_words, mpi->MBEDTLS_PRIVATE(n)); - - /* Copy MPI data to memory block registers */ - for (uint32_t i = 0; i < copy_words; i++) { - DPORT_REG_WRITE(mem_base + i * 4, mpi->MBEDTLS_PRIVATE(p[i])); - } - - /* Zero any remaining memory block data */ - for (uint32_t i = copy_words; i < hw_words; i++) { - DPORT_REG_WRITE(mem_base + i * 4, 0); - } - -#if _INTERNAL_DEBUG_PURPOSE - /* - * With Xtensa GCC 11.2.0 (from ESP-IDF v5.x), it was observed that above zero initialization - * loop gets optimized to `memset` call from the ROM library. This was causing an issue that - * specific write (store) operation to the MPI peripheral block was getting lost erroneously. - * Following data re-verify loop could catch it during runtime. - * - * As a workaround, we are using DPORT_WRITE_REG (volatile writes) wrappers to write to - * the MPI peripheral. - * - */ - - //for (uint32_t i = copy_words; i < hw_words; i++) { assert(pbase[i] == 0); } -#endif -} - -/* Read mbedTLS MPI bignum back from hardware memory block. - - Reads num_words words from block. - - Bignum 'x' should already be grown to at least num_words by caller (can be done while - calculation is in progress, to save some cycles) -*/ -static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, size_t num_words) -{ - assert(x->MBEDTLS_PRIVATE(n) >= num_words); - - /* Copy data from memory block registers */ - esp_dport_access_read_buffer(x->MBEDTLS_PRIVATE(p), mem_base, num_words); - - /* Zero any remaining limbs in the bignum, if the buffer is bigger - than num_words */ - for (size_t i = num_words; i < x->MBEDTLS_PRIVATE(n); i++) { - x->MBEDTLS_PRIVATE(p[i]) = 0; - } -} - - -/* Begin an RSA operation. op_reg specifies which 'START' register - to write to. -*/ -static inline void start_op(uint32_t op_reg) -{ - /* Clear interrupt status */ - DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); - - /* Note: above REG_WRITE includes a memw, so we know any writes - to the memory blocks are also complete. */ - - DPORT_REG_WRITE(op_reg, 1); -} - -/* Wait for an RSA operation to complete. -*/ -static inline void wait_op_complete(void) -{ - while (DPORT_REG_READ(RSA_INTERRUPT_REG) != 1) - { } - - /* clear the interrupt */ - DPORT_REG_WRITE(RSA_INTERRUPT_REG, 1); -} - -/* Read result from last MPI operation */ -void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words) -{ - wait_op_complete(); - mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words); -} - -/* Z = (X * Y) mod M */ -void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t hw_words) -{ - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, hw_words); - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, hw_words); - DPORT_REG_WRITE(RSA_M_DASH_REG, (uint32_t)Mprime); - - /* "mode" register loaded with number of 512-bit blocks, minus 1 */ - DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hw_words / 16) - 1); - - /* Execute first stage montgomery multiplication */ - start_op(RSA_MULT_START_REG); - - wait_op_complete(); - - /* execute second stage */ - /* Load Y to X input memory block, rerun */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, Y, hw_words); - - start_op(RSA_MULT_START_REG); -} - -/* Z = X * Y */ -void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t hw_words) -{ - /* Copy X (right-extended) & Y (left-extended) to memory block */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words); - mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + hw_words * 4, Y, hw_words); - /* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block. - This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware(). - */ - - DPORT_REG_WRITE(RSA_M_DASH_REG, 0); - - /* "mode" register loaded with number of 512-bit blocks in result, - plus 7 (for range 9-12). (this is ((N~ / 32) - 1) + 8)) - */ - DPORT_REG_WRITE(RSA_MULT_MODE_REG, ((hw_words * 2) / 16) + 7); - - start_op(RSA_MULT_START_REG); - -} - - -int esp_mont_hw_op(mbedtls_mpi *Z, const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, - mbedtls_mpi_uint Mprime, - size_t hw_words, - bool again) -{ - // Note Z may be the same pointer as X or Y - int ret = 0; - - // montgomery mult prepare - if (again == false) { - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, hw_words); - DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime); - DPORT_REG_WRITE(RSA_MULT_MODE_REG, hw_words / 16 - 1); - } - - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Y, hw_words); - - start_op(RSA_MULT_START_REG); - Z->MBEDTLS_PRIVATE(s) = 1; // The sign of Z will be = M->s (but M->s is always 1) - MBEDTLS_MPI_CHK( mbedtls_mpi_grow(Z, hw_words) ); - - wait_op_complete(); - - /* Read back the result */ - mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, hw_words); - - - /* from HAC 14.36 - 3. If Z >= M then Z = Z - M */ - if (mbedtls_mpi_cmp_mpi(Z, M) >= 0) { - MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(Z, Z, M)); - } -cleanup: - return ret; -} - - - -/* Special-case of mbedtls_mpi_mult_mpi(), where we use hardware montgomery mod - multiplication to calculate an mbedtls_mpi_mult_mpi result where either - A or B are >2048 bits so can't use the standard multiplication method. - - Result (z_words, based on A bits + B bits) must still be less than 4096 bits. - - This case is simpler than the general case modulo multiply of - esp_mpi_mul_mpi_mod() because we can control the other arguments: - - * Modulus is chosen with M=(2^num_bits - 1) (ie M=R-1), so output - isn't actually modulo anything. - * Mprime and Rinv are therefore predictable as follows: - Mprime = 1 - Rinv = 1 - - (See RSA Accelerator section in Technical Reference for more about Mprime, Rinv) -*/ -void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - size_t hw_words = num_words; - - /* M = 2^num_words - 1, so block is entirely FF */ - for (size_t i = 0; i < hw_words; i++) { - DPORT_REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX); - } - /* Mprime = 1 */ - DPORT_REG_WRITE(RSA_M_DASH_REG, 1); - - /* "mode" register loaded with number of 512-bit blocks, minus 1 */ - DPORT_REG_WRITE(RSA_MULT_MODE_REG, (hw_words / 16) - 1); - - /* Load X */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, hw_words); - - /* Rinv = 1, write first word */ - DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1); - - /* Zero out rest of the Rinv words */ - for (size_t i = 1; i < hw_words; i++) { - DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0); - } - - start_op(RSA_MULT_START_REG); - - wait_op_complete(); - - /* finish the modular multiplication */ - /* Load Y to X input memory block, rerun */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, Y, hw_words); - - start_op(RSA_MULT_START_REG); - -} diff --git a/components/mbedtls/port/esp32c3/bignum.c b/components/mbedtls/port/esp32c3/bignum.c deleted file mode 100644 index fc5380f4ea..0000000000 --- a/components/mbedtls/port/esp32c3/bignum.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Multi-precision integer library - * ESP32 C3 hardware accelerated parts based on mbedTLS implementation - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD - */ -#include -#include -#include "soc/hwcrypto_periph.h" -#include "esp_private/periph_ctrl.h" -#include "mbedtls/bignum.h" -#include "bignum_impl.h" -#include "soc/system_reg.h" -#include "soc/periph_defs.h" -#include "esp_crypto_lock.h" - - -size_t esp_mpi_hardware_words(size_t words) -{ - return words; -} - -void esp_mpi_enable_hardware_hw_op( void ) -{ - esp_crypto_mpi_lock_acquire(); - - /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); - - REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); - - while (REG_READ(RSA_QUERY_CLEAN_REG) != 1) { - } - // Note: from enabling RSA clock to here takes about 1.3us - - REG_WRITE(RSA_INTERRUPT_REG, 0); -} - -void esp_mpi_disable_hardware_hw_op( void ) -{ - REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); - - /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); - - esp_crypto_mpi_lock_release(); -} - -void esp_mpi_interrupt_enable( bool enable ) -{ - REG_WRITE(RSA_INTERRUPT_REG, enable); -} - -void esp_mpi_interrupt_clear( void ) -{ - REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); -} - -/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. - - If num_words is higher than the number of words in the bignum then - these additional words will be zeroed in the memory buffer. -*/ -static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words) -{ - uint32_t *pbase = (uint32_t *)mem_base; - uint32_t copy_words = MIN(num_words, mpi->MBEDTLS_PRIVATE(n)); - - /* Copy MPI data to memory block registers */ - for (int i = 0; i < copy_words; i++) { - pbase[i] = mpi->MBEDTLS_PRIVATE(p)[i]; - } - - /* Zero any remaining memory block data */ - for (int i = copy_words; i < num_words; i++) { - pbase[i] = 0; - } -} - -/* Read mbedTLS MPI bignum back from hardware memory block. - - Reads num_words words from block. -*/ -static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words) -{ - - /* Copy data from memory block registers */ - const size_t REG_WIDTH = sizeof(uint32_t); - for (size_t i = 0; i < num_words; i++) { - x->MBEDTLS_PRIVATE(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 < x->MBEDTLS_PRIVATE(n); i++) { - x->MBEDTLS_PRIVATE(p)[i] = 0; - } -} - - - -/* Begin an RSA operation. op_reg specifies which 'START' register - to write to. -*/ -static inline void start_op(uint32_t op_reg) -{ - /* Clear interrupt status */ - REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); - - /* Note: above REG_WRITE includes a memw, so we know any writes - to the memory blocks are also complete. */ - - REG_WRITE(op_reg, 1); -} - -/* Wait for an RSA operation to complete. -*/ -static inline void wait_op_complete(void) -{ - while (REG_READ(RSA_QUERY_INTERRUPT_REG) != 1) - { } - - /* clear the interrupt */ - REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); -} - - -/* Read result from last MPI operation */ -void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words) -{ - wait_op_complete(); - mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words); -} - - -/* Z = (X * Y) mod M - - Not an mbedTLS function -*/ -void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); - REG_WRITE(RSA_M_DASH_REG, Mprime); - - start_op(RSA_MOD_MULT_START_REG); -} - -/* Z = (X ^ Y) mod M -*/ -void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - size_t y_bits = mbedtls_mpi_bitlen(Y); - - REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); - REG_WRITE(RSA_M_DASH_REG, Mprime); - - /* Enable acceleration options */ - REG_WRITE(RSA_CONSTANT_TIME_REG, 0); - REG_WRITE(RSA_SEARCH_ENABLE_REG, 1); - REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1); - - /* Execute first stage montgomery multiplication */ - start_op(RSA_MODEXP_START_REG); - - REG_WRITE(RSA_SEARCH_ENABLE_REG, 0); -} - - -/* Z = X * Y */ -void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* Copy X (right-extended) & Y (left-extended) to memory block */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + num_words * 4, Y, num_words); - /* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block. - This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware(). - */ - REG_WRITE(RSA_LENGTH_REG, (num_words * 2 - 1)); - start_op(RSA_MULT_START_REG); -} - - - -/** - * @brief Special-case of (X * Y), where we use hardware montgomery mod - multiplication to calculate result where either A or B are >2048 bits so - can't use the standard multiplication method. - * - */ -void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* M = 2^num_words - 1, so block is entirely FF */ - for (int i = 0; i < num_words; i++) { - REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX); - } - - /* Mprime = 1 */ - REG_WRITE(RSA_M_DASH_REG, 1); - REG_WRITE(RSA_LENGTH_REG, num_words - 1); - - /* Load X & Y */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - - /* Rinv = 1, write first word */ - REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1); - - /* Zero out rest of the Rinv words */ - for (int i = 1; i < num_words; i++) { - REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0); - } - - start_op(RSA_MOD_MULT_START_REG); -} diff --git a/components/mbedtls/port/esp32c6/bignum.c b/components/mbedtls/port/esp32c6/bignum.c deleted file mode 100644 index cbd8ad28c7..0000000000 --- a/components/mbedtls/port/esp32c6/bignum.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Multi-precision integer library - * ESP32 C6 hardware accelerated parts based on mbedTLS implementation - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD - */ -#include -#include -#include "soc/hwcrypto_periph.h" -#include "esp_private/periph_ctrl.h" -#include "mbedtls/bignum.h" -#include "bignum_impl.h" -#include "soc/pcr_reg.h" -#include "soc/periph_defs.h" -#include "soc/system_reg.h" -#include "esp_crypto_lock.h" - - -size_t esp_mpi_hardware_words(size_t words) -{ - return words; -} - -void esp_mpi_enable_hardware_hw_op( void ) -{ - esp_crypto_mpi_lock_acquire(); - - /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); - - REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); - - while (REG_READ(RSA_QUERY_CLEAN_REG) != 1) { - } - // Note: from enabling RSA clock to here takes about 1.3us - - REG_WRITE(RSA_INT_ENA_REG, 0); -} - -void esp_mpi_disable_hardware_hw_op( void ) -{ - REG_SET_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); - - /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); - - esp_crypto_mpi_lock_release(); -} - -void esp_mpi_interrupt_enable( bool enable ) -{ - REG_WRITE(RSA_INT_ENA_REG, enable); -} - -void esp_mpi_interrupt_clear( void ) -{ - REG_WRITE(RSA_INT_CLR_REG, 1); -} - -/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. - - If num_words is higher than the number of words in the bignum then - these additional words will be zeroed in the memory buffer. -*/ -static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words) -{ - uint32_t *pbase = (uint32_t *)mem_base; - uint32_t copy_words = MIN(num_words, mpi->MBEDTLS_PRIVATE(n)); - - /* Copy MPI data to memory block registers */ - for (int i = 0; i < copy_words; i++) { - pbase[i] = mpi->MBEDTLS_PRIVATE(p)[i]; - } - - /* Zero any remaining memory block data */ - for (int i = copy_words; i < num_words; i++) { - pbase[i] = 0; - } -} - -/* Read mbedTLS MPI bignum back from hardware memory block. - - Reads num_words words from block. -*/ -static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words) -{ - - /* Copy data from memory block registers */ - const size_t REG_WIDTH = sizeof(uint32_t); - for (size_t i = 0; i < num_words; i++) { - x->MBEDTLS_PRIVATE(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 < x->MBEDTLS_PRIVATE(n); i++) { - x->MBEDTLS_PRIVATE(p)[i] = 0; - } -} - - - -/* Begin an RSA operation. op_reg specifies which 'START' register - to write to. -*/ -static inline void start_op(uint32_t op_reg) -{ - /* Clear interrupt status */ - REG_WRITE(RSA_INT_CLR_REG, 1); - - /* Note: above REG_WRITE includes a memw, so we know any writes - to the memory blocks are also complete. */ - - REG_WRITE(op_reg, 1); -} - -/* Wait for an RSA operation to complete. -*/ -static inline void wait_op_complete(void) -{ - while (REG_READ(RSA_QUERY_IDLE_REG) != 1) - { } - - /* clear the interrupt */ - REG_WRITE(RSA_INT_CLR_REG, 1); -} - - -/* Read result from last MPI operation */ -void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words) -{ - wait_op_complete(); - mem_block_to_mpi(Z, RSA_Z_MEM, z_words); -} - - -/* Z = (X * Y) mod M - - Not an mbedTLS function -*/ -void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - REG_WRITE(RSA_MODE_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_X_MEM, X, num_words); - mpi_to_mem_block(RSA_Y_MEM, Y, num_words); - mpi_to_mem_block(RSA_M_MEM, M, num_words); - mpi_to_mem_block(RSA_Z_MEM, Rinv, num_words); - REG_WRITE(RSA_M_PRIME_REG, Mprime); - - start_op(RSA_SET_START_MODMULT_REG); -} - -/* Z = (X ^ Y) mod M -*/ -void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - size_t y_bits = mbedtls_mpi_bitlen(Y); - - REG_WRITE(RSA_MODE_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_X_MEM, X, num_words); - mpi_to_mem_block(RSA_Y_MEM, Y, num_words); - mpi_to_mem_block(RSA_M_MEM, M, num_words); - mpi_to_mem_block(RSA_Z_MEM, Rinv, num_words); - REG_WRITE(RSA_M_PRIME_REG, Mprime); - - /* Enable acceleration options */ - REG_WRITE(RSA_CONSTANT_TIME_REG, 0); - REG_WRITE(RSA_SEARCH_ENABLE_REG, 1); - REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1); - - /* Execute first stage montgomery multiplication */ - start_op(RSA_SET_START_MODEXP_REG); - - REG_WRITE(RSA_SEARCH_ENABLE_REG, 0); -} - - -/* Z = X * Y */ -void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* Copy X (right-extended) & Y (left-extended) to memory block */ - mpi_to_mem_block(RSA_X_MEM, X, num_words); - mpi_to_mem_block(RSA_Z_MEM + num_words * 4, Y, num_words); - /* NB: as Y is left-exte, we don't zero the bottom words_mult words of Y block. - This is OK for now bec zeroing is done by hardware when we do esp_mpi_acquire_hardware(). - */ - REG_WRITE(RSA_MODE_REG, (num_words * 2 - 1)); - start_op(RSA_SET_START_MULT_REG); -} - - - -/** - * @brief Special-case of (X * Y), where we use hardware montgomery mod - multiplication to calculate result where either A or B are >2048 bits so - can't use the standard multiplication method. - * - */ -void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* M = 2^num_words - 1, so block is entirely FF */ - for (int i = 0; i < num_words; i++) { - REG_WRITE(RSA_M_MEM + i * 4, UINT32_MAX); - } - - /* Mprime = 1 */ - REG_WRITE(RSA_M_PRIME_REG, 1); - REG_WRITE(RSA_MODE_REG, num_words - 1); - - /* Load X & Y */ - mpi_to_mem_block(RSA_X_MEM, X, num_words); - mpi_to_mem_block(RSA_Y_MEM, Y, num_words); - - /* Rinv = 1, write first word */ - REG_WRITE(RSA_Z_MEM, 1); - - /* Zero out rest of the Rinv words */ - for (int i = 1; i < num_words; i++) { - REG_WRITE(RSA_Z_MEM + i * 4, 0); - } - - start_op(RSA_SET_START_MODMULT_REG); -} diff --git a/components/mbedtls/port/esp32h2/bignum.c b/components/mbedtls/port/esp32h2/bignum.c deleted file mode 100644 index 27c8878d94..0000000000 --- a/components/mbedtls/port/esp32h2/bignum.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Multi-precision integer library - * ESP32 H2 hardware accelerated parts based on mbedTLS implementation - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD - */ -#include -#include -#include "soc/hwcrypto_periph.h" -#include "esp_private/periph_ctrl.h" -#include "mbedtls/bignum.h" -#include "bignum_impl.h" -#include "soc/pcr_reg.h" -#include "soc/periph_defs.h" -#include "soc/system_reg.h" -#include "esp_crypto_lock.h" - - -size_t esp_mpi_hardware_words(size_t words) -{ - return words; -} - -void esp_mpi_enable_hardware_hw_op( void ) -{ - esp_crypto_mpi_lock_acquire(); - - /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); - - REG_CLR_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); - - while (REG_READ(RSA_QUERY_CLEAN_REG) != 1) { - } - // Note: from enabling RSA clock to here takes about 1.3us - - REG_WRITE(RSA_INT_ENA_REG, 0); -} - -void esp_mpi_disable_hardware_hw_op( void ) -{ - REG_SET_BIT(PCR_RSA_PD_CTRL_REG, PCR_RSA_MEM_PD); - - /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); - - esp_crypto_mpi_lock_release(); -} - -void esp_mpi_interrupt_enable( bool enable ) -{ - REG_WRITE(RSA_INT_ENA_REG, enable); -} - -void esp_mpi_interrupt_clear( void ) -{ - REG_WRITE(RSA_INT_CLR_REG, 1); -} - -/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. - - If num_words is higher than the number of words in the bignum then - these additional words will be zeroed in the memory buffer. -*/ -static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words) -{ - uint32_t *pbase = (uint32_t *)mem_base; - uint32_t copy_words = MIN(num_words, mpi->MBEDTLS_PRIVATE(n)); - - /* Copy MPI data to memory block registers */ - for (int i = 0; i < copy_words; i++) { - pbase[i] = mpi->MBEDTLS_PRIVATE(p)[i]; - } - - /* Zero any remaining memory block data */ - for (int i = copy_words; i < num_words; i++) { - pbase[i] = 0; - } -} - -/* Read mbedTLS MPI bignum back from hardware memory block. - - Reads num_words words from block. -*/ -static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words) -{ - - /* Copy data from memory block registers */ - const size_t REG_WIDTH = sizeof(uint32_t); - for (size_t i = 0; i < num_words; i++) { - x->MBEDTLS_PRIVATE(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 < x->MBEDTLS_PRIVATE(n); i++) { - x->MBEDTLS_PRIVATE(p)[i] = 0; - } -} - - - -/* Begin an RSA operation. op_reg specifies which 'START' register - to write to. -*/ -static inline void start_op(uint32_t op_reg) -{ - /* Clear interrupt status */ - REG_WRITE(RSA_INT_CLR_REG, 1); - - /* Note: above REG_WRITE includes a memw, so we know any writes - to the memory blocks are also complete. */ - - REG_WRITE(op_reg, 1); -} - -/* Wait for an RSA operation to complete. -*/ -static inline void wait_op_complete(void) -{ - while (REG_READ(RSA_QUERY_IDLE_REG) != 1) - { } - - /* clear the interrupt */ - REG_WRITE(RSA_INT_CLR_REG, 1); -} - - -/* Read result from last MPI operation */ -void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words) -{ - wait_op_complete(); - mem_block_to_mpi(Z, RSA_Z_MEM_REG, z_words); -} - - -/* Z = (X * Y) mod M - - Not an mbedTLS function -*/ -void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - REG_WRITE(RSA_MODE_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_X_MEM_REG, X, num_words); - mpi_to_mem_block(RSA_Y_MEM_REG, Y, num_words); - mpi_to_mem_block(RSA_M_MEM_REG, M, num_words); - mpi_to_mem_block(RSA_Z_MEM_REG, Rinv, num_words); - REG_WRITE(RSA_M_PRIME_REG, Mprime); - - start_op(RSA_SET_START_MODMULT_REG); -} - -/* Z = (X ^ Y) mod M -*/ -void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - size_t y_bits = mbedtls_mpi_bitlen(Y); - - REG_WRITE(RSA_MODE_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_X_MEM_REG, X, num_words); - mpi_to_mem_block(RSA_Y_MEM_REG, Y, num_words); - mpi_to_mem_block(RSA_M_MEM_REG, M, num_words); - mpi_to_mem_block(RSA_Z_MEM_REG, Rinv, num_words); - REG_WRITE(RSA_M_PRIME_REG, Mprime); - - /* Enable acceleration options */ - REG_WRITE(RSA_CONSTANT_TIME_REG, 0); - REG_WRITE(RSA_SEARCH_ENABLE_REG, 1); - REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1); - - /* Execute first stage montgomery multiplication */ - start_op(RSA_SET_START_MODEXP_REG); - - REG_WRITE(RSA_SEARCH_ENABLE_REG, 0); -} - - -/* Z = X * Y */ -void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* Copy X (right-extended) & Y (left-extended) to memory block */ - mpi_to_mem_block(RSA_X_MEM_REG, X, num_words); - mpi_to_mem_block(RSA_Z_MEM_REG + num_words * 4, Y, num_words); - /* NB: as Y is left-exte, we don't zero the bottom words_mult words of Y block. - This is OK for now bec zeroing is done by hardware when we do esp_mpi_acquire_hardware(). - */ - REG_WRITE(RSA_MODE_REG, (num_words * 2 - 1)); - start_op(RSA_SET_START_MULT_REG); -} - - - -/** - * @brief Special-case of (X * Y), where we use hardware montgomery mod - multiplication to calculate result where either A or B are >2048 bits so - can't use the standard multiplication method. - * - */ -void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* M = 2^num_words - 1, so block is entirely FF */ - for (int i = 0; i < num_words; i++) { - REG_WRITE(RSA_M_MEM_REG + i * 4, UINT32_MAX); - } - - /* Mprime = 1 */ - REG_WRITE(RSA_M_PRIME_REG, 1); - REG_WRITE(RSA_MODE_REG, num_words - 1); - - /* Load X & Y */ - mpi_to_mem_block(RSA_X_MEM_REG, X, num_words); - mpi_to_mem_block(RSA_Y_MEM_REG, Y, num_words); - - /* Rinv = 1, write first word */ - REG_WRITE(RSA_Z_MEM_REG, 1); - - /* Zero out rest of the Rinv words */ - for (int i = 1; i < num_words; i++) { - REG_WRITE(RSA_Z_MEM_REG + i * 4, 0); - } - - start_op(RSA_SET_START_MODMULT_REG); -} diff --git a/components/mbedtls/port/esp32s2/bignum.c b/components/mbedtls/port/esp32s2/bignum.c deleted file mode 100644 index eeeeabc3b1..0000000000 --- a/components/mbedtls/port/esp32s2/bignum.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Multi-precision integer library - * ESP32 S2 hardware accelerated parts based on mbedTLS implementation - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD - */ -#include "soc/hwcrypto_periph.h" -#include "esp_private/periph_ctrl.h" -#include -#include "bignum_impl.h" -#include "soc/dport_reg.h" -#include "soc/periph_defs.h" -#include -#include "esp_crypto_lock.h" - -size_t esp_mpi_hardware_words(size_t words) -{ - return words; -} - -void esp_mpi_enable_hardware_hw_op( void ) -{ - esp_crypto_mpi_lock_acquire(); - - /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); - - DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_MEM_PD); - - while (DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) { - } - // Note: from enabling RSA clock to here takes about 1.3us - - REG_WRITE(RSA_INTERRUPT_REG, 0); -} - -void esp_mpi_disable_hardware_hw_op( void ) -{ - DPORT_REG_SET_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD); - - /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); - - esp_crypto_mpi_lock_release(); -} - -void esp_mpi_interrupt_enable( bool enable ) -{ - REG_WRITE(RSA_INTERRUPT_REG, enable); -} - -void esp_mpi_interrupt_clear( void ) -{ - REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); -} - -/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. - - If num_words is higher than the number of words in the bignum then - these additional words will be zeroed in the memory buffer. -*/ -static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words) -{ - uint32_t *pbase = (uint32_t *)mem_base; - uint32_t copy_words = MIN(num_words, mpi->MBEDTLS_PRIVATE(n)); - - /* Copy MPI data to memory block registers */ - for (uint32_t i = 0; i < copy_words; i++) { - pbase[i] = mpi->MBEDTLS_PRIVATE(p)[i]; - } - - /* Zero any remaining memory block data */ - for (uint32_t i = copy_words; i < num_words; i++) { - pbase[i] = 0; - } -} - -/* Read mbedTLS MPI bignum back from hardware memory block. - - Reads num_words words from block. -*/ -static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words) -{ - - /* Copy data from memory block registers */ - esp_dport_access_read_buffer(x->MBEDTLS_PRIVATE(p), mem_base, num_words); - /* Zero any remaining limbs in the bignum, if the buffer is bigger - than num_words */ - for (size_t i = num_words; i < x->MBEDTLS_PRIVATE(n); i++) { - x->MBEDTLS_PRIVATE(p)[i] = 0; - } -} - - - -/* Begin an RSA operation. op_reg specifies which 'START' register - to write to. -*/ -static inline void start_op(uint32_t op_reg) -{ - /* Clear interrupt status */ - DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); - - /* Note: above REG_WRITE includes a memw, so we know any writes - to the memory blocks are also complete. */ - - DPORT_REG_WRITE(op_reg, 1); -} - -/* Wait for an RSA operation to complete. -*/ -static inline void wait_op_complete(void) -{ - while (DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG) != 1) - { } - - /* clear the interrupt */ - DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); -} - - -/* Read result from last MPI operation */ -void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words) -{ - wait_op_complete(); - mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words); -} - - -/* Z = (X * Y) mod M - - Not an mbedTLS function -*/ -void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); - DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime); - - start_op(RSA_MOD_MULT_START_REG); -} - -/* Z = (X ^ Y) mod M -*/ -void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - size_t y_bits = mbedtls_mpi_bitlen(Y); - - DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); - DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime); - - /* Enable acceleration options */ - DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0); - DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 1); - DPORT_REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1); - - /* Execute first stage montgomery multiplication */ - start_op(RSA_MODEXP_START_REG); - - DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 0); -} - - -/* Z = X * Y */ -void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* Copy X (right-extended) & Y (left-extended) to memory block */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + num_words * 4, Y, num_words); - /* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block. - This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware(). - */ - DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words * 2 - 1)); - start_op(RSA_MULT_START_REG); -} - - - -/** - * @brief Special-case of (X * Y), where we use hardware montgomery mod - multiplication to calculate result where either A or B are >2048 bits so - can't use the standard multiplication method. - * - */ -void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* M = 2^num_words - 1, so block is entirely FF */ - for (size_t i = 0; i < num_words; i++) { - DPORT_REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX); - } - - /* Mprime = 1 */ - DPORT_REG_WRITE(RSA_M_DASH_REG, 1); - DPORT_REG_WRITE(RSA_LENGTH_REG, num_words - 1); - - /* Load X & Y */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - - /* Rinv = 1, write first word */ - DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1); - - /* Zero out rest of the Rinv words */ - for (size_t i = 1; i < num_words; i++) { - DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0); - } - - start_op(RSA_MOD_MULT_START_REG); -} diff --git a/components/mbedtls/port/esp32s3/bignum.c b/components/mbedtls/port/esp32s3/bignum.c deleted file mode 100644 index fe33dea2f0..0000000000 --- a/components/mbedtls/port/esp32s3/bignum.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Multi-precision integer library - * ESP32 S3 hardware accelerated parts based on mbedTLS implementation - * - * SPDX-FileCopyrightText: The Mbed TLS Contributors - * - * SPDX-License-Identifier: Apache-2.0 - * - * SPDX-FileContributor: 2016-2022 Espressif Systems (Shanghai) CO LTD - */ -#include "soc/hwcrypto_periph.h" -#include "esp_private/periph_ctrl.h" -#include -#include "bignum_impl.h" -#include "soc/dport_reg.h" -#include "soc/system_reg.h" -#include "soc/periph_defs.h" -#include -#include "esp_crypto_lock.h" - -size_t esp_mpi_hardware_words(size_t words) -{ - return words; -} - -void esp_mpi_enable_hardware_hw_op( void ) -{ - esp_crypto_mpi_lock_acquire(); - - /* Enable RSA hardware */ - periph_module_enable(PERIPH_RSA_MODULE); - - REG_CLR_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); - - while (DPORT_REG_READ(RSA_QUERY_CLEAN_REG) != 1) { - } - // Note: from enabling RSA clock to here takes about 1.3us - - REG_WRITE(RSA_INTERRUPT_REG, 0); - -} - -void esp_mpi_disable_hardware_hw_op( void ) -{ - REG_SET_BIT(SYSTEM_RSA_PD_CTRL_REG, SYSTEM_RSA_MEM_PD); - - /* Disable RSA hardware */ - periph_module_disable(PERIPH_RSA_MODULE); - - esp_crypto_mpi_lock_release(); -} - -void esp_mpi_interrupt_enable( bool enable ) -{ - REG_WRITE(RSA_INTERRUPT_REG, enable); -} - -void esp_mpi_interrupt_clear( void ) -{ - REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); -} - -/* Copy mbedTLS MPI bignum 'mpi' to hardware memory block at 'mem_base'. - - If num_words is higher than the number of words in the bignum then - these additional words will be zeroed in the memory buffer. -*/ -static inline void mpi_to_mem_block(uint32_t mem_base, const mbedtls_mpi *mpi, size_t num_words) -{ - uint32_t *pbase = (uint32_t *)mem_base; - uint32_t copy_words = MIN(num_words, mpi->MBEDTLS_PRIVATE(n)); - - /* Copy MPI data to memory block registers */ - for (uint32_t i = 0; i < copy_words; i++) { - pbase[i] = mpi->MBEDTLS_PRIVATE(p)[i]; - } - - /* Zero any remaining memory block data */ - for (uint32_t i = copy_words; i < num_words; i++) { - pbase[i] = 0; - } -} - -/* Read mbedTLS MPI bignum back from hardware memory block. - - Reads num_words words from block. -*/ -static inline void mem_block_to_mpi(mbedtls_mpi *x, uint32_t mem_base, int num_words) -{ - - /* Copy data from memory block registers */ - esp_dport_access_read_buffer(x->MBEDTLS_PRIVATE(p), mem_base, num_words); - /* Zero any remaining limbs in the bignum, if the buffer is bigger - than num_words */ - for (size_t i = num_words; i < x->MBEDTLS_PRIVATE(n); i++) { - x->MBEDTLS_PRIVATE(p)[i] = 0; - } -} - - - -/* Begin an RSA operation. op_reg specifies which 'START' register - to write to. -*/ -static inline void start_op(uint32_t op_reg) -{ - /* Clear interrupt status */ - DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); - - /* Note: above REG_WRITE includes a memw, so we know any writes - to the memory blocks are also complete. */ - - DPORT_REG_WRITE(op_reg, 1); -} - -/* Wait for an RSA operation to complete. -*/ -static inline void wait_op_complete(void) -{ - while (DPORT_REG_READ(RSA_QUERY_INTERRUPT_REG) != 1) - { } - - /* clear the interrupt */ - DPORT_REG_WRITE(RSA_CLEAR_INTERRUPT_REG, 1); -} - - -/* Read result from last MPI operation */ -void esp_mpi_read_result_hw_op(mbedtls_mpi *Z, size_t z_words) -{ - wait_op_complete(); - mem_block_to_mpi(Z, RSA_MEM_Z_BLOCK_BASE, z_words); -} - - -/* Z = (X * Y) mod M - - Not an mbedTLS function -*/ -void esp_mpi_mul_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); - DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime); - - start_op(RSA_MOD_MULT_START_REG); -} - -/* Z = (X ^ Y) mod M -*/ -void esp_mpi_exp_mpi_mod_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, const mbedtls_mpi *M, const mbedtls_mpi *Rinv, mbedtls_mpi_uint Mprime, size_t num_words) -{ - size_t y_bits = mbedtls_mpi_bitlen(Y); - - DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words - 1)); - - /* Load M, X, Rinv, Mprime (Mprime is mod 2^32) */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - mpi_to_mem_block(RSA_MEM_M_BLOCK_BASE, M, num_words); - mpi_to_mem_block(RSA_MEM_RB_BLOCK_BASE, Rinv, num_words); - DPORT_REG_WRITE(RSA_M_DASH_REG, Mprime); - - /* Enable acceleration options */ - DPORT_REG_WRITE(RSA_CONSTANT_TIME_REG, 0); - DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 1); - DPORT_REG_WRITE(RSA_SEARCH_POS_REG, y_bits - 1); - - /* Execute first stage montgomery multiplication */ - start_op(RSA_MODEXP_START_REG); - - DPORT_REG_WRITE(RSA_SEARCH_OPEN_REG, 0); -} - - -/* Z = X * Y */ -void esp_mpi_mul_mpi_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* Copy X (right-extended) & Y (left-extended) to memory block */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Z_BLOCK_BASE + num_words * 4, Y, num_words); - /* NB: as Y is left-extended, we don't zero the bottom words_mult words of Y block. - This is OK for now because zeroing is done by hardware when we do esp_mpi_acquire_hardware(). - */ - DPORT_REG_WRITE(RSA_LENGTH_REG, (num_words * 2 - 1)); - start_op(RSA_MULT_START_REG); -} - - - -/** - * @brief Special-case of (X * Y), where we use hardware montgomery mod - multiplication to calculate result where either A or B are >2048 bits so - can't use the standard multiplication method. - * - */ -void esp_mpi_mult_mpi_failover_mod_mult_hw_op(const mbedtls_mpi *X, const mbedtls_mpi *Y, size_t num_words) -{ - /* M = 2^num_words - 1, so block is entirely FF */ - for (size_t i = 0; i < num_words; i++) { - DPORT_REG_WRITE(RSA_MEM_M_BLOCK_BASE + i * 4, UINT32_MAX); - } - - /* Mprime = 1 */ - DPORT_REG_WRITE(RSA_M_DASH_REG, 1); - DPORT_REG_WRITE(RSA_LENGTH_REG, num_words - 1); - - /* Load X & Y */ - mpi_to_mem_block(RSA_MEM_X_BLOCK_BASE, X, num_words); - mpi_to_mem_block(RSA_MEM_Y_BLOCK_BASE, Y, num_words); - - /* Rinv = 1, write first word */ - DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE, 1); - - /* Zero out rest of the Rinv words */ - for (size_t i = 1; i < num_words; i++) { - DPORT_REG_WRITE(RSA_MEM_RB_BLOCK_BASE + i * 4, 0); - } - - start_op(RSA_MOD_MULT_START_REG); -} diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index 4c4fb9160c..1562eb4550 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -83,6 +83,10 @@ if(CONFIG_SOC_MCPWM_SUPPORTED) list(APPEND srcs "${target}/mcpwm_periph.c") endif() +if(CONFIG_SOC_MPI_SUPPORTED) + list(APPEND srcs "${target}/mpi_periph.c") +endif() + if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) list(APPEND srcs "${target}/sdmmc_periph.c") endif() diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index 08837fd384..de8340381b 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -691,6 +691,14 @@ config SOC_SHA_SUPPORT_SHA512 bool default y +config SOC_MPI_MEM_BLOCKS_NUM + int + default 4 + +config SOC_MPI_OPERATIONS_NUM + bool + default y + config SOC_RSA_MAX_BIT_LEN int default 4096 diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index ff223b9435..d1bbb6021e 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -340,6 +340,9 @@ #define SOC_SHA_SUPPORT_SHA384 (1) #define SOC_SHA_SUPPORT_SHA512 (1) +/*--------------------------- MPI CAPS ---------------------------------------*/ +#define SOC_MPI_MEM_BLOCKS_NUM (4) +#define SOC_MPI_OPERATIONS_NUM (1) /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (4096) diff --git a/components/soc/esp32/mpi_periph.c b/components/soc/esp32/mpi_periph.c new file mode 100644 index 0000000000..4bb547f0c6 --- /dev/null +++ b/components/soc/esp32/mpi_periph.c @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/hwcrypto_reg.h" +#include "soc/mpi_periph.h" + +const uint32_t MPI_LL_BLOCK_BASES[SOC_MPI_MEM_BLOCKS_NUM] = { + RSA_MEM_X_BLOCK_BASE, + RSA_MEM_Y_BLOCK_BASE, + RSA_MEM_Z_BLOCK_BASE, + RSA_MEM_M_BLOCK_BASE, +}; + +const uint32_t MPI_LL_OPERATIONS[SOC_MPI_OPERATIONS_NUM] = { + RSA_MULT_START_REG, +}; diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 2b2f9b3dd5..82d591bd61 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -535,6 +535,14 @@ config SOC_RTCIO_PIN_COUNT int default 0 +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/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 36578e982f..ade192c234 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -242,6 +242,10 @@ * for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */ #define SOC_RTCIO_PIN_COUNT (0U) +/*--------------------------- MPI CAPS ---------------------------------------*/ +#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/esp32c3/mpi_periph.c b/components/soc/esp32c3/mpi_periph.c new file mode 100644 index 0000000000..c9f3870045 --- /dev/null +++ b/components/soc/esp32c3/mpi_periph.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/hwcrypto_reg.h" +#include "soc/mpi_periph.h" + +const uint32_t MPI_LL_BLOCK_BASES[4] = { + RSA_MEM_X_BLOCK_BASE, + RSA_MEM_Y_BLOCK_BASE, + RSA_MEM_Z_BLOCK_BASE, + RSA_MEM_M_BLOCK_BASE, +}; + +const uint32_t MPI_LL_OPERATIONS[3] = { + RSA_MULT_START_REG, + RSA_MOD_MULT_START_REG, + RSA_MODEXP_START_REG, +}; diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index b0361896b0..8535552e4d 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -731,6 +731,14 @@ config SOC_PARLIO_TX_RX_SHARE_INTERRUPT 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/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index f4e90ef5a9..689e7faef5 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -300,6 +300,10 @@ #define SOC_PARLIO_RX_UNIT_MAX_DATA_WIDTH 16 /*!< Number of data lines of the RX unit */ #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) + /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (3072) diff --git a/components/soc/esp32c6/mpi_periph.c b/components/soc/esp32c6/mpi_periph.c new file mode 100644 index 0000000000..1fd50f5318 --- /dev/null +++ b/components/soc/esp32c6/mpi_periph.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 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, +}; diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 9c71ab72e6..61c58b8bfc 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -731,6 +731,14 @@ config SOC_RTCIO_PIN_COUNT int default 0 +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/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 330f4c7340..48ad55dee1 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -311,6 +311,10 @@ * for hold, wake & 32kHz crystal functions - via LP_AON registers */ #define SOC_RTCIO_PIN_COUNT (0U) +/*--------------------------- MPI CAPS ---------------------------------------*/ +#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/esp32h2/mpi_periph.c b/components/soc/esp32h2/mpi_periph.c new file mode 100644 index 0000000000..0efc0d191b --- /dev/null +++ b/components/soc/esp32h2/mpi_periph.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 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_REG, + RSA_Y_MEM_REG, + RSA_Z_MEM_REG, + RSA_M_MEM_REG, +}; + +const uint32_t MPI_LL_OPERATIONS[3] = { + RSA_SET_START_MULT_REG, + RSA_SET_START_MODMULT_REG, + RSA_SET_START_MODEXP_REG, +}; diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 654e3b05f9..4549f29a02 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -831,6 +831,14 @@ config SOC_SHA_SUPPORT_SHA512_T 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 4096 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 8456e1fadb..8d1fb1fa07 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -361,6 +361,10 @@ #define SOC_SHA_SUPPORT_SHA512_T (1) +/*--------------------------- MPI CAPS ---------------------------------------*/ +#define SOC_MPI_MEM_BLOCKS_NUM (4) +#define SOC_MPI_OPERATIONS_NUM (3) + /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (4096) diff --git a/components/soc/esp32s2/mpi_periph.c b/components/soc/esp32s2/mpi_periph.c new file mode 100644 index 0000000000..c9f3870045 --- /dev/null +++ b/components/soc/esp32s2/mpi_periph.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/hwcrypto_reg.h" +#include "soc/mpi_periph.h" + +const uint32_t MPI_LL_BLOCK_BASES[4] = { + RSA_MEM_X_BLOCK_BASE, + RSA_MEM_Y_BLOCK_BASE, + RSA_MEM_Z_BLOCK_BASE, + RSA_MEM_M_BLOCK_BASE, +}; + +const uint32_t MPI_LL_OPERATIONS[3] = { + RSA_MULT_START_REG, + RSA_MOD_MULT_START_REG, + RSA_MODEXP_START_REG, +}; diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 8d981b17ba..deb39a0ee4 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -967,6 +967,14 @@ config SOC_SHA_SUPPORT_SHA512_T 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 4096 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index dd8b147efd..9bc9dd84c4 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -390,6 +390,10 @@ #define SOC_SHA_SUPPORT_SHA512_T (1) +/*--------------------------- MPI CAPS ---------------------------------------*/ +#define SOC_MPI_MEM_BLOCKS_NUM (4) +#define SOC_MPI_OPERATIONS_NUM (3) + /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (4096) diff --git a/components/soc/esp32s3/mpi_periph.c b/components/soc/esp32s3/mpi_periph.c new file mode 100644 index 0000000000..c9f3870045 --- /dev/null +++ b/components/soc/esp32s3/mpi_periph.c @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/hwcrypto_reg.h" +#include "soc/mpi_periph.h" + +const uint32_t MPI_LL_BLOCK_BASES[4] = { + RSA_MEM_X_BLOCK_BASE, + RSA_MEM_Y_BLOCK_BASE, + RSA_MEM_Z_BLOCK_BASE, + RSA_MEM_M_BLOCK_BASE, +}; + +const uint32_t MPI_LL_OPERATIONS[3] = { + RSA_MULT_START_REG, + RSA_MOD_MULT_START_REG, + RSA_MODEXP_START_REG, +}; diff --git a/components/soc/include/soc/mpi_periph.h b/components/soc/include/soc/mpi_periph.h new file mode 100644 index 0000000000..b2a289ea4e --- /dev/null +++ b/components/soc/include/soc/mpi_periph.h @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern const uint32_t MPI_LL_BLOCK_BASES[SOC_MPI_MEM_BLOCKS_NUM]; +extern const uint32_t MPI_LL_OPERATIONS[SOC_MPI_OPERATIONS_NUM]; + +#ifdef __cplusplus +} +#endif