Why doesn't NVS Encryption use the standard Flash Encryption mechanism?
Posted: Wed Jul 06, 2022 5:34 pm
The NVS documentation says that "NVS is not directly compatible with the ESP32 flash encryption system". Instead the user is required to have a separate encrypted nvs_key partition to store another set of custom keys used only for nvs.
The page header (32 bytes) and the Entry state bitmap (32 bytes) are stored unencrypted while all the entries (32 bytes each) are stored encrypted using AES-XTS with the custom keys. Looking at nvs_encrypted_partition.cpp in the esp-idf, I see that the encryption/decryption is done manually using mbedtls_aes_crypt_xts.
What I don't understand is why the entries are encrypted in a custom way, instead of just using the standard flash api for this? When flash encryption is enabled, the methods esp_partition_write and esp_partition_read can transparently encrypt/decrypt the data using the hardware cache or encryption block and the methods esp_partition_write_raw and esp_partition_read_raw could be used for the unencrypted header that must be stored in plaintext. That should be much more efficient than manually encrypting/decrypting the data, as well as avoiding to have to create an nvs_key partition, right? Can anyone explain why that more obvious approach is not used?
The page header (32 bytes) and the Entry state bitmap (32 bytes) are stored unencrypted while all the entries (32 bytes each) are stored encrypted using AES-XTS with the custom keys. Looking at nvs_encrypted_partition.cpp in the esp-idf, I see that the encryption/decryption is done manually using mbedtls_aes_crypt_xts.
What I don't understand is why the entries are encrypted in a custom way, instead of just using the standard flash api for this? When flash encryption is enabled, the methods esp_partition_write and esp_partition_read can transparently encrypt/decrypt the data using the hardware cache or encryption block and the methods esp_partition_write_raw and esp_partition_read_raw could be used for the unencrypted header that must be stored in plaintext. That should be much more efficient than manually encrypting/decrypting the data, as well as avoiding to have to create an nvs_key partition, right? Can anyone explain why that more obvious approach is not used?