You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/01/01 12:37:50 UTC

[incubator-nuttx] 01/04: esp32s2/esp32c3: Build MCUboot bootloader with Flash Encryption support

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 9e5e60ba4893b22f6bc6289a734415c365712461
Author: Gustavo Henrique Nihei <gu...@espressif.com>
AuthorDate: Thu Dec 30 11:58:24 2021 -0300

    esp32s2/esp32c3: Build MCUboot bootloader with Flash Encryption support
---
 arch/risc-v/src/esp32c3/Bootloader.mk    |  7 +++
 arch/risc-v/src/esp32c3/Kconfig          |  2 +
 arch/risc-v/src/esp32c3/Kconfig.security | 94 ++++++++++++++++++++++++++++++--
 arch/xtensa/src/esp32/Kconfig.security   |  4 +-
 arch/xtensa/src/esp32s2/Bootloader.mk    |  7 +++
 arch/xtensa/src/esp32s2/Kconfig          | 10 ++++
 arch/xtensa/src/esp32s2/Kconfig.security | 94 ++++++++++++++++++++++++++++++--
 tools/esp32s2/Config.mk                  |  2 +-
 8 files changed, 209 insertions(+), 11 deletions(-)

diff --git a/arch/risc-v/src/esp32c3/Bootloader.mk b/arch/risc-v/src/esp32c3/Bootloader.mk
index 5211259..ba39945 100644
--- a/arch/risc-v/src/esp32c3/Bootloader.mk
+++ b/arch/risc-v/src/esp32c3/Bootloader.mk
@@ -78,7 +78,14 @@ ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
 		$(if $(CONFIG_ESP32C3_SECURE_BOOT_ALLOW_JTAG),$(call cfg_en,CONFIG_SECURE_BOOT_ALLOW_JTAG)) \
 		$(if $(CONFIG_ESP32C3_SECURE_BOOT_ALLOW_EFUSE_RD_DIS),$(call cfg_en,CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)) \
 		$(if $(CONFIG_ESP32C3_SECURE_DISABLE_ROM_DL_MODE),$(call cfg_en,CONFIG_SECURE_DISABLE_ROM_DL_MODE)) \
+		$(if $(CONFIG_ESP32C3_SECURE_ENABLE_SECURE_ROM_DL_MODE),$(call cfg_en,CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE)) \
 		$(if $(CONFIG_ESP32C3_SECURE_INSECURE_ALLOW_DL_MODE),$(call cfg_en,CONFIG_SECURE_INSECURE_ALLOW_DL_MODE)) \
+		$(if $(CONFIG_ESP32C3_SECURE_FLASH_ENC_ENABLED),$(call cfg_en,CONFIG_SECURE_FLASH_ENC_ENABLED)) \
+		$(if $(CONFIG_ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT),$(call cfg_en,CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)) \
+		$(if $(CONFIG_ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_RELEASE),$(call cfg_en,CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE)) \
+		$(if $(CONFIG_ESP32C3_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC),$(call cfg_en,CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC)) \
+		$(if $(CONFIG_ESP32C3_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE),$(call cfg_en,CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE)) \
+		$(if $(CONFIG_ESP32C3_SECURE_FLASH_REQUIRE_ALREADY_ENABLED),$(call cfg_en,CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED)) \
 		$(call cfg_val,CONFIG_ESP_BOOTLOADER_SIZE,0xF000) \
 		$(call cfg_val,CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS,$(CONFIG_ESP32C3_OTA_PRIMARY_SLOT_OFFSET)) \
 		$(call cfg_val,CONFIG_ESP_APPLICATION_SIZE,$(CONFIG_ESP32C3_OTA_SLOT_SIZE)) \
diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig
index a8356bb..7b3cdd1 100644
--- a/arch/risc-v/src/esp32c3/Kconfig
+++ b/arch/risc-v/src/esp32c3/Kconfig
@@ -77,6 +77,8 @@ config ESP32C3_ESPTOOLPY_NO_STUB
 		The flasher tool sends a precompiled download stub first by default.
 		That stub allows things like compressed downloads and more.
 		Usually you should not need to disable that feature.
+		It is only required to be disabled in certain scenarios when either
+		Secure Boot V2 or Flash Encryption is enabled.
 
 config ESP32C3_FLASH_DETECT
 	bool "Auto-detect FLASH size"
diff --git a/arch/risc-v/src/esp32c3/Kconfig.security b/arch/risc-v/src/esp32c3/Kconfig.security
index d4876bd..250e33c 100644
--- a/arch/risc-v/src/esp32c3/Kconfig.security
+++ b/arch/risc-v/src/esp32c3/Kconfig.security
@@ -21,7 +21,7 @@ config ESP32C3_SECURE_BOOT
 
 if ESP32C3_SECURE_BOOT
 
-comment "Secure Boot support requires building bootloader from source (ESP32C3_BOOTLOADER_BUILD_FROM_SOURCE)"
+comment "Secure Boot support requires building the bootloader from source (ESP32C3_BOOTLOADER_BUILD_FROM_SOURCE)"
 	depends on !ESP32C3_BOOTLOADER_BUILD_FROM_SOURCE
 
 config ESP32C3_SECURE_BOOT_BUILD_SIGNED_BINARIES
@@ -101,8 +101,54 @@ config ESP32C3_SECURE_BOOT_INSECURE
 
 endif # ESP32C3_SECURE_BOOT
 
+comment "Flash Encryption"
+
+config ESP32C3_SECURE_FLASH_ENC_ENABLED
+	bool "Enable Flash Encryption on boot (READ HELP FIRST)"
+	default n
+	depends on ESP32C3_APP_FORMAT_MCUBOOT
+	---help---
+		If this option is set, flash contents will be encrypted by the bootloader on first boot.
+
+		Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
+		system is complicated and not always possible.
+
+		Read https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/security/flash-encryption.html
+		before enabling.
+
+if ESP32C3_SECURE_FLASH_ENC_ENABLED
+
+comment "Flash Encryption support requires building the bootloader from source (ESP32C3_BOOTLOADER_BUILD_FROM_SOURCE)"
+	depends on !ESP32C3_BOOTLOADER_BUILD_FROM_SOURCE
+
+choice ESP32C3_SECURE_FLASH_ENCRYPTION_MODE
+	bool "Enable usage mode"
+	default ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		By default, Development mode is enabled which allows ROM download mode to perform Flash Encryption
+		operations (plaintext is sent to the device, and it encrypts it internally and writes ciphertext
+		to flash). This mode is not secure, it's possible for an attacker to write their own chosen plaintext
+		to flash.
+
+		Release mode should always be selected for production or manufacturing. Once enabled it's no longer
+		possible for the device in ROM Download Mode to use the Flash Encryption hardware.
+
+		Refer to the Flash Encryption section of the ESP-IDF Programmer's Guide for details:
+		https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/security/flash-encryption.html#flash-encryption-configuration
+
+	config ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+		bool "Development (NOT SECURE)"
+		select ESP32C3_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
+
+	config ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
+		bool "Release"
+
+endchoice
+
+endif # ESP32C3_SECURE_FLASH_ENC_ENABLED
+
 menu "Potentially insecure options"
-	visible if ESP32C3_SECURE_BOOT_INSECURE
+	visible if ESP32C3_SECURE_BOOT_INSECURE || ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
 
 	# NOTE: Options in this menu NEED to have ESP32C3_SECURE_BOOT_INSECURE
 	# and/or ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT in "depends on", as the menu
@@ -113,7 +159,7 @@ menu "Potentially insecure options"
 config ESP32C3_SECURE_BOOT_ALLOW_JTAG
 	bool "Allow JTAG Debugging"
 	default n
