How to avoid accidental re-flash when secure boot enabled?

dldtechnology
Posts: 10
Joined: Sun Nov 20, 2016 12:09 am

How to avoid accidental re-flash when secure boot enabled?

Postby dldtechnology » Mon Mar 09, 2020 2:48 pm

We have an application that uses the full secure boot procedure as documented in the manual - this all works great, and we rely on OTA updates after initial flash. Our flashing software calls esptool.py in the background with the following:

Code: Select all

esptool.py --port {0} -b 460800 --before default_reset --after hard_reset write_flash -z 0x1000 securebootloader.bin 0x10000 main.bin 0x8000 partition.bin
However, at production, several boards were put through the process twice which has now bricked them since the flash was encrypted the first time around and now can't load plain text images.

Is there any way to prevent this in future?? Are there any efuses that will prevent serial access to the ROM bootloader???

The efuses of a bricked unit are:

Code: Select all

EFUSE_NAME             Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Security fuses:
FLASH_CRYPT_CNT        Flash encryption mode counter                     = 1 R/W (0x1)
FLASH_CRYPT_CONFIG     Flash encryption config (key tweak bits)          = 15 R/W (0xf)
CONSOLE_DEBUG_DISABLE  Disable ROM BASIC interpreter fallback            = 1 R/W (0x1)
ABS_DONE_0             secure boot enabled for bootloader                = 1 R/W (0x1)
ABS_DONE_1             secure boot abstract 1 locked                     = 0 R/W (0x0)
JTAG_DISABLE           Disable JTAG                                      = 1 R/W (0x1)
DISABLE_DL_ENCRYPT     Disable flash encryption in UART bootloader       = 1 R/W (0x1)
DISABLE_DL_DECRYPT     Disable flash decryption in UART bootloader       = 1 R/W (0x1)
DISABLE_DL_CACHE       Disable flash cache in UART bootloader            = 1 R/W (0x1)
BLK1                   Flash encryption key
  = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLK2                   Secure boot key
  = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLK3                   Variable Block 3
  = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 R/W

Efuse fuses:
WR_DIS                 Efuse write disable mask                          = 384 R/W (0x180)
RD_DIS                 Efuse read disablemask                            = 3 R/W (0x3)
CODING_SCHEME          Efuse variable block length scheme                = 0 R/W (0x0)
KEY_STATUS             Usage of efuse block 3 (reserved)                 = 0 R/W (0x0)

Config fuses:
XPD_SDIO_FORCE         Ignore MTDI pin (GPIO12) for VDD_SDIO on reset    = 0 R/W (0x0)
XPD_SDIO_REG           If XPD_SDIO_FORCE, enable VDD_SDIO reg on reset   = 0 R/W (0x0)
XPD_SDIO_TIEH          If XPD_SDIO_FORCE & XPD_SDIO_REG, 1=3.3V 0=1.8V   = 0 R/W (0x0)
CLK8M_FREQ             8MHz clock freq override                          = 53 R/W (0x35)
SPI_PAD_CONFIG_CLK     Override SD_CLK pad (GPIO6/SPICLK)                = 0 R/W (0x0)
SPI_PAD_CONFIG_Q       Override SD_DATA_0 pad (GPIO7/SPIQ)               = 0 R/W (0x0)
SPI_PAD_CONFIG_D       Override SD_DATA_1 pad (GPIO8/SPID)               = 0 R/W (0x0)
SPI_PAD_CONFIG_HD      Override SD_DATA_2 pad (GPIO9/SPIHD)              = 0 R/W (0x0)
SPI_PAD_CONFIG_CS0     Override SD_CMD pad (GPIO11/SPICS0)               = 0 R/W (0x0)
DISABLE_SDIO_HOST      Disable SDIO host                                 = 0 R/W (0x0)

Identity fuses:
MAC                    Factory MAC Address
  = 98:f4:ab:1c:66:50 (CRC 4e OK) R/W
CHIP_VER_REV1          Silicon Revision 1                                = 1 R/W (0x1)
CHIP_VER_REV2          Silicon Revision 2                                = 0 R/W (0x0)
CHIP_VERSION           Reserved for future chip versions                 = 2 R/W (0x2)
CHIP_PACKAGE           Chip package identifier                           = 1 R/W (0x1)

Calibration fuses:
BLK3_PART_RESERVE      BLOCK3 partially served for ADC calibration data  = 0 R/W (0x0)
ADC_VREF               Voltage reference calibration                     = 1100 R/W (0x10)

Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).

vjacobs
Posts: 10
Joined: Mon May 20, 2019 8:34 am

Re: How to avoid accidental re-flash when secure boot enabled?

Postby vjacobs » Tue Mar 10, 2020 9:48 pm

HI,

I was having the same issue for our production.

I'm calling the esptool.py in a batch script, that first runs espefuse.py and checks (through string searching and substring) the ABS_DONE_0 bit before erasing/flashing. If it set to 1, abort. If it's 0, I start the flash procedure.

I was a bit surprised that the esptool.py doesn't check this on its own.

Hope this helps.

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: How to avoid accidental re-flash when secure boot enabled?

Postby ESP_Angus » Tue Mar 10, 2020 10:24 pm

Hi vjacobs & dld,

Unfortunately as you note esptool doesn't check if security features are enabled before flashing at the moment, but we have planned this as a change in esptool v3.0 (currently in development). We didn't want to add it in a v2.x update as it's a breaking change (there are also reasons to flash a secure boot + digest together, or a pre-encrypted payload and those scripts will need to updated to work with the new version).

The new behaviour will be not to flash a device with flash encryption or secure boot enabled by default, but to require a command line flag to "flash anyway".

In the meantime, something like what vjacobs describes - running espefuse.py first and checking the output - will work.

The ESP32 ECO V3 has an efuse to disable the UART loader entirely, but previous revisions unfortunately do not have this efuse.

axellin
Posts: 200
Joined: Mon Sep 17, 2018 9:09 am

Re: How to avoid accidental re-flash when secure boot enabled?

Postby axellin » Tue Mar 10, 2020 11:19 pm

ESP_Angus wrote:
Tue Mar 10, 2020 10:24 pm

The ESP32 ECO V3 has an efuse to disable the UART loader entirely, but previous revisions unfortunately do not have this efuse.
Is ESP32 ECO V3 ready for mass production?
I check the website: https://www.espressif.com/en/products/hardware/modules
The modules using ESP32 ECO V3 are marked as "RECOMMEND" but "Coming Soon"?

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: How to avoid accidental re-flash when secure boot enabled?

Postby ESP_Angus » Tue Mar 10, 2020 11:39 pm

axellin wrote:
Tue Mar 10, 2020 11:19 pm
Is ESP32 ECO V3 ready for mass production?
Recommend contacting Espressif sales about this. https://www.espressif.com/en/company/co ... stions-crm - I believe the answer depends on the quantity and which package/module you need, but they're the people to answer those questions.

dldtechnology
Posts: 10
Joined: Sun Nov 20, 2016 12:09 am

Re: How to avoid accidental re-flash when secure boot enabled?

Postby dldtechnology » Wed Mar 18, 2020 7:32 am

Thanks all for the info :D - we will do a manual fuse check first.

Who is online

Users browsing this forum: No registered users and 452 guests