mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-10 12:53:29 +00:00
Merge branch 'feature/dis_uart_dl_mode' into 'master'
feature: Disable UART download mode Closes IDF-1386 See merge request espressif/esp-idf!8590
This commit is contained in:
@@ -587,6 +587,7 @@ menu "Security features"
|
||||
|
||||
config SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||
bool "Release"
|
||||
select SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
|
||||
endchoice
|
||||
|
||||
@@ -698,5 +699,48 @@ menu "Security features"
|
||||
the wrong device. The device needs to have flash encryption already enabled using espefuse.py.
|
||||
|
||||
endmenu # Potentially Insecure
|
||||
|
||||
config SECURE_DISABLE_ROM_DL_MODE
|
||||
bool "Permanently disable ROM Download Mode"
|
||||
depends on !IDF_TARGET_ESP32 || ESP32_REV_MIN_3
|
||||
default n
|
||||
help
|
||||
If set, during startup the app will burn an eFuse bit to permanently disable the UART ROM
|
||||
Download Mode. This prevents any future use of esptool.py, espefuse.py and similar tools.
|
||||
|
||||
Once disabled, if the SoC is booted with strapping pins set for ROM Download Mode
|
||||
then an error is printed instead.
|
||||
|
||||
It is recommended to enable this option in any production application where Flash
|
||||
Encryption and/or Secure Boot is enabled and access to Download Mode is not required.
|
||||
|
||||
It is also possible to permanently disable Download Mode by calling
|
||||
esp_efuse_disable_rom_download_mode() at runtime.
|
||||
|
||||
config SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
bool "Permanently switch to ROM UART Secure Download mode"
|
||||
depends on IDF_TARGET_ESP32S2 && !SECURE_DISABLE_ROM_DL_MODE
|
||||
help
|
||||
If set, during startup the app will burn an eFuse bit to permanently switch the UART ROM
|
||||
Download Mode into a separate Secure Download mode. This option can only work if
|
||||
Download Mode is not already disabled by eFuse.
|
||||
|
||||
Secure Download mode limits the use of Download Mode functions to simple flash read,
|
||||
write and erase operations, plus a command to return a summary of currently enabled
|
||||
security features.
|
||||
|
||||
Secure Download mode is not compatible with the esptool.py flasher stub feature,
|
||||
espefuse.py, read/writing memory or registers, encrypted download, or any other
|
||||
features that interact with unsupported Download Mode commands.
|
||||
|
||||
Secure Download mode should be enabled in any application where Flash Encryption
|
||||
and/or Secure Boot is enabled. Disabling this option does not immediately cancel
|
||||
the benefits of the security features, but it increases the potential "attack
|
||||
surface" for an attacker to try and bypass them with a successful physical attack.
|
||||
|
||||
It is also possible to enable secure download mode at runtime by calling
|
||||
esp_efuse_enable_rom_secure_download_mode()
|
||||
|
||||
|
||||
endmenu # Security features
|
||||
|
||||
|
@@ -128,6 +128,10 @@ esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
|
||||
* is enabled but secure boot is not used. This should protect against
|
||||
* serial re-flashing of an unauthorised code in absence of secure boot.
|
||||
*
|
||||
* @note On ESP32 V3 only, write protecting FLASH_CRYPT_CNT will also prevent
|
||||
* disabling UART Download Mode. If both are wanted, call
|
||||
* esp_efuse_disable_rom_download_mode() before calling this function.
|
||||
*
|
||||
*/
|
||||
void esp_flash_write_protect_crypt_cnt(void);
|
||||
|
||||
|
@@ -188,31 +188,28 @@ static esp_err_t initialise_flash_encryption(void)
|
||||
|
||||
#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
|
||||
ESP_LOGI(TAG, "Disable UART bootloader encryption...");
|
||||
const uint8_t dis_manual_encrypt = 1;
|
||||
esp_efuse_write_field_blob(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT, &dis_manual_encrypt, 1);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader encryption");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
|
||||
ESP_LOGI(TAG, "Disable UART bootloader cache...");
|
||||
const uint8_t dis_download_caches = 1;
|
||||
esp_efuse_write_field_blob(ESP_EFUSE_DIS_DOWNLOAD_DCACHE, &dis_download_caches, 1);
|
||||
esp_efuse_write_field_blob(ESP_EFUSE_DIS_DOWNLOAD_ICACHE, &dis_download_caches, 1);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_DCACHE);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader cache - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable JTAG...");
|
||||
const uint8_t dis_jtag = 1;
|
||||
esp_efuse_write_field_blob(ESP_EFUSE_HARD_DIS_JTAG, &dis_jtag, 1);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_HARD_DIS_JTAG);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
const uint8_t dis_boot_remap = 1;
|
||||
esp_efuse_write_field_blob(ESP_EFUSE_DIS_BOOT_REMAP, &dis_boot_remap, 1);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_BOOT_REMAP);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
|
||||
|
@@ -34,12 +34,20 @@ esp_err_t esp_secure_boot_permanently_enable(void)
|
||||
return r;
|
||||
}
|
||||
|
||||
ets_efuse_clear_program_registers();
|
||||
REG_SET_BIT(EFUSE_PGM_DATA3_REG, EFUSE_SECURE_BOOT_EN);
|
||||
ets_efuse_program(ETS_EFUSE_BLOCK0);
|
||||
esp_efuse_batch_write_begin(); /* Batch all efuse writes at the end of this function */
|
||||
|
||||
assert(ets_efuse_secure_boot_enabled());
|
||||
ESP_LOGI(TAG, "Secure boot permanently enabled");
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_SECURE_BOOT_EN);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_BOOT_REMAP);
|
||||
esp_efuse_write_field_bit(ESP_EFUSE_DIS_LEGACY_SPI_BOOT);
|
||||
|
||||
// TODO: also disable JTAG here, etc
|
||||
|
||||
esp_err_t err = esp_efuse_batch_write_commit();
|
||||
|
||||
if (err == ESP_OK) {
|
||||
assert(ets_efuse_secure_boot_enabled());
|
||||
ESP_LOGI(TAG, "Secure boot permanently enabled");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@@ -41,8 +41,7 @@ void esp_flash_encryption_init_checks()
|
||||
#ifdef CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
|
||||
#ifdef CONFIG_SECURE_BOOT
|
||||
if (esp_secure_boot_enabled() && esp_flash_encryption_enabled()) {
|
||||
uint8_t flash_crypt_cnt_wr_dis = 0;
|
||||
esp_efuse_read_field_blob(WR_DIS_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
|
||||
bool flash_crypt_cnt_wr_dis = esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT);
|
||||
if (!flash_crypt_cnt_wr_dis) {
|
||||
uint8_t flash_crypt_cnt = 0;
|
||||
esp_efuse_read_field_blob(CRYPT_CNT, &flash_crypt_cnt, CRYPT_CNT[0]->bit_count);
|
||||
@@ -76,13 +75,7 @@ void esp_flash_encryption_init_checks()
|
||||
|
||||
void esp_flash_write_protect_crypt_cnt(void)
|
||||
{
|
||||
uint8_t flash_crypt_cnt_wr_dis = 0;
|
||||
|
||||
esp_efuse_read_field_blob(WR_DIS_CRYPT_CNT, &flash_crypt_cnt_wr_dis, 1);
|
||||
|
||||
if (!flash_crypt_cnt_wr_dis) {
|
||||
esp_efuse_write_field_cnt(WR_DIS_CRYPT_CNT, 1);
|
||||
}
|
||||
esp_efuse_write_field_bit(WR_DIS_CRYPT_CNT);
|
||||
}
|
||||
|
||||
esp_flash_enc_mode_t esp_get_flash_encryption_mode(void)
|
||||
@@ -101,27 +94,27 @@ esp_flash_enc_mode_t esp_get_flash_encryption_mode(void)
|
||||
|
||||
if (esp_flash_encryption_enabled()) {
|
||||
/* Check if FLASH CRYPT CNT is write protected */
|
||||
esp_efuse_read_field_blob(WR_DIS_CRYPT_CNT, &efuse_flash_crypt_cnt_wr_protected, 1);
|
||||
efuse_flash_crypt_cnt_wr_protected = esp_efuse_read_field_bit(WR_DIS_CRYPT_CNT);
|
||||
|
||||
if (efuse_flash_crypt_cnt_wr_protected) {
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_CACHE, &dis_dl_cache, 1);
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_ENCRYPT, &dis_dl_enc, 1);
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DISABLE_DL_DECRYPT, &dis_dl_dec, 1);
|
||||
dis_dl_cache = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_CACHE);
|
||||
dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_ENCRYPT);
|
||||
dis_dl_dec = esp_efuse_read_field_bit(ESP_EFUSE_DISABLE_DL_DECRYPT);
|
||||
/* Check if DISABLE_DL_DECRYPT, DISABLE_DL_ENCRYPT & DISABLE_DL_CACHE are set */
|
||||
if ( dis_dl_cache && dis_dl_enc && dis_dl_dec ) {
|
||||
mode = ESP_FLASH_ENC_MODE_RELEASE;
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT, &dis_dl_enc, 1);
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DIS_DOWNLOAD_ICACHE, &dis_dl_icache, 1);
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_DIS_DOWNLOAD_DCACHE, &dis_dl_dcache, 1);
|
||||
dis_dl_enc = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT);
|
||||
dis_dl_icache = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE);
|
||||
dis_dl_dcache = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_DCACHE);
|
||||
|
||||
if (dis_dl_enc && dis_dl_icache && dis_dl_dcache) {
|
||||
mode = ESP_FLASH_ENC_MODE_RELEASE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
mode = ESP_FLASH_ENC_MODE_DISABLED;
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include <assert.h>
|
||||
#include "esp_efuse_table.h"
|
||||
|
||||
// md5_digest_table 2e23344575b3d07f01ecb695294e9770
|
||||
// md5_digest_table 11b691b6fa8546a3862a7a876be5f758
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
@@ -87,20 +87,24 @@ static const esp_efuse_desc_t DISABLE_DL_CACHE[] = {
|
||||
{EFUSE_BLK0, 201, 1}, // Flash encrypt. Disable UART bootloader MMU cache. EFUSE_DISABLE_DL_CACHE.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t DISABLE_JTAG[] = {
|
||||
{EFUSE_BLK0, 198, 1}, // Flash encrypt. Disable JTAG. EFUSE_RD_DISABLE_JTAG.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t CONSOLE_DEBUG_DISABLE[] = {
|
||||
{EFUSE_BLK0, 194, 1}, // Flash encrypt. Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t FLASH_CRYPT_CNT[] = {
|
||||
{EFUSE_BLK0, 20, 7}, // Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t DISABLE_JTAG[] = {
|
||||
{EFUSE_BLK0, 198, 1}, // Disable JTAG. EFUSE_RD_DISABLE_JTAG.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t CONSOLE_DEBUG_DISABLE[] = {
|
||||
{EFUSE_BLK0, 194, 1}, // Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t UART_DOWNLOAD_DIS[] = {
|
||||
{EFUSE_BLK0, 27, 1}, // Disable UART download mode. Valid for ESP32 V3 and newer,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t WR_DIS_FLASH_CRYPT_CNT[] = {
|
||||
{EFUSE_BLK0, 2, 1}, // Flash encrypt. Write protection FLASH_CRYPT_CNT. EFUSE_WR_DIS_FLASH_CRYPT_CNT,
|
||||
{EFUSE_BLK0, 2, 1}, // Flash encrypt. Write protection FLASH_CRYPT_CNT,
|
||||
};
|
||||
|
||||
static const esp_efuse_desc_t WR_DIS_BLK1[] = {
|
||||
@@ -260,23 +264,28 @@ const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_CACHE[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_DISABLE_JTAG[] = {
|
||||
&DISABLE_JTAG[0], // Flash encrypt. Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_CONSOLE_DEBUG_DISABLE[] = {
|
||||
&CONSOLE_DEBUG_DISABLE[0], // Flash encrypt. Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_FLASH_CRYPT_CNT[] = {
|
||||
&FLASH_CRYPT_CNT[0], // Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_DISABLE_JTAG[] = {
|
||||
&DISABLE_JTAG[0], // Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_CONSOLE_DEBUG_DISABLE[] = {
|
||||
&CONSOLE_DEBUG_DISABLE[0], // Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_UART_DOWNLOAD_DIS[] = {
|
||||
&UART_DOWNLOAD_DIS[0], // Disable UART download mode. Valid for ESP32 V3 and newer
|
||||
NULL
|
||||
};
|
||||
|
||||
const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT[] = {
|
||||
&WR_DIS_FLASH_CRYPT_CNT[0], // Flash encrypt. Write protection FLASH_CRYPT_CNT. EFUSE_WR_DIS_FLASH_CRYPT_CNT
|
||||
&WR_DIS_FLASH_CRYPT_CNT[0], // Flash encrypt. Write protection FLASH_CRYPT_CNT
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@@ -39,13 +39,16 @@ ENCRYPT_CONFIG, EFUSE_BLK0, 188, 4, Flash encrypt. EFUSE_FLASH_C
|
||||
DISABLE_DL_ENCRYPT, EFUSE_BLK0, 199, 1, Flash encrypt. Disable UART bootloader encryption. EFUSE_DISABLE_DL_ENCRYPT.
|
||||
DISABLE_DL_DECRYPT, EFUSE_BLK0, 200, 1, Flash encrypt. Disable UART bootloader decryption. EFUSE_DISABLE_DL_DECRYPT.
|
||||
DISABLE_DL_CACHE, EFUSE_BLK0, 201, 1, Flash encrypt. Disable UART bootloader MMU cache. EFUSE_DISABLE_DL_CACHE.
|
||||
DISABLE_JTAG, EFUSE_BLK0, 198, 1, Flash encrypt. Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
CONSOLE_DEBUG_DISABLE, EFUSE_BLK0, 194, 1, Flash encrypt. Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
FLASH_CRYPT_CNT, EFUSE_BLK0, 20, 7, Flash encrypt. Flash encryption is enabled if this field has an odd number of bits set. EFUSE_FLASH_CRYPT_CNT.
|
||||
|
||||
# Misc Security #
|
||||
DISABLE_JTAG, EFUSE_BLK0, 198, 1, Disable JTAG. EFUSE_RD_DISABLE_JTAG.
|
||||
CONSOLE_DEBUG_DISABLE, EFUSE_BLK0, 194, 1, Disable ROM BASIC interpreter fallback. EFUSE_RD_CONSOLE_DEBUG_DISABLE.
|
||||
UART_DOWNLOAD_DIS, EFUSE_BLK0, 27, 1, Disable UART download mode. Valid for ESP32 V3 and newer, only.
|
||||
|
||||
# Write protection #
|
||||
####################
|
||||
WR_DIS_FLASH_CRYPT_CNT, EFUSE_BLK0, 2, 1, Flash encrypt. Write protection FLASH_CRYPT_CNT. EFUSE_WR_DIS_FLASH_CRYPT_CNT
|
||||
WR_DIS_FLASH_CRYPT_CNT, EFUSE_BLK0, 2, 1, Flash encrypt. Write protection FLASH_CRYPT_CNT, UART_DOWNLOAD_DIS. EFUSE_WR_DIS_FLASH_CRYPT_CNT
|
||||
WR_DIS_BLK1, EFUSE_BLK0, 7, 1, Flash encrypt. Write protection encryption key. EFUSE_WR_DIS_BLK1
|
||||
WR_DIS_BLK2, EFUSE_BLK0, 8, 1, Security boot. Write protection security key. EFUSE_WR_DIS_BLK2
|
||||
WR_DIS_BLK3, EFUSE_BLK0, 9, 1, Write protection for EFUSE_BLK3. EFUSE_WR_DIS_BLK3
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 87.
|
@@ -17,7 +17,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// md5_digest_table 2e23344575b3d07f01ecb695294e9770
|
||||
// md5_digest_table 11b691b6fa8546a3862a7a876be5f758
|
||||
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.
|
||||
// If you want to change some fields, you need to change esp_efuse_table.csv file
|
||||
// then run `efuse_common_table` or `efuse_custom_table` command it will generate this file.
|
||||
@@ -36,9 +36,10 @@ extern const esp_efuse_desc_t* ESP_EFUSE_ENCRYPT_CONFIG[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_ENCRYPT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_DECRYPT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_DL_CACHE[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CRYPT_CNT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_DISABLE_JTAG[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_CONSOLE_DEBUG_DISABLE[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_FLASH_CRYPT_CNT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_UART_DOWNLOAD_DIS[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK1[];
|
||||
extern const esp_efuse_desc_t* ESP_EFUSE_WR_DIS_BLK2[];
|
||||
|
@@ -21,6 +21,7 @@ extern "C" {
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "sdkconfig.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "esp32/esp_efuse.h"
|
||||
@@ -66,6 +67,23 @@ typedef struct esp_efuse_desc_s esp_efuse_desc_t;
|
||||
*/
|
||||
esp_err_t esp_efuse_read_field_blob(const esp_efuse_desc_t* field[], void* dst, size_t dst_size_bits);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read a single bit eFuse field as a boolean value.
|
||||
*
|
||||
* @note The value must exist and must be a single bit wide. If there is any possibility of an error
|
||||
* in the provided arguments, call esp_efuse_read_field_blob() and check the returned value instead.
|
||||
*
|
||||
* @note If assertions are enabled and the parameter is invalid, execution will abort
|
||||
*
|
||||
* @param[in] field A pointer to the structure describing the fields of efuse.
|
||||
* @return
|
||||
* - true: The field parameter is valid and the bit is set.
|
||||
* - false: The bit is not set, or the parameter is invalid and assertions are disabled.
|
||||
*
|
||||
*/
|
||||
bool esp_efuse_read_field_bit(const esp_efuse_desc_t *field[]);
|
||||
|
||||
/**
|
||||
* @brief Reads bits from EFUSE field and returns number of bits programmed as "1".
|
||||
*
|
||||
@@ -114,6 +132,23 @@ esp_err_t esp_efuse_write_field_blob(const esp_efuse_desc_t* field[], const void
|
||||
*/
|
||||
esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t* field[], size_t cnt);
|
||||
|
||||
/**
|
||||
* @brief Write a single bit eFuse field to 1
|
||||
*
|
||||
* For use with eFuse fields that are a single bit. This function will write the bit to value 1 if
|
||||
* it is not already set, or does nothing if the bit is already set.
|
||||
*
|
||||
* This is equivalent to calling esp_efuse_write_field_cnt() with the cnt parameter equal to 1,
|
||||
* except that it will return ESP_OK if the field is already set to 1.
|
||||
*
|
||||
* @param[in] field Pointer to the structure describing the efuse field.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: The operation was successfully completed, or the bit was already set to value 1.
|
||||
* - ESP_ERR_INVALID_ARG: Error in the passed arugments, including if the efuse field is not 1 bit wide.
|
||||
*/
|
||||
esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[]);
|
||||
|
||||
/**
|
||||
* @brief Sets a write protection for the whole block.
|
||||
*
|
||||
@@ -274,15 +309,48 @@ void esp_efuse_reset(void);
|
||||
* By default, if booting from flash fails the ESP32 will boot a
|
||||
* BASIC console in ROM.
|
||||
*
|
||||
* Call this function (from bootloader or app) to permanently
|
||||
* disable the console on this chip.
|
||||
*
|
||||
* Call this function (from bootloader or app) to permanently disable the console on this chip.
|
||||
*
|
||||
*/
|
||||
void esp_efuse_disable_basic_rom_console(void);
|
||||
#endif
|
||||
|
||||
|
||||
/* @brief Disable ROM Download Mode via eFuse
|
||||
*
|
||||
* Permanently disables the ROM Download Mode feature. Once disabled, if the SoC is booted with
|
||||
* strapping pins set for ROM Download Mode then an error is printed instead.
|
||||
*
|
||||
* @note Not all SoCs support this option. An error will be returned if called on an ESP32
|
||||
* with a silicon revision lower than 3, as these revisions do not support this option.
|
||||
*
|
||||
* @note If ROM Download Mode is already disabled, this function does nothing and returns success.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK If the eFuse was successfully burned, or had already been burned.
|
||||
* - ESP_ERR_NOT_SUPPORTED (ESP32 only) This SoC is not capable of disabling UART download mode
|
||||
* - ESP_ERR_INVALID_STATE (ESP32 only) This eFuse is write protected and cannot be written
|
||||
*/
|
||||
esp_err_t esp_efuse_disable_rom_download_mode(void);
|
||||
|
||||
#if SOC_SUPPORTS_SECURE_DL_MODE
|
||||
/* @brief Switch ROM Download Mode to Secure Download mode via eFuse
|
||||
*
|
||||
* Permanently enables Secure Download mode. This mode limits the use of ROM Download Mode functions
|
||||
* to simple flash read, write and erase operations, plus a command to return a summary of currently
|
||||
* enabled security features.
|
||||
*
|
||||
* @note If Secure Download mode is already enabled, this function does nothing and returns success.
|
||||
*
|
||||
* @note Disabling the ROM Download Mode also disables Secure Download Mode.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK If the eFuse was successfully burned, or had already been burned.
|
||||
* - ESP_ERR_INVALID_STATE ROM Download Mode has been disabled via eFuse, so Secure Download mode is unavailable.
|
||||
*/
|
||||
esp_err_t esp_efuse_enable_rom_secure_download_mode(void);
|
||||
#endif
|
||||
|
||||
/* @brief Write random data to efuse key block write registers
|
||||
*
|
||||
* @note Caller is responsible for ensuring efuse
|
||||
|
@@ -70,14 +70,33 @@ uint32_t esp_efuse_get_pkg_ver(void)
|
||||
// Disable BASIC ROM Console via efuse
|
||||
void esp_efuse_disable_basic_rom_console(void)
|
||||
{
|
||||
uint8_t console_debug_disable = 0;
|
||||
esp_efuse_read_field_blob(ESP_EFUSE_CONSOLE_DEBUG_DISABLE, &console_debug_disable, 1);
|
||||
if (console_debug_disable == 0) {
|
||||
if (!esp_efuse_read_field_bit(ESP_EFUSE_CONSOLE_DEBUG_DISABLE)) {
|
||||
esp_efuse_write_field_cnt(ESP_EFUSE_CONSOLE_DEBUG_DISABLE, 1);
|
||||
ESP_EARLY_LOGI(TAG, "Disable BASIC ROM Console fallback via efuse...");
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_disable_rom_download_mode(void)
|
||||
{
|
||||
#ifndef CONFIG_ESP32_REV_MIN_3
|
||||
/* Check if we support this revision at all */
|
||||
if(esp_efuse_get_chip_ver() < 3) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_UART_DOWNLOAD_DIS)) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* WR_DIS_FLASH_CRYPT_CNT also covers UART_DOWNLOAD_DIS on ESP32 */
|
||||
if(esp_efuse_read_field_bit(ESP_EFUSE_WR_DIS_FLASH_CRYPT_CNT)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
return esp_efuse_write_field_bit(ESP_EFUSE_UART_DOWNLOAD_DIS);
|
||||
}
|
||||
|
||||
void esp_efuse_write_random_key(uint32_t blk_wdata0_reg)
|
||||
{
|
||||
uint32_t buf[8];
|
||||
|
@@ -60,3 +60,17 @@ void esp_efuse_write_random_key(uint32_t blk_wdata0_reg)
|
||||
bzero(buf, sizeof(buf));
|
||||
bzero(raw, sizeof(raw));
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_disable_rom_download_mode(void)
|
||||
{
|
||||
return esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE);
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_enable_rom_secure_download_mode(void)
|
||||
{
|
||||
if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
|
||||
}
|
||||
|
||||
|
@@ -54,6 +54,14 @@ esp_err_t esp_efuse_read_field_blob(const esp_efuse_desc_t* field[], void* dst,
|
||||
return err;
|
||||
}
|
||||
|
||||
bool esp_efuse_read_field_bit(const esp_efuse_desc_t *field[])
|
||||
{
|
||||
uint8_t value = 0;
|
||||
esp_err_t err = esp_efuse_read_field_blob(field, &value, 1);
|
||||
assert(err == ESP_OK);
|
||||
return (err == ESP_OK) && value;
|
||||
}
|
||||
|
||||
// read number of bits programmed as "1" in the particular field
|
||||
esp_err_t esp_efuse_read_field_cnt(const esp_efuse_desc_t* field[], size_t* out_cnt)
|
||||
{
|
||||
@@ -131,6 +139,25 @@ esp_err_t esp_efuse_write_field_cnt(const esp_efuse_desc_t* field[], size_t cnt)
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_write_field_bit(const esp_efuse_desc_t* field[])
|
||||
{
|
||||
esp_err_t err;
|
||||
uint8_t existing = 0;
|
||||
const uint8_t one = 1;
|
||||
|
||||
if (field == NULL || field[0]->bit_count != 1) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Check existing value. esp_efuse_write_field_blob() also checks this, but will log an error */
|
||||
err = esp_efuse_read_field_blob(field, &existing, 1);
|
||||
if (err != ESP_OK || existing) {
|
||||
return err; // Error reading, or the bit is already written and we can no-op this
|
||||
}
|
||||
|
||||
return esp_efuse_write_field_blob(field, &one, 1);
|
||||
}
|
||||
|
||||
// get the length of the field in bits
|
||||
int esp_efuse_get_field_size(const esp_efuse_desc_t* field[])
|
||||
{
|
||||
|
@@ -267,6 +267,32 @@ TEST_CASE("efuse test write_field_cnt", "[efuse]")
|
||||
test_write_cnt();
|
||||
}
|
||||
|
||||
TEST_CASE("efuse test single bit functions", "[efuse]")
|
||||
{
|
||||
esp_efuse_utility_erase_virt_blocks();
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
|
||||
uint8_t test_bit;
|
||||
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
|
||||
TEST_ASSERT_EQUAL_HEX8(0, test_bit);
|
||||
|
||||
test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
|
||||
TEST_ASSERT_EQUAL_HEX8(0, test_bit);
|
||||
|
||||
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
|
||||
TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
|
||||
TEST_ASSERT_EQUAL_HEX8(1, test_bit);
|
||||
|
||||
test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
|
||||
TEST_ASSERT_EQUAL_HEX8(1, test_bit);
|
||||
|
||||
// Can write the bit again and it's a no-op
|
||||
TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
|
||||
TEST_ASSERT_EQUAL_HEX8(1, esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1));
|
||||
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
}
|
||||
|
||||
void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
|
||||
{
|
||||
if ((num_used_bits + count_bits) % 8) {
|
||||
|
@@ -366,6 +366,10 @@ void start_cpu0_default(void)
|
||||
#if CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE
|
||||
esp_efuse_disable_basic_rom_console();
|
||||
#endif
|
||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
esp_efuse_disable_rom_download_mode();
|
||||
#endif
|
||||
|
||||
rtc_gpio_force_hold_dis_all();
|
||||
|
||||
#ifdef CONFIG_VFS_SUPPORT_IO
|
||||
|
@@ -292,6 +292,16 @@ void start_cpu0_default(void)
|
||||
#if CONFIG_ESP32S2_BROWNOUT_DET
|
||||
esp_brownout_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_SECURE_DISABLE_ROM_DL_MODE
|
||||
err = esp_efuse_disable_rom_download_mode();
|
||||
assert(err == ESP_OK && "Failed to disable ROM download mode");
|
||||
#endif
|
||||
#if CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
err = esp_efuse_enable_rom_secure_download_mode();
|
||||
assert(err == ESP_OK && "Failed to enable Secure Download mode");
|
||||
#endif
|
||||
|
||||
rtc_gpio_force_hold_dis_all();
|
||||
|
||||
#ifdef CONFIG_VFS_SUPPORT_IO
|
||||
|
@@ -27,7 +27,11 @@ if(NOT BOOTLOADER_BUILD)
|
||||
set(ESPTOOLPY_BEFORE "${CONFIG_ESPTOOLPY_BEFORE}")
|
||||
set(ESPTOOLPY_AFTER "${CONFIG_ESPTOOLPY_AFTER}")
|
||||
set(ESPTOOLPY_CHIP "${target}")
|
||||
set(ESPTOOLPY_WITH_STUB TRUE)
|
||||
if(CONFIG_ESPTOOLPY_WITH_STUB)
|
||||
set(ESPTOOLPY_WITH_STUB true)
|
||||
else()
|
||||
set(ESPTOOLPY_WITH_STUB false)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SECURE_BOOT OR CONFIG_SECURE_FLASH_ENC_ENABLED)
|
||||
# If security enabled then override post flash option
|
||||
|
@@ -54,6 +54,12 @@ menu "Serial flasher config"
|
||||
decompress it on the fly before flashing it. For most payloads, this should result in a
|
||||
speed increase.
|
||||
|
||||
config ESPTOOLPY_WITH_STUB
|
||||
# Only real reason to disable this is when ESP32-S2 Secure Download Mode is set
|
||||
bool
|
||||
default "y"
|
||||
depends on !SECURE_ENABLE_SECURE_ROM_DL_MODE
|
||||
|
||||
choice ESPTOOLPY_FLASHMODE
|
||||
prompt "Flash SPI mode"
|
||||
default ESPTOOLPY_FLASHMODE_DIO
|
||||
|
Submodule components/esptool_py/esptool updated: 988b9a2441...5eada56341
@@ -16,7 +16,7 @@
|
||||
"extra_esptool_args" : {
|
||||
"after" : "${ESPTOOLPY_AFTER}",
|
||||
"before" : "${ESPTOOLPY_BEFORE}",
|
||||
"stub" : "${ESPTOOLPY_WITH_STUB}",
|
||||
"stub" : ${ESPTOOLPY_WITH_STUB},
|
||||
"chip" : "${ESPTOOLPY_CHIP}"
|
||||
}
|
||||
}
|
||||
|
@@ -153,6 +153,9 @@ else()
|
||||
list(APPEND esptool_flash_main_args "--after=${CONFIG_ESPTOOLPY_AFTER}")
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_ESPTOOLPY_WITH_STUB)
|
||||
list(APPEND esptool_flash_main_args "--no-stub")
|
||||
endif()
|
||||
|
||||
idf_component_set_property(esptool_py FLASH_ARGS "${esptool_flash_main_args}")
|
||||
idf_component_set_property(esptool_py FLASH_SUB_ARGS "${ESPTOOLPY_FLASH_OPTIONS}")
|
||||
|
@@ -5,4 +5,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define SOC_CPU_CORES_NUM 1
|
||||
#define SOC_CPU_CORES_NUM 1
|
||||
|
||||
#define SOC_SUPPORTS_SECURE_DL_MODE 1
|
||||
|
Reference in New Issue
Block a user