mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'feature/esp_tee_flash_prot_spi1' into 'master'
feat(esp_tee): Add support for flash memory isolation and protection (SPI1) Closes IDF-10481, IDF-10083, and IDF-8915 See merge request espressif/esp-idf!36454
This commit is contained in:
commit
870a1846b1
@ -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)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
idf_build_get_property(esp_tee_build ESP_TEE_BUILD)
|
||||
idf_build_get_property(custom_secure_service_tbl CUSTOM_SECURE_SERVICE_TBL)
|
||||
idf_build_get_property(custom_secure_service_yaml CUSTOM_SECURE_SERVICE_YAML)
|
||||
idf_build_get_property(custom_secure_service_dir CUSTOM_SECURE_SERVICE_COMPONENT_DIR)
|
||||
idf_build_get_property(custom_secure_service_component CUSTOM_SECURE_SERVICE_COMPONENT)
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
@ -82,33 +82,37 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(secure_service_tbl_parser_py
|
||||
${COMPONENT_DIR}/scripts/secure_service_tbl_parser.py ${CMAKE_CURRENT_BINARY_DIR}/secure_service.tbl
|
||||
set(secure_service_yml
|
||||
${COMPONENT_DIR}/scripts/${IDF_TARGET}/sec_srv_tbl_default.yml ${custom_secure_service_yaml}
|
||||
)
|
||||
|
||||
set(secure_service_gen_headers
|
||||
${CONFIG_DIR}/secure_service_num.h ${CONFIG_DIR}/secure_service_dec.h
|
||||
${CONFIG_DIR}/secure_service_int.h ${CONFIG_DIR}/secure_service_ext.h
|
||||
set(secure_service_yml_parser_py
|
||||
${COMPONENT_DIR}/scripts/secure_service_yml_parser.py
|
||||
)
|
||||
|
||||
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()
|
||||
|
||||
execute_process(
|
||||
COMMAND cat ${COMPONENT_DIR}/scripts/${target}/secure_service.tbl ${custom_secure_service_tbl}
|
||||
OUTPUT_FILE secure_service.tbl
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND python ${secure_service_yml_parser_py}
|
||||
"--sec_srv" ${secure_service_yml}
|
||||
"--exclude" ${exclude_srv}
|
||||
WORKING_DIRECTORY ${CONFIG_DIR}
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND python ${secure_service_tbl_parser_py} ${secure_service_gen_headers}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
set_property(DIRECTORY ${COMPONENT_DIR} APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES ${secure_service_gen_headers}
|
||||
)
|
||||
|
||||
execute_process(
|
||||
COMMAND python ${secure_service_tbl_parser_py} "--wrap"
|
||||
COMMAND python ${secure_service_yml_parser_py}
|
||||
"--sec_srv" ${secure_service_yml}
|
||||
"--exclude" ${exclude_srv} "--wrap"
|
||||
OUTPUT_VARIABLE wrap_list
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
|
@ -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
|
||||
|
283
components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml
Normal file
283
components/esp_tee/scripts/esp32c6/sec_srv_tbl_default.yml
Normal file
@ -0,0 +1,283 @@
|
||||
secure_services:
|
||||
- family: misc
|
||||
entries:
|
||||
- id: 0
|
||||
type: custom
|
||||
function: invalid_secure_service
|
||||
args: 0
|
||||
# ID: 1-4 (4) - External memory (Flash) protection [SPI0]
|
||||
- family: flash_protection_spi0
|
||||
entries:
|
||||
- id: 1
|
||||
type: IDF
|
||||
function: mmu_hal_map_region
|
||||
args: 6
|
||||
- id: 2
|
||||
type: IDF
|
||||
function: mmu_hal_unmap_region
|
||||
args: 3
|
||||
- id: 3
|
||||
type: IDF
|
||||
function: mmu_hal_vaddr_to_paddr
|
||||
args: 4
|
||||
- id: 4
|
||||
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:
|
||||
- id: 30
|
||||
type: IDF
|
||||
function: esp_rom_route_intr_matrix
|
||||
args: 3
|
||||
- id: 31
|
||||
type: IDF
|
||||
function: rv_utils_intr_enable
|
||||
args: 1
|
||||
- id: 32
|
||||
type: IDF
|
||||
function: rv_utils_intr_disable
|
||||
args: 1
|
||||
- id: 33
|
||||
type: IDF
|
||||
function: rv_utils_intr_set_priority
|
||||
args: 2
|
||||
- id: 34
|
||||
type: IDF
|
||||
function: rv_utils_intr_set_type
|
||||
args: 2
|
||||
- id: 35
|
||||
type: IDF
|
||||
function: rv_utils_intr_set_threshold
|
||||
args: 1
|
||||
- id: 36
|
||||
type: IDF
|
||||
function: rv_utils_intr_edge_ack
|
||||
args: 1
|
||||
- id: 37
|
||||
type: IDF
|
||||
function: rv_utils_intr_global_enable
|
||||
args: 0
|
||||
# ID: 54-85 (32) - HAL
|
||||
- family: hal
|
||||
entries:
|
||||
- id: 54
|
||||
type: IDF
|
||||
function: efuse_hal_chip_revision
|
||||
args: 0
|
||||
- id: 55
|
||||
type: IDF
|
||||
function: efuse_hal_get_chip_ver_pkg
|
||||
args: 1
|
||||
- id: 56
|
||||
type: IDF
|
||||
function: efuse_hal_get_disable_wafer_version_major
|
||||
args: 0
|
||||
- id: 57
|
||||
type: IDF
|
||||
function: efuse_hal_get_mac
|
||||
args: 1
|
||||
- id: 58
|
||||
type: IDF
|
||||
function: wdt_hal_init
|
||||
args: 4
|
||||
- id: 59
|
||||
type: IDF
|
||||
function: wdt_hal_deinit
|
||||
args: 1
|
||||
# ID: 86-133 (48) - Crypto
|
||||
- family: crypto
|
||||
entries:
|
||||
- id: 86
|
||||
type: IDF
|
||||
function: esp_aes_intr_alloc
|
||||
args: 0
|
||||
- id: 87
|
||||
type: IDF
|
||||
function: esp_aes_crypt_cbc
|
||||
args: 6
|
||||
- id: 88
|
||||
type: IDF
|
||||
function: esp_aes_crypt_cfb8
|
||||
args: 6
|
||||
- id: 89
|
||||
type: IDF
|
||||
function: esp_aes_crypt_cfb128
|
||||
args: 7
|
||||
- id: 90
|
||||
type: IDF
|
||||
function: esp_aes_crypt_ctr
|
||||
args: 7
|
||||
- id: 91
|
||||
type: IDF
|
||||
function: esp_aes_crypt_ecb
|
||||
args: 4
|
||||
- id: 92
|
||||
type: IDF
|
||||
function: esp_aes_crypt_ofb
|
||||
args: 6
|
||||
- id: 93
|
||||
type: IDF
|
||||
function: esp_sha
|
||||
args: 4
|
||||
- id: 94
|
||||
type: IDF
|
||||
function: esp_sha_block
|
||||
args: 3
|
||||
- id: 95
|
||||
type: IDF
|
||||
function: esp_sha_dma
|
||||
args: 6
|
||||
- id: 96
|
||||
type: IDF
|
||||
function: esp_sha_read_digest_state
|
||||
args: 2
|
||||
- id: 97
|
||||
type: IDF
|
||||
function: esp_sha_write_digest_state
|
||||
args: 2
|
||||
# ID: 134-149 (16) - eFuse
|
||||
- family: efuse
|
||||
entries:
|
||||
- id: 134
|
||||
type: IDF
|
||||
function: esp_efuse_check_secure_version
|
||||
args: 1
|
||||
- id: 135
|
||||
type: IDF
|
||||
function: esp_efuse_read_field_blob
|
||||
args: 3
|
||||
- id: 136
|
||||
type: IDF
|
||||
function: esp_flash_encryption_enabled
|
||||
args: 0
|
||||
# ID: 150-169 (20) - Reserved for future use
|
||||
- family: attestation
|
||||
entries:
|
||||
- id: 170
|
||||
type: custom
|
||||
function: esp_tee_att_generate_token
|
||||
args: 6
|
||||
# ID: 175-194 (20) - Secure Storage
|
||||
- family: secure_storage
|
||||
entries:
|
||||
- id: 175
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_init
|
||||
args: 0
|
||||
- id: 176
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_gen_key
|
||||
args: 2
|
||||
- id: 177
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_get_signature
|
||||
args: 4
|
||||
- id: 178
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_get_pubkey
|
||||
args: 2
|
||||
- id: 179
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_encrypt
|
||||
args: 8
|
||||
- id: 180
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_decrypt
|
||||
args: 8
|
||||
- id: 181
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_is_slot_empty
|
||||
args: 1
|
||||
- id: 182
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_clear_slot
|
||||
args: 1
|
||||
# ID: 195-199 (5) - OTA
|
||||
- family: ota
|
||||
entries:
|
||||
- id: 195
|
||||
type: custom
|
||||
function: esp_tee_ota_begin
|
||||
args: 0
|
||||
- id: 196
|
||||
type: custom
|
||||
function: esp_tee_ota_write
|
||||
args: 3
|
||||
- id: 197
|
||||
type: custom
|
||||
function: esp_tee_ota_end
|
||||
args: 0
|
||||
# ID: 200+ - User-defined
|
@ -1,57 +0,0 @@
|
||||
# SS no. API type Function Args
|
||||
0 custom invalid_secure_service 0
|
||||
# ID: 1-47 (47) - External memory (Flash) protection
|
||||
1 IDF mmu_hal_map_region 6
|
||||
2 IDF mmu_hal_unmap_region 3
|
||||
3 IDF mmu_hal_vaddr_to_paddr 4
|
||||
4 IDF mmu_hal_paddr_to_vaddr 5
|
||||
# Services before the ID 48 will be placed in the internal memory table,
|
||||
# while the rest will be placed in the external memory table.
|
||||
# ID: 48-71 (24) - Interrupt Handling
|
||||
48 IDF esp_rom_route_intr_matrix 3
|
||||
49 IDF rv_utils_intr_enable 1
|
||||
50 IDF rv_utils_intr_disable 1
|
||||
51 IDF rv_utils_intr_set_priority 2
|
||||
52 IDF rv_utils_intr_set_type 2
|
||||
53 IDF rv_utils_intr_set_threshold 1
|
||||
54 IDF rv_utils_intr_edge_ack 1
|
||||
55 IDF rv_utils_intr_global_enable 0
|
||||
# ID: 72-119 (48) - HAL
|
||||
72 IDF efuse_hal_chip_revision 0
|
||||
73 IDF efuse_hal_get_chip_ver_pkg 1
|
||||
74 IDF efuse_hal_get_disable_wafer_version_major 0
|
||||
75 IDF efuse_hal_get_mac 1
|
||||
76 IDF wdt_hal_init 4
|
||||
77 IDF wdt_hal_deinit 1
|
||||
# ID: 120-167 (48) - Crypto
|
||||
120 IDF esp_aes_intr_alloc 0
|
||||
121 IDF esp_aes_crypt_cbc 6
|
||||
122 IDF esp_aes_crypt_cfb8 6
|
||||
123 IDF esp_aes_crypt_cfb128 7
|
||||
124 IDF esp_aes_crypt_ctr 7
|
||||
125 IDF esp_aes_crypt_ecb 4
|
||||
126 IDF esp_aes_crypt_ofb 6
|
||||
127 IDF esp_sha 4
|
||||
128 IDF esp_sha_dma 6
|
||||
129 IDF esp_sha_read_digest_state 2
|
||||
130 IDF esp_sha_write_digest_state 2
|
||||
131 IDF esp_sha_block 3
|
||||
# ID: 168-183 (16) - eFuse
|
||||
168 IDF esp_efuse_check_secure_version 1
|
||||
169 IDF esp_efuse_read_field_blob 3
|
||||
170 IDF esp_flash_encryption_enabled 0
|
||||
# ID: 184-249 (66) - Reserved for future use
|
||||
# ID: 270-293 (24) - Secure Storage
|
||||
270 custom esp_tee_sec_storage_init 0
|
||||
271 custom esp_tee_sec_storage_gen_key 2
|
||||
272 custom esp_tee_sec_storage_get_signature 4
|
||||
273 custom esp_tee_sec_storage_get_pubkey 2
|
||||
274 custom esp_tee_sec_storage_encrypt 8
|
||||
275 custom esp_tee_sec_storage_decrypt 8
|
||||
276 custom esp_tee_sec_storage_is_slot_empty 1
|
||||
277 custom esp_tee_sec_storage_clear_slot 1
|
||||
# ID: 294-299 (6) - OTA
|
||||
294 custom esp_tee_ota_begin 0
|
||||
295 custom esp_tee_ota_write 3
|
||||
296 custom esp_tee_ota_end 0
|
||||
# ID: 300+ - User-defined
|
@ -1,25 +1,37 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import argparse
|
||||
import re
|
||||
from typing import List
|
||||
from typing import Set
|
||||
from typing import Tuple
|
||||
|
||||
SEC_SRV_TABLE_SPLIT_ID = 48
|
||||
import yaml
|
||||
|
||||
SEC_SRV_TABLE_SPLIT_ID = 30
|
||||
OUTPUT_HEADERS = [
|
||||
'secure_service_num.h',
|
||||
'secure_service_dec.h',
|
||||
'secure_service_int.h',
|
||||
'secure_service_ext.h',
|
||||
]
|
||||
|
||||
|
||||
def parse_services(secure_service_tbl: str) -> List[Tuple[int, str, int]]:
|
||||
def parse_services(yml_files: List[str], excluded_fam: Set[str]) -> List[Tuple[int, str, int]]:
|
||||
services, service_ids = [], set()
|
||||
pattern = re.compile(r'^([0-9A-Fa-fXx]+)\s+\S+\s+(\S+)\s+(\d+)')
|
||||
|
||||
with open(secure_service_tbl, 'r') as f:
|
||||
for line in f:
|
||||
if match := pattern.match(line):
|
||||
service_id = int(match.group(1), 0)
|
||||
if service_id in service_ids:
|
||||
raise ValueError(f'Duplicate service call ID found: 0x{service_id:X}')
|
||||
service_ids.add(service_id)
|
||||
services.append((service_id, match.group(2), int(match.group(3))))
|
||||
for yml_file in yml_files:
|
||||
with open(yml_file, 'r') as f:
|
||||
data = yaml.safe_load(f)
|
||||
for family in data.get('secure_services', []):
|
||||
family_name = family.get('family', '')
|
||||
if family_name in excluded_fam:
|
||||
continue
|
||||
for entry in family.get('entries', []):
|
||||
service_id = entry['id']
|
||||
if service_id in service_ids:
|
||||
raise ValueError(f'Duplicate service call ID found: 0x{service_id:X}')
|
||||
service_ids.add(service_id)
|
||||
services.append((service_id, entry['function'], entry['args']))
|
||||
|
||||
return sorted(services, key=lambda x: x[0])
|
||||
|
||||
@ -83,30 +95,36 @@ def generate_table_split(services: List[Tuple[int, str, int]], output_file_1: st
|
||||
f2.write(header + body_2)
|
||||
|
||||
|
||||
def generate_wrap_list(secure_service_tbl: str) -> None:
|
||||
pattern = re.compile(r'^[0-9A-Fa-fXx]+\s+IDF\s+(\S+)\s+\d+')
|
||||
with open(secure_service_tbl, 'r') as f:
|
||||
wrap_list = [f'-Wl,--wrap={match.group(1)}' for line in f if (match := pattern.match(line))]
|
||||
def generate_wrap_list(yml_files: List[str], excluded_fam: Set[str]) -> None:
|
||||
wrap_list: list[str] = []
|
||||
for yml_file in yml_files:
|
||||
with open(yml_file, 'r') as f:
|
||||
data = yaml.safe_load(f)
|
||||
wrap_list.extend(
|
||||
f'-Wl,--wrap={entry["function"]}'
|
||||
for family in data.get('secure_services', [])
|
||||
for entry in family.get('entries', [])
|
||||
if entry['type'] == 'IDF' and family.get('family', '') not in excluded_fam
|
||||
)
|
||||
print(' '.join(wrap_list), end='')
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description='Generate secure service outputs')
|
||||
parser = argparse.ArgumentParser(description='Generate secure service outputs from YAML table')
|
||||
parser.add_argument('--wrap', action='store_true', help='Generate linker wrap options')
|
||||
parser.add_argument('secure_service_tbl', type=str, help='Path to secure service table file')
|
||||
parser.add_argument('output_files', nargs='*', help='Output files: [secure_service_num.h, secure_service_dec.h, secure_service_1.h, secure_service_2.h]')
|
||||
parser.add_argument('-s', '--sec_srv', nargs='+', required=True, help='Secure service table(s) in YAML')
|
||||
parser.add_argument('--exclude', nargs='*', default=[], help='List of API families to exclude from the output')
|
||||
|
||||
args = parser.parse_args()
|
||||
excluded_fam = set(args.exclude)
|
||||
|
||||
if args.wrap:
|
||||
generate_wrap_list(args.secure_service_tbl)
|
||||
generate_wrap_list(args.sec_srv, excluded_fam)
|
||||
else:
|
||||
if len(args.output_files) != 4:
|
||||
parser.error('Missing output header files!')
|
||||
services = parse_services(args.secure_service_tbl)
|
||||
generate_num_header(services, args.output_files[0])
|
||||
generate_dec_header(services, args.output_files[1])
|
||||
generate_table_split(services, args.output_files[2], args.output_files[3])
|
||||
services = parse_services(args.sec_srv, excluded_fam)
|
||||
generate_num_header(services, OUTPUT_HEADERS[0])
|
||||
generate_dec_header(services, OUTPUT_HEADERS[1])
|
||||
generate_table_split(services, OUTPUT_HEADERS[2], OUTPUT_HEADERS[3])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
@ -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
|
||||
|
@ -1,5 +0,0 @@
|
||||
# This file must be manually included in the project's top level CMakeLists.txt before project()
|
||||
# This ensures that the variables are set before TEE starts building
|
||||
|
||||
# Append secure service table consisting of secure services
|
||||
idf_build_set_property(CUSTOM_SECURE_SERVICE_TBL ${CMAKE_CURRENT_LIST_DIR}/esp_tee_att.tbl APPEND)
|
@ -1,2 +0,0 @@
|
||||
# SS no. API type Function Args
|
||||
250 custom esp_tee_att_generate_token 6
|
@ -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,
|
||||
|
@ -2,19 +2,6 @@
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses extra components for the following -
|
||||
# 1. common functions such as Wi-Fi and Ethernet connection.
|
||||
# 2. managing TEE OTA updates
|
||||
# 3. dumping TEE attestation info
|
||||
# 4. TEE Secure storage
|
||||
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_ota_ops
|
||||
$ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_attestation
|
||||
$ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_sec_storage)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# Including the attestation service calls
|
||||
include($ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_attestation/esp_tee_att.cmake)
|
||||
|
||||
project(tee_cli)
|
||||
|
@ -0,0 +1,7 @@
|
||||
dependencies:
|
||||
tee_attestation:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_attestation
|
||||
tee_ota_ops:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_ota_ops
|
||||
tee_sec_storage:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_sec_storage
|
@ -2,6 +2,9 @@
|
||||
CONFIG_SECURE_ENABLE_TEE=y
|
||||
CONFIG_SECURE_TEE_IRAM_SIZE=0x9000
|
||||
|
||||
# Enabling flash protection over SPI1
|
||||
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=y
|
||||
|
||||
# Custom partition table
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_PARTITION_TABLE_TWO_OTA_TEE=y
|
||||
|
@ -1,19 +1,9 @@
|
||||
#This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# This example uses extra components for the following -
|
||||
# 1. Test framework related.
|
||||
# 2. Managing TEE OTA updates
|
||||
# 3. TEE Secure Storage
|
||||
# 4. TEE Entity Attestation
|
||||
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/tools/unit-test-app/components
|
||||
$ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_ota_ops
|
||||
$ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_sec_storage
|
||||
$ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_attestation)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# For registering the test-specific and attestation secure services
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/components/test_sec_srv/test_tee_project.cmake)
|
||||
include($ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_attestation/esp_tee_att.cmake)
|
||||
|
||||
project(esp_tee_test)
|
||||
|
@ -0,0 +1,71 @@
|
||||
secure_services:
|
||||
- family: test
|
||||
entries:
|
||||
- id: 200
|
||||
type: custom
|
||||
function: esp_tee_service_add
|
||||
args: 2
|
||||
- id: 201
|
||||
type: custom
|
||||
function: esp_tee_service_sub
|
||||
args: 2
|
||||
- id: 202
|
||||
type: custom
|
||||
function: esp_tee_service_mul
|
||||
args: 2
|
||||
- id: 203
|
||||
type: custom
|
||||
function: esp_tee_service_div
|
||||
args: 2
|
||||
- id: 204
|
||||
type: custom
|
||||
function: esp_tee_test_timer_init
|
||||
args: 1
|
||||
- id: 205
|
||||
type: custom
|
||||
function: esp_tee_secure_int_test
|
||||
args: 0
|
||||
- id: 206
|
||||
type: custom
|
||||
function: esp_tee_non_secure_int_test
|
||||
args: 1
|
||||
- id: 207
|
||||
type: custom
|
||||
function: esp_tee_test_int_count
|
||||
args: 1
|
||||
- id: 208
|
||||
type: custom
|
||||
function: esp_tee_test_resv_reg1_write_violation
|
||||
args: 0
|
||||
- id: 209
|
||||
type: custom
|
||||
function: esp_tee_test_resv_reg1_exec_violation
|
||||
args: 0
|
||||
- id: 210
|
||||
type: custom
|
||||
function: esp_tee_test_iram_reg1_write_violation
|
||||
args: 0
|
||||
- id: 211
|
||||
type: custom
|
||||
function: esp_tee_test_iram_reg2_write_violation
|
||||
args: 0
|
||||
- id: 212
|
||||
type: custom
|
||||
function: esp_tee_test_dram_reg1_exec_violation
|
||||
args: 0
|
||||
- id: 213
|
||||
type: custom
|
||||
function: esp_tee_test_dram_reg2_exec_violation
|
||||
args: 0
|
||||
- id: 214
|
||||
type: custom
|
||||
function: esp_tee_test_illegal_instruction
|
||||
args: 0
|
||||
- id: 215
|
||||
type: custom
|
||||
function: dummy_secure_service
|
||||
args: 0
|
||||
- id: 216
|
||||
type: custom
|
||||
function: add_in_loop
|
||||
args: 3
|
@ -1,18 +0,0 @@
|
||||
# SS no. API type Function Args
|
||||
300 custom esp_tee_service_add 2
|
||||
301 custom esp_tee_service_sub 2
|
||||
302 custom esp_tee_service_mul 2
|
||||
303 custom esp_tee_service_div 2
|
||||
304 custom esp_tee_test_timer_init 1
|
||||
305 custom esp_tee_secure_int_test 0
|
||||
306 custom esp_tee_non_secure_int_test 1
|
||||
307 custom esp_tee_test_int_count 1
|
||||
308 custom esp_tee_test_resv_reg1_write_violation 0
|
||||
309 custom esp_tee_test_resv_reg1_exec_violation 0
|
||||
310 custom esp_tee_test_iram_reg1_write_violation 0
|
||||
311 custom esp_tee_test_iram_reg2_write_violation 0
|
||||
312 custom esp_tee_test_dram_reg1_exec_violation 0
|
||||
313 custom esp_tee_test_dram_reg2_exec_violation 0
|
||||
314 custom esp_tee_test_illegal_instruction 0
|
||||
315 custom dummy_secure_service 0
|
||||
316 custom add_in_loop 3
|
@ -1,11 +1,11 @@
|
||||
# tee_project.cmake file must be manually included in the project's top level CMakeLists.txt before project()
|
||||
# This file must be manually included in the project's top level CMakeLists.txt before project()
|
||||
# This ensures that the variables are set before TEE starts building
|
||||
|
||||
get_filename_component(directory "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE DIRECTORY)
|
||||
get_filename_component(name ${CMAKE_CURRENT_LIST_DIR} NAME)
|
||||
|
||||
# Append secure service table consisting of secure services
|
||||
idf_build_set_property(CUSTOM_SECURE_SERVICE_TBL ${CMAKE_CURRENT_LIST_DIR}/test.tbl APPEND)
|
||||
idf_build_set_property(CUSTOM_SECURE_SERVICE_YAML ${CMAKE_CURRENT_LIST_DIR}/sec_srv_tbl_test.yml APPEND)
|
||||
|
||||
# Append the directory of this component which is used by esp_tee component as
|
||||
# EXTRA_COMPONENT_DIRS
|
||||
|
@ -1,2 +1,10 @@
|
||||
dependencies:
|
||||
ccomp_timer: "^1.0.0"
|
||||
tee_attestation:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_attestation
|
||||
tee_ota_ops:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_ota_ops
|
||||
tee_sec_storage:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_sec_storage
|
||||
test_utils:
|
||||
path: ${IDF_PATH}/tools/unit-test-app/components/test_utils
|
||||
|
@ -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
|
||||
*/
|
||||
@ -21,8 +21,11 @@
|
||||
#include "secure_service_num.h"
|
||||
|
||||
#include "unity.h"
|
||||
#include "ccomp_timer.h"
|
||||
|
||||
#define BOOT_COUNT_NAMESPACE "boot_count"
|
||||
#define TEST_PART_LABEL "custom"
|
||||
#define TEST_BUF_SZ 256
|
||||
|
||||
static const char *TAG = "test_esp_tee_flash_prot";
|
||||
|
||||
@ -106,6 +109,66 @@ TEST_CASE_MULTIPLE_STAGES("Test REE-TEE isolation: Flash - SPI0 (esp_partition_m
|
||||
test_initial_boot, test_esp_partition_mmap_api, test_esp_partition_mmap_api,
|
||||
test_esp_partition_mmap_api, test_esp_partition_mmap_api);
|
||||
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
static void test_esp_partition_api_r(const esp_partition_t *part)
|
||||
{
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
uint8_t buf_r[128];
|
||||
memset(buf_r, 0x00, sizeof(buf_r));
|
||||
TEST_ESP_ERR(ESP_FAIL, esp_partition_read(part, 0x00, buf_r, sizeof(buf_r)));
|
||||
}
|
||||
|
||||
static void test_esp_partition_api_w(const esp_partition_t *part)
|
||||
{
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
uint8_t buf_w[128];
|
||||
memset(buf_w, 0xA5, sizeof(buf_w));
|
||||
TEST_ESP_OK(esp_partition_write(part, 0x00, buf_w, sizeof(buf_w)));
|
||||
}
|
||||
|
||||
static void test_esp_partition_api_e(const esp_partition_t *part)
|
||||
{
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
TEST_ESP_OK(esp_partition_erase_range(part, 0x00, SPI_FLASH_SEC_SIZE));
|
||||
}
|
||||
|
||||
static void test_esp_partition_api(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
boot_count++;
|
||||
set_boot_count_in_nvs(boot_count);
|
||||
|
||||
const esp_partition_t *part = NULL;
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_0, NULL);
|
||||
test_esp_partition_api_r(part);
|
||||
break;
|
||||
case 3:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_1, NULL);
|
||||
test_esp_partition_api_w(part);
|
||||
break;
|
||||
case 4:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_SEC_STORAGE, NULL);
|
||||
test_esp_partition_api_w(part);
|
||||
break;
|
||||
case 5:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_OTA, NULL);
|
||||
test_esp_partition_api_e(part);
|
||||
break;
|
||||
default:
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("Test REE-TEE isolation: Flash - SPI1 (esp_partition)", "[flash_prot][timeout=60]",
|
||||
test_initial_boot, test_esp_partition_api, test_esp_partition_api,
|
||||
test_esp_partition_api, test_esp_partition_api);
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------- API family 2: spi_flash ------------------------------------------------- */
|
||||
|
||||
static void test_spi_flash_mmap_api(void)
|
||||
@ -149,3 +212,172 @@ static void test_spi_flash_mmap_api(void)
|
||||
TEST_CASE_MULTIPLE_STAGES("Test REE-TEE isolation: Flash - SPI0 (spi_flash_mmap)", "[flash_prot][timeout=60]",
|
||||
test_initial_boot, test_spi_flash_mmap_api, test_spi_flash_mmap_api,
|
||||
test_spi_flash_mmap_api);
|
||||
|
||||
/* ---------------------------------------------- API family 3: esp_flash ------------------------------------------------- */
|
||||
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
static void test_esp_flash_api_r(uint32_t paddr)
|
||||
{
|
||||
uint8_t buf_r[128];
|
||||
memset(buf_r, 0x00, sizeof(buf_r));
|
||||
TEST_ESP_ERR(ESP_FAIL, esp_flash_read(NULL, buf_r, paddr, sizeof(buf_r)));
|
||||
}
|
||||
|
||||
static void test_esp_flash_api_w(uint32_t paddr)
|
||||
{
|
||||
uint8_t buf_w[128];
|
||||
memset(buf_w, 0xA5, sizeof(buf_w));
|
||||
TEST_ESP_OK(esp_flash_write(NULL, buf_w, paddr, sizeof(buf_w)));
|
||||
}
|
||||
|
||||
static void test_esp_flash_api_e(uint32_t paddr)
|
||||
{
|
||||
TEST_ESP_OK(esp_flash_erase_region(NULL, paddr, SPI_FLASH_SEC_SIZE));
|
||||
}
|
||||
|
||||
static void test_esp_flash_api(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
boot_count++;
|
||||
set_boot_count_in_nvs(boot_count);
|
||||
|
||||
const esp_partition_t *part = NULL;
|
||||
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_0, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_flash_api_w(part->address);
|
||||
break;
|
||||
case 3:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_1, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_flash_api_r(part->address);
|
||||
break;
|
||||
case 4:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_SEC_STORAGE, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_flash_api_e(part->address);
|
||||
break;
|
||||
case 5:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_OTA, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_flash_api_w(part->address);
|
||||
break;
|
||||
default:
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("Test REE-TEE isolation: Flash - SPI1 (esp_flash)", "[flash_prot][timeout=60]",
|
||||
test_initial_boot, test_esp_flash_api, test_esp_flash_api, test_esp_flash_api,
|
||||
test_esp_flash_api);
|
||||
|
||||
/* ---------------------------------------------- API family 4: esp_rom ------------------------------------------------- */
|
||||
|
||||
static IRAM_ATTR void test_esp_rom_spiflash_api_r(uint32_t paddr)
|
||||
{
|
||||
uint32_t buf_r[32];
|
||||
memset(buf_r, 0x00, sizeof(buf_r));
|
||||
esp_rom_spiflash_result_t rc = esp_rom_spiflash_read(paddr, buf_r, sizeof(buf_r));
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_ROM_SPIFLASH_RESULT_OK, rc);
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, buf_r, sizeof(buf_r), ESP_LOG_INFO);
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_esp_rom_spiflash_api_w(uint32_t paddr)
|
||||
{
|
||||
uint32_t buf_w[32];
|
||||
memset(buf_w, 0xA5, sizeof(buf_w));
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
esp_rom_spiflash_result_t rc = esp_rom_spiflash_write(paddr, buf_w, sizeof(buf_w));
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_ROM_SPIFLASH_RESULT_OK, rc);
|
||||
}
|
||||
|
||||
static IRAM_ATTR void test_esp_rom_spiflash_api_e(uint32_t paddr)
|
||||
{
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
esp_rom_spiflash_result_t rc = esp_rom_spiflash_erase_area(paddr, SPI_FLASH_SEC_SIZE);
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_ROM_SPIFLASH_RESULT_OK, rc);
|
||||
}
|
||||
|
||||
static void test_esp_rom_spiflash_api(void)
|
||||
{
|
||||
uint8_t boot_count = get_boot_count_from_nvs();
|
||||
boot_count++;
|
||||
set_boot_count_in_nvs(boot_count);
|
||||
|
||||
const esp_partition_t *part = NULL;
|
||||
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_0, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_rom_spiflash_api_r(part->address);
|
||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||
break;
|
||||
case 3:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_TEE_1, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_rom_spiflash_api_w(part->address);
|
||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||
break;
|
||||
case 4:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_SEC_STORAGE, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_rom_spiflash_api_e(part->address);
|
||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||
break;
|
||||
case 5:
|
||||
part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_TEE_OTA, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
test_esp_rom_spiflash_api_w(part->address);
|
||||
TEST_FAIL_MESSAGE("System fault should have been generated");
|
||||
break;
|
||||
default:
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_STAGES("Test REE-TEE isolation: Flash - SPI1 (esp_rom_spiflash)", "[flash_prot][timeout=60]",
|
||||
test_initial_boot, test_esp_rom_spiflash_api, test_esp_rom_spiflash_api,
|
||||
test_esp_rom_spiflash_api, test_esp_rom_spiflash_api);
|
||||
#endif
|
||||
|
||||
TEST_CASE("Test TEE flash read/write performance", "[flash_prot]")
|
||||
{
|
||||
const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, TEST_PART_LABEL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
|
||||
TEST_ESP_OK(esp_partition_erase_range(part, 0x00, part->size));
|
||||
TEST_ASSERT_TRUE((part->size % TEST_BUF_SZ) == 0);
|
||||
|
||||
ESP_LOGI(TAG, "R/W operations over a %luKB partition in %luB chunks...", part->size / 1024, TEST_BUF_SZ);
|
||||
|
||||
uint8_t buf_w[TEST_BUF_SZ];
|
||||
memset(buf_w, 0xA5, sizeof(buf_w));
|
||||
|
||||
float write_usec, read_usec;
|
||||
ccomp_timer_start();
|
||||
for (size_t offs = 0; offs < part->size; offs += TEST_BUF_SZ) {
|
||||
TEST_ESP_OK(esp_partition_write(part, offs, buf_w, TEST_BUF_SZ));
|
||||
}
|
||||
write_usec = ccomp_timer_stop();
|
||||
ESP_LOGI(TAG, "[Time taken] Write: %.2fus", write_usec);
|
||||
|
||||
uint8_t buf_r[TEST_BUF_SZ] = {};
|
||||
|
||||
ccomp_timer_start();
|
||||
for (size_t offs = 0; offs < part->size; offs += TEST_BUF_SZ) {
|
||||
TEST_ESP_OK(esp_partition_read(part, offs, buf_r, TEST_BUF_SZ));
|
||||
}
|
||||
read_usec = ccomp_timer_stop();
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(buf_w, buf_r, TEST_BUF_SZ);
|
||||
ESP_LOGI(TAG, "[Time taken] Read: %.2fus", read_usec);
|
||||
}
|
||||
|
@ -4,3 +4,4 @@ tee, app, tee_0, , 192K,
|
||||
secure_storage, data, tee_sec_stg, , 64K,
|
||||
factory, app, factory, , 512K,
|
||||
nvs, data, nvs, , 24K,
|
||||
custom, data, , , 1M
|
||||
|
|
@ -8,3 +8,4 @@ ota_0, app, ota_0, , 512K,
|
||||
ota_1, app, ota_1, , 512K,
|
||||
otadata, data, ota, , 8K,
|
||||
nvs, data, nvs, , 24K,
|
||||
custom, data, , , 1M
|
||||
|
|
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
@ -15,6 +15,11 @@ CONFIGS_OTA = [
|
||||
pytest.param('ota', marks=[pytest.mark.esp32c6])
|
||||
]
|
||||
|
||||
CONFIGS_ALL = [
|
||||
pytest.param('default', marks=[pytest.mark.esp32c6]),
|
||||
pytest.param('ota', marks=[pytest.mark.esp32c6])
|
||||
]
|
||||
|
||||
TEE_VIOLATION_TEST_EXC_RSN: Dict[str, Any] = {
|
||||
'esp32c6': {
|
||||
('Reserved', 'W1'): 'Store access fault',
|
||||
@ -42,6 +47,8 @@ REE_ISOLATION_TEST_EXC_RSN: Dict[str, Any] = {
|
||||
|
||||
TEE_APM_VIOLATION_EXC_CHK = ['AES', 'eFuse', 'MMU']
|
||||
|
||||
TEST_PARTITION_LABEL = 'test'
|
||||
|
||||
# ---------------- TEE default tests ----------------
|
||||
|
||||
|
||||
@ -52,14 +59,14 @@ def test_esp_tee(dut: IdfDut) -> None:
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True)
|
||||
@pytest.mark.parametrize('config', CONFIGS_ALL, indirect=True)
|
||||
def test_esp_tee_crypto_aes(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(group='aes')
|
||||
dut.run_all_single_board_cases(group='aes-gcm')
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True)
|
||||
@pytest.mark.parametrize('config', CONFIGS_ALL, indirect=True)
|
||||
def test_esp_tee_crypto_sha(dut: IdfDut) -> None:
|
||||
dut.run_all_single_board_cases(group='mbedtls')
|
||||
dut.run_all_single_board_cases(group='hw_crypto')
|
||||
@ -67,7 +74,7 @@ def test_esp_tee_crypto_sha(dut: IdfDut) -> None:
|
||||
|
||||
# NOTE: Stress testing the AES performance case for interrupt-related edge-cases
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True)
|
||||
@pytest.mark.parametrize('config', CONFIGS_ALL, indirect=True)
|
||||
def test_esp_tee_aes_perf(dut: IdfDut) -> None:
|
||||
# start test
|
||||
for i in range(24):
|
||||
@ -134,17 +141,56 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
dut.expect('Exception origin: U-mode')
|
||||
|
||||
# ---------------- TEE Flash Protection Tests ----------------
|
||||
|
||||
|
||||
class TeeFlashAccessApi(Enum):
|
||||
ESP_PARTITION_MMAP = 1
|
||||
SPI_FLASH_MMAP = 2
|
||||
ESP_PARTITION = 3
|
||||
ESP_FLASH = 4
|
||||
ESP_ROM_SPIFLASH = 5
|
||||
|
||||
|
||||
def check_panic_or_reset(dut: IdfDut) -> None:
|
||||
try:
|
||||
exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=5).group(2).decode()
|
||||
if exc not in {'Cache error', 'Authority exception'}:
|
||||
raise RuntimeError('Flash operation incorrect exception')
|
||||
except Exception:
|
||||
rst_rsn = dut.expect(r'rst:(0x[0-9A-Fa-f]+) \(([^)]+)\)', timeout=5).group(2).decode()
|
||||
# Fault assert check produces this reset reason
|
||||
if rst_rsn != 'LP_SW_HPSYS':
|
||||
raise RuntimeError('Flash operation incorrect reset reason')
|
||||
|
||||
|
||||
def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFlashAccessApi) -> None:
|
||||
exp_seq = {
|
||||
TeeFlashAccessApi.ESP_PARTITION: ['read', 'program_page', 'program_page', 'erase_sector'],
|
||||
TeeFlashAccessApi.ESP_FLASH: ['program_page', 'read', 'erase_sector', 'program_page']
|
||||
}
|
||||
|
||||
def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int) -> None:
|
||||
for stage in range(1, stages + 1):
|
||||
dut.write(str(test_case_num))
|
||||
dut.expect(r'\s+\((\d+)\)\s+"([^"]+)"\r?\n', timeout=30)
|
||||
dut.write(str(stage))
|
||||
|
||||
if 1 < stage <= stages:
|
||||
rst_rsn = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=30).group(2).decode()
|
||||
if rst_rsn != 'Cache error':
|
||||
raise RuntimeError('Incorrect reset reason observed after TEE image failure!')
|
||||
if api in exp_seq:
|
||||
try:
|
||||
match = dut.expect(r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=5)
|
||||
fault_api = match.group(1).decode()
|
||||
if fault_api != exp_seq[api][stage - 2]:
|
||||
raise RuntimeError('Flash operation address check failed')
|
||||
except Exception:
|
||||
# NOTE: The esp_partition_read API handles both decrypted
|
||||
# and plaintext reads. When flash encryption is enabled,
|
||||
# it uses the MMU HAL instead of the SPI flash HAL.
|
||||
exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=5).group(2).decode()
|
||||
if exc != 'Cache error':
|
||||
raise RuntimeError('Flash operation incorrect exception')
|
||||
else:
|
||||
check_panic_or_reset(dut)
|
||||
|
||||
if stage != stages:
|
||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||
@ -160,8 +206,8 @@ def test_esp_tee_flash_prot_esp_partition_mmap(dut: IdfDut) -> None:
|
||||
# start test
|
||||
extra_data = dut.parse_test_menu()
|
||||
for test_case in extra_data:
|
||||
if test_case.name == 'Test REE-TEE isolation: Flash - SPI1 (esp_partition_mmap)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases))
|
||||
if test_case.name == 'Test REE-TEE isolation: Flash - SPI0 (esp_partition_mmap)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases), TeeFlashAccessApi.ESP_PARTITION_MMAP)
|
||||
else:
|
||||
continue
|
||||
|
||||
@ -177,7 +223,55 @@ def test_esp_tee_flash_prot_spi_flash_mmap(dut: IdfDut) -> None:
|
||||
extra_data = dut.parse_test_menu()
|
||||
for test_case in extra_data:
|
||||
if test_case.name == 'Test REE-TEE isolation: Flash - SPI0 (spi_flash_mmap)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases))
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases), TeeFlashAccessApi.SPI_FLASH_MMAP)
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True)
|
||||
@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
|
||||
def test_esp_tee_flash_prot_esp_rom_spiflash(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
|
||||
# start test
|
||||
extra_data = dut.parse_test_menu()
|
||||
for test_case in extra_data:
|
||||
if test_case.name == 'Test REE-TEE isolation: Flash - SPI1 (esp_rom_spiflash)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases), TeeFlashAccessApi.ESP_ROM_SPIFLASH)
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True)
|
||||
@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
|
||||
def test_esp_tee_flash_prot_esp_partition(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
|
||||
# start test
|
||||
extra_data = dut.parse_test_menu()
|
||||
for test_case in extra_data:
|
||||
if test_case.name == 'Test REE-TEE isolation: Flash - SPI1 (esp_partition)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases), TeeFlashAccessApi.ESP_PARTITION)
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True)
|
||||
@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
|
||||
def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None:
|
||||
# Flash the bootloader, TEE and REE firmware
|
||||
dut.serial.custom_flash()
|
||||
|
||||
# start test
|
||||
extra_data = dut.parse_test_menu()
|
||||
for test_case in extra_data:
|
||||
if test_case.name == 'Test REE-TEE isolation: Flash - SPI1 (esp_flash)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases), TeeFlashAccessApi.ESP_FLASH)
|
||||
else:
|
||||
continue
|
||||
|
||||
|
@ -9,3 +9,6 @@ CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y
|
||||
|
||||
# secure storage key slot for attestation
|
||||
CONFIG_SECURE_TEE_ATT_KEY_SLOT_ID=14
|
||||
|
||||
# Enabling flash protection over SPI1
|
||||
CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1=y
|
||||
|
@ -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
|
||||
~~~~~~~~~~~
|
||||
|
||||
@ -286,31 +329,43 @@ To extend the ESP-TEE framework with custom service calls, follow the steps outl
|
||||
1. Create a Custom Service Call Table
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Define a component for defining custom service calls and create a ``.tbl`` file within the component.
|
||||
Define a component for defining custom service calls and create a ``.yml`` file within the component.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
touch <path/to/tbl/file>/custom_srvcall.tbl
|
||||
touch <path/to/yml/file>/custom_srvcall.yml
|
||||
|
||||
Add your custom service call entries to the ``.tbl`` file in the following format:
|
||||
Add your custom service call entries to the ``.yml`` file in the following format:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: yaml
|
||||
|
||||
<service_call_number> custom <function_name> <arguments_count>
|
||||
secure_services:
|
||||
- family: <api_family>
|
||||
entries:
|
||||
- id: <service_call_number>
|
||||
type: custom
|
||||
function: <function_name>
|
||||
args: <arguments_count>
|
||||
|
||||
**Example Entry**
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: yaml
|
||||
|
||||
# SS no. API type Function Args
|
||||
201 custom custom_sec_srv_op 1
|
||||
secure_services:
|
||||
- family: example
|
||||
entries:
|
||||
- id: 300
|
||||
type: custom
|
||||
function: example_sec_serv_aes_op
|
||||
args: 5
|
||||
|
||||
- ``201``: Unique service call number
|
||||
|
||||
- ``300``: Unique service call number
|
||||
- ``custom``: Custom service call type
|
||||
- ``custom_sec_srv_op``: Function name
|
||||
- ``1``: Number of arguments
|
||||
- ``example_sec_serv_aes_op``: Function name
|
||||
- ``5``: Number of arguments
|
||||
|
||||
Ensure that the custom service call numbers does not conflict with the :component_file:`default service call table<esp_tee/scripts/{IDF_TARGET_PATH_NAME}/secure_service.tbl>`. The ESP-TEE framework parses the custom service call table along with the default table to generate relevant header files used in applications.
|
||||
Ensure that the custom service call numbers does not conflict with the :component_file:`default service call table<esp_tee/scripts/{IDF_TARGET_PATH_NAME}/sec_srv_tbl_default.yml>`. The ESP-TEE framework parses the custom service call table along with the default table to generate relevant header files used in applications.
|
||||
|
||||
2. Define the Service Call Implementation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -327,7 +382,7 @@ Define the function corresponding to the custom service call in the TEE. This fu
|
||||
return 0;
|
||||
}
|
||||
|
||||
The function name should have the prefix ``_ss_`` before the name and must match the name specified in the ``.tbl`` file.
|
||||
The function name should have the prefix ``_ss_`` before the name and must match the name specified in the ``.yml`` file.
|
||||
|
||||
For reference, all default service call functions are defined in the :component_file:`file<esp_tee/subproject/main/core/esp_secure_services.c>`.
|
||||
|
||||
@ -342,7 +397,7 @@ Define a CMake file (e.g., ``custom_sec_srv.cmake``) in the component that defin
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
idf_build_set_property(CUSTOM_SECURE_SERVICE_TBL ${CMAKE_CURRENT_LIST_DIR}/custom_srvcall.tbl APPEND)
|
||||
idf_build_set_property(CUSTOM_SECURE_SERVICE_YAML ${CMAKE_CURRENT_LIST_DIR}/custom_srvcall.yml APPEND)
|
||||
|
||||
#. Set the custom component directory and name so that the ``esp_tee`` subproject can use it
|
||||
|
||||
|
@ -255,8 +255,6 @@ API Reference
|
||||
|
||||
.. note::
|
||||
|
||||
- To use the TEE Attestation APIs into your project, ensure the :component:`tee_attestation <esp_tee/subproject/components/tee_attestation>` component is included by setting ``EXTRA_COMPONENT_DIRS`` in your project's ``CMakeLists.txt`` file, as shown in the :example:`tee_attestation <security/tee/tee_attestation>` example. For more information, refer to the :ref:`optional_project_variable` section from the :doc:`Build System </api-guides/build-system>` documentation.
|
||||
|
||||
- Additionally, the component-specific :component_file:`CMake <esp_tee/subproject/components/tee_attestation/esp_tee_att.cmake>` file needs to be included in the top-level ``CMakeLists.txt`` of your project before calling the ``project()`` command to integrate the corresponding service calls into the project.
|
||||
To use the TEE Attestation APIs in your project, ensure that the :component:`tee_attestation <esp_tee/subproject/components/tee_attestation>` component is listed as a local dependency in the component manager manifest file `idf_component.yml <https://docs.espressif.com/projects/idf-component-manager/en/latest/reference/manifest_file.html>`_. Refer to the :example:`tee_attestation <security/tee/tee_attestation>` example for guidance.
|
||||
|
||||
.. include-build-file:: inc/esp_tee_attestation.inc
|
||||
|
@ -74,6 +74,6 @@ API Reference
|
||||
|
||||
.. note::
|
||||
|
||||
To use the TEE OTA APIs into your project, ensure the :component:`tee_ota_ops <esp_tee/subproject/components/tee_ota_ops>` component is included by setting ``EXTRA_COMPONENT_DIRS`` in your project's ``CMakeLists.txt`` file, as shown in the :example:`tee_secure_ota <security/tee/tee_secure_ota>` example. For more information, refer to the :ref:`optional_project_variable` section from the :doc:`Build System </api-guides/build-system>` documentation.
|
||||
To use the TEE OTA APIs in your project, ensure that the :component:`tee_ota_ops <esp_tee/subproject/components/tee_ota_ops>` component is listed as a local dependency in the component manager manifest file `idf_component.yml <https://docs.espressif.com/projects/idf-component-manager/en/latest/reference/manifest_file.html>`_. Refer to the :example:`tee_secure_ota <security/tee/tee_secure_ota>` example for guidance.
|
||||
|
||||
.. include-build-file:: inc/esp_tee_ota_ops.inc
|
||||
|
@ -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:
|
||||
@ -112,6 +108,6 @@ API Reference
|
||||
|
||||
.. note::
|
||||
|
||||
To use the TEE Secure Storage APIs into your project, ensure the :component:`tee_sec_storage <esp_tee/subproject/components/tee_sec_storage>` component is included by setting ``EXTRA_COMPONENT_DIRS`` in your project's ``CMakeLists.txt`` file, as shown in the :example:`tee_secure_storage <security/tee/tee_secure_storage>` example. For more information, refer to the :ref:`optional_project_variable` section from the :doc:`Build System </api-guides/build-system>` documentation.
|
||||
To use the TEE Secure Storage APIs in your project, ensure that the :component:`tee_sec_storage <esp_tee/subproject/components/tee_sec_storage>` component is listed as a local dependency in the component manager manifest file `idf_component.yml <https://docs.espressif.com/projects/idf-component-manager/en/latest/reference/manifest_file.html>`_. Refer to the :example:`tee_secure_storage <security/tee/tee_secure_storage>` example for guidance.
|
||||
|
||||
.. include-build-file:: inc/esp_tee_sec_storage.inc
|
||||
|
@ -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
|
||||
@ -120,7 +120,7 @@ All features that the TEE exposes to the REE are implemented as secure services.
|
||||
|
||||
Since multitasking is not currently supported in the TEE, secure service calls are serialized, and subsequent calls remain pending until the current service completes.
|
||||
|
||||
For {IDF_TARGET_NAME}, a list of secure services can be found at this :component_file:`table<esp_tee/scripts/{IDF_TARGET_PATH_NAME}/secure_service.tbl>`. Following are the types of secure services.
|
||||
For {IDF_TARGET_NAME}, a list of secure services can be found at this :component_file:`table<esp_tee/scripts/{IDF_TARGET_PATH_NAME}/sec_srv_tbl_default.yml>`. Following are the types of secure services.
|
||||
|
||||
- **Core secure services**: Built-in services within the TEE firmware that provide routine functionalities to the REE, such as interrupt configuration and eFuse access.
|
||||
|
||||
|
@ -2,14 +2,8 @@
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses extra components for the following -
|
||||
# 1. Printing TEE attestation info
|
||||
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_attestation)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# Including the attestation service calls
|
||||
include($ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_attestation/esp_tee_att.cmake)
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(tee_attestation)
|
||||
|
@ -8,9 +8,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_console.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
tee_attestation:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_attestation
|
@ -4,7 +4,9 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# Including the example service calls
|
||||
# For registering custom secure services for the example
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/components/example_secure_service/tee_project.cmake)
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(tee_basic)
|
||||
|
@ -13,7 +13,7 @@
|
||||
└── example_secure_service # Component parent directory
|
||||
├── CMakeLists.txt
|
||||
├── example_service.c # Custom secure service APIs
|
||||
├── example.tbl # Custom secure service table, which is appended to the default one provided by TEE
|
||||
├── sec_srv_tbl_example.yml # Custom secure service table, which is parsed alongwith the default one provided by TEE
|
||||
├── include
|
||||
│ └── example_service.h
|
||||
└── tee_project.cmake # To be manually included in the project's top level CMakeLists.txt before project(...)
|
||||
|
@ -1,2 +0,0 @@
|
||||
# SS no. API type Function Args
|
||||
300 custom example_sec_serv_aes_op 5
|
@ -0,0 +1,7 @@
|
||||
secure_services:
|
||||
- family: example
|
||||
entries:
|
||||
- id: 200
|
||||
type: custom
|
||||
function: example_sec_serv_aes_op
|
||||
args: 5
|
@ -1,11 +1,11 @@
|
||||
# tee_project.cmake file must be manually included in the project's top level CMakeLists.txt before project()
|
||||
# This file must be manually included in the project's top level CMakeLists.txt before project()
|
||||
# This ensures that the variables are set before TEE starts building
|
||||
|
||||
get_filename_component(directory "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE DIRECTORY)
|
||||
get_filename_component(name ${CMAKE_CURRENT_LIST_DIR} NAME)
|
||||
|
||||
# Append secure service table consisting of secure services
|
||||
idf_build_set_property(CUSTOM_SECURE_SERVICE_TBL ${CMAKE_CURRENT_LIST_DIR}/example.tbl APPEND)
|
||||
idf_build_set_property(CUSTOM_SECURE_SERVICE_YAML ${CMAKE_CURRENT_LIST_DIR}/sec_srv_tbl_example.yml APPEND)
|
||||
|
||||
# Append the directory of this component which is used by esp_tee component as
|
||||
# EXTRA_COMPONENT_DIRS
|
||||
|
@ -1,2 +1,3 @@
|
||||
idf_component_register(SRCS "tee_main.c"
|
||||
INCLUDE_DIRS "")
|
||||
INCLUDE_DIRS ""
|
||||
PRIV_REQUIRES esp_tee mbedtls)
|
||||
|
@ -2,12 +2,8 @@
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# (Not part of the boilerplate)
|
||||
# This example uses extra components for the following -
|
||||
# 1. common functions such as Wi-Fi and Ethernet connection.
|
||||
# 2. managing TEE OTA updates
|
||||
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common
|
||||
$ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_ota_ops)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(tee_secure_ota)
|
||||
|
@ -1,2 +1,4 @@
|
||||
idf_component_register(SRCS "cmd_ota.c" "app_main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES app_update console esp_driver_uart esp_event esp_http_client
|
||||
esp_https_ota esp_netif esp_wifi mbedtls nvs_flash)
|
||||
|
@ -0,0 +1,5 @@
|
||||
dependencies:
|
||||
tee_ota_ops:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_ota_ops
|
||||
protocol_examples_common:
|
||||
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
|
@ -2,8 +2,8 @@
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/components/esp_tee/subproject/components/tee_sec_storage)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
|
||||
idf_build_set_property(MINIMAL_BUILD ON)
|
||||
project(tee_secure_storage)
|
||||
|
@ -1,2 +1,3 @@
|
||||
idf_component_register(SRCS "tee_main.c"
|
||||
INCLUDE_DIRS "")
|
||||
INCLUDE_DIRS ""
|
||||
PRIV_REQUIRES mbedtls)
|
||||
|
@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
tee_sec_storage:
|
||||
path: ${IDF_PATH}/components/esp_tee/subproject/components/tee_sec_storage
|
@ -19,7 +19,6 @@
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#include "secure_service_num.h"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user