mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
ci(esp_tee): Add tests for verifying behaviour for illegal flash accesses (SPI0)
This commit is contained in:
parent
1499c65754
commit
86125aeb98
@ -2,7 +2,7 @@ idf_build_get_property(idf_path IDF_PATH)
|
||||
|
||||
set(priv_requires bootloader_support driver esp_tee esp_timer mbedtls spi_flash)
|
||||
# Test FW related
|
||||
list(APPEND priv_requires cmock json test_utils unity)
|
||||
list(APPEND priv_requires cmock json nvs_flash test_utils unity)
|
||||
# TEE related
|
||||
list(APPEND priv_requires tee_sec_storage tee_attestation tee_ota_ops test_sec_srv)
|
||||
|
||||
@ -13,7 +13,8 @@ list(APPEND srcs "test_esp_tee_ctx_switch.c"
|
||||
"test_esp_tee_panic.c"
|
||||
"test_esp_tee_sec_stg.c"
|
||||
"test_esp_tee_ota.c"
|
||||
"test_esp_tee_att.c")
|
||||
"test_esp_tee_att.c"
|
||||
"test_esp_tee_flash_prot.c")
|
||||
|
||||
set(mbedtls_test_srcs_dir "${idf_path}/components/mbedtls/test_apps/main")
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
*/
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "unity.h"
|
||||
#include "memory_checks.h"
|
||||
|
||||
@ -42,5 +44,6 @@ static void test_task(void *pvParameters)
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
xTaskCreatePinnedToCore(test_task, "testTask", CONFIG_UNITY_FREERTOS_STACK_SIZE, NULL, CONFIG_UNITY_FREERTOS_PRIORITY, NULL, CONFIG_UNITY_FREERTOS_CPU);
|
||||
}
|
||||
|
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#include "esp_flash.h"
|
||||
#include "esp_rom_spiflash.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "esp_private/cache_utils.h"
|
||||
#include "esp_partition.h"
|
||||
#include "nvs_flash.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#include "secure_service_num.h"
|
||||
|
||||
#include "unity.h"
|
||||
|
||||
#define BOOT_COUNT_NAMESPACE "boot_count"
|
||||
|
||||
static const char *TAG = "test_esp_tee_flash_prot";
|
||||
|
||||
static void set_boot_count_in_nvs(uint8_t boot_count)
|
||||
{
|
||||
nvs_handle_t boot_count_handle;
|
||||
TEST_ESP_OK(nvs_open(BOOT_COUNT_NAMESPACE, NVS_READWRITE, &boot_count_handle));
|
||||
TEST_ESP_OK(nvs_set_u8(boot_count_handle, "boot_count", boot_count));
|
||||
TEST_ESP_OK(nvs_commit(boot_count_handle));
|
||||
nvs_close(boot_count_handle);
|
||||
}
|
||||
|
||||
static uint8_t get_boot_count_from_nvs(void)
|
||||
{
|
||||
nvs_handle_t boot_count_handle;
|
||||
esp_err_t err = nvs_open(BOOT_COUNT_NAMESPACE, NVS_READONLY, &boot_count_handle);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
set_boot_count_in_nvs(0);
|
||||
}
|
||||
uint8_t boot_count;
|
||||
TEST_ESP_OK(nvs_get_u8(boot_count_handle, "boot_count", &boot_count));
|
||||
nvs_close(boot_count_handle);
|
||||
return boot_count;
|
||||
}
|
||||
|
||||
static void test_initial_boot(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "Boot: 1");
|
||||
set_boot_count_in_nvs(1);
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- API family 1: esp_partition ------------------------------------------------- */
|
||||
|
||||
static void test_esp_partition_mmap_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;
|
||||
esp_partition_mmap_handle_t out_handle;
|
||||
const void *outptr = 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_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||
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_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_INST, &outptr, &out_handle));
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||
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_OTA, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||
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_SEC_STORAGE, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
TEST_ESP_OK(esp_partition_mmap(part, 0, part->size, ESP_PARTITION_MMAP_DATA, &outptr, &out_handle));
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, outptr, 0x20, ESP_LOG_INFO);
|
||||
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 - SPI0 (esp_partition_mmap)", "[flash_prot][timeout=60]",
|
||||
test_initial_boot, test_esp_partition_mmap_api, test_esp_partition_mmap_api,
|
||||
test_esp_partition_mmap_api, test_esp_partition_mmap_api);
|
||||
|
||||
/* ---------------------------------------------- API family 2: spi_flash ------------------------------------------------- */
|
||||
|
||||
static void test_spi_flash_mmap_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;
|
||||
spi_flash_mmap_handle_t handle;
|
||||
const void *ptr = 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_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_DATA, &ptr, &handle));
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
||||
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_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_INST, &ptr, &handle));
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
||||
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_OTA, NULL);
|
||||
TEST_ASSERT_NOT_NULL(part);
|
||||
TEST_ESP_OK(spi_flash_mmap(part->address, part->size, SPI_FLASH_MMAP_DATA, &ptr, &handle));
|
||||
ESP_LOG_BUFFER_HEXDUMP(TAG, ptr, 0x20, ESP_LOG_INFO);
|
||||
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 - 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);
|
@ -8,6 +8,8 @@
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/lp_analog_peri_reg.h"
|
||||
#include "soc/lp_wdt_reg.h"
|
||||
#include "soc/spi_mem_reg.h"
|
||||
#include "soc/ext_mem_defs.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -46,6 +48,15 @@ TEST_CASE("Test APM violation interrupt: eFuse", "[apm_violation]")
|
||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
||||
}
|
||||
|
||||
TEST_CASE("Test APM violation interrupt: MMU", "[apm_violation]")
|
||||
{
|
||||
uint32_t val = UINT32_MAX;
|
||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), SOC_MMU_ENTRY_NUM - 2);
|
||||
val = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0));
|
||||
TEST_ASSERT_EQUAL(0, val);
|
||||
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
||||
}
|
||||
|
||||
/* TEE IRAM: Reserved/Vector-table boundary */
|
||||
TEST_CASE("Test TEE-TEE violation: IRAM (W1)", "[exception]")
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ REE_ISOLATION_TEST_EXC_RSN: Dict[str, Any] = {
|
||||
}
|
||||
}
|
||||
|
||||
TEE_APM_VIOLATION_EXC_CHK = ['AES', 'eFuse']
|
||||
TEE_APM_VIOLATION_EXC_CHK = ['AES', 'eFuse', 'MMU']
|
||||
|
||||
# ---------------- TEE default tests ----------------
|
||||
|
||||
@ -134,6 +134,53 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None:
|
||||
raise RuntimeError('Incorrect exception received!')
|
||||
dut.expect('Exception origin: U-mode')
|
||||
|
||||
|
||||
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 stage != stages:
|
||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||
|
||||
|
||||
@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_mmap(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_mmap)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases))
|
||||
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_spi_flash_mmap(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 - SPI0 (spi_flash_mmap)':
|
||||
run_multiple_stages(dut, test_case.index, len(test_case.subcases))
|
||||
else:
|
||||
continue
|
||||
|
||||
# ---------------- TEE Local OTA tests ----------------
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user