Merge branch 'feature/enable_flash_encryption_for_esp32h21' into 'master'

feat: enable flash encryption support for esp32h21

Closes IDF-11499

See merge request espressif/esp-idf!36440
This commit is contained in:
Mahavir Jain
2025-03-17 13:54:22 +08:00
12 changed files with 128 additions and 42 deletions

View File

@@ -1032,8 +1032,9 @@ menu "Security features"
DIS_USB_SERIAL_JTAG, DIS_FORCE_DOWNLOAD, DIS_TWAI, JTAG_SEL_ENABLE,
DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT.
ESP32-H2: DIS_ICACHE, DIS_USB_JTAG, POWERGLITCH_EN, DIS_FORCE_DOWNLOAD, SPI_DOWNLOAD_MSPI_DIS,
DIS_TWAI, JTAG_SEL_ENABLE, DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT.
ESP32-H2 & ESP32H21: DIS_ICACHE, DIS_ICACHE, DIS_USB_JTAG, POWERGLITCH_EN, DIS_FORCE_DOWNLOAD,
SPI_DOWNLOAD_MSPI_DIS, DIS_TWAI, JTAG_SEL_ENABLE, DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT,
DIS_USB_SERIAL_JTAG
ESP32-S2: DIS_ICACHE, DIS_DCACHE, DIS_DOWNLOAD_ICACHE, DIS_DOWNLOAD_DCACHE,
DIS_FORCE_DOWNLOAD, DIS_USB, DIS_TWAI, DIS_BOOT_REMAP, SOFT_DIS_JTAG,

View File

@@ -55,7 +55,7 @@ esp_err_t esp_flash_encryption_enable_secure_features(void)
// esp32h2 has DIS_ICACHE. Write-protection bit = 2.
// List of eFuses with the same write protection bit:
// DIS_ICACHE, DIS_USB_JTAG, POWERGLITCH_EN, DIS_FORCE_DOWNLOAD, SPI_DOWNLOAD_MSPI_DIS,
// DIS_TWAI, JTAG_SEL_ENABLE, DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT
// DIS_TWAI, JTAG_SEL_ENABLE, DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT, DIS_USB_SERIAL_JTAG
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_DIS_ICACHE);
#endif

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -16,7 +16,37 @@ static __attribute__((unused)) const char *TAG = "flash_encrypt";
esp_err_t esp_flash_encryption_enable_secure_features(void)
{
//TODO: [ESP32H21] IDF-11499
abort();
#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
ESP_LOGI(TAG, "Disable UART bootloader encryption...");
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT);
#else
ESP_LOGW(TAG, "Not disabling UART bootloader encryption");
#endif
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
ESP_LOGI(TAG, "Disable JTAG...");
esp_efuse_write_field_bit(ESP_EFUSE_DIS_PAD_JTAG);
esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG);
#else
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
#endif
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DIRECT_BOOT);
#if defined(CONFIG_SECURE_BOOT_V2_ENABLED) && !defined(CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)
// This bit is set when enabling Secure Boot V2, but we can't enable it until this later point in the first boot
// otherwise the Flash Encryption key cannot be read protected
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_RD_DIS);
#endif
#ifndef CONFIG_SECURE_FLASH_SKIP_WRITE_PROTECTION_CACHE
// Set write-protection for DIS_ICACHE to prevent bricking chip in case it will be set accidentally.
// esp32h21 has DIS_ICACHE. Write-protection bit = 2.
// List of eFuses with the same write protection bit:
// DIS_ICACHE, DIS_USB_JTAG, POWERGLITCH_EN, DIS_FORCE_DOWNLOAD, SPI_DOWNLOAD_MSPI_DIS,
// DIS_TWAI, JTAG_SEL_ENABLE, DIS_PAD_JTAG, DIS_DOWNLOAD_MANUAL_ENCRYPT, DIS_USB_SERIAL_JTAG
esp_efuse_write_field_bit(ESP_EFUSE_WR_DIS_DIS_ICACHE);
#endif
return ESP_OK;
}

View File

