diff --git a/components/esp_tee/CMakeLists.txt b/components/esp_tee/CMakeLists.txt index 908067d0c21..fc58bbed717 100644 --- a/components/esp_tee/CMakeLists.txt +++ b/components/esp_tee/CMakeLists.txt @@ -104,11 +104,12 @@ if(CONFIG_SECURE_ENABLE_TEE AND NOT esp_tee_build) list(APPEND exclude_srv "attestation") endif() + idf_build_get_property(secure_service_headers_dir SECURE_SERVICE_HEADERS_DIR) execute_process( COMMAND python ${secure_service_yml_parser_py} "--sec_srv" ${secure_service_yml} "--exclude" ${exclude_srv} - WORKING_DIRECTORY ${CONFIG_DIR} + WORKING_DIRECTORY ${secure_service_headers_dir} ) execute_process( diff --git a/components/esp_tee/project_include.cmake b/components/esp_tee/project_include.cmake index b3c0e912659..cb6fd8aa301 100644 --- a/components/esp_tee/project_include.cmake +++ b/components/esp_tee/project_include.cmake @@ -6,7 +6,6 @@ idf_build_get_property(python PYTHON) idf_build_get_property(extra_cmake_args EXTRA_CMAKE_ARGS) idf_build_get_property(project_dir PROJECT_DIR) idf_build_get_property(non_os_build NON_OS_BUILD) -idf_build_get_property(config_dir CONFIG_DIR) idf_build_get_property(custom_secure_service_dir CUSTOM_SECURE_SERVICE_COMPONENT_DIR) idf_build_get_property(custom_secure_service_component CUSTOM_SECURE_SERVICE_COMPONENT) @@ -33,13 +32,24 @@ set(tee_binary_files "${TEE_BUILD_DIR}/esp_tee.map" ) +# Use only Newlib libc to reduce binary size, as some Newlib functions are already available in ROM +set(esp_tee_sdkconfig "${CMAKE_CURRENT_BINARY_DIR}/sdkconfig.esp_tee") +configure_file("${sdkconfig}" "${esp_tee_sdkconfig}" COPYONLY) +file(APPEND "${esp_tee_sdkconfig}" "\nCONFIG_LIBC_NEWLIB=y\n") + +set(secure_service_headers_dir "${CMAKE_CURRENT_BINARY_DIR}/secure_service_headers") +make_directory(${secure_service_headers_dir}) +idf_build_set_property(SECURE_SERVICE_HEADERS_DIR "${secure_service_headers_dir}") +include_directories("${secure_service_headers_dir}") + externalproject_add(esp_tee SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject" BINARY_DIR "${TEE_BUILD_DIR}" - CMAKE_ARGS -DSDKCONFIG=${sdkconfig} -DIDF_PATH=${idf_path} -DIDF_TARGET=${idf_target} - -DCONFIG_DIR=${config_dir} -DCUSTOM_SECURE_SERVICE_COMPONENT=${custom_secure_service_component} - -DCUSTOM_SECURE_SERVICE_COMPONENT_DIR=${custom_secure_service_dir} - ${extra_cmake_args} ${sign_key_arg} + CMAKE_ARGS -DSDKCONFIG=${esp_tee_sdkconfig} -DIDF_PATH=${idf_path} -DIDF_TARGET=${idf_target} + -DCUSTOM_SECURE_SERVICE_COMPONENT=${custom_secure_service_component} + -DCUSTOM_SECURE_SERVICE_COMPONENT_DIR=${custom_secure_service_dir} + -DSECURE_SERVICE_HEADERS_DIR=${secure_service_headers_dir} + ${extra_cmake_args} ${sign_key_arg} INSTALL_COMMAND "" BUILD_ALWAYS 1 # no easy way around this... USES_TERMINAL_CONFIGURE TRUE diff --git a/components/esp_tee/subproject/CMakeLists.txt b/components/esp_tee/subproject/CMakeLists.txt index b4d77bd32be..74a1094809d 100644 --- a/components/esp_tee/subproject/CMakeLists.txt +++ b/components/esp_tee/subproject/CMakeLists.txt @@ -30,8 +30,7 @@ list(APPEND COMPONENTS bootloader_support efuse esp_security mbedtls) # TEE-specific components list(APPEND COMPONENTS tee_flash_mgr tee_ota_ops tee_sec_storage tee_attestation) -# Include sdkconfig.h derived from the parent build. -include_directories(${CONFIG_DIR}) +include_directories("${SECURE_SERVICE_HEADERS_DIR}") include("${IDF_PATH}/tools/cmake/project.cmake") set(common_req esp_common esp_hw_support esp_rom freertos hal log newlib soc spi_flash) diff --git a/components/esp_tee/subproject/main/CMakeLists.txt b/components/esp_tee/subproject/main/CMakeLists.txt index 83a77c34cea..36ec492f0ab 100644 --- a/components/esp_tee/subproject/main/CMakeLists.txt +++ b/components/esp_tee/subproject/main/CMakeLists.txt @@ -61,7 +61,7 @@ idf_component_register(SRCS ${srcs} # NOTE: The ESP32-H2 ROM does not have sprintf/snprintf implementation, # thus newlib-nano implementation from the toolchain has been used. -if(CONFIG_IDF_TARGET_ESP32H2) +if(CONFIG_LIBC_NEWLIB AND CONFIG_IDF_TARGET_ESP32H2) target_link_libraries(${COMPONENT_LIB} INTERFACE "--specs=nano.specs") endif() @@ -76,6 +76,8 @@ target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_app_desc_tee_include_impl # Newlib syscalls stub implementation: Linking symbol target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_tee_include_syscalls_impl") +target_link_libraries(${COMPONENT_LIB} PRIVATE "-u esp_tee_include_heap_impl") + # cut PROJECT_VER and PROJECT_NAME to required 32 characters. idf_build_get_property(project_ver PROJECT_VER) idf_build_get_property(project_name PROJECT_NAME) diff --git a/components/esp_tee/subproject/main/common/multi_heap.c b/components/esp_tee/subproject/main/common/multi_heap.c index 4261bd73dd7..49d963a8e65 100644 --- a/components/esp_tee/subproject/main/common/multi_heap.c +++ b/components/esp_tee/subproject/main/common/multi_heap.c @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include #include #include #include "esp_rom_tlsf.h" @@ -151,6 +152,33 @@ void *calloc(size_t n, size_t size) return esp_tee_heap_calloc(n, size); } +#if CONFIG_LIBC_PICOLIBC +void *realloc(void* ptr, size_t size) +{ + if (tee_heap == NULL) { + return NULL; + } + + if (ptr == NULL) { + return esp_tee_heap_malloc(heap, size); + } + + size_t previous_block_size = tlsf_block_size(ptr); + void *result = tlsf_realloc(tee_heap->heap_data, ptr, size); + if (result) { + /* No need to subtract the tlsf_alloc_overhead() as it has already + * been subtracted when allocating the block at first with malloc */ + tee_heap->free_bytes += previous_block_size; + tee_heap->free_bytes -= tlsf_block_size(result); + if (tee_heap->free_bytes < tee_heap->minimum_free_bytes) { + tee_heap->minimum_free_bytes = tee_heap->free_bytes; + } + } + + return result; +} +#endif + void free(void *ptr) { esp_tee_heap_free(ptr); @@ -206,3 +234,10 @@ void *heap_caps_aligned_calloc(size_t alignment, size_t n, size_t size, uint32_t } return ptr; } + +/* No-op function, used to force linking this file, + instead of the heap implementation from libc. + */ +void esp_tee_include_heap_impl(void) +{ +} diff --git a/components/esp_tee/subproject/main/common/syscall_stubs.c b/components/esp_tee/subproject/main/common/syscall_stubs.c index ee810a1aac2..01c337fb22d 100644 --- a/components/esp_tee/subproject/main/common/syscall_stubs.c +++ b/components/esp_tee/subproject/main/common/syscall_stubs.c @@ -15,7 +15,9 @@ #include #include "esp_random.h" +#include "sdkconfig.h" +#if CONFIG_LIBC_NEWLIB // NOTE: Remove compile-time warnings for the below newlib-provided functions struct _reent *__getreent(void) { @@ -68,6 +70,54 @@ int _getentropy_r(struct _reent *r, void *buffer, size_t length) esp_fill_random(buffer, length); return 0; } +#else +int fstat(int fd, struct stat *st) +{ + errno = ENOSYS; + return -1; +} + +int close(int fd) +{ + errno = ENOSYS; + return -1; +} + +off_t lseek(int fd, off_t offset, int whence) +{ + errno = ENOSYS; + return -1; +} + +ssize_t read(int fd, void *ptr, size_t len) +{ + errno = ENOSYS; + return -1; +} + +ssize_t write(int fd, const void *ptr, size_t len) +{ + errno = ENOSYS; + return -1; +} + +int getpid(void) +{ + return 1; +} + +int kill(int pid, int sig) +{ + errno = ENOSYS; + return -1; +} + +int getentropy(void *buffer, size_t length) +{ + esp_fill_random(buffer, length); + return 0; +} +#endif // CONFIG_LIBC_NEWLIB void *pthread_getspecific(pthread_key_t key) { diff --git a/components/newlib/src/picolibc/picolibc_init.c b/components/newlib/src/picolibc/picolibc_init.c index 7bd52667cbe..07540a4e554 100644 --- a/components/newlib/src/picolibc/picolibc_init.c +++ b/components/newlib/src/picolibc/picolibc_init.c @@ -37,8 +37,55 @@ int __retarget_lock_try_acquire(struct __lock * p); int __retarget_lock_try_acquire_recursive(struct __lock *p); #endif +#if CONFIG_SECURE_ENABLE_TEE +struct _reent_stub { + int _errno; + __FILE *_stdin, *_stdout, *_stderr; + int _inc; + char *_emergency; + int _reserved_0; + int _reserved_1; + struct __locale_t *_locale; + void *_mp; + void (*__cleanup)(struct _reent *); + int _gamma_signgam; + int _cvtlen; + char *_cvtbuf; + struct _rand48 *_r48; +#if 0 /* unlikely used fields in ROM implementation */ + struct __tm *_localtime_buf; + char *_asctime_buf; + void (** _sig_func)(int); + struct _atexit *_reserved_6; + struct _atexit _reserved_7; + struct _glue _reserved_8; + __FILE *__sf; + struct _misc_reent *_misc; + char *_signal_buf; +#endif +}; + +void *__getreent_rom_stub(void) +{ + static struct _reent_stub reent_stub; + return &reent_stub; +} +#endif // SECURE_ENABLE_TEE + static struct syscall_stub_table s_stub_table = { +#if CONFIG_SECURE_ENABLE_TEE + /* + * ESP-TEE uses snprintf() from ROM, which requires at least a fake __getreent stub. + * + * NOTE: If floating-point variables are intended to be used, + * the following fields must be specified in the syscall_stub_table: + * ._printf_float = + * ._scanf_float = + */ + .__getreent = (void *)__getreent_rom_stub, +#else .__getreent = (void *)abort, +#endif ._malloc_r = (void *)abort, ._free_r = (void *)abort, ._realloc_r = (void *)abort,