diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index d3f4fe40a7..8bc72f6179 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -1,12 +1,17 @@ idf_build_get_property(idf_target IDF_TARGET) idf_build_get_property(python PYTHON) +idf_build_get_property(esp_tee_build ESP_TEE_BUILD) + +if(esp_tee_build) + include(${COMPONENT_DIR}/esp_tee/esp_tee_mbedtls.cmake) + return() +endif() if(NOT ${IDF_TARGET} STREQUAL "linux") -set(priv_requires soc esp_hw_support) - -if(NOT BOOTLOADER_BUILD) - list(APPEND priv_requires esp_pm) -endif() + set(priv_requires soc esp_hw_support) + if(NOT BOOTLOADER_BUILD) + list(APPEND priv_requires esp_pm) + endif() endif() set(mbedtls_srcs "") diff --git a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c new file mode 100644 index 0000000000..6c0c47b4f7 --- /dev/null +++ b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.c @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include "esp_err.h" + +#include "mbedtls/aes.h" +#include "esp_crypto_dma.h" + +#include "hal/clk_gate_ll.h" +#include "hal/gdma_ll.h" +#include "hal/gdma_types.h" +#include "hal/aes_hal.h" + +#include "soc/lldesc.h" +#include "soc/periph_defs.h" +#include "soc/gdma_channel.h" +#include "soc/gdma_struct.h" +#include "soc/soc_caps.h" + +#define TEE_CRYPTO_GDMA_CH (0) + +/* + * NOTE: [ESP-TEE] This is a low-level (LL), non-OS version of + * port/crypto_shared_gdma/esp_crypto_shared_gdma.c that defines + * the shared DMA layer for the AES and SHA peripherals for ESP-TEE. + */ + +/* ---------------------------------------------- Shared GDMA layer for AES/SHA crypto ------------------------------------------------- */ + +static void crypto_shared_gdma_init(void) +{ + // enable APB to access GDMA registers + periph_ll_enable_clk_clear_rst(PERIPH_GDMA_MODULE); + + // enable gdma clock + gdma_ll_force_enable_reg_clock(&GDMA, true); + + // setting the transfer ability + gdma_ll_tx_enable_data_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true); + gdma_ll_tx_enable_descriptor_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true); + + gdma_ll_rx_enable_data_burst(&GDMA, TEE_CRYPTO_GDMA_CH, false); + gdma_ll_rx_enable_descriptor_burst(&GDMA, TEE_CRYPTO_GDMA_CH, true); + +#if SOC_GDMA_SUPPORT_PSRAM + gdma_ll_tx_set_block_size_psram(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_LL_EXT_MEM_BK_SIZE_16B); + gdma_ll_rx_set_block_size_psram(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_LL_EXT_MEM_BK_SIZE_16B); +#endif // SOC_GDMA_SUPPORT_PSRAM + + gdma_ll_tx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); + gdma_ll_tx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_TRIG_PERIPH_M2M, SOC_GDMA_TRIG_PERIPH_M2M0); + + gdma_ll_rx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); + gdma_ll_rx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, GDMA_TRIG_PERIPH_M2M, SOC_GDMA_TRIG_PERIPH_M2M0); + +} + +esp_err_t esp_tee_crypto_shared_gdma_start(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output, gdma_trigger_peripheral_t periph) +{ + int periph_inst_id = SOC_GDMA_TRIG_PERIPH_M2M0; + if (periph == GDMA_TRIG_PERIPH_SHA) { + periph_inst_id = SOC_GDMA_TRIG_PERIPH_SHA0; + } else if (periph == GDMA_TRIG_PERIPH_AES) { + periph_inst_id = SOC_GDMA_TRIG_PERIPH_AES0; + } else { + return ESP_ERR_INVALID_ARG; + } + + crypto_shared_gdma_init(); + + gdma_ll_tx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); + gdma_ll_rx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); + + gdma_ll_tx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); + gdma_ll_tx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id); + + gdma_ll_rx_reset_channel(&GDMA, TEE_CRYPTO_GDMA_CH); + gdma_ll_rx_connect_to_periph(&GDMA, TEE_CRYPTO_GDMA_CH, periph, periph_inst_id); + + gdma_ll_tx_set_desc_addr(&GDMA, TEE_CRYPTO_GDMA_CH, (intptr_t)input); + gdma_ll_tx_start(&GDMA, TEE_CRYPTO_GDMA_CH); + + gdma_ll_rx_set_desc_addr(&GDMA, TEE_CRYPTO_GDMA_CH, (intptr_t)output); + gdma_ll_rx_start(&GDMA, TEE_CRYPTO_GDMA_CH); + + return ESP_OK; +} + +void esp_tee_crypto_shared_gdma_free(void) +{ + gdma_ll_tx_stop(&GDMA, TEE_CRYPTO_GDMA_CH); + gdma_ll_rx_stop(&GDMA, TEE_CRYPTO_GDMA_CH); + + gdma_ll_tx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); + gdma_ll_rx_disconnect_from_periph(&GDMA, TEE_CRYPTO_GDMA_CH); + + gdma_ll_tx_set_priority(&GDMA, TEE_CRYPTO_GDMA_CH, 0); + gdma_ll_rx_set_priority(&GDMA, TEE_CRYPTO_GDMA_CH, 0); + + // disable gdma clock + gdma_ll_force_enable_reg_clock(&GDMA, false); + + // disable APB for GDMA registers + periph_ll_disable_clk_set_rst(PERIPH_GDMA_MODULE); +} + +/* ---------------------------------------------- DMA Implementations: AES ------------------------------------------------- */ + +esp_err_t esp_aes_dma_start(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output) +{ + return esp_tee_crypto_shared_gdma_start(input, output, GDMA_TRIG_PERIPH_AES); +} + +bool esp_aes_dma_done(crypto_dma_desc_t *output) +{ + return (output->dw0.owner == 0); +} + +/* ---------------------------------------------- DMA Implementations: SHA ------------------------------------------------- */ + +esp_err_t esp_sha_dma_start(const crypto_dma_desc_t *input) +{ + return esp_tee_crypto_shared_gdma_start(input, NULL, GDMA_TRIG_PERIPH_SHA); +} diff --git a/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.h b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.h new file mode 100644 index 0000000000..21dfac04f3 --- /dev/null +++ b/components/mbedtls/esp_tee/esp_tee_crypto_shared_gdma.h @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "hal/gdma_types.h" +#include "esp_crypto_dma.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Start a GDMA transfer on the shared crypto DMA channel for ESP-TEE + * + * @note This is a low-level (LL), non-OS version of esp_crypto_shared_gdma_start() + * + * @param input Input linked list descriptor (crypto_dma_desc_t *) + * @param output Output linked list descriptor (crypto_dma_desc_t *) + * @param periph Crypto peripheral to connect the DMA to, either GDMA_TRIG_PERIPH_AES or + * GDMA_TRIG_PERIPH_SHA + * @return esp_err_t ESP_OK on success, ESP_ERR_INVALID_ARG if invalid peripheral specified + */ +esp_err_t esp_tee_crypto_shared_gdma_start(const crypto_dma_desc_t *input, const crypto_dma_desc_t *output, gdma_trigger_peripheral_t periph); + +/** + * @brief Frees the TEE-specific shared crypto DMA channel. + * + * @note This is a low-level (LL), non-OS version of esp_crypto_shared_gdma_free() + */ +void esp_tee_crypto_shared_gdma_free(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake new file mode 100644 index 0000000000..7a08feba3d --- /dev/null +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls.cmake @@ -0,0 +1,61 @@ +idf_component_get_property(hal_dir hal COMPONENT_DIR) +idf_component_get_property(heap_dir heap COMPONENT_DIR) + +set(priv_requires soc esp_hw_support) +set(include_dirs "${COMPONENT_DIR}/port/include" + "${COMPONENT_DIR}/mbedtls/include" + "${COMPONENT_DIR}/mbedtls/library") + +# Shared GDMA layer for TEE +set(srcs "${COMPONENT_DIR}/esp_tee/esp_tee_crypto_shared_gdma.c") + +# HAL for the AES/SHA peripherals +list(APPEND srcs "${hal_dir}/aes_hal.c" + "${hal_dir}/sha_hal.c") + +list(APPEND include_dirs "${COMPONENT_DIR}/port/aes/include" + "${COMPONENT_DIR}/port/aes/dma/include" + "${COMPONENT_DIR}/port/sha/dma/include") + +list(APPEND srcs "${COMPONENT_DIR}/port/aes/esp_aes_common.c" + "${COMPONENT_DIR}/port/aes/dma/esp_aes.c" + "${COMPONENT_DIR}/port/aes/dma/esp_aes_dma_core.c") + +list(APPEND srcs "${COMPONENT_DIR}/port/sha/dma/sha.c" + "${COMPONENT_DIR}/port/sha/esp_sha.c") + +# Supporting headers +list(APPEND include_dirs "${heap_dir}/include") + +idf_component_register(INCLUDE_DIRS "${include_dirs}" + PRIV_REQUIRES "${priv_requires}" + SRCS "${srcs}") + +# Only build mbedtls libraries +set(ENABLE_TESTING CACHE BOOL OFF) +set(ENABLE_PROGRAMS CACHE BOOL OFF) + +# Use pre-generated source files in mbedtls repository +set(GEN_FILES CACHE BOOL OFF) + +# Needed to for include_next includes to work from within mbedtls +include_directories("${COMPONENT_DIR}/port/include") + +# Import mbedtls library targets +add_subdirectory(mbedtls) + +set(mbedtls_targets mbedcrypto) + +foreach(target ${mbedtls_targets}) + target_compile_definitions(${target} PUBLIC + -DMBEDTLS_CONFIG_FILE="${COMPONENT_DIR}/esp_tee/esp_tee_mbedtls_config.h") +endforeach() + +target_link_libraries(${COMPONENT_LIB} INTERFACE ${mbedtls_targets}) + +if(CONFIG_MBEDTLS_HARDWARE_SHA) + target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/sha/dma/esp_sha1.c" + "${COMPONENT_DIR}/port/sha/dma/esp_sha256.c" + "${COMPONENT_DIR}/port/sha/dma/esp_sha512.c" + ) +endif() diff --git a/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h new file mode 100644 index 0000000000..665a009e1c --- /dev/null +++ b/components/mbedtls/esp_tee/esp_tee_mbedtls_config.h @@ -0,0 +1,57 @@ +/** + * + * \brief Default mbedTLS configuration options for the ESP-TEE framework + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + * + * SPDX-FileCopyrightText: The Mbed TLS Contributors + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ESP_TEE_MBEDTLS_CONFIG_H +#define ESP_TEE_MBEDTLS_CONFIG_H + +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_HAVE_TIME +#define MBEDTLS_PLATFORM_MS_TIME_ALT +#undef MBEDTLS_TIMING_C +#define MBEDTLS_PLATFORM_C + +#define MBEDTLS_CIPHER_C +#define MBEDTLS_AES_C +#define MBEDTLS_GCM_C + +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_C +#define MBEDTLS_ECDSA_C + +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA224_C +#define MBEDTLS_SHA256_C + +#ifdef CONFIG_MBEDTLS_HARDWARE_SHA +#define MBEDTLS_SHA1_ALT +#define MBEDTLS_SHA224_ALT +#define MBEDTLS_SHA256_ALT +#endif + +#define MBEDTLS_ENTROPY_C + +#endif /* ESP_TEE_MBEDTLS_CONFIG_H */ diff --git a/components/mbedtls/port/aes/dma/esp_aes.c b/components/mbedtls/port/aes/dma/esp_aes.c index be87512e79..28af391bf3 100644 --- a/components/mbedtls/port/aes/dma/esp_aes.c +++ b/components/mbedtls/port/aes/dma/esp_aes.c @@ -36,8 +36,14 @@ #include "esp_private/esp_crypto_lock_internal.h" #if SOC_AES_GDMA +#if !ESP_TEE_BUILD #define AES_LOCK() esp_crypto_sha_aes_lock_acquire() #define AES_RELEASE() esp_crypto_sha_aes_lock_release() +#else +#define AES_RCC_ATOMIC() +#define AES_LOCK() +#define AES_RELEASE() +#endif #elif SOC_AES_CRYPTO_DMA #define AES_LOCK() esp_crypto_dma_lock_acquire() #define AES_RELEASE() esp_crypto_dma_lock_release() diff --git a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c index f870cf1f51..b68aba8666 100644 --- a/components/mbedtls/port/aes/dma/esp_aes_dma_core.c +++ b/components/mbedtls/port/aes/dma/esp_aes_dma_core.c @@ -6,33 +6,37 @@ #include #include #include "esp_attr.h" -#include "esp_cache.h" #include "esp_check.h" #include "esp_err.h" #include "esp_heap_caps.h" #include "esp_intr_alloc.h" #include "esp_log.h" #include "esp_memory_utils.h" -#include "esp_private/esp_cache_private.h" #include "esp_private/periph_ctrl.h" #include "soc/soc_caps.h" #include "sdkconfig.h" -#if CONFIG_PM_ENABLE -#include "esp_pm.h" -#endif #include "hal/aes_hal.h" +#include "hal/cache_hal.h" +#include "hal/cache_ll.h" #include "esp_aes_dma_priv.h" #include "esp_aes_internal.h" #include "esp_crypto_dma.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" - #include "mbedtls/aes.h" #include "mbedtls/platform_util.h" +#if !ESP_TEE_BUILD +#include "esp_cache.h" +#include "esp_private/esp_cache_private.h" +#if CONFIG_PM_ENABLE +#include "esp_pm.h" +#endif +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#endif + #if SOC_AES_SUPPORT_GCM #include "aes/esp_aes_gcm.h" #endif @@ -60,6 +64,7 @@ */ #define AES_WAIT_INTR_TIMEOUT_MS 2000 +#if !ESP_TEE_BUILD #if defined(CONFIG_MBEDTLS_AES_USE_INTERRUPT) static SemaphoreHandle_t op_complete_sem; #if defined(CONFIG_PM_ENABLE) @@ -67,6 +72,9 @@ static esp_pm_lock_handle_t s_pm_cpu_lock; static esp_pm_lock_handle_t s_pm_sleep_lock; #endif #endif +#else +extern bool intr_flag; +#endif static const char *TAG = "esp-aes"; @@ -82,6 +90,7 @@ static bool s_check_dma_capable(const void *p) } #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT) +#if !ESP_TEE_BUILD static IRAM_ATTR void esp_aes_complete_isr(void *arg) { BaseType_t higher_woken; @@ -112,12 +121,14 @@ void esp_aes_intr_alloc(void) assert(op_complete_sem != NULL); } } +#endif static esp_err_t esp_aes_isr_initialise( void ) { aes_hal_interrupt_clear(); aes_hal_interrupt_enable(true); +#if !ESP_TEE_BUILD /* AES is clocked proportionally to CPU clock, take power management lock */ #ifdef CONFIG_PM_ENABLE if (s_pm_cpu_lock == NULL) { @@ -133,6 +144,9 @@ static esp_err_t esp_aes_isr_initialise( void ) esp_pm_lock_acquire(s_pm_cpu_lock); esp_pm_lock_acquire(s_pm_sleep_lock); #endif +#else + intr_flag = true; +#endif return ESP_OK; } @@ -153,6 +167,7 @@ static int esp_aes_dma_wait_complete(bool use_intr, crypto_dma_desc_t *output_de { #if defined (CONFIG_MBEDTLS_AES_USE_INTERRUPT) if (use_intr) { +#if !ESP_TEE_BUILD if (!xSemaphoreTake(op_complete_sem, AES_WAIT_INTR_TIMEOUT_MS / portTICK_PERIOD_MS)) { /* indicates a fundamental problem with driver */ ESP_LOGE(TAG, "Timed out waiting for completion of AES Interrupt"); @@ -162,6 +177,15 @@ static int esp_aes_dma_wait_complete(bool use_intr, crypto_dma_desc_t *output_de esp_pm_lock_release(s_pm_cpu_lock); esp_pm_lock_release(s_pm_sleep_lock); #endif // CONFIG_PM_ENABLE +#else + /* NOTE: ESP-TEE does not support multitasking - secure service calls are serialized. + * When waiting for AES interrupt here, we simply busy-wait since there are no + * other tasks to switch to. Note that REE interrupts could still preempt us. + */ + while (intr_flag) { + esp_rom_delay_us(1); + } +#endif } #endif /* Checking this if interrupt is used also, to avoid @@ -175,23 +199,14 @@ static int esp_aes_dma_wait_complete(bool use_intr, crypto_dma_desc_t *output_de static inline size_t get_cache_line_size(const void *addr) { - esp_err_t ret = ESP_FAIL; - size_t cache_line_size = 0; - + uint32_t cache_level = #if (CONFIG_SPIRAM && SOC_PSRAM_DMA_CAPABLE) - if (esp_ptr_external_ram(addr)) { - ret = esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_line_size); - } else + esp_ptr_external_ram(addr) ? CACHE_LL_LEVEL_EXT_MEM : CACHE_LL_LEVEL_INT_MEM; +#else + CACHE_LL_LEVEL_INT_MEM; #endif - { - ret = esp_cache_get_alignment(MALLOC_CAP_DMA, &cache_line_size); - } - if (ret != ESP_OK) { - return 0; - } - - return cache_line_size; + return (size_t)cache_hal_get_cache_line_size(cache_level, CACHE_TYPE_DATA); } /* Output buffers in external ram needs to be 16-byte aligned and DMA can't access input in the iCache mem range, diff --git a/components/mbedtls/port/sha/dma/sha.c b/components/mbedtls/port/sha/dma/sha.c index f3c6b17a93..31f89d7d7f 100644 --- a/components/mbedtls/port/sha/dma/sha.c +++ b/components/mbedtls/port/sha/dma/sha.c @@ -30,19 +30,23 @@ #include #include "esp_private/esp_crypto_lock_internal.h" -#include "esp_private/esp_cache_private.h" + #include "esp_log.h" #include "esp_memory_utils.h" #include "esp_crypto_lock.h" #include "esp_attr.h" #include "esp_crypto_dma.h" -#include "esp_cache.h" +#include "esp_heap_caps.h" #include "hal/dma_types.h" #include "soc/ext_mem_defs.h" #include "soc/periph_defs.h" +#if !ESP_TEE_BUILD +#include "esp_cache.h" +#include "esp_private/esp_cache_private.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" +#endif #include "esp_private/periph_ctrl.h" #include "sys/param.h" @@ -59,8 +63,14 @@ #endif /* SOC_AXI_DMA_EXT_MEM_ENC_ALIGNMENT */ #if SOC_SHA_GDMA +#if !ESP_TEE_BUILD #define SHA_LOCK() esp_crypto_sha_aes_lock_acquire() #define SHA_RELEASE() esp_crypto_sha_aes_lock_release() +#else +#define SHA_RCC_ATOMIC() +#define SHA_LOCK() +#define SHA_RELEASE() +#endif #elif SOC_SHA_CRYPTO_DMA #define SHA_LOCK() esp_crypto_dma_lock_acquire() #define SHA_RELEASE() esp_crypto_dma_lock_release()