mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
refactor(hal): Created esp_hal_security for security code
This commit is contained in:
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/dport_access.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "hal/aes_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief State of AES accelerator, busy or idle
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_AES_STATE_BUSY = 0, /* Transform in progress */
|
||||
ESP_AES_STATE_IDLE, /* AES accelerator is idle */
|
||||
} esp_aes_state_t;
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for AES peripheral module
|
||||
*
|
||||
* @param enable true to enable the module, false to disable the module
|
||||
*/
|
||||
static inline void aes_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
} else {
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_AES);
|
||||
}
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define aes_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
aes_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Reset the AES peripheral module
|
||||
*/
|
||||
static inline void aes_ll_reset_register(void)
|
||||
{
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_AES);
|
||||
|
||||
// Clear reset on digital signature and secure boot also, otherwise AES is held in reset
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_DIGITAL_SIGNATURE);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SECUREBOOT);
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define aes_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
aes_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Write the encryption/decryption key to hardware
|
||||
*
|
||||
* @param key Key to be written to the AES hardware
|
||||
* @param key_word_len Number of words in the key
|
||||
*
|
||||
* @return Number of bytes written to hardware, used for fault injection check,
|
||||
* if a write was skipped then this sum is likely to be wrong
|
||||
*/
|
||||
static inline uint8_t aes_ll_write_key(const uint8_t *key, size_t key_word_len)
|
||||
{
|
||||
/* This variable is used for fault injection checks, so marked volatile to avoid optimisation */
|
||||
volatile uint8_t key_bytes_in_hardware = 0;
|
||||
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
uint32_t key_word;
|
||||
|
||||
for (int i = 0; i < key_word_len; i++) {
|
||||
memcpy(&key_word, key + 4 * i, 4);
|
||||
DPORT_REG_WRITE(AES_KEY_BASE + i * 4, key_word);
|
||||
key_bytes_in_hardware += 4;
|
||||
}
|
||||
return key_bytes_in_hardware;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the mode
|
||||
*
|
||||
* @param mode ESP_AES_ENCRYPT = 1, or ESP_AES_DECRYPT = 0
|
||||
* @param key_bytes Number of bytes in the key
|
||||
*/
|
||||
static inline void aes_ll_set_mode(int mode, uint8_t key_bytes)
|
||||
{
|
||||
const uint32_t MODE_DECRYPT_BIT = 4;
|
||||
unsigned mode_reg_base = (mode == ESP_AES_ENCRYPT) ? 0 : MODE_DECRYPT_BIT;
|
||||
|
||||
/* See TRM for the mapping between keylength and mode bit */
|
||||
DPORT_REG_WRITE(AES_MODE_REG, mode_reg_base + ((key_bytes / 8) - 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes message block to AES hardware
|
||||
*
|
||||
* @param input Block to be written
|
||||
*/
|
||||
static inline void aes_ll_write_block(const uint8_t *input)
|
||||
{
|
||||
const uint32_t *input_words = (const uint32_t *)input;
|
||||
uint32_t i0;
|
||||
uint32_t i1;
|
||||
uint32_t i2;
|
||||
uint32_t i3;
|
||||
|
||||
/* Storing i0,i1,i2,i3 in registers not an array
|
||||
helps a lot with optimisations at -Os level */
|
||||
i0 = input_words[0];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE, i0);
|
||||
|
||||
i1 = input_words[1];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE + 4, i1);
|
||||
|
||||
i2 = input_words[2];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE + 8, i2);
|
||||
|
||||
i3 = input_words[3];
|
||||
DPORT_REG_WRITE(AES_TEXT_BASE + 12, i3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the AES block
|
||||
*
|
||||
* @note If a transform was ran then this is the output
|
||||
*
|
||||
* @param output the output of the transform, length = AES_BLOCK_BYTES
|
||||
*/
|
||||
static inline void aes_ll_read_block(void *output)
|
||||
{
|
||||
uint32_t *output_words = (uint32_t *)output;
|
||||
esp_dport_access_read_buffer(output_words, AES_TEXT_BASE, AES_BLOCK_WORDS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Starts block transform
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_start_transform(void)
|
||||
{
|
||||
DPORT_REG_WRITE(AES_START_REG, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read state of AES accelerator
|
||||
*
|
||||
* @return esp_aes_state_t
|
||||
*/
|
||||
static inline esp_aes_state_t aes_ll_get_state(void)
|
||||
{
|
||||
return (esp_aes_state_t)DPORT_REG_READ(AES_IDLE_REG);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "hal/assert.h"
|
||||
#include "hal/mpi_types.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_periph.h"
|
||||
#include "soc/mpi_periph.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for MPI peripheral module
|
||||
*
|
||||
* @param enable true to enable the module, false to disable the module
|
||||
*/
|
||||
static inline void mpi_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
|
||||
} else {
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_RSA);
|
||||
}
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define mpi_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
mpi_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Reset the MPI peripheral module
|
||||
*/
|
||||
static inline void mpi_ll_reset_register(void)
|
||||
{
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_RSA);
|
||||
|
||||
// Clear reset on digital signature also, otherwise RSA is held in reset
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_DIGITAL_SIGNATURE);
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define mpi_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
mpi_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/* 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_power_up(void)
|
||||
{
|
||||
DPORT_REG_CLR_BIT(DPORT_RSA_PD_CTRL_REG, DPORT_RSA_PD);
|
||||
}
|
||||
|
||||
static inline void mpi_ll_power_down(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_OPERATIONS_REG[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_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++) { HAL_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_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_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)
|
||||
{
|
||||
HAL_ASSERT(n >= num_words);
|
||||
uint32_t mem_base = MPI_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
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#include "xt_instr_macros.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline uint32_t mpu_ll_id_to_addr(unsigned id)
|
||||
{
|
||||
// vpn - id
|
||||
// 0x00000000 = 0
|
||||
// 0x20000000 = 1
|
||||
// 0x40000000 = 2
|
||||
// 0x60000000 = 3
|
||||
// 0x80000000 = 4
|
||||
// 0xa0000000 = 5
|
||||
// 0xc0000000 = 6
|
||||
// 0xe0000000 = 7
|
||||
return id * SOC_MPU_MIN_REGION_SIZE;
|
||||
}
|
||||
|
||||
static inline void mpu_ll_set_region_rw(uint32_t addr)
|
||||
{
|
||||
WDTLB(0x0, addr); // cached, no allocate
|
||||
}
|
||||
|
||||
static inline void mpu_ll_set_region_rwx(uint32_t addr)
|
||||
{
|
||||
WDTLB(0x2, addr); // bypass cache
|
||||
}
|
||||
|
||||
static inline void mpu_ll_set_region_x(uint32_t addr)
|
||||
{
|
||||
WITLB(0x3, addr); // cached
|
||||
}
|
||||
|
||||
static inline void mpu_ll_set_region_illegal(uint32_t addr)
|
||||
{
|
||||
WITLB(0xF, addr);
|
||||
WDTLB(0xF, addr);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,200 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/sha_types.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/dport_access.h"
|
||||
#include "hal/misc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SHA_LL_TYPE_OFFSET 0x10
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for SHA peripheral module
|
||||
*
|
||||
* @param enable true to enable the module, false to disable the module
|
||||
*/
|
||||
static inline void sha_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
} else {
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_CLK_EN_REG, DPORT_PERI_EN_SHA);
|
||||
}
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define sha_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
sha_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Reset the SHA peripheral module
|
||||
*/
|
||||
static inline void sha_ll_reset_register(void)
|
||||
{
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SHA);
|
||||
|
||||
// Clear reset on secure boot also, otherwise SHA is held in reset
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERI_RST_EN_REG, DPORT_PERI_EN_SECUREBOOT);
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define sha_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
sha_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Returns the LOAD_REG register address for the given sha type
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @return uint32_t the LOAD_REG register address
|
||||
*/
|
||||
inline static uint32_t SHA_LOAD_REG(esp_sha_type sha_type)
|
||||
{
|
||||
return SHA_1_LOAD_REG + sha_type * SHA_LL_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the BUSY register address for the given sha type
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @return uint32_t the BUSY register address
|
||||
*/
|
||||
inline static uint32_t SHA_BUSY_REG(esp_sha_type sha_type)
|
||||
{
|
||||
return SHA_1_BUSY_REG + sha_type * SHA_LL_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the START register address for the given sha type
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @return uint32_t the START register address
|
||||
*/
|
||||
inline static uint32_t SHA_START_REG(esp_sha_type sha_type)
|
||||
{
|
||||
return SHA_1_START_REG + sha_type * SHA_LL_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the CONTINUE register address for the given sha type
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @return uint32_t the CONTINUE register address
|
||||
*/
|
||||
inline static uint32_t SHA_CONTINUE_REG(esp_sha_type sha_type)
|
||||
{
|
||||
return SHA_1_CONTINUE_REG + sha_type * SHA_LL_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a new SHA block conversion (no initial hash in HW)
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_start_block(esp_sha_type sha_type)
|
||||
{
|
||||
DPORT_REG_WRITE(SHA_START_REG(sha_type), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Continue a SHA block conversion (initial hash in HW)
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_continue_block(esp_sha_type sha_type)
|
||||
{
|
||||
DPORT_REG_WRITE(SHA_CONTINUE_REG(sha_type), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load the current hash digest to digest register
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_load(esp_sha_type sha_type)
|
||||
{
|
||||
DPORT_REG_WRITE(SHA_LOAD_REG(sha_type), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load the mode for the SHA engine
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_set_mode(esp_sha_type sha_type)
|
||||
{
|
||||
(void) sha_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the SHA engine is currently busy hashing a block
|
||||
*
|
||||
* @return true SHA engine busy
|
||||
* @return false SHA engine idle
|
||||
*/
|
||||
static inline bool sha_ll_busy(void)
|
||||
{
|
||||
return (DPORT_REG_READ(SHA_1_BUSY_REG) || DPORT_REG_READ(SHA_256_BUSY_REG)
|
||||
|| DPORT_REG_READ(SHA_384_BUSY_REG) || DPORT_REG_READ(SHA_512_BUSY_REG));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a text (message) block to the SHA engine
|
||||
*
|
||||
* @param input_text Input buffer to be written to the SHA engine
|
||||
* @param block_word_len Number of words in block
|
||||
*/
|
||||
static inline void sha_ll_fill_text_block(const void *input_text, size_t block_word_len)
|
||||
{
|
||||
uint32_t *reg_addr_buf = NULL;
|
||||
uint32_t *data_words = NULL;
|
||||
reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||
data_words = (uint32_t *)input_text;
|
||||
for (size_t i = 0; i < block_word_len; i++) {
|
||||
reg_addr_buf[i] = HAL_SWAP32(data_words[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the message digest from the SHA engine
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @param digest_state Buffer that message digest will be written to
|
||||
* @param digest_word_len Length of the message digest
|
||||
*/
|
||||
static inline void sha_ll_read_digest(esp_sha_type sha_type, void *digest_state, size_t digest_word_len)
|
||||
{
|
||||
uint32_t *digest_state_words = (uint32_t *)digest_state;
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_TEXT_BASE);
|
||||
if (sha_type == SHA2_384 || sha_type == SHA2_512) {
|
||||
/* for these ciphers using 64-bit states, swap each pair of words */
|
||||
DPORT_INTERRUPT_DISABLE(); // Disable interrupt only on current CPU.
|
||||
for (size_t i = 0; i < digest_word_len; i += 2) {
|
||||
digest_state_words[i + 1] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i]);
|
||||
digest_state_words[i] = DPORT_SEQUENCE_REG_READ((uint32_t)®_addr_buf[i + 1]);
|
||||
}
|
||||
DPORT_INTERRUPT_RESTORE(); // restore the previous interrupt level
|
||||
} else {
|
||||
esp_dport_access_read_buffer(digest_state_words, (uint32_t)®_addr_buf[0], digest_word_len);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user