-	depends on ESP32C3_SECURE_BOOT_INSECURE
+	depends on ESP32C3_SECURE_BOOT_INSECURE || ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
 	---help---
 		If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot
 		when either Secure Boot or Flash Encryption is enabled.
@@ -143,12 +189,51 @@ config ESP32C3_SECURE_BOOT_ALLOW_EFUSE_RD_DIS
 		then it is __NOT__ possible to read/write efuses using espefuse.py utility.
 		However, efuse can be read/written from the application.
 
+config ESP32C3_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
+	bool "Leave UART bootloader encryption enabled"
+	default n
+	depends on ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		If not set (default), the bootloader will permanently disable UART bootloader encryption access on
+		first boot. If set, the UART bootloader will still be able to access hardware encryption.
+
+		It is recommended to only set this option in testing environments.
+
+config ESP32C3_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
+	bool "Leave UART bootloader flash cache enabled"
+	default n
+	depends on ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		If not set (default), the bootloader will permanently disable UART bootloader flash cache access on
+		first boot. If set, the UART bootloader will still be able to access the flash cache.
+
+		Only set this option in testing environments.
+
+config ESP32C3_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+	bool "Require Flash Encryption to be already enabled"
+	default n
+	depends on ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		If not set (default), and Flash Encryption is not yet enabled in eFuses, the 2nd stage bootloader
+		will enable Flash Encryption: generate the Flash Encryption key and program eFuses.
+		If this option is set, and Flash Encryption is not yet enabled, the bootloader will error out and
+		reboot.
+		If Flash Encryption is enabled in eFuses, this option does not change the bootloader behavior.
+
+		Only use this option in testing environments, to avoid accidentally enabling Flash Encryption on
+		the wrong device. The device needs to have Flash Encryption already enabled using espefuse.py.
+
 endmenu # Potentially insecure options
 
+config ESP32C3_SECURE_ROM_DL_MODE_ENABLED
+	bool
+	default y if !ESP32C3_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+
 choice ESP32C3_SECURE_UART_ROM_DL_MODE
 	bool "UART ROM download mode"
+	default ESP32C3_SECURE_ENABLE_SECURE_ROM_DL_MODE if ESP32C3_SECURE_ROM_DL_MODE_ENABLED
 	default ESP32C3_SECURE_INSECURE_ALLOW_DL_MODE
-	depends on ESP32C3_SECURE_BOOT
+	depends on ESP32C3_SECURE_BOOT || ESP32C3_SECURE_FLASH_ENC_ENABLED
 
 	config ESP32C3_SECURE_DISABLE_ROM_DL_MODE
 		bool "Permanently disabled (recommended)"
@@ -167,6 +252,7 @@ choice ESP32C3_SECURE_UART_ROM_DL_MODE
 
 	config ESP32C3_SECURE_ENABLE_SECURE_ROM_DL_MODE
 		bool "Permanently switch to Secure mode (recommended)"
+		select ESP32C3_ESPTOOLPY_NO_STUB
 		---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
diff --git a/arch/xtensa/src/esp32/Kconfig.security b/arch/xtensa/src/esp32/Kconfig.security
index b79b2f50..1422b23 100644
--- a/arch/xtensa/src/esp32/Kconfig.security
+++ b/arch/xtensa/src/esp32/Kconfig.security
@@ -20,7 +20,7 @@ config ESP32_SECURE_BOOT
 
 if ESP32_SECURE_BOOT
 
-comment "Secure Boot support requires building bootloader from source (ESP32_BOOTLOADER_BUILD_FROM_SOURCE)"
+comment "Secure Boot support requires building the bootloader from source (ESP32_BOOTLOADER_BUILD_FROM_SOURCE)"
 	depends on !ESP32_BOOTLOADER_BUILD_FROM_SOURCE
 
 config ESP32_SECURE_BOOT_BUILD_SIGNED_BINARIES
