mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
feat(mbedtls): migrates ESP-TEE with PSA APIs
This commit is contained in:
@@ -14,12 +14,8 @@
|
||||
#include "bootloader_sha.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#endif
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "esp_random.h"
|
||||
#include "mbedtls/ecdh.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "esp_attestation_utils.h"
|
||||
|
||||
#define ECDSA_PUBKEY_PREFIX_SZ (0x02)
|
||||
@@ -91,8 +87,8 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair
|
||||
return err;
|
||||
}
|
||||
|
||||
memcpy(sign_r, sign.sign_r, sign_r_len);
|
||||
memcpy(sign_s, sign.sign_s, sign_s_len);
|
||||
memcpy(sign_r, sign.signature, sign_r_len);
|
||||
memcpy(sign_s, sign.signature + sign_r_len, sign_s_len);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -113,44 +109,34 @@ static esp_err_t gen_ecdsa_keypair_secp256r1(esp_att_ecdsa_keypair_t *keypair)
|
||||
|
||||
memset(keypair, 0x00, sizeof(esp_att_ecdsa_keypair_t));
|
||||
|
||||
int ret = -1;
|
||||
esp_err_t err = ESP_FAIL;
|
||||
|
||||
mbedtls_ecdsa_context ecdsa_ctx;
|
||||
mbedtls_ecdsa_init(&ecdsa_ctx);
|
||||
|
||||
ret = mbedtls_ecdsa_genkey(&ecdsa_ctx, MBEDTLS_ECP_DP_SECP256R1, rng_func, NULL);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_bits(&key_attributes, 256);
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA);
|
||||
psa_status_t status = psa_generate_key(&key_attributes, &keypair->key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
size_t pvt_len = mbedtls_mpi_size(&ecdsa_ctx.MBEDTLS_PRIVATE(d));
|
||||
ret = mbedtls_mpi_write_binary(&ecdsa_ctx.MBEDTLS_PRIVATE(d), (unsigned char *)keypair->pvt_key, pvt_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
size_t pub_key_len = 0;
|
||||
uint8_t pub_key[2 * SECP256R1_ECDSA_KEY_LEN + 1] = {0};
|
||||
status = psa_export_public_key(keypair->key_id, pub_key, sizeof(pub_key), &pub_key_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
size_t pubx_len = mbedtls_mpi_size(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)));
|
||||
ret = mbedtls_mpi_write_binary(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), (unsigned char *)(keypair->pub_key_x), pubx_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
if (pub_key_len != sizeof(pub_key)) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
size_t puby_len = mbedtls_mpi_size(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)));
|
||||
ret = mbedtls_mpi_write_binary(&(ecdsa_ctx.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), (unsigned char *)(keypair->pub_key_y), puby_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
memcpy(keypair->pub_key_x, pub_key + 1, SECP256R1_ECDSA_KEY_LEN);
|
||||
memcpy(keypair->pub_key_y, pub_key + 1 + SECP256R1_ECDSA_KEY_LEN, SECP256R1_ECDSA_KEY_LEN);
|
||||
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
|
||||
keypair->curve = 0;
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA keypair (-0x%X)", -ret);
|
||||
}
|
||||
mbedtls_ecdsa_free(&ecdsa_ctx);
|
||||
return err;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair, const uint8_t *digest, const size_t len,
|
||||
@@ -164,67 +150,21 @@ static esp_err_t get_ecdsa_sign_secp256r1(const esp_att_ecdsa_keypair_t *keypair
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
|
||||
mbedtls_ecp_keypair pvt_key;
|
||||
mbedtls_mpi r, s;
|
||||
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
mbedtls_ecp_keypair_init(&pvt_key);
|
||||
|
||||
int ret = mbedtls_ecp_read_key(MBEDTLS_ECP_DP_SECP256R1, &pvt_key, keypair->pvt_key, sizeof(keypair->pvt_key));
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
size_t signature_len = 0;
|
||||
uint8_t signature[sign_r_len + sign_s_len];
|
||||
psa_status_t status = psa_sign_hash(keypair->key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, signature, sign_r_len + sign_s_len, &signature_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
mbedtls_ecdsa_context ecdsa_ctx;
|
||||
mbedtls_ecdsa_init(&ecdsa_ctx);
|
||||
|
||||
ret = mbedtls_ecdsa_from_keypair(&ecdsa_ctx, &pvt_key);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
if (signature_len != sign_r_len + sign_s_len) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
ret = mbedtls_ecdsa_sign(&ecdsa_ctx.MBEDTLS_PRIVATE(grp), &r, &s, &ecdsa_ctx.MBEDTLS_PRIVATE(d),
|
||||
digest, len, rng_func, NULL);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(sign_r, signature, sign_r_len);
|
||||
memcpy(sign_s, signature + sign_r_len, sign_s_len);
|
||||
|
||||
size_t r_len = mbedtls_mpi_size(&r);
|
||||
if (r_len > sign_s_len) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&r, (unsigned char *)(sign_r), r_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
size_t s_len = mbedtls_mpi_size(&s);
|
||||
if (s_len > sign_s_len) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&s, (unsigned char *)(sign_s), s_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA signature (-0x%X)", -ret);
|
||||
}
|
||||
|
||||
mbedtls_ecdsa_free(&ecdsa_ctx);
|
||||
mbedtls_ecp_keypair_free(&pvt_key);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_mpi_free(&r);
|
||||
|
||||
return err;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -241,33 +181,23 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey(const esp_att_ecdsa_keypair_t *keypair,
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
|
||||
size_t hexstr_len = sizeof(keypair->pub_key_x) * 2 + ECDSA_PUBKEY_PREFIX_SZ + 1;
|
||||
char *hexstr = calloc(hexstr_len, sizeof(uint8_t));
|
||||
if (hexstr == NULL) {
|
||||
err = ESP_ERR_NO_MEM;
|
||||
goto exit;
|
||||
size_t pubkey_hexstr_size = sizeof(keypair->pub_key_x) * 2 + ECDSA_PUBKEY_PREFIX_SZ + 1;
|
||||
*pubkey_hexstr = calloc(pubkey_hexstr_size, sizeof(char));
|
||||
if (*pubkey_hexstr == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
/* Checking the parity of the y-component of the public key */
|
||||
char *pubkey_prefix = (keypair->pub_key_y[SECP256R1_ECDSA_KEY_LEN - 1] & 1)
|
||||
? ECDSA_COMPRESSED_KEY_ODD_PREFIX
|
||||
: ECDSA_COMPRESSED_KEY_EVEN_PREFIX;
|
||||
memcpy(hexstr, pubkey_prefix, ECDSA_PUBKEY_PREFIX_SZ);
|
||||
char *pubkey_prefix = (keypair->pub_key_y[SECP256R1_ECDSA_KEY_LEN - 1] & 1) ? ECDSA_COMPRESSED_KEY_ODD_PREFIX : ECDSA_COMPRESSED_KEY_EVEN_PREFIX;
|
||||
memcpy(*pubkey_hexstr, pubkey_prefix, ECDSA_PUBKEY_PREFIX_SZ);
|
||||
|
||||
err = esp_att_utils_hexbuf_to_hexstr(keypair->pub_key_x, sizeof(keypair->pub_key_x),
|
||||
&hexstr[ECDSA_PUBKEY_PREFIX_SZ], hexstr_len - ECDSA_PUBKEY_PREFIX_SZ);
|
||||
int err = esp_att_utils_hexbuf_to_hexstr(keypair->pub_key_x, sizeof(keypair->pub_key_x), *pubkey_hexstr + ECDSA_PUBKEY_PREFIX_SZ, pubkey_hexstr_size - ECDSA_PUBKEY_PREFIX_SZ);
|
||||
if (err != ESP_OK) {
|
||||
goto exit;
|
||||
free(*pubkey_hexstr);
|
||||
*pubkey_hexstr = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
*pubkey_hexstr = hexstr;
|
||||
return ESP_OK;
|
||||
|
||||
exit:
|
||||
free(hexstr);
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *keypair, uint8_t *digest, const size_t len)
|
||||
@@ -276,17 +206,44 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *k
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Check if the public key is available in the keypair struct
|
||||
// We already export the public key in the gen_ecdsa_keypair_secp256r1 function
|
||||
// If not, we need to export it again
|
||||
if (keypair->pub_key_x[0] != 0) {
|
||||
memcpy(digest, keypair->pub_key_x, len);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (keypair->pub_key_y[0] != 0) {
|
||||
memcpy(digest, keypair->pub_key_y, len);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint8_t pubkey_c[SECP256R1_ECDSA_KEY_LEN * 2] = {0};
|
||||
memcpy(pubkey_c, keypair->pub_key_x, SECP256R1_ECDSA_KEY_LEN);
|
||||
memcpy(pubkey_c + SECP256R1_ECDSA_KEY_LEN, keypair->pub_key_y, SECP256R1_ECDSA_KEY_LEN);
|
||||
memcpy(pubkey_c, keypair->pub_key_x, sizeof(keypair->pub_key_x));
|
||||
memcpy(pubkey_c + SECP256R1_ECDSA_KEY_LEN, keypair->pub_key_y, sizeof(keypair->pub_key_y));
|
||||
|
||||
uint8_t pubkey_digest[SHA256_DIGEST_SZ];
|
||||
int ret = mbedtls_sha256((const unsigned char *)pubkey_c, sizeof(pubkey_c), pubkey_digest, false);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed to calculate pubkey digest (-%X)", -ret);
|
||||
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
status = psa_hash_update(&hash_op, pubkey_c, sizeof(pubkey_c));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
size_t pubkey_digest_len = 0;
|
||||
status = psa_hash_finish(&hash_op, pubkey_digest, len, &pubkey_digest_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (pubkey_digest_len != len) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
memcpy(digest, pubkey_digest, len);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,7 @@
|
||||
#include "bootloader_sha.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#endif
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "esp_random.h"
|
||||
#include "mbedtls/ecdh.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include "json_generator.h"
|
||||
#include "esp_attestation_utils.h"
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -37,9 +37,9 @@
|
||||
#include "esp32c6/rom/secure_boot.h"
|
||||
#endif
|
||||
#endif
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#define DECLARE_PRIVATE_IDENTIFIERS
|
||||
// // #include "mbedtls/sha256.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "esp_attestation_utils.h"
|
||||
|
||||
@@ -50,7 +50,7 @@ static const char *TAG = "esp_att_utils";
|
||||
|
||||
/* Forward declaration */
|
||||
static esp_err_t read_partition(uint32_t offset, void *buf, size_t size);
|
||||
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest);
|
||||
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len);
|
||||
static esp_err_t get_active_app_part_pos(esp_partition_pos_t *pos);
|
||||
static esp_err_t get_active_tee_part_pos(esp_partition_pos_t *pos);
|
||||
|
||||
@@ -78,7 +78,7 @@ static esp_err_t read_partition(uint32_t offset, void *buf, size_t size)
|
||||
return (esp_err_t)esp_tee_flash_read(offset, buf, size, true);
|
||||
}
|
||||
|
||||
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest)
|
||||
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len)
|
||||
{
|
||||
if (digest == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -87,12 +87,9 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
|
||||
uint32_t mmu_free_pages_count = esp_tee_flash_mmap_get_free_pages();
|
||||
uint32_t partial_image_len = mmu_free_pages_count * CONFIG_MMU_PAGE_SIZE;
|
||||
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
int ret = mbedtls_sha256_starts(&ctx, false);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -100,18 +97,27 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
|
||||
uint32_t mmap_len = MIN(len, partial_image_len);
|
||||
const void *image = esp_tee_flash_mmap(flash_offset, mmap_len);
|
||||
if (image == NULL) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
psa_hash_abort(&hash_op);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
status = psa_hash_update(&hash_op, image, mmap_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
mbedtls_sha256_update(&ctx, image, mmap_len);
|
||||
esp_tee_flash_munmap(image);
|
||||
|
||||
flash_offset += mmap_len;
|
||||
len -= mmap_len;
|
||||
}
|
||||
|
||||
mbedtls_sha256_finish(&ctx, digest);
|
||||
mbedtls_sha256_free(&ctx);
|
||||
size_t digest_size = 0;
|
||||
status = psa_hash_finish(&hash_op, digest, digest_len, &digest_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -154,7 +160,7 @@ static esp_err_t read_partition(uint32_t offset, void *buf, size_t size)
|
||||
return esp_flash_read(NULL, buf, offset, size);
|
||||
}
|
||||
|
||||
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest)
|
||||
esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t *digest, size_t digest_len)
|
||||
{
|
||||
if (digest == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -165,11 +171,10 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
|
||||
uint32_t mmu_free_pages_count = bootloader_mmap_get_free_pages();
|
||||
uint32_t partial_image_len = mmu_free_pages_count * CONFIG_MMU_PAGE_SIZE;
|
||||
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
|
||||
if (mbedtls_sha256_starts(&sha256_ctx, false) != 0) {
|
||||
goto exit;
|
||||
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
@@ -178,7 +183,9 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
|
||||
if (image == NULL) {
|
||||
goto exit;
|
||||
}
|
||||
if (mbedtls_sha256_update(&sha256_ctx, image, mmap_len) != 0) {
|
||||
status = psa_hash_update(&hash_op, image, mmap_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
goto exit;
|
||||
}
|
||||
bootloader_munmap(image);
|
||||
@@ -187,13 +194,16 @@ esp_err_t get_flash_contents_sha256(uint32_t flash_offset, uint32_t len, uint8_t
|
||||
len -= mmap_len;
|
||||
}
|
||||
|
||||
if (mbedtls_sha256_finish(&sha256_ctx, digest) != 0) {
|
||||
size_t digest_len = 0;
|
||||
status = psa_hash_finish(&hash_op, digest, digest_len, &digest_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = ESP_OK;
|
||||
exit:
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
psa_hash_abort(&hash_op);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -283,7 +293,7 @@ static esp_err_t get_part_digest(const esp_partition_pos_t *pos, esp_att_part_di
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
err = get_flash_contents_sha256(pos->offset, image_len, digest);
|
||||
err = get_flash_contents_sha256(pos->offset, image_len, digest, digest_len);
|
||||
if (err != ESP_OK) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -14,9 +14,7 @@
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_efuse_table.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "esp_attestation.h"
|
||||
#include "esp_attestation_utils.h"
|
||||
|
||||
@@ -63,33 +61,28 @@ static esp_err_t fetch_device_id(uint8_t *devid_buf)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
int ret = mbedtls_sha256_starts(&ctx, false);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)mac_addr, sizeof(mac_addr));
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
status = psa_hash_update(&hash_op, mac_addr, sizeof(mac_addr));
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
uint8_t digest[SHA256_DIGEST_SZ] = {0};
|
||||
ret = mbedtls_sha256_finish(&ctx, digest);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
size_t digest_len = 0;
|
||||
status = psa_hash_finish(&hash_op, devid_buf, SHA256_DIGEST_SZ, &digest_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
memcpy(devid_buf, digest, SHA256_DIGEST_SZ);
|
||||
mbedtls_sha256_free(&ctx);
|
||||
if (digest_len != SHA256_DIGEST_SZ) {
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
exit:
|
||||
return err;
|
||||
@@ -179,6 +172,8 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating attestation token");
|
||||
|
||||
if (token_buf_size < ESP_ATT_TK_MIN_SIZE) {
|
||||
ESP_LOGE(TAG, "EAT buffer too small: got %luB, need > %dB", token_buf_size, ESP_ATT_TK_MIN_SIZE);
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
@@ -211,12 +206,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
|
||||
|
||||
memset(token_buf, 0x00, token_buf_size);
|
||||
|
||||
mbedtls_sha256_context ctx;
|
||||
mbedtls_sha256_init(&ctx);
|
||||
|
||||
int ret = mbedtls_sha256_starts(&ctx, false);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
|
||||
psa_status_t status = psa_hash_setup(&hash_op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -236,9 +228,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
|
||||
}
|
||||
json_gen_push_object_str(&jstr, "header", hdr_json);
|
||||
|
||||
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)hdr_json, hdr_len - 1);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
status = psa_hash_update(&hash_op, (const unsigned char *)hdr_json, hdr_len - 1);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(hdr_json);
|
||||
@@ -253,9 +245,9 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
|
||||
}
|
||||
json_gen_push_object_str(&jstr, "eat", eat_json);
|
||||
|
||||
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)eat_json, eat_len - 1);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
status = psa_hash_update(&hash_op, (const unsigned char *)eat_json, eat_len - 1);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(eat_json);
|
||||
@@ -269,20 +261,20 @@ esp_err_t esp_att_generate_token(const uint32_t nonce, const uint32_t client_id,
|
||||
}
|
||||
json_gen_push_object_str(&jstr, "public_key", pubkey_json);
|
||||
|
||||
ret = mbedtls_sha256_update(&ctx, (const unsigned char *)pubkey_json, pubkey_len - 1);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
status = psa_hash_update(&hash_op, (const unsigned char *)pubkey_json, pubkey_len - 1);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
free(pubkey_json);
|
||||
|
||||
uint8_t digest[SHA256_DIGEST_SZ] = {0};
|
||||
ret = mbedtls_sha256_finish(&ctx, digest);
|
||||
if (ret != 0) {
|
||||
mbedtls_sha256_free(&ctx);
|
||||
size_t digest_len = 0;
|
||||
status = psa_hash_finish(&hash_op, digest, sizeof(digest), &digest_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_hash_abort(&hash_op);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
mbedtls_sha256_free(&ctx);
|
||||
|
||||
char *sign_json = NULL;
|
||||
int sign_len = -1;
|
||||
|
||||
+3
-1
@@ -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
|
||||
*/
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
#include "esp_attestation.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -79,8 +79,7 @@ typedef struct {
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t sign_r[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< R component */
|
||||
uint8_t sign_s[MAX_ECDSA_SUPPORTED_KEY_LEN]; /*!< S component */
|
||||
uint8_t signature[MAX_ECDSA_SUPPORTED_KEY_LEN * 2]; /*!< Signature */
|
||||
} __attribute__((__packed__)) esp_tee_sec_storage_ecdsa_sign_t;
|
||||
|
||||
#if ESP_TEE_BUILD && !(__DOXYGEN__)
|
||||
|
||||
@@ -13,11 +13,18 @@
|
||||
#include "esp_efuse_chip.h"
|
||||
#include "esp_random.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#if SOC_HMAC_SUPPORTED
|
||||
#include "esp_hmac.h"
|
||||
#endif
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
// #include "mbedtls/aes.h"
|
||||
// #include "mbedtls/gcm.h"
|
||||
// #include "mbedtls/sha256.h"
|
||||
// #include "mbedtls/ecdsa.h"
|
||||
// #include "mbedtls/error.h"
|
||||
#include "esp_hmac_pbkdf2.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
#include "nvs.h"
|
||||
@@ -45,13 +52,13 @@
|
||||
/* Structure to hold ECDSA SECP256R1 key pair */
|
||||
typedef struct {
|
||||
uint8_t priv_key[ECDSA_SECP256R1_KEY_LEN]; /* Private key for ECDSA SECP256R1 */
|
||||
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) + 1]; /* 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) */
|
||||
uint8_t pub_key[(2 * ECDSA_SECP192R1_KEY_LEN) + 1]; /* Public key for ECDSA SECP192R1 (X and Y coordinates) */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_ecdsa_secp192r1_t;
|
||||
|
||||
/* Structure to hold AES-256 key and IV */
|
||||
@@ -72,7 +79,7 @@ typedef struct {
|
||||
uint32_t reserved[38]; /* Reserved space for future use */
|
||||
} __attribute__((aligned(4))) __attribute__((__packed__)) sec_stg_key_t;
|
||||
|
||||
_Static_assert(sizeof(sec_stg_key_t) == 256, "Incorrect sec_stg_key_t size");
|
||||
_Static_assert(sizeof(sec_stg_key_t) == 260, "Incorrect sec_stg_key_t size");
|
||||
|
||||
static nvs_handle_t tee_nvs_hdl;
|
||||
|
||||
@@ -128,12 +135,6 @@ static int buffer_hexdump(const char *label, const void *buffer, size_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rand_func(void *rng_state, unsigned char *output, size_t len)
|
||||
{
|
||||
esp_fill_random(output, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE
|
||||
static esp_err_t compute_nvs_keys_with_hmac(esp_efuse_block_t key_blk, nvs_sec_cfg_t *cfg)
|
||||
{
|
||||
@@ -269,6 +270,8 @@ esp_err_t esp_tee_sec_storage_init(void)
|
||||
ESP_LOGW(TAG, "TEE Secure Storage enabled in insecure DEVELOPMENT mode");
|
||||
#endif
|
||||
|
||||
psa_crypto_init();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -306,66 +309,75 @@ static int generate_ecdsa_key(sec_stg_key_t *keyctx, esp_tee_sec_storage_type_t
|
||||
return -1;
|
||||
}
|
||||
|
||||
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_SECP256R1;
|
||||
size_t key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to initialize PSA Crypto: %ld", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8);
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
|
||||
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;
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8);
|
||||
#else
|
||||
ESP_LOGE(TAG, "Unsupported key-type!");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Generating ECDSA key for curve %d...", curve_id);
|
||||
|
||||
mbedtls_ecdsa_context ctxECDSA;
|
||||
mbedtls_ecdsa_init(&ctxECDSA);
|
||||
|
||||
int ret = mbedtls_ecdsa_genkey(&ctxECDSA, curve_id, rand_func, NULL);
|
||||
if (ret != 0) {
|
||||
status = psa_generate_key(&key_attributes, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA key: %ld", status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
uint8_t *priv_key = (key_type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) ?
|
||||
keyctx->ecdsa_secp256r1.priv_key :
|
||||
size_t priv_key_len = 0;
|
||||
size_t pub_key_len = 0;
|
||||
|
||||
/* Use the correct union member based on key type */
|
||||
uint8_t *priv_key_buf = NULL;
|
||||
size_t priv_key_buf_size = 0;
|
||||
uint8_t *pub_key_buf = NULL;
|
||||
size_t pub_key_buf_size = 0;
|
||||
|
||||
if (key_type == ESP_SEC_STG_KEY_ECDSA_SECP192R1) {
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
keyctx->ecdsa_secp192r1.priv_key;
|
||||
#else
|
||||
NULL;
|
||||
priv_key_buf = keyctx->ecdsa_secp192r1.priv_key;
|
||||
priv_key_buf_size = sizeof(keyctx->ecdsa_secp192r1.priv_key);
|
||||
pub_key_buf = keyctx->ecdsa_secp192r1.pub_key;
|
||||
pub_key_buf_size = sizeof(keyctx->ecdsa_secp192r1.pub_key);
|
||||
#endif
|
||||
} else {
|
||||
priv_key_buf = keyctx->ecdsa_secp256r1.priv_key;
|
||||
priv_key_buf_size = sizeof(keyctx->ecdsa_secp256r1.priv_key);
|
||||
pub_key_buf = keyctx->ecdsa_secp256r1.pub_key;
|
||||
pub_key_buf_size = sizeof(keyctx->ecdsa_secp256r1.pub_key);
|
||||
}
|
||||
|
||||
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(Q).MBEDTLS_PRIVATE(X)), pub_key, key_len);
|
||||
if (ret != 0) {
|
||||
status = psa_export_key(key_id, priv_key_buf, priv_key_buf_size, &priv_key_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to export ECDSA private key: %ld", status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y)), pub_key + key_len, key_len);
|
||||
if (ret != 0) {
|
||||
status = psa_export_public_key(key_id, pub_key_buf, pub_key_buf_size, &pub_key_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to export ECDSA public key: %ld", status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&ctxECDSA.MBEDTLS_PRIVATE(d), priv_key, key_len);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
buffer_hexdump("Private key", priv_key, key_len);
|
||||
buffer_hexdump("Public key", pub_key, key_len * 2);
|
||||
buffer_hexdump("Private key", priv_key_buf, priv_key_len);
|
||||
buffer_hexdump("Public key", pub_key_buf, pub_key_len);
|
||||
|
||||
exit:
|
||||
mbedtls_ecdsa_free(&ctxECDSA);
|
||||
return ret;
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
return status == PSA_SUCCESS ? 0 : -1;
|
||||
}
|
||||
|
||||
static int generate_aes256_key(sec_stg_key_t *keyctx)
|
||||
@@ -454,68 +466,47 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign(const esp_tee_sec_storage_key_cfg_t *cf
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_ecp_keypair priv_key;
|
||||
mbedtls_ecdsa_context sign_ctx;
|
||||
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
mbedtls_ecp_keypair_init(&priv_key);
|
||||
mbedtls_ecdsa_init(&sign_ctx);
|
||||
|
||||
size_t key_len = 0;
|
||||
int ret = -1;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
|
||||
uint8_t *priv_key = NULL;
|
||||
size_t priv_key_len = 0;
|
||||
if (cfg->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));
|
||||
key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8);
|
||||
priv_key = keyctx.ecdsa_secp256r1.priv_key;
|
||||
priv_key_len = sizeof(keyctx.ecdsa_secp256r1.priv_key);
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
} else if (cfg->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));
|
||||
key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8);
|
||||
priv_key = keyctx.ecdsa_secp192r1.priv_key;
|
||||
priv_key_len = sizeof(keyctx.ecdsa_secp192r1.priv_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_ecdsa_from_keypair(&sign_ctx, &priv_key);
|
||||
if (ret != 0) {
|
||||
psa_status_t status = psa_import_key(&key_attributes, priv_key, priv_key_len, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "Failed to import ECDSA private key: %ld", status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ESP_LOGD(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);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error generating signature: %d", ret);
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
|
||||
ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len);
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
|
||||
size_t signature_len = 0;
|
||||
status = psa_sign_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), hash, hlen, out_sign->signature, sizeof(out_sign->signature), &signature_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
err = ESP_FAIL;
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA signature: %ld", status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
mbedtls_ecdsa_free(&sign_ctx);
|
||||
mbedtls_ecp_keypair_free(&priv_key);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_mpi_free(&r);
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -534,6 +525,20 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg
|
||||
|
||||
sec_stg_key_t keyctx;
|
||||
size_t keyctx_len = sizeof(keyctx);
|
||||
|
||||
/* Read key from storage first before accessing its fields */
|
||||
err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read key from secure storage");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keyctx.type != cfg->type) {
|
||||
ESP_LOGE(TAG, "Key type mismatch");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* Now determine the public key source and length based on key type */
|
||||
uint8_t *pub_key_src = NULL;
|
||||
size_t pub_key_len = 0;
|
||||
|
||||
@@ -553,20 +558,18 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
err = secure_storage_read(cfg->id, (void *)&keyctx, &keyctx_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read key from secure storage");
|
||||
return err;
|
||||
// If pub_key_src[0] is 0x04, then it is compressed format
|
||||
// This is what we save when exporting the public key from PSA
|
||||
if (pub_key_src[0] == 0x04) {
|
||||
memcpy(out_pubkey->pub_x, pub_key_src + 1, pub_key_len);
|
||||
memcpy(out_pubkey->pub_y, pub_key_src + pub_key_len + 1, pub_key_len);
|
||||
} else {
|
||||
// This case is when the keys are host generated
|
||||
// In this case the public key is stored as X and Y concatenated without 0x04 prefix
|
||||
memcpy(out_pubkey->pub_x, pub_key_src, pub_key_len);
|
||||
memcpy(out_pubkey->pub_y, pub_key_src + pub_key_len, pub_key_len);
|
||||
}
|
||||
|
||||
if (keyctx.type != cfg->type) {
|
||||
ESP_LOGE(TAG, "Key type mismatch");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
memcpy(out_pubkey->pub_x, pub_key_src, pub_key_len);
|
||||
memcpy(out_pubkey->pub_y, pub_key_src + pub_key_len, pub_key_len);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -731,7 +734,7 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_ecp_keypair_calc_public(&keypair, rand_func, NULL);
|
||||
ret = mbedtls_ecp_keypair_calc_public(&keypair, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
@@ -739,16 +742,16 @@ esp_err_t esp_tee_sec_storage_ecdsa_sign_pbkdf2(const esp_tee_sec_storage_pbkdf2
|
||||
|
||||
ret = mbedtls_ecdsa_sign(&keypair.MBEDTLS_PRIVATE(grp), &r, &s,
|
||||
&keypair.MBEDTLS_PRIVATE(d), hash, hlen,
|
||||
rand_func, NULL);
|
||||
mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE);
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(out_sign, 0x00, sizeof(esp_tee_sec_storage_ecdsa_sign_t));
|
||||
ret = mbedtls_mpi_write_binary(&r, out_sign->sign_r, key_len);
|
||||
ret = mbedtls_mpi_write_binary(&r, out_sign->signature, key_len);
|
||||
if (ret == 0) {
|
||||
ret = mbedtls_mpi_write_binary(&s, out_sign->sign_s, key_len);
|
||||
ret = mbedtls_mpi_write_binary(&s, out_sign->signature + key_len, key_len);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
|
||||
@@ -54,6 +54,12 @@ ssize_t _write_r(struct _reent *r, int fd, const void *ptr, size_t len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t _open_r(struct _reent *r, const char *path, int flags, int mode)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _getpid_r(struct _reent *r)
|
||||
{
|
||||
return 1;
|
||||
@@ -180,14 +186,26 @@ int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C61
|
||||
// #if CONFIG_IDF_TARGET_ESP32H2
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
return (void *) -1;
|
||||
}
|
||||
#endif
|
||||
// #endif
|
||||
|
||||
void esp_tee_include_syscalls_impl(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int _unlink_r(struct _reent *r, const char *path)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _rename_r(struct _reent *r, const char *src, const char *dst)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -214,3 +214,8 @@ ASSERT ((_tee_iram_end <= _tee_dram_start),
|
||||
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
|
||||
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
|
||||
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
|
||||
/* MMU Page Alignment Checks */
|
||||
ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % 0x10000) == 0,
|
||||
"Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!");
|
||||
ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % 0x10000) == 0,
|
||||
"Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (0x10000/64KB)!");
|
||||
|
||||
@@ -219,3 +219,8 @@ ASSERT ((_tee_iram_end <= _tee_dram_start),
|
||||
"Error: TEE IRAM segment overflowed into the DRAM segment! Increase CONFIG_SECURE_TEE_IRAM_SIZE as required.");
|
||||
ASSERT((_tee_heap_end >= _tee_heap_start + 0x2000),
|
||||
"Error: TEE heap size is too small - minimum is 8KB (0x2000)! Increase CONFIG_SECURE_TEE_DRAM_SIZE as required.");
|
||||
/* MMU Page Alignment Checks */
|
||||
ASSERT ((CONFIG_SECURE_TEE_IROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0,
|
||||
"Error: SECURE_TEE_IROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!");
|
||||
ASSERT ((CONFIG_SECURE_TEE_DROM_SIZE % CONFIG_MMU_PAGE_SIZE) == 0,
|
||||
"Error: SECURE_TEE_DROM_SIZE must be a multiple of MMU_PAGE_SIZE (CONFIG_MMU_PAGE_SIZE)!");
|
||||
|
||||
Reference in New Issue
Block a user