Thanks for your detailed answer , I understand that completely Now.ESP_Angus wrote:As WiFive says, using flash encryption & secure boot together provides local physical firmware security. To protect data in transit over the network, you need additional steps.
To prevent OTA updates being downloaded by unauthorised parties, I'd recommend using HTTPS and some kind of authentication method based on a private key or other secret stored in the client ESP32 - either TLS Client Certificate auth, or some kind of secret device ID which is not broadcast but stored encrypted in the ESP32 flash.
The ESP32 identifies itself to the server over HTTPS, and then the sends provides the .bin image using TLS to encrypt the data transfer.
Questions regarding flash encryption and Secure Boot
Re: Questions regarding flash encryption and Secure Boot
Re: Questions regarding flash encryption and Secure Boot
Hi,
I read this post and information about flash encryption and secure boot but still I'm not sure what is the best way in my scenario. I tried to create ESP32 based device of course. But after selling product I want to allow users upgrade firmware, so of course I should use OTA feature. But I also wan't to allow user to upgrade firmware using UART or web interface without connection to Internet, but providing firmware file on the website.
So what is the best solution? I'm thinking that the best way is sue Secure Boot + Flash encryption but with fixed keys for all devices and then provide pre-signed binaries on the website. But if I understand correctly I need to modify OTA procedures to use write procedures without encryption. The problem I found is that pre-signed images need to know what is the fixed address in flash and for OTA this address can be different for both partitions?
So maybe I need to use another key used for firmware file encryption (can I store another key in efuse?) and then decrypt firmware on the fly and burn to flash and this will encrypt data again but using build in keys.
Is there any simple but good solution to provide users offline firmware, but be sure that firmware can run only on my devices ?
I read this post and information about flash encryption and secure boot but still I'm not sure what is the best way in my scenario. I tried to create ESP32 based device of course. But after selling product I want to allow users upgrade firmware, so of course I should use OTA feature. But I also wan't to allow user to upgrade firmware using UART or web interface without connection to Internet, but providing firmware file on the website.
So what is the best solution? I'm thinking that the best way is sue Secure Boot + Flash encryption but with fixed keys for all devices and then provide pre-signed binaries on the website. But if I understand correctly I need to modify OTA procedures to use write procedures without encryption. The problem I found is that pre-signed images need to know what is the fixed address in flash and for OTA this address can be different for both partitions?
So maybe I need to use another key used for firmware file encryption (can I store another key in efuse?) and then decrypt firmware on the fly and burn to flash and this will encrypt data again but using build in keys.
Is there any simple but good solution to provide users offline firmware, but be sure that firmware can run only on my devices ?
Re: Questions regarding flash encryption and Secure Boot
Hi marbalon,
We haven't really talked about local UART updates in flash encryption + secure boot model, but it's possible:
- One possibility (as you've mentioned) is to store the pregenerated keys for each device (you can use the same key for all devices, but we don't recommend this as you have "all your keys in one basket"). Then distribute pre-encrypted signed app .bin files and a pre-encrypted otadata partition. By flashing both these at once via the standard esptool.py, the otadata partition will set the ESP32 to boot from the just-flashed OTA app partition.
- The other possibility is to build an OTA mechanism that use your own serial protocol or some other local access protocol. The OTA framework ("app_update" API) in ESP-IDF is protocol-agnostic, it assumes you get a stream of bytes (from somewhere) and then pass it to the app_update API. The assumption is that this will be some kind of network protocol, but you could just as easily implement something like ZMODEM over serial (to error correct the data in flight) and push that stream of data into the app_update API.
Or if you have something like an SD card slot, you can have users copy a file onto the SD and then load it from there, etc, etc.
We haven't really talked about local UART updates in flash encryption + secure boot model, but it's possible:
- One possibility (as you've mentioned) is to store the pregenerated keys for each device (you can use the same key for all devices, but we don't recommend this as you have "all your keys in one basket"). Then distribute pre-encrypted signed app .bin files and a pre-encrypted otadata partition. By flashing both these at once via the standard esptool.py, the otadata partition will set the ESP32 to boot from the just-flashed OTA app partition.
- The other possibility is to build an OTA mechanism that use your own serial protocol or some other local access protocol. The OTA framework ("app_update" API) in ESP-IDF is protocol-agnostic, it assumes you get a stream of bytes (from somewhere) and then pass it to the app_update API. The assumption is that this will be some kind of network protocol, but you could just as easily implement something like ZMODEM over serial (to error correct the data in flight) and push that stream of data into the app_update API.
Or if you have something like an SD card slot, you can have users copy a file onto the SD and then load it from there, etc, etc.
Re: Questions regarding flash encryption and Secure Boot
Thanks for your answer. I finally made what I want to do
But I have also two questions:
1. If I wan't to protect only firmware binary, flash encryption is enough with this efuse settings ?
2. And what is ABS_DONE_1 because I can't find detailed desctiption of this bit.
BR,
Marcin.
But I have also two questions:
1. If I wan't to protect only firmware binary, flash encryption is enough with this efuse settings ?
Code: Select all
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)
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
= 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 -/-
BR,
Marcin.
Re: Questions regarding flash encryption and Secure Boot
Yes, this is sufficient to protect against firmware readout (without an attacker finding some software vulnerability).marbalon wrote: 1. If I wan't to protect only firmware binary, flash encryption is enough with this efuse settings ?
Code: Select all
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) 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 = 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 -/-
This efuse is not currently used.marbalon wrote: 2. And what is ABS_DONE_1 because I can't find detailed desctiption of this bit.
-
- Posts: 9
- Joined: Thu Apr 12, 2018 7:03 am
Re: Questions regarding flash encryption and Secure Boot
Hi
I have a small question about rewriting the bootloader.
So I use the pregenerated key, I quietly encrypt and rewrite the firmware.
But I can not re-write the bootloader, even in encrypted form.
Why can not I overwrite the bootloader with an encrypted file?
I have a small question about rewriting the bootloader.
So I use the pregenerated key, I quietly encrypt and rewrite the firmware.
But I can not re-write the bootloader, even in encrypted form.
Why can not I overwrite the bootloader with an encrypted file?
Re: Questions regarding flash encryption and Secure Boot
If you don't have secure boot enabled, you can encrypt the bootloader with your known key and replace it.Yuriy Bohdanovsky wrote:Hi
I have a small question about rewriting the bootloader.
So I use the pregenerated key, I quietly encrypt and rewrite the firmware.
But I can not re-write the bootloader, even in encrypted form.
Why can not I overwrite the bootloader with an encrypted file?
If you do have secure boot enabled, you can't do this - the bootloader is read-only once secure boot is enabled. This is to prevent a software exploit on the device (software can write encrypted data) from replacing code in order to persist the exploit.
-
- Posts: 9
- Joined: Thu Apr 12, 2018 7:03 am
Re: Questions regarding flash encryption and Secure Boot
Hi
I'm using the setting
I write the firmware and bootloader, in the terminal I see how the bootloader encrypts the memory.
Next, I overwrite the firmware file and the table file in encrypted form.
Everything is working.
To encrypt the bootloader file, I use the command
When I write a bootloader with an encrypted file
I get a brick.
what's my mistake?
thank you for your help
I'm using the setting
Code: Select all
sdkconfig
CONFIG_SECURE_BOOT_ENABLED=
CONFIG_FLASH_ENCRYPTION_ENABLED=y
CONFIG_FLASH_ENCRYPTION_INSECURE=
Next, I overwrite the firmware file and the table file in encrypted form.
Everything is working.
To encrypt the bootloader file, I use the command
Code: Select all
$python /home/osboxes/esp/esp-idf/components/esptool_py/esptool/espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x1000 -o bootloader-encrypted.bin bootloader.bin
I get a brick.
Code: Select all
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371
ets Jun 8 2016 00:22:57
thank you for your help
-
- Posts: 9
- Joined: Thu Apr 12, 2018 7:03 am
Re: Questions regarding flash encryption and Secure Boot
My security fuses
Code: Select all
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 = 0 R/W (0x0)
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
= 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 -/-
BLK2 Secure boot key
= 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
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 = 128 R/W (0x80)
RD_DIS Efuse read disablemask = 1 R/W (0x1)
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)
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 MAC Address
= 30:ae:a4:7b:c7:14 (CRC d3 OK) R/W
CHIP_VERSION Chip version = 8 -/W (0x8)
CHIP_PACKAGE Chip package identifier = 0 -/W (0x0)
Flash voltage (VDD_SDIO) determined by GPIO12 on reset (High for 1.8V, Low/NC for 3.3V).
Re: Questions regarding flash encryption and Secure Boot
This all looks correct. Did you use the same my_flash_encryption_key.bin for the app firmware & partition table when you overwrote those? Was this key written into the ESP32 with espefuse.py before the first boot?Yuriy Bohdanovsky wrote: I write the firmware and bootloader, in the terminal I see how the bootloader encrypts the memory.
Next, I overwrite the firmware file and the table file in encrypted form.
Everything is working.
To encrypt the bootloader file, I use the commandWhen I write a bootloader with an encrypted fileCode: Select all
$python /home/osboxes/esp/esp-idf/components/esptool_py/esptool/espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x1000 -o bootloader-encrypted.bin bootloader.bin
Are you sure you flashed bootloader-encrypted.bin not bootloder.bin? Can you post the full esptool.py command lines you used each time?