@@ -117,7 +117,7 @@ config ESP32_SECURE_FLASH_ENC_ENABLED
 
 if ESP32_SECURE_FLASH_ENC_ENABLED
 
-comment "Flash Encryption support requires building bootloader from source (ESP32_BOOTLOADER_BUILD_FROM_SOURCE)"
+comment "Flash Encryption support requires building the bootloader from source (ESP32_BOOTLOADER_BUILD_FROM_SOURCE)"
 	depends on !ESP32_BOOTLOADER_BUILD_FROM_SOURCE
 
 choice ESP32_SECURE_FLASH_ENCRYPTION_MODE
diff --git a/arch/xtensa/src/esp32s2/Bootloader.mk b/arch/xtensa/src/esp32s2/Bootloader.mk
index 3ad1fc0..54248df 100644
--- a/arch/xtensa/src/esp32s2/Bootloader.mk
+++ b/arch/xtensa/src/esp32s2/Bootloader.mk
@@ -78,7 +78,14 @@ ifeq ($(CONFIG_ESP32S2_APP_FORMAT_MCUBOOT),y)
 		$(if $(CONFIG_ESP32S2_SECURE_BOOT_ALLOW_JTAG),$(call cfg_en,CONFIG_SECURE_BOOT_ALLOW_JTAG)) \
 		$(if $(CONFIG_ESP32S2_SECURE_BOOT_ALLOW_EFUSE_RD_DIS),$(call cfg_en,CONFIG_SECURE_BOOT_V2_ALLOW_EFUSE_RD_DIS)) \
 		$(if $(CONFIG_ESP32S2_SECURE_DISABLE_ROM_DL_MODE),$(call cfg_en,CONFIG_SECURE_DISABLE_ROM_DL_MODE)) \
+		$(if $(CONFIG_ESP32S2_SECURE_ENABLE_SECURE_ROM_DL_MODE),$(call cfg_en,CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE)) \
 		$(if $(CONFIG_ESP32S2_SECURE_INSECURE_ALLOW_DL_MODE),$(call cfg_en,CONFIG_SECURE_INSECURE_ALLOW_DL_MODE)) \
+		$(if $(CONFIG_ESP32S2_SECURE_FLASH_ENC_ENABLED),$(call cfg_en,CONFIG_SECURE_FLASH_ENC_ENABLED)) \
+		$(if $(CONFIG_ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT),$(call cfg_en,CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)) \
+		$(if $(CONFIG_ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_RELEASE),$(call cfg_en,CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE)) \
+		$(if $(CONFIG_ESP32S2_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC),$(call cfg_en,CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC)) \
+		$(if $(CONFIG_ESP32S2_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE),$(call cfg_en,CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE)) \
+		$(if $(CONFIG_ESP32S2_SECURE_FLASH_REQUIRE_ALREADY_ENABLED),$(call cfg_en,CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED)) \
 		$(call cfg_val,CONFIG_ESP_BOOTLOADER_SIZE,0xF000) \
 		$(call cfg_val,CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS,$(CONFIG_ESP32S2_OTA_PRIMARY_SLOT_OFFSET)) \
 		$(call cfg_val,CONFIG_ESP_APPLICATION_SIZE,$(CONFIG_ESP32S2_OTA_SLOT_SIZE)) \
diff --git a/arch/xtensa/src/esp32s2/Kconfig b/arch/xtensa/src/esp32s2/Kconfig
index da2c9cb..23152d1 100644
--- a/arch/xtensa/src/esp32s2/Kconfig
+++ b/arch/xtensa/src/esp32s2/Kconfig
@@ -81,6 +81,16 @@ config ESP32S2_FLASH_16M
 	bool
 	default n
 
+config ESP32S2_ESPTOOLPY_NO_STUB
+	bool "Disable download stub"
+	default n
+	---help---
+		The flasher tool sends a precompiled download stub first by default.
+		That stub allows things like compressed downloads and more.
+		Usually you should not need to disable that feature.
+		It is only required to be disabled in certain scenarios when either
+		Secure Boot V2 or Flash Encryption is enabled.
+
 config ESP32S2_FLASH_DETECT
 	bool "Auto-detect FLASH size"
 	default y
