From c9f7bcd452436679b8341b9cbd47a395f568698e Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Wed, 30 Apr 2025 11:57:10 +0530 Subject: [PATCH] feat(esp_tee): Support the `nvs_flash` for the ESP-TEE build --- components/esp_partition/CMakeLists.txt | 16 ++- components/esp_partition/partition_tee.c | 136 ++++++++++++++++++ .../subproject/main/ld/esp32c6/esp_tee.ld.in | 7 + .../mbedtls/esp_tee/esp_tee_mbedtls.cmake | 1 + .../mbedtls/esp_tee/esp_tee_mbedtls_config.h | 2 + components/nvs_flash/CMakeLists.txt | 31 +++- components/nvs_flash/src/nvs_api.cpp | 2 + .../nvs_flash/src/nvs_memory_management.hpp | 2 + components/nvs_flash/src/nvs_page.cpp | 4 +- components/nvs_flash/src/nvs_platform.cpp | 2 +- 10 files changed, 197 insertions(+), 6 deletions(-) create mode 100644 components/esp_partition/partition_tee.c diff --git a/components/esp_partition/CMakeLists.txt b/components/esp_partition/CMakeLists.txt index 624681a367..0f40bd55b0 100644 --- a/components/esp_partition/CMakeLists.txt +++ b/components/esp_partition/CMakeLists.txt @@ -1,3 +1,5 @@ +idf_build_get_property(esp_tee_build ESP_TEE_BUILD) + # bootloader build simplified version if(BOOTLOADER_BUILD) set(srcs "partition_bootloader.c") @@ -10,7 +12,19 @@ idf_component_register(SRCS "${srcs}" REQUIRES ${reqs} PRIV_REQUIRES ${priv_reqs}) -# regular, non bootloader build +# esp-tee build simplified version +elseif(esp_tee_build) +set(srcs "partition_tee.c") +set(reqs "spi_flash") +set(priv_reqs "tee_flash_mgr") + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include" + PRIV_INCLUDE_DIRS ${private_include_dirs} + REQUIRES ${reqs} + PRIV_REQUIRES ${priv_reqs}) + +# regular, OS build else() set(srcs "partition.c") set(priv_reqs esp_system spi_flash partition_table) diff --git a/components/esp_partition/partition_tee.c b/components/esp_partition/partition_tee.c new file mode 100644 index 0000000000..c3fcd28cbb --- /dev/null +++ b/components/esp_partition/partition_tee.c @@ -0,0 +1,136 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_partition.h" +#include "spi_flash_mmap.h" +#include "esp_tee_flash.h" +#include "esp_log.h" + +static __attribute__((unused)) const char *TAG = "partition_tee"; + +const esp_partition_t *esp_partition_find_first(esp_partition_type_t type, esp_partition_subtype_t subtype, const char* label) +{ + static esp_partition_t internal_partition = {0}; + esp_partition_info_t partition_info = {0}; + + esp_err_t err = esp_tee_flash_find_partition(type, subtype, label, &partition_info); + if (err != ESP_OK) { + return NULL; + } + + // Populate the internal partition structure + internal_partition.flash_chip = NULL; + internal_partition.type = partition_info.type; + internal_partition.subtype = partition_info.subtype; + internal_partition.address = partition_info.pos.offset; + internal_partition.size = partition_info.pos.size; + internal_partition.erase_size = SPI_FLASH_SEC_SIZE; + strncpy(internal_partition.label, (char *)partition_info.label, sizeof(internal_partition.label) - 1); + internal_partition.encrypted = partition_info.flags & PART_FLAG_ENCRYPTED; + internal_partition.readonly = partition_info.flags & PART_FLAG_READONLY; + + return &internal_partition; +} + +esp_err_t esp_partition_read(const esp_partition_t *partition, + size_t src_offset, void *dst, size_t size) +{ + assert(partition != NULL); + if (src_offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (size > partition->size - src_offset) { + return ESP_ERR_INVALID_SIZE; + } + + if (!partition->encrypted) { + return esp_tee_flash_read(partition->address + src_offset, dst, size, false); + } + + const void *buf = esp_tee_flash_mmap(partition->address + src_offset, size); + if (buf == NULL) { + return ESP_ERR_NO_MEM; + } + + memcpy(dst, buf, size); + esp_tee_flash_munmap(buf); + return ESP_OK; +} + +esp_err_t esp_partition_write(const esp_partition_t *partition, + size_t dst_offset, const void *src, size_t size) +{ + assert(partition != NULL); + if (partition->readonly) { + return ESP_ERR_NOT_ALLOWED; + } + if (dst_offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (size > partition->size - dst_offset) { + return ESP_ERR_INVALID_SIZE; + } + dst_offset = partition->address + dst_offset; + if (!partition->encrypted) { + return esp_tee_flash_write(dst_offset, (void *)src, size, false); + } + + return esp_tee_flash_write(dst_offset, (void *)src, size, true); +} + +esp_err_t esp_partition_read_raw(const esp_partition_t *partition, + size_t src_offset, void *dst, size_t size) +{ + assert(partition != NULL); + if (src_offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (size > partition->size - src_offset) { + return ESP_ERR_INVALID_SIZE; + } + + return esp_tee_flash_read(partition->address + src_offset, dst, size, false); +} + +esp_err_t esp_partition_write_raw(const esp_partition_t *partition, + size_t dst_offset, const void *src, size_t size) +{ + assert(partition != NULL); + if (partition->readonly) { + return ESP_ERR_NOT_ALLOWED; + } + if (dst_offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (size > partition->size - dst_offset) { + return ESP_ERR_INVALID_SIZE; + } + dst_offset = partition->address + dst_offset; + + return esp_tee_flash_write(dst_offset, (void *)src, size, false); +} + +esp_err_t esp_partition_erase_range(const esp_partition_t *partition, + size_t offset, size_t size) +{ + assert(partition != NULL); + if (partition->readonly) { + return ESP_ERR_NOT_ALLOWED; + } + if (offset > partition->size) { + return ESP_ERR_INVALID_ARG; + } + if (size > partition->size - offset) { + return ESP_ERR_INVALID_SIZE; + } + + return esp_tee_flash_erase_range(partition->address + offset, size); +} + +uint32_t esp_partition_get_main_flash_sector_size(void) +{ + return SPI_FLASH_SEC_SIZE; +} diff --git a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in index 7c5a572861..560fde38e6 100644 --- a/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in +++ b/components/esp_tee/subproject/main/ld/esp32c6/esp_tee.ld.in @@ -148,6 +148,7 @@ SECTIONS *(.rodata_desc .rodata_desc.*) /* Should be the first. TEE App version info. DO NOT PUT ANYTHING BEFORE IT! */ *(.rodata .rodata.*) *(.srodata .srodata.*) + *(.gcc_except_table .gcc_except_table.*) _tee_xip_data_end = ABSOLUTE(.); } > flash_data_seg @@ -213,6 +214,12 @@ SECTIONS *libmbedcrypto.a:*(.literal .text .literal.* .text.*) /* HMAC-DS layer */ *libesp_security.a:*(.literal .text .literal.* .text.*) + /* NVS flash and related modules */ + *libnvs_flash.a:*(.literal .text .literal.* .text.*) + *libstdc++.a:*(.literal .text .literal.* .text.*) + *libgcc.a:*(.literal .text .literal.* .text.*) + /* esp_partition API */ + *libesp_partition.a:*(.literal .text .literal.* .text.*) /* TEE attestation module */ *libattestation.a:*(.literal .text .literal.* .text.*) *json_generator.a:*(.literal .text .literal.* .text.*) diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake index 1e3d0c91ec..6b89f92859 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -52,6 +52,7 @@ target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/dma/esp_aes.c" "${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c") target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/aes/esp_aes_common.c" + "${COMPONENT_DIR}/port/aes/esp_aes_xts.c" "${COMPONENT_DIR}/port/aes/esp_aes_gcm.c") # SHA implementation diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h index cd4071249e..14078e2bd2 100644 --- a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -36,7 +36,9 @@ #define MBEDTLS_CIPHER_C #define MBEDTLS_AES_C #define MBEDTLS_GCM_C +#define MBEDTLS_AES_ALT #define MBEDTLS_GCM_ALT +#define MBEDTLS_CIPHER_MODE_XTS #define MBEDTLS_ASN1_WRITE_C #define MBEDTLS_ASN1_PARSE_C diff --git a/components/nvs_flash/CMakeLists.txt b/components/nvs_flash/CMakeLists.txt index eb8057afe2..edbfeaa36e 100644 --- a/components/nvs_flash/CMakeLists.txt +++ b/components/nvs_flash/CMakeLists.txt @@ -1,3 +1,5 @@ +idf_build_get_property(esp_tee_build ESP_TEE_BUILD) + if(BOOTLOADER_BUILD) # bootloader build simplified version set(srcs "src/nvs_bootloader.c" @@ -13,8 +15,33 @@ if(BOOTLOADER_BUILD) PRIV_INCLUDE_DIRS "private_include" ) +elseif(esp_tee_build) + # esp-tee build simplified version + set(srcs "src/nvs_api.cpp" + "src/nvs_item_hash_list.cpp" + "src/nvs_page.cpp" + "src/nvs_pagemanager.cpp" + "src/nvs_storage.cpp" + "src/nvs_handle_simple.cpp" + "src/nvs_handle_locked.cpp" + "src/nvs_partition.cpp" + "src/nvs_encrypted_partition.cpp" + "src/nvs_partition_lookup.cpp" + "src/nvs_partition_manager.cpp" + "src/nvs_types.cpp" + "src/nvs_platform.cpp") + + set(requires esp_partition mbedtls) + set(priv_requires spi_flash newlib) + + idf_component_register(SRCS "${srcs}" + REQUIRES "${requires}" + PRIV_REQUIRES "${priv_requires}" + INCLUDE_DIRS "include" + PRIV_INCLUDE_DIRS "private_include") + else() - # regular, non bootloader build + # regular, OS build idf_build_get_property(target IDF_TARGET) set(srcs "src/nvs_api.cpp" @@ -66,4 +93,4 @@ else() target_compile_options(${COMPONENT_LIB} PUBLIC "-fno-analyzer") endif() -endif() #bootloader build +endif() #non-OS build diff --git a/components/nvs_flash/src/nvs_api.cpp b/components/nvs_flash/src/nvs_api.cpp index 2bbb460e06..8fdf30c0eb 100644 --- a/components/nvs_flash/src/nvs_api.cpp +++ b/components/nvs_flash/src/nvs_api.cpp @@ -129,6 +129,7 @@ extern "C" esp_err_t nvs_flash_init_partition(const char *part_name) } Lock lock; + assert(nvs::Page::SEC_SIZE == esp_partition_get_main_flash_sector_size()); return NVSPartitionManager::get_instance()->init_partition(part_name); } @@ -169,6 +170,7 @@ extern "C" esp_err_t nvs_flash_secure_init_partition(const char *part_name, nvs_ } Lock lock; + assert(nvs::Page::SEC_SIZE == esp_partition_get_main_flash_sector_size()); return NVSPartitionManager::get_instance()->secure_init_partition(part_name, cfg); } diff --git a/components/nvs_flash/src/nvs_memory_management.hpp b/components/nvs_flash/src/nvs_memory_management.hpp index 2936365a7b..54138f8aba 100644 --- a/components/nvs_flash/src/nvs_memory_management.hpp +++ b/components/nvs_flash/src/nvs_memory_management.hpp @@ -5,7 +5,9 @@ */ #include +#if !ESP_TEE_BUILD #include "esp_heap_caps.h" +#endif #pragma once diff --git a/components/nvs_flash/src/nvs_page.cpp b/components/nvs_flash/src/nvs_page.cpp index f818ddb56f..f16c4a3b83 100644 --- a/components/nvs_flash/src/nvs_page.cpp +++ b/components/nvs_flash/src/nvs_page.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ namespace nvs { Page::Page() : mPartition(nullptr) { } -const uint32_t nvs::Page::SEC_SIZE = esp_partition_get_main_flash_sector_size(); +const uint32_t nvs::Page::SEC_SIZE = 4096; uint32_t Page::Header::calculateCrc32() { diff --git a/components/nvs_flash/src/nvs_platform.cpp b/components/nvs_flash/src/nvs_platform.cpp index 045996bccd..d7da78023e 100644 --- a/components/nvs_flash/src/nvs_platform.cpp +++ b/components/nvs_flash/src/nvs_platform.cpp @@ -7,7 +7,7 @@ using namespace nvs; -#ifdef LINUX_TARGET +#if LINUX_TARGET || ESP_TEE_BUILD Lock::Lock() {} Lock::~Lock() {} esp_err_t nvs::Lock::init() {return ESP_OK;}