ESP-IDF Programming Guide Choose target... Choose version... Get Started API Reference Hardware Reference API Guides Security Guides Migration Guides Libraries and Frameworks Contributions Guide ESP-IDF Versions Resources Copyrights and Licenses About Switch Between Languages ESP-IDF Programming Guide ESP-IDF Programming Guide Edit on GitHub ESP-IDF Programming Guide [中文] This is the documentation for Espressif IoT Development Framework (esp-idf). ESP-IDF is the official development framework for the ESP32, ESP32-S, ESP32-C, ESP32-H and ESP32-P Series SoCs. This document describes using ESP-IDF with the ESP32-C3 SoC. To switch to a different SoC target, choose target from the dropdown in the upper left. Get Started API Reference API Guides Was this page helpful? Thank you! We received your feedback. If you have any comments, fill in Espressif Documentation Feedback Form. We value your feedback. Let us know how we can improve this page by filling in Espressif Documentation Feedback Form. Next © Copyright 2016 - 2026, Espressif Systems (Shanghai) Co., Ltd. Built with Sphinx using a theme based on Read the Docs Sphinx Theme. Download HTML ESP-IDF Programming Guide Choose target... Choose version... Get Started API Reference Hardware Reference API Guides Security Guides Security Overview Flash Encryption Secure Boot v2 Security Features Enablement Workflows Introduction Goals Prerequisites Scope Security Features Enablement Enable Flash Encryption and Secure Boot v2 Externally Enable Flash Encryption Externally Enable Secure Boot v2 Externally Enable NVS Encryption Externally Vulnerabilities Migration Guides Libraries and Frameworks Contributions Guide ESP-IDF Versions Resources Copyrights and Licenses About Switch Between Languages ESP-IDF Programming Guide Security Guides Security Features Enablement Workflows Edit on GitHub Security Features Enablement Workflows [中文] Introduction When enabling security features on ESP32 SoCs, it is recommended that power supply be uninterrupted. Power failures during this process could cause issues that are hard to debug and, in some cases, may cause permanent boot-up failures. This guide describes a set of workflows to enable security features on the device with the assistance of an external host machine. These workflows are broken down into various stages, with each stage generating signing/encryption keys on the host machine. This allows for greater chances of recovery in case of power or other failures. Furthermore, these workflows expedites the overall provisioning process via the use of the host machine (e.g., encrypting firmware on the host is quicker than on the device). Important It is possible to try out the security features for ESP32-C3 target SoC under QEMU Emulator virtually. Once the security workflow is established, you can then proceed to the real hardware. Goals Simplify the traditional workflow for enabling security features with stepwise instructions. Design a more flexible workflow when compared to the traditional firmware-based workflow. Improve reliability by dividing the workflow into small operations. Eliminate dependency on Second Stage Bootloader. Prerequisites esptool: Please make sure the esptool has been installed. It can be installed by running: pip install esptool Scope Enable Flash Encryption and Secure Boot v2 Externally Enable Flash Encryption Externally Enable Secure Boot v2 Externally Enable NVS Encryption Externally Security Features Enablement Enable Flash Encryption and Secure Boot v2 Externally Important It is recommended to enable both Flash Encryption and Secure Boot v2 for a production use case. When enabling the Flash Encryption and Secure Boot v2 together, they must be enabled in the following order: Enable the Flash Encryption feature by following the steps listed in Enable Flash Encryption Externally. Enable the Secure Boot v2 feature by following the steps listed in Enable Secure Boot v2 Externally. The reason for this particular ordering is that when enabling 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. Enable Flash Encryption Externally In this case, all the eFuses related to Flash Encryption are written with help of the espefuse tool. More details about Flash Encryption process can be found in Flash Encryption. Ensure that you have an ESP32-C3 device with default Flash Encryption eFuse settings as shown in Relevant eFuses See how to check ESP32-C3 Flash Encryption Status. At this point, the Flash Encryption must not be already enabled on the chip. Additionally, the flash on the chip needs to be erased, which can be done by running: esptool --port PORT erase-flash Generate a Flash Encryption key A random Flash Encryption key can be generated by running: espsecure generate-flash-encryption-key my_flash_encryption_key.bin Program the generated Flash Encryption key into the device To store the Flash Encryption key in the eFuses, run the following commands: Warning This action cannot be reverted. espefuse --port PORT burn-key BLOCK my_flash_encryption_key.bin XTS_AES_128_KEY where BLOCK is a free keyblock between BLOCK_KEY0 and BLOCK_KEY5. Warning For the ESP32-C3 BLOCK9 (BLOCK_KEY5) can not be used by XTS_AES keys. Burn the SPI_BOOT_CRYPT_CNT eFuse 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 SPI_BOOT_CRYPT_CNT value in the below command from 7 to 0x1 (not recommended for production). espefuse --port PORT --chip esp32c3 burn-efuse SPI_BOOT_CRYPT_CNT 7 Burn Flash Encryption-related security eFuses as listed below Burn security eFuses Important For production use cases, it is highly recommended to burn all the eFuses listed below. DIS_DOWNLOAD_ICACHE: Disable UART cache DIS_DIRECT_BOOT: Disable direct boot (legacy SPI boot mode) DIS_USB_JTAG: Disable USB switch to JTAG DIS_PAD_JTAG: Disable JTAG permanently DIS_DOWNLOAD_MANUAL_ENCRYPT: Disable UART bootloader encryption access The respective eFuses can be burned by running: espefuse burn-efuse --port PORT EFUSE_NAME 0x1 Note 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 can be found here. Write protect security eFuses After burning the respective eFuses we need to write_protect the security configurations. It can be done by burning following eFuse espefuse --port PORT write-protect-efuse DIS_ICACHE Note The write protection of above eFuse also write protects multiple other eFuses, Please refer to the ESP32-C3 eFuse table for more details. Configure the project The bootloader and the application binaries for the project must be built with Flash Encryption release mode with default configurations. Flash Encryption release mode can be set in the menuconfig as follows: Enable Flash Encryption on boot. Select release 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). Select UART ROM download mode (permanently switch to Secure mode (recommended)). 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. Select the appropriate bootloader log verbosity. Save the configuration and exit. Build, Encrypt and Flash the binaries The binaries can be encrypted on the host machine by running: espsecure encrypt-flash-data --aes-xts --keyfile my_flash_encryption_key.bin --address 0x0 --output bootloader-enc.bin build/bootloader/bootloader.bin espsecure encrypt-flash-data --aes-xts --keyfile my_flash_encryption_key.bin --address 0x8000 --output partition-table-enc.bin build/partition_table/partition-table.bin espsecure encrypt-flash-data --aes-xts --keyfile my_flash_encryption_key.bin --address 0x10000 --output my-app-enc.bin build/my-app.bin Note If secure boot is enabled, perform secure boot signing of the firmware before carrying out the above encryption operation. In the above command, the offsets are used for a sample firmware, and the actual offset for your firmware can be obtained by checking the partition table entry or by running idf.py partition-table. Please note that not all the binaries need to be encrypted, the encryption applies only to those generated from the partitions which are marked as encrypted in the partition table definition file. Other binaries are flashed unencrypted, i.e., as a plain output of the build process. The above files can then be flashed to their respective offset using esptool. To see all of the command line options recommended for esptool, see the output printed when idf.py build succeeds. When the application contains the following partition: otadata and nvs_encryption_keys, they need to be encrypted as well. Please refer to Encrypted Partitions for more details about encrypted partitions. Note If the flashed ciphertext file is not recognized by the ESP32-C3 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. The command espsecure decrypt-flash-data can be used with the same options (and different input or output files), to decrypt ciphertext flash contents or a previously encrypted file. Secure the ROM download mode Warning Please perform the following step at the very end. After this eFuse is burned