Esp32 nvs encryption issue

esp32builder
Posts: 2
Joined: Sat Jan 27, 2024 12:55 pm

Esp32 nvs encryption issue

Postby esp32builder » Sat Jan 27, 2024 1:16 pm

I have an issue with nvs encryption.

The target is unicore esp32 (ESP32-U4WDH revision 3).

My project has the following partition structure:

# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, ,0x140000,
spiffs, data, spiffs, ,0x160000,
nvs_key, data, nvs_keys, , 0x1000, encrypted

The actual fimware is generated in PlatformiO IDE and the transferred to ESP-IDF and flashed to esp32. The bootloader has encryption enabled (as well, nvs-encryption enabled) in development mode. UART download/encrypt/decrypt not disabled. The encryption key generated and burned to eFuses. The flash erased completely before flashing the content. The bootloader, partition table and firmware flashed in encrypted form.

The flash encryption works fine, the app is encrypted.

I have included following lines in my code:

----------
esp_err_t ret;
Serial.begin(115200);

nvs_flash_erase(); // erasing nvs at every startup
ret = nvs_flash_init();
Serial.println("NVS Init");
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
Serial.println("NVS erased and initialized");
}
if (ret != ESP_OK) {
Serial.printf("NVS init failed error code: %d\n", ret);
} else {
Serial.println("NVS initialized.\n");
}
ESP_ERROR_CHECK(ret);
-----------

The nvs partition is still saving the wifi credentials as plain text. What am I doing wrong / some additional steps missing?

esp32builder
Posts: 2
Joined: Sat Jan 27, 2024 12:55 pm

Re: Esp32 nvs encryption issue

Postby esp32builder » Sun Jan 28, 2024 11:02 am

Reply by myself:

Seems that I should use nvs_flash_secure_init() instead of nvs_flash_init() in order to initialize nvs in encrypted mode. However, the issue is that PlatformiO IDE doesn't support build flag CONFIG_NVS_ENCRYPTION and thus, the nvs_flash_secure_init() will just cause an error message.

My primary purpose to encrypt nvs is to hide the SSID credentials. The second attempt to do this was to remove sta.ssid, sta.pswd, and sta.apinfo keys from namespace 'nvs.net80211' after Wifi.begin. However, this was (of course) doomed as there is wear leveling and the actual keys are not really removed, but instead, there will be several places in flash dump, where you can see the crendials as plain text.

The next attempt was to erase the whole nvs after wifi is connected. This works well, but can't be used in production as the flash write cycles will start accumulating rapidly. As well, the big boys may have some tools available to get the erased information visible.

The solution I found was the use of WiFi.persistent(false) or esp_wifi_set_storage(WIFI_STORAGE_RAM) before Wifi.begin. It is still not quite clear to me, which one is really doing the trick as first I tried both separately and I think there was no effect at all (or maybe the place in the code was wrong...). However, both together just before calling Wifi.begin works. Need to double check, which one (or both?) is working.

Hope this helps if someone is having similar issues.

Who is online

Users browsing this forum: Baidu [Spider] and 80 guests