mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-20 00:36:01 -04:00
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:
commit
a8b6a70620
@ -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
|
@ -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()
|
||||
|
||||
|
27
components/esp_hw_support/port/esp32/esp_crypto_lock.c
Normal file
27
components/esp_hw_support/port/esp32/esp_crypto_lock.c
Normal 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);
|
||||
}
|
@ -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.
|
||||
|
@ -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()
|
||||
|
150
components/hal/esp32/include/hal/mpi_ll.h
Normal file
150
components/hal/esp32/include/hal/mpi_ll.h
Normal 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
|
153
components/hal/esp32c3/include/hal/mpi_ll.h
Normal file
153
components/hal/esp32c3/include/hal/mpi_ll.h
Normal 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
|
153
components/hal/esp32c6/include/hal/mpi_ll.h
Normal file
153
components/hal/esp32c6/include/hal/mpi_ll.h
Normal 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
|
153
components/hal/esp32h2/include/hal/mpi_ll.h
Normal file
153
components/hal/esp32h2/include/hal/mpi_ll.h
Normal 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
|
151
components/hal/esp32s2/include/hal/mpi_ll.h
Normal file
151
components/hal/esp32s2/include/hal/mpi_ll.h
Normal 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
|
149
components/hal/esp32s3/include/hal/mpi_ll.h
Normal file
149
components/hal/esp32s3/include/hal/mpi_ll.h
Normal 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
|
146
components/hal/include/hal/mpi_hal.h
Normal file
146
components/hal/include/hal/mpi_hal.h
Normal 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
|
19
components/hal/include/hal/mpi_types.h
Normal file
19
components/hal/include/hal/mpi_types.h
Normal 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
126
components/hal/mpi_hal.c
Normal 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);
|
||||
}
|
7
components/hal/test_apps/mpi/CMakeLists.txt
Normal file
7
components/hal/test_apps/mpi/CMakeLists.txt
Normal 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)
|
33
components/hal/test_apps/mpi/README.md
Normal file
33
components/hal/test_apps/mpi/README.md
Normal 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>
|
||||
```
|
6
components/hal/test_apps/mpi/main/CMakeLists.txt
Normal file
6
components/hal/test_apps/mpi/main/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
set(srcs "app_main.c"
|
||||
"test_mpi.c")
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
REQUIRES unity
|
||||
WHOLE_ARCHIVE)
|
13
components/hal/test_apps/mpi/main/app_main.c
Normal file
13
components/hal/test_apps/mpi/main/app_main.c
Normal 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();
|
||||
}
|
145
components/hal/test_apps/mpi/main/test_mpi.c
Normal file
145
components/hal/test_apps/mpi/main/test_mpi.c
Normal 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();
|
||||
}
|
382
components/hal/test_apps/mpi/main/test_params.h
Normal file
382
components/hal/test_apps/mpi/main/test_params.h
Normal 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,
|
||||
};
|
16
components/hal/test_apps/mpi/pytest_mpi.py
Normal file
16
components/hal/test_apps/mpi/pytest_mpi.py
Normal 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()
|
2
components/hal/test_apps/mpi/sdkconfig.defaults
Normal file
2
components/hal/test_apps/mpi/sdkconfig.defaults
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_ESP_TASK_WDT_EN=y
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
@ -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)
|
||||
|
227
components/mbedtls/port/bignum/bignum_alt.c
Normal file
227
components/mbedtls/port/bignum/bignum_alt.c
Normal 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
|
@ -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);
|
||||
/*
|
@ -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);
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
19
components/soc/esp32/mpi_periph.c
Normal file
19
components/soc/esp32/mpi_periph.c
Normal 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,
|
||||
};
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
21
components/soc/esp32c3/mpi_periph.c
Normal file
21
components/soc/esp32c3/mpi_periph.c
Normal 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,
|
||||
};
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
21
components/soc/esp32c6/mpi_periph.c
Normal file
21
components/soc/esp32c6/mpi_periph.c
Normal 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,
|
||||
};
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
21
components/soc/esp32h2/mpi_periph.c
Normal file
21
components/soc/esp32h2/mpi_periph.c
Normal 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,
|
||||
};
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
21
components/soc/esp32s2/mpi_periph.c
Normal file
21
components/soc/esp32s2/mpi_periph.c
Normal 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,
|
||||
};
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
21
components/soc/esp32s3/mpi_periph.c
Normal file
21
components/soc/esp32s3/mpi_periph.c
Normal 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,
|
||||
};
|
22
components/soc/include/soc/mpi_periph.h
Normal file
22
components/soc/include/soc/mpi_periph.h
Normal 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
|
Loading…
Reference in New Issue
Block a user