encryption still enabled after FLASH_CRYPT_CNT=0xff and ABS_DONE_X = 0

PotatoMan
Posts: 2
Joined: Fri Nov 23, 2018 9:32 am

encryption still enabled after FLASH_CRYPT_CNT=0xff and ABS_DONE_X = 0

Postby PotatoMan » Fri Nov 23, 2018 10:03 am

Hello!

In our project we are planning to encrypt our firmware, but allow users to disable encryption and write their own.
Our planned installation procedure is as follows:
1) write custom bootloader to spi flash, that has only one purpose: write pregenerated key and enable encryption in fuses, set FLASH_CRYPT_CNT to 0x7f, but leave ABS_DONE_X bits 0x0
2) write encrypted bootloader, partition table and firmware to spi flash

everything works as expected, however after updating FLASH_CRYPT_CNT to 0xff, flash encryption is still enabled

In https://dl.espressif.com/doc/esp-idf/la ... -crypt-cnt it states that
After all 8 bits are set (efuse value 0xFF): Transparent reading of encrypted flash is disabled, any encrypted data is permanently inaccessible. Bootloader will normally detect this condition and halt.
that would mean that flash encryption should be disabled, but writing unencrypted firmware in spi flash results in the following output:

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
while writing encrypted firmware works fine.

espefuse summary:

Code: Select all

espefuse.py v2.6-beta1
Connecting....
EFUSE_NAME             Description = [Meaningful Value] [Readable/Writeable] (Hex Value)
----------------------------------------------------------------------------------------
Security fuses:
FLASH_CRYPT_CNT        Flash encryption mode counter                     = 255 R/W (0xff)
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                              
  = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/- 
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:2a:6f:d4 (CRC 51 OK) R/W 
CHIP_VER_REV1          Silicon Revision 1                                = 1 R/W (0x1)
CHIP_VERSION           Reserved for future chip versions                 = 0 R/W (0x0)
CHIP_PACKAGE           Chip package identifier                           = 0 R/W (0x0)

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

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

Code: Select all

espefuse.py v2.6-beta1
Connecting........_____....._____....._____....._
EFUSE block 0:
0ff10080 a42a6fd4 005130ae 00008000 00000039 f0000000 000003c4
EFUSE block 1:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
EFUSE block 2:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
EFUSE block 3:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Thank You

PotatoMan
Posts: 2
Joined: Fri Nov 23, 2018 9:32 am

Re: encryption still enabled after FLASH_CRYPT_CNT=0xff and ABS_DONE_X = 0

Postby PotatoMan » Thu Nov 29, 2018 3:33 pm

bump

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

Re: encryption still enabled after FLASH_CRYPT_CNT=0xff and ABS_DONE_X = 0

Postby ESP_Angus » Fri Nov 30, 2018 12:02 am

Hi PotatoMan,

Sorry I didn't see your post the first time around.

I must also apologise, the Flash Encryption documentation is incorrect about this. The ESP32 Technical Reference Manual section 25.3.3 "Flash Decryption Block" gives the actual behaviour of FLASH_CRYPT_CNT:
• During SPI Flash Boot
In the low 7 bits of flash_crypt_cnt, if the number of value 1 is odd, the Flash Decryption block is
operational. Otherwise, it is not.
So the top bit of this efuse field is ignored, and the maximum number of (effective) bits is 7 (value 0x7f).

If you wish to allow users to disable encryption and write their own firmware (an admirable goal), you could burn FLASH_CRYPT_CNT with 5 bits (value 0x1f) and instruct users to burn an additional bit (value 0x3f) to disable. However, this will not be as secure because it's now possible to flash a plaintext bootloader which encrypts itself, re-enables encryption (value 0x7f), and dumps the decrypted app contents on the next boot.

Will update the flash encryption documentation ASAP.

User avatar
brp80000
Posts: 138
Joined: Thu Oct 04, 2018 7:13 pm

Re: encryption still enabled after FLASH_CRYPT_CNT=0xff and ABS_DONE_X = 0

Postby brp80000 » Tue Dec 04, 2018 6:04 pm

Could you share an example of bootloader with encryption))?

Who is online

Users browsing this forum: Timmwardion and 133 guests