host-based-security-workflows.rst 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. Host-Based Security Workflows
  2. =============================
  3. {IDF_TARGET_CRYPT_CNT:default="SPI_BOOT_CRYPT_CNT",esp32="FLASH_CRYPT_CNT"}
  4. {IDF_TARGET_CRYPT_CNT_MAX_VAL:default="7",esp32="127"}
  5. {IDF_TARGET_SBV2_DEFAULT_SCHEME:default="RSA", esp32c2="ECDSA (V2)"}
  6. Introduction
  7. ------------
  8. It is recommended to have an uninterrupted power supply while enabling security features on ESP32 SoCs. Power failures during the secure manufacturing process could cause issues that are hard to debug and, in some cases, may cause permanent boot-up failures.
  9. This guide highlights an approach where security features are enabled with the assistance of an external host machine. Security workflows are broken down into various stages and key material is generated on the host machine; thus, allowing greater recovery chances in case of power or other failures. It also offers better timings for secure manufacturing, e.g., in the case of encryption of firmware on the host machine vs. on the device.
  10. Goals
  11. -----
  12. #. Simplify the traditional workflow with stepwise instructions.
  13. #. Design a more flexible workflow as compared to the traditional firmware-based workflow.
  14. #. Improve reliability by dividing the workflow into small operations.
  15. #. Eliminate dependency on :ref:`second-stage-bootloader` (firmware bootloader).
  16. Pre-requisite
  17. -------------
  18. * ``esptool``: Please make sure the ``esptool`` has been installed. It can be installed by running:
  19. .. code:: bash
  20. pip install esptool
  21. Scope
  22. -----
  23. * :ref:`enable-flash-encryption-and-secure-boot-v2-externally`
  24. * :ref:`enable-flash-encryption-externally`
  25. * :ref:`enable-secure-boot-v2-externally`
  26. Security Workflows
  27. ------------------
  28. .. _enable-flash-encryption-and-secure-boot-v2-externally:
  29. Enable Flash Encryption and Secure Boot V2 Externally
  30. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  31. .. important::
  32. It is recommended to enable both Flash Encryption and Secure Boot V2 for a production use case.
  33. When enabling the Flash Encryption and Secure Boot V2 externally we need to enable them in the following order:
  34. #. Enable the Flash Encryption feature by following the steps listed in :ref:`enable-flash-encryption-externally`.
  35. #. Enable the Secure Boot V2 feature by following the steps listed in :ref:`enable-secure-boot-v2-externally`.
  36. The reason for this order is as follows:
  37. To enable the Secure Boot (SB) V2, it is necessary to keep the SB V2 key readable. To protect the key's readability, the write protection for RD_DIS (ESP_EFUSE_WR_DIS_RD_DIS) is applied. However, this action poses a challenge when attempting to enable Flash Encryption, as the Flash Encryption (FE) key needs to remain unreadable. This conflict arises because the RD_DIS is already write-protected, making it impossible to read protect the FE key.
  38. .. _enable-flash-encryption-externally:
  39. Enable Flash Encryption Externally
  40. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  41. In this case, all the eFuses related to flash encryption are written with help of the espefuse tool. More details about flash encryption can be found in the :doc:`Flash Encryption Guide </security/flash-encryption>`
  42. 1. Ensure that you have an {IDF_TARGET_NAME} device with default flash encryption eFuse settings as shown in :ref:`flash-encryption-efuse`.
  43. See how to check :ref:`flash-encryption-status`.
  44. In this case, the flash on the chip must be erased and flash encryption must not be enabled. The chip can be erased by running:
  45. .. code:: bash
  46. esptool.py --port PORT erase_flash
  47. 2. Generate a flash encryption key.
  48. A random flash encryption key can be generated by running:
  49. .. only:: not SOC_FLASH_ENCRYPTION_XTS_AES
  50. .. code-block:: bash
  51. espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
  52. .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
  53. If :ref:`Size of generated AES-XTS key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` is AES-128 (256-bit key):
  54. .. code-block:: bash
  55. espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
  56. else if :ref:`Size of generated AES-XTS key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` is AES-256 (512-bit key):
  57. .. code-block:: bash
  58. espsecure.py generate_flash_encryption_key --keylen 512 my_flash_encryption_key.bin
  59. .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
  60. .. code-block:: bash
  61. espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
  62. .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
  63. If :ref:`Size of generated AES-XTS key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` is AES-128 (256-bit key):
  64. .. code-block:: bash
  65. espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin
  66. else if :ref:`Size of generated AES-XTS key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>` is AES-128 key derived from 128 bits (SHA256(128 bits)):
  67. .. code-block:: bash
  68. espsecure.py generate_flash_encryption_key --keylen 128 my_flash_encryption_key.bin
  69. 3. Burn the flash encryption key into eFuse.
  70. This action **cannot be reverted**. It can be done by running:
  71. .. only:: not SOC_FLASH_ENCRYPTION_XTS_AES
  72. .. code-block:: bash
  73. espefuse.py --port PORT burn_key flash_encryption my_flash_encryption_key.bin
  74. .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_256
  75. .. code-block:: bash
  76. espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin KEYPURPOSE
  77. where ``BLOCK`` is a free keyblock between ``BLOCK_KEY0`` and ``BLOCK_KEY5``. And ``KEYPURPOSE`` is either ``XTS_AES_256_KEY_1``, ``XTS_AES_256_KEY_2``, ``XTS_AES_128_KEY``. See `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_ for a description of the key purposes.
  78. For AES-128 (256-bit key) - ``XTS_AES_128_KEY``:
  79. .. code-block:: bash
  80. espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY
  81. For AES-256 (512-bit key) - ``XTS_AES_256_KEY_1`` and ``XTS_AES_256_KEY_2``. ``espefuse.py`` supports burning both these two key purposes together with a 512-bit key to two separate key blocks via the virtual key purpose ``XTS_AES_256_KEY``. When this is used ``espefuse.py`` will burn the first 256 bits of the key to the specified ``BLOCK`` and burn the corresponding block key purpose to ``XTS_AES_256_KEY_1``. The last 256 bits of the key will be burned to the first free key block after ``BLOCK`` and the corresponding block key purpose to ``XTS_AES_256_KEY_2``
  82. .. code-block:: bash
  83. espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_256_KEY
  84. If you wish to specify exactly which two blocks are used then it is possible to divide the key into two 256-bit keys, and manually burn each half with ``XTS_AES_256_KEY_1`` and ``XTS_AES_256_KEY_2`` as key purposes:
  85. .. code-block:: bash
  86. split -b 32 my_flash_encryption_key.bin my_flash_encryption_key.bin
  87. espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin.aa XTS_AES_256_KEY_1
  88. espefuse.py --port PORT burn_key BLOCK+1 my_flash_encryption_key.bin.ab XTS_AES_256_KEY_2
  89. .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and not SOC_FLASH_ENCRYPTION_XTS_AES_256 and not SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
  90. .. code-block:: bash
  91. espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY
  92. where ``BLOCK`` is a free keyblock between ``BLOCK_KEY0`` and ``BLOCK_KEY5``.
  93. .. only:: SOC_FLASH_ENCRYPTION_XTS_AES_128 and SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK
  94. For AES-128 (256-bit key) - ``XTS_AES_128_KEY`` (the ``XTS_KEY_LENGTH_256`` eFuse will be burn to 1):
  95. .. code-block:: bash
  96. espefuse.py --port PORT burn_key BLOCK_KEY0 flash_encryption_key256.bin XTS_AES_128_KEY
  97. For AES-128 key derived from 128 bits (SHA256(128 bits)) - ``XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS``. The FE key will be written in the lower part of eFuse BLOCK_KEY0. The upper 128 bits are not used and will remain available for reading by software. Using the special mode of the espefuse tool, shown in the ``For burning both keys together`` section below, the user can write their data to it using any espefuse commands.
  98. .. code-block:: bash
  99. espefuse.py --port PORT burn_key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS
  100. For burning both keys together (Secure Boot and Flash Encryption):
  101. .. code-block:: bash
  102. espefuse.py --port PORT --chip esp32c2 burn_key_digest secure_boot_signing_key.pem \
  103. burn_key BLOCK_KEY0 flash_encryption_key128.bin XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS
  104. .. only:: SOC_EFUSE_BLOCK9_KEY_PURPOSE_QUIRK
  105. .. warning::
  106. For the {IDF_TARGET_NAME} BLOCK9 (BLOCK_KEY5) can not be used by XTS_AES keys.
  107. 4. Burn the ``{IDF_TARGET_CRYPT_CNT}`` eFuse.
  108. If you only want to enable flash encryption in **Development** mode and want to keep the ability to disable it in the future, Update the {IDF_TARGET_CRYPT_CNT} value in the below command from {IDF_TARGET_CRYPT_CNT_MAX_VAL} to 0x1. (not recommended for production)
  109. .. code-block:: bash
  110. espefuse.py --port PORT --chip {IDF_TARGET_PATH_NAME} burn_efuse {IDF_TARGET_CRYPT_CNT} {IDF_TARGET_CRYPT_CNT_MAX_VAL}
  111. .. only:: esp32
  112. In the case of {IDF_TARGET_NAME}, you also need to burn the ``FLASH_CRYPT_CONFIG``. It can be done by running:
  113. .. code-block:: bash
  114. espefuse.py --port PORT --chip {IDF_TARGET_PATH_NAME} burn_efuse FLASH_CRYPT_CONFIG 0xF
  115. .. note::
  116. At this point, the flash encryption on the device has been enabled. You may test the flash encryption process as given in step 5. Please note that the security-related eFuses have not been burned at this point. It is recommended that they should be burned in production use cases as explained in step 6.
  117. 5. Encrypt and flash the binaries.
  118. The bootloader and the application binaries for the project must be built with Flash Encryption Release mode with default configurations.
  119. Flash encryption Release mode can be set in the menuconfig as follows:
  120. .. list::
  121. - :ref:`Enable flash encryption on boot <CONFIG_SECURE_FLASH_ENC_ENABLED>`
  122. :esp32: - :ref:`Select Release mode <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (Note that once Release mode is selected, the ``DISABLE_DL_ENCRYPT`` and ``DISABLE_DL_DECRYPT`` eFuse bits will be burned to disable flash encryption hardware in ROM Download Mode.)
  123. :esp32: - :ref:`Select UART ROM download mode (Permanently disabled (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>` (Note that this option is only available when :ref:`CONFIG_ESP32_REV_MIN` is set to 3 (ESP32 V3).) The default choice is to keep UART ROM download mode enabled, however it is recommended to permanently disable this mode to reduce the options available to an attacker.
  124. :not esp32: - :ref:`Select Release mode <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (Note that once Release mode is selected, the ``EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT`` eFuse bit will be burned to disable flash encryption hardware in ROM Download Mode.)
  125. :not esp32: - :ref:`Select UART ROM download mode (Permanently switch to Secure mode (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>`. This is the default option and is recommended. It is also possible to change this configuration setting to permanently disable UART ROM download mode, if this mode is not needed.
  126. - :ref:`Select the appropriate bootloader log verbosity <CONFIG_BOOTLOADER_LOG_LEVEL>`
  127. - Save the configuration and exit.
  128. The binaries can be encrypted on the host machine by running:
  129. .. only:: esp32
  130. .. code-block:: bash
  131. espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x1000 --output bootloader-enc.bin build/bootloader/bootloader.bin
  132. espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x8000 --output partition-table-enc.bin build/partition_table/partition-table.bin
  133. espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x10000 --output my-app-enc.bin build/my-app.bin
  134. .. only:: not esp32
  135. .. code-block:: bash
  136. espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x0 --output bootloader-enc.bin build/my-app.bin
  137. espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x8000 --output partition-table-enc.bin build/partition_table/partition-table.bin
  138. espsecure.py encrypt_flash_data --aes_xts --keyfile my_flash_encryption_key.bin --address 0x10000 --output my-app-enc.bin build/my-app.bin
  139. The above files can then be flashed to their respective offset using ``esptool.py``. To see all of the command line options recommended for ``esptool.py``, see the output printed when ``idf.py build`` succeeds. In the above command the offsets are used for a sample firmware, the actual offset for your firmware can be obtained by checking the partition table entry or by running `idf.py partition-table`. When the application contains the following partition: ``otadata``, ``nvs_encryption_keys`` they need to be encrypted as well. Please refer to :ref:`encrypted-partitions` for more details about encrypted partitions.
  140. .. note::
  141. If the flashed ciphertext file is not recognized by the {IDF_TARGET_NAME} when it boots, check that the keys match and that the command line arguments match exactly, including the correct offset. It is important to provide the correct offset as the ciphertext changes when the offset changes.
  142. .. only:: esp32
  143. If your ESP32 uses non-default :ref:`FLASH_CRYPT_CONFIG value in eFuse <setting-flash-crypt-config>` then you will need to pass the ``--flash_crypt_conf`` argument to ``espsecure.py`` to set the matching value. This will not happen if the device configured flash encryption by itself but may happen when burning eFuses manually to enable flash encryption.
  144. The command ``espsecure.py decrypt_flash_data`` can be used with the same options (and different input/output files), to decrypt ciphertext flash contents or a previously encrypted file.
  145. 6. Burn flash encryption-related security eFuses as listed below:
  146. A) Burn security eFuses:
  147. .. important::
  148. For production use cases, it is highly recommended to burn all the eFuses listed below.
  149. .. list::
  150. :esp32: - ``DISABLE_DL_ENCRYPT``: Disable the UART bootloader encryption access.
  151. :esp32: - ``DISABLE_DL_DECRYPT``: Disable the UART bootloader decryption access.
  152. :esp32: - ``DISABLE_DL_CACHE``: Disable the UART bootloader flash cache access.
  153. :esp32: - ``JTAG_DISABLE``: Disable the JTAG
  154. :SOC_EFUSE_DIS_BOOT_REMAP: - ``DIS_BOOT_REMAP``: Disable capability to Remap ROM to RAM address space
  155. :SOC_EFUSE_DIS_DOWNLOAD_ICACHE: - ``DIS_DOWNLOAD_ICACHE``: Disable UART cache
  156. :SOC_EFUSE_DIS_DOWNLOAD_DCACHE: - ``DIS_DOWNLOAD_DCACHE``: Disable UART cache.
  157. :SOC_EFUSE_HARD_DIS_JTAG: - ``HARD_DIS_JTAG``: Hard disable JTAG peripheral
  158. :SOC_EFUSE_DIS_DIRECT_BOOT:- ``DIS_DIRECT_BOOT``: Disable direct boot (legacy SPI boot mode)
  159. :SOC_EFUSE_DIS_LEGACY_SPI_BOOT: - ``DIS_LEGACY_SPI_BOOT``: Disable legacy SPI boot mode
  160. :SOC_EFUSE_DIS_USB_JTAG: - ``DIS_USB_JTAG``: Disable USB switch to JTAG
  161. :SOC_EFUSE_DIS_PAD_JTAG: - ``DIS_PAD_JTAG``: Disable JTAG permanently
  162. :not esp32: - ``DIS_DOWNLOAD_MANUAL_ENCRYPT``: Disable UART bootloader encryption access
  163. The respective eFuses can be burned by running:
  164. .. code:: bash
  165. espefuse.py burn_efuse --port PORT EFUSE_NAME 0x1
  166. .. note::
  167. Please update the EFUSE_NAME with the eFuse that you need to burn. Multiple eFuses can be burned at the same time by appending them to the above command (e.g., EFUSE_NAME VAL EFUSE_NAME2 VAL2). More documentation about `espefuse.py` can be found `here <https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html>`_
  168. B) Write protect security eFuses:
  169. After burning the respective eFuses we need to write_protect the security configurations
  170. .. only:: esp32
  171. .. code:: bash
  172. espefuse.py --port PORT write_protect_efuse MAC
  173. .. note::
  174. The write disable bit for MAC also write disables DIS_CACHE which is required to prevent accidental burning of this bit.
  175. C) Disable UART ROM DL mode:
  176. .. only:: not esp32
  177. .. code:: bash
  178. espefuse.py --port PORT write_protect_efuse DIS_ICACHE
  179. .. note::
  180. The write protection of above eFuse also write protects multiple other eFuses, Please refer to the {IDF_TARGET_NAME} eFuse table for more details.
  181. C) Enable Security Download mode:
  182. .. warning::
  183. Please burn the following bit at the very end. After this bit is burned, the espefuse tool can no longer be used to burn additional eFuses.
  184. .. list::
  185. :esp32: - ``UART_DOWNLOAD_DIS`` : Disable the UART ROM Download mode.
  186. :not esp32: - ``ENABLE_SECURITY_DOWNLOAD``: Enable Secure ROM download mode
  187. .. only:: esp32
  188. The eFuse can be burned by running:
  189. .. code:: bash
  190. espefuse.py --port PORT burn_efuse UART_DOWNLOAD_DIS
  191. .. only:: not esp32
  192. The eFuse can be burned by running:
  193. .. code:: bash
  194. espefuse.py --port PORT burn_efuse ENABLE_SECURITY_DOWNLOAD
  195. .. important::
  196. 7. Delete flash encryption key on host:
  197. Once the flash encryption has been enabled for the device, the key **must be deleted immediately**. This ensures that the host cannot produce encrypted binaries for the same device going forward. This step is important to reduce the vulnerability of the flash encryption key.
  198. Flash Encryption Guidelines
  199. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  200. * It is recommended to generate a unique flash encryption key for each device for production use-cases.
  201. * It is recommended to ensure that the RNG used by host machine to generate the flash encryption key has good entropy.
  202. * See :ref:`flash-encryption-limitations` for more details.
  203. .. _enable-secure-boot-v2-externally:
  204. Enable Secure Boot V2 Externally
  205. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  206. In this workflow, we shall use ``espsecure`` tool to generate signing keys and use the ``espefuse`` tool to burn the relevant eFuses. The details about the Secure Boot V2 process can be found at :doc:`Secure Boot V2 Guide </security/secure-boot-v2>`
  207. 1. Generate Secure Boot V2 Signing Private Key.
  208. .. only:: esp32 or SOC_SECURE_BOOT_V2_RSA
  209. The Secure Boot V2 signing key for the RSA3072 scheme can be generated by running:
  210. .. code:: bash
  211. espsecure.py generate_signing_key --version 2 --scheme rsa3072 secure_boot_signing_key.pem
  212. .. only:: SOC_SECURE_BOOT_V2_ECC
  213. The Secure Boot V2 signing key for ECDSA scheme can be generated by running:
  214. .. code:: bash
  215. espsecure.py generate_signing_key --version 2 --scheme ecdsa256 secure_boot_signing_key.pem
  216. The scheme in the above command can be changed to ``ecdsa192`` to generate ecdsa192 private key.
  217. .. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
  218. A total of 3 keys can be used for Secure Boot V2 at once. These should be computed independently and stored separately. The same command with different key file names can be used to generate multiple Secure Boot V2 signing keys. It is recommended to use multiple keys in order to reduce dependency on a single key.
  219. 2. Generate Public Key Digest.
  220. The public key digest for the private key generated in the previous step can be generated by running:
  221. .. code:: bash
  222. espsecure.py digest_sbv2_public_key --keyfile secure_boot_signing_key.pem --output digest.bin
  223. .. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
  224. In case of multiple digests, each digest should be kept in a separate file.
  225. 3. Burn the key digest in eFuse.
  226. The public key digest can be burned in the eFuse by running:
  227. .. only:: esp32
  228. .. code:: bash
  229. espefuse.py --port PORT --chip esp32 burn_key secure_boot_v2 digest.bin
  230. .. only:: esp32c2
  231. .. code:: bash
  232. espefuse.py --port PORT --chip esp32c2 burn_key KEY_BLOCK0 SECURE_BOOT_DIGEST digest.bin
  233. .. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
  234. .. code:: bash
  235. espefuse.py --port PORT --chip {IDF_TARGET_PATH_NAME} burn_key BLOCK SECURE_BOOT_DIGEST0 digest.bin
  236. where ``BLOCK`` is a free keyblock between ``BLOCK_KEY0`` and ``BLOCK_KEY5``.
  237. In case of multiple digests, the other digests can be burned sequentially by changing the key purpose to ``SECURE_BOOT_DIGEST1`` and ``SECURE_BOOT_DIGEST2`` respectively.
  238. 4. Enable Secure Boot V2.
  239. Secure Boot V2 eFuse can be enabled by running:
  240. .. only:: esp32
  241. .. code:: bash
  242. espefuse.py --port PORT --chip esp32 burn_efuse ABS_DONE_1
  243. .. only:: not esp32
  244. .. code:: bash
  245. espefuse.py --port PORT --chip {IDF_TARGET_PATH_NAME} burn_efuse SECURE_BOOT_EN
  246. .. note::
  247. At this stage the secure boot V2 has been enabled for the {IDF_TARGET_NAME}. The ROM bootloader shall now verify the authenticity of the :ref:`second-stage-bootloader` on every bootup. You may test the secure boot process by executing Steps 5 & 6. Please note that security-related eFuses have not been burned at this point. For production use cases, all security-related eFuses must be burned as given in step 7.
  248. 5. Build the binaries.
  249. By default, the ROM bootloader would only verify the :ref:`second-stage-bootloader` (firmware bootloader). The firmware bootloader would verify the app partition only when the :ref:`CONFIG_SECURE_BOOT` option is enabled (and :ref:`CONFIG_SECURE_BOOT_VERSION` is set to ``SECURE_BOOT_V2_ENABLED``) while building the bootloader.
  250. a) Open the :ref:`project-configuration-menu`, in "Security features" set "Enable hardware Secure Boot in bootloader" to enable Secure Boot.
  251. .. only:: esp32
  252. For ESP32, Secure Boot V2 is available only for ESP32 ECO3 onwards. To view the "Secure Boot V2" option the chip revision should be changed to revision v3.0 (ECO3). To change the chip revision, set "Minimum Supported ESP32 Revision" to "Rev 3.0 (ECO3)" in "Component Config" -> "Hardware Settings" -> "Chip Revision".
  253. .. only:: SOC_SECURE_BOOT_V2_RSA or SOC_SECURE_BOOT_V2_ECC
  254. The "Secure Boot V2" option will be selected and the "App Signing Scheme" will be set to {IDF_TARGET_SBV2_DEFAULT_SCHEME} by default.
  255. b) Disable the option :ref:`CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES` for the project in the :ref:`project-configuration-menu`. This shall make sure that all the generated binaries are secure padded and unsigned. This step is done to avoid generating signed binaries as we are going to manually sign the binaries using ``espsecure`` tool.
  256. After the above configurations, the bootloader and application binaries can be built with ``idf.py build`` command.
  257. 6. Sign and Flash the binaries.
  258. The Secure Boot V2 workflow only verifies the ``bootloader`` and ``application`` binaries, hence only those binaries need to be signed. The other binaries (e.g., ``partition-table.bin``) can be flashed as they are generated in the build stage.
  259. The ``bootloader.bin`` and ``app.bin`` binaries can be signed by running:
  260. .. code:: bash
  261. espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem --output bootloader-signed.bin build/bootloader/bootloader.bin
  262. espsecure.py sign_data --version 2 --keyfile secure_boot_signing_key.pem --output my-app-signed.bin build/my-app.bin
  263. .. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
  264. If multiple keys secure boot keys are to be used then the same signed binary can be appended with a signature block signed with the new key as follows:
  265. .. code:: bash
  266. espsecure.py sign_data --keyfile secure_boot_signing_key2.pem --version 2 --append_signatures -o bootloader-signed2.bin bootloader-signed.bin
  267. espsecure.py sign_data --keyfile secure_boot_signing_key2.pem --version 2 --append_signatures -o my-app-signed2.bin my-app-signed.bin
  268. The same process can be repeated for the third key. Note that the names of the input and output files must not be the same.
  269. The signatures attached to a binary can be checked by running:
  270. .. code:: bash
  271. espsecure.py signature_info_v2 bootloader-signed.bin
  272. The above files along with other binaries (e.g., partition table) can then be flashed to their respective offset using ``esptool.py``. To see all of the command line options recommended for ``esptool.py``, see the output printed when ``idf.py build`` succeeds. The flash offset for your firmware can be obtained by checking the partition table entry or by running ``idf.py partition-table``.
  273. 7. Burn relevant eFuses.
  274. A) Burn security eFuses:
  275. .. important::
  276. For production use cases, it is highly recommended to burn all the eFuses listed below.
  277. .. list::
  278. :esp32: - ``JTAG_DISABLE``: Disable the JTAG
  279. :SOC_EFUSE_DIS_BOOT_REMAP: - ``DIS_BOOT_REMAP``: Disable capability to Remap ROM to RAM address space
  280. :SOC_EFUSE_HARD_DIS_JTAG: - ``HARD_DIS_JTAG``: Hard disable JTAG peripheral
  281. :SOC_EFUSE_SOFT_DIS_JTAG: - ``SOFT_DIS_JTAG``: Disable software access to JTAG peripheral
  282. :SOC_EFUSE_DIS_DIRECT_BOOT:- ``DIS_DIRECT_BOOT``: Disable direct boot (legacy SPI boot mode)
  283. :SOC_EFUSE_DIS_LEGACY_SPI_BOOT: - ``DIS_LEGACY_SPI_BOOT``: Disable legacy SPI boot mode
  284. :SOC_EFUSE_DIS_USB_JTAG: - ``DIS_USB_JTAG``: Disable USB switch to JTAG
  285. :SOC_EFUSE_DIS_PAD_JTAG: - ``DIS_PAD_JTAG``: Disable JTAG permanently
  286. :SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS: - ``SECURE_BOOT_AGGRESSIVE_REVOKE``: Aggressive revocation of key digests, see :ref:`secure-boot-v2-aggressive-key-revocation` for more details.
  287. The respective eFuses can be burned by running:
  288. .. code:: bash
  289. espefuse.py burn_efuse --port PORT EFUSE_NAME 0x1
  290. .. note::
  291. Please update the EFUSE_NAME with the eFuse that you need to burn. Multiple eFuses can be burned at the same time by appending them to the above command (e.g., EFUSE_NAME VAL EFUSE_NAME2 VAL2). More documentation about `espefuse.py` can be found `here <https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html>`_
  292. B) Secure Boot V2-related eFuses:
  293. i) Disable the ability for read protection:
  294. The secure boot digest burned in the eFuse must be kept readable otherwise secure boot operation would result in a failure. To prevent the accidental enabling of read protection for this key block we need to burn the following eFuse:
  295. .. code:: bash
  296. espefuse.py -p $ESPPORT write_protect_efuse RD_DIS
  297. .. important::
  298. After this eFuse has been burned, read protection cannot be enabled for any key. E.g., if flash encryption which requires read protection for its key is not enabled at this point then it cannot be enabled afterwards. Please ensure that no eFuse keys are going to need read protection after this.
  299. .. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
  300. ii) Revoke key digests:
  301. The unused digest slots need to be revoked when we are burning the secure boot key. The respective slots can be revoked by running
  302. .. code:: bash
  303. espefuse.py --port PORT --chip {IDF_TARGET_PATH_NAME} burn_efuse EFUSE_REVOKE_BIT
  304. The ``EFUSE_REVOKE_BIT`` in the above command can be ``SECURE_BOOT_KEY_REVOKE0`` or ``SECURE_BOOT_KEY_REVOKE1`` or ``SECURE_BOOT_KEY_REVOKE2``. Please note that only the unused key digests must be revoked. Once revoked, the respective digest cannot be used again.
  305. .. only:: esp32
  306. C) Disable UART ROM DL mode:
  307. .. only:: not esp32
  308. C) Enable Security Download mode:
  309. .. warning::
  310. Please burn the following bit at the very end. After this bit is burned, the espefuse tool can no longer be used to burn additional eFuses.
  311. .. list::
  312. :esp32: - ``UART_DOWNLOAD_DIS`` : Disable the UART ROM Download mode.
  313. :not esp32: - ``ENABLE_SECURITY_DOWNLOAD``: Enable Secure ROM download mode
  314. .. only:: esp32
  315. The eFuse can be burned by running:
  316. .. code:: bash
  317. espefuse.py --port PORT burn_efuse UART_DOWNLOAD_DIS
  318. .. only:: not esp32
  319. The eFuse can be burned by running:
  320. .. code:: bash
  321. espefuse.py --port PORT burn_efuse ENABLE_SECURITY_DOWNLOAD
  322. Secure Boot V2 Guidelines
  323. ~~~~~~~~~~~~~~~~~~~~~~~~~
  324. * It is recommended to store the secure boot key in a highly secure place. A physical or a cloud HSM may be used for secure storage of the secure boot private key. Please take a look at :ref:`remote-sign-v2-image` for more details.
  325. .. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
  326. * It is recommended to use all the available digest slots to reduce dependency on a single private key.