feat(partition_table): Support primary subtypes partitions

This commit is contained in:
Konstantin Kondrashov
2024-10-14 20:45:24 +03:00
parent 7d179ccd3e
commit 8c4f576f99
12 changed files with 264 additions and 79 deletions

View File

@@ -102,6 +102,24 @@ static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_
static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data, uint8_t *image_digest, uint8_t *verified_digest);
static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
static uint32_t s_bootloader_partition_offset = ESP_PRIMARY_BOOTLOADER_OFFSET;
uint32_t esp_image_bootloader_offset_get(void)
{
return s_bootloader_partition_offset;
}
void esp_image_bootloader_offset_set(const uint32_t offset)
{
s_bootloader_partition_offset = offset;
ESP_LOGI(TAG, "Bootloader offsets for PRIMARY: 0x%x, Secondary: 0x%" PRIx32, ESP_PRIMARY_BOOTLOADER_OFFSET, s_bootloader_partition_offset);
}
static bool is_bootloader(uint32_t offset)
{
return ((offset == ESP_PRIMARY_BOOTLOADER_OFFSET) || (offset == s_bootloader_partition_offset));
}
static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
{
#ifdef BOOTLOADER_BUILD
@@ -135,7 +153,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
// For secure boot V1 on ESP32, we don't calculate SHA or verify signature on bootloaders.
// (For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because
// esptool.py may have rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.)
verify_sha = (part->offset != ESP_BOOTLOADER_OFFSET) && do_verify;
verify_sha = !is_bootloader(part->offset) && do_verify;
#endif
if (part->size > SIXTEEN_MB) {
@@ -199,7 +217,7 @@ static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_
#if CONFIG_SECURE_BOOT_V2_ENABLED
ESP_FAULT_ASSERT(!esp_secure_boot_enabled() || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
#else // Secure Boot V1 on ESP32, only verify signatures for apps not bootloaders
ESP_FAULT_ASSERT(data->start_addr == ESP_BOOTLOADER_OFFSET || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
ESP_FAULT_ASSERT(is_bootloader(data->start_addr) || memcmp(image_digest, verified_digest, HASH_LEN) == 0);
#endif
#endif // SECURE_BOOT_CHECK_SIGNATURE
@@ -332,7 +350,8 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
// Checking the chip revision header *will* print a bunch of other info
// regardless of silent setting as this may be important, but don't bother checking it
// if it looks like the app partition is erased or otherwise garbage
CHECK_ERR(bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION));
esp_image_type image_type = is_bootloader(src_addr) ? ESP_IMAGE_BOOTLOADER : ESP_IMAGE_APPLICATION;
CHECK_ERR(bootloader_common_check_chip_validity(image, image_type));
if (image->segment_count > ESP_IMAGE_MAX_SEGMENTS) {
FAIL_LOAD("image at 0x%"PRIx32" segment count %d exceeds max %d", src_addr, image->segment_count, ESP_IMAGE_MAX_SEGMENTS);
@@ -695,7 +714,7 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t
// Case II: Bootloader verifying bootloader
// The esp_app_desc_t structure is located in DROM and is always in segment #0.
// Anti-rollback check and efuse block version check should handle only Case I from above.
if (segment == 0 && metadata->start_addr != ESP_BOOTLOADER_OFFSET) {
if (segment == 0 && !is_bootloader(metadata->start_addr)) {
/* ESP32 doesn't have more memory and more efuse bits for block major version. */
#if !CONFIG_IDF_TARGET_ESP32
const esp_app_desc_t *app_desc = (const esp_app_desc_t *)src;
@@ -847,8 +866,8 @@ esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data)
return ESP_ERR_INVALID_ARG;
}
const esp_partition_pos_t bootloader_part = {
.offset = ESP_BOOTLOADER_OFFSET,
.size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
.offset = ESP_PRIMARY_BOOTLOADER_OFFSET,
.size = ESP_BOOTLOADER_SIZE,
};
return esp_image_verify(ESP_IMAGE_VERIFY,
&bootloader_part,
@@ -871,7 +890,7 @@ static esp_err_t process_appended_hash_and_sig(esp_image_metadata_t *data, uint3
#if CONFIG_SECURE_BOOT || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT
// Case I: Bootloader part
if (part_offset == ESP_BOOTLOADER_OFFSET) {
if (is_bootloader(part_offset)) {
// For bootloader with secure boot v1, signature stays in an independent flash
// sector (offset 0x0) and does not get appended to the image.
#if CONFIG_SECURE_BOOT_V2_ENABLED
@@ -1005,7 +1024,7 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han
#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) {
if (!is_bootloader(data->start_addr)) {
data->image_len = end - data->start_addr + sizeof(esp_secure_boot_sig_block_t);
}
#endif