Mass mfg: Release efuse config?

someburner
Posts: 7
Joined: Sun Oct 30, 2016 5:32 am

Mass mfg: Release efuse config?

Postby someburner » Thu Apr 13, 2023 10:21 pm

For a variety of reasons, we do not want the ESP32 to be self-encrypting during our mfg process. I have identified what I believe to be the right process for generating the flash enc key, flashing the secure boot v2 digest, and then flashing pre-encrypted binaries. But I would like to double check here.

1.) Other than

Code: Select all

UART_DOWNLOAD_DIS = false
, (and block2, which I replaced with ??s altho I understand that is public) does this configuration look correct for an ESP32 v3 (wroom32e) "release configuration"?

Code: Select all

Efuse fuses:
WR_DIS (BLOCK0):                                   Efuse write disable mask                           = 385 R/W (0x0181)
RD_DIS (BLOCK0):                                   Efuse read disable mask                            = 1 R/- (0x1)
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                               
   = b8:d6:1a:55:7f:84 (CRC 0x4a OK) R/W 
MAC_CRC (BLOCK0):                                  CRC8 for factory MAC address                       = 74 R/W (0x4a)
CHIP_VER_REV1 (BLOCK0):                            Silicon Revision 1                                 = True R/W (0b1)
CHIP_VER_REV2 (BLOCK0):                            Silicon Revision 2                                 = True R/W (0b1)
WAFER_VERSION_MINOR (BLOCK0):                      WAFER VERSION MINOR                                = 0 R/W (0b00)
CHIP_PACKAGE (BLOCK0):                             Chip package identifier                            = 1 R/W (0b001)
CHIP_PACKAGE_4BIT (BLOCK0):                        Chip package identifier #4bit                      = 0 R/W (0b0)
MAC_VERSION (BLOCK3):                              Version of the MAC field                           = 0 R/W (0x00)
WAFER_VERSION_MAJOR (BLOCK0):                      calc WAFER VERSION MAJOR from CHIP_VER_REV1 and CH = 3 R/W (0b011)
                                                   IP_VER_REV2 and apb_ctl_date (read only)          
PKG_VERSION (BLOCK0):                              calc Chip package = CHIP_PACKAGE_4BIT << 3 + CHIP_ = 1 R/W (0x1)
                                                   PACKAGE (read only)                               

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     = False R/W (0b0)
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                                   
   = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? R/- 
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 
2.) For the secure boot digest, we are using

Code: Select all

espefuse.py burn_key_digest key.pem
. However, it is not ideal to have the full signing key with our mfg. But I have seen in docs it says not to flash the secure boot digest (32 bytes) directly to BLOCK2 in case the chip has a different fuse config? Why can't we just do:

Code: Select all

espsecure.py digest_sbv2_public_key --keyfile key.pem --output digest.bin
espefuse.py burn_key secure_boot_v2 digest.bin
Or can you?

3.) Besides the sbv2 digest and the flash key, we issue the following burn_efuse commands, and then flash all of our encrypted binaries.

Code: Select all

'burn_efuse',
'FLASH_CRYPT_CNT',    '0x7F',
'FLASH_CRYPT_CONFIG', '0xF',
'DISABLE_DL_ENCRYPT', '0x1',
'DISABLE_DL_DECRYPT', '0x1',
'DISABLE_DL_CACHE',   '0x1',
'JTAG_DISABLE',       '0x1'
It seems like this works fine, but just want to make sure there are no issues with this. I found that setting FLASH_CRYPT_CNT to 0x1 was a problem because the bootloader would then also set UART_DOWNLOAD_DIS, which for the moment we don't want to do.

someburner
Posts: 7
Joined: Sun Oct 30, 2016 5:32 am

Re: Mass mfg: Release efuse config?

Postby someburner » Tue Apr 18, 2023 12:46 am

Regarding #2: espsecure.py automatically parses whether the .pem file is a private or public key and derives the public key. Perhaps there is a method in espsecure.py for this already but for future reference to anyone with a similar question you can just do

Code: Select all

openssl rsa -in private_key.pem -pubout > public_key.pem
and that works fine as an argument to burn_key_digest.

Overall I still find the documentation around efuses to be lacking. It would be nice to have more examples of all-in-one procedures, since if you're testing this out yourself you just have to burn through chips to see what works. I suppose there is the virtual efuse manager but seems time consuming when you just want to get to "release" efuse settings prior to first boot.

