mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-28 16:46:31 +03:00
feat: migrates esp_tee to PSA APIs
This commit is contained in:
committed by
Mahavir Jain
parent
fdd5ef561d
commit
e7e31d5d39
@@ -12,14 +12,14 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
config SECURE_TEE_IRAM_SIZE
|
||||
hex "IRAM region size"
|
||||
default 0x8000
|
||||
range 0x5000 0xA000
|
||||
range 0x5000 0xF000
|
||||
help
|
||||
This configuration sets the IRAM size for the TEE module.
|
||||
This should be 256-byte (0x100) aligned.
|
||||
|
||||
config SECURE_TEE_DRAM_SIZE
|
||||
hex "DRAM region size"
|
||||
default 0x4000
|
||||
default 0x5000
|
||||
range 0x3000 0x7000
|
||||
help
|
||||
This configuration sets the DRAM size for the TEE module.
|
||||
@@ -45,7 +45,7 @@ menu "ESP-TEE (Trusted Execution Environment)"
|
||||
|
||||
config SECURE_TEE_IROM_SIZE
|
||||
hex
|
||||
default 0x10000
|
||||
default 0x20000
|
||||
help
|
||||
This should be a multiple of MMU_PAGE_SIZE.
|
||||
|
||||
|
||||
@@ -14,12 +14,8 @@
|
||||
#include "bootloader_sha.h"
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#endif
|
||||
|
||||
#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)
|
||||
@@ -277,16 +207,30 @@ esp_err_t esp_att_utils_ecdsa_get_pubkey_digest(const esp_att_ecdsa_keypair_t *k
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#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,8 @@
|
||||
#include "esp32c6/rom/secure_boot.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "mbedtls/sha256.h"
|
||||
|
||||
#define DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "psa/crypto.h"
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include "esp_attestation_utils.h"
|
||||
|
||||
@@ -50,7 +49,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 +77,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 +86,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 +96,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 +159,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 +170,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 +182,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 +193,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_size = 0;
|
||||
status = psa_hash_finish(&hash_op, digest, digest_len, &digest_size);
|
||||
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 +292,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"
|
||||
|
||||
#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;
|
||||
@@ -211,12 +204,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 +226,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 +243,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 +259,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -86,8 +86,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__)
|
||||
|
||||
@@ -15,15 +15,11 @@
|
||||
#include "spi_flash_mmap.h"
|
||||
#if SOC_HMAC_SUPPORTED
|
||||
#include "esp_hmac.h"
|
||||
#include "esp_hmac_pbkdf2.h"
|
||||
#else
|
||||
#include "mbedtls/md.h"
|
||||
#endif
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "esp_hmac_pbkdf2.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "mbedtls/psa_util.h"
|
||||
|
||||
#include "esp_rom_sys.h"
|
||||
#include "nvs.h"
|
||||
@@ -142,12 +138,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)
|
||||
{
|
||||
@@ -314,10 +304,10 @@ esp_err_t esp_tee_sec_storage_clear_key(const char *key_id)
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t get_ecdsa_curve_info(esp_tee_sec_storage_type_t type, sec_stg_key_t *ctx, mbedtls_ecp_group_id *curve,
|
||||
size_t *key_len, uint8_t **priv_key, uint8_t **pub_key)
|
||||
static esp_err_t get_ecdsa_curve_info(esp_tee_sec_storage_type_t type, sec_stg_key_t *ctx,
|
||||
uint8_t **priv_key, size_t *priv_key_len, uint8_t **pub_key, size_t *pub_key_len)
|
||||
{
|
||||
if (!ctx || !curve || !key_len || !priv_key || !pub_key) {
|
||||
if (!ctx || !priv_key || !priv_key_len || !pub_key || !pub_key_len) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -325,26 +315,26 @@ static esp_err_t get_ecdsa_curve_info(esp_tee_sec_storage_type_t type, sec_stg_k
|
||||
|
||||
switch (type) {
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
||||
*curve = MBEDTLS_ECP_DP_SECP256R1;
|
||||
*key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
*priv_key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
*priv_key = ctx->ecdsa_secp256r1.priv_key;
|
||||
*pub_key_len = sizeof(ctx->ecdsa_secp256r1.pub_key);
|
||||
*pub_key = ctx->ecdsa_secp256r1.pub_key;
|
||||
err = ESP_OK;
|
||||
break;
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
|
||||
*curve = MBEDTLS_ECP_DP_SECP192R1;
|
||||
*key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
*priv_key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
*priv_key = ctx->ecdsa_secp192r1.priv_key;
|
||||
*pub_key_len = sizeof(ctx->ecdsa_secp192r1.pub_key);
|
||||
*pub_key = ctx->ecdsa_secp192r1.pub_key;
|
||||
err = ESP_OK;
|
||||
break;
|
||||
#endif
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP384R1:
|
||||
*curve = MBEDTLS_ECP_DP_SECP384R1;
|
||||
*key_len = ECDSA_SECP384R1_KEY_LEN;
|
||||
*priv_key_len = ECDSA_SECP384R1_KEY_LEN;
|
||||
*priv_key = ctx->ecdsa_secp384r1.priv_key;
|
||||
*pub_key_len = sizeof(ctx->ecdsa_secp384r1.pub_key);
|
||||
*pub_key = ctx->ecdsa_secp384r1.pub_key;
|
||||
err = ESP_OK;
|
||||
break;
|
||||
@@ -364,46 +354,70 @@ 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_NONE;
|
||||
size_t key_len = 0;
|
||||
uint8_t *priv_key = NULL;
|
||||
uint8_t *pub_key = NULL;
|
||||
|
||||
if (get_ecdsa_curve_info(key_type, keyctx, &curve_id, &key_len, &priv_key, &pub_key) != ESP_OK) {
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
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;
|
||||
esp_err_t err = get_ecdsa_curve_info(key_type, keyctx, &priv_key_buf, &priv_key_buf_size, &pub_key_buf, &pub_key_buf_size);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to get ECDSA curve info: %d", err);
|
||||
return -1;
|
||||
}
|
||||
psa_set_key_bits(&key_attributes, priv_key_buf_size * 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));
|
||||
|
||||
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) {
|
||||
psa_status_t status = psa_generate_key(&key_attributes, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to generate ECDSA key: %ld", status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_write_binary(&(ctxECDSA.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X)), pub_key, key_len);
|
||||
if (ret != 0) {
|
||||
size_t priv_key_len = 0;
|
||||
size_t pub_key_len = 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) {
|
||||
/* PSA exports public key with 0x04 prefix (65 bytes for secp256r1, 49 bytes for secp192r1)
|
||||
* We need to strip the prefix and store only X and Y coordinates (64 bytes for secp256r1, 48 bytes for secp192r1)
|
||||
* Use fixed-size array to avoid VLA issues with goto statements
|
||||
*/
|
||||
uint8_t pub_key_with_prefix[(2 * ECDSA_SECP384R1_KEY_LEN) + 1]; /* Max size: 65 bytes for secp256r1 */
|
||||
size_t pub_key_len_with_prefix = 0;
|
||||
size_t expected_pub_key_len_with_prefix = pub_key_buf_size + 1;
|
||||
|
||||
status = psa_export_public_key(key_id, pub_key_with_prefix, sizeof(pub_key_with_prefix), &pub_key_len_with_prefix);
|
||||
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;
|
||||
/* Strip the 0x04 prefix if present */
|
||||
if (pub_key_len_with_prefix == expected_pub_key_len_with_prefix && pub_key_with_prefix[0] == 0x04) {
|
||||
memcpy(pub_key_buf, pub_key_with_prefix + 1, pub_key_buf_size);
|
||||
pub_key_len = pub_key_buf_size;
|
||||
} else {
|
||||
/* Fallback: copy directly if format is unexpected (should not happen with PSA) */
|
||||
ESP_LOGW(TAG, "Unexpected public key format, copying directly");
|
||||
size_t copy_len = (pub_key_len_with_prefix < pub_key_buf_size) ? pub_key_len_with_prefix : pub_key_buf_size;
|
||||
memcpy(pub_key_buf, pub_key_with_prefix, copy_len);
|
||||
pub_key_len = copy_len;
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -500,66 +514,53 @@ 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 keypair_ctx;
|
||||
mbedtls_ecdsa_context sign_ctx;
|
||||
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));
|
||||
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
mbedtls_ecp_keypair_init(&keypair_ctx);
|
||||
mbedtls_ecdsa_init(&sign_ctx);
|
||||
|
||||
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
|
||||
size_t key_len = 0;
|
||||
uint8_t *priv_key = NULL;
|
||||
uint8_t *pub_key = NULL;
|
||||
|
||||
err = get_ecdsa_curve_info(keyctx.type, &keyctx, &curve_id, &key_len, &priv_key, &pub_key);
|
||||
if (err != ESP_OK) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
size_t priv_key_len = 0;
|
||||
if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP256R1) {
|
||||
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) {
|
||||
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 CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN
|
||||
} else if (cfg->type == ESP_SEC_STG_KEY_ECDSA_SECP384R1) {
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP384R1_KEY_LEN * 8);
|
||||
priv_key = keyctx.ecdsa_secp384r1.priv_key;
|
||||
priv_key_len = sizeof(keyctx.ecdsa_secp384r1.priv_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
int ret = mbedtls_ecp_read_key(curve_id, &keypair_ctx, priv_key, key_len);
|
||||
if (ret != 0) {
|
||||
err = ESP_FAIL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_ecdsa_from_keypair(&sign_ctx, &keypair_ctx);
|
||||
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(&keypair_ctx);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_mpi_free(&r);
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -579,6 +580,7 @@ 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");
|
||||
@@ -590,18 +592,34 @@ esp_err_t esp_tee_sec_storage_ecdsa_get_pubkey(const esp_tee_sec_storage_key_cfg
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
|
||||
size_t key_len = 0;
|
||||
uint8_t *priv_key = NULL;
|
||||
uint8_t *pub_key = NULL;
|
||||
/* Now determine the public key source and length based on key type */
|
||||
uint8_t *pub_key_src = NULL;
|
||||
size_t pub_key_len = 0;
|
||||
|
||||
err = get_ecdsa_curve_info(keyctx.type, &keyctx, &curve_id, &key_len, &priv_key, &pub_key);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
switch (cfg->type) {
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
||||
pub_key_src = keyctx.ecdsa_secp256r1.pub_key;
|
||||
pub_key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
break;
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
|
||||
pub_key_src = keyctx.ecdsa_secp192r1.pub_key;
|
||||
pub_key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
break;
|
||||
#endif
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP384R1:
|
||||
pub_key_src = keyctx.ecdsa_secp384r1.pub_key;
|
||||
pub_key_len = ECDSA_SECP384R1_KEY_LEN;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unsupported key-type");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
memcpy(out_pubkey->pub_x, pub_key, key_len);
|
||||
memcpy(out_pubkey->pub_y, pub_key + key_len, key_len);
|
||||
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;
|
||||
}
|
||||
@@ -771,7 +789,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;
|
||||
@@ -779,16 +797,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,24 @@ int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C61
|
||||
void *_sbrk(ptrdiff_t incr)
|
||||
{
|
||||
return (void *) -1;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "esp_app_desc.h"
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/* TEE symbols */
|
||||
extern uint32_t _tee_stack;
|
||||
extern uint32_t _tee_bss_start;
|
||||
@@ -154,6 +156,13 @@ void __attribute__((noreturn)) esp_tee_init(uint32_t ree_entry_addr, uint32_t re
|
||||
}
|
||||
ESP_FAULT_ASSERT(err == ESP_OK);
|
||||
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to initialize PSA Crypto! (0x%08x)", status);
|
||||
abort();
|
||||
}
|
||||
ESP_FAULT_ASSERT(status == PSA_SUCCESS);
|
||||
|
||||
/* Initializing the secure storage */
|
||||
err = esp_tee_sec_storage_init();
|
||||
if (err != ESP_OK) {
|
||||
|
||||
@@ -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)!");
|
||||
|
||||
@@ -230,7 +230,7 @@ static void init_ota_sem(void)
|
||||
static int create_ota_task(const char *url, const char *task_name, void (*ota_task)(void *))
|
||||
{
|
||||
init_ota_sem();
|
||||
if (xTaskCreate(ota_task, task_name, configMINIMAL_STACK_SIZE * 3, (void *)url, 5, NULL) != pdPASS) {
|
||||
if (xTaskCreate(ota_task, task_name, configMINIMAL_STACK_SIZE * 4, (void *)url, 5, NULL) != pdPASS) {
|
||||
ESP_LOGE(TAG, "Task creation failed for %s", task_name);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
#include "esp_console.h"
|
||||
#include "argtable3/argtable3.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#include "example_tee_srv.h"
|
||||
@@ -32,6 +30,8 @@
|
||||
#define AES256_GCM_TAG_LEN (16)
|
||||
#define MAX_AES_PLAINTEXT_LEN (256)
|
||||
|
||||
#define ECDSA_SECP256R1_KEY_LEN (32)
|
||||
|
||||
static const char *TAG = "tee_sec_stg";
|
||||
|
||||
static esp_err_t hexstr_to_hexbuf(const char *hexstr, size_t hexstr_len, void *hexbuf, size_t hexbuf_sz)
|
||||
@@ -96,57 +96,33 @@ static esp_err_t verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len,
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
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_PUBLIC_KEY(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));
|
||||
|
||||
mbedtls_ecdsa_context ecdsa_context;
|
||||
mbedtls_ecdsa_init(&ecdsa_context);
|
||||
uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN + 1];
|
||||
pub_key[0] = 0x04;
|
||||
memcpy(pub_key + 1, pubkey->pub_x, ECDSA_SECP256R1_KEY_LEN);
|
||||
memcpy(pub_key + 1 + ECDSA_SECP256R1_KEY_LEN, pubkey->pub_y, ECDSA_SECP256R1_KEY_LEN);
|
||||
|
||||
int ret = mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
|
||||
if (ret != 0) {
|
||||
psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P);
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&r, sign->sign_r, plen);
|
||||
if (ret != 0) {
|
||||
status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, sizeof(sign->signature));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&s, sign->sign_s, plen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
|
||||
if (key_id) {
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -166,8 +142,10 @@ static int get_msg_sha256(int argc, char **argv)
|
||||
const char *msg = (const char *)cmd_get_msg_sha256_args.msg->sval[0];
|
||||
|
||||
uint8_t msg_digest[SHA256_DIGEST_SZ];
|
||||
int ret = mbedtls_sha256((const unsigned char *)msg, strlen(msg), msg_digest, false);
|
||||
if (ret != 0) {
|
||||
size_t msg_len = strlen(msg);
|
||||
size_t digest_len = 0;
|
||||
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)msg, msg_len, msg_digest, sizeof(msg_digest), &digest_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to calculate message hash!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
|
||||
# Reducing TEE I/DRAM sizes
|
||||
# 24KB
|
||||
CONFIG_SECURE_TEE_IRAM_SIZE=0x6000
|
||||
# 12KB
|
||||
CONFIG_SECURE_TEE_DRAM_SIZE=0x3000
|
||||
# 16KB
|
||||
CONFIG_SECURE_TEE_DRAM_SIZE=0x4000
|
||||
|
||||
# Disable TEE logs (also disable all panic logs)
|
||||
CONFIG_SECURE_TEE_DEBUG_MODE=n
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Reducing TEE I/DRAM sizes
|
||||
# 29KB
|
||||
CONFIG_SECURE_TEE_IRAM_SIZE=0x7400
|
||||
# 20KB
|
||||
CONFIG_SECURE_TEE_DRAM_SIZE=0x5000
|
||||
|
||||
# TEE Secure Storage: Release mode
|
||||
CONFIG_SECURE_TEE_SEC_STG_MODE_RELEASE=y
|
||||
|
||||
@@ -18,4 +18,4 @@ CONFIG_SECURE_TEE_SEC_STG_EFUSE_HMAC_KEY_ID=5
|
||||
|
||||
# Increasing TEE DRAM size
|
||||
# 18KB
|
||||
CONFIG_SECURE_TEE_DRAM_SIZE=0x4800
|
||||
CONFIG_SECURE_TEE_DRAM_SIZE=0x5000
|
||||
|
||||
@@ -21,26 +21,30 @@ endif()
|
||||
|
||||
set(mbedtls_test_srcs_dir "${idf_path}/components/mbedtls/test_apps/main")
|
||||
|
||||
# AES
|
||||
#AES
|
||||
if(CONFIG_SOC_AES_SUPPORTED)
|
||||
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes.c"
|
||||
"${mbedtls_test_srcs_dir}/test_aes_gcm.c"
|
||||
"${mbedtls_test_srcs_dir}/test_aes_perf.c")
|
||||
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_psa_aes.c"
|
||||
"${mbedtls_test_srcs_dir}/test_psa_aes_gcm.c"
|
||||
"${mbedtls_test_srcs_dir}/test_aes_perf.c"
|
||||
)
|
||||
endif()
|
||||
|
||||
# SHA
|
||||
if(CONFIG_SOC_SHA_SUPPORTED)
|
||||
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_mbedtls_sha.c"
|
||||
"${mbedtls_test_srcs_dir}/test_sha.c"
|
||||
"${mbedtls_test_srcs_dir}/test_sha_perf.c")
|
||||
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_sha.c"
|
||||
"${mbedtls_test_srcs_dir}/test_sha_perf.c")
|
||||
endif()
|
||||
|
||||
# Mixed
|
||||
if(CONFIG_SOC_AES_SUPPORTED AND CONFIG_SOC_SHA_SUPPORTED)
|
||||
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_aes_sha_parallel.c")
|
||||
endif()
|
||||
# ECC
|
||||
|
||||
#ECC
|
||||
if(CONFIG_SOC_ECC_SUPPORTED)
|
||||
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_ecp.c")
|
||||
endif()
|
||||
|
||||
# Utility
|
||||
list(APPEND srcs "${mbedtls_test_srcs_dir}/test_apb_dport_access.c"
|
||||
"${mbedtls_test_srcs_dir}/test_mbedtls_utils.c")
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -9,10 +9,64 @@
|
||||
#include "nvs_flash.h"
|
||||
#include "unity.h"
|
||||
#include "memory_checks.h"
|
||||
#include "psa/crypto.h"
|
||||
#if SOC_SHA_SUPPORT_PARALLEL_ENG
|
||||
#include "sha/sha_parallel_engine.h"
|
||||
#else
|
||||
#include "sha/sha_core.h"
|
||||
#endif
|
||||
#include "bignum_impl.h"
|
||||
|
||||
/* setUp runs before every test */
|
||||
void setUp(void)
|
||||
{
|
||||
#if SOC_SHA_SUPPORTED
|
||||
// Execute esp_sha operation to allocate internal SHA semaphore (in case of ESP32)
|
||||
// and initial DMA setup memory which is considered as leaked otherwise
|
||||
const uint8_t input_buffer[64] = {0};
|
||||
uint8_t output_buffer[64];
|
||||
#if SOC_SHA_SUPPORT_SHA1
|
||||
esp_sha(SHA1, input_buffer, sizeof(input_buffer), output_buffer);
|
||||
#endif // SOC_SHA_SUPPORT_SHA1
|
||||
#if SOC_SHA_SUPPORT_SHA256
|
||||
esp_sha(SHA2_256, input_buffer, sizeof(input_buffer), output_buffer);
|
||||
#endif // SOC_SHA_SUPPORT_SHA256
|
||||
#if SOC_SHA_SUPPORT_SHA512
|
||||
esp_sha(SHA2_512, input_buffer, sizeof(input_buffer), output_buffer);
|
||||
#endif // SOC_SHA_SUPPORT_SHA512
|
||||
#endif // SOC_SHA_SUPPORTED
|
||||
|
||||
#if defined(CONFIG_MBEDTLS_HARDWARE_MPI)
|
||||
esp_mpi_enable_hardware_hw_op();
|
||||
esp_mpi_disable_hardware_hw_op();
|
||||
#endif // CONFIG_MBEDTLS_HARDWARE_MPI
|
||||
|
||||
#if SOC_AES_SUPPORTED
|
||||
// Execute mbedtls_aes_init operation to allocate AES interrupt
|
||||
// allocation memory which is considered as leak otherwise
|
||||
const uint8_t plaintext[16] = {0};
|
||||
uint8_t ciphertext[32];
|
||||
const uint8_t key[16] = { 0 };
|
||||
psa_status_t status;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT);
|
||||
psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&attributes, 128);
|
||||
status = psa_import_key(&attributes, key, sizeof(key), &key_id);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
size_t output_len = 0;
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext, sizeof(plaintext), ciphertext, sizeof(ciphertext), &output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
|
||||
const uint8_t plaintext_long[256] = {0};
|
||||
uint8_t ciphertext_long[272];
|
||||
output_len = 0;
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, plaintext_long, sizeof(plaintext_long), ciphertext_long, sizeof(ciphertext_long), &output_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
psa_destroy_key(key_id);
|
||||
#endif // SOC_AES_SUPPORTED
|
||||
test_utils_record_free_mem();
|
||||
test_utils_set_leak_level(CONFIG_UNITY_CRITICAL_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL);
|
||||
test_utils_set_leak_level(CONFIG_UNITY_WARN_LEAK_LEVEL_GENERAL, ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_GENERAL);
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#define MBEDTLS_DECLARE_PRIVATE_IDENTIFIERS
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "esp_tee_attestation.h"
|
||||
@@ -24,6 +22,7 @@
|
||||
/* Note: negative value here so that assert message prints a grep-able
|
||||
error hex value (mbedTLS uses -N for error codes) */
|
||||
#define TEST_ASSERT_MBEDTLS_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X))
|
||||
#define TEST_ASSERT_PSA_OK(X) TEST_ASSERT_EQUAL_HEX32(0, -(X))
|
||||
|
||||
#define SHA256_DIGEST_SZ (32)
|
||||
#define ECDSA_SECP256R1_KEY_LEN (32)
|
||||
@@ -165,19 +164,13 @@ static void prehash_token_data(const char *token_json, uint8_t *digest, size_t l
|
||||
char *eat_str = cJSON_PrintUnformatted(eat);
|
||||
char *public_key_str = cJSON_PrintUnformatted(public_key);
|
||||
|
||||
mbedtls_sha256_context sha256_ctx;
|
||||
|
||||
mbedtls_sha256_init(&sha256_ctx);
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_starts(&sha256_ctx, false));
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)header_str, strlen(header_str)));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)eat_str, strlen(eat_str)));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_update(&sha256_ctx, (const unsigned char *)public_key_str, strlen(public_key_str)));
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256_finish(&sha256_ctx, digest));
|
||||
|
||||
mbedtls_sha256_free(&sha256_ctx);
|
||||
psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
|
||||
TEST_ASSERT_PSA_OK(psa_hash_setup(&operation, PSA_ALG_SHA_256));
|
||||
size_t digest_len = 0;
|
||||
TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)header_str, strlen(header_str)));
|
||||
TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)eat_str, strlen(eat_str)));
|
||||
TEST_ASSERT_PSA_OK(psa_hash_update(&operation, (const unsigned char *)public_key_str, strlen(public_key_str)));
|
||||
TEST_ASSERT_PSA_OK(psa_hash_finish(&operation, digest, SHA256_DIGEST_SZ, &digest_len));
|
||||
|
||||
free(public_key_str);
|
||||
free(eat_str);
|
||||
@@ -239,13 +232,13 @@ static void fetch_signature(const char *token_json, esp_tee_sec_storage_ecdsa_si
|
||||
uint8_t *sign_r_buf = NULL;
|
||||
size_t sign_r_buf_sz = 0;
|
||||
hexstr_to_bytes(sign_r->valuestring, &sign_r_buf, &sign_r_buf_sz);
|
||||
memcpy(sign_ctx->sign_r, sign_r_buf, sign_r_buf_sz);
|
||||
memcpy(sign_ctx->signature, sign_r_buf, sign_r_buf_sz);
|
||||
free(sign_r_buf);
|
||||
|
||||
uint8_t *sign_s_buf = NULL;
|
||||
size_t sign_s_buf_sz = 0;
|
||||
hexstr_to_bytes(sign_s->valuestring, &sign_s_buf, &sign_s_buf_sz);
|
||||
memcpy(sign_ctx->sign_s, sign_s_buf, sign_s_buf_sz);
|
||||
memcpy(sign_ctx->signature + sign_r_buf_sz, sign_s_buf, sign_s_buf_sz);
|
||||
free(sign_s_buf);
|
||||
|
||||
cJSON_Delete(root);
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/sha512.h"
|
||||
#include "ecdsa/ecdsa_alt.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
@@ -26,6 +21,7 @@
|
||||
#include "nvs.h"
|
||||
#include "unity.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "ecdsa/ecdsa_alt.h"
|
||||
|
||||
/* Note: negative value here so that assert message prints a grep-able
|
||||
error hex value (mbedTLS uses -N for error codes) */
|
||||
@@ -58,49 +54,70 @@ int verify_ecdsa_sign(const esp_tee_sec_storage_type_t key_type, const uint8_t *
|
||||
TEST_ASSERT_NOT_NULL(sign);
|
||||
TEST_ASSERT_NOT_EQUAL(0, len);
|
||||
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
int err = ESP_FAIL;
|
||||
|
||||
mbedtls_ecdsa_context ecdsa_context;
|
||||
mbedtls_ecdsa_init(&ecdsa_context);
|
||||
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_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
|
||||
mbedtls_ecp_group_id curve_id = MBEDTLS_ECP_DP_NONE;
|
||||
size_t pub_key_len;
|
||||
size_t signature_size;
|
||||
|
||||
/* Use fixed-size array large enough for all supported curves (max: SECP384R1 = 2*48+1 = 97) */
|
||||
uint8_t pub_key[2 * ECDSA_SECP384R1_KEY_LEN + 1];
|
||||
|
||||
switch (key_type) {
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
||||
curve_id = MBEDTLS_ECP_DP_SECP256R1;
|
||||
break;
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP192R1:
|
||||
curve_id = MBEDTLS_ECP_DP_SECP192R1;
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP192R1_KEY_LEN * 8);
|
||||
pub_key_len = ECDSA_SECP192R1_KEY_LEN;
|
||||
signature_size = ECDSA_SECP192R1_KEY_LEN * 2;
|
||||
break;
|
||||
#endif // CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP192R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP256R1:
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP256R1_KEY_LEN * 8);
|
||||
pub_key_len = ECDSA_SECP256R1_KEY_LEN;
|
||||
signature_size = ECDSA_SECP256R1_KEY_LEN * 2;
|
||||
break;
|
||||
#endif
|
||||
#if CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN
|
||||
case ESP_SEC_STG_KEY_ECDSA_SECP384R1:
|
||||
curve_id = MBEDTLS_ECP_DP_SECP384R1;
|
||||
psa_set_key_bits(&key_attributes, ECDSA_SECP384R1_KEY_LEN * 8);
|
||||
pub_key_len = ECDSA_SECP384R1_KEY_LEN;
|
||||
signature_size = ECDSA_SECP384R1_KEY_LEN * 2;
|
||||
break;
|
||||
#endif
|
||||
#endif // CONFIG_SECURE_TEE_SEC_STG_SUPPORT_SECP384R1_SIGN
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unsupported key type: %d", key_type);
|
||||
return -1;
|
||||
ESP_LOGE(TAG, "Unsupported ECDSA curve type");
|
||||
err = ESP_ERR_INVALID_ARG;
|
||||
goto exit;
|
||||
}
|
||||
pub_key[0] = 0x04;
|
||||
memcpy(pub_key + 1, pubkey->pub_x, pub_key_len);
|
||||
memcpy(pub_key + 1 + pub_key_len, pubkey->pub_y, pub_key_len);
|
||||
|
||||
psa_status_t status = psa_import_key(&key_attributes, pub_key, 2 * pub_key_len + 1, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to import ECDSA public key: %ld", status);
|
||||
err = ESP_ERR_INVALID_ARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
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);
|
||||
status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, signature_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to verify ECDSA signature: %ld", status);
|
||||
err = ESP_ERR_INVALID_ARG;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&r, sign->sign_r, plen));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&s, sign->sign_s, plen));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s));
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
err = ESP_OK;
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_storage]")
|
||||
@@ -112,7 +129,9 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora
|
||||
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));
|
||||
size_t msg_digest_len = 0;
|
||||
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
free(message);
|
||||
|
||||
esp_tee_sec_storage_key_cfg_t key_cfg = {
|
||||
@@ -130,12 +149,12 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp256r1)", "[sec_stora
|
||||
TEST_ESP_OK(esp_tee_sec_storage_gen_key(&key_cfg));
|
||||
|
||||
esp_tee_sec_storage_ecdsa_sign_t sign = {};
|
||||
TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, sizeof(msg_digest), &sign));
|
||||
TEST_ESP_OK(esp_tee_sec_storage_ecdsa_sign(&key_cfg, msg_digest, msg_digest_len, &sign));
|
||||
|
||||
esp_tee_sec_storage_ecdsa_pubkey_t pubkey = {};
|
||||
TEST_ESP_OK(esp_tee_sec_storage_ecdsa_get_pubkey(&key_cfg, &pubkey));
|
||||
|
||||
TEST_ESP_OK(verify_ecdsa_sign(key_cfg.type, msg_digest, sizeof(msg_digest), &pubkey, &sign));
|
||||
TEST_ESP_OK(verify_ecdsa_sign(key_cfg.type, msg_digest, msg_digest_len, &pubkey, &sign));
|
||||
|
||||
TEST_ESP_OK(esp_tee_sec_storage_clear_key(key_cfg.id));
|
||||
}
|
||||
@@ -151,7 +170,10 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp192r1)", "[sec_stora
|
||||
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));
|
||||
size_t msg_digest_len = 0;
|
||||
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len);
|
||||
(void)msg_digest_len;
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
free(message);
|
||||
|
||||
esp_tee_sec_storage_key_cfg_t key_cfg = {
|
||||
@@ -191,7 +213,11 @@ TEST_CASE("Test TEE Secure Storage - Sign-verify (ecdsa_secp384r1)", "[sec_stora
|
||||
esp_fill_random(message, buf_sz);
|
||||
|
||||
uint8_t msg_digest[SHA384_DIGEST_SZ];
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha512(message, buf_sz, msg_digest, false));
|
||||
// TEST_ASSERT_MBEDTLS_OK(mbedtls_sha512(message, buf_sz, msg_digest, false));
|
||||
size_t msg_digest_len = 0;
|
||||
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_384, message, buf_sz, msg_digest, sizeof(msg_digest), &msg_digest_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
(void)msg_digest_len;
|
||||
free(message);
|
||||
|
||||
esp_tee_sec_storage_key_cfg_t key_cfg = {
|
||||
@@ -284,7 +310,9 @@ TEST_CASE("Test TEE Secure Storage - Operations with invalid/non-existent keys",
|
||||
TEST_ASSERT_NOT_NULL(message);
|
||||
esp_fill_random(message, SZ);
|
||||
uint8_t msg_digest[SHA256_DIGEST_SZ];
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_sha256(message, SZ, msg_digest, false));
|
||||
size_t msg_digest_len = 0;
|
||||
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, message, SZ, msg_digest, sizeof(msg_digest), &msg_digest_len);
|
||||
TEST_ASSERT_EQUAL(PSA_SUCCESS, status);
|
||||
free(message);
|
||||
|
||||
const char *key_id = "key_id_misc";
|
||||
@@ -586,18 +614,18 @@ static void test_ecdsa_sign(mbedtls_ecp_group_id gid)
|
||||
};
|
||||
TEST_ASSERT_EQUAL(0, esp_ecdsa_tee_set_pk_context(&key_ctx, &conf));
|
||||
|
||||
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(key_ctx);
|
||||
mbedtls_ecp_keypair *keypair = key_ctx.MBEDTLS_PRIVATE(pk_ctx); //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, sha_len, NULL, NULL));
|
||||
|
||||
esp_tee_sec_storage_ecdsa_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));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&r, sign.signature, key_len));
|
||||
TEST_ASSERT_MBEDTLS_OK(mbedtls_mpi_write_binary(&s, sign.signature + key_len, key_len));
|
||||
|
||||
TEST_ESP_OK(verify_ecdsa_sign(key_type, sha, sha_len, &pubkey, &sign));
|
||||
|
||||
mbedtls_pk_free(&key_ctx);
|
||||
esp_ecdsa_free_pk_context(&key_ctx);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
|
||||
@@ -11,3 +11,6 @@ CONFIG_SECURE_TEE_TEST_MODE=y
|
||||
# Setting partition table
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0xF000
|
||||
|
||||
# TEE IRAM size
|
||||
CONFIG_SECURE_TEE_IRAM_SIZE=0xC400
|
||||
|
||||
@@ -83,9 +83,21 @@
|
||||
#define MBEDTLS_ECP_VERIFY_ALT
|
||||
#endif
|
||||
|
||||
#if !SOC_HMAC_SUPPORTED
|
||||
#define MBEDTLS_MD_C
|
||||
#endif
|
||||
#define PSA_WANT_ECC_SECP_R1_192 1
|
||||
#define PSA_WANT_ECC_SECP_R1_384 1
|
||||
#undef PSA_WANT_ECC_SECP_K1_192
|
||||
#undef PSA_WANT_ECC_SECP_K1_256
|
||||
#undef PSA_WANT_ECC_SECP_R1_224
|
||||
#undef PSA_WANT_ECC_SECP_R1_521
|
||||
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_256
|
||||
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_384
|
||||
#undef PSA_WANT_ECC_BRAINPOOL_P_R1_512
|
||||
#undef MBEDTLS_ECP_DP_BP256R1_ENABLED
|
||||
#undef MBEDTLS_ECP_DP_BP384R1_ENABLED
|
||||
#undef MBEDTLS_ECP_DP_BP512R1_ENABLED
|
||||
#undef MBEDTLS_ECP_DP_SECP192K1_ENABLED
|
||||
#undef MBEDTLS_ECP_DP_SECP224K1_ENABLED
|
||||
#undef MBEDTLS_ECP_DP_SECP256K1_ENABLED
|
||||
|
||||
#define MBEDTLS_ENTROPY_C
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "mbedtls/gcm.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "esp_tee.h"
|
||||
#include "secure_service_num.h"
|
||||
@@ -45,42 +45,72 @@ static esp_err_t aes_gcm_crypt_common(example_aes_gcm_ctx_t *ctx, uint8_t *tag,
|
||||
ESP_LOGI(TAG, "Secure service call: PROTECTED M-mode");
|
||||
ESP_LOGI(TAG, "AES-256-GCM %s", is_encrypt ? "encryption" : "decryption");
|
||||
|
||||
mbedtls_gcm_context gcm;
|
||||
mbedtls_gcm_init(&gcm);
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT;
|
||||
psa_status_t status;
|
||||
psa_key_id_t key_id;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_algorithm_t alg = PSA_ALG_GCM;
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
|
||||
psa_set_key_algorithm(&key_attributes, alg);
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_AES);
|
||||
psa_set_key_bits(&key_attributes, AES256_KEY_BITS);
|
||||
status = psa_import_key(&key_attributes, key, sizeof(key), &key_id);
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Error in importing key: %d", status);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
if (is_encrypt) {
|
||||
status = psa_aead_encrypt_setup(&operation, key_id, alg);
|
||||
} else {
|
||||
status = psa_aead_decrypt_setup(&operation, key_id, alg);
|
||||
}
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Error in AEAD setup: %d", status);
|
||||
goto cleanup;
|
||||
}
|
||||
status = psa_aead_set_lengths(&operation, ctx->aad_len, ctx->input_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Error in setting lengths: %d", status);
|
||||
goto cleanup;
|
||||
}
|
||||
psa_aead_set_nonce(&operation, nonce, AES256_NONCE_LEN);
|
||||
if (ctx->aad_len > 0) {
|
||||
status = psa_aead_update_ad(&operation, ctx->aad, ctx->aad_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Error in updating AAD: %d", status);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = mbedtls_gcm_setkey(&gcm, MBEDTLS_CIPHER_ID_AES, key, AES256_KEY_BITS);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in setting key: %d", ret);
|
||||
size_t output_len = 0;
|
||||
status = psa_aead_update(&operation, ctx->input, ctx->input_len, output, ctx->input_len, &output_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Error in updating aead: %d", status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (is_encrypt) {
|
||||
ret = mbedtls_gcm_crypt_and_tag(&gcm, MBEDTLS_GCM_ENCRYPT, ctx->input_len,
|
||||
nonce, AES256_NONCE_LEN,
|
||||
ctx->aad, ctx->aad_len,
|
||||
ctx->input, output,
|
||||
tag_len, tag);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in encrypting data: %d", ret);
|
||||
size_t output_tag_len = 0;
|
||||
status = psa_aead_finish(&operation, output + output_len, ctx->input_len + tag_len - output_len, &output_len, tag, tag_len, &output_tag_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Error in finishing encryption: %d", status);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
ret = mbedtls_gcm_auth_decrypt(&gcm, ctx->input_len,
|
||||
nonce, AES256_NONCE_LEN,
|
||||
ctx->aad, ctx->aad_len,
|
||||
tag, tag_len,
|
||||
ctx->input, output);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Error in decrypting data: %d", ret);
|
||||
size_t plaintext_len = 0;
|
||||
status = psa_aead_verify(&operation, output, ctx->input_len, &plaintext_len, tag, tag_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Error in verifying decryption: %d", status);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
err = ESP_OK;
|
||||
|
||||
cleanup:
|
||||
mbedtls_gcm_free(&gcm);
|
||||
psa_aead_abort(&operation);
|
||||
psa_destroy_key(key_id);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "example_service.h"
|
||||
|
||||
#define EXAMPLE_BUF_SZ (32)
|
||||
#define AES256_GCM_TAG_LEN (12)
|
||||
#define AES256_GCM_TAG_LEN (16)
|
||||
#define AES256_GCM_AAD_LEN (16)
|
||||
|
||||
static const char *TAG = "example_tee_basic";
|
||||
|
||||
@@ -4,3 +4,4 @@ CONFIG_SECURE_TEE_LOG_LEVEL_INFO=y
|
||||
CONFIG_PARTITION_TABLE_SINGLE_APP_TEE=y
|
||||
CONFIG_SECURE_TEE_ATTESTATION=n
|
||||
CONFIG_MBEDTLS_TEE_SEC_STG_ECDSA_SIGN=n
|
||||
CONFIG_SECURE_TEE_IRAM_SIZE=0xC000
|
||||
|
||||
@@ -29,7 +29,9 @@ Before the project configuration and build, be sure to set the correct chip targ
|
||||
|
||||
Open the project configuration menu (`idf.py menuconfig`).
|
||||
|
||||
- Configure the secure storage example key ID at `Example Configuration → TEE: Secure Storage Key ID`.
|
||||
- Configure unique secure storage key IDs for each workflow:
|
||||
- `Example Configuration → TEE: Secure Storage Key ID for signing`
|
||||
- `Example Configuration → TEE: Secure Storage Key ID for encryption`
|
||||
|
||||
TEE Secure Storage follows the NVS partition format and uses an XTS-AES encryption scheme derived via the HMAC peripheral or software-based HMAC implementation. It supports two key derivation modes, configurable via `CONFIG_SECURE_TEE_SEC_STG_MODE`:
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
config EXAMPLE_TEE_SEC_STG_KEY_STR_ID
|
||||
string "TEE: Secure Storage Key ID"
|
||||
default "key_id_0"
|
||||
config EXAMPLE_TEE_SEC_STG_SIGN_KEY_STR_ID
|
||||
string "TEE: Secure Storage Key ID for signing"
|
||||
default "sign_key_id_0"
|
||||
help
|
||||
This configuration sets the key string identifier from the TEE secure storage
|
||||
storing the ECDSA keypair for executing sign/verify operations
|
||||
from the TEE side
|
||||
Identifier for the ECDSA keypair stored in secure storage and used for
|
||||
sign/verify operations in this example.
|
||||
|
||||
config EXAMPLE_TEE_SEC_STG_ENC_KEY_STR_ID
|
||||
string "TEE: Secure Storage Key ID for encryption"
|
||||
default "aes_key_id_0"
|
||||
help
|
||||
Identifier for the AES-256 key stored in secure storage and used for
|
||||
the AEAD encryption/decryption part of this example.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "esp_tee_sec_storage.h"
|
||||
#include "secure_service_num.h"
|
||||
@@ -28,7 +26,8 @@
|
||||
#define AES256_GCM_TAG_LEN (16)
|
||||
#define AES256_GCM_AAD_LEN (16)
|
||||
|
||||
#define KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_KEY_STR_ID)
|
||||
#define SIGN_KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_SIGN_KEY_STR_ID)
|
||||
#define ENC_KEY_STR_ID (CONFIG_EXAMPLE_TEE_SEC_STG_ENC_KEY_STR_ID)
|
||||
#define MAX_AES_PLAINTEXT_LEN (128)
|
||||
|
||||
static const char *message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
|
||||
@@ -47,56 +46,33 @@ static esp_err_t verify_ecdsa_secp256r1_sign(const uint8_t *digest, size_t len,
|
||||
|
||||
esp_err_t err = ESP_FAIL;
|
||||
|
||||
mbedtls_mpi r, s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
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_PUBLIC_KEY(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));
|
||||
|
||||
mbedtls_ecdsa_context ecdsa_context;
|
||||
mbedtls_ecdsa_init(&ecdsa_context);
|
||||
uint8_t pub_key[2 * ECDSA_SECP256R1_KEY_LEN + 1];
|
||||
pub_key[0] = 0x04;
|
||||
memcpy(pub_key + 1, pubkey->pub_x, ECDSA_SECP256R1_KEY_LEN);
|
||||
memcpy(pub_key + 1 + ECDSA_SECP256R1_KEY_LEN, pubkey->pub_y, ECDSA_SECP256R1_KEY_LEN);
|
||||
|
||||
int ret = mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
|
||||
if (ret != 0) {
|
||||
psa_status_t status = psa_import_key(&key_attributes, pub_key, sizeof(pub_key), &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P);
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&r, sign->sign_r, plen);
|
||||
if (ret != 0) {
|
||||
status = psa_verify_hash(key_id, PSA_ALG_ECDSA(PSA_ALG_SHA_256), digest, len, sign->signature, sizeof(sign->signature));
|
||||
if (status != PSA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&s, sign->sign_s, plen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), pubkey->pub_x, plen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), pubkey->pub_y, plen);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), digest, len, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
psa_destroy_key(key_id);
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
|
||||
err = ESP_OK;
|
||||
|
||||
exit:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -107,14 +83,15 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
|
||||
ESP_LOGI(TAG, "Message-to-be-signed: %s", msg);
|
||||
|
||||
uint8_t msg_digest[SHA256_DIGEST_SZ];
|
||||
int ret = mbedtls_sha256((const unsigned char *)msg, strlen(msg), msg_digest, false);
|
||||
if (ret != 0) {
|
||||
size_t msg_digest_len = 0;
|
||||
psa_status_t status = psa_hash_compute(PSA_ALG_SHA_256, (const uint8_t *)msg, strlen(msg), msg_digest, sizeof(msg_digest), &msg_digest_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to calculate message hash!");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_key_cfg_t cfg = {
|
||||
.id = (const char *)(KEY_STR_ID),
|
||||
.id = (const char *)(SIGN_KEY_STR_ID),
|
||||
.type = ESP_SEC_STG_KEY_ECDSA_SECP256R1
|
||||
};
|
||||
|
||||
@@ -131,7 +108,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_ecdsa_sign_t sign = {};
|
||||
err = esp_tee_sec_storage_ecdsa_sign(&cfg, msg_digest, sizeof(msg_digest), &sign);
|
||||
err = esp_tee_sec_storage_ecdsa_sign(&cfg, msg_digest, msg_digest_len, &sign);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to generate signature!");
|
||||
goto exit;
|
||||
@@ -146,7 +123,7 @@ static void example_tee_sec_stg_sign_verify(void *pvParameter)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = verify_ecdsa_secp256r1_sign(msg_digest, sizeof(msg_digest), &pubkey, &sign);
|
||||
err = verify_ecdsa_secp256r1_sign(msg_digest, msg_digest_len, &pubkey, &sign);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify signature!");
|
||||
goto exit;
|
||||
@@ -182,7 +159,7 @@ static void example_tee_sec_stg_encrypt_decrypt(void *pvParameter)
|
||||
}
|
||||
|
||||
esp_tee_sec_storage_key_cfg_t cfg = {
|
||||
.id = (const char *)(KEY_STR_ID),
|
||||
.id = (const char *)(ENC_KEY_STR_ID),
|
||||
.type = ESP_SEC_STG_KEY_AES256
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user