feat(mbedtls): Add support for ECDSA signing with TEE secure storage

This commit is contained in:
Laukik Hase
2025-02-13 14:22:30 +05:30
parent 1e8933d296
commit 3fd107aa04
8 changed files with 388 additions and 58 deletions

View File

@ -12,6 +12,7 @@
#include "mbedtls/ecp.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/sha256.h"
#include "ecdsa/ecdsa_alt.h"
#include "esp_tee.h"
#include "esp_tee_sec_storage.h"
@ -322,3 +323,77 @@ TEST_CASE("Test TEE Secure Storage - Corruption from non-secure world", "[secure
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
}
#endif
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
static const uint8_t sha[] = {
0x0c, 0xaa, 0x08, 0xb4, 0xf0, 0x89, 0xd3, 0x45,
0xbb, 0x55, 0x98, 0xd9, 0xc2, 0xe9, 0x65, 0x5d,
0x7e, 0xa3, 0xa9, 0xc3, 0xcd, 0x69, 0xb1, 0xcf,
0x91, 0xbe, 0x58, 0x10, 0xfe, 0x80, 0x65, 0x6e
};
static void test_ecdsa_sign(mbedtls_ecp_group_id gid, const uint8_t *hash, int slot_id)
{
TEST_ESP_OK(esp_tee_sec_storage_init());
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
bool is_crv_p192 = false;
esp_tee_sec_storage_type_t key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1;
size_t key_len = ECDSA_SECP256R1_KEY_LEN;
if (gid == MBEDTLS_ECP_DP_SECP192R1) {
is_crv_p192 = true;
key_type = ESP_SEC_STG_KEY_ECDSA_SECP192R1;
key_len = ECDSA_SECP192R1_KEY_LEN;
}
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, key_type));
esp_tee_sec_storage_pubkey_t pubkey = {};
TEST_ESP_OK(esp_tee_sec_storage_get_pubkey(slot_id, key_type, &pubkey));
mbedtls_mpi r, s;
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
mbedtls_ecdsa_context ecdsa_context;
mbedtls_ecdsa_init(&ecdsa_context);
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), gid));
mbedtls_pk_context key_ctx;
esp_ecdsa_pk_conf_t conf = {
.grp_id = gid,
.tee_slot_id = slot_id,
.load_pubkey = true,
.use_tee_sec_stg_key = true,
};
TEST_ASSERT_EQUAL(0, esp_ecdsa_tee_set_pk_context(&key_ctx, &conf));
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(key_ctx);
mbedtls_mpi key_mpi = keypair->MBEDTLS_PRIVATE(d);
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_sign(&ecdsa_context.MBEDTLS_PRIVATE(grp), &r, &s, &key_mpi, sha, SHA256_DIGEST_SZ, NULL, NULL));
esp_tee_sec_storage_sign_t sign = {};
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, sign.sign_r, key_len));
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, sign.sign_s, key_len));
ESP_LOGI(TAG, "Verifying generated signature...");
TEST_ESP_OK(verify_ecdsa_sign(sha, sizeof(sha), &pubkey, &sign, is_crv_p192));
mbedtls_pk_free(&key_ctx);
mbedtls_ecdsa_free(&ecdsa_context);
mbedtls_mpi_free(&r);
mbedtls_mpi_free(&s);
}
TEST_CASE("Test TEE Secure Storage - mbedtls ECDSA signing", "[mbedtls]")
{
test_ecdsa_sign(MBEDTLS_ECP_DP_SECP256R1, sha, MIN_SEC_STG_SLOT_ID);
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
test_ecdsa_sign(MBEDTLS_ECP_DP_SECP192R1, sha, MAX_SEC_STG_SLOT_ID);
#endif
}
#endif

View File

