Which version of SecureBoot should I use for ESP32-WROVER-E

RuslanPopov
Posts: 21
Joined: Mon Nov 21, 2022 3:47 pm

Which version of SecureBoot should I use for ESP32-WROVER-E

Postby RuslanPopov » Mon Nov 21, 2022 3:56 pm

Hi all.

I have written a firmware without looking at the chip on the board. There were no problems until I started to activate the SecureBoot feature. I thought that I have worked with usual ESP32-WROOM-32 and have setted the SecureBoot v1 and have burnt everything in reflashable mode. But I failed.

Then I took the other chip and repeat the process. I was successful and decide to compare the chips and then I have known that the last one was REV1 and first on was REV3.

Which version of SecureBoot should I use for WROVER-E to successfullt activate bootloader?

Also, am I understand the following right and the chip is trying to boot from unsigned booloader.bin?

Code: Select all

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
ets Jul 29 2019 12:21:46

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
invalid header: 0x9f51083b
ets Jul 29 2019 12:21:46

ESP_Mahavir
Posts: 188
Joined: Wed Jan 24, 2018 6:51 am

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby ESP_Mahavir » Tue Nov 22, 2022 4:31 am

Hello,

Please use following command to get the revision of ESP32:

Code: Select all

esptool.py chip_id --port <PORT>
For ESP32 ECO3 (revision 3), both secure boot v1 and v2 are supported. We recommend using secure boot v2 scheme.

For earlier revisions, only secure boot v1 is supported.

From the failure logs you shared, it appears to be the case that ROM loader was unable to find correct bootloader binary in the flash (offset 0x1000). Please share details about the steps you followed, artifacts that were flashed and EFuse summary. This will help to understand the problem.

RuslanPopov
Posts: 21
Joined: Mon Nov 21, 2022 3:47 pm

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby RuslanPopov » Tue Nov 22, 2022 10:31 pm

Code: Select all

esptool.py chip_id
esptool.py v4.1
Found 1 serial ports
Serial port /dev/ttyACM0
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
Chip is ESP32-D0WD-V3 (revision 3)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 34:86:5d:ad:f9:e0
Uploading stub...
Running stub...
Stub running...
Warning: ESP32 has no Chip ID. Reading MAC instead.
MAC: 34:86:5d:ad:f9:e0
Hard resetting via RTS pin...

RuslanPopov
Posts: 21
Joined: Mon Nov 21, 2022 3:47 pm

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby RuslanPopov » Tue Nov 22, 2022 10:37 pm

Burn the secure boot key:

Code: Select all

espefuse.py burn_key secure_boot_v1 ../keys/secure-bootloader-key-256.bin --force-write-always --port=/dev/ttyACM0
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting......
Detecting chip type... ESP32
espefuse.py v4.1

=== Run "burn_key" command ===
Burn keys to blocks:
 - BLOCK2 -> [63 e5 23 e9 3c e7 65 9f e2 0e ca ea 88 71 4c cb 7d 97 1c 1a b5 f2 25 39 3a df bb 4c 38 97 b3 4c]
	Reversing the byte order
	BLOCK2 is read-protected.	Burn in this case may damage an already written value. Skipped because '--force-write-always' option.
	BLOCK2 is write-protected. Burn is not possible. Skipped because '--force-write-always' option.
	Disabling read to key block
	Disabling write to key block

Burn keys in efuse blocks.
The key block will be read and write protected


Check all blocks for burn...
idx, BLOCK_NAME,          Conclusion
[00] BLOCK0               is not empty
	(written ): 0x000003f4f0100000000010380000a200000734865dadf9e007f30180
	(to write): 0x00000000000000000000000000000000000000000000000000020100
	All wr_data bits are set in the written block, continue with EMPTY_BLOCK.
	BLOCK2 is read-protected.	Burn in this case may damage an already written value. Skipped because '--force-write-always' option.
	BLOCK2 is write-protected. Burn is not possible. Skipped because '--force-write-always' option.
[02] BLOCK2               is empty, will burn the new value
.
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BLOCK2 (['secure_boot_v1', 'secure_boot_v2']) is read-protected. Read back the burn value is not possible.
Read all '0'
Reading updated efuses...
Successful
Burn the flash encryption key:

Code: Select all

espefuse.py burn_key flash_encryption ../keys/flash_encription_key.bin --force-write-always --port=/dev/ttyACM0
Connecting.....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
espefuse.py v4.1

