mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
fix(esp_tee): Fix TEE attestation stack protection fault with secure boot enabled
- Increased the TEE stack when secure boot is enabled - Also, generate a build error when the generated TEE binary image size is greater than the TEE partition size
This commit is contained in:
@@ -27,6 +27,7 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
|
||||
config SECURE_TEE_STACK_SIZE
|
||||
hex "Stack size"
|
||||
default 0x1000 if SECURE_BOOT
|
||||
default 0xc00
|
||||
range 0x800 0x1000
|
||||
help
|
||||
|
||||
@@ -8,7 +8,7 @@ idf_build_get_property(project_dir PROJECT_DIR)
|
||||
idf_build_get_property(non_os_build NON_OS_BUILD)
|
||||
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(partition_table_bin PARTITION_TABLE_BIN_PATH)
|
||||
|
||||
if(NOT CONFIG_SECURE_ENABLE_TEE OR non_os_build)
|
||||
return()
|
||||
@@ -80,6 +80,7 @@ externalproject_add(esp_tee
|
||||
-DCUSTOM_SECURE_SERVICE_COMPONENT=${custom_secure_service_component}
|
||||
-DCUSTOM_SECURE_SERVICE_COMPONENT_DIR=${custom_secure_service_dir}
|
||||
-DSECURE_SERVICE_HEADERS_DIR=${secure_service_headers_dir}
|
||||
-DPARTITION_TABLE_BIN_PATH=${partition_table_bin}
|
||||
${extra_cmake_args} ${sign_key_arg}
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS 1 # no easy way around this...
|
||||
|
||||
@@ -98,3 +98,17 @@ if(CONFIG_SECURE_BOOT_V2_ENABLED)
|
||||
${key_arg}
|
||||
)
|
||||
endif()
|
||||
|
||||
# Generate TEE post-build check of the TEE size against the partition
|
||||
partition_table_add_check_tee_size_target(esp_tee_check_size
|
||||
DEPENDS gen_esp_tee_binary
|
||||
TEE_BINARY_PATH "${CMAKE_BINARY_DIR}/${esp_tee_unsigned_bin}")
|
||||
add_dependencies(app esp_tee_check_size)
|
||||
|
||||
if(CONFIG_SECURE_BOOT_V2_ENABLED AND CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||
# Check the size of the TEE + signature block.
|
||||
partition_table_add_check_tee_size_target(esp_tee_check_size_signed
|
||||
DEPENDS gen_signed_esp_tee_binary
|
||||
TEE_BINARY_PATH "${CMAKE_BINARY_DIR}/${project_bin}")
|
||||
add_dependencies(app esp_tee_check_size_signed)
|
||||
endif()
|
||||
|
||||
@@ -15,7 +15,3 @@ CONFIG_NVS_SEC_KEY_PROTECT_USING_FLASH_ENC=y
|
||||
# TEE Secure Storage: Release mode
|
||||
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
|
||||
CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
|
||||
|
||||
# Increasing TEE DRAM size
|
||||
# 18KB
|
||||
CONFIG_SECURE_TEE_DRAM_SIZE=0x5000
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ESP-IDF Partition Table
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
tee_0, app, tee_0, , 192K,
|
||||
tee_1, app, tee_1, , 192K,
|
||||
tee_0, app, tee_0, , 256K,
|
||||
tee_1, app, tee_1, , 256K,
|
||||
tee_otadata, data, tee_ota, , 8K,
|
||||
secure_storage, data, nvs, , 56K,
|
||||
ota_0, app, ota_0, , 512K,
|
||||
|
||||
|
@@ -24,6 +24,12 @@ CONFIG_OTA = [
|
||||
for target in TESTING_TARGETS
|
||||
]
|
||||
|
||||
CONFIG_TEST = [
|
||||
# 'config, target, skip_autoflash, markers',
|
||||
('tee_ota', target, 'y', (pytest.mark.host_test,))
|
||||
for target in TESTING_TARGETS
|
||||
]
|
||||
|
||||
CONFIG_ALL = [
|
||||
# 'config, target, markers',
|
||||
(config, target, (pytest.mark.generic,))
|
||||
@@ -337,7 +343,7 @@ def tee_ota_stage_checks(dut: IdfDut, stage: TeeOtaStage, offset: str) -> None:
|
||||
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
CONFIG_TEST,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None:
|
||||
@@ -352,7 +358,7 @@ def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None:
|
||||
dut.write('"Test TEE OTA - Reboot without ending OTA"')
|
||||
|
||||
# OTA begin checks
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.BEGIN, '0x40000')
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.BEGIN, '0x50000')
|
||||
|
||||
# after reboot
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.REBOOT, '0x10000')
|
||||
@@ -360,7 +366,7 @@ def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None:
|
||||
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
CONFIG_TEST,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_valid_img(dut: IdfDut) -> None:
|
||||
@@ -375,23 +381,23 @@ def test_esp_tee_ota_valid_img(dut: IdfDut) -> None:
|
||||
dut.write('"Test TEE OTA - Valid image"')
|
||||
|
||||
# OTA begin checks
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.BEGIN, '0x40000')
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.BEGIN, '0x50000')
|
||||
dut.expect('TEE OTA update successful!', timeout=10)
|
||||
|
||||
# after reboot 1
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.REBOOT, '0x40000')
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.REBOOT, '0x50000')
|
||||
|
||||
# resetting device to check for image validity
|
||||
dut.serial.hard_reset()
|
||||
|
||||
# after reboot 2
|
||||
dut.expect('TEE otadata - Current image state: VALID', timeout=10)
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.REBOOT, '0x40000')
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.REBOOT, '0x50000')
|
||||
|
||||
|
||||
@idf_parametrize(
|
||||
'config, target, skip_autoflash, markers',
|
||||
CONFIG_OTA,
|
||||
CONFIG_TEST,
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
|
||||
@@ -406,12 +412,12 @@ def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
|
||||
dut.write('"Test TEE OTA - Rollback"')
|
||||
|
||||
# OTA begin checks
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.BEGIN, '0x40000')
|
||||
tee_ota_stage_checks(dut, TeeOtaStage.BEGIN, '0x50000')
|
||||
dut.expect('TEE OTA update successful!', timeout=10)
|
||||
|
||||
# after reboot 1
|
||||
dut.expect('TEE otadata - Current image state: NEW', timeout=10)
|
||||
dut.expect('Loaded TEE app from partition at offset 0x40000', timeout=10)
|
||||
dut.expect('Loaded TEE app from partition at offset 0x50000', timeout=10)
|
||||
rst_rsn = dut.expect(r'rst:(0x[0-9A-Fa-f]+) \(([^)]+)\)', timeout=10).group(2).decode()
|
||||
# NOTE: LP_WDT_SYS (C6/H2) and RTC_WDT_SYS (C5) are expected as bootloader fails to load the dummy TEE app
|
||||
if rst_rsn not in {'LP_WDT_SYS', 'RTC_WDT_SYS'}:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
tee, app, tee_0, , 192K,
|
||||
tee, app, tee_0, , 256K,
|
||||
secure_storage, data, nvs, , 64K,
|
||||
factory, app, factory, , 1536K,
|
||||
nvs, data, nvs, , 24K,
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
tee_0, app, tee_0, , 192K,
|
||||
tee_1, app, tee_1, , 192K,
|
||||
tee_0, app, tee_0, , 256K,
|
||||
tee_1, app, tee_1, , 256K,
|
||||
tee_otadata, data, tee_ota, , 8K,
|
||||
secure_storage, data, nvs, , 56K,
|
||||
ota_0, app, ota_0, , 1536K,
|
||||
|
||||
|
@@ -139,3 +139,27 @@ function(partition_table_add_check_bootloader_size_target target_name)
|
||||
bootloader ${BOOTLOADER_OFFSET} ${CMD_BOOTLOADER_BINARY_PATH})
|
||||
add_custom_target(${target_name} COMMAND ${command} DEPENDS ${CMD_DEPENDS})
|
||||
endfunction()
|
||||
|
||||
# Add a custom target (see add_custom_target) that checks a TEE binary
|
||||
# built by the build system will fit in the TEE partition.
|
||||
#
|
||||
# Adding the target doesn't mean it gets called during the build, use add_dependencies to make another
|
||||
# target depend on this one.
|
||||
#
|
||||
# Arguments:
|
||||
# - target name - (first argument) name of the target to create
|
||||
# - DEPENDS - dependencies the new target should have (i.e. whatever target generates the TEE binary)
|
||||
# - TEE_BINARY_PATH - path to TEE binary file
|
||||
#
|
||||
# Note: This function uses the PARTITION_TABLE_BIN_PATH variable which is passed from the parent
|
||||
# build to the TEE subproject via CMAKE_ARGS.
|
||||
function(partition_table_add_check_tee_size_target target_name)
|
||||
cmake_parse_arguments(CMD "" "TEE_BINARY_PATH" "DEPENDS" ${ARGN})
|
||||
idf_build_get_property(python PYTHON)
|
||||
|
||||
set(command ${python} ${PARTITION_TABLE_CHECK_SIZES_TOOL_PATH}
|
||||
--offset ${PARTITION_TABLE_OFFSET}
|
||||
partition --type app --subtype tee_0
|
||||
${PARTITION_TABLE_BIN_PATH} ${CMD_TEE_BINARY_PATH})
|
||||
add_custom_target(${target_name} COMMAND ${command} DEPENDS ${CMD_DEPENDS})
|
||||
endfunction()
|
||||
|
||||
Reference in New Issue
Block a user