mirror of
https://github.com/espressif/esp-idf.git
synced 2026-07-15 15:33:02 +03:00
Merge branch 'fix/esp_tee_bbp_v5.5' into 'release/v5.5'
fix(esp_tee): Harden TEE secure services against REE manipulation (v5.5) See merge request espressif/esp-idf!49370
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
|
||||
*/
|
||||
@@ -20,6 +20,11 @@ extern "C" {
|
||||
#define TEE_SECURE_INUM (31)
|
||||
#if SOC_INT_CLIC_SUPPORTED
|
||||
#define TEE_PASS_INUM (30)
|
||||
/* CLIC: 3 effective priority bits (NLBITS=3), max priority = 7 */
|
||||
#define TEE_SECURE_INUM_PRIO (7)
|
||||
#else
|
||||
/* PLIC: 4-bit priority field, max priority = 15 */
|
||||
#define TEE_SECURE_INUM_PRIO (15)
|
||||
#endif
|
||||
|
||||
#define ESP_TEE_M2U_SWITCH_MAGIC 0xfedef
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "bootloader_utility_tee.h"
|
||||
#include "esp_tee_ota_utils.h"
|
||||
|
||||
@@ -17,6 +18,8 @@
|
||||
#include "esp_tee_flash.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
static const char *TAG = "esp_tee_flash";
|
||||
|
||||
// Structure containing the valid flash address range for flash operations through TEE
|
||||
@@ -169,8 +172,8 @@ esp_err_t esp_tee_flash_setup_prot_ctx(uint8_t tee_boot_part)
|
||||
if (subtype == PART_SUBTYPE_DATA_TEE_OTA) {
|
||||
needs_protection = true;
|
||||
} else if (subtype == PART_SUBTYPE_DATA_WIFI) {
|
||||
size_t label_len = strlen(ESP_TEE_SEC_STG_PART_LABEL);
|
||||
if (memcmp(partition_entry->partition.label, ESP_TEE_SEC_STG_PART_LABEL, label_len) == 0) {
|
||||
if (strncmp((const char *)partition_entry->partition.label, ESP_TEE_SEC_STG_PART_LABEL,
|
||||
sizeof(partition_entry->partition.label)) == 0) {
|
||||
needs_protection = true;
|
||||
}
|
||||
}
|
||||
@@ -241,3 +244,30 @@ bool esp_tee_flash_check_prange_in_active_tee_part(const size_t paddr, const siz
|
||||
|
||||
return ((paddr < tee_prot_ctx.active_part_end_paddr) && (paddr_end > tee_prot_ctx.active_part_start_paddr));
|
||||
}
|
||||
|
||||
bool esp_tee_flash_check_prange_write_protected(const size_t paddr, const size_t len)
|
||||
{
|
||||
size_t paddr_start = paddr;
|
||||
if (len == FLASH_SECTOR_SIZE || len == FLASH_BLOCK_SIZE) {
|
||||
paddr_start &= ~(len - 1);
|
||||
}
|
||||
|
||||
size_t paddr_end = paddr_start + len;
|
||||
if (paddr_end < paddr_start) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const size_t ptb_start = CONFIG_PARTITION_TABLE_OFFSET;
|
||||
const size_t ptb_end = ALIGN_UP(CONFIG_PARTITION_TABLE_OFFSET + ESP_PARTITION_TABLE_MAX_LEN, FLASH_SECTOR_SIZE);
|
||||
bool ptb_overlap = (paddr_start < ptb_end) && (paddr_end > ptb_start);
|
||||
|
||||
/* Bootloader: write-protected unless dangerous writes are explicitly allowed. */
|
||||
bool btl_overlap = false;
|
||||
#if !CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED
|
||||
const size_t btl_start = CONFIG_BOOTLOADER_OFFSET_IN_FLASH;
|
||||
const size_t btl_end = CONFIG_PARTITION_TABLE_OFFSET;
|
||||
btl_overlap = (paddr_start < btl_end) && (paddr_end > btl_start);
|
||||
#endif
|
||||
|
||||
return (ptb_overlap || btl_overlap);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -133,3 +133,15 @@ bool esp_tee_flash_check_prange_in_tee_region(const size_t paddr, const size_t l
|
||||
* @return bool true if any part of the range overlaps with active TEE partition, false otherwise
|
||||
*/
|
||||
bool esp_tee_flash_check_prange_in_active_tee_part(const size_t paddr, const size_t len);
|
||||
|
||||
/**
|
||||
* @brief Check if the given physical address range overlaps a write-protected flash region.
|
||||
* The partition table is always protected; the bootloader is protected unless
|
||||
* CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is set. Use only for write/erase operations.
|
||||
*
|
||||
* @param paddr Starting physical address of the range to check
|
||||
* @param len Length of the address range in bytes
|
||||
*
|
||||
* @return bool true if the range overlaps the write-protected region, false otherwise
|
||||
*/
|
||||
bool esp_tee_flash_check_prange_write_protected(const size_t paddr, const size_t len);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -53,7 +53,7 @@ int esp_tee_service_dispatcher(int argc, va_list ap)
|
||||
argc--;
|
||||
|
||||
const secure_service_entry_t *service = find_service_by_id(sid);
|
||||
if (service == NULL) {
|
||||
if (service == NULL || service->func == NULL) {
|
||||
ESP_LOGE(TAG, "Invalid service ID!");
|
||||
return ret;
|
||||
}
|
||||
@@ -71,13 +71,16 @@ int esp_tee_service_dispatcher(int argc, va_list ap)
|
||||
uint32_t *argp = &argv[0];
|
||||
|
||||
asm volatile(
|
||||
// Reserve outgoing-argument area for stack args 9+
|
||||
"addi sp, sp, -16 \n"
|
||||
|
||||
"mv t0, %1 \n" // t0 = argc
|
||||
"mv t1, %3 \n" // t1 = argp
|
||||
|
||||
"li t2, 8 \n" // t2 = 8 (max register args)
|
||||
"ble t0, t2, load_regs \n" // If argc <= 8 (a0-a7), skip stack routine
|
||||
|
||||
// Store extra args (argc > 8) on stack
|
||||
// Store extra args (argc > 8) on the reserved area
|
||||
"mv t3, sp \n"
|
||||
"addi t1, t1, 32 \n"
|
||||
|
||||
@@ -87,7 +90,7 @@ int esp_tee_service_dispatcher(int argc, va_list ap)
|
||||
"addi t1, t1, 4 \n"
|
||||
"addi t3, t3, 4 \n"
|
||||
"addi t0, t0, -1 \n"
|
||||
"bge t0, t2, stack_loop \n"
|
||||
"bgt t0, t2, stack_loop \n"
|
||||
|
||||
// Load the first 8 arguments into a0-a7
|
||||
"load_regs: \n"
|
||||
@@ -104,10 +107,13 @@ int esp_tee_service_dispatcher(int argc, va_list ap)
|
||||
"mv t1, %2 \n" // Load function pointer
|
||||
"jalr 0(t1) \n" // Call function
|
||||
"mv %0, a0 \n" // Store return value
|
||||
|
||||
// Restore the outgoing-argument area
|
||||
"addi sp, sp, 16 \n"
|
||||
: "=r"(ret)
|
||||
: "r"(argc), "r"(fp_secure_service), "r"(argp)
|
||||
: "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
|
||||
"t0", "t1", "t2", "t3", "t4"
|
||||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "ra", "memory"
|
||||
);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -358,10 +358,15 @@ esp_err_t _ss_esp_hmac_jtag_disable(void)
|
||||
|
||||
static size_t get_ds_msg_sign_len(esp_digital_signature_length_t rsa_length)
|
||||
{
|
||||
if (rsa_length != ESP_DS_RSA_1024 && rsa_length != ESP_DS_RSA_2048 &&
|
||||
rsa_length != ESP_DS_RSA_3072 && rsa_length != ESP_DS_RSA_4096) {
|
||||
|
||||
if (rsa_length != ESP_DS_RSA_1024 && rsa_length != ESP_DS_RSA_2048 && rsa_length != ESP_DS_RSA_3072
|
||||
#if SOC_DS_SIGNATURE_MAX_BIT_LEN == 4096
|
||||
&& rsa_length != ESP_DS_RSA_4096
|
||||
#endif
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (size_t)(rsa_length + 1) * 4;
|
||||
}
|
||||
|
||||
@@ -397,6 +402,7 @@ esp_err_t _ss_esp_ds_start_sign(const void *message,
|
||||
esp_ds_context_t **esp_ds_ctx)
|
||||
{
|
||||
bool valid_addr = (esp_tee_buf_in_ree(esp_ds_ctx, sizeof(esp_ds_context_t *)) &&
|
||||
esp_tee_buf_in_ree(*esp_ds_ctx, sizeof(esp_ds_context_t)) &&
|
||||
esp_tee_buf_in_ree(data, sizeof(esp_ds_data_t)));
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -425,8 +431,16 @@ bool _ss_esp_ds_is_busy(void)
|
||||
|
||||
esp_err_t _ss_esp_ds_finish_sign(void *signature, esp_ds_context_t *esp_ds_ctx)
|
||||
{
|
||||
const size_t max_sign = get_ds_msg_sign_len(ESP_DS_RSA_4096);
|
||||
bool valid_addr = esp_tee_buf_in_ree(signature, max_sign);
|
||||
const size_t max_sign = SOC_DS_SIGNATURE_MAX_BIT_LEN / 8;
|
||||
bool valid_addr = (esp_tee_buf_in_ree(signature, max_sign) &&
|
||||
esp_tee_buf_in_ree(esp_ds_ctx, sizeof(esp_ds_context_t)));
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const esp_ds_data_t *data = (const esp_ds_data_t *)esp_ds_ctx->data;
|
||||
valid_addr &= esp_tee_buf_in_ree(data, sizeof(esp_ds_data_t)) &&
|
||||
(get_ds_msg_sign_len(data->rsa_length) > 0);
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
@@ -17,10 +18,12 @@
|
||||
#include "hal/spi_flash_hal.h"
|
||||
#include "hal/spi_flash_types.h"
|
||||
#include "spi_flash_chip_generic.h"
|
||||
#include "spi_flash/spi_flash_defs.h"
|
||||
#include "memspi_host_driver.h"
|
||||
#include "esp_private/mspi_timing_tuning.h"
|
||||
#include "esp_flash.h"
|
||||
#include "riscv/rv_utils.h"
|
||||
#include "soc/soc.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_memory_utils.h"
|
||||
@@ -35,28 +38,49 @@ static __attribute__((unused)) const char *TAG = "esp_tee_sec_srv_iram";
|
||||
|
||||
/* ---------------------------------------------- Interrupts ------------------------------------------------- */
|
||||
|
||||
#if SOC_INT_CLIC_SUPPORTED
|
||||
#define TEE_RESERVED_INTR_MASK ((1U << TEE_SECURE_INUM) | (1U << TEE_PASS_INUM))
|
||||
#else
|
||||
#define TEE_RESERVED_INTR_MASK ((1U << TEE_SECURE_INUM))
|
||||
#endif
|
||||
|
||||
static inline bool is_intr_num_invalid(uint32_t intr_num)
|
||||
{
|
||||
return (intr_num >= (uint32_t)SOC_CPU_INTR_NUM) ||
|
||||
(((1U << intr_num) & TEE_RESERVED_INTR_MASK) != 0U);
|
||||
}
|
||||
|
||||
void _ss_esp_rom_route_intr_matrix(int cpu_no, uint32_t model_num, uint32_t intr_num)
|
||||
{
|
||||
if (is_intr_num_invalid(intr_num)) {
|
||||
return;
|
||||
}
|
||||
return esp_tee_route_intr_matrix(cpu_no, model_num, intr_num);
|
||||
}
|
||||
|
||||
void _ss_rv_utils_intr_enable(uint32_t intr_mask)
|
||||
{
|
||||
rv_utils_tee_intr_enable(intr_mask);
|
||||
rv_utils_tee_intr_enable(intr_mask & ~TEE_RESERVED_INTR_MASK);
|
||||
}
|
||||
|
||||
void _ss_rv_utils_intr_disable(uint32_t intr_mask)
|
||||
{
|
||||
rv_utils_tee_intr_disable(intr_mask);
|
||||
rv_utils_tee_intr_disable(intr_mask & ~TEE_RESERVED_INTR_MASK);
|
||||
}
|
||||
|
||||
void _ss_rv_utils_intr_set_priority(int rv_int_num, int priority)
|
||||
{
|
||||
if (is_intr_num_invalid((uint32_t)rv_int_num)) {
|
||||
return;
|
||||
}
|
||||
rv_utils_tee_intr_set_priority(rv_int_num, priority);
|
||||
}
|
||||
|
||||
void _ss_rv_utils_intr_set_type(int intr_num, enum intr_type type)
|
||||
{
|
||||
if (is_intr_num_invalid((uint32_t)intr_num)) {
|
||||
return;
|
||||
}
|
||||
rv_utils_tee_intr_set_type(intr_num, type);
|
||||
}
|
||||
|
||||
@@ -67,6 +91,9 @@ void _ss_rv_utils_intr_set_threshold(int priority_threshold)
|
||||
|
||||
void _ss_rv_utils_intr_edge_ack(uint32_t intr_num)
|
||||
{
|
||||
if (is_intr_num_invalid(intr_num)) {
|
||||
return;
|
||||
}
|
||||
rv_utils_intr_edge_ack(intr_num);
|
||||
}
|
||||
|
||||
@@ -107,6 +134,9 @@ void _ss_rv_utils_wfe_mode_enable(bool en)
|
||||
#if SOC_INT_CLIC_SUPPORTED
|
||||
void _ss_esprv_int_set_vectored(int rv_int_num, bool vectored)
|
||||
{
|
||||
if (is_intr_num_invalid((uint32_t)rv_int_num)) {
|
||||
return;
|
||||
}
|
||||
esprv_int_set_vectored(rv_int_num, vectored);
|
||||
}
|
||||
#endif
|
||||
@@ -290,16 +320,31 @@ void _ss_Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size)
|
||||
#if CONFIG_SECURE_TEE_EXT_FLASH_MEMPROT_SPI1
|
||||
/* ---------------------------------------------- SPI Flash HAL ------------------------------------------------- */
|
||||
|
||||
#define FLASH_ADDR_MAX_24BIT (0xFFFFFFU)
|
||||
|
||||
static bool is_flash_addr_writable(uint32_t paddr, uint32_t len)
|
||||
{
|
||||
return !esp_tee_flash_check_prange_in_tee_region(paddr, len) &&
|
||||
!esp_tee_flash_check_prange_write_protected(paddr, len);
|
||||
}
|
||||
|
||||
static bool is_flash_addr_readable(uint32_t paddr, uint32_t len)
|
||||
{
|
||||
return !esp_tee_flash_check_prange_in_tee_region(paddr, len);
|
||||
}
|
||||
|
||||
static bool is_spi_host_in_ree(spi_flash_host_inst_t *host)
|
||||
{
|
||||
return esp_tee_buf_in_ree(host, sizeof(spi_flash_host_inst_t));
|
||||
return esp_tee_buf_in_ree(host, sizeof(spi_flash_hal_context_t));
|
||||
}
|
||||
|
||||
static bool is_spi_trans_valid(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
|
||||
{
|
||||
bool valid_addr = (is_spi_host_in_ree(host) &&
|
||||
esp_tee_buf_in_ree(trans, sizeof(spi_flash_trans_t)));
|
||||
if (!is_spi_host_in_ree(host) || !esp_tee_buf_in_ree(trans, sizeof(spi_flash_trans_t))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid_addr = true;
|
||||
if (trans->mosi_len != 0) {
|
||||
valid_addr &= esp_tee_buf_in_ree(trans->mosi_data, trans->mosi_len);
|
||||
}
|
||||
@@ -309,6 +354,37 @@ static bool is_spi_trans_valid(spi_flash_host_inst_t *host, spi_flash_trans_t *t
|
||||
return valid_addr;
|
||||
}
|
||||
|
||||
static bool is_spi_cmd_addr_ok(uint32_t addr_bitlen, uint32_t address, uint32_t mosi_len, uint32_t miso_len)
|
||||
{
|
||||
if (addr_bitlen == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (addr_bitlen < 32U && address > ((1U << addr_bitlen) - 1U)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t data_len = MAX(1, MAX(mosi_len, miso_len));
|
||||
return is_flash_addr_writable(address, data_len);
|
||||
}
|
||||
|
||||
extern void spi_flash_hal_poll_cmd_done(spi_flash_host_inst_t *host);
|
||||
extern esp_err_t spi_flash_hal_configure_host_io_mode(spi_flash_host_inst_t *host, uint32_t command,
|
||||
uint32_t addr_bitlen, int dummy_cyclelen_base,
|
||||
esp_flash_io_mode_t io_mode);
|
||||
|
||||
static const spi_flash_host_driver_t tee_host_driver = {
|
||||
.poll_cmd_done = spi_flash_hal_poll_cmd_done,
|
||||
.configure_host_io_mode = spi_flash_hal_configure_host_io_mode,
|
||||
};
|
||||
|
||||
static inline const spi_flash_host_driver_t *tee_substitute_host_driver(spi_flash_host_inst_t *host)
|
||||
{
|
||||
const spi_flash_host_driver_t *orig = host->driver;
|
||||
host->driver = &tee_host_driver;
|
||||
return orig;
|
||||
}
|
||||
|
||||
uint32_t _ss_spi_flash_hal_check_status(spi_flash_host_inst_t *host)
|
||||
{
|
||||
bool valid_addr = is_spi_host_in_ree(host);
|
||||
@@ -323,17 +399,23 @@ uint32_t _ss_spi_flash_hal_check_status(spi_flash_host_inst_t *host)
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_trans_t *trans)
|
||||
{
|
||||
bool valid_addr = (is_spi_trans_valid(host, trans) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(trans->address, trans->mosi_len) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(trans->address, trans->miso_len));
|
||||
bool trans_valid = is_spi_trans_valid(host, trans);
|
||||
if (!trans_valid) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_FAULT_ASSERT(trans_valid);
|
||||
|
||||
if (!valid_addr) {
|
||||
bool addr_ok = is_spi_cmd_addr_ok(trans->address_bitlen, trans->address, trans->mosi_len, trans->miso_len);
|
||||
if (!addr_ok) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, trans->address);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
ESP_FAULT_ASSERT(addr_ok);
|
||||
|
||||
return spi_flash_hal_common_command(host, trans);
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
esp_err_t r = spi_flash_hal_common_command(host, trans);
|
||||
host->driver = orig;
|
||||
return r;
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_device_config(spi_flash_host_inst_t *host)
|
||||
@@ -351,7 +433,8 @@ esp_err_t _ss_spi_flash_hal_device_config(spi_flash_host_inst_t *host)
|
||||
void _ss_spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_address)
|
||||
{
|
||||
bool valid_addr = (is_spi_host_in_ree(host) &&
|
||||
!esp_tee_flash_check_paddr_in_tee_region(start_address));
|
||||
start_address <= FLASH_ADDR_MAX_24BIT &&
|
||||
is_flash_addr_writable(start_address, FLASH_BLOCK_SIZE));
|
||||
|
||||
if (!valid_addr) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
|
||||
@@ -359,13 +442,16 @@ void _ss_spi_flash_hal_erase_block(spi_flash_host_inst_t *host, uint32_t start_a
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
spi_flash_hal_erase_block(host, start_address);
|
||||
host->driver = orig;
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_address)
|
||||
{
|
||||
bool valid_addr = (is_spi_host_in_ree(host) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(start_address, FLASH_SECTOR_SIZE));
|
||||
start_address <= FLASH_ADDR_MAX_24BIT &&
|
||||
is_flash_addr_writable(start_address, FLASH_SECTOR_SIZE));
|
||||
|
||||
if (!valid_addr) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, start_address);
|
||||
@@ -373,13 +459,16 @@ void _ss_spi_flash_hal_erase_sector(spi_flash_host_inst_t *host, uint32_t start_
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
spi_flash_hal_erase_sector(host, start_address);
|
||||
host->driver = orig;
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buffer, uint32_t address, uint32_t length)
|
||||
{
|
||||
bool valid_addr = (is_spi_host_in_ree(host) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(address, length) &&
|
||||
address <= FLASH_ADDR_MAX_24BIT &&
|
||||
is_flash_addr_writable(address, length) &&
|
||||
esp_tee_buf_in_ree(buffer, length));
|
||||
|
||||
if (!valid_addr) {
|
||||
@@ -388,13 +477,15 @@ void _ss_spi_flash_hal_program_page(spi_flash_host_inst_t *host, const void *buf
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
spi_flash_hal_program_page(host, buffer, address, length);
|
||||
host->driver = orig;
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t address, uint32_t read_len)
|
||||
{
|
||||
bool valid_addr = (is_spi_host_in_ree(host) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(address, read_len) &&
|
||||
is_flash_addr_readable(address, read_len) &&
|
||||
esp_tee_buf_in_ree(buffer, read_len));
|
||||
|
||||
if (!valid_addr) {
|
||||
@@ -403,7 +494,10 @@ esp_err_t _ss_spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return spi_flash_hal_read(host, buffer, address, read_len);
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
esp_err_t r = spi_flash_hal_read(host, buffer, address, read_len);
|
||||
host->driver = orig;
|
||||
return r;
|
||||
}
|
||||
|
||||
void _ss_spi_flash_hal_resume(spi_flash_host_inst_t *host)
|
||||
@@ -415,7 +509,9 @@ void _ss_spi_flash_hal_resume(spi_flash_host_inst_t *host)
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
spi_flash_hal_resume(host);
|
||||
host->driver = orig;
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp)
|
||||
@@ -427,7 +523,10 @@ esp_err_t _ss_spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return spi_flash_hal_set_write_protect(host, wp);
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
esp_err_t r = spi_flash_hal_set_write_protect(host, wp);
|
||||
host->driver = orig;
|
||||
return r;
|
||||
}
|
||||
|
||||
esp_err_t _ss_spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const spi_flash_sus_cmd_conf *sus_conf)
|
||||
@@ -476,7 +575,9 @@ void _ss_spi_flash_hal_suspend(spi_flash_host_inst_t *host)
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
spi_flash_hal_suspend(host);
|
||||
host->driver = orig;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------- SPI Flash Extras ------------------------------------------------- */
|
||||
@@ -485,6 +586,22 @@ extern uint32_t bootloader_flash_execute_command_common(uint8_t command, uint32_
|
||||
uint8_t dummy_len, uint8_t mosi_len, uint32_t mosi_data,
|
||||
uint8_t miso_len);
|
||||
|
||||
static inline bool ree_flash_cmd_allowed(uint8_t cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CMD_WRSR3: /* 0x11 - write status register 3 */
|
||||
case CMD_RDSR3: /* 0x15 - read status register 3 */
|
||||
case CMD_WRENVSR: /* 0x50 - write enable for volatile SR */
|
||||
case CMD_WRAP: /* 0x77 - flash wrap enable/clear (alt) */
|
||||
case CMD_RDID: /* 0x9F - read chip ID */
|
||||
case CMD_HPMEN: /* 0xA3 - HPM enable via command */
|
||||
case CMD_BURST_RD: /* 0xC0 - flash wrap enable/clear */
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t _ss_bootloader_flash_execute_command_common(
|
||||
uint8_t command,
|
||||
uint32_t addr_len, uint32_t address,
|
||||
@@ -492,14 +609,18 @@ uint32_t _ss_bootloader_flash_execute_command_common(
|
||||
uint8_t mosi_len, uint32_t mosi_data,
|
||||
uint8_t miso_len)
|
||||
{
|
||||
bool valid_addr = (!esp_tee_flash_check_prange_in_tee_region(address, mosi_len) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(address, miso_len));
|
||||
if (!ree_flash_cmd_allowed(command)) {
|
||||
ESP_LOGD(TAG, "[%s] Disallowed flash command 0x%02x from REE", __func__, command);
|
||||
return 0;
|
||||
}
|
||||
ESP_FAULT_ASSERT(ree_flash_cmd_allowed(command));
|
||||
|
||||
if (!valid_addr) {
|
||||
bool addr_ok = is_spi_cmd_addr_ok(addr_len, address, mosi_len / 8U, miso_len / 8U);
|
||||
if (!addr_ok) {
|
||||
ESP_LOGD(TAG, "[%s] Illegal flash access at 0x%08x", __func__, address);
|
||||
return 0;
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
ESP_FAULT_ASSERT(addr_ok);
|
||||
|
||||
return bootloader_flash_execute_command_common(command, addr_len, address, dummy_len,
|
||||
mosi_len, mosi_data, miso_len);
|
||||
@@ -508,7 +629,7 @@ uint32_t _ss_bootloader_flash_execute_command_common(
|
||||
esp_err_t _ss_memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr, uint32_t size)
|
||||
{
|
||||
bool valid_addr = (is_spi_host_in_ree(host) &&
|
||||
!esp_tee_flash_check_prange_in_tee_region(addr, size));
|
||||
is_flash_addr_readable(addr, size));
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -520,14 +641,25 @@ esp_err_t _ss_memspi_host_flush_cache(spi_flash_host_inst_t *host, uint32_t addr
|
||||
|
||||
esp_err_t _ss_spi_flash_chip_generic_config_host_io_mode(esp_flash_t *chip, uint32_t flags)
|
||||
{
|
||||
bool valid_addr = esp_tee_buf_in_ree(chip, sizeof(struct esp_flash_t));
|
||||
spi_flash_host_inst_t *host = NULL;
|
||||
bool valid_addr = (esp_tee_buf_in_ree(chip, sizeof(struct esp_flash_t)) &&
|
||||
is_spi_host_in_ree((host = chip->host)));
|
||||
|
||||
if (!valid_addr) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return spi_flash_chip_generic_config_host_io_mode(chip, flags);
|
||||
esp_flash_t chip_snap = {
|
||||
.host = host,
|
||||
.read_mode = chip->read_mode,
|
||||
.hpm_dummy_ena = chip->hpm_dummy_ena,
|
||||
};
|
||||
|
||||
const spi_flash_host_driver_t *orig = tee_substitute_host_driver(host);
|
||||
esp_err_t r = spi_flash_chip_generic_config_host_io_mode(&chip_snap, flags);
|
||||
host->driver = orig;
|
||||
return r;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32C5
|
||||
|
||||
@@ -38,8 +38,13 @@ FORCE_INLINE_ATTR bool esp_tee_buf_in_ree(const void *p, size_t len)
|
||||
return false;
|
||||
}
|
||||
|
||||
return esp_tee_ptr_in_ree(p) &&
|
||||
esp_tee_ptr_in_ree((const char *)p + len - 1);
|
||||
uintptr_t end = start + len;
|
||||
return ((start >= SOC_NS_IDRAM_START && end <= SOC_NS_IDRAM_END) ||
|
||||
(start >= (uintptr_t)esp_tee_app_config.ns_drom_start && end <= SOC_S_MMU_MMAP_RESV_START_VADDR)
|
||||
#if SOC_RTC_MEM_SUPPORTED
|
||||
|| (start >= SOC_RTC_DATA_LOW && end <= SOC_RTC_DATA_HIGH)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -70,14 +70,9 @@ void esp_tee_soc_secure_sys_init(void)
|
||||
REG_CLR_BIT(DR_REG_INTMTX_BASE + 4 * i, BIT(8));
|
||||
}
|
||||
|
||||
/* TODO: IDF-8958
|
||||
* The values for the secure interrupt number and priority and
|
||||
* the interrupt priority threshold (for both M and U mode) need
|
||||
* to be investigated further
|
||||
*/
|
||||
esprv_int_set_threshold(0);
|
||||
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, TEE_SECURE_INUM_PRIO);
|
||||
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
||||
esprv_int_set_vectored(TEE_SECURE_INUM, true);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -68,13 +68,7 @@ void esp_tee_soc_secure_sys_init(void)
|
||||
esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM);
|
||||
}
|
||||
|
||||
/* TODO: IDF-8958
|
||||
* The values for the secure interrupt number and priority and
|
||||
* the interrupt priority threshold (for both M and U mode) need
|
||||
* to be investigated further
|
||||
*/
|
||||
/* TODO: Currently, we do not allow interrupts to be set up with a priority greater than 7, see intr_alloc.c */
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, TEE_SECURE_INUM_PRIO);
|
||||
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||
esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH);
|
||||
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -68,18 +68,10 @@ void esp_tee_soc_secure_sys_init(void)
|
||||
esp_rom_route_intr_matrix(core_id, i, ETS_INVALID_INUM);
|
||||
}
|
||||
|
||||
/* TODO: IDF-8958
|
||||
* The values for the secure interrupt number and priority and
|
||||
* the interrupt priority threshold (for both M and U mode) need
|
||||
* to be investigated further
|
||||
*/
|
||||
#ifdef SOC_CPU_HAS_FLEXIBLE_INTC
|
||||
/* TODO: Currently, we do not allow interrupts to be set up with a priority greater than 7, see intr_alloc.c */
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, 7);
|
||||
esprv_int_set_priority(TEE_SECURE_INUM, TEE_SECURE_INUM_PRIO);
|
||||
esprv_int_set_type(TEE_SECURE_INUM, ESP_CPU_INTR_TYPE_LEVEL);
|
||||
esprv_int_set_threshold(RVHAL_INTR_ENABLE_THRESH);
|
||||
esprv_int_enable(BIT(TEE_SECURE_INUM));
|
||||
#endif
|
||||
|
||||
ESP_LOGD(TAG, "Initial interrupt config -");
|
||||
ESP_LOGD(TAG, "mideleg: 0x%08x", RV_READ_CSR(mideleg));
|
||||
|
||||
Reference in New Issue
Block a user