DEV Community

How to encrypt the NVS volume on the ESP32

Kyriakos Kentzoglanakis on April 18, 2020

There has been a lot of discussion around embedded device security during the last few years especially after well-publicized DDoS incidents involv...
Collapse
 
pollock94 profile image
Palok Biswas

I have a separate NVS partition for device credentials. Everything worked as usual after following your instructions, however, nvs_open_from_partition() failed to open the partition. I initialized the partition using nvs_flash_secure_init_partition() and it gives me an error of namespace not existing. Any idea why that is happening?

Collapse
 
pollock94 profile image
Palok Biswas

nvs_flash_secure_init_partition is working now but nvs_get_str() is unable to find the key value that was in my nvs partition. Works fine without the encryption

Collapse
 
kkentzo profile image
Kyriakos Kentzoglanakis

Are you still facing a problem? I am using nvs_open before calling nvs_get_str which returns the stored string successfully (if that helps).

Collapse
 
alex_c0de profile image
Alexandre Beaulieu

Thank you for this article. It was very helpful. Just a note that when developing with the encrypted flash in development mode, the NVS key must be written with the --encrypt flag otherwise nvs_flash_read_security_cfg will return 0x1117 (ESP_ERR_NVS_CORRUPT_KEY_PART).

In the example, this would be:
esptool.py -p PORT --before default_reset --after no_reset write_flash --encrypt 0x320000 nvs_keys.bin

Collapse
 
achrafboussaada profile image
Achraf Boussaada

So I tried to create a custom nvs partition and write data to it and flash it to the chip and then programmatically initialize it and read data from it. That worked fine.
Now with the esptool.py I tried to encrypt the partition generate its keys and flash it to the chip. Following the documentation (docs.espressif.com/projects/esp-id...) and your post I tried to read data from the encrypted partition. The problem I'm having is that the data I flashed seems not be found. I used nvs_get_stats() to get Infos about the entries of the new partition but I always get entries count is 1. This didn't happen before when I tried it with the unencrypted partition. Also, intialilizing and openening the encrypted partition without nvs_flash_secure_init_partition() gives me the same result and doesn't through an error about encryption keys needed or something.

Collapse
 
achrafboussaada profile image
Achraf Boussaada

After further inverstigation nvs_flash_read_security_cfg() is giving me ESP_ERR_NVS_CORRUPT_KEY_PART

Collapse
 
achrafboussaada profile image
Achraf Boussaada

when you're flashing the nvs_keys.bin you gave 0x320000 as a location address. How did you determine that?

Collapse
 
kkentzo profile image
Kyriakos Kentzoglanakis

The address of a particular partition can be discovered either by inspecting the esp32 serial output (where the partitions are printed out) or by applying the esp-idf's gen_esp32part.py utility on the project's partition image (e.g. gen_esp32part.py build/partition_table/partition-table.bin)

Collapse
 
achrafboussaada profile image
Achraf Boussaada

Thanks for the reply. I just realised that you need to create another partition to store the keys, and the partition should be flaged as encrypted. I'm sorry if this seems obvious, but I'm new to this, is there no security risk doing this?

Thread Thread
 
kkentzo profile image
Kyriakos Kentzoglanakis

The partition that stores the encryption keys for the nvs partition is itself encrypted by the device (handled by the bootloader -- more info here. The reason for the existence of the keys partition is that the esp32 does not (yet?) handle the encryption of an nvs partition transparently, so we have to do it ourselves.

Thread Thread
 
achrafboussaada profile image
Achraf Boussaada

Thanks. Final question about the keys partition. According to the documentation the partition needs to have a encrypted flag. Did you add it manually when creating the partition from the CSV file?

Collapse
 
marcarleto profile image
MarcioCarleto

I've deleted the lines "cert,file,string,./path/to/certificate.pem.crt" and "pvkey,file,string,./path/to/private.pem.key" because I don´t have the .crt or .key in my application, it generated the encrypted_nvs.bin and nvs_keys.bin files but I don´t know what is the encrypted_nvs.bin address of my application I should use (yours is 0xa000 right?). I've attached my partition-table offsets when I build my project, can you please help on this?
Image description

Collapse
 
marcarleto profile image
MarcioCarleto

I've deleted the lines "cert,file,string,./path/to/certificate.pem.crt" and "pvkey,file,string,./path/to/private.pem.key" because I don´t have the .crt or .key in my application, it generated the encrypted_nvs.bin and nvs_keys.bin files but I don´t know what is the encrypted_nvs.bin address of my application I should use (yours is 0xa000 right?). I've attached my partition-table offsets when I build my project, can you please help on this?

Image description

Collapse
 
mocasrhey profile image
mocasrhey

i flashed the partition and it executes nvs_open with success but nvs_get_str returns ESP_ERR_NVS_NOT_FOUND, do you have any idea of what might be the problem?

Collapse
 
kkentzo profile image
Kyriakos Kentzoglanakis

My guess would be that the key does not exist. Did you try to write a key/value pair to nvs first before you attempt to retrieve the key's value?