@@ -20,6 +20,7 @@
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "hal/assert.h"
#include "hal/spi_flash_encrypt_types.h"
#ifdef __cplusplus
extern "C" {
@@ -155,11 +156,11 @@ static inline bool spi_flash_encrypt_ll_check(uint32_t address, uint32_t length)
* @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 spi_flash_encrypt_ll_enable_pseudo_rounds(uint8_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
static inline void spi_flash_encrypt_ll_enable_pseudo_rounds(esp_xts_aes_psuedo_rounds_state_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
{
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_MODE_PSEUDO, mode);
if (mode) {
if (mode != ESP_XTS_AES_PSEUDO_ROUNDS_DISABLE) {
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_BASE, base);
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_INC, increment);
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_RNG_CNT, key_rng_cnt);

View File

@@ -20,6 +20,7 @@
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "hal/assert.h"
#include "hal/spi_flash_encrypt_types.h"
#ifdef __cplusplus
extern "C" {
@@ -155,13 +156,13 @@ static inline bool spi_flash_encrypt_ll_check(uint32_t address, uint32_t length)
* @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 spi_flash_encrypt_ll_enable_pseudo_rounds(uint8_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
static inline void spi_flash_encrypt_ll_enable_pseudo_rounds(esp_xts_aes_psuedo_rounds_state_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
{
(void) key_rng_cnt;
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_MODE_PSEUDO, mode);
if (mode) {
if (mode != ESP_XTS_AES_PSEUDO_ROUNDS_DISABLE) {
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_BASE, base);
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_INC, increment);
} else {

View File

@@ -20,6 +20,7 @@
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "hal/assert.h"
#include "hal/spi_flash_encrypt_types.h"
#include "hal/efuse_hal.h"
#include "soc/chip_revision.h"
@@ -158,11 +159,11 @@ static inline bool spi_flash_encrypt_ll_check(uint32_t address, uint32_t length)
* @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 spi_flash_encrypt_ll_enable_pseudo_rounds(uint8_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
static inline void spi_flash_encrypt_ll_enable_pseudo_rounds(esp_xts_aes_psuedo_rounds_state_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
{
REG_SET_FIELD(XTS_AES_PSEUDO_ROUND_CONF_REG(0), XTS_AES_MODE_PSEUDO, mode);
if (mode) {
if (mode != ESP_XTS_AES_PSEUDO_ROUNDS_DISABLE) {
REG_SET_FIELD(XTS_AES_PSEUDO_ROUND_CONF_REG(0), XTS_AES_PSEUDO_BASE, base);
REG_SET_FIELD(XTS_AES_PSEUDO_ROUND_CONF_REG(0), XTS_AES_PSEUDO_INC, increment);
REG_SET_FIELD(XTS_AES_PSEUDO_ROUND_CONF_REG(0), XTS_AES_PSEUDO_RNG_CNT, key_rng_cnt);

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -20,8 +20,7 @@
#include "soc/soc.h"
#include "soc/soc_caps.h"
#include "hal/assert.h"
//TODO: [ESP32H21] IDF-11499, inherit from h2
#include "hal/spi_flash_encrypt_types.h"
#ifdef __cplusplus
extern "C" {
@@ -149,6 +148,37 @@ static inline bool spi_flash_encrypt_ll_check(uint32_t address, uint32_t length)
return ((address % length) == 0) ? true : false;
}
/**
* @brief Enable the pseudo-round function during XTS-AES operations
*
* @param mode set the mode for pseudo rounds, zero to disable, with increasing security upto three.
* @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 spi_flash_encrypt_ll_enable_pseudo_rounds(esp_xts_aes_psuedo_rounds_state_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
{
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_MODE_PSEUDO, mode);
if (mode != ESP_XTS_AES_PSEUDO_ROUNDS_DISABLE) {
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_BASE, base);
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_INC, increment);
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_RNG_CNT, key_rng_cnt);
} else {
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_BASE, 0);
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_INC, 0);
REG_SET_FIELD(SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0), SPI_MEM_PSEUDO_RNG_CNT, 0);
}
}
/**
* @brief Check if the pseudo round function is supported
*/
static inline bool spi_flash_encrypt_ll_is_pseudo_rounds_function_supported(void)
{
return true;
}
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -12,6 +12,7 @@
// The HAL layer for SPI Flash Encryption
#include "hal/spi_flash_encrypt_types.h"
#include "hal/spi_flash_encrypted_ll.h"
#include "soc/soc_caps.h"
@@ -19,29 +20,6 @@
extern "C" {
#endif
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
/**
* @brief Default pseudo rounds configs of the XTS-AES accelerator
*/
typedef enum {
ESP_XTS_AES_PSEUDO_ROUNDS_DISABLE = 0,
ESP_XTS_AES_PSEUDO_ROUNDS_LOW,
ESP_XTS_AES_PSEUDO_ROUNDS_MEDIUM,
ESP_XTS_AES_PSEUDO_ROUNDS_HIGH,
} esp_xts_aes_psuedo_rounds_state_t;
/* The total number of pseudo-rounds randomly inserted in an XTS-AES operation are controlled by
* configuring the PSEUDO_MODE, PSEUDO_BASE, PSEUDO_INC parameters.
* Users can also set the frequency of random key updates by configuring the PSEUDO_RNG_CNT.
* Here, we would be using some pre-decided values for these parameters corresponding to the security needed.
* For more information regarding these parameters please refer the TRM.
*/
#define XTS_AES_PSEUDO_ROUNDS_BASE 4
#define XTS_AES_PSEUDO_ROUNDS_INC 2
#define XTS_AES_PSEUDO_ROUNDS_RNG_CNT 7
#endif /* SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND */
/**
* @brief Enable the flash encryption
*/
@@ -90,7 +68,7 @@ bool spi_flash_encryption_hal_check(uint32_t address, uint32_t length);
* @param increment increment number of pseudo rounds, zero if disable
* @param key_rng_cnt update frequency of the pseudo-key, zero if disable
*/
void spi_flash_encryption_hal_enable_pseudo_rounds(uint8_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt);
void spi_flash_encryption_hal_enable_pseudo_rounds(esp_xts_aes_psuedo_rounds_state_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt);
#endif /* SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND */
#ifdef __cplusplus

View File

@@ -0,0 +1,39 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "soc/soc_caps.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
/**
* @brief Default pseudo rounds configs of the XTS-AES accelerator
*/
typedef enum {
ESP_XTS_AES_PSEUDO_ROUNDS_DISABLE = 0,
ESP_XTS_AES_PSEUDO_ROUNDS_LOW,
ESP_XTS_AES_PSEUDO_ROUNDS_MEDIUM,
ESP_XTS_AES_PSEUDO_ROUNDS_HIGH,
} esp_xts_aes_psuedo_rounds_state_t;
/* The total number of pseudo-rounds randomly inserted in an XTS-AES operation are controlled by
* configuring the PSEUDO_MODE, PSEUDO_BASE, PSEUDO_INC parameters.
* Users can also set the frequency of random key updates by configuring the PSEUDO_RNG_CNT.
* Here, we would be using some pre-decided values for these parameters corresponding to the security needed.
* For more information regarding these parameters please refer the TRM.
*/
#define XTS_AES_PSEUDO_ROUNDS_BASE 4
#define XTS_AES_PSEUDO_ROUNDS_INC 2
#define XTS_AES_PSEUDO_ROUNDS_RNG_CNT 7
#endif /* SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND */
#ifdef __cplusplus
}
#endif

View File

@@ -52,7 +52,7 @@ bool spi_flash_encryption_hal_check(uint32_t address, uint32_t length)
}
#ifdef SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
void spi_flash_encryption_hal_enable_pseudo_rounds(uint8_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
void spi_flash_encryption_hal_enable_pseudo_rounds(esp_xts_aes_psuedo_rounds_state_t mode, uint8_t base, uint8_t increment, uint8_t key_rng_cnt)
{
if (spi_flash_encrypt_ll_is_pseudo_rounds_function_supported()) {
spi_flash_encrypt_ll_enable_pseudo_rounds(mode, base, increment, key_rng_cnt);

View File

@@ -619,6 +619,10 @@ config SOC_FLASH_ENCRYPTION_XTS_AES_128
bool
default y
config SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND
bool
default y
config SOC_APM_CTRL_FILTER_SUPPORTED
bool
default y

View File

@@ -50,7 +50,7 @@
#define SOC_ECC_SUPPORTED 1
#define SOC_ECC_EXTENDED_MODES_SUPPORTED 1
// #define SOC_ECDSA_SUPPORTED 1 //TODO: [ESP32H21] IDF-11496
#define SOC_FLASH_ENC_SUPPORTED 1 //TODO: [ESP32H21] IDF-11499
#define SOC_FLASH_ENC_SUPPORTED 1
// #define SOC_SECURE_BOOT_SUPPORTED 1 //TODO: [ESP32H21] IDF-11500
// #define SOC_BOD_SUPPORTED 1 //TODO: [ESP32H21] IDF-11530
// #define SOC_APM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11494
@@ -477,6 +477,7 @@
#define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64)
#define SOC_FLASH_ENCRYPTION_XTS_AES 1
#define SOC_FLASH_ENCRYPTION_XTS_AES_128 1
#define SOC_FLASH_ENCRYPTION_XTS_AES_SUPPORT_PSEUDO_ROUND 1
/*-------------------------- APM CAPS ----------------------------------------*/
#define SOC_APM_CTRL_FILTER_SUPPORTED 1 /*!< Support for APM control filter */