@ -294,27 +294,40 @@ if(CONFIG_MBEDTLS_HARDWARE_ECC)
"${COMPONENT_DIR}/port/ecc/ecc_alt.c")
endif()
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecdsa/ecdsa_alt.c")
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY OR CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecdsa/ecdsa_alt.c")
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_restartable")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature_restartable")
set(WRAP_FUNCTIONS_SIGN
mbedtls_ecdsa_sign
mbedtls_ecdsa_sign_restartable
mbedtls_ecdsa_write_signature
mbedtls_ecdsa_write_signature_restartable)
set(WRAP_FUNCTIONS_VERIFY
mbedtls_ecdsa_verify
mbedtls_ecdsa_verify_restartable
mbedtls_ecdsa_read_signature
mbedtls_ecdsa_read_signature_restartable)
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
foreach(wrap ${WRAP_FUNCTIONS_SIGN})
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
endforeach()
if(CONFIG_SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_det_ext")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_det_restartable")
endif()
endif()
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify_restartable")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature")
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature_restartable")
foreach(wrap ${WRAP_FUNCTIONS_VERIFY})
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
endforeach()
endif()
if(CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
target_link_libraries(mbedcrypto PRIVATE idf::tee_sec_storage)
endif()
endif()

View File

@ -584,6 +584,11 @@ menu "mbedTLS"
The key should be burnt in little endian format. espefuse.py utility handles it internally
but care needs to be taken while burning using esp_efuse APIs
config MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
bool "Enable ECDSA signing using TEE secure storage"
default y
depends on SECURE_ENABLE_TEE
menu "Enable Software Countermeasure for ECDSA signing using on-chip ECDSA peripheral"
depends on MBEDTLS_HARDWARE_ECDSA_SIGN
depends on IDF_TARGET_ESP32H2

View File

@ -1,27 +1,40 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "hal/ecc_ll.h"
#include "hal/ecdsa_ll.h"
#include "hal/ecdsa_hal.h"
#ifdef SOC_MPI_SUPPORTED
#include "hal/mpi_ll.h"
#endif
#include "esp_err.h"
#include "esp_log.h"
#include "hal/ecdsa_types.h"
#include "ecdsa/ecdsa_alt.h"
#include "soc/soc_caps.h"
#include "esp_crypto_lock.h"
#include "esp_efuse.h"
#include "esp_private/esp_crypto_lock_internal.h"
#include "mbedtls/error.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
#include "mbedtls/platform_util.h"
#include "ecdsa/ecdsa_alt.h"
#include "soc/soc_caps.h"
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
#include "esp_tee_sec_storage.h"
#else
#include "hal/ecc_ll.h"
#include "hal/ecdsa_ll.h"
#include "hal/ecdsa_hal.h"
#if SOC_MPI_SUPPORTED
#include "hal/mpi_ll.h"
#endif
#include "esp_efuse.h"
#endif
#define ECDSA_KEY_MAGIC (short) 0xECD5A
#define ECDSA_KEY_MAGIC_TEE (short) 0xA5DCE
#define ECDSA_SHA_LEN 32
#define MAX_ECDSA_COMPONENT_LEN 32
@ -51,6 +64,7 @@
__attribute__((unused)) static const char *TAG = "ecdsa_alt";
#if SOC_ECDSA_SUPPORTED
static void esp_ecdsa_acquire_hardware(void)
{
esp_crypto_ecdsa_lock_acquire();
@ -66,7 +80,7 @@ static void esp_ecdsa_acquire_hardware(void)
ecc_ll_reset_register();
}
#ifdef SOC_ECDSA_USES_MPI
#if SOC_ECDSA_USES_MPI
/* We need to reset the MPI peripheral because ECDSA peripheral
* of some targets use the MPI peripheral as well.
*/
@ -88,7 +102,7 @@ static void esp_ecdsa_release_hardware(void)
ecc_ll_power_down();
}
#ifdef SOC_ECDSA_USES_MPI
#if SOC_ECDSA_USES_MPI
MPI_RCC_ATOMIC() {
mpi_ll_enable_bus_clock(false);
}
@ -96,8 +110,9 @@ static void esp_ecdsa_release_hardware(void)
esp_crypto_ecdsa_lock_release();
}
#endif /* SOC_ECDSA_SUPPORTED */
static void ecdsa_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len)
static void __attribute__((unused)) ecdsa_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t len)
{
/* When the size is 24 bytes, it should be padded with 0 bytes*/
memset(le_point, 0x0, 32);
@ -107,7 +122,7 @@ static void ecdsa_be_to_le(const uint8_t* be_point, uint8_t *le_point, uint8_t l
}
}
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
int esp_ecdsa_load_pubkey(mbedtls_ecp_keypair *keypair, int efuse_blk)
{
int ret = -1;
@ -181,7 +196,31 @@ cleanup:
}
#endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
static int validate_ecdsa_pk_input(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *conf)
{
int ret = -1;
if (!key_ctx) {
ESP_LOGE(TAG, "mbedtls_pk_context cannot be NULL");
return ret;
}
if (!conf) {
ESP_LOGE(TAG, "esp_ecdsa_pk_conf_t cannot be NULL");
return ret;
}
if (conf->grp_id != MBEDTLS_ECP_DP_SECP192R1 && conf->grp_id != MBEDTLS_ECP_DP_SECP256R1) {
ESP_LOGE(TAG, "Invalid EC curve group id mentioned in esp_ecdsa_pk_conf_t");
return ret;
}
return 0;
}
#endif
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
int esp_ecdsa_privkey_load_mpi(mbedtls_mpi *key, int efuse_blk)
{
if (!key) {
@ -247,25 +286,18 @@ int esp_ecdsa_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *c
{
int ret = -1;
int efuse_key_block = -1;
ret = validate_ecdsa_pk_input(key_ctx, conf);
if (ret != 0) {
return ret;
}
if (conf->use_km_key) {
efuse_key_block = USE_ECDSA_KEY_FROM_KEY_MANAGER;
} else {
efuse_key_block = conf->efuse_block;
}
if (!key_ctx) {
ESP_LOGE(TAG, "mbedtls_pk_context cannot be NULL");
return ret;
}
if (!conf) {
ESP_LOGE(TAG, "esp_ecdsa_pk_conf_t cannot be NULL");
return ret;
}
if (conf->grp_id != MBEDTLS_ECP_DP_SECP192R1 && conf->grp_id != MBEDTLS_ECP_DP_SECP256R1) {
ESP_LOGE(TAG, "Invalid EC curve group id mentioned in esp_ecdsa_pk_conf_t");
return ret;
}
if ((ret = esp_ecdsa_privkey_load_pk_context(key_ctx, efuse_key_block)) != 0) {
ESP_LOGE(TAG, "Loading private key context failed, esp_ecdsa_privkey_load_pk_context() returned %d", ret);
@ -278,7 +310,7 @@ int esp_ecdsa_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *c
return ret;
}
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
if (conf->load_pubkey) {
if ((ret = esp_ecdsa_load_pubkey(keypair, efuse_key_block)) != 0) {
ESP_LOGE(TAG, "Loading public key context failed, esp_ecdsa_load_pubkey() returned %d", ret);
@ -390,7 +422,138 @@ static int esp_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s
return 0;
}
#endif
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, int slot_id)
{
int ret = -1;
uint16_t len;
esp_tee_sec_storage_type_t key_type;
if (keypair->MBEDTLS_PRIVATE(grp).id == MBEDTLS_ECP_DP_SECP256R1) {
len = 32;
key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1;
} else if (keypair->MBEDTLS_PRIVATE(grp).id == MBEDTLS_ECP_DP_SECP192R1) {
len = 24;
key_type = ESP_SEC_STG_KEY_ECDSA_SECP192R1;
} else {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
esp_tee_sec_storage_pubkey_t pubkey = {};
if (esp_tee_sec_storage_get_pubkey(slot_id, key_type, &pubkey) != ESP_OK) {
ESP_LOGE(TAG, "Failed to get public key from secure storage");
goto cleanup;
}
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&(keypair->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), pubkey.pub_x, len));
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&(keypair->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), pubkey.pub_y, len));
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&(keypair->MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z)), 1));
return 0;
cleanup:
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
int esp_ecdsa_tee_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *conf)
{
int ret = -1;
ret = validate_ecdsa_pk_input(key_ctx, conf);
if (ret != 0) {
ESP_LOGE(TAG, "Invalid input, validate_input() returned %d", ret);
return ret;
}
if (!conf->use_tee_sec_stg_key) {
ESP_LOGE(TAG, "Invalid esp_ecdsa_pk_conf_t configuration");
return ret;
}
int slot_id = conf->tee_slot_id;
if (slot_id < MIN_SEC_STG_SLOT_ID || slot_id > MAX_SEC_STG_SLOT_ID) {
ESP_LOGE(TAG, "Invalid slot id");
return ret;
}
const mbedtls_pk_info_t *pk_info;
mbedtls_ecp_keypair *keypair;
mbedtls_pk_init(key_ctx);
pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
mbedtls_pk_setup(key_ctx, pk_info);
keypair = mbedtls_pk_ec(*key_ctx);
mbedtls_mpi_init(&(keypair->MBEDTLS_PRIVATE(d)));
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) = ECDSA_KEY_MAGIC_TEE;
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(n) = slot_id;
keypair->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(p) = NULL;
if ((ret = mbedtls_ecp_group_load(&(keypair->MBEDTLS_PRIVATE(grp)), conf->grp_id)) != 0) {
ESP_LOGE(TAG, "Loading ecp group failed, mbedtls_pk_ec() returned %d", ret);
return ret;
}
if (conf->load_pubkey) {
if ((ret = esp_ecdsa_tee_load_pubkey(keypair, slot_id)) != 0) {
ESP_LOGE(TAG, "Loading public key context failed, esp_ecdsa_load_pubkey() returned %d", ret);
return ret;
}
}
return 0;
}
static int esp_ecdsa_tee_sign(mbedtls_ecp_group *grp, mbedtls_mpi* r, mbedtls_mpi* s,
const mbedtls_mpi *d, const unsigned char* msg, size_t msg_len,
ecdsa_sign_type_t k_type)
{
uint16_t len;
esp_tee_sec_storage_type_t key_type;
if (!grp || !r || !s || !d || !msg) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
if (msg_len != ECDSA_SHA_LEN) {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
if (grp->id == MBEDTLS_ECP_DP_SECP256R1) {
len = 32;
key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1;
} else if (grp->id == MBEDTLS_ECP_DP_SECP192R1) {
len = 24;
key_type = ESP_SEC_STG_KEY_ECDSA_SECP192R1;
} else {
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
if (k_type != ECDSA_K_TYPE_TRNG) {
ESP_LOGE(TAG, "ECDSA deterministic mode not supported");
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
int slot_id = d->MBEDTLS_PRIVATE(n);
esp_tee_sec_storage_sign_t sign = {};
esp_err_t err = esp_tee_sec_storage_get_signature(slot_id, key_type, (uint8_t *)msg, msg_len, &sign);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to get signature");
return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
}
mbedtls_mpi_read_binary(r, sign.sign_r, len);
mbedtls_mpi_read_binary(s, sign.sign_s, len);
return 0;
}
#endif
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
/*
* Compute ECDSA signature of a hashed message;
*/
@ -409,12 +572,22 @@ int __wrap_mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mp
/*
* Check `d` whether it contains the hardware key
*/
if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
signed short key_magic = d->MBEDTLS_PRIVATE(s);
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
if (key_magic == ECDSA_KEY_MAGIC) {
// Use hardware ECDSA peripheral
return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_TRNG);
} else {
return __real_mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, f_rng, p_rng);
}
#endif
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
if (key_magic == ECDSA_KEY_MAGIC_TEE) {
// Use TEE secure storage
return esp_ecdsa_tee_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_TRNG);
}
#endif
// Fallback to software implementation
return __real_mbedtls_ecdsa_sign(grp, r, s, d, buf, blen, f_rng, p_rng);
}
extern int __real_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
@ -438,12 +611,22 @@ int __wrap_mbedtls_ecdsa_sign_restartable(mbedtls_ecp_group *grp, mbedtls_mpi *r
/*
* Check `d` whether it contains the hardware key
*/
if (d->MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
signed short key_magic = d->MBEDTLS_PRIVATE(s);
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
if (key_magic == ECDSA_KEY_MAGIC) {
// Use hardware ECDSA peripheral
return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_TRNG);
} else {
return __real_mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, f_rng, p_rng, f_rng_blind, p_rng_blind, rs_ctx);
}
#endif
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
if (key_magic == ECDSA_KEY_MAGIC_TEE) {
// Use TEE secure storage
return esp_ecdsa_tee_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_TRNG);
}
#endif
// Fallback to software implementation
return __real_mbedtls_ecdsa_sign_restartable(grp, r, s, d, buf, blen, f_rng, p_rng, f_rng_blind, p_rng_blind, rs_ctx);
}
#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE
@ -572,7 +755,9 @@ int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
void *p_rng,
mbedtls_ecdsa_restart_ctx *rs_ctx)
{
if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) != ECDSA_KEY_MAGIC) {
signed short key_magic = ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s);
if (key_magic != ECDSA_KEY_MAGIC && key_magic != ECDSA_KEY_MAGIC_TEE) {
return __real_mbedtls_ecdsa_write_signature_restartable(ctx, md_alg, hash, hlen, sig, sig_size, slen, f_rng, p_rng, rs_ctx);
}
@ -582,17 +767,27 @@ int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
mbedtls_mpi_init(&r);
mbedtls_mpi_init(&s);
#if defined(SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE) && defined(CONFIG_MBEDTLS_ECDSA_DETERMINISTIC)
ecdsa_sign_type_t k_type = ECDSA_K_TYPE_DETERMINISITIC;
#else
ecdsa_sign_type_t k_type = ECDSA_K_TYPE_TRNG;
#endif
/*
* Check `d` whether it contains the hardware key
*/
if (ctx->MBEDTLS_PRIVATE(d).MBEDTLS_PRIVATE(s) == ECDSA_KEY_MAGIC) {
#if CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
if (key_magic == ECDSA_KEY_MAGIC) {
// Use hardware ECDSA peripheral
#if defined(SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE) && defined(CONFIG_MBEDTLS_ECDSA_DETERMINISTIC)
MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, ECDSA_K_TYPE_DETERMINISITIC));
#else
MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, ECDSA_K_TYPE_TRNG));
#endif /* SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE */
MBEDTLS_MPI_CHK(esp_ecdsa_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, k_type));
}
#endif
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
if (key_magic == ECDSA_KEY_MAGIC_TEE) {
// Use TEE secure storage
MBEDTLS_MPI_CHK(esp_ecdsa_tee_sign(&ctx->MBEDTLS_PRIVATE(grp), &r, &s, &ctx->MBEDTLS_PRIVATE(d), hash, hlen, k_type));
}
#endif
MBEDTLS_MPI_CHK(ecdsa_signature_to_asn1(&r, &s, sig, sig_size, slen));
@ -621,7 +816,7 @@ int __wrap_mbedtls_ecdsa_write_signature(mbedtls_ecdsa_context *ctx,
ctx, md_alg, hash, hlen, sig, sig_size, slen,
f_rng, p_rng, NULL);
}
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN */
#endif /* CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN */
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
static int esp_ecdsa_verify(mbedtls_ecp_group *grp,

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -27,13 +27,20 @@ extern "C" {
*/
typedef struct {
mbedtls_ecp_group_id grp_id; /*!< MbedTLS ECP group identifier */
uint8_t efuse_block; /*!< EFuse block id for ECDSA private key */
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
union {
uint8_t efuse_block; /*!< EFuse block id for ECDSA private key */
uint8_t tee_slot_id; /*!< TEE secure storage slot id for ECDSA private key */
}; /*!< Union to hold either EFuse block id or TEE secure storage slot id for ECDSA private key */
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY || CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
bool load_pubkey; /*!< Export ECDSA public key from the hardware */
#endif
bool use_km_key; /*!< Use key deployed in the key manager for ECDSA operation.
Note: The key must be already deployed by the application and it must be activated for the lifetime of this context */
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN
bool use_tee_sec_stg_key; /*!< Use key deployed in the TEE secure storage for ECDSA operation.
Note: The key must be already deployed by the application and it must be activated for the lifetime of this context */
#endif
} esp_ecdsa_pk_conf_t; //TODO: IDF-9008 (Add a config to select the ecdsa key from the key manager peripheral)
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY || __DOXYGEN__
@ -106,6 +113,38 @@ int esp_ecdsa_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *c
#endif // CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN || __DOXYGEN__
#if CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN || __DOXYGEN__
/**
* @brief Populate the public key buffer of the mbedtls_ecp_keypair context from
* the TEE secure storage.
*
* @param keypair The mbedtls ECP key-pair structure
* @param slot_id The TEE secure storage slot id that holds the private key.
*
* @return - 0 if successful else MBEDTLS_ERR_ECP_BAD_INPUT_DATA
*/
int esp_ecdsa_tee_load_pubkey(mbedtls_ecp_keypair *keypair, int slot_id);
/**
* @brief Initialize PK context and fully populate the mbedtls_ecp_keypair context.
* This function modifies the MPI struct used to represent the private key `d`
* in the ECP keypair to differentiate between TEE secure storage keys and software keys.
* It also populates the ECP group field in the mbedtls_ecp_keypair context.
* Additionally, if the load_pubkey flag is set in the esp_ecdsa_pk_conf_t config argument,
* the public key buffer of the mbedtls_ecp_keypair context will be populated.
*
* @param key_ctx The context in which this function stores the TEE secure storage context.
* This must be uninitialized.
* @param conf ESP-ECDSA private key context initialization config structure.
*
* @return - 0 if successful
* - -1 otherwise
*/
int esp_ecdsa_tee_set_pk_context(mbedtls_pk_context *key_ctx, esp_ecdsa_pk_conf_t *conf);
#endif // CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN || __DOXYGEN__
#ifdef __cplusplus
}
#endif

View File

@ -2,3 +2,4 @@
CONFIG_SECURE_ENABLE_TEE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_TWO_OTA_TEE=y
CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n

View File

@ -2,3 +2,4 @@
CONFIG_SECURE_ENABLE_TEE=y
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
CONFIG_SECURE_TEE_ATTESTATION=n
CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n

View File

@ -2,3 +2,4 @@
CONFIG_SECURE_ENABLE_TEE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_TWO_OTA_TEE=y
CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n