=== Run "burn_key" command ===
Burn keys to blocks:
 - BLOCK1 -> [d0 b0 b8 52 f1 4f 32 a7 5f e4 0b 4d 84 f5 4e 2b 91 1b 6c 73 17 b9 b1 c6 45 96 5c 22 d4 81 09 55]
	Reversing the byte order
	BLOCK1 is read-protected.	Burn in this case may damage an already written value. Skipped because '--force-write-always' option.
	BLOCK1 is write-protected. Burn is not possible. Skipped because '--force-write-always' option.
	Disabling read to key block
	Disabling write to key block

Burn keys in efuse blocks.
The key block will be read and write protected


Check all blocks for burn...
idx, BLOCK_NAME,          Conclusion
[00] BLOCK0               is not empty
	(written ): 0x000003f4f0100000000010380000a200000734865dadf9e007f30180
	(to write): 0x00000000000000000000000000000000000000000000000000010080
	All wr_data bits are set in the written block, continue with EMPTY_BLOCK.
	BLOCK1 is read-protected.	Burn in this case may damage an already written value. Skipped because '--force-write-always' option.
	BLOCK1 is write-protected. Burn is not possible. Skipped because '--force-write-always' option.
[01] BLOCK1               is empty, will burn the new value
.
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BLOCK1 (['flash_encryption']) is read-protected. Read back the burn value is not possible.
Read all '0'
Reading updated efuses...
Successful
Encrypt the image of bootloader with its digest:

Code: Select all

espsecure.py encrypt_flash_data --keyfile ../keys/flash_encription_key.bin --address 0x0 --output bootloader-reflash-digest.enc.bin bootloader-reflash-digest.bin
espsecure.py v4.1
Using 256-bit key
Flash the image:

Code: Select all

esptool.py --chip esp32 --port=/dev/ttyACM0 --baud=460800 --before=default_reset --after=no_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x0 bootloader-reflash-digest.enc.bin --force
esptool.py v4.1
Serial port /dev/ttyACM0
Connecting....
Chip is ESP32-D0WD-V3 (revision 3)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 34:86:5d:ad:f9:e0
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x0000bfff...
Compressed 46592 bytes to 44873...
Wrote 46592 bytes (44873 compressed) at 0x00000000 in 1.4 seconds (effective 271.6 kbit/s)...
Hash of data verified.

Leaving...
Staying in bootloader.
Monitoring:

Code: Select all

make monitor BAUD=115200 PORT=/dev/ttyACM0
pyserial-miniterm --raw /dev/ttyACM0 115200
--- Miniterm on /dev/ttyACM0  115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
ets Jul 29 2019 12:21:46

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
ets Jul 29 2019 12:21:46

ESP_Mahavir
Posts: 188
Joined: Wed Jan 24, 2018 6:51 am

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby ESP_Mahavir » Wed Nov 23, 2022 8:26 am

Can you please share the output of following command:

Code: Select all

espefuse.py --summary --chip esp32 --port <PORT>
I see that you have programmed flash encryption and secure boot keys externally but would like to confirm if the feature itself is enabled or not.

- Value of `ABS_DONE_0` from eFuse can confirm if secure boot v1 is enabled or not
- Value of `FLASH_CRYPT_CNT` (odd number of 1's) can confirm if flash encryption is enabled or not

RuslanPopov
Posts: 21
Joined: Mon Nov 21, 2022 3:47 pm

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby RuslanPopov » Wed Nov 23, 2022 8:36 am

Code: Select all

espefuse.py summary --baud=115200 --port=/dev/ttyACM0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP32
espefuse.py v4.1

=== Run "summary" command ===
EFUSE_NAME (Block) Description  = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Calibration fuses:
BLK3_PART_RESERVE (BLOCK0):                        BLOCK3 partially served for ADC calibration data   = False R/W (0b0)
ADC_VREF (BLOCK0):                                 Voltage reference calibration                      = 1100 R/W (0b10000)

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

Efuse fuses:
WR_DIS (BLOCK0):                                   Efuse write disable mask                           = 384 R/W (0x0180)
RD_DIS (BLOCK0):                                   Efuse read disable mask                            = 3 R/W (0x3)
CODING_SCHEME (BLOCK0):                            Efuse variable block length scheme
   = NONE (BLK1-3 len=256 bits) R/W (0b00)
KEY_STATUS (BLOCK0):                               Usage of efuse block 3 (reserved)                  = False R/W (0b0)

Identity fuses:
MAC (BLOCK0):                                      Factory MAC Address
   = 34:86:5d:ad:f9:e0 (CRC 0x07 OK) R/W
MAC_CRC (BLOCK0):                                  CRC8 for factory MAC address                       = 7 R/W (0x07)
CHIP_VER_REV1 (BLOCK0):                            Silicon Revision 1                                 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0):                            Silicon Revision 2                                 = True R/W (0b1)
CHIP_VERSION (BLOCK0):                             Reserved for future chip versions                  = 2 R/W (0b10)
CHIP_PACKAGE (BLOCK0):                             Chip package identifier                            = 1 R/W (0b001)
CHIP_PACKAGE_4BIT (BLOCK0):                        Chip package identifier #4bit                      = False R/W (0b0)
MAC_VERSION (BLOCK3):                              Version of the MAC field                           = 0 R/W (0x00)

