mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 11:03:11 +00:00
Merge branch 'ci/esp_tee_fixes_v6.0' into 'release/v6.0'
feat(esp_tee): Miscellaneous fixes and improvements (v6.0) See merge request espressif/esp-idf!46800
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -27,6 +27,7 @@ extern "C" {
|
||||
#define ALIGN_UP_TO_MMU_PAGE_SIZE(addr) (((addr) + (SOC_MMU_PAGE_SIZE) - 1) & ~((SOC_MMU_PAGE_SIZE) - 1))
|
||||
#define ALIGN_DOWN_TO_MMU_PAGE_SIZE(addr) ((addr) & ~((SOC_MMU_PAGE_SIZE) - 1))
|
||||
|
||||
/* Alignment Checks */
|
||||
#if ((CONFIG_SECURE_TEE_IRAM_SIZE) & (0xFF))
|
||||
#error "CONFIG_SECURE_TEE_IRAM_SIZE must be 256-byte (0x100) aligned"
|
||||
#endif
|
||||
@@ -43,6 +44,14 @@ extern "C" {
|
||||
#error "CONFIG_SECURE_TEE_INTR_STACK_SIZE must be 16-byte (0x10) aligned"
|
||||
#endif
|
||||
|
||||
#if ((CONFIG_SECURE_TEE_IROM_SIZE) % SOC_MMU_PAGE_SIZE)
|
||||
#error "CONFIG_SECURE_TEE_IROM_SIZE must be a multiple of SOC_MMU_PAGE_SIZE"
|
||||
#endif
|
||||
|
||||
#if ((CONFIG_SECURE_TEE_DROM_SIZE) % SOC_MMU_PAGE_SIZE)
|
||||
#error "CONFIG_SECURE_TEE_DROM_SIZE must be a multiple of SOC_MMU_PAGE_SIZE"
|
||||
#endif
|
||||
|
||||
/* TEE Secure Storage partition label and NVS namespace */
|
||||
#define ESP_TEE_SEC_STG_PART_LABEL "secure_storage"
|
||||
#define ESP_TEE_SEC_STG_NVS_NAMESPACE "tee_sec_stg_ns"
|
||||
|
||||
@@ -222,7 +222,7 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *k
|
||||
return ESP_FAIL;
|
||||
}
|
||||
size_t pubkey_digest_len = 0;
|
||||
status = psa_hash_finish(&hash_op, pubkey_digest, len, &pubkey_digest_len);
|
||||
status = psa_hash_finish(&hash_op, pubkey_digest, sizeof(pubkey_digest), &pubkey_digest_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -236,8 +236,3 @@ ASSERT ((_tee_iram_end <= _tee_dram_start),
|
||||
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
|
||||
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
|
||||
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
|
||||
/* MMU Page Alignment Checks */
|
||||
ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % 0x10000) == 0,
|
||||
"Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!");
|
||||
ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % 0x10000) == 0,
|
||||
"Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!");
|
||||
|
||||
@@ -241,8 +241,3 @@ ASSERT ((_tee_iram_end <= _tee_dram_start),
|
||||
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
|
||||
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
|
||||
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
|
||||
/* MMU Page Alignment Checks */
|
||||
ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0,
|
||||
"Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!");
|
||||
ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0,
|
||||
"Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!");
|
||||
|
||||
@@ -14,6 +14,7 @@ extern int _tee_vec_end;
|
||||
extern int _tee_iram_start;
|
||||
extern int _tee_iram_end;
|
||||
extern int _tee_dram_start;
|
||||
extern int _tee_intr_stack;
|
||||
|
||||
typedef void (*func_ptr)(void);
|
||||
|
||||
@@ -64,13 +65,13 @@ static void do_stack_smash(bool underflow, int depth, volatile uint8_t *sink)
|
||||
|
||||
/* Underflow path */
|
||||
asm volatile(
|
||||
"li t0, 2048\n"
|
||||
"add sp, sp, t0\n"
|
||||
"mv sp, %0\n" :: "r"(&_tee_intr_stack)
|
||||
);
|
||||
|
||||
volatile uint8_t a = 1;
|
||||
volatile uint8_t b = a;
|
||||
(void)b;
|
||||
/* The blocking delay ensures that the stack protection fault interrupt is
|
||||
* captured and handled by the CPU before the current function returns.
|
||||
*/
|
||||
esp_rom_delay_us(10);
|
||||
}
|
||||
|
||||
void _ss_esp_tee_test_stack_overflow(void)
|
||||
|
||||
@@ -229,43 +229,74 @@ TEST_CASE("Test REE-TEE isolation: DROM-W1", "[exception]")
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
static void do_stack_smash(bool underflow, int depth, volatile uint8_t *sink)
|
||||
static void do_stack_overflow(int depth, volatile uint8_t *sink)
|
||||
{
|
||||
/* Overflow path */
|
||||
if (!underflow) {
|
||||
if (depth == -1) {
|
||||
return; // unreachable
|
||||
}
|
||||
|
||||
uint8_t buffer[1024];
|
||||
buffer[0] = (uint8_t)depth;
|
||||
*sink = buffer[0];
|
||||
|
||||
do_stack_smash(false, depth + 1, sink);
|
||||
return;
|
||||
if (depth == -1) {
|
||||
return; // unreachable
|
||||
}
|
||||
|
||||
/* Underflow path */
|
||||
asm volatile(
|
||||
"li t0, 4096\n"
|
||||
"add sp, sp, t0\n"
|
||||
uint8_t buffer[1024];
|
||||
buffer[0] = (uint8_t)depth;
|
||||
*sink = buffer[0];
|
||||
|
||||
do_stack_overflow(depth + 1, sink);
|
||||
}
|
||||
|
||||
static void __attribute__((noinline)) do_stack_underflow(void *underflow)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"mv sp, %0\n" :: "r"(underflow)
|
||||
);
|
||||
|
||||
volatile uint8_t temp = 1;
|
||||
(void)temp;
|
||||
/* The blocking delay ensures that the stack protection fault interrupt is
|
||||
* captured and handled by the CPU before the current function returns.
|
||||
*/
|
||||
esp_rom_delay_us(10);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
bool underflow;
|
||||
StackType_t *underflow_stack;
|
||||
} StackProtectionTaskArgs;
|
||||
|
||||
static void tStackProtection(void *pvParameters)
|
||||
{
|
||||
StackProtectionTaskArgs *tArgs = (StackProtectionTaskArgs *)pvParameters;
|
||||
|
||||
if (!tArgs->underflow) { /* Overflow path */
|
||||
volatile uint8_t sink = 0;
|
||||
do_stack_overflow(1, &sink);
|
||||
} else { /* Underflow path */
|
||||
do_stack_underflow((void *)tArgs->underflow_stack);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_stack_smash(bool underflow)
|
||||
{
|
||||
static struct {
|
||||
StackType_t StackBuffer[2048];
|
||||
StackType_t Underflow[1024];
|
||||
StackType_t UnderflowEnd[0];
|
||||
} tData;
|
||||
|
||||
static StaticTask_t TaskBuffer;
|
||||
static StackProtectionTaskArgs taskArgs;
|
||||
taskArgs.underflow = underflow;
|
||||
taskArgs.underflow_stack = tData.UnderflowEnd;
|
||||
|
||||
TaskHandle_t handle = xTaskCreateStatic(tStackProtection, "tStackProt", sizeof(tData.StackBuffer) / sizeof(StackType_t), &taskArgs, 10, tData.StackBuffer, &TaskBuffer);
|
||||
TEST_ASSERT_NULL(handle);
|
||||
}
|
||||
|
||||
TEST_CASE("Test REE stack overflow", "[exception]")
|
||||
{
|
||||
volatile uint8_t sink = 0;
|
||||
do_stack_smash(false, 1, &sink);
|
||||
do_stack_smash(false);
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
TEST_CASE("Test REE stack underflow", "[exception]")
|
||||
{
|
||||
volatile uint8_t sink = 0;
|
||||
do_stack_smash(true, 0, &sink);
|
||||
do_stack_smash(true);
|
||||
TEST_FAIL_MESSAGE("Exception should have been generated");
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,9 @@ def test_esp_tee_aes_perf(dut: IdfDut) -> None:
|
||||
def run_exception_case(
|
||||
dut: IdfDut, menu_prefix: str, test_name: str, expected: str, check_origin: bool = False
|
||||
) -> None:
|
||||
# Panics are expected during these tests
|
||||
dut.skip_decode_panic = True
|
||||
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write(f'"{menu_prefix}: {test_name}"')
|
||||
|
||||
@@ -137,6 +140,9 @@ def test_esp_tee_apm_violation(dut: IdfDut) -> None:
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_esp_tee_stack_smashing(dut: IdfDut) -> None:
|
||||
# Panics are expected during this test
|
||||
dut.skip_decode_panic = True
|
||||
|
||||
for env in ('REE', 'TEE'):
|
||||
for case in ('overflow', 'underflow'):
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
@@ -229,6 +235,9 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl
|
||||
|
||||
|
||||
def run_flash_access_test(dut: IdfDut, api: TeeFlashAccessApi, test_name: str) -> None:
|
||||
# Panics are expected during these tests
|
||||
dut.skip_decode_panic = True
|
||||
|
||||
dut.serial.custom_flash()
|
||||
|
||||
extra_data = dut._parse_test_menu()
|
||||
@@ -396,6 +405,9 @@ def test_esp_tee_ota_valid_img(dut: IdfDut) -> None:
|
||||
indirect=['config', 'target', 'skip_autoflash'],
|
||||
)
|
||||
def test_esp_tee_ota_rollback(dut: IdfDut) -> None:
|
||||
# Panics are expected during these tests
|
||||
dut.skip_decode_panic = True
|
||||
|
||||
# Flashing the TEE app to the non-secure app's passive partition
|
||||
dut.serial.custom_flash_w_test_tee_img_rb()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user