feat(mbedtls): migrates ESP-TEE with PSA APIs

This commit is contained in:
Ashish Sharma
2025-09-16 15:05:05 +08:00
parent c47caf4f0a
commit f306dbea84
175 changed files with 4213 additions and 2038 deletions

View File

@@ -5,15 +5,85 @@
*/
#include "esp_log.h"
#include "esp_secure_boot.h"
#include "mbedtls/pk.h"
#include "psa/crypto.h"
#include "mbedtls/pk.h"
#include "mbedtls/rsa.h"
#include "mbedtls/asn1.h"
#include "mbedtls/asn1write.h"
#include "secure_boot_signature_priv.h"
ESP_LOG_ATTR_TAG(TAG, "secure_boot_v2_rsa");
/*
* Helper function to encode RSA public key (N, e) into DER format manually
* This creates a PKCS#1 RSAPublicKey structure:
*
* RSAPublicKey ::= SEQUENCE {
* modulus INTEGER, -- n
* publicExponent INTEGER -- e
* }
*/
static int encode_rsa_pubkey_der(const uint8_t *modulus, size_t modulus_len,
const uint8_t *exponent, size_t exponent_len,
uint8_t *der_buf, size_t der_buf_size,
uint8_t **der_start, size_t *der_len)
{
if (!der_buf || !der_start || !der_len || der_buf_size == 0) {
return -1;
}
int ret;
unsigned char *c = der_buf + der_buf_size;
size_t len = 0;
/* Write the exponent (e) as an INTEGER */
/* Skip leading zeros in exponent */
while (exponent_len > 0 && *exponent == 0) {
exponent++;
exponent_len--;
}
/* Write exponent */
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, exponent, exponent_len));
/* Add padding byte if MSB is set (to keep it positive) */
if (exponent_len > 0 && (exponent[0] & 0x80)) {
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, (const unsigned char *)"\x00", 1));
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, der_buf, exponent_len + ((exponent[0] & 0x80) ? 1 : 0)));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, der_buf, MBEDTLS_ASN1_INTEGER));
/* Write the modulus (N) as an INTEGER */
/* Skip leading zeros in modulus */
const uint8_t *mod_ptr = modulus;
size_t mod_len = modulus_len;
while (mod_len > 0 && *mod_ptr == 0) {
mod_ptr++;
mod_len--;
}
/* Write modulus */
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, mod_ptr, mod_len));
/* Add padding byte if MSB is set */
if (mod_len > 0 && (mod_ptr[0] & 0x80)) {
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, der_buf, (const unsigned char *)"\x00", 1));
}
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, der_buf, mod_len + ((mod_ptr[0] & 0x80) ? 1 : 0)));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, der_buf, MBEDTLS_ASN1_INTEGER));
/* Write SEQUENCE header */
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, der_buf, len));
MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, der_buf,
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
*der_start = c;
*der_len = len;
return 0;
}
esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, const ets_secure_boot_sig_block_t *trusted_block)
{
if (!sig_block || !image_digest || !trusted_block) {
@@ -23,8 +93,10 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc
esp_err_t ret = ESP_OK;
psa_status_t status;
const unsigned rsa_key_size = sizeof(sig_block->block[0].signature);
unsigned char *sig_be = calloc(1, rsa_key_size);
unsigned char *sig_be = NULL;
unsigned char *pubkey_der_buf = NULL;
sig_be = calloc(1, rsa_key_size);
if (sig_be == NULL) {
return ESP_ERR_NO_MEM;
}
@@ -33,41 +105,47 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_key_id_t key_id = 0;
/* Prepare the RSA public key data */
const mbedtls_mpi N = { .MBEDTLS_PRIVATE(s) = 1,
.MBEDTLS_PRIVATE(n) = sizeof(trusted_block->key.n)/sizeof(mbedtls_mpi_uint),
.MBEDTLS_PRIVATE(p) = (void *)trusted_block->key.n,
};
const mbedtls_mpi e = { .MBEDTLS_PRIVATE(s) = 1,
.MBEDTLS_PRIVATE(n) = sizeof(trusted_block->key.e)/sizeof(mbedtls_mpi_uint), // 1
.MBEDTLS_PRIVATE(p) = (void *)&trusted_block->key.e,
};
mbedtls_pk_context pk;
mbedtls_pk_init(&pk);
mbedtls_pk_setup(&pk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA));
mbedtls_rsa_context *rsa = mbedtls_pk_rsa(pk);
ret = mbedtls_rsa_import(rsa, &N, NULL, NULL, NULL, &e);
if (ret != 0) {
ESP_LOGE(TAG, "Failed to import RSA public key, err: %d", ret);
mbedtls_pk_free(&pk);
goto cleanup;
}
ret = mbedtls_rsa_complete(rsa);
if (ret != 0) {
ESP_LOGE(TAG, "Failed to complete RSA context, err: %d", ret);
mbedtls_pk_free(&pk);
goto cleanup;
/* Allocate buffer for DER-encoded public key */
size_t pubkey_der_buf_size = PSA_KEY_EXPORT_RSA_PUBLIC_KEY_MAX_SIZE(3072);
pubkey_der_buf = calloc(1, pubkey_der_buf_size);
if (pubkey_der_buf == NULL) {
free(sig_be);
return ESP_ERR_NO_MEM;
}
// Load the public key into PSA
ret = mbedtls_pk_get_psa_attributes(&pk, PSA_KEY_USAGE_VERIFY_HASH, &key_attributes);
/* Convert raw N and e to DER format manually */
uint8_t *der_start = NULL;
size_t der_len = 0;
/* Convert modulus from little-endian to big-endian */
uint8_t *n_be = calloc(1, rsa_key_size);
if (n_be == NULL) {
free(sig_be);
free(pubkey_der_buf);
return ESP_ERR_NO_MEM;
}
for (size_t i = 0; i < rsa_key_size; i++) {
n_be[i] = trusted_block->key.n[rsa_key_size - 1 - i];
}
/* Convert e from uint32_t to byte array (big-endian) */
uint8_t e_bytes[4];
e_bytes[0] = (trusted_block->key.e >> 24) & 0xFF;
e_bytes[1] = (trusted_block->key.e >> 16) & 0xFF;
e_bytes[2] = (trusted_block->key.e >> 8) & 0xFF;
e_bytes[3] = trusted_block->key.e & 0xFF;
ret = encode_rsa_pubkey_der(
n_be, rsa_key_size,
e_bytes, sizeof(e_bytes),
pubkey_der_buf, pubkey_der_buf_size,
&der_start, &der_len
);
free(n_be);
if (ret != 0) {
ESP_LOGE(TAG, "Failed to get key attributes, err: %d", ret);
mbedtls_pk_free(&pk);
ESP_LOGE(TAG, "Failed to encode RSA public key to DER, err: %d", ret);
goto cleanup;
}
@@ -76,16 +154,14 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc
psa_set_key_algorithm(&key_attributes, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256));
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);
ret = mbedtls_pk_import_into_psa(&pk, &key_attributes, &key_id);
if (ret != 0) {
ESP_LOGE(TAG, "Failed to import key into PSA, err: %d", ret);
mbedtls_pk_free(&pk);
/* Import DER-encoded public key into PSA */
status = psa_import_key(&key_attributes, der_start, der_len, &key_id);
if (status != PSA_SUCCESS) {
ESP_LOGE(TAG, "Failed to import key into PSA, err: %d", status);
ret = ESP_FAIL;
goto cleanup;
}
mbedtls_rsa_free(rsa);
mbedtls_pk_free(&pk);
/* Signature needs to be byte swapped into BE representation */
for (int j = 0; j < rsa_key_size; j++) {
sig_be[rsa_key_size - j - 1] = trusted_block->signature[j];
@@ -111,6 +187,7 @@ cleanup:
}
psa_reset_key_attributes(&key_attributes);
free(sig_be);
free(pubkey_der_buf);
return ret;
}