diff --git a/arch/xtensa/src/esp32s2/Kconfig.security b/arch/xtensa/src/esp32s2/Kconfig.security
index f9b1297..f03c975 100644
--- a/arch/xtensa/src/esp32s2/Kconfig.security
+++ b/arch/xtensa/src/esp32s2/Kconfig.security
@@ -20,7 +20,7 @@ config ESP32S2_SECURE_BOOT
 
 if ESP32S2_SECURE_BOOT
 
-comment "Secure Boot support requires building bootloader from source (ESP32S2_BOOTLOADER_BUILD_FROM_SOURCE)"
+comment "Secure Boot support requires building the bootloader from source (ESP32S2_BOOTLOADER_BUILD_FROM_SOURCE)"
 	depends on !ESP32S2_BOOTLOADER_BUILD_FROM_SOURCE
 
 config ESP32S2_SECURE_BOOT_BUILD_SIGNED_BINARIES
@@ -100,8 +100,54 @@ config ESP32S2_SECURE_BOOT_INSECURE
 
 endif # ESP32S2_SECURE_BOOT
 
+comment "Flash Encryption"
+
+config ESP32S2_SECURE_FLASH_ENC_ENABLED
+	bool "Enable Flash Encryption on boot (READ HELP FIRST)"
+	default n
+	depends on ESP32S2_APP_FORMAT_MCUBOOT
+	---help---
+		If this option is set, flash contents will be encrypted by the bootloader on first boot.
+
+		Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
+		system is complicated and not always possible.
+
+		Read https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/security/flash-encryption.html
+		before enabling.
+
+if ESP32S2_SECURE_FLASH_ENC_ENABLED
+
+comment "Flash Encryption support requires building the bootloader from source (ESP32S2_BOOTLOADER_BUILD_FROM_SOURCE)"
+	depends on !ESP32S2_BOOTLOADER_BUILD_FROM_SOURCE
+
+choice ESP32S2_SECURE_FLASH_ENCRYPTION_MODE
+	bool "Enable usage mode"
+	default ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		By default, Development mode is enabled which allows ROM download mode to perform Flash Encryption
+		operations (plaintext is sent to the device, and it encrypts it internally and writes ciphertext
+		to flash). This mode is not secure, it's possible for an attacker to write their own chosen plaintext
+		to flash.
+
+		Release mode should always be selected for production or manufacturing. Once enabled it's no longer
+		possible for the device in ROM Download Mode to use the Flash Encryption hardware.
+
+		Refer to the Flash Encryption section of the ESP-IDF Programmer's Guide for details:
+		https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/security/flash-encryption.html#flash-encryption-configuration
+
+	config ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+		bool "Development (NOT SECURE)"
+		select ESP32S2_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
+
+	config ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_RELEASE
+		bool "Release"
+
+endchoice
+
+endif # ESP32S2_SECURE_FLASH_ENC_ENABLED
+
 menu "Potentially insecure options"
-	visible if ESP32S2_SECURE_BOOT_INSECURE
+	visible if ESP32S2_SECURE_BOOT_INSECURE || ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
 
 	# NOTE: Options in this menu NEED to have ESP32S2_SECURE_BOOT_INSECURE
 	# and/or ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT in "depends on", as the menu
@@ -112,7 +158,7 @@ menu "Potentially insecure options"
 config ESP32S2_SECURE_BOOT_ALLOW_JTAG
 	bool "Allow JTAG Debugging"
 	default n
-	depends on ESP32S2_SECURE_BOOT_INSECURE
+	depends on ESP32S2_SECURE_BOOT_INSECURE || ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
 	---help---
 		If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot
 		when either Secure Boot or Flash Encryption is enabled.