Security fuses:
FLASH_CRYPT_CNT (BLOCK0):                          Flash encryption mode counter                      = 127 R/W (0b1111111)
UART_DOWNLOAD_DIS (BLOCK0):                        Disable UART download mode (ESP32 rev3 only)       = False R/W (0b0)
FLASH_CRYPT_CONFIG (BLOCK0):                       Flash encryption config (key tweak bits)           = 15 R/W (0xf)
CONSOLE_DEBUG_DISABLE (BLOCK0):                    Disable ROM BASIC interpreter fallback             = True R/W (0b1)
ABS_DONE_0 (BLOCK0):                               Secure boot V1 is enabled for bootloader image     = True R/W (0b1)
ABS_DONE_1 (BLOCK0):                               Secure boot V2 is enabled for bootloader image     = True R/W (0b1)
JTAG_DISABLE (BLOCK0):                             Disable JTAG                                       = True R/W (0b1)
DISABLE_DL_ENCRYPT (BLOCK0):                       Disable flash encryption in UART bootloader        = True R/W (0b1)
DISABLE_DL_DECRYPT (BLOCK0):                       Disable flash decryption in UART bootloader        = True R/W (0b1)
DISABLE_DL_CACHE (BLOCK0):                         Disable flash cache in UART bootloader             = True R/W (0b1)
BLOCK1 (BLOCK1):                                   Flash encryption key
   = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLOCK2 (BLOCK2):                                   Secure boot key
   = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
BLOCK3 (BLOCK3):                                   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

Flash voltage (VDD_SDIO) determined by GPIO12 on reset

ESP_Mahavir
Posts: 188
Joined: Wed Jan 24, 2018 6:51 am

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby ESP_Mahavir » Wed Nov 23, 2022 4:02 pm

It appears that you have both secure boot v1 and v2 schemes enabled in the eFuse settings. In this case, secure boot v2 shall take the precedence. However, I am not sure how this really happened, probably you experimented with both the settings.

Error from ROM loader regarding "invalid header" points to the incorrect contents in the flash. From eFuse settings, flash encryption is enabled on the device and hence its very likely that ROM loader is not decrypting correct contents from the flash here (offset 0x1000), it expects for the image header but instead it is finding garbage. Only reason why this could happen is, bootloader is not encrypted with the key that is programmed in the eFuse.

Can you please double check if you are using same flash encryption key to encrypt the contents that was programmed in the eFuse?

RuslanPopov
Posts: 21
Joined: Mon Nov 21, 2022 3:47 pm

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby RuslanPopov » Wed Nov 23, 2022 4:10 pm

Yes, you're right. I have worked with SBv1, failed, then read about SBv2 and tried to use it, failed again :)

Then I have checked ESP-IDF sources and found that my error messages point to Flash Encryption feature.

I have checked all (I hope that) ways to upload clear and encrypted bootloader binaries and other binaries (partitions, application and so on).

Your answer about SBv2 precedence gives me the way which I should check. I will do it this night and report here. Thank you!

RuslanPopov
Posts: 21
Joined: Mon Nov 21, 2022 3:47 pm

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby RuslanPopov » Wed Nov 23, 2022 8:30 pm

I have rebuilded bootloader with SecureBoot v2.

Code: Select all

