forked from espressif/esp-idf
feat(esp_tee): Add support for SECP192R1
curve in TEE secure storage
This commit is contained in:
@ -91,6 +91,12 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
help
|
||||
eFuse block ID storing the TEE secure storage encryption key
|
||||
|
||||
config SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
bool "Secure Storage: Support signing with the ECDSA SECP192R1 curve"
|
||||
default n
|
||||
help
|
||||
Enable ECDSA signing with the SECP192R1 curve using the TEE secure storage.
|
||||
|
||||
config SECURE_TEE_ATTESTATION
|
||||
bool "Enable Attestation"
|
||||
default y
|
||||
|
@ -248,11 +248,11 @@ secure_services:
|
||||
- id: 177
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_get_signature
|
||||
args: 4
|
||||
args: 5
|
||||
- id: 178
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_get_pubkey
|
||||
args: 2
|
||||
args: 3
|
||||
- id: 179
|
||||
type: custom
|
||||
function: esp_tee_sec_storage_encrypt
|
||||
|
@ -60,7 +60,7 @@ static esp_err_t gen_ecdsa_keypair_secp256r1(esp_att_ecdsa_keypair_t *keypair)
|
||||
}
|
||||
}
|
||||
|
||||
err = esp_tee_sec_storage_get_pubkey(slot_id, &pubkey);
|
||||
err = esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch ECDSA pubkey (%d)", err);
|
||||
return err;
|
||||
@ -84,7 +84,7 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
esp_err_t err = esp_tee_sec_storage_get_signature(ESP_ATT_TK_KEY_ID, (uint8_t *)digest, len, &sign);
|
||||
esp_err_t err = esp_tee_sec_storage_get_signature(ESP_ATT_TK_KEY_ID, ESP_SEC_STG_KEY_ECDSA_SECP256R1, (uint8_t *)digest, len, &sign);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ extern "C" {
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_SEC_STG_KEY_ECDSA_SECP256R1 = 0,
|
||||
ESP_SEC_STG_KEY_AES256,
|
||||
ESP_SEC_STG_KEY_AES256 = 1,
|
||||
ESP_SEC_STG_KEY_ECDSA_SECP192R1 = 2,
|
||||
ESP_SEC_STG_MAX,
|
||||
} esp_tee_sec_storage_type_t;
|
||||
|
||||
@ -71,23 +72,25 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type
|
||||
* the key pair located in the given secure storage slot.
|
||||
*
|
||||
* @param[in] slot_id secure storage slot ID
|
||||
* @param[in] key_type secure storage key type
|
||||
* @param[in] hash Message digest
|
||||
* @param[in] hlen Digest length
|
||||
* @param[out] out_sign Output context holding the signature
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign);
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign);
|
||||
|
||||
/**
|
||||
* @brief Return the public key for the given secure storage slot
|
||||
*
|
||||
* @param[in] slot_id secure storage slot ID
|
||||
* @param[in] key_type secure storage key type
|
||||
* @param[out] pubkey Output context holding the public key
|
||||
*
|
||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
||||
*/
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey);
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey);
|
||||
|
||||
/**
|
||||
* @brief Check whether the given slot in the secure storage is empty or not
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -40,6 +40,7 @@
|
||||
#define AES256_GCM_AAD_LEN 16
|
||||
|
||||
#define ECDSA_SECP256R1_KEY_LEN 32
|
||||
#define ECDSA_SECP192R1_KEY_LEN 24
|
||||
|
||||
/* Structure to hold metadata for secure storage slots */
|
||||
typedef struct {
|
||||
@ -58,6 +59,12 @@ typedef struct {
|
||||
uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN]; /* Public key for ECDSA SECP256R1 (X and Y coordinates) */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_ecdsa_secp256r1_t;
|
||||
|
||||
/* Structure to hold ECDSA SECP192R1 key pair */
|
||||
typedef struct {
|
||||
uint8_t priv_key[ECDSA_SECP192R1_KEY_LEN]; /* Private key for ECDSA SECP192R1 */
|
||||
uint8_t pub_key[2 * ECDSA_SECP192R1_KEY_LEN]; /* Public key for ECDSA SECP192R1 (X and Y coordinates) */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_ecdsa_secp192r1_t;
|
||||
|
||||
/* Structure to hold AES-256 GCM key and IV */
|
||||
typedef struct {
|
||||
uint8_t key[AES256_GCM_KEY_LEN]; /* Key for AES-256 GCM */
|
||||
@ -67,6 +74,7 @@ typedef struct {
|
||||
/* Union to hold different types of cryptographic keys */
|
||||
typedef union {
|
||||
sec_stg_ecdsa_secp256r1_t ecdsa_secp256r1; /* ECDSA SECP256R1 key pair */
|
||||
sec_stg_ecdsa_secp192r1_t ecdsa_secp192r1; /* ECDSA SECP192R1 key pair */
|
||||
sec_stg_aes256_gcm_t aes256_gcm; /* AES-256 GCM key and IV */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_key_t;
|
||||
|
||||
@ -348,39 +356,69 @@ esp_err_t esp_tee_sec_storage_init(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static int generate_ecdsa_secp256r1_key(sec_stg_key_t *keyctx)
|
||||
static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t key_type)
|
||||
{
|
||||
if (keyctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating ECDSA-SECP256R1 private key...");
|
||||
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1;
|
||||
size_t key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
curve_id = MBEDTLS_ECP_DP_SECP192R1;
|
||||
key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
#else
|
||||
ESP_LOGE(TAG, "Unsupported key type!");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating ECDSA key for curve %d...", curve_id);
|
||||
|
||||
mbedtls_ecdsa_context ctxECDSA;
|
||||
mbedtls_ecdsa_init(&ctxECDSA);
|
||||
|
||||
int ret = mbedtls_ecdsa_genkey(&ctxECDSA, MBEDTLS_ECP_DP_SECP256R1, rand_func, NULL);
|
||||
int ret = mbedtls_ecdsa_genkey(&ctxECDSA, curve_id, rand_func, NULL);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA key");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&ctxECDSA.MBEDTLS_PRIVATE(d), keyctx->ecdsa_secp256r1.priv_key, ECDSA_SECP256R1_KEY_LEN);
|
||||
uint8_t *priv_key = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ?
|
||||
keyctx->ecdsa_secp256r1.priv_key :
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
keyctx->ecdsa_secp192r1.priv_key;
|
||||
#else
|
||||
NULL;
|
||||
#endif
|
||||
|
||||
uint8_t *pub_key = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ?
|
||||
keyctx->ecdsa_secp256r1.pub_key :
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
keyctx->ecdsa_secp192r1.pub_key;
|
||||
#else
|
||||
NULL;
|
||||
#endif
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&ctxECDSA.MBEDTLS_PRIVATE(d), priv_key, key_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), &keyctx->ecdsa_secp256r1.pub_key[0], ECDSA_SECP256R1_KEY_LEN);
|
||||
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), pub_key, key_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), &keyctx->ecdsa_secp256r1.pub_key[ECDSA_SECP256R1_KEY_LEN], ECDSA_SECP256R1_KEY_LEN);
|
||||
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), pub_key + key_len, key_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
buffer_hexdump("Private key", keyctx->ecdsa_secp256r1.priv_key, sizeof(keyctx->ecdsa_secp256r1.priv_key));
|
||||
buffer_hexdump("Private key", priv_key, key_len);
|
||||
buffer_hexdump("Public key", pub_key, key_len * 2);
|
||||
|
||||
exit:
|
||||
mbedtls_ecdsa_free(&ctxECDSA);
|
||||
@ -418,7 +456,10 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type
|
||||
|
||||
switch (key_type) {
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
||||
if (generate_ecdsa_secp256r1_key(&keyctx) != 0) {
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
|
||||
#endif
|
||||
if (generate_ecdsa_key(&keyctx, key_type) != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA keypair (%d)", ret);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -437,7 +478,7 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type
|
||||
return secure_storage_write(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), key_type);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID || hash == NULL || out_sign == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@ -447,9 +488,15 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
#if !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
ESP_LOGE(TAG, "Unsupported key type!");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), ESP_SEC_STG_KEY_ECDSA_SECP256R1);
|
||||
sec_stg_key_t keyctx;
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), key_type);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||
return err;
|
||||
@ -464,7 +511,19 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz
|
||||
mbedtls_ecp_keypair_init(&priv_key);
|
||||
mbedtls_ecdsa_init(&sign_ctx);
|
||||
|
||||
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &priv_key, keyctx.ecdsa_secp256r1.priv_key, sizeof(keyctx.ecdsa_secp256r1.priv_key));
|
||||
int ret = -1;
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) {
|
||||
ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &priv_key, keyctx.ecdsa_secp256r1.priv_key, sizeof(keyctx.ecdsa_secp256r1.priv_key));
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
} else if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP192R1, &priv_key, keyctx.ecdsa_secp192r1.priv_key, sizeof(keyctx.ecdsa_secp192r1.priv_key));
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unsupported key type for signature generation");
|
||||
err = ESP_ERR_NOT_SUPPORTED;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
@ -476,7 +535,7 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating ECDSA-SECP256R1 signature...");
|
||||
ESP_LOGI(TAG, "Generating ECDSA signature...");
|
||||
|
||||
ret = mbedtls_ecdsa_sign(&sign_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &sign_ctx.MBEDTLS_PRIVATE(d), hash, hlen,
|
||||
rand_func, NULL);
|
||||
@ -486,13 +545,21 @@ esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, siz
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, ECDSA_SECP256R1_KEY_LEN);
|
||||
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_sign_t));
|
||||
|
||||
size_t key_len = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ? ECDSA_SECP256R1_KEY_LEN :
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
ECDSA_SECP192R1_KEY_LEN;
|
||||
#else
|
||||
0;
|
||||
#endif
|
||||
ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len);
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, ECDSA_SECP256R1_KEY_LEN);
|
||||
ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len);
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
@ -508,22 +575,38 @@ exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
{
|
||||
if (slot_id > MAX_SEC_STG_SLOT_ID || pubkey == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
size_t key_len;
|
||||
uint8_t *pub_key_src;
|
||||
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), ESP_SEC_STG_KEY_ECDSA_SECP256R1);
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) {
|
||||
key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
pub_key_src = keyctx.ecdsa_secp256r1.pub_key;
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
} else if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
pub_key_src = keyctx.ecdsa_secp192r1.pub_key;
|
||||
#endif
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Unsupported key type");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(sec_stg_key_t), key_type);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||
return err;
|
||||
}
|
||||
|
||||
memcpy(pubkey->pub_x, &keyctx.ecdsa_secp256r1.pub_key[0], ECDSA_SECP256R1_KEY_LEN);
|
||||
memcpy(pubkey->pub_y, &keyctx.ecdsa_secp256r1.pub_key[ECDSA_SECP256R1_KEY_LEN], ECDSA_SECP256R1_KEY_LEN);
|
||||
// Copy public key components in one shot
|
||||
memcpy(pubkey->pub_x, pub_key_src, key_len);
|
||||
memcpy(pubkey->pub_y, pub_key_src + key_len, key_len);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -618,7 +701,7 @@ static esp_err_t tee_sec_storage_crypt_common(uint16_t slot_id, uint8_t *input,
|
||||
}
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), 1);
|
||||
esp_err_t err = secure_storage_read(slot_id, (uint8_t *)&keyctx, sizeof(keyctx), ESP_SEC_STG_KEY_AES256);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||
return err;
|
||||
|
@ -18,14 +18,14 @@ esp_err_t esp_tee_sec_storage_gen_key(uint16_t slot_id, esp_tee_sec_storage_type
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(3, SS_ESP_TEE_SEC_STORAGE_GEN_KEY, slot_id, key_type);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *sign)
|
||||
esp_err_t esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *sign)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(5, SS_ESP_TEE_SEC_STORAGE_GET_SIGNATURE, slot_id, hash, hlen, sign);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(6, SS_ESP_TEE_SEC_STORAGE_GET_SIGNATURE, slot_id, key_type, hash, hlen, sign);
|
||||
}
|
||||
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
esp_err_t esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
{
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(3, SS_ESP_TEE_SEC_STORAGE_GET_PUBKEY, slot_id, pubkey);
|
||||
return esp_tee_service_call_with_noniram_intr_disabled(4, SS_ESP_TEE_SEC_STORAGE_GET_PUBKEY, slot_id, key_type, pubkey);
|
||||
}
|
||||
|
||||
bool esp_tee_sec_storage_is_slot_empty(uint16_t slot_id)
|
||||
|
@ -368,7 +368,7 @@ esp_err_t _ss_esp_tee_sec_storage_gen_key(uint16_t slot_id, uint8_t key_type)
|
||||
return esp_tee_sec_storage_gen_key(slot_id, key_type);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
|
||||
esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, uint8_t *hash, size_t hlen, esp_tee_sec_storage_sign_t *out_sign)
|
||||
{
|
||||
bool valid_addr = ((esp_tee_ptr_in_ree((void *)hash) && esp_tee_ptr_in_ree((void *)out_sign)) &
|
||||
(esp_tee_ptr_in_ree((void *)(hash + hlen)) &&
|
||||
@ -379,10 +379,10 @@ esp_err_t _ss_esp_tee_sec_storage_get_signature(uint16_t slot_id, uint8_t *hash,
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_tee_sec_storage_get_signature(slot_id, hash, hlen, out_sign);
|
||||
return esp_tee_sec_storage_get_signature(slot_id, key_type, hash, hlen, out_sign);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_storage_type_t key_type, esp_tee_sec_storage_pubkey_t *pubkey)
|
||||
{
|
||||
bool valid_addr = ((esp_tee_ptr_in_ree((void *)pubkey)) &
|
||||
(esp_tee_ptr_in_ree((void *)((char *)pubkey + sizeof(esp_tee_sec_storage_pubkey_t)))));
|
||||
@ -392,7 +392,7 @@ esp_err_t _ss_esp_tee_sec_storage_get_pubkey(uint16_t slot_id, esp_tee_sec_stora
|
||||
}
|
||||
ESP_FAULT_ASSERT(valid_addr);
|
||||
|
||||
return esp_tee_sec_storage_get_pubkey(slot_id, pubkey);
|
||||
return esp_tee_sec_storage_get_pubkey(slot_id, key_type, pubkey);
|
||||
}
|
||||
|
||||
esp_err_t _ss_esp_tee_sec_storage_encrypt(uint16_t slot_id, uint8_t *input, uint8_t len, uint8_t *aad,
|
||||
|
@ -289,7 +289,7 @@ static int tee_sec_stg_sign(int argc, char **argv)
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
err = esp_tee_sec_storage_get_signature(slot_id, digest, sizeof(digest), &sign);
|
||||
err = esp_tee_sec_storage_get_signature(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, digest, sizeof(digest), &sign);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to generate signature!");
|
||||
goto exit;
|
||||
@ -307,7 +307,7 @@ static int tee_sec_stg_sign(int argc, char **argv)
|
||||
free(sign_hexstr);
|
||||
|
||||
esp_tee_sec_storage_pubkey_t pubkey = {};
|
||||
err = esp_tee_sec_storage_get_pubkey(slot_id, &pubkey);
|
||||
err = esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch public-key!");
|
||||
goto exit;
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
static const char *TAG = "test_esp_tee_att";
|
||||
|
||||
extern int verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign);
|
||||
extern int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign, bool is_crv_p192);
|
||||
|
||||
static uint8_t hexchar_to_byte(char hex)
|
||||
{
|
||||
@ -277,7 +277,7 @@ TEST_CASE("Test TEE Attestation - Generate and verify the EAT", "[attestation]")
|
||||
|
||||
ESP_LOGI(TAG, "Verifying the generated EAT...");
|
||||
// Verifying the generated token
|
||||
TEST_ASSERT_EQUAL(0, verify_ecdsa_secp256r1_sign(digest, sizeof(digest), &pubkey_ctx, &sign_ctx));
|
||||
TEST_ASSERT_EQUAL(0, verify_ecdsa_sign(digest, sizeof(digest), &pubkey_ctx, &sign_ctx, false));
|
||||
free(token_buf);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -20,6 +20,7 @@
|
||||
#include "esp_random.h"
|
||||
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* Note: negative value here so that assert message prints a grep-able
|
||||
error hex value (mbedTLS uses -N for error codes) */
|
||||
@ -27,11 +28,16 @@
|
||||
|
||||
#define SHA256_DIGEST_SZ (32)
|
||||
#define ECDSA_SECP256R1_KEY_LEN (32)
|
||||
#define ECDSA_SECP192R1_KEY_LEN (24)
|
||||
|
||||
static const char *TAG = "test_esp_tee_sec_storage";
|
||||
|
||||
int verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign)
|
||||
int verify_ecdsa_sign(const uint8_t *digest, size_t len, const esp_tee_sec_storage_pubkey_t *pubkey, const esp_tee_sec_storage_sign_t *sign, bool is_crv_p192)
|
||||
{
|
||||
#if !CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
TEST_ASSERT_FALSE(is_crv_p192);
|
||||
#endif
|
||||
|
||||
TEST_ASSERT_NOT_NULL(pubkey);
|
||||
TEST_ASSERT_NOT_NULL(digest);
|
||||
TEST_ASSERT_NOT_NULL(sign);
|
||||
@ -44,7 +50,12 @@ int verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, const esp_tee
|
||||
mbedtls_ecdsa_context ecdsa_context;
|
||||
mbedtls_ecdsa_init(&ecdsa_context);
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1));
|
||||
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1;
|
||||
if (is_crv_p192) {
|
||||
curve_id = MBEDTLS_ECP_DP_SECP192R1;
|
||||
}
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), curve_id));
|
||||
size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P);
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&r, sign->sign_r, plen));
|
||||
@ -81,19 +92,54 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1) with all key-
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1));
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
TEST_ESP_OK(esp_tee_sec_storage_get_signature(slot_id, msg_digest, sizeof(msg_digest), &sign));
|
||||
TEST_ESP_OK(esp_tee_sec_storage_get_signature(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, msg_digest, sizeof(msg_digest), &sign));
|
||||
|
||||
esp_tee_sec_storage_pubkey_t pubkey = {};
|
||||
TEST_ESP_OK(esp_tee_sec_storage_get_pubkey(slot_id, &pubkey));
|
||||
TEST_ESP_OK(esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey));
|
||||
|
||||
ESP_LOGI(TAG, "Verifying generated signature...");
|
||||
TEST_ESP_OK(verify_ecdsa_secp256r1_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign));
|
||||
TEST_ESP_OK(verify_ecdsa_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign, false));
|
||||
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||
TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id));
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp192r1) with all key-slot IDs", "[secure_storage]")
|
||||
{
|
||||
const size_t buf_sz = 16 * 1024 + 6; // NOTE: Not an exact multiple of SHA block size
|
||||
unsigned char *message = heap_caps_malloc(buf_sz, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
TEST_ASSERT_NOT_NULL(message);
|
||||
|
||||
esp_fill_random(message, buf_sz);
|
||||
|
||||
uint8_t msg_digest[SHA256_DIGEST_SZ];
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256(message, buf_sz, msg_digest, false));
|
||||
free(message);
|
||||
|
||||
TEST_ESP_OK(esp_tee_sec_storage_init());
|
||||
|
||||
for (uint16_t slot_id = 0; slot_id <= MAX_SEC_STG_SLOT_ID; slot_id++) {
|
||||
ESP_LOGI(TAG, "Slot ID: %u", slot_id);
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP192R1));
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
TEST_ESP_OK(esp_tee_sec_storage_get_signature(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP192R1, msg_digest, sizeof(msg_digest), &sign));
|
||||
|
||||
esp_tee_sec_storage_pubkey_t pubkey = {};
|
||||
TEST_ESP_OK(esp_tee_sec_storage_get_pubkey(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP192R1, &pubkey));
|
||||
|
||||
ESP_LOGI(TAG, "Verifying generated signature...");
|
||||
TEST_ESP_OK(verify_ecdsa_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign, true));
|
||||
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||
TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Test TEE Secure Storage - Encrypt-decrypt (aes256_gcm) with all key-slot IDs", "[secure_storage]")
|
||||
{
|
||||
const uint8_t SZ = 100;
|
||||
@ -161,7 +207,9 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys",
|
||||
const uint16_t slot_id = 7;
|
||||
ESP_LOGI(TAG, "Slot ID: %u - Trying AES operation with ECDSA key...", slot_id);
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1));
|
||||
|
||||
esp_tee_sec_storage_type_t key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1;
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, key_type));
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_tee_sec_storage_encrypt(slot_id, plaintext, SZ, aad, sizeof(aad),
|
||||
tag, sizeof(tag), ciphertext));
|
||||
@ -172,7 +220,7 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys",
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_AES256));
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_tee_sec_storage_get_signature(slot_id, msg_digest, sizeof(msg_digest), &sign));
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_tee_sec_storage_get_signature(slot_id, key_type, msg_digest, sizeof(msg_digest), &sign));
|
||||
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||
TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id));
|
||||
@ -242,14 +290,16 @@ TEST_CASE("Test TEE Secure Storage - Null Pointer and Zero Length", "[secure_sto
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_decrypt(slot_id, data, sizeof(data), NULL, 0, tag, 0, data));
|
||||
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1));
|
||||
|
||||
esp_tee_sec_storage_type_t key_type = ESP_SEC_STG_KEY_ECDSA_SECP256R1;
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, key_type));
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, NULL, sizeof(data), &sign));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_get_signature(slot_id, data, 0, &sign));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, data, sizeof(data), NULL));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, key_type, NULL, sizeof(data), &sign));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_SIZE, esp_tee_sec_storage_get_signature(slot_id, key_type, data, 0, &sign));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_signature(slot_id, key_type, data, sizeof(data), NULL));
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_pubkey(slot_id, NULL));
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_tee_sec_storage_get_pubkey(slot_id, key_type, NULL));
|
||||
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions_tee_ota.csv"
|
||||
# Increasing Bootloader log verbosity
|
||||
CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y
|
||||
|
||||
CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=y
|
||||
|
||||
# secure storage key slot for attestation
|
||||
CONFIG_SECURE_TEE_ATT_KEY_SLOT_ID=14
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#define MBEDTLS_ASN1_PARSE_C
|
||||
#define MBEDTLS_BIGNUM_C
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
#define MBEDTLS_ECP_C
|
||||
#define MBEDTLS_ECDSA_C
|
||||
|
||||
|
@ -125,7 +125,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_sign_t sign = {};
|
||||
err = esp_tee_sec_storage_get_signature(KEY_SLOT_ID, msg_digest, sizeof(msg_digest), &sign);
|
||||
err = esp_tee_sec_storage_get_signature(KEY_SLOT_ID, ESP_SEC_STG_KEY_ECDSA_SECP256R1, msg_digest, sizeof(msg_digest), &sign);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to generate signature!");
|
||||
goto exit;
|
||||
@ -134,7 +134,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
|
||||
ESP_LOG_BUFFER_HEX("Signature", &sign, sizeof(sign));
|
||||
|
||||
esp_tee_sec_storage_pubkey_t pubkey = {};
|
||||
err = esp_tee_sec_storage_get_pubkey(KEY_SLOT_ID, &pubkey);
|
||||
err = esp_tee_sec_storage_get_pubkey(KEY_SLOT_ID, ESP_SEC_STG_KEY_ECDSA_SECP256R1, &pubkey);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to fetch public-key!");
|
||||
goto exit;
|
||||
|
Reference in New Issue
Block a user