forked from espressif/esp-idf
Merge branch 'feature/ecdsa_op_w_tee_sec_stg' into 'master'
feat(esp_tee): Add support for mbedtls ECDSA signing with TEE secure storage Closes IDF-12183 See merge request espressif/esp-idf!37217
This commit is contained in:
@@ -91,6 +91,12 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
|||||||
help
|
help
|
||||||
eFuse block ID storing the TEE secure storage encryption key
|
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
|
config SECURE_TEE_ATTESTATION
|
||||||
bool "Enable Attestation"
|
bool "Enable Attestation"
|
||||||
default y
|
default y
|
||||||
|
@@ -248,11 +248,11 @@ secure_services:
|
|||||||
- id: 177
|
- id: 177
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_sec_storage_get_signature
|
function: esp_tee_sec_storage_get_signature
|
||||||
args: 4
|
args: 5
|
||||||
- id: 178
|
- id: 178
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_sec_storage_get_pubkey
|
function: esp_tee_sec_storage_get_pubkey
|
||||||
args: 2
|
args: 3
|
||||||
- id: 179
|
- id: 179
|
||||||
type: custom
|
type: custom
|
||||||
function: esp_tee_sec_storage_encrypt
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to fetch ECDSA pubkey (%d)", err);
|
ESP_LOGE(TAG, "Failed to fetch ECDSA pubkey (%d)", err);
|
||||||
return 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_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) {
|
if (err != ESP_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,8 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESP_SEC_STG_KEY_ECDSA_SECP256R1 = 0,
|
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_SEC_STG_MAX,
|
||||||
} esp_tee_sec_storage_type_t;
|
} 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.
|
* the key pair located in the given secure storage slot.
|
||||||
*
|
*
|
||||||
* @param[in] slot_id secure storage slot ID
|
* @param[in] slot_id secure storage slot ID
|
||||||
|
* @param[in] key_type secure storage key type
|
||||||
* @param[in] hash Message digest
|
* @param[in] hash Message digest
|
||||||
* @param[in] hlen Digest length
|
* @param[in] hlen Digest length
|
||||||
* @param[out] out_sign Output context holding the signature
|
* @param[out] out_sign Output context holding the signature
|
||||||
*
|
*
|
||||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
* @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
|
* @brief Return the public key for the given secure storage slot
|
||||||
*
|
*
|
||||||
* @param[in] slot_id secure storage slot ID
|
* @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
|
* @param[out] pubkey Output context holding the public key
|
||||||
*
|
*
|
||||||
* @return esp_err_t ESP_OK on success, appropriate error code otherwise.
|
* @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
|
* @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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
#define AES256_GCM_AAD_LEN 16
|
#define AES256_GCM_AAD_LEN 16
|
||||||
|
|
||||||
#define ECDSA_SECP256R1_KEY_LEN 32
|
#define ECDSA_SECP256R1_KEY_LEN 32
|
||||||
|
#define ECDSA_SECP192R1_KEY_LEN 24
|
||||||
|
|
||||||
/* Structure to hold metadata for secure storage slots */
|
/* Structure to hold metadata for secure storage slots */
|
||||||
typedef struct {
|
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) */
|
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;
|
} __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 */
|
/* Structure to hold AES-256 GCM key and IV */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t key[AES256_GCM_KEY_LEN]; /* Key for AES-256 GCM */
|
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 */
|
/* Union to hold different types of cryptographic keys */
|
||||||
typedef union {
|
typedef union {
|
||||||
sec_stg_ecdsa_secp256r1_t ecdsa_secp256r1; /* ECDSA SECP256R1 key pair */
|
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 */
|
sec_stg_aes256_gcm_t aes256_gcm; /* AES-256 GCM key and IV */
|
||||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_key_t;
|
} __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;
|
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) {
|
if (keyctx == NULL) {
|
||||||
return -1;
|
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_context ctxECDSA;
|
||||||
mbedtls_ecdsa_init(&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) {
|
if (ret != 0) {
|
||||||
ESP_LOGE(TAG, "Failed to generate ECDSA key");
|
ESP_LOGE(TAG, "Failed to generate ECDSA key");
|
||||||
goto exit;
|
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) {
|
if (ret != 0) {
|
||||||
goto exit;
|
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) {
|
if (ret != 0) {
|
||||||
goto exit;
|
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) {
|
if (ret != 0) {
|
||||||
goto exit;
|
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:
|
exit:
|
||||||
mbedtls_ecdsa_free(&ctxECDSA);
|
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) {
|
switch (key_type) {
|
||||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
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);
|
ESP_LOGE(TAG, "Failed to generate ECDSA keypair (%d)", ret);
|
||||||
return ESP_FAIL;
|
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);
|
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) {
|
if (slot_id > MAX_SEC_STG_SLOT_ID || hash == NULL || out_sign == NULL) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
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;
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||||
return err;
|
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_ecp_keypair_init(&priv_key);
|
||||||
mbedtls_ecdsa_init(&sign_ctx);
|
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) {
|
if (ret != 0) {
|
||||||
err = ESP_FAIL;
|
err = ESP_FAIL;
|
||||||
goto exit;
|
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;
|
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,
|
ret = mbedtls_ecdsa_sign(&sign_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &sign_ctx.MBEDTLS_PRIVATE(d), hash, hlen,
|
||||||
rand_func, NULL);
|
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;
|
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) {
|
if (ret != 0) {
|
||||||
err = ESP_FAIL;
|
err = ESP_FAIL;
|
||||||
goto exit;
|
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) {
|
if (ret != 0) {
|
||||||
err = ESP_FAIL;
|
err = ESP_FAIL;
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -508,22 +575,38 @@ exit:
|
|||||||
return err;
|
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) {
|
if (slot_id > MAX_SEC_STG_SLOT_ID || pubkey == NULL) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
sec_stg_key_t keyctx;
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pubkey->pub_x, &keyctx.ecdsa_secp256r1.pub_key[0], ECDSA_SECP256R1_KEY_LEN);
|
// Copy public key components in one shot
|
||||||
memcpy(pubkey->pub_y, &keyctx.ecdsa_secp256r1.pub_key[ECDSA_SECP256R1_KEY_LEN], ECDSA_SECP256R1_KEY_LEN);
|
memcpy(pubkey->pub_x, pub_key_src, key_len);
|
||||||
|
memcpy(pubkey->pub_y, pub_key_src + key_len, key_len);
|
||||||
|
|
||||||
return ESP_OK;
|
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;
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
ESP_LOGE(TAG, "Failed to fetch key from slot");
|
||||||
return err;
|
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);
|
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)
|
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);
|
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)) &
|
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)) &&
|
(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);
|
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)) &
|
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)))));
|
(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);
|
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,
|
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 = {};
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to generate signature!");
|
ESP_LOGE(TAG, "Failed to generate signature!");
|
||||||
goto exit;
|
goto exit;
|
||||||
@@ -307,7 +307,7 @@ static int tee_sec_stg_sign(int argc, char **argv)
|
|||||||
free(sign_hexstr);
|
free(sign_hexstr);
|
||||||
|
|
||||||
esp_tee_sec_storage_pubkey_t pubkey = {};
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to fetch public-key!");
|
ESP_LOGE(TAG, "Failed to fetch public-key!");
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
static const char *TAG = "test_esp_tee_att";
|
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)
|
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...");
|
ESP_LOGI(TAG, "Verifying the generated EAT...");
|
||||||
// Verifying the generated token
|
// 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);
|
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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include "mbedtls/ecp.h"
|
#include "mbedtls/ecp.h"
|
||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
|
#include "ecdsa/ecdsa_alt.h"
|
||||||
|
|
||||||
#include "esp_tee.h"
|
#include "esp_tee.h"
|
||||||
#include "esp_tee_sec_storage.h"
|
#include "esp_tee_sec_storage.h"
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
#include "esp_random.h"
|
#include "esp_random.h"
|
||||||
|
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
/* Note: negative value here so that assert message prints a grep-able
|
/* Note: negative value here so that assert message prints a grep-able
|
||||||
error hex value (mbedTLS uses -N for error codes) */
|
error hex value (mbedTLS uses -N for error codes) */
|
||||||
@@ -27,11 +29,16 @@
|
|||||||
|
|
||||||
#define SHA256_DIGEST_SZ (32)
|
#define SHA256_DIGEST_SZ (32)
|
||||||
#define ECDSA_SECP256R1_KEY_LEN (32)
|
#define ECDSA_SECP256R1_KEY_LEN (32)
|
||||||
|
#define ECDSA_SECP192R1_KEY_LEN (24)
|
||||||
|
|
||||||
static const char *TAG = "test_esp_tee_sec_storage";
|
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(pubkey);
|
||||||
TEST_ASSERT_NOT_NULL(digest);
|
TEST_ASSERT_NOT_NULL(digest);
|
||||||
TEST_ASSERT_NOT_NULL(sign);
|
TEST_ASSERT_NOT_NULL(sign);
|
||||||
@@ -44,7 +51,12 @@ int verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len, const esp_tee
|
|||||||
mbedtls_ecdsa_context ecdsa_context;
|
mbedtls_ecdsa_context ecdsa_context;
|
||||||
mbedtls_ecdsa_init(&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);
|
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));
|
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&r, sign->sign_r, plen));
|
||||||
@@ -81,19 +93,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));
|
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_ECDSA_SECP256R1));
|
||||||
|
|
||||||
esp_tee_sec_storage_sign_t sign = {};
|
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 = {};
|
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...");
|
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_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||||
TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(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]")
|
TEST_CASE("Test TEE Secure Storage - Encrypt-decrypt (aes256_gcm) with all key-slot IDs", "[secure_storage]")
|
||||||
{
|
{
|
||||||
const uint8_t SZ = 100;
|
const uint8_t SZ = 100;
|
||||||
@@ -161,7 +208,9 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys",
|
|||||||
const uint16_t slot_id = 7;
|
const uint16_t slot_id = 7;
|
||||||
ESP_LOGI(TAG, "Slot ID: %u - Trying AES operation with ECDSA key...", slot_id);
|
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_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),
|
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, esp_tee_sec_storage_encrypt(slot_id, plaintext, SZ, aad, sizeof(aad),
|
||||||
tag, sizeof(tag), ciphertext));
|
tag, sizeof(tag), ciphertext));
|
||||||
@@ -172,7 +221,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));
|
TEST_ESP_OK(esp_tee_sec_storage_gen_key(slot_id, ESP_SEC_STG_KEY_AES256));
|
||||||
|
|
||||||
esp_tee_sec_storage_sign_t sign = {};
|
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_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||||
TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id));
|
TEST_ASSERT_TRUE(esp_tee_sec_storage_is_slot_empty(slot_id));
|
||||||
@@ -242,14 +291,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_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_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 = {};
|
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_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, data, 0, &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, data, sizeof(data), NULL));
|
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));
|
TEST_ESP_OK(esp_tee_sec_storage_clear_slot(slot_id));
|
||||||
}
|
}
|
||||||
@@ -272,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");
|
TEST_FAIL_MESSAGE("APM violation interrupt should have been generated");
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
||||||
|
@@ -7,6 +7,8 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions_tee_ota.csv"
|
|||||||
# Increasing Bootloader log verbosity
|
# Increasing Bootloader log verbosity
|
||||||
CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y
|
CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG=y
|
||||||
|
|
||||||
|
CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN=y
|
||||||
|
|
||||||
# secure storage key slot for attestation
|
# secure storage key slot for attestation
|
||||||
CONFIG_SECURE_TEE_ATT_KEY_SLOT_ID=14
|
CONFIG_SECURE_TEE_ATT_KEY_SLOT_ID=14
|
||||||
|
|
||||||
|
@@ -294,27 +294,40 @@ if(CONFIG_MBEDTLS_HARDWARE_ECC)
|
|||||||
"${COMPONENT_DIR}/port/ecc/ecc_alt.c")
|
"${COMPONENT_DIR}/port/ecc/ecc_alt.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN OR CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
|
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")
|
target_sources(mbedcrypto PRIVATE "${COMPONENT_DIR}/port/ecdsa/ecdsa_alt.c")
|
||||||
|
|
||||||
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN)
|
set(WRAP_FUNCTIONS_SIGN
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign")
|
mbedtls_ecdsa_sign
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_restartable")
|
mbedtls_ecdsa_sign_restartable
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature")
|
mbedtls_ecdsa_write_signature
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_write_signature_restartable")
|
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)
|
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_ext")
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_det_restartable")
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_sign_det_restartable")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
|
if(CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY)
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify")
|
foreach(wrap ${WRAP_FUNCTIONS_VERIFY})
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_verify_restartable")
|
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=${wrap}")
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature")
|
endforeach()
|
||||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=mbedtls_ecdsa_read_signature_restartable")
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN)
|
||||||
|
target_link_libraries(mbedcrypto PRIVATE idf::tee_sec_storage)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -584,6 +584,11 @@ menu "mbedTLS"
|
|||||||
The key should be burnt in little endian format. espefuse.py utility handles it internally
|
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
|
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"
|
menu "Enable Software Countermeasure for ECDSA signing using on-chip ECDSA peripheral"
|
||||||
depends on MBEDTLS_HARDWARE_ECDSA_SIGN
|
depends on MBEDTLS_HARDWARE_ECDSA_SIGN
|
||||||
depends on IDF_TARGET_ESP32H2
|
depends on IDF_TARGET_ESP32H2
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
#define MBEDTLS_ASN1_PARSE_C
|
#define MBEDTLS_ASN1_PARSE_C
|
||||||
#define MBEDTLS_BIGNUM_C
|
#define MBEDTLS_BIGNUM_C
|
||||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||||
|
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||||
#define MBEDTLS_ECP_C
|
#define MBEDTLS_ECP_C
|
||||||
#define MBEDTLS_ECDSA_C
|
#define MBEDTLS_ECDSA_C
|
||||||
|
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "hal/ecc_ll.h"
|
|
||||||
#include "hal/ecdsa_ll.h"
|
#include "esp_err.h"
|
||||||
#include "hal/ecdsa_hal.h"
|
#include "esp_log.h"
|
||||||
#ifdef SOC_MPI_SUPPORTED
|
|
||||||
#include "hal/mpi_ll.h"
|
#include "hal/ecdsa_types.h"
|
||||||
#endif
|
#include "ecdsa/ecdsa_alt.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
|
||||||
#include "esp_crypto_lock.h"
|
#include "esp_crypto_lock.h"
|
||||||
#include "esp_efuse.h"
|
|
||||||
#include "esp_private/esp_crypto_lock_internal.h"
|
#include "esp_private/esp_crypto_lock_internal.h"
|
||||||
|
|
||||||
#include "mbedtls/error.h"
|
#include "mbedtls/error.h"
|
||||||
#include "mbedtls/ecdsa.h"
|
#include "mbedtls/ecdsa.h"
|
||||||
#include "mbedtls/asn1.h"
|
#include "mbedtls/asn1.h"
|
||||||
#include "mbedtls/asn1write.h"
|
#include "mbedtls/asn1write.h"
|
||||||
#include "mbedtls/platform_util.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 (short) 0xECD5A
|
||||||
|
#define ECDSA_KEY_MAGIC_TEE (short) 0xA5DCE
|
||||||
#define ECDSA_SHA_LEN 32
|
#define ECDSA_SHA_LEN 32
|
||||||
#define MAX_ECDSA_COMPONENT_LEN 32
|
#define MAX_ECDSA_COMPONENT_LEN 32
|
||||||
|
|
||||||
@@ -51,6 +64,7 @@
|
|||||||
|
|
||||||
__attribute__((unused)) static const char *TAG = "ecdsa_alt";
|
__attribute__((unused)) static const char *TAG = "ecdsa_alt";
|
||||||
|
|
||||||
|
#if SOC_ECDSA_SUPPORTED
|
||||||
static void esp_ecdsa_acquire_hardware(void)
|
static void esp_ecdsa_acquire_hardware(void)
|
||||||
{
|
{
|
||||||
esp_crypto_ecdsa_lock_acquire();
|
esp_crypto_ecdsa_lock_acquire();
|
||||||
@@ -66,7 +80,7 @@ static void esp_ecdsa_acquire_hardware(void)
|
|||||||
ecc_ll_reset_register();
|
ecc_ll_reset_register();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SOC_ECDSA_USES_MPI
|
#if SOC_ECDSA_USES_MPI
|
||||||
/* We need to reset the MPI peripheral because ECDSA peripheral
|
/* We need to reset the MPI peripheral because ECDSA peripheral
|
||||||
* of some targets use the MPI peripheral as well.
|
* of some targets use the MPI peripheral as well.
|
||||||
*/
|
*/
|
||||||
@@ -88,7 +102,7 @@ static void esp_ecdsa_release_hardware(void)
|
|||||||
ecc_ll_power_down();
|
ecc_ll_power_down();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SOC_ECDSA_USES_MPI
|
#if SOC_ECDSA_USES_MPI
|
||||||
MPI_RCC_ATOMIC() {
|
MPI_RCC_ATOMIC() {
|
||||||
mpi_ll_enable_bus_clock(false);
|
mpi_ll_enable_bus_clock(false);
|
||||||
}
|
}
|
||||||
@@ -96,8 +110,9 @@ static void esp_ecdsa_release_hardware(void)
|
|||||||
|
|
||||||
esp_crypto_ecdsa_lock_release();
|
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*/
|
/* When the size is 24 bytes, it should be padded with 0 bytes*/
|
||||||
memset(le_point, 0x0, 32);
|
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 esp_ecdsa_load_pubkey(mbedtls_ecp_keypair *keypair, int efuse_blk)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@@ -181,7 +196,31 @@ cleanup:
|
|||||||
}
|
}
|
||||||
#endif /* SOC_ECDSA_SUPPORT_EXPORT_PUBKEY */
|
#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)
|
int esp_ecdsa_privkey_load_mpi(mbedtls_mpi *key, int efuse_blk)
|
||||||
{
|
{
|
||||||
if (!key) {
|
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 ret = -1;
|
||||||
int efuse_key_block = -1;
|
int efuse_key_block = -1;
|
||||||
|
|
||||||
|
ret = validate_ecdsa_pk_input(key_ctx, conf);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (conf->use_km_key) {
|
if (conf->use_km_key) {
|
||||||
efuse_key_block = USE_ECDSA_KEY_FROM_KEY_MANAGER;
|
efuse_key_block = USE_ECDSA_KEY_FROM_KEY_MANAGER;
|
||||||
} else {
|
} else {
|
||||||
efuse_key_block = conf->efuse_block;
|
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) {
|
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);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
#if SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
||||||
if (conf->load_pubkey) {
|
if (conf->load_pubkey) {
|
||||||
if ((ret = esp_ecdsa_load_pubkey(keypair, efuse_key_block)) != 0) {
|
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);
|
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;
|
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;
|
* 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
|
* 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
|
// Use hardware ECDSA peripheral
|
||||||
return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_TRNG);
|
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,
|
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
|
* 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
|
// Use hardware ECDSA peripheral
|
||||||
return esp_ecdsa_sign(grp, r, s, d, buf, blen, ECDSA_K_TYPE_TRNG);
|
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
|
#ifdef SOC_ECDSA_SUPPORT_DETERMINISTIC_MODE
|
||||||
@@ -572,7 +755,9 @@ int __wrap_mbedtls_ecdsa_write_signature_restartable(mbedtls_ecdsa_context *ctx,
|
|||||||
void *p_rng,
|
void *p_rng,
|
||||||
mbedtls_ecdsa_restart_ctx *rs_ctx)
|
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);
|
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(&r);
|
||||||
mbedtls_mpi_init(&s);
|
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
|
* 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
|
// 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, k_type));
|
||||||
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 */
|
|
||||||
}
|
}
|
||||||
|
#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));
|
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,
|
ctx, md_alg, hash, hlen, sig, sig_size, slen,
|
||||||
f_rng, p_rng, NULL);
|
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
|
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_VERIFY
|
||||||
static int esp_ecdsa_verify(mbedtls_ecp_group *grp,
|
static int esp_ecdsa_verify(mbedtls_ecp_group *grp,
|
||||||
|
@@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -27,13 +27,20 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mbedtls_ecp_group_id grp_id; /*!< MbedTLS ECP group identifier */
|
mbedtls_ecp_group_id grp_id; /*!< MbedTLS ECP group identifier */
|
||||||
uint8_t efuse_block; /*!< EFuse block id for ECDSA private key */
|
union {
|
||||||
#ifdef SOC_ECDSA_SUPPORT_EXPORT_PUBKEY
|
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 */
|
bool load_pubkey; /*!< Export ECDSA public key from the hardware */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
bool use_km_key; /*!< Use key deployed in the key manager for ECDSA operation.
|
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 */
|
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)
|
} 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__
|
#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__
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -2,3 +2,4 @@
|
|||||||
CONFIG_SECURE_ENABLE_TEE=y
|
CONFIG_SECURE_ENABLE_TEE=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
CONFIG_PARTITION_TABLE_TWO_OTA_TEE=y
|
CONFIG_PARTITION_TABLE_TWO_OTA_TEE=y
|
||||||
|
CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n
|
||||||
|
@@ -2,3 +2,4 @@
|
|||||||
CONFIG_SECURE_ENABLE_TEE=y
|
CONFIG_SECURE_ENABLE_TEE=y
|
||||||
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
|
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
|
||||||
CONFIG_SECURE_TEE_ATTESTATION=n
|
CONFIG_SECURE_TEE_ATTESTATION=n
|
||||||
|
CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n
|
||||||
|
@@ -2,3 +2,4 @@
|
|||||||
CONFIG_SECURE_ENABLE_TEE=y
|
CONFIG_SECURE_ENABLE_TEE=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
CONFIG_PARTITION_TABLE_TWO_OTA_TEE=y
|
CONFIG_PARTITION_TABLE_TWO_OTA_TEE=y
|
||||||
|
CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n
|
||||||
|
@@ -125,7 +125,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
esp_tee_sec_storage_sign_t sign = {};
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to generate signature!");
|
ESP_LOGE(TAG, "Failed to generate signature!");
|
||||||
goto exit;
|
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_LOG_BUFFER_HEX("Signature", &sign, sizeof(sign));
|
||||||
|
|
||||||
esp_tee_sec_storage_pubkey_t pubkey = {};
|
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) {
|
if (err != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "Failed to fetch public-key!");
|
ESP_LOGE(TAG, "Failed to fetch public-key!");
|
||||||
goto exit;
|
goto exit;
|
||||||
|
Reference in New Issue
Block a user