Maybe this is answered somewhere already but I am still unclear on a couple things:

1. Is it possible to combine all 3 of my operations into one command? (e.g. burn_key + burn_efuse + burn_key_digest)

2. How prevalent is the 3/4 / repeat efuse coding scheme on ESP32 wroom modules? Sounds like there were some batches some years ago that were 3/4 and now they are generally all "none" scheme?

3. Still curious about any input on whether my posted summary has any flaws or any fuses need write protecting.

ESP_WangYX
Posts: 97
Joined: Mon Jun 28, 2021 12:48 pm

Re: Mass mfg: Release efuse config?

Postby ESP_WangYX » Fri Apr 21, 2023 3:55 am

There is a tool that can be used to avoid device self encryption when enabling flash encryption: Flash Download Tools[/https://www.espressif.com/en/support/do ... ther-tools].
I think the espefuse.py cannot use different subcommands in one command at the same time. But it is possible to operate on multiple efuse domains in one subcommand, for example:

Code: Select all

espefuse.py -p $ESPPORT --do-not-confirm  burn_efuse DIS_DOWNLOAD_ICACHE 1 DIS_PAD_JTAG 1 DIS_USB_JTAG 1 DIS_DIRECT_BOOT 1 DIS_DOWNLOAD_MANUAL_ENCRYPT 1 FLASH_CRYPT_CONFIG 0xF

ESP_flying_raijin
Posts: 25
Joined: Tue Aug 13, 2019 2:03 pm

Re: Mass mfg: Release efuse config?

Postby ESP_flying_raijin » Fri Apr 28, 2023 3:56 am

Hi @someburner
Sorry for the delayed reply. Just to add here, we are currently in progress to add the documentation for enabling security features using espefuse tool. But that may be available publicly in a couple of weeks.

Please find my answers below

1) The eFuse summary look good to me.
However the write protection of certain security eFuses doesn't seem to be enabled.
Have you write protected eFuses such as FLASH_CRYPT_CNT ?

2) Writing the eFuse key that way is supported, you need to burn ABS_DONE_1 eFuse in order to enable Secure Boot version 2
When you are enabling secure boot, make sure you are disabling the ability to read disable the key blocks so that secure boot key would not be read protected (expected behaviour).
(WR_DIS_EFUSE_RD_DISABLE)

( Note: Flash encryption must be enabled before this because after this no key blocks can be read protected)

3)
I think you should add following eFuse to the list as well
CONSOLE_DEBUG_DISABLE 0x1

The UART_ROM_DL_MODE is disabled based on the option set for SECURE_ROM_DL_MODE_ENABLED config option. The value of FLASH_CRYPT_CNT does not determine that.
You may keep CONFIG_SECURE_INSECURE_ALLOW_DL_MODE set to prevent bootloader from disabling ROM DL mode.
1. Is it possible to combine all 3 of my operations into one command? (e.g. burn_key + burn_efuse + burn_key_digest)
At the moment it is not possible to combine Key burning operation with eFuse burning operation. You may execute the commands in succession with --do-no-confirm option for faster eFuse burning process.

Multiple eFuses can be burned in the same command as shown in
https://docs.espressif.com/projects/esp ... burn-efuse
More documentation regarding the espefuse tool can be found at https://docs.espressif.com/projects/esp ... spefuse-py

How prevalent is the 3/4 / repeat efuse coding scheme on ESP32 wroom modules? Sounds like there were some batches some years ago that were 3/4 and now they are generally all "none" scheme?
The 3/4 coding scheme has some limitations ( e.g. Secure Version is not supported). The default coding scheme is None for esp32 and it is recommended to keep it same. The size of keys also gets reduced in 3/4 coding scheme.

Additionally I would recommend disabling the ROM download mode completely. You can update the firmware using OTA afterwards.
If UART ROM DL mode is not disabled then a RAM loadable stub can be executed on the device which can bypass the secure boot check and work as a normal firmware ( it can even have the ability to decrypt the contents on the flash and dump them on UART)

I hope I have answered your queries.
Please let me know if you want me to elaborate on any point.
Thanks,
Aditya

Who is online

Users browsing this forum: atx823, Gaston1980, Majestic-12 [Bot] and 255 guests