How do I use flash encryption and non-OTA updates?

M-Schiller
Posts: 6
Joined: Tue Aug 09, 2022 6:30 am

How do I use flash encryption and non-OTA updates?

Postby M-Schiller » Tue Nov 08, 2022 8:00 am

Hi everyone,

I am trying to understand flash encryption (https://docs.espressif.com/projects/esp ... ption.html) and would like to get some help in regards to whether my thoughts make sense and can be achieved somehow.

What I'm trying to achieve:
  1. Make it impossible to read the encryption key via either JTAG or UART.
  2. Make it impossible / not helpful to read out the application binary via JTAG or UART. (I guess this can be achieved via (1) - if the key is unreadable, the encrypted binary is not helpful.)
  3. Allow unlimited updates using pre-encrypted images via JTAG or UART.
These requirements are necessary (IMHO) in order to make it impractical to just download the software and flash it to another device.

I figured that my requirements necessitate some hybrid form of "development" and "release" mode.

What I did so far is, create a key and flash it to block1.
Can or should I change R/W access bits for block1? Can or should I protect the block1 e-fuses?

Furthermore, I will need to set DISABLE_DL_DECRYPT according to the notice in the above link:
"Leaving DISABLE_DL_DECRYPT unset (0) makes flash encryption useless."
Will this disable serial updates using pre-encrypted images?

Which e-fuses will I need to burn in order to achieve the stated goals?
Am I missing any significant security flaw here?
Which e-fuse protections are required or just useful?

Thanks in advance.


EDIT: After further reading, I've come to the conclusion that "Development" and "Release" mode are just configurations of
`DISABLE_DL_ENCRYPT`, `DISABLE_DL_DECRYPT`, `DISABLE_DL_CACHE` and a bunch of other e-fuses. Is my understanding correct?
Last edited by M-Schiller on Thu Nov 10, 2022 8:46 am, edited 4 times in total.

error404
Posts: 12
Joined: Thu May 12, 2022 8:54 am

Re: Flash Encryption and non-OTA updates

Postby error404 » Thu Nov 10, 2022 8:05 am

I want to achieve a goal similar to what @M-Schiller wants.

Does someone have answers to his questions? :?:

dmitrij999
Posts: 71
Joined: Sat Mar 02, 2019 8:06 pm

Re: Flash Encryption and non-OTA updates

Postby dmitrij999 » Thu Nov 10, 2022 8:48 am

Based on my experience, yes, you can, and there are some moments:
1) The key automatically becomes unreadable via UART/JTAG after first running you application and bootloader with flash encryption enabled
2) After that, you can readout only encrypted binary
3) To be able to update your software unlimited, you need to pre-generate the encryption key, flash your flash contents without reboot, then burn your encryption key, and then reboot. Wait until it encrypts all the flash contents and reboot. Then you will have flash contents encrypted and be able to update via serial, using your key to pre-encrypt your image.

As well, despite of Espressif advice to disable UART ROM downloader, you need to leave it enabled. If possible to leave secure UART ROM downloader, use it.
For security reasons, please generate the per-device key instead of generating the key common for other devices.

M-Schiller
Posts: 6
Joined: Tue Aug 09, 2022 6:30 am

Re: How do I use flash encryption and non-OTA updates?

Postby M-Schiller » Thu Nov 10, 2022 9:00 am

Thanks for your response, do you perhaps have any course of actions in regards to the eFuses?

I have burned my key already, however will I need to change anything here? I've been hesitant to flash an encrypting BL because I don't want to brick my device.

---------------------------------------- Excerpt of espefuse.py's output -------------------------------------------------
Efuse fuses:
WR_DIS (BLOCK0): Efuse write disable mask = 128 R/W (0x0080)
RD_DIS (BLOCK0): Efuse read disable mask = 1 R/W (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)

------------------------------------------------------------------------------------------------------------------------------------

I think especially these fuses would be important:
  • DISABLE_DL_DECRYPT - needs to be burned
  • DISABLE_DL_ENCRYPT - ???
  • DISABLE_DL_CACHE - ???
  • FLASH_CRYPT_CNT - I guess this needs to be burned to a specific value as well, otherwise you could just set a bit here, flash a new plaintext bootloader and have it dump the flash contents, correct?
  • UART_DOWNLOAD_DIS - needs to be unset (0) and write-protected, right?
  • JTAG_DISABLE - needs to be unset (0) and write-protected, right?

dmitrij999
Posts: 71
Joined: Sat Mar 02, 2019 8:06 pm

Re: How do I use flash encryption and non-OTA updates?

Postby dmitrij999 » Thu Nov 10, 2022 10:32 pm

As I remember, I didn't alter any of eFUSE you name on my own. They were altered by the bootloader.
Here is the part of my config regarding the bootloader:

Code: Select all

#
# Security features
#
# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set
# CONFIG_SECURE_BOOT 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
# end of Security features

DISABLE_DL_DECRYPT - disables decryption with DL mode in readout
DISABLE_DL_ENCRYPT - disables encryption with DL mode in flashing (if set, you need to flash pre-encrypted images)
FLASH_CRYPT_CNT - counter for DEVELOPMENT mode
UART_DOWNLOAD_DIS - do you have ESP32-V3-ECO?

As an option, I propose you to use virtual efuses creating the efuse_em partition in its table and configure efuse controller

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

Re: How do I use flash encryption and non-OTA updates?

Postby ESP_Mahavir » Fri Nov 11, 2022 6:42 am

Hello,
DISABLE_DL_DECRYPT - needs to be burned
Yes. This EFuse needs to be burned to disable decryption in UART DL mode.
DISABLE_DL_ENCRYPT - ???
This must not be disabled. Otherwise, you won't be able to write encrypted data in UART DL mode.
DISABLE_DL_CACHE - ???
This disables cache in UART DL mode. You may disable it, as it won't affect the encrypted write path.
FLASH_CRYPT_CNT - I guess this needs to be burned to a specific value as well, otherwise you could just set a bit here, flash a new plaintext bootloader and have it dump the flash contents, correct?
This should be write protected with odd number of bits set. This will write protect the UART DL mode settings for ESP32 ECO3 revision (bit 7 from this field is used to disable UART DL mode) too. Please see https://github.com/espressif/esp-idf/bl ... .c#L43-L61
UART_DOWNLOAD_DIS - needs to be unset (0) and write-protected, right?
Please see reply above
JTAG_DISABLE - needs to be unset (0) and write-protected, right?
I think you can keep JTAG disabled, or you want to allow debugging too?

You can try all settings virtually under ESP32 port for Qemu. Please see documentation at: https://github.com/espressif/qemu/wiki

Who is online

Users browsing this forum: Google [Bot] and 105 guests