@@ -142,12 +188,51 @@ config ESP32S2_SECURE_BOOT_ALLOW_EFUSE_RD_DIS
 		then it is __NOT__ possible to read/write efuses using espefuse.py utility.
 		However, efuse can be read/written from the application.
 
+config ESP32S2_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC
+	bool "Leave UART bootloader encryption enabled"
+	default n
+	depends on ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		If not set (default), the bootloader will permanently disable UART bootloader encryption access on
+		first boot. If set, the UART bootloader will still be able to access hardware encryption.
+
+		It is recommended to only set this option in testing environments.
+
+config ESP32S2_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE
+	bool "Leave UART bootloader flash cache enabled"
+	default n
+	depends on ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		If not set (default), the bootloader will permanently disable UART bootloader flash cache access on
+		first boot. If set, the UART bootloader will still be able to access the flash cache.
+
+		Only set this option in testing environments.
+
+config ESP32S2_SECURE_FLASH_REQUIRE_ALREADY_ENABLED
+	bool "Require Flash Encryption to be already enabled"
+	default n
+	depends on ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+	---help---
+		If not set (default), and Flash Encryption is not yet enabled in eFuses, the 2nd stage bootloader
+		will enable Flash Encryption: generate the Flash Encryption key and program eFuses.
+		If this option is set, and Flash Encryption is not yet enabled, the bootloader will error out and
+		reboot.
+		If Flash Encryption is enabled in eFuses, this option does not change the bootloader behavior.
+
+		Only use this option in testing environments, to avoid accidentally enabling Flash Encryption on
+		the wrong device. The device needs to have Flash Encryption already enabled using espefuse.py.
+
 endmenu # Potentially insecure options
 
+config ESP32S2_SECURE_ROM_DL_MODE_ENABLED
+	bool
+	default y if !ESP32S2_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT
+
 choice ESP32S2_SECURE_UART_ROM_DL_MODE
 	bool "UART ROM download mode"
+	default ESP32S2_SECURE_ENABLE_SECURE_ROM_DL_MODE if ESP32S2_SECURE_ROM_DL_MODE_ENABLED
 	default ESP32S2_SECURE_INSECURE_ALLOW_DL_MODE
-	depends on ESP32S2_SECURE_BOOT
+	depends on ESP32S2_SECURE_BOOT || ESP32S2_SECURE_FLASH_ENC_ENABLED
 
 	config ESP32S2_SECURE_DISABLE_ROM_DL_MODE
 		bool "Permanently disabled (recommended)"
@@ -166,6 +251,7 @@ choice ESP32S2_SECURE_UART_ROM_DL_MODE
 
 	config ESP32S2_SECURE_ENABLE_SECURE_ROM_DL_MODE
 		bool "Permanently switch to Secure mode (recommended)"
+		select ESP32S2_ESPTOOLPY_NO_STUB
 		---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
diff --git a/tools/esp32s2/Config.mk b/tools/esp32s2/Config.mk
index ec56206..8c24c47 100644
--- a/tools/esp32s2/Config.mk
+++ b/tools/esp32s2/Config.mk
@@ -253,7 +253,7 @@ define FLASH
 		echo "USAGE: make flash ESPTOOL_PORT=<port> [ ESPTOOL_BAUD=<baud> ] [ ESPTOOL_BINDIR=<dir> ]"; \
 		exit 1; \
 	fi
-	$(eval ESPTOOL_OPTS := -c esp32s2 -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) $(ESPTOOL_RESET_OPTS))
+	$(eval ESPTOOL_OPTS := -c esp32s2 -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) $(ESPTOOL_RESET_OPTS) $(if $(CONFIG_ESP32S2_ESPTOOLPY_NO_STUB),--no-stub))
 	esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS)
 
 	$(if $(CONFIG_ESP32S2_SECURE_BOOT),$(call HELP_FLASH_BOOTLOADER))