Skip to content

Commit c23714f

Browse files
committed
feat(esp_tee): Add support for flash memory isolation and protection (SPI1)
1 parent 37525c6 commit c23714f

File tree

13 files changed

+463
-31
lines changed

13 files changed

+463
-31
lines changed

components/bootloader_support/bootloader_flash/src/bootloader_flash.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -752,6 +752,15 @@ esp_err_t IRAM_ATTR bootloader_flash_unlock_default(void)
752752

753753
esp_err_t __attribute__((weak, alias("bootloader_flash_unlock_default"))) bootloader_flash_unlock(void);
754754

755+
756+
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1 && !NON_OS_BUILD
757+
extern uint32_t bootloader_flash_execute_command_common(
758+
uint8_t command,
759+
uint32_t addr_len, uint32_t address,
760+
uint8_t dummy_len,
761+
uint8_t mosi_len, uint32_t mosi_data,
762+
uint8_t miso_len);
763+
#else
755764
IRAM_ATTR uint32_t bootloader_flash_execute_command_common(
756765
uint8_t command,
757766
uint32_t addr_len, uint32_t address,
@@ -804,6 +813,7 @@ IRAM_ATTR uint32_t bootloader_flash_execute_command_common(
804813
}
805814
return ret;
806815
}
816+
#endif
807817

