From 4573271d2ba7ca66423b27b4d561f51c00f0c1dc Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Wed, 22 Nov 2023 15:14:52 +0530 Subject: [PATCH 1/2] fix(bootloader_support): Fix image_length calculation when secure boot v1 is enabled Fixed the value of the image_length field of the image metadata populated by esp_image_verfiy() to include the size of the signature sector when Secure Boot V1 is enabled. --- components/bootloader_support/src/esp_image_format.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index e45c6c2d7ec..12f663013fe 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -932,9 +932,13 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han return ESP_ERR_IMAGE_INVALID; } -#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME // Adjust image length result to include the appended signature +#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME || CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME data->image_len = end - data->start_addr + sizeof(ets_secure_boot_signature_t); +#elif defined(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME) + if (data->start_addr != ESP_BOOTLOADER_OFFSET) { + data->image_len = end - data->start_addr + sizeof(esp_secure_boot_sig_block_t); + } #endif #endif // SECURE_BOOT_CHECK_SIGNATURE From eebdd3f391e8360b53f9269f686d7e68788ac217 Mon Sep 17 00:00:00 2001 From: "harshal.patil" Date: Wed, 22 Nov 2023 15:17:37 +0530 Subject: [PATCH 2/2] feat(bootloader_support): Encrypt only the app image instead of the whole partition Currently, when flash encryption is enabled, the whole partition gets encrypted. This can be optimised by encrypting only the app image instead of encrypting the whole partition. Closes https://github.com/espressif/esp-idf/issues/12576 --- components/bootloader/Kconfig.projbuild | 16 ++++++++++++++++ .../src/flash_encryption/flash_encrypt.c | 15 +++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index acf65a932e5..86b1684a25f 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -1071,6 +1071,22 @@ menu "Security features" DIS_DOWNLOAD_MANUAL_ENCRYPT, DIS_USB_JTAG, DIS_USB_SERIAL_JTAG, STRAP_JTAG_SEL, USB_PHY_SEL. endmenu # Potentially Insecure + config SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART + bool "Encrypt only the app image that is present in the partition of type app" + depends on SECURE_FLASH_ENC_ENABLED && !SECURE_FLASH_REQUIRE_ALREADY_ENABLED + default n + help + If set, optimise encryption time for the partition of type APP, + by only encrypting the app image that is present in the partition, + instead of the whole partition. + The image length used for encryption is derived from the image metadata, which + includes the size of the app image, checksum, hash and also the signature sector + when secure boot is enabled. + + If not set (default), the whole partition of type APP would be encrypted, + which increases the encryption time but might be useful if there + is any custom data appended to the firmware image. + config SECURE_FLASH_CHECK_ENC_EN_IN_APP bool "Check Flash Encryption enabled on app startup" depends on SECURE_FLASH_ENC_ENABLED diff --git a/components/bootloader_support/src/flash_encryption/flash_encrypt.c b/components/bootloader_support/src/flash_encryption/flash_encrypt.c index daf920564a0..f861107e8a7 100644 --- a/components/bootloader_support/src/flash_encryption/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encryption/flash_encrypt.c @@ -393,14 +393,21 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit { esp_err_t err; bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED); + uint32_t size = partition->pos.size; if (partition->type == PART_TYPE_APP) { /* check if the partition holds a valid unencrypted app */ - esp_image_metadata_t data_ignored; + esp_image_metadata_t image_data = {}; err = esp_image_verify(ESP_IMAGE_VERIFY, &partition->pos, - &data_ignored); + &image_data); should_encrypt = (err == ESP_OK); +#ifdef SECURE_FLASH_ENCRYPT_ONLY_IMAGE_LEN_IN_APP_PART + if (should_encrypt) { + // Encrypt only the app image instead of encrypting the whole partition + size = image_data.image_len; + } +#endif } else if ((partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) || (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_NVS_KEYS)) { /* check if we have ota data partition and the partition should be encrypted unconditionally */ @@ -411,9 +418,9 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit return ESP_OK; } else { /* should_encrypt */ - ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, partition->pos.size); + ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x (length 0x%x)...", index, partition->pos.offset, size); - err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size); + err = esp_flash_encrypt_region(partition->pos.offset, size); ESP_LOGI(TAG, "Done encrypting"); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to encrypt partition %d", index);