mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
feat(esp_tee): Add support for flash memory isolation and protection (SPI1)
This commit is contained in:
parent
37525c605d
commit
c23714f775
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -752,6 +752,15 @@ esp_err_t IRAM_ATTR bootloader_flash_unlock_default(void)
|
||||
|
||||
esp_err_t __attribute__((weak, alias("bootloader_flash_unlock_default"))) bootloader_flash_unlock(void);
|
||||
|
||||
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1 && !NON_OS_BUILD
|
||||
extern uint32_t bootloader_flash_execute_command_common(
|
||||
uint8_t command,
|
||||
uint32_t addr_len, uint32_t address,
|
||||
uint8_t dummy_len,
|
||||
uint8_t mosi_len, uint32_t mosi_data,
|
||||
uint8_t miso_len);
|
||||
#else
|
||||
IRAM_ATTR uint32_t bootloader_flash_execute_command_common(
|
||||
uint8_t command,
|
||||
uint32_t addr_len, uint32_t address,
|
||||
@ -804,6 +813,7 @@ IRAM_ATTR uint32_t bootloader_flash_execute_command_common(
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t IRAM_ATTR bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
|
||||
{
|
||||
|
@ -94,6 +94,10 @@ if(CONFIG_SECURE_ENABLE_TEE AND NOT esp_tee_build)
|
||||
# Default secure service API families: flash_protection_spi0, flash_protection_spi1,
|
||||
# interrupt_handling, hal, crypto, efuse, secure_storage, ota, attestation
|
||||
set(exclude_srv)
|
||||
if(NOT CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1)
|
||||
list(APPEND exclude_srv "flash_protection_spi1")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_SECURE_TEE_ATTESTATION)
|
||||
list(APPEND exclude_srv "attestation")
|
||||
endif()
|
||||
|
@ -110,6 +110,35 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
|
||||
endmenu
|
||||
|
||||
config SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
bool "Memprot: Isolate TEE flash regions over SPI1"
|
||||
depends on SECURE_ENABLE_TEE
|
||||
default n
|
||||
help
|
||||
This configuration restricts access to TEE-reserved regions in external flash
|
||||
by making them inaccessible to the REE via the SPI1 interface (physical addresses).
|
||||
|
||||
With this enabled, all SPI flash read, write, or erase operations over SPI1 will
|
||||
be routed through service calls to the TEE, introducing additional performance
|
||||
overhead.
|
||||
|
||||
When Flash Encryption (SECURE_FLASH_ENC_ENABLED) is enabled, the REE can still
|
||||
access TEE-related flash partitions over SPI1, but read operations will return
|
||||
encrypted data contents. This prevents attackers from inferring the TEE contents
|
||||
with direct reads.
|
||||
|
||||
Additionally, with Secure Boot enabled (SECURE_BOOT_V2_ENABLED), any unauthorized
|
||||
modifications to the TEE firmware will be detected during boot, causing signature
|
||||
verification to fail. Thus, these options provide a level of protection suitable for
|
||||
most applications. However, while the TEE firmware integrity is protected, other TEE
|
||||
partitions (Secure Storage, TEE OTA data) can be manipulated through direct writes.
|
||||
|
||||
Enable this option only when complete isolation of all TEE flash regions is required,
|
||||
even with the associated performance tradeoffs.
|
||||
|
||||
Note: All accesses to the TEE partitions over SPI0 (i.e. the MMU) are blocked
|
||||
unconditionally.
|
||||
|
||||
config SECURE_TEE_DEBUG_MODE
|
||||
bool "Enable Debug Mode"
|
||||
default y
|
||||
|
@ -24,6 +24,77 @@ secure_services:
|
||||
type: IDF
|
||||
function: mmu_hal_paddr_to_vaddr
|
||||
args: 5
|
||||
# ID: 5-21 (17) - External memory (Flash) protection [SPI1]
|
||||
- family: flash_protection_spi1
|
||||
entries:
|
||||
- id: 5
|
||||
type: IDF
|
||||
function: spi_flash_hal_check_status
|
||||
args: 1
|
||||
- id: 6
|
||||
type: IDF
|
||||
function: spi_flash_hal_common_command
|
||||
args: 2
|
||||
- id: 7
|
||||
type: IDF
|
||||
function: spi_flash_hal_device_config
|
||||
args: 1
|
||||
- id: 8
|
||||
type: IDF
|
||||
function: spi_flash_hal_erase_block
|
||||
args: 2
|
||||
- id: 9
|
||||
type: IDF
|
||||
function: spi_flash_hal_erase_chip
|
||||
args: 1
|
||||
- id: 10
|
||||
type: IDF
|
||||
function: spi_flash_hal_erase_sector
|
||||
args: 2
|
||||
- id: 11
|
||||
type: IDF
|
||||
function: spi_flash_hal_program_page
|
||||
args: 4
|
||||
- id: 12
|
||||
type: IDF
|
||||
function: spi_flash_hal_read
|
||||
args: 4
|
||||
- id: 13
|
||||
type: IDF
|
||||
function: spi_flash_hal_resume
|
||||
args: 1
|
||||
- id: 14
|
||||
type: IDF
|
||||
function: spi_flash_hal_set_write_protect
|
||||
args: 2
|
||||
- id: 15
|
||||
type: IDF
|
||||
function: spi_flash_hal_setup_read_suspend
|
||||
args: 2
|
||||
- id: 16
|
||||
type: IDF
|
||||
function: spi_flash_hal_supports_direct_read
|
||||
args: 2
|
||||
- id: 17
|
||||
type: IDF
|
||||
function: spi_flash_hal_supports_direct_write
|
||||
args: 2
|
||||
- id: 18
|
||||
type: IDF
|
||||
function: spi_flash_hal_suspend
|
||||
args: 1
|
||||
- id: 19
|
||||
type: IDF
|
||||
function: bootloader_flash_execute_command_common
|
||||
args: 7
|
||||
- id: 20
|
||||
type: IDF
|
||||
function: memspi_host_flush_cache
|
||||
args: 3
|
||||
- id: 21
|
||||
type: IDF
|
||||
function: spi_flash_chip_generic_config_host_io_mode
|
||||
args: 2
|
||||
# ID: 30-53 (24) - Interrupt Handling
|
||||
- family: interrupt_handling
|
||||
entries:
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "hal/sha_hal.h"
|
||||
#include "hal/mmu_types.h"
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "hal/spi_flash_types.h"
|
||||
#include "esp_flash.h"
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
@ -247,3 +249,101 @@ bool IRAM_ATTR __wrap_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mm
|
||||
{
|
||||
return esp_tee_service_call(6, SS_MMU_HAL_PADDR_TO_VADDR, mmu_id, paddr, target, type, out_vaddr);
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
|
||||
|
||||
uint32_t IRAM_ATTR __wrap_spi_flash_hal_check_status(spi_flash_host_inst_t *host)
|
||||
{
|
||||
return esp_tee_service_call(2, SS_SPI_FLASH_HAL_CHECK_STATUS, host);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
|
||||
{
|
||||
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_COMMON_COMMAND, host, trans);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_device_config(spi_flash_host_inst_t *host)
|
||||
{
|
||||
return esp_tee_service_call(2, SS_SPI_FLASH_HAL_DEVICE_CONFIG, host);
|
||||
}
|
||||
|
||||
void IRAM_ATTR __wrap_spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
|
||||
{
|
||||
esp_tee_service_call(3, SS_SPI_FLASH_HAL_ERASE_BLOCK, host, start_address);
|
||||
}
|
||||
|
||||
void IRAM_ATTR __wrap_spi_flash_hal_erase_chip(spi_flash_host_inst_t *host)
|
||||
{
|
||||
esp_tee_service_call(2, SS_SPI_FLASH_HAL_ERASE_CHIP, host);
|
||||
}
|
||||
|
||||
void IRAM_ATTR __wrap_spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
|
||||
{
|
||||
esp_tee_service_call(3, SS_SPI_FLASH_HAL_ERASE_SECTOR, host, start_address);
|
||||
}
|
||||
|
||||
void IRAM_ATTR __wrap_spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
|
||||
{
|
||||
esp_tee_service_call(5, SS_SPI_FLASH_HAL_PROGRAM_PAGE, host, buffer, address, length);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
|
||||
{
|
||||
return esp_tee_service_call(5, SS_SPI_FLASH_HAL_READ, host, buffer, address, read_len);
|
||||
}
|
||||
|
||||
void IRAM_ATTR __wrap_spi_flash_hal_resume(spi_flash_host_inst_t *host)
|
||||
{
|
||||
esp_tee_service_call(2, SS_SPI_FLASH_HAL_RESUME, host);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
|
||||
{
|
||||
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_SET_WRITE_PROTECT, host, wp);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)
|
||||
{
|
||||
return esp_tee_service_call(6, SS_SPI_FLASH_HAL_SETUP_READ_SUSPEND, host, sus_conf);
|
||||
}
|
||||
|
||||
bool IRAM_ATTR __wrap_spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
|
||||
{
|
||||
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_SUPPORTS_DIRECT_READ, host, p);
|
||||
}
|
||||
|
||||
bool IRAM_ATTR __wrap_spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
|
||||
{
|
||||
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_SUPPORTS_DIRECT_WRITE, host, p);
|
||||
}
|
||||
|
||||
void IRAM_ATTR __wrap_spi_flash_hal_suspend(spi_flash_host_inst_t *host)
|
||||
{
|
||||
esp_tee_service_call(2, SS_SPI_FLASH_HAL_SUSPEND, host);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- SPI Flash Extras ------------------------------------------------- */
|
||||
|
||||
uint32_t IRAM_ATTR __wrap_bootloader_flash_execute_command_common(
|
||||
uint8_t command,
|
||||
uint32_t addr_len, uint32_t address,
|
||||
uint8_t dummy_len,
|
||||
uint8_t mosi_len, uint32_t mosi_data,
|
||||
uint8_t miso_len)
|
||||
{
|
||||
return esp_tee_service_call(8, SS_BOOTLOADER_FLASH_EXECUTE_COMMAND_COMMON,
|
||||
command, addr_len, address, dummy_len, mosi_len,
|
||||
mosi_data, miso_len);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __wrap_memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
|
||||
{
|
||||
return esp_tee_service_call(4, SS_MEMSPI_HOST_FLUSH_CACHE, host, addr, size);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR __wrap_spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t flags)
|
||||
{
|
||||
return esp_tee_service_call(3, SS_SPI_FLASH_CHIP_GENERIC_CONFIG_HOST_IO_MODE, chip, flags);
|
||||
}
|
||||
#endif
|
||||
|
@ -54,6 +54,10 @@ list(APPEND srcs "${hal_dir}/apm_hal.c"
|
||||
"${hal_dir}/brownout_hal.c"
|
||||
"${hal_dir}/wdt_hal_iram.c")
|
||||
|
||||
if(CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1)
|
||||
list(APPEND srcs "${hal_dir}/spi_flash_hal.c")
|
||||
endif()
|
||||
|
||||
# TLSF implementation for heap
|
||||
list(APPEND include "${heap_dir}/include"
|
||||
"${heap_dir}/tlsf"
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "esp_flash.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_rom_efuse.h"
|
||||
#include "esp_fault.h"
|
||||
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/mmu_types.h"
|
||||
@ -19,6 +18,11 @@
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "hal/sha_hal.h"
|
||||
|
||||
#include "hal/spi_flash_hal.h"
|
||||
#include "hal/spi_flash_types.h"
|
||||
#include "spi_flash_chip_generic.h"
|
||||
#include "memspi_host_driver.h"
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "aes/esp_aes.h"
|
||||
#include "sha/sha_core.h"
|
||||
@ -34,6 +38,8 @@
|
||||
#include "esp_tee_ota_ops.h"
|
||||
#include "esp_attestation.h"
|
||||
|
||||
static __attribute__((unused)) const char *TAG = "esp_tee_sec_srv";
|
||||
|
||||
void _ss_invalid_secure_service(void)
|
||||
{
|
||||
assert(0);
|
||||
@ -449,7 +455,7 @@ void _ss_mmu_hal_map_region(uint32_t mmu_id, mmu_target_t mem_type, uint32_t vad
|
||||
if (vaddr_chk || paddr_chk) {
|
||||
return;
|
||||
}
|
||||
ESP_FAULT_ASSERT(!vaddr_chk && !vaddr_chk);
|
||||
ESP_FAULT_ASSERT(!vaddr_chk && !paddr_chk);
|
||||
|
||||
mmu_hal_map_region(mmu_id, mem_type, vaddr, paddr, len, out_len);
|
||||
}
|
||||
@ -484,3 +490,151 @@ bool _ss_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mmu_target_t ta
|
||||
ESP_FAULT_ASSERT(!paddr_chk);
|
||||
return mmu_hal_paddr_to_vaddr(mmu_id, paddr, target, type, out_vaddr);
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
|
||||
|
||||
uint32_t _ss_spi_flash_hal_check_status(spi_flash_host_inst_t *host)
|
||||
{
|
||||
return spi_flash_hal_check_status(host);
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
|
||||
{
|
||||
return spi_flash_hal_common_command(host, trans);
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_device_config(spi_flash_host_inst_t *host)
|
||||
{
|
||||
return spi_flash_hal_device_config(host);
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
|
||||
{
|
||||
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(start_address);
|
||||
if (paddr_chk) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
|
||||
return;
|
||||
}
|
||||
ESP_FAULT_ASSERT(!paddr_chk);
|
||||
spi_flash_hal_erase_block(host, start_address);
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_erase_chip(spi_flash_host_inst_t *host)
|
||||
{
|
||||
spi_flash_hal_erase_chip(host);
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
|
||||
{
|
||||
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(start_address);
|
||||
if (paddr_chk) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
|
||||
return;
|
||||
}
|
||||
ESP_FAULT_ASSERT(!paddr_chk);
|
||||
spi_flash_hal_erase_sector(host, start_address);
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
|
||||
{
|
||||
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
|
||||
if (paddr_chk) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
|
||||
return;
|
||||
}
|
||||
|
||||
bool buf_addr_chk = ((esp_tee_ptr_in_ree((void *)buffer) && esp_tee_ptr_in_ree((void *)(buffer + length))));
|
||||
if (!buf_addr_chk) {
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_FAULT_ASSERT(!paddr_chk && buf_addr_chk);
|
||||
spi_flash_hal_program_page(host, buffer, address, length);
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
|
||||
{
|
||||
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
|
||||
if (paddr_chk) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
bool buf_addr_chk = ((esp_tee_ptr_in_ree((void *)buffer) && esp_tee_ptr_in_ree((void *)(buffer + read_len))));
|
||||
if (!buf_addr_chk) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_FAULT_ASSERT(!paddr_chk && buf_addr_chk);
|
||||
return spi_flash_hal_read(host, buffer, address, read_len);
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_resume(spi_flash_host_inst_t *host)
|
||||
{
|
||||
spi_flash_hal_resume(host);
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
|
||||
{
|
||||
return spi_flash_hal_set_write_protect(host, wp);
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)
|
||||
{
|
||||
return spi_flash_hal_setup_read_suspend(host, sus_conf);
|
||||
}
|
||||
|
||||
bool _ss_spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
|
||||
{
|
||||
return spi_flash_hal_supports_direct_read(host, p);
|
||||
}
|
||||
|
||||
bool _ss_spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
|
||||
{
|
||||
return spi_flash_hal_supports_direct_write(host, p);
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_suspend(spi_flash_host_inst_t *host)
|
||||
{
|
||||
spi_flash_hal_suspend(host);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- SPI Flash Extras ------------------------------------------------- */
|
||||
|
||||
extern uint32_t bootloader_flash_execute_command_common(uint8_t command, uint32_t addr_len, uint32_t address,
|
||||
uint8_t dummy_len, uint8_t mosi_len, uint32_t mosi_data,
|
||||
uint8_t miso_len);
|
||||
|
||||
uint32_t _ss_bootloader_flash_execute_command_common(
|
||||
uint8_t command,
|
||||
uint32_t addr_len, uint32_t address,
|
||||
uint8_t dummy_len,
|
||||
uint8_t mosi_len, uint32_t mosi_data,
|
||||
uint8_t miso_len)
|
||||
{
|
||||
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(address);
|
||||
if (paddr_chk) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_FAULT_ASSERT(!paddr_chk);
|
||||
return bootloader_flash_execute_command_common(command, addr_len, address, dummy_len,
|
||||
mosi_len, mosi_data, miso_len);
|
||||
}
|
||||
|
||||
esp_err_t _ss_memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
|
||||
{
|
||||
bool paddr_chk = esp_tee_flash_check_paddr_in_tee_region(addr);
|
||||
if (paddr_chk) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_FAULT_ASSERT(!paddr_chk);
|
||||
return memspi_host_flush_cache(host, addr, size);
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t flags)
|
||||
{
|
||||
return spi_flash_chip_generic_config_host_io_mode(chip, flags);
|
||||
}
|
||||
#endif
|
||||
|
@ -104,6 +104,8 @@ SECTIONS
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*libtee_flash_mgr.a:*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libbootloader_support.a:bootloader_flash.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libmain.a:esp_secure_services.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libmain.a:esp_secure_dispatcher.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libmain.a:panic_helper_riscv.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
*libmain.a:esp_tee_apm_intr.c.*(.rodata .srodata .rodata.* .srodata.*)
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
|
@ -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
|
||||
*/
|
||||
@ -35,6 +35,14 @@ static const char *TAG = "esp_tee_apm_prot_cfg";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* NOTE: Flash protection over the SPI1 controller */
|
||||
#define HP_APM_SPI1_REG_START DR_REG_SPI1_BASE
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
#define HP_APM_SPI1_REG_END DR_REG_I2C_EXT_BASE
|
||||
#else
|
||||
#define HP_APM_SPI1_REG_END HP_APM_SPI1_REG_START
|
||||
#endif
|
||||
|
||||
/*----------------------- HP APM range and filter configuration -----------------------*/
|
||||
|
||||
/* HP_APM: REE0 mode accessible regions */
|
||||
@ -56,52 +64,61 @@ apm_ctrl_region_config_data_t hp_apm_pms_data[] = {
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 2: Peripherals [MMU - Interrupt Matrix] (RW) */
|
||||
/* Protected: Interrupt Matrix */
|
||||
/* Region 2: Peripherals [MMU - SPI1] (RW) */
|
||||
/* Protected: SPI1 */
|
||||
{
|
||||
.regn_num = 2,
|
||||
.regn_start_addr = SPI_MEM_MMU_POWER_CTRL_REG(0),
|
||||
.regn_end_addr = (HP_APM_SPI1_REG_START - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 3: Peripherals [SPI1 - Interrupt Matrix] (RW) */
|
||||
/* Protected: Interrupt Matrix */
|
||||
{
|
||||
.regn_num = 3,
|
||||
.regn_start_addr = HP_APM_SPI1_REG_END,
|
||||
.regn_end_addr = (DR_REG_INTMTX_BASE - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 3: Peripherals [H/W Lock - AES] (RW) */
|
||||
/* Region 4: Peripherals [H/W Lock - AES] (RW) */
|
||||
/* Protected: AES, SHA */
|
||||
{
|
||||
.regn_num = 3,
|
||||
.regn_num = 4,
|
||||
.regn_start_addr = DR_REG_ATOMIC_BASE,
|
||||
.regn_end_addr = (DR_REG_AES_BASE - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 4: Peripherals [RSA - TEE Controller & APM] (RW) */
|
||||
/* Region 5: Peripherals [RSA - TEE Controller & APM] (RW) */
|
||||
/* Protected: APM, TEE Controller */
|
||||
{
|
||||
.regn_num = 4,
|
||||
.regn_num = 5,
|
||||
.regn_start_addr = DR_REG_RSA_BASE,
|
||||
.regn_end_addr = (DR_REG_TEE_BASE - 0x4),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 5: Peripherals [Miscellaneous - PMU] (RW) */
|
||||
/* Region 6: Peripherals [Miscellaneous - PMU] (RW) */
|
||||
{
|
||||
.regn_num = 5,
|
||||
.regn_num = 6,
|
||||
.regn_start_addr = DR_REG_MISC_BASE,
|
||||
.regn_end_addr = (DR_REG_PMU_BASE - 0x04),
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 6: Peripherals [DEBUG - PWDET] (RW) */
|
||||
/* Region 7: Peripherals [DEBUG - PWDET] (RW) */
|
||||
{
|
||||
.regn_num = 6,
|
||||
.regn_num = 7,
|
||||
.regn_start_addr = DR_REG_OPT_DEBUG_BASE,
|
||||
.regn_end_addr = 0x600D0000,
|
||||
.regn_pms = 0x6,
|
||||
.filter_enable = 1,
|
||||
},
|
||||
/* Region 7: REE SRAM region (RW) */
|
||||
/* Region 8: REE SRAM region (RW) */
|
||||
{
|
||||
.regn_num = 7,
|
||||
.regn_num = 8,
|
||||
.regn_start_addr = SOC_NS_IRAM_START,
|
||||
.regn_end_addr = SOC_IRAM_HIGH,
|
||||
.regn_pms = 0x6,
|
||||
@ -147,9 +164,9 @@ apm_ctrl_secure_mode_config_t hp_apm_sec_mode_data = {
|
||||
|
||||
/* HP_APM: TEE mode accessible regions */
|
||||
apm_ctrl_region_config_data_t hp_apm_pms_data_tee[] = {
|
||||
/* Region 8: Entire memory region (RWX)*/
|
||||
/* Region 9: Entire memory region (RWX)*/
|
||||
{
|
||||
.regn_num = 8,
|
||||
.regn_num = 9,
|
||||
.regn_start_addr = 0x0,
|
||||
.regn_end_addr = ~0x0,
|
||||
.regn_pms = 0x7,
|
||||
|
@ -425,6 +425,7 @@ esp_err_t spi_flash_chip_generic_wait_idle(esp_flash_t *chip, uint32_t timeout_u
|
||||
return (timeout_us > 0) ? ESP_OK : ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
esp_err_t spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t flags)
|
||||
{
|
||||
uint32_t dummy_cyclelen_base;
|
||||
@ -483,6 +484,7 @@ esp_err_t spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t
|
||||
|
||||
return chip->host->driver->configure_host_io_mode(chip->host, read_command, addr_bitlen, dummy_cyclelen_base, read_mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t spi_flash_chip_generic_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t* out_io_mode)
|
||||
{
|
||||
|
@ -100,10 +100,6 @@ External Memory (Flash)
|
||||
|
||||
Designated partitions in the external flash are reserved for the TEE, serving various purposes, including TEE code execution via XIP, secure storage, and OTA data. The PMS safeguards these partitions from unauthorized access, with the APM module protecting the MMU and SPI1 controller registers, and the PMP securing the cache.
|
||||
|
||||
.. note::
|
||||
|
||||
Flash memory protection is under development and will be introduced in the next revision of ESP-TEE.
|
||||
|
||||
.. figure:: ../../../_static/esp_tee/{IDF_TARGET_PATH_NAME}/esp_tee_flash_layout.png
|
||||
:align: center
|
||||
:scale: 80%
|
||||
@ -112,6 +108,53 @@ Designated partitions in the external flash are reserved for the TEE, serving va
|
||||
|
||||
ESP-TEE: Flash Memory Map for {IDF_TARGET_NAME}
|
||||
|
||||
.. _tee-flash-prot-scope:
|
||||
|
||||
**Flash Protection - Virtual and Physical Access**
|
||||
|
||||
The key interfaces for flash memory protection are the cache connected to SPI0, which provides virtual access to flash memory, and the SPI1 controller, which provides physical access. By default, the cache and the MMU registers are secured by the PMS, preventing virtual access to the TEE-related flash partitions from the REE.
|
||||
|
||||
When :doc:`Flash Encryption <../flash-encryption>` is enabled, the REE can still access TEE flash regions via SPI1, but read operations will return encrypted data. Since neither the REE nor TEE has direct access to the flash encryption key, this prevents attackers from inferring TEE contents through direct reads.
|
||||
|
||||
Additionally with :ref:`Secure Boot <secure_boot-guide>` enabled, any unauthorized modifications to the TEE firmware will be detected during boot, causing signature verification to fail. Thus, the combination of Flash Encryption and Secure Boot provides a robust level of protection suitable for most applications.
|
||||
However, do note that while the TEE firmware integrity is protected, other TEE partitions (e.g., :doc:`Secure Storage <tee-sec-storage>`, :ref:`TEE OTA data <tee-ota-data-partition>`) can be modified through direct writes.
|
||||
|
||||
For stronger isolation, you can enable :ref:`CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1`, which completely blocks access to all TEE flash regions via SPI1 for the REE. With this setting, all SPI flash read, write, and erase operations are routed through service calls to the TEE. While this option provides enhanced security, it introduces some performance overhead.
|
||||
|
||||
The table below shows the rough time taken to read and write to a 1MB partition in 256B chunks with :doc:`../../api-reference/storage/partition`, highlighting the impact of ESP-TEE and the :ref:`CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1` configuration.
|
||||
|
||||
.. list-table:: Flash Protection: Performance Impact
|
||||
:header-rows: 1
|
||||
|
||||
* - Case
|
||||
- Read (ms)
|
||||
- Read Δ (ms)
|
||||
- Read Δ (%)
|
||||
- Write (ms)
|
||||
- Write Δ (ms)
|
||||
- Write Δ (%)
|
||||
* - ESP-TEE disabled
|
||||
- 262.01
|
||||
- -
|
||||
- -
|
||||
- 3394.23
|
||||
- -
|
||||
- -
|
||||
* - ESP-TEE enabled
|
||||
- 279.86
|
||||
- +17.85
|
||||
- +6.81%
|
||||
- 3415.64
|
||||
- +21.41
|
||||
- +0.63%
|
||||
* - ESP-TEE + SPI1 protected
|
||||
- 359.73
|
||||
- +97.72
|
||||
- +37.33%
|
||||
- 3778.65
|
||||
- +384.42
|
||||
- +11.32%
|
||||
|
||||
Peripherals
|
||||
~~~~~~~~~~~
|
||||
|
||||
|
@ -67,10 +67,6 @@ The TEE Secure Storage feature supports two modes (:ref:`CONFIG_SECURE_TEE_SEC_S
|
||||
|
||||
All the assets pertaining to the TEE secure storage are protected by the APM peripheral and thus, are inaccessible to the REE application. Any attempt to directly access them would result in a system fault.
|
||||
|
||||
.. note::
|
||||
|
||||
Flash memory protection is currently not implemented - it will be added soon in the next revision of the ESP-TEE framework.
|
||||
|
||||
.. note::
|
||||
|
||||
- Currently, the TEE secure storage supports the storage of two types of cryptographic keys:
|
||||
|
@ -71,10 +71,6 @@ Memory Allocation
|
||||
|
||||
ESP-TEE divides the memory into separate regions for the TEE and REE, allocating part of the internal SRAM and external flash memory to the TEE. This separation safeguards sensitive data and operations within the TEE, preventing unauthorized access from the REE.
|
||||
|
||||
.. note::
|
||||
|
||||
Flash memory protection is under development and will be introduced in the next revision of ESP-TEE.
|
||||
|
||||
.. _tee-internal-memory:
|
||||
|
||||
Internal Memory (SRAM)
|
||||
@ -105,10 +101,14 @@ Example partition table is given below: ::
|
||||
nvs, data, nvs, 0x150000, 24K,
|
||||
phy_init, data, phy, 0x156000, 4K,
|
||||
|
||||
.. note::
|
||||
.. important::
|
||||
|
||||
The partition following the last TEE-related partition must be aligned to the configured MMU page size. This alignment is required to prevent secure boot verification failures when validating the user application (REE) image.
|
||||
|
||||
.. note::
|
||||
|
||||
For more details on the default policy and scope of flash memory protection with ESP-TEE, refer to the :ref:`Flash Protection - Virtual and Physical Access <tee-flash-prot-scope>` section from the advanced guide.
|
||||
|
||||
.. _tee-secure-services:
|
||||
|
||||
Secure Services
|
||||
|
Loading…
x
Reference in New Issue
Block a user