applecrusher wrote: ↑Thu Apr 04, 2019 10:42 pm
The last command just extracts the public key. If you look at both the espressif documentation and the pycom documentation, this just extracts a 64 bit key, which I thought would have been the secure bootloader key, but the secure bootloader key is just a 32 bit key. So how do I create a secure bootloader key?
It's a bit confusing, as hardware secure boot on the ESP32 is a two stage process (
a summary of the full process is here).
The first boot stage is when the ROM loads the bootloader.bin from the flash. This uses a "digest" of the bootloader (stored in flash at offset 0x0) which is generated from a 32 byte (256 bit) secure bootloader key which is stored in efuse and not readable by software. This digest can be generated beforehand ("reflashable" mode) or generated by the device on first boot ("one-time flash" mode).
The second boot stage is when the IDF bootloader verifies the app. This part uses an ECDSA signature appended to the app .bin file. This signature is created using the private key of an Elliptic Curve key pair (secure_boot_signing_key.pem). The IDF bootloader itself contains just the public key data from this EC key pair as 64 bytes of raw binary data (signature_verification_key.bin), which is enough for it to verify the signature. Storing only the public key means that even if an attacker gets a copy of bootloader.bin, they can't generate any new signatures.
Going back to the first boot stage, in "one-time flash" mode the key stored in efuse is generated from the hardware random number generator and no copy is ever available elsewhere. This means the IDF bootloader can only be flashed once (but the IDF bootloader can still boot any app which is signed correctly).
In "reflashable" mode, you keep a copy of the key which is in efuse so it's possible to generate new secure boot digests, in order to update the bootloader. One option here would be to generate a random 32 byte key and burn this to efuse. However then you would need to keep two secrets - secure_boot_signing_key.pem and this 32 byte random key. To reduce the number of secret files, the ESP-IDF build system has a step where it takes the SHA-256 digest of secure_boot_signing_key.pem and this can be used as the secure boot key in efuse. This means you only need to keep one file secret - secure_boot_signing_key.pem - for both things.
In IDF build system, this step is done automatically. If you're using PyCom's tools then it might not be automatic, but you can do it as follows:
Code: Select all
espsecure.py digest_private_key --keyfile secure_boot_signing_key.pem secure-bootloader-key.bin
Then burn secure-booloader-key key to efuse:
Code: Select all
espefuse.py burn_key secure_boot secure-bootloader-key.bin
Then, if secure boot is already enabled and you want to reflash bootloader.bin:
Code: Select all
espsecure.py digest_secure_bootloader --keyfile secure-bootloader-key.bin --output bootloader-digest.bin bootloader.bin
esptool.py write_flash 0x0 bootloader-digest.bin
(See also
here)
If using the ESP-IDF build system then all of these steps are built-in, so the build system will produce secure-bootloader-key.bin file, print the correct burn_key command to run, generate a bootloader digest, etc.