mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
feat(bootloader_support): Migrated mbedTLS crypto APIs to PSA
This commit is contained in:
committed by
Ashish Sharma
parent
25814db7b1
commit
c39347c00c
@@ -9,7 +9,7 @@
|
||||
that can be used from bootloader or app code.
|
||||
|
||||
This header is available to source code in the bootloader & bootloader_support components only.
|
||||
Use mbedTLS APIs or include esp32/sha.h to calculate SHA256 in IDF apps.
|
||||
Use PSA APIs or include esp32/sha.h to calculate SHA256 in IDF apps.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -179,42 +179,55 @@ void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest
|
||||
#else /* NON_OS_BUILD || CONFIG_APP_BUILD_TYPE_RAM */
|
||||
|
||||
#include "bootloader_flash_priv.h"
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <mbedtls/sha512.h>
|
||||
#include "psa/crypto.h"
|
||||
|
||||
bootloader_sha256_handle_t bootloader_sha256_start(void)
|
||||
{
|
||||
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)malloc(sizeof(mbedtls_sha256_context));
|
||||
if (!ctx) {
|
||||
// Initialize PSA Crypto subsystem
|
||||
psa_status_t status = psa_crypto_init();
|
||||
if (status != PSA_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
mbedtls_sha256_init(ctx);
|
||||
int ret = mbedtls_sha256_starts(ctx, false);
|
||||
if (ret != 0) {
|
||||
|
||||
psa_hash_operation_t *op = (psa_hash_operation_t *)malloc(sizeof(psa_hash_operation_t));
|
||||
if (!op) {
|
||||
return NULL;
|
||||
}
|
||||
return ctx;
|
||||
|
||||
*op = psa_hash_operation_init();
|
||||
status = psa_hash_setup(op, PSA_ALG_SHA_256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
free(op);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (bootloader_sha256_handle_t)op;
|
||||
}
|
||||
|
||||
void bootloader_sha256_data(bootloader_sha256_handle_t handle, const void *data, size_t data_len)
|
||||
{
|
||||
assert(handle != NULL);
|
||||
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
|
||||
int ret = mbedtls_sha256_update(ctx, data, data_len);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
psa_hash_operation_t *op = (psa_hash_operation_t *)handle;
|
||||
|
||||
psa_status_t status = psa_hash_update(op, data, data_len);
|
||||
assert(status == PSA_SUCCESS);
|
||||
(void)status; // Suppress unused variable warning in release builds
|
||||
}
|
||||
|
||||
void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest)
|
||||
{
|
||||
assert(handle != NULL);
|
||||
mbedtls_sha256_context *ctx = (mbedtls_sha256_context *)handle;
|
||||
psa_hash_operation_t *op = (psa_hash_operation_t *)handle;
|
||||
|
||||
if (digest != NULL) {
|
||||
int ret = mbedtls_sha256_finish(ctx, digest);
|
||||
assert(ret == 0);
|
||||
(void)ret;
|
||||
size_t hash_len;
|
||||
psa_status_t status = psa_hash_finish(op, digest, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_len);
|
||||
assert(status == PSA_SUCCESS);
|
||||
assert(hash_len == PSA_HASH_LENGTH(PSA_ALG_SHA_256));
|
||||
} else {
|
||||
psa_hash_abort(op);
|
||||
}
|
||||
mbedtls_sha256_free(ctx);
|
||||
|
||||
free(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -11,12 +11,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "psa/crypto.h"
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -27,7 +22,7 @@ extern const uint8_t signature_verification_key_start[] asm("_binary_signature_v
|
||||
extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end");
|
||||
|
||||
#define SIGNATURE_VERIFICATION_KEYLEN 64
|
||||
|
||||
#define PSA_ECDSA_PUB_KEY_SIZE_BITS 256
|
||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
{
|
||||
uint8_t digest[ESP_SECURE_BOOT_DIGEST_LEN];
|
||||
@@ -76,53 +71,31 @@ esp_err_t esp_secure_boot_verify_ecdsa_signature_block(const esp_secure_boot_sig
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Verifying secure boot signature");
|
||||
psa_status_t status;
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_handle;
|
||||
|
||||
int ret;
|
||||
mbedtls_mpi r, s;
|
||||
// Set key attributes
|
||||
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));
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
psa_set_key_bits(&key_attributes, PSA_ECDSA_PUB_KEY_SIZE_BITS);
|
||||
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
/* Extract r and s components from RAW ECDSA signature of 64 bytes */
|
||||
#define ECDSA_INTEGER_LEN 32
|
||||
ret = mbedtls_mpi_read_binary(&r, &sig_block->signature[0], ECDSA_INTEGER_LEN);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(1), err:%d", ret);
|
||||
// Import the public key
|
||||
status = psa_import_key(&key_attributes, signature_verification_key_start, keylen, &key_handle);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to import key, status:%d", status);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&s, &sig_block->signature[ECDSA_INTEGER_LEN], ECDSA_INTEGER_LEN);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(2), err:%d", ret);
|
||||
mbedtls_mpi_free(&r);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
// Verify the signature
|
||||
status = psa_verify_hash(key_handle, PSA_ALG_ECDSA(PSA_ALG_SHA_256), image_digest, ESP_SECURE_BOOT_DIGEST_LEN, sig_block->signature, SIGNATURE_VERIFICATION_KEYLEN);
|
||||
ESP_LOGD(TAG, "Verification result %d", status);
|
||||
|
||||
/* Initialise ECDSA context */
|
||||
mbedtls_ecdsa_context ecdsa_context;
|
||||
mbedtls_ecdsa_init(&ecdsa_context);
|
||||
// Destroy the key handle
|
||||
psa_destroy_key(key_handle);
|
||||
|
||||
mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
|
||||
size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P);
|
||||
if (keylen != 2 * plen) {
|
||||
ESP_LOGE(TAG, "Incorrect ECDSA key length %d", keylen);
|
||||
ret = ESP_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Extract X and Y components from ECDSA public key */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), signature_verification_key_start, plen));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), signature_verification_key_start + plen, plen));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1));
|
||||
|
||||
ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), image_digest, ESP_SECURE_BOOT_DIGEST_LEN, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s);
|
||||
ESP_LOGD(TAG, "Verification result %d", ret);
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
return ret == 0 ? ESP_OK : ESP_ERR_IMAGE_INVALID;
|
||||
return status == PSA_SUCCESS ? ESP_OK : ESP_ERR_IMAGE_INVALID;
|
||||
#endif // CONFIG_MBEDTLS_ECDSA_C && CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
}
|
||||
#endif // CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME
|
||||
|
||||
@@ -5,15 +5,9 @@
|
||||
*/
|
||||
#include "esp_log.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ecp.h"
|
||||
#include "rom/ecdsa.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "secure_boot_signature_priv.h"
|
||||
|
||||
@@ -31,27 +25,29 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t ret;
|
||||
esp_err_t ret = ESP_OK;
|
||||
psa_status_t status;
|
||||
|
||||
mbedtls_mpi r, s;
|
||||
/* Prepare public key for verification */
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_handle = 0;
|
||||
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
/* Initialise ECDSA context */
|
||||
mbedtls_ecdsa_context ecdsa_context;
|
||||
mbedtls_ecdsa_init(&ecdsa_context);
|
||||
/* Set key attributes according to the curve */
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
|
||||
uint8_t key_size = 0;
|
||||
psa_ecc_family_t curve_family;
|
||||
|
||||
switch(trusted_block->ecdsa.key.curve_id) {
|
||||
case ECDSA_CURVE_P192:
|
||||
key_size = 24;
|
||||
mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP192R1);
|
||||
curve_family = PSA_ECC_FAMILY_SECP_R1;
|
||||
psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size));
|
||||
break;
|
||||
case ECDSA_CURVE_P256:
|
||||
key_size = 32;
|
||||
mbedtls_ecp_group_load(&ecdsa_context.MBEDTLS_PRIVATE(grp), MBEDTLS_ECP_DP_SECP256R1);
|
||||
curve_family = PSA_ECC_FAMILY_SECP_R1;
|
||||
psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(key_size));
|
||||
break;
|
||||
#if CONFIG_SECURE_BOOT_ECDSA_KEY_LEN_384_BITS
|
||||
case ECDSA_CURVE_P384:
|
||||
@@ -64,50 +60,55 @@ esp_err_t verify_ecdsa_signature_block(const ets_secure_boot_signature_t *sig_bl
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
uint8_t x_point[ECDSA_INTEGER_LEN] = {};
|
||||
uint8_t y_point[ECDSA_INTEGER_LEN] = {};
|
||||
uint8_t _r[ECDSA_INTEGER_LEN] = {};
|
||||
uint8_t _s[ECDSA_INTEGER_LEN] = {};
|
||||
psa_set_key_algorithm(&key_attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
|
||||
psa_set_key_type(&key_attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve_family));
|
||||
|
||||
/* Convert r and s components to big endian format */
|
||||
/* Prepare the public key data from X and Y coordinates */
|
||||
uint8_t public_key[2 * ECDSA_INTEGER_LEN];
|
||||
uint8_t x_point[ECDSA_INTEGER_LEN] = {0};
|
||||
uint8_t y_point[ECDSA_INTEGER_LEN] = {0};
|
||||
|
||||
/* Convert key points from little-endian to big-endian format */
|
||||
for (int i = 0; i < key_size; i++) {
|
||||
_r[i] = trusted_block->ecdsa.signature[key_size - i - 1];
|
||||
_s[i] = trusted_block->ecdsa.signature[2 * key_size - i - 1];
|
||||
x_point[i] = trusted_block->ecdsa.key.point[key_size - i - 1];
|
||||
y_point[i] = trusted_block->ecdsa.key.point[2 * key_size - i - 1];
|
||||
}
|
||||
|
||||
/* Extract r and s components from RAW ECDSA signature of 64 bytes */
|
||||
ret = mbedtls_mpi_read_binary(&r, _r, key_size);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(r), err:%d", ret);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
return ESP_FAIL;
|
||||
/* Combine X and Y into a single public key buffer */
|
||||
memcpy(public_key, x_point, key_size);
|
||||
memcpy(public_key + key_size, y_point, key_size);
|
||||
|
||||
/* Import the public key */
|
||||
status = psa_import_key(&key_attributes, public_key, 2 * key_size, &key_handle);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to import key, err:%d", status);
|
||||
ret = ESP_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = mbedtls_mpi_read_binary(&s, _s, key_size);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed mbedtls_mpi_read_binary(s), err:%d", ret);
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
return ESP_FAIL;
|
||||
/* Convert signature from little-endian to big-endian format */
|
||||
uint8_t signature[2 * ECDSA_INTEGER_LEN] = {0};
|
||||
for (int i = 0; i < key_size; i++) {
|
||||
signature[i] = trusted_block->ecdsa.signature[key_size - i - 1];
|
||||
signature[key_size + i] = trusted_block->ecdsa.signature[2 * key_size - i - 1];
|
||||
}
|
||||
|
||||
size_t plen = mbedtls_mpi_size(&ecdsa_context.MBEDTLS_PRIVATE(grp).P);
|
||||
/* Verify the signature */
|
||||
status = psa_verify_hash(key_handle, PSA_ALG_ECDSA(PSA_ALG_SHA_256),
|
||||
image_digest, ESP_SECURE_BOOT_DIGEST_LEN,
|
||||
signature, 2 * key_size);
|
||||
|
||||
for (int i = 0; i < plen; i++) {
|
||||
x_point[i] = trusted_block->ecdsa.key.point[plen - 1 - i];
|
||||
y_point[i] = trusted_block->ecdsa.key.point[2 * plen - 1 - i];
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Signature verification failed, err:%d", status);
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Extract X and Y components from ECDSA public key */
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(X), x_point, plen));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Y), y_point, plen));
|
||||
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&ecdsa_context.MBEDTLS_PRIVATE(Q).MBEDTLS_PRIVATE(Z), 1));
|
||||
|
||||
ret = mbedtls_ecdsa_verify(&ecdsa_context.MBEDTLS_PRIVATE(grp), image_digest, ESP_SECURE_BOOT_DIGEST_LEN, &ecdsa_context.MBEDTLS_PRIVATE(Q), &r, &s);
|
||||
|
||||
cleanup:
|
||||
mbedtls_mpi_free(&r);
|
||||
mbedtls_mpi_free(&s);
|
||||
mbedtls_ecdsa_free(&ecdsa_context);
|
||||
/* Clean up resources */
|
||||
if (key_handle) {
|
||||
psa_destroy_key(key_handle);
|
||||
}
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "esp_log.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "secure_boot_signature_priv.h"
|
||||
|
||||
@@ -22,55 +17,56 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
mbedtls_rsa_context pk;
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
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);
|
||||
|
||||
if (sig_be == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
unsigned char *buf = calloc(1, rsa_key_size);
|
||||
if (buf == NULL) {
|
||||
|
||||
/* Create key attributes for RSA public key */
|
||||
psa_key_attributes_t key_attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_key_id_t key_id = 0;
|
||||
|
||||
/* Set key attributes */
|
||||
psa_set_key_usage_flags(&key_attributes, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
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);
|
||||
|
||||
/* Set the key size in bits (RSA key size is typically 2048 or 3072 bits) */
|
||||
psa_set_key_bits(&key_attributes, PSA_BYTES_TO_BITS(rsa_key_size));
|
||||
|
||||
/* Prepare the RSA public key in the format expected by PSA */
|
||||
/* PSA expects the key in big-endian format as a sequence of {N, E} */
|
||||
size_t n_size = rsa_key_size; /* N size in bytes */
|
||||
size_t e_size = sizeof(trusted_block->key.e); /* E size in bytes */
|
||||
size_t key_data_size = n_size + e_size + 8; /* Additional bytes for encoding */
|
||||
|
||||
uint8_t *key_data = calloc(1, key_data_size);
|
||||
if (key_data == NULL) {
|
||||
free(sig_be);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x", ret);
|
||||
goto exit_outer;
|
||||
}
|
||||
/* Construct the key data - would normally need proper DER encoding,
|
||||
but PSA may accept raw concatenated N and E values */
|
||||
uint8_t *p = 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_rsa_init(&pk);
|
||||
mbedtls_rsa_set_padding(&pk,MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
|
||||
ret = mbedtls_rsa_import(&pk, &N, NULL, NULL, NULL, &e);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed mbedtls_rsa_import, err: %d", ret);
|
||||
goto exit_inner;
|
||||
}
|
||||
/* Copy N (modulus) */
|
||||
memcpy(p, trusted_block->key.n, n_size);
|
||||
p += n_size;
|
||||
|
||||
ret = mbedtls_rsa_complete(&pk);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed mbedtls_rsa_complete, err: %d", ret);
|
||||
goto exit_inner;
|
||||
}
|
||||
/* Copy E (exponent) */
|
||||
memcpy(p, &trusted_block->key.e, e_size);
|
||||
|
||||
ret = mbedtls_rsa_check_pubkey(&pk);
|
||||
if (ret != 0) {
|
||||
ESP_LOGI(TAG, "Key is not an RSA key -%0x", -ret);
|
||||
goto exit_inner;
|
||||
/* Import the RSA public key */
|
||||
status = psa_import_key(&key_attributes, key_data, key_data_size, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Failed to import RSA public key, err: %d", status);
|
||||
ret = ESP_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Signature needs to be byte swapped into BE representation */
|
||||
@@ -78,24 +74,27 @@ esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_bloc
|
||||
sig_be[rsa_key_size - j - 1] = trusted_block->signature[j];
|
||||
}
|
||||
|
||||
ret = mbedtls_rsa_public( &pk, sig_be, buf);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "mbedtls_rsa_public failed, err: %d", ret);
|
||||
goto exit_inner;
|
||||
}
|
||||
/* Verify the signature using PSA APIs */
|
||||
status = psa_verify_hash(key_id, PSA_ALG_RSA_PSS(PSA_ALG_SHA_256),
|
||||
image_digest, ESP_SECURE_BOOT_DIGEST_LEN,
|
||||
sig_be, rsa_key_size);
|
||||
|
||||
ret = mbedtls_rsa_rsassa_pss_verify( &pk, MBEDTLS_MD_SHA256, ESP_SECURE_BOOT_DIGEST_LEN, image_digest, sig_be);
|
||||
if (ret != 0) {
|
||||
ESP_LOGE(TAG, "Failed mbedtls_rsa_rsassa_pss_verify, err: %d", ret);
|
||||
if (status != PSA_SUCCESS) {
|
||||
ESP_LOGE(TAG, "Signature verification failed, err: %d", status);
|
||||
ret = ESP_FAIL;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Signature verified successfully!");
|
||||
ret = ESP_OK;
|
||||
}
|
||||
exit_inner:
|
||||
mbedtls_rsa_free(&pk);
|
||||
exit_outer:
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
mbedtls_entropy_free(&entropy);
|
||||
|
||||
cleanup:
|
||||
/* Clean up resources */
|
||||
if (key_id != 0) {
|
||||
psa_destroy_key(key_id);
|
||||
}
|
||||
psa_reset_key_attributes(&key_attributes);
|
||||
free(key_data);
|
||||
free(sig_be);
|
||||
free(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -11,12 +11,6 @@
|
||||
#include "bootloader_signature.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "mbedtls/sha256.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/md.h"
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_secure_boot.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
idf_component_register(SRCS "test_app_main.c" "test_verify_image.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES unity bootloader_support esp_partition app_update
|
||||
REQUIRES unity bootloader_support esp_partition app_update mbedtls
|
||||
WHOLE_ARCHIVE)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "unity_test_runner.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_ota_ops.h"
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
// Some resources are lazy allocated, e.g. newlib locks, GDMA channel lazy installed by crypto driver
|
||||
// the threshold is left for those cases
|
||||
@@ -28,8 +28,10 @@ void setUp(void)
|
||||
{
|
||||
// load the partition table before measuring the initial free heap size.
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, esp_ota_get_running_partition());
|
||||
psa_crypto_init();
|
||||
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
|
||||
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
|
||||
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
|
||||
Reference in New Issue
Block a user