mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
refactor(hal): Created esp_hal_security for security code
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "esp_hal_security/aes_types.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "hal/config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief State of AES accelerator, busy, idle or done
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_AES_STATE_IDLE = 0, /* AES accelerator is idle */
|
||||
ESP_AES_STATE_BUSY, /* Transform in progress */
|
||||
ESP_AES_STATE_DONE, /* Transform completed */
|
||||
} 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)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_aes_clk_en = enable;
|
||||
}
|
||||
|
||||
/// 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)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_aes = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_aes = 0;
|
||||
|
||||
// Clear reset on digital signature and parent crypto, otherwise AES is held in reset
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ds = 0;
|
||||
}
|
||||
|
||||
/// 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
|
||||
*/
|
||||
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_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);
|
||||
REG_WRITE(AES_KEY_0_REG + i * 4, key_word);
|
||||
key_in_hardware += 4;
|
||||
}
|
||||
return key_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 */
|
||||
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 void *input)
|
||||
{
|
||||
uint32_t input_word;
|
||||
|
||||
for (int i = 0; i < AES_BLOCK_WORDS; i++) {
|
||||
memcpy(&input_word, (uint8_t*)input + 4 * i, 4);
|
||||
REG_WRITE(AES_TEXT_IN_0_REG + i * 4, input_word);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the AES block
|
||||
*
|
||||
* @param output the output of the transform, length = AES_BLOCK_BYTES
|
||||
*/
|
||||
static inline void aes_ll_read_block(void *output)
|
||||
{
|
||||
uint32_t output_word;
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
|
||||
for (size_t i = 0; i < AES_BLOCK_WORDS; i++) {
|
||||
output_word = REG_READ(AES_TEXT_OUT_0_REG + (i * REG_WIDTH));
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy((uint8_t*)output + i * 4, &output_word, sizeof(output_word));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts block transform
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_start_transform(void)
|
||||
{
|
||||
REG_WRITE(AES_TRIGGER_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)REG_READ(AES_STATE_REG);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set mode of operation
|
||||
*
|
||||
* @note Only used for DMA transforms
|
||||
*
|
||||
* @param mode Mode of operation to set (e.g., ECB, CBC, CTR, etc.)
|
||||
*/
|
||||
static inline void aes_ll_set_block_mode(esp_aes_mode_t mode)
|
||||
{
|
||||
REG_WRITE(AES_BLOCK_MODE_REG, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AES-CTR counter to INC32
|
||||
*
|
||||
* @note Only affects AES-CTR mode
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_set_inc(void)
|
||||
{
|
||||
REG_WRITE(AES_INC_SEL_REG, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the DMA
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_dma_exit(void)
|
||||
{
|
||||
REG_WRITE(AES_DMA_EXIT_REG, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of blocks to be transformed
|
||||
*
|
||||
* @note Only used for DMA transforms
|
||||
*
|
||||
* @param num_blocks Number of blocks to transform
|
||||
*/
|
||||
static inline void aes_ll_set_num_blocks(size_t num_blocks)
|
||||
{
|
||||
REG_WRITE(AES_BLOCK_NUM_REG, num_blocks);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write IV to hardware iv registers
|
||||
*/
|
||||
static inline void aes_ll_set_iv(const uint8_t *iv)
|
||||
{
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(AES_IV_MEM);
|
||||
uint32_t iv_word;
|
||||
|
||||
for (int i = 0; i < IV_WORDS; i++) {
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy(&iv_word, iv + 4 * i, sizeof(iv_word));
|
||||
REG_WRITE(®_addr_buf[i], iv_word);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read IV from hardware iv registers
|
||||
*/
|
||||
static inline void aes_ll_read_iv(uint8_t *iv)
|
||||
{
|
||||
uint32_t iv_word;
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
|
||||
for (size_t i = 0; i < IV_WORDS; i++) {
|
||||
iv_word = REG_READ(AES_IV_MEM + (i * REG_WIDTH));
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy(iv + i * 4, &iv_word, sizeof(iv_word));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable DMA mode
|
||||
*
|
||||
* @param enable true to enable, false to disable.
|
||||
*/
|
||||
static inline void aes_ll_dma_enable(bool enable)
|
||||
{
|
||||
REG_WRITE(AES_DMA_ENABLE_REG, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable transform completed interrupt
|
||||
*
|
||||
* @param enable true to enable, false to disable.
|
||||
*/
|
||||
static inline void aes_ll_interrupt_enable(bool enable)
|
||||
{
|
||||
REG_WRITE(AES_INT_ENA_REG, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the interrupt
|
||||
*
|
||||
*/
|
||||
static inline void aes_ll_interrupt_clear(void)
|
||||
{
|
||||
REG_WRITE(AES_INT_CLEAR_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the pseudo-round function during AES operations
|
||||
*
|
||||
* @param enable true to enable, false to disable
|
||||
* @param base basic number of pseudo rounds, zero if disable
|
||||
* @param increment increment number of pseudo rounds, zero if disable
|
||||
* @param key_rng_cnt update frequency of the pseudo-key, zero if disable
|
||||
*/
|
||||
static inline void aes_ll_enable_pseudo_rounds(bool enable, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
|
||||
{
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_EN, enable);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_BASE, base);
|
||||
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_INC, increment);
|
||||
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_RNG_CNT, key_rng_cnt);
|
||||
} else {
|
||||
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_BASE, 0);
|
||||
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_INC, 0);
|
||||
REG_SET_FIELD(AES_PSEUDO_REG, AES_PSEUDO_RNG_CNT, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Continue a previous started transform
|
||||
*
|
||||
* @note Only used when doing GCM
|
||||
*/
|
||||
static inline void aes_ll_cont_transform(void)
|
||||
{
|
||||
REG_WRITE(AES_CONTINUE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads the AES-GCM hash sub-key H
|
||||
*
|
||||
* @param gcm_hash hash value
|
||||
*/
|
||||
static inline void aes_ll_gcm_read_hash(uint8_t *gcm_hash)
|
||||
{
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
uint32_t hash_word;
|
||||
|
||||
for (size_t i = 0; i < AES_BLOCK_WORDS; i++) {
|
||||
hash_word = REG_READ(AES_H_MEM + (i * REG_WIDTH));
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy(gcm_hash + i * 4, &hash_word, sizeof(hash_word));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of Additional Authenticated Data (AAD) blocks
|
||||
*
|
||||
* @note Only affects AES-GCM
|
||||
|
||||
* @param aad_num_blocks the number of Additional Authenticated Data (AAD) blocks
|
||||
*/
|
||||
static inline void aes_ll_gcm_set_aad_num_blocks(size_t aad_num_blocks)
|
||||
{
|
||||
REG_WRITE(AES_AAD_BLOCK_NUM_REG, aad_num_blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the J0 value, for more information see the GCM subchapter in the TRM
|
||||
*
|
||||
* @note Only affects AES-GCM
|
||||
*
|
||||
* @param j0 J0 value
|
||||
*/
|
||||
static inline void aes_ll_gcm_set_j0(const uint8_t *j0)
|
||||
{
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(AES_J0_MEM);
|
||||
uint32_t j0_word;
|
||||
|
||||
for (int i = 0; i < AES_BLOCK_WORDS; i++) {
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy(&j0_word, j0 + 4 * i, sizeof(j0_word));
|
||||
REG_WRITE(®_addr_buf[i], j0_word);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of effective bits of incomplete blocks in plaintext/ciphertext.
|
||||
*
|
||||
* @note Only affects AES-GCM
|
||||
*
|
||||
* @param num_valid_bits the number of effective bits of incomplete blocks in plaintext/ciphertext.
|
||||
*/
|
||||
static inline void aes_ll_gcm_set_num_valid_bit(size_t num_valid_bits)
|
||||
{
|
||||
REG_WRITE(AES_REMAINDER_BIT_NUM_REG, num_valid_bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the tag after a AES-GCM transform
|
||||
*
|
||||
* @param tag Pointer to where to store the result with length TAG_WORDS
|
||||
*/
|
||||
static inline void aes_ll_gcm_read_tag(uint8_t *tag)
|
||||
{
|
||||
uint32_t tag_word;
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
|
||||
for (size_t i = 0; i < TAG_WORDS; i++) {
|
||||
tag_word = REG_READ(AES_T0_MEM + (i * REG_WIDTH));
|
||||
/* Memcpy to avoid potential unaligned access */
|
||||
memcpy(tag + i * 4, &tag_word, sizeof(tag_word));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the pseudo round function is supported
|
||||
*/
|
||||
static inline bool aes_ll_is_pseudo_rounds_function_supported(void)
|
||||
{
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "hal/assert.h"
|
||||
#include "soc/dma_pms_reg.h"
|
||||
#include "soc/hp2lp_peri_pms_reg.h"
|
||||
#include "soc/hp_peri_pms_reg.h"
|
||||
#include "soc/lp2hp_peri_pms_reg.h"
|
||||
#include "soc/lp_peri_pms_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Master Secure Mode
|
||||
*/
|
||||
typedef enum {
|
||||
APM_LL_SECURE_MODE_TEE = 0, /* Trusted execution environment mode (Machine mode). */
|
||||
APM_LL_SECURE_MODE_REE = 1, /* Rich execution environment mode (User mode). */
|
||||
APM_LL_SECURE_MODE_INV = 2, /* Invalid mode. */
|
||||
} apm_ll_secure_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Bus Masters.
|
||||
*/
|
||||
typedef enum {
|
||||
APM_LL_MASTER_LPCPU = 0,
|
||||
APM_LL_MASTER_HPCPU0,
|
||||
APM_LL_MASTER_HPCPU1,
|
||||
APM_LL_MASTER_DMA,
|
||||
} apm_ll_master_id_t;
|
||||
|
||||
/**
|
||||
* @brief APM Controller
|
||||
*/
|
||||
typedef enum {
|
||||
LP_APM_CTRL = 0,
|
||||
HP2LP_APM_CTRL,
|
||||
HP_APM_CTRL,
|
||||
LP2HP_APM_CTRL,
|
||||
DMA_APM_CTRL,
|
||||
MAX_APM_CTRL,
|
||||
} apm_ll_apm_ctrl_t;
|
||||
|
||||
/**
|
||||
* @brief HP CPU Peripherals.
|
||||
*/
|
||||
typedef enum {
|
||||
PMS_COREn_XM_PSRAM_ALLOW = 0,
|
||||
PMS_COREn_XM_FLASH_ALLOW,
|
||||
PMS_COREn_XM_L2MEM_ALLOW,
|
||||
PMS_COREn_XM_L2ROM_ALLOW,
|
||||
PMS_COREn_XM_TRACE0_ALLOW = 6,
|
||||
PMS_COREn_XM_TRACE1_ALLOW,
|
||||
PMS_COREn_XM_CPU_BUS_MON_ALLOW,
|
||||
PMS_COREn_XM_L2MEM_MON_ALLOW,
|
||||
PMS_COREn_XM_TCM_MON_ALLOW,
|
||||
PMS_COREn_XM_CACHE_ALLOW,
|
||||
|
||||
PMS_COREn_XM_HP_USBOTG_ALLOW = 32,
|
||||
PMS_COREn_XM_HP_USBOTG11_ALLOW,
|
||||
PMS_COREn_XM_HP_USBOTG11_WRAP_ALLOW,
|
||||
PMS_COREn_XM_HP_GDMA_ALLOW,
|
||||
PMS_COREn_XM_HP_SDMMC_ALLOW = 37,
|
||||
PMS_COREn_XM_HP_AHB_PDMA_ALLOW,
|
||||
PMS_COREn_XM_HP_JPEG_ALLOW,
|
||||
PMS_COREn_XM_HP_PPA_ALLOW,
|
||||
PMS_COREn_XM_HP_DMA2D_ALLOW,
|
||||
PMS_COREn_XM_HP_KEY_MANAGER_ALLOW,
|
||||
PMS_COREn_XM_HP_AXI_PDMA_ALLOW,
|
||||
PMS_COREn_XM_HP_FLASH_ALLOW,
|
||||
PMS_COREn_XM_HP_PSRAM_ALLOW,
|
||||
PMS_COREn_XM_HP_CRYPTO_ALLOW,
|
||||
PMS_COREn_XM_HP_GMAC_ALLOW,
|
||||
PMS_COREn_XM_HP_USB_PHY_ALLOW,
|
||||
PMS_COREn_XM_HP_CSI_HOST_ALLOW = 50,
|
||||
PMS_COREn_XM_HP_DSI_HOST_ALLOW,
|
||||
PMS_COREn_XM_HP_ISP_ALLOW,
|
||||
PMS_COREn_XM_HP_H264_CORE_ALLOW,
|
||||
PMS_COREn_XM_HP_RMT_ALLOW,
|
||||
PMS_COREn_XM_HP_BITSCRAMBLER_ALLOW,
|
||||
PMS_COREn_XM_HP_AXI_ICM_ALLOW,
|
||||
PMS_COREn_XM_HP_PERI_PMS_ALLOW,
|
||||
PMS_COREn_XM_LP2HP_PERI_PMS_ALLOW,
|
||||
PMS_COREn_XM_DMA_PMS_ALLOW,
|
||||
PMS_COREn_XM_HP_H264_DMA2D_ALLOW = 60,
|
||||
|
||||
PMS_COREn_XM_HP_MCPWM0_ALLOW = 64,
|
||||
PMS_COREn_XM_HP_MCPWM1_ALLOW,
|
||||
PMS_COREn_XM_HP_TIMER_GROUP0_ALLOW,
|
||||
PMS_COREn_XM_HP_TIMER_GROUP1_ALLOW,
|
||||
PMS_COREn_XM_HP_I2C0_ALLOW,
|
||||
PMS_COREn_XM_HP_I2C1_ALLOW,
|
||||
PMS_COREn_XM_HP_I2S0_ALLOW,
|
||||
PMS_COREn_XM_HP_I2S1_ALLOW,
|
||||
PMS_COREn_XM_HP_I2S2_ALLOW,
|
||||
PMS_COREn_XM_HP_PCNT_ALLOW,
|
||||
PMS_COREn_XM_HP_UART0_ALLOW,
|
||||
PMS_COREn_XM_HP_UART1_ALLOW,
|
||||
PMS_COREn_XM_HP_UART2_ALLOW,
|
||||
PMS_COREn_XM_HP_UART3_ALLOW,
|
||||
PMS_COREn_XM_HP_UART4_ALLOW,
|
||||
PMS_COREn_XM_HP_PARLIO_ALLOW269,
|
||||
PMS_COREn_XM_HP_GPSPI2_ALLOW270,
|
||||
PMS_COREn_XM_HP_GPSPI3_ALLOW271,
|
||||
PMS_COREn_XM_HP_USBDEVICE_ALLOW,
|
||||
PMS_COREn_XM_HP_LEDC_ALLOW,
|
||||
PMS_COREn_XM_HP_ETM_ALLOW = 85,
|
||||
PMS_COREn_XM_HP_INTRMTX_ALLOW,
|
||||
PMS_COREn_XM_HP_TWAI0_ALLOW,
|
||||
PMS_COREn_XM_HP_TWAI1_ALLOW,
|
||||
PMS_COREn_XM_HP_TWAI2_ALLOW,
|
||||
PMS_COREn_XM_HP_I3C_MST_ALLOW,
|
||||
PMS_COREn_XM_HP_I3C_SLV_ALLOW,
|
||||
PMS_COREn_XM_HP_LCDCAM_ALLOW,
|
||||
PMS_COREn_XM_HP_ADC_ALLOW = 94,
|
||||
PMS_COREn_XM_HP_UHCI_ALLOW,
|
||||
|
||||
PMS_COREn_XM_HP_GPIO_ALLOW = 96,
|
||||
PMS_COREn_XM_HP_IOMUX_ALLOW,
|
||||
PMS_COREn_XM_HP_SYSTIMER_ALLOW,
|
||||
PMS_COREn_XM_HP_SYS_REG_ALLOW,
|
||||
PMS_COREn_XM_HP_CLKRST_ALLOW,
|
||||
PMS_COREn_XM_HP_PERI_MAX,
|
||||
} apm_ll_hp_peri_t;
|
||||
|
||||
/**
|
||||
* @brief LP CPU Peripherals.
|
||||
*/
|
||||
typedef enum {
|
||||
PMS_MM_LP_SYSREG_ALLOW = 0,
|
||||
PMS_MM_LP_AONCLKRST_ALLOW,
|
||||
PMS_MM_LP_TIMER_ALLOW,
|
||||
PMS_MM_LP_ANAPERI_ALLOW,
|
||||
PMS_MM_LP_PMU_ALLOW,
|
||||
PMS_MM_LP_WDT_ALLOW,
|
||||
PMS_MM_LP_MAILBOX_ALLOW,
|
||||
PMS_MM_LP_PERICLKRST_ALLOW = 8,
|
||||
PMS_MM_LP_UART_ALLOW,
|
||||
PMS_MM_LP_I2C_ALLOW,
|
||||
PMS_MM_LP_SPI_ALLOW,
|
||||
PMS_MM_LP_I2CMST_ALLOW,
|
||||
PMS_MM_LP_I2S_ALLOW,
|
||||
PMS_MM_LP_ADC_ALLOW,
|
||||
PMS_MM_LP_TOUCH_ALLOW,
|
||||
PMS_MM_LP_IOMUX_ALLOW,
|
||||
PMS_MM_LP_INTR_ALLOW,
|
||||
PMS_MM_LP_EFUSE_ALLOW,
|
||||
PMS_MM_LP_PMS_ALLOW,
|
||||
PMS_MM_HP2LP_PMS_ALLOW,
|
||||
PMS_MM_LP_TSENS_ALLOW,
|
||||
PMS_MM_LP_HUK_ALLOW,
|
||||
PMS_HP_COREn_MM_LP_SRAM_ALLOW,
|
||||
PMS_LP_MM_PERI_MAX,
|
||||
} apm_ll_lp_peri_t;
|
||||
|
||||
/**
|
||||
* @brief LP CPU Peripherals.
|
||||
*/
|
||||
typedef enum {
|
||||
PMS_DMA_GDMA_CH0 = 0,
|
||||
PMS_DMA_GDMA_CH1,
|
||||
PMS_DMA_GDMA_CH2,
|
||||
PMS_DMA_GDMA_CH3,
|
||||
PMS_DMA_AHB_PDMA_ADC,
|
||||
PMS_DMA_AHB_PDMA_I2S0,
|
||||
PMS_DMA_AHB_PDMA_I2S1,
|
||||
PMS_DMA_AHB_PDMA_I2S2,
|
||||
PMS_DMA_AHB_PDMA_I3C_MST,
|
||||
PMS_DMA_AHB_PDMA_UHCI0,
|
||||
PMS_DMA_AHB_PDMA_RMT,
|
||||
PMS_DMA_AXI_PDMA_LCDCAM,
|
||||
PMS_DMA_AXI_PDMA_GPSPI2,
|
||||
PMS_DMA_AXI_PDMA_GPSPI3,
|
||||
PMS_DMA_AXI_PDMA_PARLIO,
|
||||
PMS_DMA_AXI_PDMA_AES,
|
||||
PMS_DMA_AXI_PDMA_SHA,
|
||||
PMS_DMA_DMA2D_JPEG,
|
||||
PMS_DMA_USB,
|
||||
PMS_DMA_GMAC,
|
||||
PMS_DMA_SDMMC,
|
||||
PMS_DMA_USBOTG11,
|
||||
PMS_DMA_TRACE0,
|
||||
PMS_DMA_TRACE1,
|
||||
PMS_DMA_L2MEM_MON,
|
||||
PMS_DMA_TCM_MON,
|
||||
PMS_DMA_H264,
|
||||
PMS_DMA_DMA2D_PPA,
|
||||
PMS_DMA_DMA2D_DUMMY,
|
||||
PMS_DMA_AHB_PDMA_DUMMY,
|
||||
PMS_DMA_AXI_PDMA_DUMMY,
|
||||
PMS_DMA_MAX,
|
||||
} apm_ll_dma_master_t;
|
||||
|
||||
#define PMS_PERI_MAX_REGION_NUM 2
|
||||
#define PMS_DMA_MAX_REGION_NUM 32
|
||||
|
||||
#define PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri) \
|
||||
({\
|
||||
(PMS_CORE0_MM_HP_PERI_PMS_REG0_REG + (master_id * 0x20) \
|
||||
+ (sec_mode * 0x10) + ((hp_peri/32) * 0x4) ); \
|
||||
})
|
||||
|
||||
#define PMS_PERI_REGION_LOW_REG(regn_num) \
|
||||
({\
|
||||
(PMS_PERI_REGION0_LOW_REG + (regn_num * 8)); \
|
||||
})
|
||||
|
||||
#define PMS_PERI_REGION_HIGH_REG(regn_num) \
|
||||
({\
|
||||
(PMS_PERI_REGION0_HIGH_REG + (regn_num * 8)); \
|
||||
})
|
||||
|
||||
#define PMS_DMA_PMS_R_REG(dma_master) \
|
||||
({\
|
||||
(PMS_DMA_GDMA_CH0_R_PMS_REG + (dma_master * 8)); \
|
||||
})
|
||||
|
||||
#define PMS_DMA_PMS_W_REG(dma_master) \
|
||||
({\
|
||||
(PMS_DMA_GDMA_CH0_W_PMS_REG + (dma_master * 8)); \
|
||||
})
|
||||
|
||||
/**
|
||||
* @brief Configure HP peripherals access permission for the HP CPU0/1.
|
||||
*
|
||||
* @param master_id HP CPU0/1
|
||||
* @param hp_peri HP peripheral whose access permission to be configured.
|
||||
* @param enable Permission enable/disable
|
||||
*/
|
||||
static inline void apm_ll_hp_peri_access_enable(apm_ll_master_id_t master_id, apm_ll_hp_peri_t hp_peri,
|
||||
apm_ll_secure_mode_t sec_mode, bool enable)
|
||||
{
|
||||
HAL_ASSERT((master_id > APM_LL_MASTER_LPCPU) && (master_id < APM_LL_MASTER_DMA)
|
||||
&& (hp_peri < PMS_COREn_XM_HP_PERI_MAX) && (sec_mode < APM_LL_SECURE_MODE_INV));
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri), BIT(hp_peri % 32));
|
||||
} else {
|
||||
REG_CLR_BIT(PMS_COREn_XM_PMS_REGn_REG(master_id, sec_mode, hp_peri), BIT(hp_peri % 32));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure LP peripherals access permission for the LP CPU.
|
||||
*
|
||||
* @param lp_peri LP peripheral whose access permission to be configured.
|
||||
* @param enable Permission enable/disable
|
||||
*/
|
||||
static inline void apm_ll_lp_peri_access_enable(apm_ll_lp_peri_t lp_peri, bool enable)
|
||||
{
|
||||
HAL_ASSERT(lp_peri < PMS_LP_MM_PERI_MAX);
|
||||
|
||||
if (enable) {
|
||||
REG_SET_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(lp_peri));
|
||||
} else {
|
||||
REG_CLR_BIT(PMS_LP_MM_LP_PERI_PMS_REG0_REG, BIT(lp_peri));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure peripherals configurable address ranges.
|
||||
*
|
||||
* @param regn_num Configurable address range number.
|
||||
* @param regn_low_addr Configurable address range start address.
|
||||
* @param regn_high_addr Configurable address range end address.
|
||||
*/
|
||||
static inline void apm_ll_peri_region_config(uint32_t regn_num, uint32_t regn_low_addr,
|
||||
uint32_t regn_high_addr)
|
||||
{
|
||||
HAL_ASSERT(regn_num < PMS_PERI_MAX_REGION_NUM);
|
||||
|
||||
REG_WRITE(PMS_PERI_REGION_LOW_REG(regn_num), regn_low_addr);
|
||||
REG_WRITE(PMS_PERI_REGION_HIGH_REG(regn_num), regn_high_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure peripherals configurable address ranges.
|
||||
*
|
||||
* @param master_id LP CPU and HP CPU0/1
|
||||
* @param sec_mode CPU privilege mode (Machine/User) which corresponds to (TEE/REE).
|
||||
* @param regn_num Configurable address range number.
|
||||
* @param regn_pms Configurable address range permission setting(2-bits field).
|
||||
* Bit 0: Region 0 permission enable/disable.
|
||||
* Bit 1: Region 1 permission enable/disable.
|
||||
* @return Configuration performed successfully?
|
||||
*/
|
||||
static inline int apm_ll_peri_region_pms(apm_ll_master_id_t master_id, apm_ll_secure_mode_t sec_mode,
|
||||
uint32_t regn_num, uint32_t regn_pms)
|
||||
{
|
||||
HAL_ASSERT((master_id < APM_LL_MASTER_DMA) && (sec_mode < APM_LL_SECURE_MODE_INV));
|
||||
|
||||
regn_pms &= 0x3;
|
||||
|
||||
switch (master_id) {
|
||||
case APM_LL_MASTER_LPCPU:
|
||||
REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_LP_CORE_REGION_PMS, regn_pms);
|
||||
break;
|
||||
case APM_LL_MASTER_HPCPU0:
|
||||
if (sec_mode) {
|
||||
REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_UM_REGION_PMS, regn_pms);
|
||||
} else {
|
||||
REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE0_MM_REGION_PMS, regn_pms);
|
||||
}
|
||||
break;
|
||||
case APM_LL_MASTER_HPCPU1:
|
||||
if (sec_mode) {
|
||||
REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_UM_REGION_PMS, regn_pms);
|
||||
} else {
|
||||
REG_SET_FIELD(PMS_PERI_REGION_PMS_REG, PMS_HP_CORE1_MM_REGION_PMS, regn_pms);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure APM controller clock gating.
|
||||
*
|
||||
* @param apm_ctrl APM controller (LP_PERI/HP_PERI/HP_DMA/LP2HP_PERI/HP2LP_PERI).
|
||||
* @param enable Permission enable/disable.
|
||||
* enable: Enable automatic clock gating.
|
||||
* disable: Keep the clock always on.
|
||||
*/
|
||||
static inline int apm_ll_apm_ctrl_clk_gating_enable(apm_ll_apm_ctrl_t apm_ctrl, bool enable)
|
||||
{
|
||||
uint32_t reg = 0;
|
||||
|
||||
HAL_ASSERT(apm_ctrl < MAX_APM_CTRL);
|
||||
|
||||
switch (apm_ctrl) {
|
||||
case LP_APM_CTRL:
|
||||
reg = PMS_LP_PERI_PMS_CLK_EN_REG;
|
||||
break;
|
||||
case HP2LP_APM_CTRL:
|
||||
reg = PMS_HP2LP_PERI_PMS_CLK_EN_REG;
|
||||
break;
|
||||
case HP_APM_CTRL:
|
||||
reg = PMS_HP_PERI_PMS_CLK_EN_REG;
|
||||
break;
|
||||
case LP2HP_APM_CTRL:
|
||||
reg = PMS_LP2HP_PERI_PMS_CLK_EN_REG;
|
||||
break;
|
||||
case DMA_APM_CTRL:
|
||||
reg = PMS_DMA_CLK_EN_REG;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
REG_CLR_BIT(reg, BIT(0));
|
||||
} else {
|
||||
REG_SET_BIT(reg, BIT(0));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure DMA configurable address range low address.
|
||||
*
|
||||
* @param regn_num Configurable DMA address range number.
|
||||
* @param regn_low_addr Configurable DMA address range start address.
|
||||
*/
|
||||
static inline void apm_ll_dma_region_set_low_address(uint32_t regn_num, uint32_t regn_low_addr)
|
||||
{
|
||||
HAL_ASSERT(regn_num < PMS_DMA_MAX_REGION_NUM);
|
||||
|
||||
REG_WRITE((PMS_DMA_REGION0_LOW_REG + (regn_num * 8)), regn_low_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure DMA configurable address range high address.
|
||||
*
|
||||
* @param regn_num Configurable DMA address range number.
|
||||
* @param regn_high_addr Configurable DMA address range end address.
|
||||
*/
|
||||
static inline void apm_ll_dma_region_set_high_address(uint32_t regn_num, uint32_t regn_high_addr)
|
||||
{
|
||||
HAL_ASSERT(regn_num < PMS_DMA_MAX_REGION_NUM);
|
||||
|
||||
REG_WRITE((PMS_DMA_REGION0_HIGH_REG + (regn_num * 8)), regn_high_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure DMA configurable address range read permission.
|
||||
*
|
||||
* @param dma_master DMA master whose access permission to be configured.
|
||||
* @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission.
|
||||
* 0: Disable read permission.
|
||||
* 1: Enable read permission.
|
||||
*/
|
||||
static inline void apm_ll_dma_region_r_pms(apm_ll_dma_master_t dma_master, uint32_t regn_mask)
|
||||
{
|
||||
HAL_ASSERT(dma_master < PMS_DMA_MAX);
|
||||
|
||||
REG_WRITE(PMS_DMA_PMS_R_REG(dma_master), regn_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure DMA configurable address range write permission.
|
||||
*
|
||||
* @param dma_master DMA master whose access permission to be configured.
|
||||
* @param regn_mask 32-bits field, each bit for corresponding DMA configurable address range permission.
|
||||
* 0: Disable write permission.
|
||||
* 1: Enable write permission.
|
||||
*/
|
||||
static inline void apm_ll_dma_region_w_pms(apm_ll_dma_master_t dma_master, uint32_t regn_mask)
|
||||
{
|
||||
HAL_ASSERT(dma_master < PMS_DMA_MAX);
|
||||
|
||||
REG_WRITE(PMS_DMA_PMS_W_REG(dma_master), regn_mask);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use it in application code.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "esp_hal_security/ds_types.h"
|
||||
#include "hal/config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for DS peripheral module
|
||||
*
|
||||
* @param true to enable the module, false to disable the module
|
||||
*/
|
||||
static inline void _ds_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_ds_clk_en = enable;
|
||||
}
|
||||
|
||||
/// 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 ds_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_ds_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Reset the DS peripheral module
|
||||
*/
|
||||
static inline void ds_ll_reset_register(void)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ds = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ds = 0;
|
||||
|
||||
// Clear reset on parent crypto, otherwise DS is held in reset
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0;
|
||||
}
|
||||
|
||||
/// 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 ds_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
ds_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
static inline void ds_ll_start(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait until DS peripheral has finished any outstanding operation.
|
||||
*/
|
||||
static inline bool ds_ll_busy(void)
|
||||
{
|
||||
return (REG_READ(DS_QUERY_BUSY_REG) > 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Busy wait until the hardware is ready.
|
||||
*/
|
||||
static inline void ds_ll_wait_busy(void)
|
||||
{
|
||||
while (ds_ll_busy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief In case of a key error, check what caused it.
|
||||
*/
|
||||
static inline ds_key_check_t ds_ll_key_error_source(void)
|
||||
{
|
||||
uint32_t key_error = REG_READ(DS_QUERY_KEY_WRONG_REG);
|
||||
if (key_error == 0) {
|
||||
return DS_NO_KEY_INPUT;
|
||||
} else {
|
||||
return DS_OTHER_WRONG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the DS key source.
|
||||
*/
|
||||
static inline void ds_ll_set_key_source(ds_key_source_t key_source)
|
||||
{
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
REG_WRITE(DS_KEY_SOURCE_REG, key_source);
|
||||
#endif /* HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the initialization vector to the corresponding register field.
|
||||
*/
|
||||
static inline void ds_ll_configure_iv(const uint32_t *iv)
|
||||
{
|
||||
for (size_t i = 0; i < (SOC_DS_KEY_PARAM_MD_IV_LENGTH / sizeof(uint32_t)); i++) {
|
||||
REG_WRITE(DS_IV_MEM + (i * 4), iv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the message which should be signed.
|
||||
*
|
||||
* @param msg Pointer to the message.
|
||||
* @param size Length of msg in bytes. It is the RSA signature length in bytes.
|
||||
*/
|
||||
static inline void ds_ll_write_message(const uint8_t *msg, size_t size)
|
||||
{
|
||||
memcpy((uint8_t*) DS_X_MEM, msg, size);
|
||||
// Fence ensures all memory operations are completed before proceeding further
|
||||
asm volatile("fence");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the encrypted private key parameters.
|
||||
*/
|
||||
static inline void ds_ll_write_private_key_params(const uint8_t *encrypted_key_params)
|
||||
{
|
||||
/* Note: as the internal peripheral still has RSA 4096 structure,
|
||||
but C is encrypted based on the actual max RSA length (ETS_DS_MAX_BITS), need to fragment it
|
||||
when copying to hardware...
|
||||
|
||||
(note if ETS_DS_MAX_BITS == 4096, this should be the same as copying data->c to hardware in one fragment)
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t addr;
|
||||
size_t len;
|
||||
} frag_t;
|
||||
const frag_t frags[] = {
|
||||
{DS_Y_MEM, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_M_MEM, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_RB_MEM, SOC_DS_SIGNATURE_MAX_BIT_LEN / 8},
|
||||
{DS_BOX_MEM, DS_IV_MEM - DS_BOX_MEM},
|
||||
};
|
||||
const size_t NUM_FRAGS = sizeof(frags) / sizeof(frag_t);
|
||||
const uint8_t *from = encrypted_key_params;
|
||||
|
||||
for (int i = 0; i < NUM_FRAGS; i++) {
|
||||
memcpy((uint8_t *)frags[i].addr, from, frags[i].len);
|
||||
// Fence ensures all memory operations are completed before proceeding further
|
||||
asm volatile("fence");
|
||||
from += frags[i].len;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin signing procedure.
|
||||
*/
|
||||
static inline void ds_ll_start_sign(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_CONTINUE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check the calculated signature.
|
||||
*
|
||||
* @return
|
||||
* - DS_SIGNATURE_OK if no issue is detected with the signature.
|
||||
* - DS_SIGNATURE_PADDING_FAIL if the padding of the private key parameters is wrong.
|
||||
* - DS_SIGNATURE_MD_FAIL if the message digest check failed. This means that the message digest calculated using
|
||||
* the private key parameters fails, i.e., the integrity of the private key parameters is not protected.
|
||||
* - DS_SIGNATURE_PADDING_AND_MD_FAIL if both padding and message digest check fail.
|
||||
*/
|
||||
static inline ds_signature_check_t ds_ll_check_signature(void)
|
||||
{
|
||||
uint32_t result = REG_READ(DS_QUERY_CHECK_REG);
|
||||
switch (result) {
|
||||
case 0:
|
||||
return DS_SIGNATURE_OK;
|
||||
case 1:
|
||||
return DS_SIGNATURE_MD_FAIL;
|
||||
case 2:
|
||||
return DS_SIGNATURE_PADDING_FAIL;
|
||||
default:
|
||||
return DS_SIGNATURE_PADDING_AND_MD_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the signature from the hardware.
|
||||
*
|
||||
* @param result The signature result.
|
||||
* @param size Length of signature result in bytes. It is the RSA signature length in bytes.
|
||||
*/
|
||||
static inline void ds_ll_read_result(uint8_t *result, size_t size)
|
||||
{
|
||||
memcpy(result, (uint8_t*) DS_Z_MEM, size);
|
||||
// Fence ensures all memory operations are completed before proceeding further
|
||||
asm volatile("fence");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exit the signature operation.
|
||||
*
|
||||
* @note This does not deactivate the module. Corresponding clock/reset bits have to be triggered for deactivation.
|
||||
*/
|
||||
static inline void ds_ll_finish(void)
|
||||
{
|
||||
REG_WRITE(DS_SET_FINISH_REG, 1);
|
||||
ds_ll_wait_busy();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "hal/assert.h"
|
||||
#include "esp_hal_security/ecc_types.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "soc/ecc_mult_reg.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/chip_revision.h"
|
||||
#include "hal/config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ECC_PARAM_PX = 0x0,
|
||||
ECC_PARAM_PY,
|
||||
ECC_PARAM_K,
|
||||
ECC_PARAM_QX,
|
||||
ECC_PARAM_QY,
|
||||
ECC_PARAM_QZ,
|
||||
} ecc_ll_param_t;
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for ECC peripheral module
|
||||
*
|
||||
* @param true to enable the module, false to disable the module
|
||||
*/
|
||||
static inline void _ecc_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_ecc_clk_en = enable;
|
||||
}
|
||||
|
||||
/// 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 ecc_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_ecc_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Reset the ECC peripheral module
|
||||
*/
|
||||
static inline void ecc_ll_reset_register(void)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecc = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecc = 0;
|
||||
|
||||
// Clear reset on ECDSA and parent crypto, otherwise ECC is held in reset
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecdsa = 0;
|
||||
}
|
||||
|
||||
/// 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 ecc_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
ecc_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
static inline void ecc_ll_power_up(void) {}
|
||||
static inline void ecc_ll_power_down(void) {}
|
||||
|
||||
static inline void ecc_ll_enable_interrupt(void)
|
||||
{
|
||||
REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1);
|
||||
}
|
||||
|
||||
static inline void ecc_ll_disable_interrupt(void)
|
||||
{
|
||||
REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 0);
|
||||
}
|
||||
|
||||
static inline void ecc_ll_clear_interrupt(void)
|
||||
{
|
||||
REG_SET_FIELD(ECC_MULT_INT_CLR_REG, ECC_MULT_CALC_DONE_INT_CLR, 1);
|
||||
}
|
||||
|
||||
static inline void ecc_ll_set_mode(ecc_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case ECC_MODE_POINT_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0);
|
||||
break;
|
||||
case ECC_MODE_VERIFY:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2);
|
||||
break;
|
||||
case ECC_MODE_VERIFY_THEN_POINT_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 3);
|
||||
break;
|
||||
case ECC_MODE_JACOBIAN_POINT_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 4);
|
||||
break;
|
||||
case ECC_MODE_POINT_ADD:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 5);
|
||||
break;
|
||||
case ECC_MODE_JACOBIAN_POINT_VERIFY:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 6);
|
||||
break;
|
||||
case ECC_MODE_POINT_VERIFY_JACOBIAN_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 7);
|
||||
break;
|
||||
case ECC_MODE_MOD_ADD:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 8);
|
||||
break;
|
||||
case ECC_MODE_MOD_SUB:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 9);
|
||||
break;
|
||||
case ECC_MODE_MOD_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 10);
|
||||
break;
|
||||
case ECC_MODE_INVERSE_MUL:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 11);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported mode");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_set_curve(ecc_curve_t curve)
|
||||
{
|
||||
switch (curve) {
|
||||
case ECC_CURVE_SECP192R1:
|
||||
case ECC_CURVE_SECP256R1:
|
||||
case ECC_CURVE_SECP384R1:
|
||||
case ECC_CURVE_SM2:
|
||||
REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH, curve);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported curve");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_set_mod_base(ecc_mod_base_t base)
|
||||
{
|
||||
switch (base) {
|
||||
case ECC_MOD_N:
|
||||
REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
|
||||
break;
|
||||
case ECC_MOD_P:
|
||||
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported curve");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t word;
|
||||
switch (param) {
|
||||
case ECC_PARAM_PX:
|
||||
reg = ECC_MULT_PX_MEM;
|
||||
break;
|
||||
case ECC_PARAM_PY:
|
||||
reg = ECC_MULT_PY_MEM;
|
||||
break;
|
||||
case ECC_PARAM_K:
|
||||
reg = ECC_MULT_K_MEM;
|
||||
break;
|
||||
case ECC_PARAM_QX:
|
||||
reg = ECC_MULT_QX_MEM;
|
||||
break;
|
||||
case ECC_PARAM_QY:
|
||||
reg = ECC_MULT_QY_MEM;
|
||||
break;
|
||||
case ECC_PARAM_QZ:
|
||||
reg = ECC_MULT_QZ_MEM;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Invalid parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i += 4) {
|
||||
memcpy(&word, buf + i, 4);
|
||||
REG_WRITE(reg + i, word);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ecc_ll_start_calc(void)
|
||||
{
|
||||
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_START);
|
||||
}
|
||||
|
||||
static inline int ecc_ll_is_calc_finished(void)
|
||||
{
|
||||
return REG_GET_FIELD(ECC_MULT_INT_RAW_REG, ECC_MULT_CALC_DONE_INT_RAW);
|
||||
}
|
||||
|
||||
static inline ecc_mode_t ecc_ll_get_mode(void)
|
||||
{
|
||||
return (ecc_mode_t)(REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE));
|
||||
}
|
||||
|
||||
static inline int ecc_ll_get_verification_result(void)
|
||||
{
|
||||
return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_VERIFICATION_RESULT);
|
||||
}
|
||||
|
||||
static inline ecc_curve_t ecc_ll_get_curve(void)
|
||||
{
|
||||
return (ecc_curve_t)(REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH));
|
||||
}
|
||||
|
||||
static inline ecc_mod_base_t ecc_ll_get_mod_base(void)
|
||||
{
|
||||
return (ecc_mod_base_t)(REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE));
|
||||
}
|
||||
|
||||
static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint32_t reg;
|
||||
switch (param) {
|
||||
case ECC_PARAM_PX:
|
||||
reg = ECC_MULT_PX_MEM;
|
||||
break;
|
||||
case ECC_PARAM_PY:
|
||||
reg = ECC_MULT_PY_MEM;
|
||||
break;
|
||||
case ECC_PARAM_K:
|
||||
reg = ECC_MULT_K_MEM;
|
||||
break;
|
||||
case ECC_PARAM_QX:
|
||||
reg = ECC_MULT_QX_MEM;
|
||||
break;
|
||||
case ECC_PARAM_QY:
|
||||
reg = ECC_MULT_QY_MEM;
|
||||
break;
|
||||
case ECC_PARAM_QZ:
|
||||
reg = ECC_MULT_QZ_MEM;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Invalid parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(buf, (void *)reg, len);
|
||||
}
|
||||
|
||||
static inline bool ecc_ll_is_p384_curve_operations_supported(void)
|
||||
{
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void ecc_ll_enable_constant_time_point_mul(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_SECURITY_MODE);
|
||||
} else {
|
||||
REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_SECURITY_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use it in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "soc/system_reg.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "esp_hal_security/hmac_hal.h"
|
||||
|
||||
#define SHA256_BLOCK_SZ 64
|
||||
#define SHA256_DIGEST_SZ 32
|
||||
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG 6
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE 7
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_UP 8
|
||||
#define EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL 5
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for HMAC peripheral module
|
||||
*
|
||||
* @param true to enable the module, false to disable the module
|
||||
*/
|
||||
static inline void _hmac_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_hmac_clk_en = enable;
|
||||
}
|
||||
|
||||
/// 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 hmac_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_hmac_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Reset the HMAC peripheral module
|
||||
*/
|
||||
static inline void hmac_ll_reset_register(void)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_hmac = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_hmac = 0;
|
||||
|
||||
// Clear reset on parent crypto, otherwise HMAC is held in reset
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0;
|
||||
}
|
||||
|
||||
/// 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 hmac_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
hmac_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Makes the peripheral ready for use, after enabling it.
|
||||
*/
|
||||
static inline void hmac_ll_start(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine where the HMAC output should go.
|
||||
*
|
||||
* The HMAC peripheral can be configured to deliver its output to the user directly, or to deliver
|
||||
* the output directly to another peripheral instead, e.g. the Digital Signature peripheral.
|
||||
*/
|
||||
static inline void hmac_ll_config_output(hmac_hal_output_t config)
|
||||
{
|
||||
switch (config) {
|
||||
case HMAC_OUTPUT_USER:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_UP);
|
||||
break;
|
||||
case HMAC_OUTPUT_DS:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE);
|
||||
break;
|
||||
case HMAC_OUTPUT_JTAG_ENABLE:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG);
|
||||
break;
|
||||
case HMAC_OUTPUT_ALL:
|
||||
REG_WRITE(HMAC_SET_PARA_PURPOSE_REG, EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL);
|
||||
break;
|
||||
default:
|
||||
; // do nothing, error will be indicated by hmac_hal_config_error()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects which hardware key should be used.
|
||||
*/
|
||||
static inline void hmac_ll_config_hw_key_id(uint32_t key_id)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_PARA_KEY_REG, key_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Apply and check configuration.
|
||||
*
|
||||
* Afterwards, the configuration can be checked for errors with hmac_hal_config_error().
|
||||
*/
|
||||
static inline void hmac_ll_config_finish(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_PARA_FINISH_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Query HMAC error state after configuration actions.
|
||||
*
|
||||
* @return
|
||||
* - 1 or greater on error
|
||||
* - 0 on success
|
||||
*/
|
||||
static inline uint32_t hmac_ll_config_error(void)
|
||||
{
|
||||
return REG_READ(HMAC_QUERY_ERROR_REG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until the HAL is ready for the next interaction.
|
||||
*/
|
||||
static inline void hmac_ll_wait_idle(void)
|
||||
{
|
||||
uint32_t query;
|
||||
do {
|
||||
query = REG_READ(HMAC_QUERY_BUSY_REG);
|
||||
} while (query != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a message block of 512 bits to the HMAC peripheral.
|
||||
*/
|
||||
static inline void hmac_ll_write_block_512(const uint32_t *block)
|
||||
{
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
for (size_t i = 0; i < SHA256_BLOCK_SZ / REG_WIDTH; i++) {
|
||||
REG_WRITE(HMAC_WR_MESSAGE_MEM + (i * REG_WIDTH), block[i]);
|
||||
}
|
||||
|
||||
REG_WRITE(HMAC_SET_MESSAGE_ONE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the 256 bit HMAC.
|
||||
*/
|
||||
static inline void hmac_ll_read_result_256(uint32_t *result)
|
||||
{
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
for (size_t i = 0; i < SHA256_DIGEST_SZ / REG_WIDTH; i++) {
|
||||
result[i] = REG_READ(HMAC_RD_RESULT_MEM + (i * REG_WIDTH));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clean the HMAC result provided to other hardware.
|
||||
*/
|
||||
static inline void hmac_ll_clean(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_INVALIDATE_DS_REG, 1);
|
||||
REG_WRITE(HMAC_SET_INVALIDATE_JTAG_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Signals that the following block will be the padded last block.
|
||||
*/
|
||||
static inline void hmac_ll_msg_padding(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_MESSAGE_PAD_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Signals that all blocks have been written and a padding block will automatically be applied by hardware.
|
||||
*
|
||||
* Only applies if the message length is a multiple of 512 bits.
|
||||
* See the chip TRM HMAC chapter for more details.
|
||||
*/
|
||||
static inline void hmac_ll_msg_end(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_MESSAGE_END_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The message including padding fits into one block, so no further action needs to be taken.
|
||||
*
|
||||
* This is called after the one-block-message has been written.
|
||||
*/
|
||||
static inline void hmac_ll_msg_one_block(void)
|
||||
{
|
||||
REG_WRITE(HMAC_ONE_BLOCK_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Indicate that more blocks will be written after the last block.
|
||||
*/
|
||||
static inline void hmac_ll_msg_continue(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_MESSAGE_ING_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the HMAC result.
|
||||
*
|
||||
* Use this after reading the HMAC result or if aborting after any of the other steps above.
|
||||
*/
|
||||
static inline void hmac_ll_calc_finish(void)
|
||||
{
|
||||
REG_WRITE(HMAC_SET_RESULT_FINISH_REG, 2);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use it in application code.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if SOC_KEY_MANAGER_SUPPORTED
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_hal_security/huk_types.h"
|
||||
#include "soc/huk_reg.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void huk_ll_power_up(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* @brief Configure the HUK mode */
|
||||
static inline void huk_ll_configure_mode(const esp_huk_mode_t huk_mode)
|
||||
{
|
||||
REG_SET_FIELD(HUK_CONF_REG, HUK_MODE, huk_mode);
|
||||
}
|
||||
|
||||
static inline void huk_ll_write_info(const uint8_t *buffer, const size_t size)
|
||||
{
|
||||
memcpy((uint8_t *)HUK_INFO_MEM, buffer, size);
|
||||
}
|
||||
|
||||
static inline void huk_ll_read_info(uint8_t *buffer, const size_t size)
|
||||
{
|
||||
memcpy(buffer, (uint8_t *)HUK_INFO_MEM, size);
|
||||
}
|
||||
|
||||
/* @brief Start the HUK at IDLE state */
|
||||
static inline void huk_ll_start(void)
|
||||
{
|
||||
REG_SET_FIELD(HUK_START_REG, HUK_START, 1);
|
||||
}
|
||||
|
||||
/* @brief Continue HUK operation at LOAD/GAIN state */
|
||||
static inline void huk_ll_continue(void)
|
||||
{
|
||||
REG_SET_FIELD(HUK_START_REG, HUK_CONTINUE, 1);
|
||||
}
|
||||
|
||||
/* @bried Enable or Disable the HUK interrupts */
|
||||
static inline void huk_ll_configure_interrupt(const esp_huk_interrupt_type_t intr, const bool en)
|
||||
{
|
||||
switch (intr) {
|
||||
case ESP_HUK_INT_PREP_DONE:
|
||||
REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PREP_DONE_INT_ENA, en);
|
||||
break;
|
||||
case ESP_HUK_INT_PROC_DONE:
|
||||
REG_SET_FIELD(HUK_INT_ENA_REG, HUK_PROC_DONE_INT_ENA, en);
|
||||
break;
|
||||
case ESP_HUK_INT_POST_DONE:
|
||||
REG_SET_FIELD(HUK_INT_ENA_REG, HUK_POST_DONE_INT_ENA, en);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* @bried Clear the HUK interrupts */
|
||||
static inline void huk_ll_clear_int(const esp_huk_interrupt_type_t intr)
|
||||
{
|
||||
switch (intr) {
|
||||
case ESP_HUK_INT_PREP_DONE:
|
||||
REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PREP_DONE_INT_CLR, 1);
|
||||
break;
|
||||
case ESP_HUK_INT_PROC_DONE:
|
||||
REG_SET_FIELD(HUK_INT_CLR_REG, HUK_PROC_DONE_INT_CLR, 1);
|
||||
break;
|
||||
case ESP_HUK_INT_POST_DONE:
|
||||
REG_SET_FIELD(HUK_INT_CLR_REG, HUK_POST_DONE_INT_CLR, 1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read state of Hardware Unique Key Generator
|
||||
*
|
||||
* @return esp_huk_state_t
|
||||
*/
|
||||
static inline esp_huk_state_t huk_ll_get_state(void)
|
||||
{
|
||||
return (esp_huk_state_t) REG_GET_FIELD(HUK_STATE_REG, HUK_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the HUK generation status
|
||||
*/
|
||||
static inline esp_huk_gen_status_t huk_ll_get_gen_status(void)
|
||||
{
|
||||
return (esp_huk_gen_status_t) REG_GET_FIELD(HUK_STATUS_REG, HUK_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the HUK date information
|
||||
*/
|
||||
static inline uint32_t huk_ll_get_date_info(void)
|
||||
{
|
||||
// Only the least significant 28 bits have desired information
|
||||
return (uint32_t)(0x0FFFFFFF & REG_READ(HUK_DATE_REG));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,535 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use it in application code.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hal/assert.h"
|
||||
#include "esp_hal_security/key_mgr_types.h"
|
||||
#include "soc/keymng_reg.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "hal/config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) < 300
|
||||
#define KEYMNG_USE_EFUSE_KEY_FLASH KEYMNG_USE_EFUSE_KEY_XTS
|
||||
#define KEYMNG_USE_EFUSE_KEY_LOCK_FLASH KEYMNG_USE_EFUSE_KEY_LOCK_XTS
|
||||
#define KEYMNG_KEY_FLASH_VLD KEYMNG_KEY_XTS_VLD
|
||||
#define KEYMNG_KEY_FLASH_VLD_V KEYMNG_KEY_XTS_VLD_V
|
||||
#define KEYMNG_KEY_FLASH_VLD_S KEYMNG_KEY_XTS_VLD_S
|
||||
#define KEYMNG_KEY_ECDSA_192_VLD KEYMNG_KEY_ECDSA_VLD
|
||||
#define KEYMNG_KEY_ECDSA_192_VLD_V KEYMNG_KEY_ECDSA_VLD_V
|
||||
#define KEYMNG_KEY_ECDSA_192_VLD_S KEYMNG_KEY_ECDSA_VLD_S
|
||||
#define KEYMNG_KEY_ECDSA_256_VLD KEYMNG_KEY_ECDSA_VLD
|
||||
#define KEYMNG_KEY_ECDSA_256_VLD_V KEYMNG_KEY_ECDSA_VLD_V
|
||||
#define KEYMNG_KEY_ECDSA_256_VLD_S KEYMNG_KEY_ECDSA_VLD_S
|
||||
#define KEYMNG_KEY_ECDSA_384_VLD KEYMNG_KEY_ECDSA_VLD
|
||||
#define KEYMNG_KEY_ECDSA_384_VLD_V KEYMNG_KEY_ECDSA_VLD_V
|
||||
#define KEYMNG_KEY_ECDSA_384_VLD_S KEYMNG_KEY_ECDSA_VLD_S
|
||||
#define KEYMNG_FLASH_KEY_LEN KEYMNG_XTS_AES_KEY_LEN
|
||||
#define KEYMNG_FLASH_KEY_LEN_V KEYMNG_XTS_AES_KEY_LEN_V
|
||||
#define KEYMNG_FLASH_KEY_LEN_S KEYMNG_XTS_AES_KEY_LEN_S
|
||||
#endif
|
||||
|
||||
static inline void key_mgr_ll_power_up(void)
|
||||
{
|
||||
// TODO: IDF-13524
|
||||
}
|
||||
|
||||
static inline void key_mgr_ll_power_down(void)
|
||||
{
|
||||
// TODO: IDF-13524
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for Key Manager peripheral
|
||||
* Note: Please use key_mgr_ll_enable_bus_clock which requires the critical section
|
||||
* and do not use _key_mgr_ll_enable_bus_clock
|
||||
* @param true to enable, false to disable
|
||||
*/
|
||||
static inline void _key_mgr_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
HP_SYS_CLKRST.soc_clk_ctrl1.reg_key_manager_sys_clk_en = enable;
|
||||
}
|
||||
|
||||
/// 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 key_mgr_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_key_mgr_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Enable the peripheral clock for Key Manager
|
||||
*
|
||||
* Note: Please use key_mgr_ll_enable_peripheral_clock which requires the critical section
|
||||
* and do not use _key_mgr_ll_enable_peripheral_clock
|
||||
* @param true to enable, false to disable
|
||||
*/
|
||||
static inline void _key_mgr_ll_enable_peripheral_clock(bool enable)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_km_clk_en = enable;
|
||||
}
|
||||
|
||||
#define key_mgr_ll_enable_peripheral_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_key_mgr_ll_enable_peripheral_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Read state of Key Manager
|
||||
*
|
||||
* @return esp_key_mgr_state_t
|
||||
*/
|
||||
static inline esp_key_mgr_state_t key_mgr_ll_get_state(void)
|
||||
{
|
||||
return (esp_key_mgr_state_t) REG_GET_FIELD(KEYMNG_STATE_REG, KEYMNG_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset the Key Manager peripheral
|
||||
* Note: Please use key_mgr_ll_reset_register which requires the critical section
|
||||
* and do not use _key_mgr_ll_reset_register
|
||||
*/
|
||||
static inline void _key_mgr_ll_reset_register(void)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_km = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_km = 0;
|
||||
|
||||
// Clear reset on parent crypto, otherwise Key Manager is held in reset
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0;
|
||||
|
||||
while (key_mgr_ll_get_state() != ESP_KEY_MGR_STATE_IDLE) {
|
||||
};
|
||||
}
|
||||
|
||||
/// 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 key_mgr_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_key_mgr_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/* @brief Start the key manager at IDLE state */
|
||||
static inline void key_mgr_ll_start(void)
|
||||
{
|
||||
REG_SET_BIT(KEYMNG_START_REG, KEYMNG_START);
|
||||
}
|
||||
|
||||
/* @brief Continue key manager operation at LOAD/GAIN state */
|
||||
static inline void key_mgr_ll_continue(void)
|
||||
{
|
||||
REG_SET_BIT(KEYMNG_START_REG, KEYMNG_CONTINUE);
|
||||
}
|
||||
|
||||
/* @brief Enable or Disable the KEY_MGR interrupts */
|
||||
static inline void key_mgr_ll_configure_interrupt(const esp_key_mgr_interrupt_type_t intr, bool en)
|
||||
{
|
||||
switch (intr) {
|
||||
case ESP_KEY_MGR_INT_PREP_DONE:
|
||||
REG_SET_FIELD(KEYMNG_INT_ENA_REG, KEYMNG_PREP_DONE_INT_ENA, en);
|
||||
break;
|
||||
case ESP_KEY_MGR_INT_PROC_DONE:
|
||||
REG_SET_FIELD(KEYMNG_INT_ENA_REG, KEYMNG_PROC_DONE_INT_ENA, en);
|
||||
break;
|
||||
case ESP_KEY_MGR_INT_POST_DONE:
|
||||
REG_SET_FIELD(KEYMNG_INT_ENA_REG, KEYMNG_POST_DONE_INT_ENA, en);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Clear the KEY_MGR interrupts */
|
||||
static inline void key_mgr_ll_clear_int(const esp_key_mgr_interrupt_type_t intr)
|
||||
{
|
||||
switch (intr) {
|
||||
case ESP_KEY_MGR_INT_PREP_DONE:
|
||||
REG_SET_FIELD(KEYMNG_INT_CLR_REG, KEYMNG_PREP_DONE_INT_CLR, 1);
|
||||
break;
|
||||
case ESP_KEY_MGR_INT_PROC_DONE:
|
||||
REG_SET_FIELD(KEYMNG_INT_CLR_REG, KEYMNG_PROC_DONE_INT_CLR, 1);
|
||||
break;
|
||||
case ESP_KEY_MGR_INT_POST_DONE:
|
||||
REG_SET_FIELD(KEYMNG_INT_CLR_REG, KEYMNG_POST_DONE_INT_CLR, 1);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the key manager to use the software provided init key
|
||||
*/
|
||||
static inline void key_mgr_ll_use_sw_init_key(void)
|
||||
{
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_SW_INIT_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the key manager key usage policy for a particular key type
|
||||
*
|
||||
*/
|
||||
static inline void key_mgr_ll_set_key_usage(const esp_key_mgr_key_type_t key_type, const esp_key_mgr_key_usage_t key_usage)
|
||||
{
|
||||
switch (key_type) {
|
||||
case ESP_KEY_MGR_ECDSA_KEY:
|
||||
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA);
|
||||
} else {
|
||||
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA);
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_KEY_MGR_FLASH_XTS_AES_KEY:
|
||||
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_FLASH);
|
||||
} else {
|
||||
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_FLASH);
|
||||
}
|
||||
break;
|
||||
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
case ESP_KEY_MGR_HMAC_KEY:
|
||||
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_HMAC);
|
||||
} else {
|
||||
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_HMAC);
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_KEY_MGR_DS_KEY:
|
||||
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_DS);
|
||||
} else {
|
||||
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_DS);
|
||||
}
|
||||
break;
|
||||
|
||||
case ESP_KEY_MGR_PSRAM_XTS_AES_KEY:
|
||||
if (key_usage == ESP_KEY_MGR_USE_EFUSE_KEY) {
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_PSRAM);
|
||||
} else {
|
||||
REG_CLR_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_PSRAM);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static inline esp_key_mgr_key_usage_t key_mgr_ll_get_key_usage(esp_key_mgr_key_type_t key_type)
|
||||
{
|
||||
switch (key_type) {
|
||||
case ESP_KEY_MGR_ECDSA_KEY:
|
||||
return (esp_key_mgr_key_usage_t)(REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_ECDSA));
|
||||
|
||||
case ESP_KEY_MGR_FLASH_XTS_AES_KEY:
|
||||
return (esp_key_mgr_key_usage_t)(REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_FLASH));
|
||||
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
case ESP_KEY_MGR_HMAC_KEY:
|
||||
return (esp_key_mgr_key_usage_t)(REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_HMAC));
|
||||
|
||||
case ESP_KEY_MGR_DS_KEY:
|
||||
return (esp_key_mgr_key_usage_t)(REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_DS));
|
||||
|
||||
case ESP_KEY_MGR_PSRAM_XTS_AES_KEY:
|
||||
return (esp_key_mgr_key_usage_t)(REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY_PSRAM));
|
||||
#endif
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return ESP_KEY_MGR_USAGE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lock for the use_sw_init_key_reg
|
||||
* After this lock has been set,
|
||||
* The Key manager configuration about the use of software init key cannot be changed
|
||||
*/
|
||||
static inline void key_mgr_ll_lock_use_sw_init_key_reg(void)
|
||||
{
|
||||
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_SW_INIT_KEY_LOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the lock for the use_sw_init_key_reg
|
||||
* After this lock has been set,
|
||||
* The Key manager configuration about whether to use a particular key from efuse or key manager cannot be changed.
|
||||
*/
|
||||
static inline void key_mgr_ll_lock_use_efuse_key_reg(esp_key_mgr_key_type_t key_type)
|
||||
{
|
||||
switch (key_type) {
|
||||
case ESP_KEY_MGR_ECDSA_KEY:
|
||||
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_ECDSA);
|
||||
break;
|
||||
|
||||
case ESP_KEY_MGR_FLASH_XTS_AES_KEY:
|
||||
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_FLASH);
|
||||
break;
|
||||
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
case ESP_KEY_MGR_HMAC_KEY:
|
||||
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_HMAC);
|
||||
break;
|
||||
|
||||
case ESP_KEY_MGR_DS_KEY:
|
||||
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_DS);
|
||||
break;
|
||||
|
||||
case ESP_KEY_MGR_PSRAM_XTS_AES_KEY:
|
||||
REG_SET_BIT(KEYMNG_LOCK_REG, KEYMNG_USE_EFUSE_KEY_LOCK_PSRAM);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Configure the key purpose to be used by the Key Manager for key generator operation */
|
||||
static inline void key_mgr_ll_set_key_purpose(const esp_key_mgr_key_purpose_t key_purpose)
|
||||
{
|
||||
REG_SET_FIELD(KEYMNG_CONF_REG, KEYMNG_KEY_PURPOSE, key_purpose);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the mode which is used by the Key Manager for the generator key deployment process
|
||||
*/
|
||||
static inline void key_mgr_ll_set_key_generator_mode(const esp_key_mgr_key_generator_mode_t mode)
|
||||
{
|
||||
REG_SET_FIELD(KEYMNG_CONF_REG, KEYMNG_KGEN_MODE, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the key manager process result
|
||||
* @return 1 for Success
|
||||
* 0 for failure
|
||||
*/
|
||||
static inline bool key_mgr_ll_is_result_success(void)
|
||||
{
|
||||
return REG_GET_FIELD(KEYMNG_RESULT_REG, KEYMNG_PROC_RESULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the deployed key is valid or not
|
||||
* @return 1 for Success
|
||||
* 0 for failure
|
||||
*/
|
||||
static inline bool key_mgr_ll_is_key_deployment_valid(const esp_key_mgr_key_type_t key_type, const esp_key_mgr_key_len_t key_len)
|
||||
{
|
||||
switch (key_type) {
|
||||
case ESP_KEY_MGR_ECDSA_KEY:
|
||||
switch (key_len) {
|
||||
case ESP_KEY_MGR_ECDSA_LEN_192:
|
||||
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_ECDSA_192_VLD);
|
||||
case ESP_KEY_MGR_ECDSA_LEN_256:
|
||||
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_ECDSA_256_VLD);
|
||||
case ESP_KEY_MGR_ECDSA_LEN_384:
|
||||
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_ECDSA_384_VLD);
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ESP_KEY_MGR_FLASH_XTS_AES_KEY:
|
||||
switch (key_len) {
|
||||
case ESP_KEY_MGR_XTS_AES_LEN_128:
|
||||
case ESP_KEY_MGR_XTS_AES_LEN_256:
|
||||
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_FLASH_VLD);
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
case ESP_KEY_MGR_HMAC_KEY:
|
||||
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_HMAC_VLD);
|
||||
|
||||
case ESP_KEY_MGR_DS_KEY:
|
||||
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_DS_VLD);
|
||||
|
||||
case ESP_KEY_MGR_PSRAM_XTS_AES_KEY:
|
||||
switch (key_len) {
|
||||
case ESP_KEY_MGR_XTS_AES_LEN_128:
|
||||
case ESP_KEY_MGR_XTS_AES_LEN_256:
|
||||
return REG_GET_FIELD(KEYMNG_KEY_VLD_REG, KEYMNG_KEY_PSRAM_VLD);
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported mode");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Write the SW init key in the key manager registers
|
||||
*
|
||||
* @input
|
||||
* sw_init_key_buf Init key buffer, this should be a readable buffer of data_len size which should contain the sw init key. The buffer must be 32 bit aligned
|
||||
* data_len Length of the init key buffer
|
||||
*/
|
||||
static inline void key_mgr_ll_write_sw_init_key(const uint8_t *sw_init_key_buf, const size_t data_len)
|
||||
{
|
||||
memcpy((uint8_t *)KEYMNG_SW_INIT_KEY_MEM, sw_init_key_buf, data_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Write the Assist info in the key manager registers
|
||||
*
|
||||
* @input
|
||||
* assist_info_buf Assist info buffer, this should be a readable buffer of data_len size which should contain the assist info. The buffer must be 32 bit aligned
|
||||
* data_len Length of the assist info buffer
|
||||
*/
|
||||
static inline void key_mgr_ll_write_assist_info(const uint8_t *assist_info_buf, const size_t data_len)
|
||||
{
|
||||
memcpy((uint8_t *)KEYMNG_ASSIST_INFO_MEM, assist_info_buf, data_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Read the Assist info from the key manager registers
|
||||
*
|
||||
* @input
|
||||
* assist_info_buf Assist info buffer, this should be a writable buffer of size KEY_MGR_ASSIST_INFO_LEN. The buffer must be 32 bit aligned
|
||||
*/
|
||||
static inline void key_mgr_ll_read_assist_info(uint8_t *assist_info_buf)
|
||||
{
|
||||
memcpy(assist_info_buf, (uint8_t *)KEYMNG_ASSIST_INFO_MEM, KEY_MGR_ASSIST_INFO_LEN);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Write the Public info in the key manager registers
|
||||
* @input
|
||||
* public_info_buf Public info buffer, this should be a readable buffer of data_len size which should contain the public info. The buffer must be 32 bit aligned
|
||||
* data_len Length of the public info buffer
|
||||
*/
|
||||
static inline void key_mgr_ll_write_public_info(const uint8_t *public_info_buf, const size_t data_len)
|
||||
{
|
||||
memcpy((uint8_t *)KEYMNG_PUBLIC_INFO_MEM, public_info_buf, data_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Read the Public info in the key manager registers
|
||||
* @input
|
||||
* public_info_buf Public info buffer, this should be a writable buffer of read_len, The buffer must be 32 bit aligned
|
||||
* read_len Length of the public info buffer
|
||||
*/
|
||||
static inline void key_mgr_ll_read_public_info(uint8_t *public_info_buf, const size_t read_len)
|
||||
{
|
||||
memcpy(public_info_buf, (uint8_t *)KEYMNG_PUBLIC_INFO_MEM, read_len);
|
||||
}
|
||||
|
||||
static inline bool key_mgr_ll_is_huk_valid(void)
|
||||
{
|
||||
return REG_GET_FIELD(KEYMNG_HUK_VLD_REG, KEYMNG_HUK_VALID);
|
||||
}
|
||||
|
||||
/* @brief Set the XTS-AES (Flash Encryption) key length for the Key Manager */
|
||||
static inline void key_mgr_ll_set_xts_aes_key_len(const esp_key_mgr_key_type_t key_type, const esp_key_mgr_key_len_t key_len)
|
||||
{
|
||||
uint32_t key_len_bit_mask;
|
||||
|
||||
if (key_type == ESP_KEY_MGR_FLASH_XTS_AES_KEY) {
|
||||
key_len_bit_mask = KEYMNG_FLASH_KEY_LEN;
|
||||
}
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
else if (key_type == ESP_KEY_MGR_PSRAM_XTS_AES_KEY) {
|
||||
key_len_bit_mask = KEYMNG_PSRAM_KEY_LEN;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (key_len) {
|
||||
case ESP_KEY_MGR_XTS_AES_LEN_128:
|
||||
REG_CLR_BIT(KEYMNG_STATIC_REG, key_len_bit_mask);
|
||||
break;
|
||||
case ESP_KEY_MGR_XTS_AES_LEN_256:
|
||||
REG_SET_BIT(KEYMNG_STATIC_REG, key_len_bit_mask);
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key length");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* @brief Get the XTS-AES (Flash Encryption) key length for the Key Manager */
|
||||
static inline esp_key_mgr_key_len_t key_mgr_ll_get_xts_aes_key_len(const esp_key_mgr_key_type_t key_type)
|
||||
{
|
||||
uint32_t key_len_bit = 0;
|
||||
|
||||
if (key_type == ESP_KEY_MGR_FLASH_XTS_AES_KEY) {
|
||||
key_len_bit = REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_FLASH_KEY_LEN);
|
||||
}
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
|
||||
else if (key_type == ESP_KEY_MGR_PSRAM_XTS_AES_KEY) {
|
||||
key_len_bit = REG_GET_BIT(KEYMNG_STATIC_REG, KEYMNG_PSRAM_KEY_LEN);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
HAL_ASSERT(false && "Unsupported key type");
|
||||
return (esp_key_mgr_key_len_t) key_len_bit;
|
||||
}
|
||||
|
||||
switch (key_len_bit) {
|
||||
case 0:
|
||||
return ESP_KEY_MGR_XTS_AES_LEN_128;
|
||||
case 1:
|
||||
return ESP_KEY_MGR_XTS_AES_LEN_256;
|
||||
default:
|
||||
HAL_ASSERT(false && "Unsupported key length");
|
||||
return (esp_key_mgr_key_len_t) key_len_bit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the Key Manager date information
|
||||
*/
|
||||
static inline uint32_t key_mgr_ll_get_date_info(void)
|
||||
{
|
||||
// Only the least significant 28 bits have desired information
|
||||
return (uint32_t)(0x0FFFFFFF & REG_READ(KEYMNG_DATE_REG));
|
||||
}
|
||||
|
||||
static inline bool key_mgr_ll_is_supported(void)
|
||||
{
|
||||
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) < 300
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool key_mgr_ll_flash_encryption_supported(void)
|
||||
{
|
||||
if (!key_mgr_ll_is_supported()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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 "esp_hal_security/mpi_types.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/mpi_periph.h"
|
||||
#include "soc/rsa_reg.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)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_rsa_clk_en = enable;
|
||||
}
|
||||
|
||||
/// 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)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_rsa = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_rsa = 0;
|
||||
|
||||
// Clear reset on digital signature, ECDSA and parent crypto, otherwise RSA is held in reset
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ds = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecdsa = 0;
|
||||
}
|
||||
|
||||
/// 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)
|
||||
|
||||
static inline size_t mpi_ll_calculate_hardware_words(size_t words)
|
||||
{
|
||||
return words;
|
||||
}
|
||||
|
||||
// No need to initialize Power Control Registers in case of ESP32-P4
|
||||
static inline void mpi_ll_power_up(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void mpi_ll_power_down(void)
|
||||
{
|
||||
}
|
||||
|
||||
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_OPERATIONS_REG[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_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_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;
|
||||
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_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
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_hal_security/sha_types.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/hwcrypto_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_crypto_sha_clk_en = enable;
|
||||
}
|
||||
|
||||
/// 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)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_sha = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_sha = 0;
|
||||
|
||||
// Clear reset on digital signature, hmac, ecdsa and parent crypto, otherwise SHA is held in reset
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_crypto = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ds = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_hmac = 0;
|
||||
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_ecdsa = 0;
|
||||
}
|
||||
|
||||
/// 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 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)
|
||||
{
|
||||
REG_WRITE(SHA_MODE_REG, sha_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a new SHA block conversions (no initial hash in HW)
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_start_block(esp_sha_type sha_type)
|
||||
{
|
||||
(void) sha_type;
|
||||
REG_WRITE(SHA_START_REG, 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)
|
||||
{
|
||||
(void) sha_type;
|
||||
REG_WRITE(SHA_CONTINUE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a new SHA message conversion using DMA (no initial hash in HW)
|
||||
*/
|
||||
static inline void sha_ll_start_dma(void)
|
||||
{
|
||||
REG_WRITE(SHA_DMA_START_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Continue a SHA message conversion using DMA (initial hash in HW)
|
||||
*/
|
||||
static inline void sha_ll_continue_dma(void)
|
||||
{
|
||||
REG_WRITE(SHA_DMA_CONTINUE_REG, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load the current hash digest to digest register
|
||||
*
|
||||
* @note Happens automatically on ESP32P4
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
*/
|
||||
static inline void sha_ll_load(esp_sha_type sha_type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the number of message blocks to be hashed
|
||||
*
|
||||
* @note DMA operation only
|
||||
*
|
||||
* @param num_blocks Number of message blocks to process
|
||||
*/
|
||||
static inline void sha_ll_set_block_num(size_t num_blocks)
|
||||
{
|
||||
REG_WRITE(SHA_DMA_BLOCK_NUM_REG, num_blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 REG_READ(SHA_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 *data_words = (uint32_t *)input_text;
|
||||
uint32_t *reg_addr_buf = (uint32_t *)(SHA_M_MEM);
|
||||
|
||||
for (int i = 0; i < block_word_len; i++) {
|
||||
REG_WRITE(®_addr_buf[i], 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;
|
||||
const size_t REG_WIDTH = sizeof(uint32_t);
|
||||
|
||||
for (size_t i = 0; i < digest_word_len; i++) {
|
||||
digest_state_words[i] = REG_READ(SHA_H_MEM + (i * REG_WIDTH));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the message digest to the SHA engine
|
||||
*
|
||||
* @param sha_type The SHA algorithm type
|
||||
* @param digest_state Message digest to be written to SHA engine
|
||||
* @param digest_word_len Length of the message digest
|
||||
*/
|
||||
static inline void sha_ll_write_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_H_MEM);
|
||||
|
||||
for (int i = 0; i < digest_word_len; i++) {
|
||||
REG_WRITE(®_addr_buf[i], digest_state_words[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets SHA512_t T_string parameter
|
||||
*
|
||||
* @param t_string T_string parameter
|
||||
*/
|
||||
static inline void sha_ll_t_string_set(uint32_t t_string)
|
||||
{
|
||||
REG_WRITE(SHA_T_STRING_REG, t_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets SHA512_t T_string parameter's length
|
||||
*
|
||||
* @param t_len T_string parameter length
|
||||
*/
|
||||
static inline void sha_ll_t_len_set(uint8_t t_len)
|
||||
{
|
||||
REG_WRITE(SHA_T_LENGTH_REG, t_len);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user