1.. _burn-key-cmd:
2
3Burn Key
4========
5
6The ``espefuse.py burn_key`` command burns keys to eFuse blocks:
7
8.. list::
9
10    :esp32: - `Secure Boot V1 <https://docs.espressif.com/projects/esp-idf/en/latest/{IDF_TARGET_PATH_NAME}/security/secure-boot-v1.html>`_
11    - `Secure Boot V2 <https://docs.espressif.com/projects/esp-idf/en/latest/{IDF_TARGET_PATH_NAME}/security/secure-boot-v2.html>`_
12    - `Flash Encryption <https://docs.espressif.com/projects/esp-idf/en/latest/{IDF_TARGET_PATH_NAME}/security/flash-encryption.html>`_
13    - etc.
14
15Positional arguments:
16
17.. list::
18
19    - ``block`` - Name of key block.
20    :esp32: - ``Keyfile``. It is a raw binary file. It must contain 256 bits of binary key if the coding scheme is ``None`` and 128 bits if ``3/4``.
21    :not esp32 and not esp32h2: - ``Keyfile``. It is a raw binary file. The length of binary key depends on the key purpose option.
22    :esp32h2: - ``Keyfile``. It is a raw binary file. The length of binary key depends on the key purpose option. For the ``ECDSA_KEY`` purpose use ``PEM`` file.
23    :not esp32: - ``Key purpose``. The purpose of this key.
24
25.. only:: esp32
26
27    It can be list of key blocks and keyfiles (like BLOCK1 file1.bin BLOCK2 file2.bin etc.).
28
29.. only:: not esp32
30
31    It can be list of key blocks and keyfiles and key purposes (like BLOCK_KEY1 file1.bin USER BLOCK_KEY2 file2.bin USER etc.).
32
33Optional arguments:
34
35.. list::
36
37    :esp32: - ``--no-protect-key``. Disable default read and write protecting of the key. If this option is not set, once the key is flashed it can not be read back.
38    :not esp32: - ``--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.
39    :not esp32: - ``--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).
40    - ``--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.
41    - ``--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.
42
43.. only:: esp32
44
45    {IDF_TARGET_NAME} supports keys:
46
47    * Secure boot key. Use ``secure_boot_v1`` or ``secure_boot_v2`` as block name. The key is placed in BLOCK2.
48    * Flash encryption key. Use ``flash_encryption`` as block name. The key is placed in BLOCK1.
49
50    Keys for ``flash_encryption`` and ``secure_boot_v1`` will be burned as read and write protected. The hardware will still have access to them.  These keys are burned in reversed byte order.
51
52    Key for ``secure_boot_v2`` will be burned only as write protected. The key must be readable because the software need access to it.
53
54    .. warning::
55
56        Do not use the names ``BLOCK1`` and ``BLOCK2`` to burn flash encryption and secure boot v2 keys because byte order will be incorrect and read protection will not meet security requirements.
57
58.. only:: not esp32 and not esp32c2
59
60    {IDF_TARGET_NAME} 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 {IDF_TARGET_NAME} chip supports the following key purposes:
61
62    .. list::
63
64        - USER.
65        - RESERVED.
66        :esp32s2 or esp32s3: - XTS_AES_256_KEY_1. The first 256 bits of 512bit flash encryption key.
67        :esp32s2 or esp32s3: - XTS_AES_256_KEY_2. The second 256 bits of 512bit flash encryption key.
68        :esp32h2: - 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.
69        - XTS_AES_128_KEY. 256 bit flash encryption key.
70        - HMAC_DOWN_ALL.
71        - HMAC_DOWN_JTAG.
72        - HMAC_DOWN_DIGITAL_SIGNATURE.
73        - HMAC_UP.
74        - SECURE_BOOT_DIGEST0. 1 secure boot key.
75        - SECURE_BOOT_DIGEST1. 2 secure boot key.
76        - SECURE_BOOT_DIGEST2. 3 secure boot key.
77        :esp32s2 or esp32s3: - XTS_AES_256_KEY. This is a virtual key purpose for flash encryption key. This allows you to write a whole 512-bit key into two blocks with ``XTS_AES_256_KEY_1`` and ``XTS_AES_256_KEY_2`` purposes without splitting the key file.
78
79.. only:: esp32h2
80
81    {IDF_TARGET_NAME} has the ECDSA accelerator for signature purposes and supports private keys based on the NIST192p or NIST256p curve. 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.
82
83    For NIST192p, the private key is 192 bits long, so 8 padding bytes ("0x00") are added.
84
85    .. code-block:: none
86
87        > espsecure.py generate_signing_key -v 2 -s ecdsa192 ecdsa192.pem
88        ECDSA NIST192p private key in PEM format written to ecdsa192.pem
89
90    .. code-block:: none
91
92        > espsecure.py generate_signing_key -v 2 -s ecdsa256 ecdsa256.pem
93        ECDSA NIST256p private key in PEM format written to ecdsa256.pem
94
95.. only:: esp32c2
96
97    {IDF_TARGET_NAME} has only one eFuse key block (256 bits long). It is block #3 - ``BLOCK_KEY0``. This block can have user, flash encryption, secure boot keys. This chip does not have any eFuse key purpose fields, but we use the key purpose option to distinguish between such keys. The key purpose option determines protection and byte order for key.
98
99    .. list::
100
101        - USER
102        - XTS_AES_128_KEY. 256 bits flash encryption key. The secure boot key can not be used with this option. In addition, eFuse ``XTS_KEY_LENGTH_256`` is set to 1, which means that the flash encryption key is 256 bits long.
103        - XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS. 128 bits flash encryption key. The 128 bits of this key will be burned to the low part of the eFuse block. These bits will be read protected.
104        - SECURE_BOOT_DIGEST. Secure boot key. The first 128 bits of key will be burned to the high part of the eFuse block.
105
106    {IDF_TARGET_NAME} can have in eFuse block the following combination of keys:
107
108    1. Both, Flash encryption (low 128 bits of eFuse block) and Secure boot key (high 128 bits of eFuse block).
109    2. only Flash encryption (low 128 bits of eFuse block), rest part of eFuse block is not possible to use in future.
110    3. only Flash encryption key (256 bits long), whole eFuse key block.
111    4. only Secure boot key (high 128 bits of eFuse block).
112    5. no keys, used for user purposes. Chip does not have security features.
113
114.. only:: not esp32
115
116    All keys will be burned with write protection if ``--no-write-protect`` is not used.
117
118    Only flash encryption key is read protected if ``--no-read-protect`` is not used.
119
120    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.
121
122.. only:: esp32
123
124    Key Coding Scheme
125    ^^^^^^^^^^^^^^^^^
126
127    When the ``None`` coding scheme is in use, keys are 256-bits (32 bytes) long. When 3/4 Coding Scheme is in use (``CODING_SCHEME`` eFuse has value 1 not 0), keys are 192-bits (24 bytes) long and an additional 64 bits of error correction data are also written.
128    espefuse v2.6 or newer supports the 3/4 Coding Scheme. The key file must be the appropriate length for the coding scheme currently in use.
129
130Unprotected Keys
131^^^^^^^^^^^^^^^^
132
133By default, when an encryption key block is burned it is also read and write protected.
134
135.. only:: esp32
136
137    The ``--no-protect-key`` option will disable this behaviour (you can separately read or write protect the key later).
138
139.. only:: not esp32
140
141    The ``--no-read-protect`` and ``--no-write-protect`` options will disable this behaviour (you can separately read or write protect the key later).
142
143.. note::
144
145    Leaving a key unprotected may compromise its use as a security feature.
146
147.. code-block:: none
148
149    espefuse.py burn_key secure_boot_v1 secure_boot_key_v1.bin
150
151.. only:: esp32
152
153    Note that the hardware flash encryption and secure boot v1 features require the key to be written to the eFuse block in reversed byte order, compared to the order used by the AES algorithm on the host. Using corresponding block name, the tool automatically reverses the bytes when writing. For this reason, an unprotected key will read back in the reverse order.
154
155Force Writing a Key
156^^^^^^^^^^^^^^^^^^^
157
158Normally, 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.
159
160Note 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.
161
162Usage
163-----
164
165.. only:: esp32
166
167    .. code-block:: none
168
169        > espefuse.py burn_key flash_encryption  256bit_fe_key.bin
170
171        === Run "burn_key" command ===
172        Sensitive data will be hidden (see --show-sensitive-info)
173        Burn keys to blocks:
174        - BLOCK1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
175                Reversing the byte order
176                Disabling read to key block
177                Disabling write to key block
178
179        Burn keys in efuse blocks.
180        The key block will be read and write protected
181
182        Check all blocks for burn...
183        idx, BLOCK_NAME,          Conclusion
184        [00] BLOCK0               is empty, will burn the new value
185        [01] BLOCK1               is empty, will burn the new value
186        .
187        This is an irreversible operation!
188        Type 'BURN' (all capitals) to continue.
189        BURN
190        BURN BLOCK1  - OK (write block == read block)
191        BURN BLOCK0  - OK (write block == read block)
192        Reading updated efuses...
193        Successful
194
195    .. code-block:: none
196
197        > espefuse.py summary
198        ...
199        BLOCK1 (BLOCK1):                                   Flash encryption key
200        = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/-
201
202    Byte order for flash encryption key is reversed. Content of flash encryption key file ("256bit_fe_key.bin"):
203
204    .. code-block:: none
205
206        0001 0203 0405 0607 0809 0a0b 0c0d 0e0f  1011 1213 1415 1617 1819 1a1b 1c1d 1e1f
207
208    When the ``no protection`` option is used then you can see the burned key:
209
210    .. code-block:: none
211
212        > espefuse.py burn_key flash_encryption  256bit_fe_key.bin --no-protect-key
213
214        === Run "burn_key" command ===
215        Sensitive data will be hidden (see --show-sensitive-info)
216        Burn keys to blocks:
217        - BLOCK1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
218                Reversing the byte order
219
220        Key is left unprotected as per --no-protect-key argument.
221        Burn keys in efuse blocks.
222        The key block will left readable and writeable (due to --no-protect-key)
223
224        Check all blocks for burn...
225        idx, BLOCK_NAME,          Conclusion
226        [01] BLOCK1               is empty, will burn the new value
227        .
228        This is an irreversible operation!
229        Type 'BURN' (all capitals) to continue.
230        BURN
231        BURN BLOCK1  - OK (write block == read block)
232        Reading updated efuses...
233        Successful
234
235    .. code-block:: none
236
237        > espefuse.py summary
238        ...
239        BLOCK1 (BLOCK1):                                   Flash encryption key
240        = 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 R/W
241
242.. only:: esp32s2 or esp32s3
243
244    Burning XTS_AES_256_KEY:
245
246    The first 256 bit of the key goes to given BLOCK (here it is ``BLOCK_KEY0``) with key purpose = ``XTS_AES_256_KEY_1``. The last 256 bit of the key will be burned to the first free key block after BLOCK (here it is ``BLOCK_KEY1``) and set key purpose to ``XTS_AES_256_KEY_2`` for this block.
247
248    This example uses ``--no-read-protect`` to expose the byte order written into eFuse blocks.
249
250    Content of flash encryption key file (``512bits_0.bin``):
251
252    .. code-block:: none
253
254        0001 0203 0405 0607 0809 0a0b 0c0d 0e0f  1011 1213 1415 1617 1819 1a1b 1c1d 1e1f
255        2021 2223 2425 2627 2829 2a2b 2c2d 2e2f  3031 3233 3435 3637 3839 3a3b 3c3d 3e3f
256
257    .. code-block:: none
258
259        > espefuse.py burn_key BLOCK_KEY0 ~/esp/tests/efuse/512bits_0.bin  XTS_AES_256_KEY --no-read-protect
260
261        === Run "burn_key" command ===
262        Sensitive data will be hidden (see --show-sensitive-info)
263        Burn keys to blocks:
264        - BLOCK_KEY0 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
265                Reversing byte order for AES-XTS hardware peripheral
266                'KEY_PURPOSE_0': 'USER' -> 'XTS_AES_256_KEY_1'.
267                Disabling write to 'KEY_PURPOSE_0'.
268                Disabling write to key block
269
270        - BLOCK_KEY1 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
271                Reversing byte order for AES-XTS hardware peripheral
272                'KEY_PURPOSE_1': 'USER' -> 'XTS_AES_256_KEY_2'.
273                Disabling write to 'KEY_PURPOSE_1'.
274                Disabling write to key block
275
276        Keys will remain readable (due to --no-read-protect)
277
278        Check all blocks for burn...
279        idx, BLOCK_NAME,          Conclusion
280        [00] BLOCK0               is empty, will burn the new value
281        [04] BLOCK_KEY0           is empty, will burn the new value
282        [05] BLOCK_KEY1           is empty, will burn the new value
283        .
284        This is an irreversible operation!
285        Type 'BURN' (all capitals) to continue.
286        BURN
287        BURN BLOCK5  - OK (write block == read block)
288        BURN BLOCK4  - OK (write block == read block)
289        BURN BLOCK0  - OK (write block == read block)
290        Reading updated efuses...
291        Successful
292
293        > espefuse.py summary
294        ...
295        KEY_PURPOSE_0 (BLOCK0)                             KEY0 purpose                                       = XTS_AES_256_KEY_1 R/- (0x2)
296        KEY_PURPOSE_1 (BLOCK0)                             KEY1 purpose                                       = XTS_AES_256_KEY_2 R/- (0x3)
297        ...
298        BLOCK_KEY0 (BLOCK4)
299        Purpose: XTS_AES_256_KEY_1
300        Encryption key0 or user data
301        = 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 R/-
302        BLOCK_KEY1 (BLOCK5)
303        Purpose: XTS_AES_256_KEY_2
304        Encryption key1 or user data
305        = 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 R/-
306
307.. only:: esp32c2
308
309    .. code-block:: none
310
311        > espefuse.py -c esp32c2  \
312                                burn_key_digest secure_images/ecdsa256_secure_boot_signing_key_v2.pem \
313                                burn_key BLOCK_KEY0 images/efuse/128bit_key.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS
314
315        === Run "burn_key_digest" command ===
316        Sensitive data will be hidden (see --show-sensitive-info)
317        Burn keys to blocks:
318        - BLOCK_KEY0_HI_128 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
319                Disabling write to key block
320
321
322        Batch mode is enabled, the burn will be done at the end of the command.
323
324        === Run "burn_key" command ===
325        Sensitive data will be hidden (see --show-sensitive-info)
326        Burn keys to blocks:
327        - BLOCK_KEY0_LOW_128 -> [?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??]
328                Reversing byte order for AES-XTS hardware peripheral
329                Disabling read to key block
330                Disabling write to key block
331                The same value for WR_DIS is already burned. Do not change the efuse.
332
333        Batch mode is enabled, the burn will be done at the end of the command.
334
335        Check all blocks for burn...
336        idx, BLOCK_NAME,          Conclusion
337        [00] BLOCK0               is empty, will burn the new value
338        [03] BLOCK_KEY0           is empty, will burn the new value
339        .
340        This is an irreversible operation!
341        Type 'BURN' (all capitals) to continue.
342        BURN
343        BURN BLOCK3  - OK (write block == read block)
344        BURN BLOCK0  - OK (write block == read block)
345        Reading updated efuses...
346