Merge branch 'feature/add_bignum_ll_layer' into 'master'

bignum: added bignum hal and ll layer

Closes IDF-7071

See merge request espressif/esp-idf!22823
This commit is contained in:
Mahavir Jain 2023-04-25 19:50:25 +08:00
commit a8b6a70620
51 changed files with 2345 additions and 1475 deletions

View File

@ -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

View File

@ -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()

View File

@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <sys/lock.h>
#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);
}

View File

@ -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.

View File

@ -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()

View File

@ -0,0 +1,150 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/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

View File

@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/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

View File

@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/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

View File

@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/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

View File

@ -0,0 +1,151 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/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

View File

@ -0,0 +1,149 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <string.h>
#include "hal/assert.h"
#include "soc/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

View File

@ -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 <stdbool.h>
#include <sys/param.h>
#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

View File

@ -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;

126
components/hal/mpi_hal.c Normal file
View File

@ -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);
}

View File

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.16)
set(COMPONENTS main)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mpi_test)

View File

@ -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 <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 <TARGET>
```

View File

@ -0,0 +1,6 @@
set(srcs "app_main.c"
"test_mpi.c")
idf_component_register(SRCS ${srcs}
REQUIRES unity
WHOLE_ARCHIVE)

View File

@ -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();
}

View File

@ -0,0 +1,145 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include <string.h>
#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();
}

View File

@ -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,
};

View File

@ -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()

View File

@ -0,0 +1,2 @@
CONFIG_ESP_TASK_WDT_EN=y
CONFIG_ESP_TASK_WDT_INIT=n

View File

@ -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)

View File

@ -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

View File

@ -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 <stdio.h>
#include <string.h>
@ -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 <mbedtls/bignum.h>
#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);
/*

View File

@ -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 <mbedtls/bignum.h>
#include "bignum_impl.h"
#include <sys/param.h>
#include <sys/lock.h>
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);
}

View File

@ -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 <string.h>
#include <sys/param.h>
#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);
}

View File

@ -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 <string.h>
#include <sys/param.h>
#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);
}

View File

@ -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 <string.h>
#include <sys/param.h>
#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);
}

View File

@ -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 <mbedtls/bignum.h>
#include "bignum_impl.h"
#include "soc/dport_reg.h"
#include "soc/periph_defs.h"
#include <sys/param.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);
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);
}

View File

@ -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 <mbedtls/bignum.h>
#include "bignum_impl.h"
#include "soc/dport_reg.h"
#include "soc/system_reg.h"
#include "soc/periph_defs.h"
#include <sys/param.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 (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);
}

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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,
};

View File

@ -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

View File

@ -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)

View File

@ -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,
};

View File

@ -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

View File

@ -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)

View File

@ -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,
};

View File

@ -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

View File

@ -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)

View File

@ -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,
};

View File

@ -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

View File

@ -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)

View File

@ -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,
};

View File

@ -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

View File

@ -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)

View File

@ -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,
};

View File

@ -0,0 +1,22 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#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