|
|
@@ -22,6 +22,7 @@
|
|
|
#include "esp_secure_boot.h"
|
|
|
#include "esp_ota_ops.h"
|
|
|
#include "esp_efuse.h"
|
|
|
+#include "esp_efuse_chip.h"
|
|
|
|
|
|
#include "secure_boot_signature_priv.h"
|
|
|
|
|
|
@@ -46,31 +47,32 @@ static esp_err_t validate_signature_block(const ets_secure_boot_sig_block_t *blo
|
|
|
return ESP_OK;
|
|
|
}
|
|
|
|
|
|
-esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests)
|
|
|
+static esp_err_t calculate_image_public_key_digests(bool verify_image_digest, bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests, esp_partition_pos_t *part_pos)
|
|
|
{
|
|
|
- esp_image_metadata_t metadata;
|
|
|
- const esp_partition_t* running_app_part = esp_ota_get_running_partition();
|
|
|
- if (running_app_part == NULL) {
|
|
|
- ESP_LOGE(TAG, "Cannot get running partition");
|
|
|
- return ESP_FAIL;
|
|
|
- }
|
|
|
- const esp_partition_pos_t part_pos = {
|
|
|
- .offset = running_app_part->address,
|
|
|
- .size = running_app_part->size,
|
|
|
- };
|
|
|
- esp_err_t err = esp_image_get_metadata(&part_pos, &metadata);
|
|
|
- if (err != ESP_OK) {
|
|
|
- ESP_LOGE(TAG, "Error reading metadata from running app (err=0x%x)", err);
|
|
|
+ esp_image_metadata_t img_metadata = {0};
|
|
|
+ esp_err_t ret = esp_image_get_metadata(part_pos, &img_metadata);
|
|
|
+ if (ret != ESP_OK) {
|
|
|
+ ESP_LOGE(TAG, "Error reading metadata from running app (err=0x%x)", ret);
|
|
|
return ESP_FAIL;
|
|
|
}
|
|
|
|
|
|
- memset(public_key_digests, 0, sizeof(esp_image_sig_public_key_digests_t));
|
|
|
+ uint8_t image_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
|
|
|
+ uint8_t __attribute__((aligned(4))) key_digest[ESP_SECURE_BOOT_DIGEST_LEN] = {0};
|
|
|
+ size_t sig_block_addr = img_metadata.start_addr + ALIGN_UP(img_metadata.image_len, FLASH_SECTOR_SIZE);
|
|
|
+
|
|
|
+ ESP_LOGD(TAG, "calculating public key digests for sig blocks of image offset 0x%"PRIu32" (sig block offset 0x%u)", img_metadata.start_addr, sig_block_addr);
|
|
|
+
|
|
|
+ bzero(public_key_digests, sizeof(esp_image_sig_public_key_digests_t));
|
|
|
|
|
|
- // Generating the SHA of the public key components in the signature block
|
|
|
+ if (verify_image_digest) {
|
|
|
+ ret = bootloader_sha256_flash_contents(img_metadata.start_addr, sig_block_addr - img_metadata.start_addr, image_digest);
|
|
|
+ if (ret != ESP_OK) {
|
|
|
+ ESP_LOGE(TAG, "error generating image digest, %d", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // metadata.image_len doesn't include any padding to start of the signature sector, so pad it here
|
|
|
- size_t sig_block_addr = metadata.start_addr + ALIGN_UP(metadata.image_len, FLASH_SECTOR_SIZE);
|
|
|
- ESP_LOGD(TAG, "reading signatures for app address 0x%"PRIx32" sig block address 0x%x", part_pos.offset, sig_block_addr);
|
|
|
+ ESP_LOGD(TAG, "reading signature(s)");
|
|
|
for (unsigned i = 0; i < SECURE_BOOT_NUM_BLOCKS; i++) {
|
|
|
ets_secure_boot_sig_block_t block;
|
|
|
size_t addr = sig_block_addr + sizeof(ets_secure_boot_sig_block_t) * i;
|
|
|
@@ -84,20 +86,59 @@ esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_publi
|
|
|
#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
|
|
|
bootloader_sha256_data(sig_block_sha, &block.ecdsa.key, sizeof(block.ecdsa.key));
|
|
|
#endif
|
|
|
- bootloader_sha256_finish(sig_block_sha, public_key_digests->key_digests[i]);
|
|
|
+ bootloader_sha256_finish(sig_block_sha, key_digest);
|
|
|
+ if (verify_image_digest) {
|
|
|
+ // Check we can verify the image using this signature and this key
|
|
|
+ uint8_t temp_verified_digest[ESP_SECURE_BOOT_DIGEST_LEN];
|
|
|
+ #if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME
|
|
|
+ bool verified = ets_rsa_pss_verify(&block.key, block.signature, image_digest, temp_verified_digest);
|
|
|
+ #elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME
|
|
|
+ bool verified = ets_ecdsa_verify(&block.ecdsa.key.point[0], block.ecdsa.signature, block.ecdsa.key.curve_id, image_digest, temp_verified_digest);
|
|
|
+ #endif
|
|
|
+ if (!verified) {
|
|
|
+ ESP_LOGE(TAG, "Secure boot key (%d) verification failed.", i);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ ESP_LOGD(TAG, "Signature block (%d) is verified", i);
|
|
|
+ }
|
|
|
+ /* Copy the key digest to the buffer provided by the caller */
|
|
|
+ memcpy((void *)public_key_digests->key_digests[public_key_digests->num_digests], key_digest, ESP_SECURE_BOOT_DIGEST_LEN);
|
|
|
}
|
|
|
public_key_digests->num_digests++;
|
|
|
}
|
|
|
} else {
|
|
|
- ESP_LOGE(TAG, "Secure boot sign blocks cannot be read from a running app (err=0x%x)", err);
|
|
|
+ ESP_LOGE(TAG, "Secure boot sign blocks cannot be read from image at %lx (err=0x%x)", part_pos->offset, err);
|
|
|
return ESP_FAIL;
|
|
|
}
|
|
|
}
|
|
|
- if (public_key_digests->num_digests > 0) {
|
|
|
- return ESP_OK;
|
|
|
+
|
|
|
+ if (ret == ESP_OK && public_key_digests->num_digests > 0) {
|
|
|
+ ESP_LOGD(TAG, "Digests successfully calculated, %d valid signatures (image offset 0x%"PRIu32")",
|
|
|
+ public_key_digests->num_digests, img_metadata.start_addr);
|
|
|
}
|
|
|
- ESP_LOGE(TAG, "No signatures were found for the running app");
|
|
|
- return ESP_ERR_NOT_FOUND;
|
|
|
+
|
|
|
+ if (public_key_digests->num_digests == 0) {
|
|
|
+ return ESP_ERR_NOT_FOUND;
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+esp_err_t esp_secure_boot_get_signature_blocks_for_running_app(bool digest_public_keys, esp_image_sig_public_key_digests_t *public_key_digests)
|
|
|
+{
|
|
|
+ esp_partition_pos_t part_pos;
|
|
|
+ const esp_partition_t* running_app_part = esp_ota_get_running_partition();
|
|
|
+ if (running_app_part == NULL) {
|
|
|
+ ESP_LOGE(TAG, "Cannot get running partition");
|
|
|
+ return ESP_FAIL;
|
|
|
+ }
|
|
|
+ part_pos.offset = running_app_part->address;
|
|
|
+ part_pos.size = running_app_part->size;
|
|
|
+
|
|
|
+ esp_err_t err = calculate_image_public_key_digests(false, digest_public_keys, public_key_digests, &part_pos);
|
|
|
+ if (public_key_digests->num_digests == 0) {
|
|
|
+ ESP_LOGE(TAG, "No signatures were found for the running app");
|
|
|
+ }
|
|
|
+ return err;
|
|
|
}
|
|
|
|
|
|
static esp_err_t get_secure_boot_key_digests(esp_image_sig_public_key_digests_t *public_key_digests)
|
|
|
@@ -236,3 +277,33 @@ esp_err_t esp_secure_boot_verify_rsa_signature_block(const ets_secure_boot_signa
|
|
|
#endif
|
|
|
|
|
|
#endif // CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME || CONFIG_SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
|
|
+
|
|
|
+#if SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
|
|
|
+
|
|
|
+esp_err_t esp_secure_boot_verify_with_efuse_digest_index(int efuse_digest_index, esp_partition_pos_t *part_pos)
|
|
|
+{
|
|
|
+ if (!part_pos || (efuse_digest_index < 0 || efuse_digest_index >= SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS)) {
|
|
|
+ return ESP_ERR_INVALID_ARG;
|
|
|
+ }
|
|
|
+ esp_image_sig_public_key_digests_t img_key_digests = {0};
|
|
|
+ esp_err_t ret = calculate_image_public_key_digests(true, true, &img_key_digests, part_pos);
|
|
|
+ if (ret != ESP_OK) {
|
|
|
+ return ESP_FAIL;
|
|
|
+ }
|
|
|
+ if (esp_efuse_get_digest_revoke(efuse_digest_index)) {
|
|
|
+ return ESP_FAIL;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Read key digests from efuse
|
|
|
+ esp_secure_boot_key_digests_t efuse_key_digests;
|
|
|
+ memset(&efuse_key_digests, 0, sizeof(esp_secure_boot_key_digests_t));
|
|
|
+ esp_secure_boot_read_key_digests(&efuse_key_digests);
|
|
|
+
|
|
|
+ for (int i = 0; i < img_key_digests.num_digests; i++) {
|
|
|
+ if (!memcmp(img_key_digests.key_digests[i], efuse_key_digests.key_digests[efuse_digest_index], ESP_SECURE_BOOT_KEY_DIGEST_LEN)) {
|
|
|
+ return ESP_OK;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ESP_FAIL;
|
|
|
+}
|
|
|
+#endif // SOC_SUPPORT_SECURE_BOOT_REVOKE_KEY && CONFIG_SECURE_BOOT_V2_ENABLED
|