Encrypted OTA + Flash Encryption + Secure Boot
Posted: Tue Jul 02, 2019 5:38 pm
I have been working with the secure boot and flash encryption and OTA for the last days.
All of them were working individually without issues (http and https OTA for about a year).
I have several days with a problem with the OTA update and flash encryption. I have a huge pressure to release this section, so my actions are touching the desperate field:
My First try fail. Any file downloaded usint ther OTA API (I was using the idf example) trigger an error at esp_ota_write (trying to write to an encrypted flash.)
My action: removed the encrypted part in the ota API code that handle the spi_flash_write_encrypted. Now I upload to the server an encrypted firmware file, and the OTA software write directly (without encryption) to an encrypted OTA partition.
This modification include the way that the encrypted otadata partition is updated. (it write like normal flash write, but the sector is not encrypted)
My problem: The problem is at the boot. the bootloader can't understand the otadata because it's not encrypted.
If I read manually the otadata partition, encrypt it (i have the keys to do espsecure.py encrypt_flash_data...) and flash back encrypted to the Flash, the bootloader recognize the data and switch to the proper OTA partition successfully. The downloaded encrypted firmware works without any issues. it works exactly as I need. Just the bootloader doesn't talk the same language than the modified OTA API regarding the otadata partition.
My options were fix the bootloader (remove encryption from otadata) or fix the ota API code when try to write to the encrypted otadata partition.
Because the first will introduce too many modification at the bootloader, I just continue with my second option.
Going a little further with the API code, the problem happen at the spi_flash_write_encrypted() routine, included in components/spi_flash/flash_ops.c
I added a loop to try a few times with a 100ms delay separation. The routine always return the same error: 0x6001.
I will really appreciate any help on this topic.
Only this detail (maybe is more than a detail) is pending to make "Encrypted OTA" + "secure boot" + "flash encrypted" work
Thanks in advance for any light.
All of them were working individually without issues (http and https OTA for about a year).
I have several days with a problem with the OTA update and flash encryption. I have a huge pressure to release this section, so my actions are touching the desperate field:
My First try fail. Any file downloaded usint ther OTA API (I was using the idf example) trigger an error at esp_ota_write (trying to write to an encrypted flash.)
My action: removed the encrypted part in the ota API code that handle the spi_flash_write_encrypted. Now I upload to the server an encrypted firmware file, and the OTA software write directly (without encryption) to an encrypted OTA partition.
This modification include the way that the encrypted otadata partition is updated. (it write like normal flash write, but the sector is not encrypted)
My problem: The problem is at the boot. the bootloader can't understand the otadata because it's not encrypted.
If I read manually the otadata partition, encrypt it (i have the keys to do espsecure.py encrypt_flash_data...) and flash back encrypted to the Flash, the bootloader recognize the data and switch to the proper OTA partition successfully. The downloaded encrypted firmware works without any issues. it works exactly as I need. Just the bootloader doesn't talk the same language than the modified OTA API regarding the otadata partition.
My options were fix the bootloader (remove encryption from otadata) or fix the ota API code when try to write to the encrypted otadata partition.
Because the first will introduce too many modification at the bootloader, I just continue with my second option.
Going a little further with the API code, the problem happen at the spi_flash_write_encrypted() routine, included in components/spi_flash/flash_ops.c
- esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size)
- {
- CHECK_WRITE_ADDRESS(dest_addr, size);
- const uint8_t *ssrc = (const uint8_t *)src;
- if ((dest_addr % 16) != 0) {
- return ESP_ERR_INVALID_ARG;
- }
- if ((size % 16) != 0) {
- return ESP_ERR_INVALID_SIZE;
- }
- COUNTER_START();
- esp_rom_spiflash_result_t rc;
- rc = spi_flash_unlock(); //<<<<< error I can't investigate further. only know that the result code is 0x6001
- if (rc == ESP_ROM_SPIFLASH_RESULT_OK) {
- // <<< never get here
- /* esp_rom_spiflash_write_encrypted encrypts data in RAM as it writes,
- so copy to a temporary buffer - 32 bytes at a time.
- Each call to esp_rom_spiflash_write_encrypted takes a 32 byte "row" of
- data to encrypt, and each row is two 16 byte AES blocks
- that share a key (as derived from flash address).
- */
- uint8_t encrypt_buf[32] __attribute__((aligned(4)));
- uint32_t row_size;
- ......
I will really appreciate any help on this topic.
Only this detail (maybe is more than a detail) is pending to make "Encrypted OTA" + "secure boot" + "flash encrypted" work
Thanks in advance for any light.