Can I use esp_flash_read to get a secret, unique identification or encryption key?
Posted: Sun Feb 06, 2022 5:09 am
How to get a secret, unique key for ESP32 chip (when flash encryption is enabled)?
A unique, secret AES key is already generated on every chip and saved in BLK1, but we have no access to it.
Can I use esp_flash_read(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, ...) to get a derived key?
I see this post
https://www.esp32.com/viewtopic.php?t=2671
"
The closest you can get is the approach used in Mongoose, where they derive the encryption key from flash encryption key by reading a block of flash filled with 0xff, and then use that key with the AES hardware
"
This code for esp32_fs_crypt_init is here:
https://github.com/mongoose-os-libs/vfs ... fs_crypt.c
but I do not like it: it performs read of entire flash looking for FFs, also FFs repeated 32 times is a big mistake.
Another similar option is to use nvs_flash_read_security_cfg/nvs_flash_generate_keys, which does this:
fills a buffer with constants, writes this buffer with esp_partition_write_raw and then reads with esp_partition_read.
But I do not want to write anything anywhere.
It appears that if I simply call:
esp_flash_read_encrypted(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, key_buffer_encr, sizeof(key_buffer_encr));
then I get first raw, unencrypted, bytes of the bootloader (CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000):
e90302306c070840 ee00000000000300 0000000000000001 3000ff3f202c0000
But if I call:
esp_flash_read(NULL, key_buffer_raw, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, sizeof(key_buffer_raw));
Then I get the same thing encrypted:
d6d9a2f8b05352d8 fafcbc3720493445 22a08b76f82f0ead fdfb6e59dbd92a12
which is what I want: a secret, unique key for my chip.
This sounds suspiciously simple - it is much simpler than nvs_flash_generate_keys or esp32_fs_crypt_init,
but does, essentially, the same thing: retrieves an encrypted version of a constant string.
Am I missing something? Is there a flaw with my simple approach?
Thank you
A unique, secret AES key is already generated on every chip and saved in BLK1, but we have no access to it.
Can I use esp_flash_read(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, ...) to get a derived key?
I see this post
https://www.esp32.com/viewtopic.php?t=2671
"
The closest you can get is the approach used in Mongoose, where they derive the encryption key from flash encryption key by reading a block of flash filled with 0xff, and then use that key with the AES hardware
"
This code for esp32_fs_crypt_init is here:
https://github.com/mongoose-os-libs/vfs ... fs_crypt.c
but I do not like it: it performs read of entire flash looking for FFs, also FFs repeated 32 times is a big mistake.
Another similar option is to use nvs_flash_read_security_cfg/nvs_flash_generate_keys, which does this:
fills a buffer with constants, writes this buffer with esp_partition_write_raw and then reads with esp_partition_read.
But I do not want to write anything anywhere.
It appears that if I simply call:
esp_flash_read_encrypted(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, key_buffer_encr, sizeof(key_buffer_encr));
then I get first raw, unencrypted, bytes of the bootloader (CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000):
e90302306c070840 ee00000000000300 0000000000000001 3000ff3f202c0000
But if I call:
esp_flash_read(NULL, key_buffer_raw, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, sizeof(key_buffer_raw));
Then I get the same thing encrypted:
d6d9a2f8b05352d8 fafcbc3720493445 22a08b76f82f0ead fdfb6e59dbd92a12
which is what I want: a secret, unique key for my chip.
This sounds suspiciously simple - it is much simpler than nvs_flash_generate_keys or esp32_fs_crypt_init,
but does, essentially, the same thing: retrieves an encrypted version of a constant string.
Am I missing something? Is there a flaw with my simple approach?
Thank you