808818
uint32_t IRAM_ATTR bootloader_execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
809819
{

components/esp_tee/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ if(CONFIG_SECURE_ENABLE_TEE AND NOT esp_tee_build)
9494
# Default secure service API families: flash_protection_spi0, flash_protection_spi1,
9595
# interrupt_handling, hal, crypto, efuse, secure_storage, ota, attestation
9696
set(exclude_srv)
97+
if(NOT CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1)
98+
list(APPEND exclude_srv "flash_protection_spi1")
99+
endif()
100+
97101
if(NOT CONFIG_SECURE_TEE_ATTESTATION)
98102
list(APPEND exclude_srv "attestation")
99103
endif()

components/esp_tee/Kconfig.projbuild

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,35 @@ menu "ESP-TEE (Trusted Execution Environment)"
110110

111111
endmenu
112112

113+
config SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
114+
bool "Memprot: Isolate TEE flash regions over SPI1"
115+
depends on SECURE_ENABLE_TEE
116+
default n
117+
help
118+
This configuration restricts access to TEE-reserved regions in external flash
119+
by making them inaccessible to the REE via the SPI1 interface (physical addresses).
120+
121+
With this enabled, all SPI flash read, write, or erase operations over SPI1 will
122+
be routed through service calls to the TEE, introducing additional performance
123+
overhead.
124+
125+
When Flash Encryption (SECURE_FLASH_ENC_ENABLED) is enabled, the REE can still
126+
access TEE-related flash partitions over SPI1, but read operations will return
127+
encrypted data contents. This prevents attackers from inferring the TEE contents
128+
with direct reads.
129+
130+
Additionally, with Secure Boot enabled (SECURE_BOOT_V2_ENABLED), any unauthorized
131+
modifications to the TEE firmware will be detected during boot, causing signature
132+
verification to fail. Thus, these options provide a level of protection suitable for
133+
most applications. However, while the TEE firmware integrity is protected, other TEE
134+
partitions (Secure Storage, TEE OTA data) can be manipulated through direct writes.
135+
136+
Enable this option only when complete isolation of all TEE flash regions is required,
137+
even with the associated performance tradeoffs.
138+
139+
Note: All accesses to the TEE partitions over SPI0 (i.e. the MMU) are blocked
140+
unconditionally.
141+
113142
config SECURE_TEE_DEBUG_MODE
114143
bool "Enable Debug Mode"
115144
default y

components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,77 @@ secure_services:
2424
type: IDF
2525
function: mmu_hal_paddr_to_vaddr
2626
args: 5
27+
# ID: 5-21 (17) - External memory (Flash) protection [SPI1]
28+
- family: flash_protection_spi1
29+
entries:
30+
- id: 5
31+
type: IDF
32+
function: spi_flash_hal_check_status
33+
args: 1
34+
- id: 6
35+
type: IDF
36+
function: spi_flash_hal_common_command
37+
args: 2
38+
- id: 7
39+
type: IDF
40+
function: spi_flash_hal_device_config
41+
args: 1
42+
- id: 8
43+
type: IDF
44+
function: spi_flash_hal_erase_block
45+
args: 2
46+
- id: 9
47+
type: IDF
48+
function: spi_flash_hal_erase_chip
49+
args: 1
50+
- id: 10
51+
type: IDF
52+
function: spi_flash_hal_erase_sector
53+
args: 2
54+
- id: 11
55+
type: IDF
56+
function: spi_flash_hal_program_page
57+
args: 4
58+
- id: 12
59+
type: IDF
60+
function: spi_flash_hal_read
61+
args: 4
62+
- id: 13
63+
type: IDF
64+
function: spi_flash_hal_resume
65+
args: 1
66+
- id: 14
67+
type: IDF
68+
function: spi_flash_hal_set_write_protect
69+
args: 2
70+
- id: 15
71+
type: IDF
72+
function: spi_flash_hal_setup_read_suspend
73+
args: 2
74+
- id: 16
75+
type: IDF
76+
function: spi_flash_hal_supports_direct_read
77+
args: 2
78+
- id: 17
79+
type: IDF
80+
function: spi_flash_hal_supports_direct_write
81+
args: 2
82+
- id: 18
83+
type: IDF
84+
function: spi_flash_hal_suspend
85+
args: 1
86+
- id: 19
87+
type: IDF
88+
function: bootloader_flash_execute_command_common
89+
args: 7
90+
- id: 20
91+
type: IDF
92+
function: memspi_host_flush_cache
93+
args: 3
94+
- id: 21
95+
type: IDF
96+
function: spi_flash_chip_generic_config_host_io_mode
97+
args: 2
2798
# ID: 30-53 (24) - Interrupt Handling
2899
- family: interrupt_handling
29100
entries:

components/esp_tee/src/esp_secure_service_wrapper.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "hal/sha_hal.h"
1414
#include "hal/mmu_types.h"
1515
#include "hal/wdt_hal.h"
16+
#include "hal/spi_flash_types.h"
17+
#include "esp_flash.h"
1618

1719
#include "soc/soc_caps.h"
1820

@@ -247,3 +249,101 @@ bool IRAM_ATTR __wrap_mmu_hal_paddr_to_vaddr(uint32_t mmu_id, uint32_t paddr, mm
247249
{
248250
return esp_tee_service_call(6, SS_MMU_HAL_PADDR_TO_VADDR, mmu_id, paddr, target, type, out_vaddr);
249251
}
252+
253+
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
254+
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
255+
256+
uint32_t IRAM_ATTR __wrap_spi_flash_hal_check_status(spi_flash_host_inst_t *host)
257+
{
258+
return esp_tee_service_call(2, SS_SPI_FLASH_HAL_CHECK_STATUS, host);
259+
}
260+
261+
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
262+
{
263+
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_COMMON_COMMAND, host, trans);
264+
}
265+
266+
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_device_config(spi_flash_host_inst_t *host)
267+
{
268+
return esp_tee_service_call(2, SS_SPI_FLASH_HAL_DEVICE_CONFIG, host);
269+
}
270+
271+
void IRAM_ATTR __wrap_spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
272+
{
273+
esp_tee_service_call(3, SS_SPI_FLASH_HAL_ERASE_BLOCK, host, start_address);
274+
}
275+
276+
void IRAM_ATTR __wrap_spi_flash_hal_erase_chip(spi_flash_host_inst_t *host)
277+
{
278+
esp_tee_service_call(2, SS_SPI_FLASH_HAL_ERASE_CHIP, host);
279+
}
280+
281+
void IRAM_ATTR __wrap_spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
282+
{
283+
esp_tee_service_call(3, SS_SPI_FLASH_HAL_ERASE_SECTOR, host, start_address);
284+
}
285+
286+
void IRAM_ATTR __wrap_spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
287+
{
288+
esp_tee_service_call(5, SS_SPI_FLASH_HAL_PROGRAM_PAGE, host, buffer, address, length);
289+
}
290+
291+
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)
292+
{
293+
return esp_tee_service_call(5, SS_SPI_FLASH_HAL_READ, host, buffer, address, read_len);
294+
}
295+
296+
void IRAM_ATTR __wrap_spi_flash_hal_resume(spi_flash_host_inst_t *host)
297+
{
298+
esp_tee_service_call(2, SS_SPI_FLASH_HAL_RESUME, host);
299+
}
300+
301+
esp_err_t IRAM_ATTR __wrap_spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
302+
{
303+
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_SET_WRITE_PROTECT, host, wp);
304+
}
305+
306+
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)
307+
{
308+
return esp_tee_service_call(6, SS_SPI_FLASH_HAL_SETUP_READ_SUSPEND, host, sus_conf);
309+
}
310+
311+
bool IRAM_ATTR __wrap_spi_flash_hal_supports_direct_read(spi_flash_host_inst_t *host, const void *p)
312+
{
313+
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_SUPPORTS_DIRECT_READ, host, p);
314+
}
315+
316+
bool IRAM_ATTR __wrap_spi_flash_hal_supports_direct_write(spi_flash_host_inst_t *host, const void *p)
317+
{
318+
return esp_tee_service_call(3, SS_SPI_FLASH_HAL_SUPPORTS_DIRECT_WRITE, host, p);
319+
}
320+
321+
void IRAM_ATTR __wrap_spi_flash_hal_suspend(spi_flash_host_inst_t *host)
322+
{
323+
esp_tee_service_call(2, SS_SPI_FLASH_HAL_SUSPEND, host);
324+
}
325+
326+
/* ---------------------------------------------- SPI Flash Extras ------------------------------------------------- */
327+
328+
uint32_t IRAM_ATTR __wrap_bootloader_flash_execute_command_common(
329+
uint8_t command,
330+
uint32_t addr_len, uint32_t address,
331+
uint8_t dummy_len,
332+
uint8_t mosi_len, uint32_t mosi_data,
333+
uint8_t miso_len)
334+
{
335+
return esp_tee_service_call(8, SS_BOOTLOADER_FLASH_EXECUTE_COMMAND_COMMON,
336+
command, addr_len, address, dummy_len, mosi_len,
337+
mosi_data, miso_len);
338+
}
339+
340+
esp_err_t IRAM_ATTR __wrap_memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
341+
{
342+
return esp_tee_service_call(4, SS_MEMSPI_HOST_FLUSH_CACHE, host, addr, size);
343+
}
344+
345+
esp_err_t IRAM_ATTR __wrap_spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t flags)
346+
{
347+
return esp_tee_service_call(3, SS_SPI_FLASH_CHIP_GENERIC_CONFIG_HOST_IO_MODE, chip, flags);
348+
}
349+
#endif

components/esp_tee/subproject/main/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ list(APPEND srcs "${hal_dir}/apm_hal.c"
5454
"${hal_dir}/brownout_hal.c"
5555
"${hal_dir}/wdt_hal_iram.c")
5656

57+
if(CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1)
58+
list(APPEND srcs "${hal_dir}/spi_flash_hal.c")
59+
endif()
60+
5761
# TLSF implementation for heap
5862
list(APPEND include "${heap_dir}/include"
5963
"${heap_dir}/tlsf"

0 commit comments

Comments
 (0)