Partition table update on secure device

erikha
Posts: 7
Joined: Wed Feb 23, 2022 8:59 am

Partition table update on secure device

Postby erikha » Wed Feb 23, 2022 10:23 am

Hello,

I have a problem with updating the partition table over-the-air.

Information:
ESP32-WROOM-32E
Using esp-idf v4.2
Secure boot v1 enabled, one-time flashable
Encrypted some partitions in NVS

When I update the partition table of a non-secure device over-the-air it works like a charm, but when performing the same update to a secure device, the device is bricked because it boot loops. I suspect the boot digest is the problem here, because this digest isn't updated when the partition table is updated.

A solution would be to be able to re-calculate the digest from the application code when the partition table is updated. Is this possible? Or is something else the problem?

Thank you for your help.

Kind regards,
erikha

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Partition table update on secure device

Postby WiFive » Wed Feb 23, 2022 3:45 pm

Are you sure the partition table of both devices is at the same address? Usually size of secure bootloader means partition table has to be moved. Do you have the boot log?

erikha
Posts: 7
Joined: Wed Feb 23, 2022 8:59 am

Re: Partition table update on secure device

Postby erikha » Wed Feb 23, 2022 4:22 pm

The bootloader is flashed with start address 0x1000 and the partition table at 0x10000 on both devices.

The boot log:

Code: Select all

rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:11376
ho 0 tail 12 room 4
load:0x40078000,len:20240
load:0x40080400,len:6712
entry 0x40080778
I (146) boot: Chip Revision: 1
I (68) boot: ESP-IDF v3.3.4 2nd stage bootloader
I (68) boot: compile time 13:07:11
I (68) boot: Enabling RNG early entropy source...
I (73) boot: SPI Speed      : 40MHz
I (77) boot: SPI Mode       : DIO
I (81) boot: SPI Flash Size : 8MB
E (85) flash_parts: partition 0 invalid magic number 0x4088
E (91) boot: Failed to verify partition table
E (96) boot: load partition table error!
ets Jun  8 2016 00:22:57

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Partition table update on secure device

Postby WiFive » Thu Feb 24, 2022 3:23 am

The digest is fine because the 2nd stage bootloader is running. The error is "invalid magic number 0x4088" for the partition table. Are you also using flash encryption and how do you write the new bootloader to flash?

erikha
Posts: 7
Joined: Wed Feb 23, 2022 8:59 am

Re: Partition table update on secure device

Postby erikha » Thu Feb 24, 2022 4:07 pm

Okay, good to know the digest is fine.

Yes, I have flash encryption enabled.

I don't write a new bootloader. The process:

- Flash device with secure bootloader A, partion table A and application A
- Boot device for first time and flash gets encrypted
- Device shipped to customer
- I want to update partition table
- Send application B OTA
- Application B boots and detects partition table A
- Application B start replacing partion table A with partition table B
- Device reboots and enters a bootloop

Is there something I did wrong or did I forget something?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Partition table update on secure device

Postby WiFive » Fri Feb 25, 2022 3:52 am

Sorry I meant how do you write the new partition table. Show code.

erikha
Posts: 7
Joined: Wed Feb 23, 2022 8:59 am

Re: Partition table update on secure device

Postby erikha » Fri Feb 25, 2022 12:59 pm

The binairy of the partion table is embedded in the application binairy that's doing the partion table update. The code:

Code: Select all

extern const unsigned char partition_table_bin_start[] asm("_binary_partition_table_bin_start");
extern const unsigned char partition_table_bin_end[]   asm("_binary_partition_table_bin_end");
static const char *PARTITION_TABLE_UPDATE_TAG = "PartitionTableUpdate";

#define APPLIANCE_UPDATE_PARTITION_TYPE     0x40
#define APPLIANCE_UPDATE_PARTITION_NAME     "appliance_update"
#define PARTITION_TABLE_SECTOR_SIZE         0x1000
#define EXPECTED_PARTITION_TABLE_SIZE       (partition_table_bin_end - partition_table_bin_start)

bool PartitionTableIsUpdateNeeded(void)
{
    return (NULL == esp_partition_find(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS_KEYS, NULL));
}

void PartitionTablePerformUpdate(void)
{
    ESP_LOGI(PARTITION_TABLE_UPDATE_TAG, "Updating Partition Table...");
    const esp_partition_t* pApplianceUpdatePartition = esp_partition_find_first(APPLIANCE_UPDATE_PARTITION_TYPE, ESP_PARTITION_SUBTYPE_ANY, APPLIANCE_UPDATE_PARTITION_NAME);
    isl_assert(pApplianceUpdatePartition);
    esp_partition_erase_range(pApplianceUpdatePartition, 0, pApplianceUpdatePartition->size);
    unsigned char* pBuffer = heap_caps_calloc(EXPECTED_PARTITION_TABLE_SIZE, sizeof(unsigned char), MALLOC_CAP_8BIT);
    isl_assert(pBuffer);
    esp_err_t flashOperationStatus = ESP_OK;
    do
    {
        if ((flashOperationStatus = esp_flash_erase_region(esp_flash_default_chip, ESP_PARTITION_TABLE_OFFSET, PARTITION_TABLE_SECTOR_SIZE)) != ESP_OK)
        {
            ESP_LOGE(PARTITION_TABLE_UPDATE_TAG, "esp_flash_erase_region failed with code %d", flashOperationStatus);
        }
        else if ((flashOperationStatus = esp_flash_write(esp_flash_default_chip, partition_table_bin_start, ESP_PARTITION_TABLE_OFFSET, EXPECTED_PARTITION_TABLE_SIZE)) != ESP_OK)
        {
            ESP_LOGE(PARTITION_TABLE_UPDATE_TAG, "esp_flash_write failed with code %d", flashOperationStatus);
        }
        else if ((flashOperationStatus = esp_flash_read(esp_flash_default_chip, pBuffer, ESP_PARTITION_TABLE_OFFSET, EXPECTED_PARTITION_TABLE_SIZE)) != ESP_OK)
        {
            ESP_LOGE(PARTITION_TABLE_UPDATE_TAG, "esp_flash_read failed with code %d", flashOperationStatus);
        }
    } while (memcmp(pBuffer, partition_table_bin_start, EXPECTED_PARTITION_TABLE_SIZE) != 0);
    heap_caps_free(pBuffer);
    ESP_LOGI(PARTITION_TABLE_UPDATE_TAG, "Partition Table Updated");
    esp_restart();
}

To be clear: this update process works perfect when secure boot and flash encrytion are NOT enabled.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Partition table update on secure device

Postby WiFive » Fri Feb 25, 2022 4:31 pm

You have to use esp_flash_write_encrypted when encryption is on

erikha
Posts: 7
Joined: Wed Feb 23, 2022 8:59 am

Re: Partition table update on secure device

Postby erikha » Fri Feb 25, 2022 6:08 pm

Okay, thank you!

Is it also possible to use the esp_write_partition() function? If I understand the docs correctly, this function allows to write to both encrypted and unencrypted partitions.

erikha
Posts: 7
Joined: Wed Feb 23, 2022 8:59 am

Re: Partition table update on secure device

Postby erikha » Fri Feb 25, 2022 6:11 pm

And another question: is it possible to save the device that suffers the bootloop? or is it bricked?

Who is online

Users browsing this forum: Bing [Bot] and 231 guests