Burn Key
The espefuse burn-key
command burns keys to eFuse blocks:
Positional arguments:
block
- Name of key block.Keyfile
. It is a raw binary file. The length of binary key depends on the key purpose option.Key purpose
. The purpose of this key.
It can be list of key blocks and keyfiles and key purposes (like BLOCK_KEY1 file1.bin USER BLOCK_KEY2 file2.bin USER etc.).
Optional arguments:
--no-write-protect
. Disable write-protecting of the key. The key remains writable. The keys use the RS coding scheme that does not support post-write data changes. Forced write can damage RS encoding bits. The write-protecting of keypurposes does not depend on the option, it will be set anyway.--no-read-protect
. Disable read-protecting of the key. The key remains readable software. The key with keypurpose [USER, RESERVED and .._DIGEST] will remain readable anyway, but for the rest keypurposes the read-protection will be defined by this option (Read-protect by default).--force-write-always
. Write the eFuse key even if it looks like it is already been written, or is write protected. Note that this option can’t disable write protection, or clear any bit which has already been set.--show-sensitive-info
. Show data to be burned (may expose sensitive data). Enabled if –debug is used. Use this option to see the byte order of the data being written.
ESP32-C5 supports eFuse key purposes. This means that each eFuse block has a special eFuse field that indicates which key is in the eFuse block. During the burn operation this eFuse key purpose is burned as well with write protection (the --no-write-protect
flag has no effect on this field). The ESP32-C5 chip supports the following key purposes:
USER.
RESERVED.
ECDSA_KEY. It can be ECDSA private keys based on NIST192p or NIST256p curve. The private key is extracted from the given file and written into a eFuse block with write and read protection enabled. This private key shall be used by ECDSA accelerator for the signing purpose.
ECDSA_KEY_P192. ECDSA private keys based on NIST192p curve.
ECDSA_KEY_P256. ECDSA private keys based on NIST256p curve.
ECDSA_KEY_P384. ECDSA private keys based on NIST384p curve. This allows you to write a whole 48-byte key into two blocks with
ECDSA_KEY_P384_H
andECDSA_KEY_P384_L
purposes.ECDSA_KEY_P384_H. Upper 32 bytes of the 48-byte ECDSA_P384 key (last 16 bytes of key + 16 padding bytes).
ECDSA_KEY_P384_L. Lower 32 bytes of the 48-byte ECDSA_P384 key.
XTS_AES_128_KEY. 256 bit flash encryption key.
HMAC_DOWN_ALL.
HMAC_DOWN_JTAG.
HMAC_DOWN_DIGITAL_SIGNATURE.
HMAC_UP.
SECURE_BOOT_DIGEST0. 1 secure boot key.
SECURE_BOOT_DIGEST1. 2 secure boot key.
SECURE_BOOT_DIGEST2. 3 secure boot key.
KM_INIT_KEY. This is a key that is used for the generation of AES/ECDSA keys by the key manager.
ESP32-C5 has the ECDSA accelerator for signature purposes and supports private keys based on the NIST192p or NIST256p curve (some chips support NIST384p). These two commands below can be used to generate such keys (PEM
file). The burn-key
command with the ECDSA_KEY
purpose takes the PEM
file and writes the private key into a eFuse block. The key is written to the block in reverse byte order.
For NIST192p, the private key is 192 bits long, so 8 padding bytes (“0x00”) are added.
For NIST256p, the private key is 256 bits long.
For NIST384p, the private key is 384 bits long, so 16 padding bytes (“0x00”) are added.
> espsecure generate_signing_key -v 2 -s ecdsa192 ecdsa192.pem
ECDSA NIST192p private key in PEM format written to ecdsa192.pem
> espsecure generate_signing_key -v 2 -s ecdsa256 ecdsa256.pem
ECDSA NIST256p private key in PEM format written to ecdsa256.pem
All keys will be burned with write protection if --no-write-protect
is not used.
Only flash encryption key is read protected if --no-read-protect
is not used.
All keys, except flash encryption, will be burned in direct byte order. The encryption key is written in reverse byte order for compatibility with encryption hardware.
Unprotected Keys
By default, when an encryption key block is burned it is also read and write protected.
The --no-read-protect
and --no-write-protect
options will disable this behaviour (you can separately read or write protect the key later).
Note
Leaving a key unprotected may compromise its use as a security feature.
espefuse burn-key secure_boot_v1 secure_boot_key_v1.bin
Force Writing a Key
Normally, a key will only be burned if the eFuse block has not been previously written to. The --force-write-always
option can be used to ignore this and try to burn the key anyhow.
Note that this option is still limited by the eFuse hardware - hardware does not allow any eFuse bits to be cleared 1->0, and can not write anything to write protected eFuse blocks.
Usage
> espefuse -c esp32c2 BLOCK_KEY0 secure_images/ecdsa384_secure_boot_signing_key.pem ECDSA_KEY_P384 --no-read-protect --show-sensitive-info
=== Run "burn-key" command ===
Burn keys to blocks:
- BLOCK_KEY0 -> [0e d2 8e c6 86 f0 f6 af 50 51 c3 5c 41 2b c7 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]
Reversing byte order for ECDSA_KEY_P384_H hardware peripheral...
'KEY_PURPOSE_0': 'USER' -> 'ECDSA_KEY_P384_H'.
Disabling write to 'KEY_PURPOSE_0'...
Disabling write to key block...
- BLOCK_KEY1 -> [65 ca a4 5b 5f 67 5c fe 34 89 f3 4a 57 d1 5a 41 d6 1c 7d ea 7a 3f cd 34 79 f2 94 c2 ad cb 94 7d]
Reversing byte order for ECDSA_KEY_P384_L hardware peripheral...
'KEY_PURPOSE_1': 'USER' -> 'ECDSA_KEY_P384_L'.
Disabling write to 'KEY_PURPOSE_1'...
Disabling write to key block...
Keys will remain readable (due to --no-read-protect).
Check all blocks for burn...
idx, BLOCK_NAME, Conclusion
[00] BLOCK0 is empty, will burn the new value
[04] BLOCK_KEY0 is empty, will burn the new value
[05] BLOCK_KEY1 is empty, will burn the new value
.
This is an irreversible operation!
Type 'BURN' (all capitals) to continue.
BURN
BURN BLOCK5 - OK (write block == read block)
BURN BLOCK4 - OK (write block == read block)
BURN BLOCK0 - OK (write block == read block)
Reading updated eFuses...
Successful.
Note
The flags --no-read-protect
and --show-sensitive-info
in this command are used for demonstration purposes only, to show the key byte order. The ECDSA_KEY keys is always written in reverse byte order. The 48 bytes of the key are extracted from the provided PEM file, and 16 padding bytes are added to form a total of 64 bytes for two eFuse blocks. Due to the required reverse byte order, the last 16 bytes of the key plus 16 padding bytes are written to BLOCK_KEY0 with the key purpose ECDSA_KEY_P384_H
, and the remaining 32 bytes are written to the next available eFuse block (here, BLOCK_KEY1) with the key purpose ECDSA_KEY_P384_L
.