For simplicity, the security features such as Secure Boot V2, Flash Encryption, NVS Encryption shall be enabled through host based python tools (e.g., espefuse).
> The instructions in the example directly burn eFuses and once done, it cannot be reverted. Please go through the below steps carefully before executing the example. All the steps must be followed without any changes and in the exact sequence, otherwise the device may end up in an unrecoverable state. Follow the [QEMU workflow](#enable-security-features-with-help-of-qemu) if you want to test the example without the risk of bricking an actual device.
In the example, we need to use the Serial port in nearly all the commands. To make it easier, we shall set the ESPPORT environment variable at once and reuse it later. See the documentation about [Connecting the ESP device to PC](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/establish-serial-connection.html#connect-esp32-to-pc) to find out the Serial port.
The detailed instructions on how to use QEMU can be found in the [QEMU documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/tools/qemu.html).
For more details about Secure Boot V2 protocol checkout the [Secure boot V2 documentation](https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot-v2.html).
<details>
<summary>Target specific documentation</summary>
For target specific documentation, run the following command after setting the [target](#2-set-the-target)
With above steps the Secure Boot V2 feature shall be enabled. The firmware build step is configured to generate signed binaries for `bootloader` and `application` by default (so there is no need to manually sign).
The necessary `security eFuses` are yet to be burned. They shall be burned by the application when first launched.
#### Use multiple Secure Boot V2 signing keys
**It is recommended to use multiple secure boot v2 signing keys**.
When the application is built (later in the workflow) the `bootloader` and `application` shall only be signed with the first key. To sign it with multiple keys, please follow below additional steps:
- Repeat `Step 1` to `Step 3` for `secure_boot_signing_key_2.pem` and `secure_boot_signing_key_3.pem` respectively.
- Sign it with remaining two keys by executing following commands with adding `-a` option for `secure_boot_signing_key_2.pem` and `secure_boot_signing_key_3.pem` respectively:
**Note: The working directory of above command is set to `build`. If the key file path is relative, then it should be relative to the `build` directory**
Details about the Flash Encryption protocol can be found at the [Flash Encryption documentation](https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html).
<details>
<summary>Target specific documentation</summary>
For target specific documentation, run the following command after setting the [target](#2-set-the-target)
At this point the Flash Encryption feature is enabled for the device. The necessary `security eFuses` shall be enabled by the `security_features_app` firmware.
The bootloader offset for esp32c3 is `0x0`. The partition table offset for the example has been set to `0xD000` which can be changed through menuconfig. The partition offset for other partitions can be obtained by running ```idf.py partition-table```
Please refer to [Encrypted Partition](https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html#encrypted-partitions) to check which partitions must be encrypted by default.
We shall use the `HMAC based NVS encryption scheme`, Please find more details in the [NVS encryption documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_encryption.html#nvs-encryption-hmac-peripheral-based-scheme)
<details>
<summary>Target specific documentation</summary>
For target specific documentation, run the following command after setting the [target](#2-set-the-target)
For generation of NVS encryption keys and NVS partition, we shall use [NVS partition generator](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_partition_gen.html#nvs-partition-generator-utility).
<details>
<summary>Target specific documentation</summary>
For target specific documentation, run the following command after setting the [target](#2-set-the-target)
We have used `BLOCK_KEY2` here to store the HMAC key. Generally, `BLOCK` can be a free keyblock between `BLOCK_KEY0` and `BLOCK_KEY5`.
If you want to change the value of the eFuse key block for this example, make sure to update the same value in `menuconfig → Component config → NVS Security Provider → eFuse key ID storing the HMAC key`.
See [Generating NVS partition](https://docs.espressif.com/projects/esp-idf/en/stable/api-reference/storage/nvs_partition_gen.html#generate-encrypted-nvs-partition) for detailed information on generating the encrypted NVS partition.
*`CSV placeholder`: CSV file which contains data of the NVS partition. See [CSV file format](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_partition_gen.html#csv-file-format) for more details.
The target provides an ability to disable JTAG access in the device for the software. This can be re-enabled in future after authentication using a unique token generated beforehand. This way the module can be opened up by bypassing security features after authentication for debugging purposes. This way when a secure locked device comes back to the ODM/OEM due to some issue, the module can be opened up for debug after successful authentication.
The example directly consumes this token data and re-enables the software disabled JTAG interface. The re-enablement can be tested by attempting a JTAG connection with the device after JTAG is enabled by the firmware. More details about JTAG debugging can be found [here](https://docs.espressif.com/projects/esp-idf/en/stable/api-guides/jtag-debugging/index.html).
By default esp32 is set to use the [built-in JTAG interface](https://docs.espressif.com/projects/esp-idf/en/stable/api-guides/jtag-debugging/configure-builtin-jtag.html). Please follow the steps given [here](https://docs.espressif.com/projects/esp-idf/en/stable/api-guides/jtag-debugging/configure-other-jtag.html) to configure the alternative JTAG interface.
The example is configured to build the signed binaries for the `bootloader.bin` and `security_features.bin` (application).
These shall be signed with the first secure boot key.
If you want to use multiple Secure Boot V2 signing keys for the image then please perform the step of [Signing with multiple Secure Boot V2 keys](README.md#use-multiple-secure-boot-v2-signing-keys).
### Encrypting partitions
At this point, we shall encrypt all the necessary partitions. Please perform [Encrypting the partitions](README.md#encrypting-the-partitions) step to do the same.
On the first boot-up, there would be prints about firmware not being secure. Please ignore the prints as we shall enable all necessary security eFuses in our application. On the Second boot onwards, you shall not see any such prints.
Espressif fork of [QEMU](https://github.com/espressif/qemu) offers the ability to emulate `esp32c3/esp32s3` target on the host machine with help of `QEMU`. That way all of the above security features can be enabled on the target that is emulated on the host machine. A major advantage of this is that no hardware is lost while trying out the security features.
Perform the [Build](README.md#build) step and all necessary substeps (e.g. encrypting partition). Please make sure the file names of newly generated files and their locations in the commands are not changed.
**NOTE: The `idf.py merge-bin` command runs with `build` as the working directory. Make sure the relative path provided are relative to the `build` directory