feat(esp_tee): Support for ESP-TEE - mbedtls component

This commit is contained in:
Laukik Hase
2024-07-01 16:07:59 +05:30
parent ba2af7f611
commit 05e31e5148
8 changed files with 348 additions and 29 deletions

View File

@@ -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 "")

View File

@@ -0,0 +1,128 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#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);
}

View File

@@ -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

View File

@@ -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()

View File

@@ -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 */

View File

@@ -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()

View File

@@ -6,33 +6,37 @@
#include <string.h>
#include <sys/param.h>
#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,

View File

@@ -30,19 +30,23 @@
#include <sys/lock.h>
#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()