forked from espressif/esp-idf
fix(esp_tee): Place APM HAL in TEE IRAM when SPI1 protection is enabled
- Place the APM HAL into TEE IRAM when `CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1` is enabled, as APM violations related to SPI1 can occur with the flash cache disabled. - Also fix an issue where flash protection tests were passing due to incorrect checks
This commit is contained in:
@@ -170,7 +170,7 @@ SECTIONS
|
|||||||
* | MMU | text+rodata | SRAM |
|
* | MMU | text+rodata | SRAM |
|
||||||
* | CACHE | text+rodata | SRAM |
|
* | CACHE | text+rodata | SRAM |
|
||||||
* | WDT | text | SRAM |
|
* | WDT | text | SRAM |
|
||||||
* | APM | text | Flash |
|
* | APM | text | Flash* |
|
||||||
* | AES | text | Flash |
|
* | AES | text | Flash |
|
||||||
* | SHA | text | Flash |
|
* | SHA | text | Flash |
|
||||||
* | HMAC | text | Flash |
|
* | HMAC | text | Flash |
|
||||||
@@ -198,7 +198,11 @@ SECTIONS
|
|||||||
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
|
*libhal.a:hmac_hal.c*(.literal .text .literal.* .text.*)
|
||||||
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
|
*libhal.a:ds_hal.c*(.literal .text .literal.* .text.*)
|
||||||
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
|
*libhal.a:ecc_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
/* NOTE: There is a possibility of APM violations (SPI1 flash protection)
|
||||||
|
* being triggered with the flash cache disabled */
|
||||||
|
#if !CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||||
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
|
*libhal.a:apm_hal.c*(.literal .text .literal.* .text.*)
|
||||||
|
#endif
|
||||||
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
|
*libhal.a:brownout_hal.c*(.literal .text .literal.* .text.*)
|
||||||
*libhal.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
|
*libhal.a:spi_flash_hal.c*(.literal .text .literal.* .text.*)
|
||||||
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
|
/* These HAL modules have functions marked with the IRAM_ATTR attribute which get placed in the SRAM */
|
||||||
|
@@ -155,47 +155,45 @@ class TeeFlashAccessApi(Enum):
|
|||||||
ESP_ROM_SPIFLASH = 5
|
ESP_ROM_SPIFLASH = 5
|
||||||
|
|
||||||
|
|
||||||
def check_panic_or_reset(dut: IdfDut) -> None:
|
def expect_panic_rsn(dut: IdfDut, expected_rsn: str) -> None:
|
||||||
try:
|
actual_rsn = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=10).group(2).decode()
|
||||||
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=5).group(2).decode()
|
if actual_rsn != expected_rsn:
|
||||||
if exc not in {'Cache error', 'APM - Authority exception'}:
|
raise RuntimeError(f'Incorrect exception: {actual_rsn} (expected: {expected_rsn})')
|
||||||
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:
|
def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFlashAccessApi) -> None:
|
||||||
exp_seq = {
|
expected_ops = {
|
||||||
TeeFlashAccessApi.ESP_PARTITION: ['read', 'program_page', 'program_page', 'erase_sector'],
|
TeeFlashAccessApi.ESP_PARTITION: ['read', 'program_page', 'program_page', 'erase_sector'],
|
||||||
TeeFlashAccessApi.ESP_FLASH: ['program_page', 'read', 'erase_sector', 'program_page'],
|
TeeFlashAccessApi.ESP_FLASH: ['program_page', 'read', 'erase_sector', 'program_page'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flash_enc_enabled = dut.app.sdkconfig.get('SECURE_FLASH_ENC_ENABLED', True)
|
||||||
|
|
||||||
for stage in range(1, stages + 1):
|
for stage in range(1, stages + 1):
|
||||||
dut.write(str(test_case_num))
|
dut.write(str(test_case_num))
|
||||||
dut.expect(r'\s+\((\d+)\)\s+"([^"]+)"\r?\n', timeout=30)
|
dut.expect(r'\s+\((\d+)\)\s+"([^"]+)"\r?\n', timeout=30)
|
||||||
dut.write(str(stage))
|
dut.write(str(stage))
|
||||||
|
|
||||||
if 1 < stage <= stages:
|
if stage > 1:
|
||||||
if api in exp_seq:
|
if api in {TeeFlashAccessApi.ESP_PARTITION_MMAP, TeeFlashAccessApi.SPI_FLASH_MMAP}:
|
||||||
try:
|
expect_panic_rsn(dut, 'Cache error')
|
||||||
match = dut.expect(
|
elif api in {TeeFlashAccessApi.ESP_PARTITION, TeeFlashAccessApi.ESP_FLASH}:
|
||||||
r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=5
|
op_index = stage - 2
|
||||||
)
|
curr_op = expected_ops[api][op_index]
|
||||||
fault_api = match.group(1).decode()
|
if api == TeeFlashAccessApi.ESP_PARTITION and curr_op == 'read' and flash_enc_enabled:
|
||||||
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
|
# NOTE: The esp_partition_read API handles both decrypted
|
||||||
# and plaintext reads. When flash encryption is enabled,
|
# and plaintext reads. When flash encryption is enabled,
|
||||||
# it uses the MMU HAL instead of the SPI flash HAL.
|
# it uses the MMU HAL instead of the SPI flash HAL.
|
||||||
exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=5).group(2).decode()
|
expect_panic_rsn(dut, 'Cache error')
|
||||||
if exc != 'Cache error':
|
|
||||||
raise RuntimeError('Flash operation incorrect exception')
|
|
||||||
else:
|
else:
|
||||||
check_panic_or_reset(dut)
|
match = dut.expect(
|
||||||
|
r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=10
|
||||||
|
)
|
||||||
|
actual_op = match.group(1).decode()
|
||||||
|
if actual_op != curr_op:
|
||||||
|
raise RuntimeError(f'Unexpected flash operation: {actual_op} (expected: {curr_op})')
|
||||||
|
elif api == TeeFlashAccessApi.ESP_ROM_SPIFLASH:
|
||||||
|
expect_panic_rsn(dut, 'APM - Authority exception')
|
||||||
|
|
||||||
if stage != stages:
|
if stage != stages:
|
||||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||||
|
Reference in New Issue
Block a user