encrypt firmware with ESP32

AlexESP32
Posts: 34
Joined: Thu Oct 03, 2019 9:41 am

encrypt firmware with ESP32

Postby AlexESP32 » Mon Jun 29, 2020 7:52 pm

Hey guys ;)

As mentioned in the topic I want to encrypt the firmware with the stored nvs data (password, certificates, ...).
Unfortunately I didn't understand the method of the espressif documentation (flash encryption, nvs encrytpion, secure boot).

To encrypt the NVS there are some questions:
Do I really need to adjust the source code or is it possible to do all with python scripts?
I tried this method: https://dev.to/kkentzo/how-to-encrypt-t ... esp32-4n9k and there is an additional function "nvs_secure_initialize". Do I need this function? Unfortunately this doesnt work in my opinion...

Thank you in advance.

Kind Regards,
Alex

ESP_jakob
Posts: 8
Joined: Mon Jun 01, 2020 6:28 am

Re: encrypt firmware with ESP32

Postby ESP_jakob » Wed Jul 01, 2020 10:07 am

Hi Alex,

NVS encryption, flash encryption and secure boot are different things which partially depend on each other. Let's put secure boot aside and try to only do nvs encryption first.

You first need to enable flash encryption, sometimes also called "generic flash encryption". I recommend using a host-generated key for first trials which allows you to re-flash the app as many times as possible, if the settings are correct. You can find instructions here: https://docs.espressif.com/projects/esp ... erated-key.
Once have done that and verified that the app is encrypted, e.g. by using the flash encryption example , you can proceed to enabling nvs encryption.

You DO NOT mark the nvs partition itself as encrypted, as nvs encryption works differently than the normal flash encryption.
But you do need little key partition which is encrypted with normal flash encryption. This and the other steps to setup and use an encrypted nvs partition are described here: https://docs.espressif.com/projects/esp ... encryption. We don't have an example app for nvs encryption, but you can have a look at the nvs unit tests: https://github.com/espressif/esp-idf/bl ... nvs.c#L346. These unit tests work, I just tested them today. They erase the whole nvs partition before each run, though.

Despite your opinion, you do need to use

Code: Select all

nvs_secure_initialize
instead of the normal initialization functions ;) . Without it you won't have nvs encryption. The rest of the code, even the de-initialization stays the same though.
You also need to compile in the options for generic flash encryption and nvs flash encryption, as described in the document pages.

Only after succeeding with all this to a satisfiable degree, I recommend you can think about secure boot. After enabling secure boot and flash encryption in release mode, your debugging and re-flashing abilities will be very limited!

Let us know how it goes!

All the Best,
Jakob

AlexESP32
Posts: 34
Joined: Thu Oct 03, 2019 9:41 am

Re: encrypt firmware with ESP32

Postby AlexESP32 » Thu Jul 02, 2020 4:58 pm

Hey Jakob!

Thank you very much :)

I think I am on the right way:
I can encrypt my partitions with flash encryption and also I got nvs encryption to work.

But there are some more questions:
1. Maybe it is possilbe to explain in short why nvs cannot be encrypted with flash encryption.
In my opinion the encryption works like that:
Take the key and encrypt bootloader, partition table, all application and all partitions which has the addition "encrypted". What are the problems that nvs cannot be encrypted here?

2. What is the method if I want to re-flash the firmware (also the nvs partition) in release mode?
In my opinion I have to encrypt the firmware / partition !at the host! with the key which I have created and then I flash the encrypted firmware. Am I right? What is the command for this?

3. Why Development Mode is not "secure"? In my opinion the only difference between Development Mode and Release Mode is: At Development Mode I can flash the ESP 4x with plain text. At release I can do this only once. Am I right? In this case Development Mode would be secure too.

4. What is this command for: idf.py encrypted-flash monitor
In my opinion I use this command if a key is burned and the firmware is encrypted and I want to flash a new encrypted firmware.
But if this is true: Why is there no key required to encrypt this new firmware at the host?
And what is the difference to this command: espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x10000 -o build/my-app-encrypted.bin build/my-app.bin
The last command make much more sense in my opinion than this command: idf.py encrypted-flash monitor

Thank you very much :) :)

ESP_jakob
Posts: 8
Joined: Mon Jun 01, 2020 6:28 am

Re: encrypt firmware with ESP32

Postby ESP_jakob » Mon Jul 06, 2020 5:44 am

Hi Alex,

Nice to hear your success!

Regarding your questions:
1: NVS relies on the entry state bitmap and the header for each page which are specially tailored to only write 0 bits (this is the way flash writes work) unless the whole page is erased. Hence, this needs to work on the raw flash.

2: You can also trigger the ESP to generate its own key and then encrypt the firmware with that one so that it is never exposed to outside the hardware. In release mode, the encryption happens on the device, right after flashing. This is named "plaintext flashing" in the corresponding sections of the documentation. You can only do this for a very limited number of times (usually 4 on the ESP32). Please refer to the following document: https://docs.espressif.com/projects/esp ... figuration.

3. Development is not secure because you can still flash a new image, hence change the code on the device and potentially read plaintext flash data with that code. The plaintext flashes are always limited as described above. If you generated and saved the key outside the ESP, then you can do an unlimited amount of "encrypted flashes" in development mode with the correct settings.

4. This is the command to do the "encrypted flash" with the key saved somewhere on the host. At least after the first flash, it will automatically pick up the correct key file but I'm not familiar with the details. If you only want to flash the app (and not the other partitions), you can also use encrypted-app-flash.

Best,
Jakob

AlexESP32
Posts: 34
Joined: Thu Oct 03, 2019 9:41 am

Re: encrypt firmware with ESP32

Postby AlexESP32 » Mon Jul 06, 2020 10:51 am

Thank you jakob ;)

Now I understand 1. & 4.

But I still don't understand the difference between Release and Development in detail...
1. Can I have unlimited amount of "encrypted flashes" in Release Mode?
2. If the "hacker" can re-flash the firmware at Development Mode with his plaintext firmware he is still not able to read the encrypted partition from my firmware, so why is the development firmware unsecure? Maybe I don't understand a small detail :D... Could you explain this again with maybe some small example please?
3. How is it possible to encrypt the firmware at host side so there is no "plaintext flashing and encryption at first boot at esp". This would make the mass production much faster. Otherwise we must always wait till the encryption is finished :)
4. I want to have the same key for all my ESPs so I can decrypt all the firmwares If I want this.
If I store the key in safe environment and the key won't be stolen the "host generated key mode" is secure. Do you agree with this?

Thank you again ;)

AlexESP32
Posts: 34
Joined: Thu Oct 03, 2019 9:41 am

Re: encrypt firmware with ESP32

Postby AlexESP32 » Tue Jul 07, 2020 4:24 am

5. Is it necessary to encrypt the Ota firmeware at host side too or will this happen automatically at 1. Boot in esp (if download of the new firmware finished)? If the encryption at host side is needed: which command is the preferred one?

Thank you 😉

Who is online

Users browsing this forum: Bing [Bot] and 17 guests