#
# Security features
#
CONFIG_SECURE_SIGNED_ON_BOOT=y
CONFIG_SECURE_SIGNED_ON_UPDATE=y
CONFIG_SECURE_SIGNED_APPS=y
CONFIG_SECURE_BOOT_SUPPORTS_RSA=y
CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=y
CONFIG_SECURE_BOOT=y
# CONFIG_SECURE_BOOT_V1_ENABLED is not set
CONFIG_SECURE_BOOT_V2_ENABLED=y
CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES=y
CONFIG_SECURE_BOOT_SIGNING_KEY="keys/secure_boot_v2_signing_key.pem"
# CONFIG_SECURE_BOOT_INSECURE is not set
CONFIG_SECURE_FLASH_ENC_ENABLED=y
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT is not set
CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=y
CONFIG_SECURE_FLASH_CHECK_ENC_EN_IN_APP=y
# CONFIG_SECURE_DISABLE_ROM_DL_MODE is not set
CONFIG_SECURE_INSECURE_ALLOW_DL_MODE=y
# end of Security features
Then manually encrypt booloader:

Code: Select all

espsecure.py encrypt_flash_data --keyfile ../keys/flash_encription_key.bin --address 0x0 --output bootloader-reflash-digest.enc.bin bootloader-reflash-digest.bin
espsecure.py v4.1
Using 256-bit key
Burn the flash encryption key:

Code: Select all

espefuse.py burn_key flash_encryption ../keys/flash_encription_key.bin --force-write-always --port=/dev/ttyACM0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting......
Detecting chip type... ESP32
espefuse.py v4.1

=== Run "burn_key" command ===
Burn keys to blocks:
 - BLOCK1 -> [d0 b0 b8 52 f1 4f 32 a7 5f e4 0b 4d 84 f5 4e 2b 91 1b 6c 73 17 b9 b1 c6 45 96 5c 22 d4 81 09 55]
	Reversing the byte order
	BLOCK1 is read-protected.	Burn in this case may damage an already written value. Skipped because '--force-write-always' option.
	BLOCK1 is write-protected. Burn is not possible. Skipped because '--force-write-always' option.
	Disabling read to key block
	Disabling write to key block

Burn keys in efuse blocks.
The key block will be read and write protected


Check all blocks for burn...
idx, BLOCK_NAME,          Conclusion
[00] BLOCK0               is not empty
	(written ): 0x000003f4f0100000000010380000a200000734865dadf9e007f30180
	(to write): 0x00000000000000000000000000000000000000000000000000010080
	All wr_data bits are set in the written block, continue with EMPTY_BLOCK.
	BLOCK1 is read-protected.	Burn in this case may damage an already written value. Skipped because '--force-write-always' option.
	BLOCK1 is write-protected. Burn is not possible. Skipped because '--force-write-always' option.
[01] BLOCK1               is empty, will burn the new value
.
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BLOCK1 (['flash_encryption']) is read-protected. Read back the burn value is not possible.
Read all '0'
Reading updated efuses...
Successful
Then burn the image:

Code: Select all

esptool.py --chip esp32 --port=/dev/ttyACM0 --baud=460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x0 bootloader-reflash-digest.enc.bin --force && make monitor BAUD=115200 PORT=/dev/ttyACM0
esptool.py v4.1
Serial port /dev/ttyACM0
Connecting....
Chip is ESP32-D0WD-V3 (revision 3)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 34:86:5d:ad:f9:e0
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00000000 to 0x0000bfff...
Compressed 46592 bytes to 44873...
Wrote 46592 bytes (44873 compressed) at 0x00000000 in 1.4 seconds (effective 271.2 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
pyserial-miniterm --raw /dev/ttyACM0 115200
--- Miniterm on /dev/ttyACM0  115200,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
�Ғ�Ң�j

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
invalid header: 0xf3a2770d
ets Jul 29 2019 12:21:46
Nothing helps :(

ESP_Mahavir
Posts: 188
Joined: Wed Jan 24, 2018 6:51 am

Re: Which version of SecureBoot should I use for ESP32-WROVER-E

Postby ESP_Mahavir » Thu Nov 24, 2022 9:09 am

MAC: 34:86:5d:ad:f9:e0
Based on the MAC address, I see that you are trying to program flash encryption key multiple times on same device. This is not possible as EFuse is one time programmable (moreover the block is already read/write protected).

I would recommend that you verify this workflow under emulator once (https://github.com/espressif/qemu/wiki) or a new ESP32 device.

Who is online

Users browsing this forum: StanInexeon and 128 guests