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 1c8e84b341635b0930798437a30eae8287f139b6
Author: Gustavo Henrique Nihei <[email protected]>
AuthorDate: Fri Nov 19 18:02:22 2021 -0300

    risc-v/esp32c3: Add Secure Boot support on top of MCUboot
    
    Signed-off-by: Gustavo Henrique Nihei <[email protected]>
---
 arch/risc-v/src/esp32c3/Bootloader.mk    | 138 ++++++++++++++------
 arch/risc-v/src/esp32c3/Kconfig          |  10 ++
 arch/risc-v/src/esp32c3/Kconfig.security | 212 +++++++++++++++++++++++++++++++
 tools/esp32c3/Config.mk                  | 124 ++++++++++++++----
 4 files changed, 416 insertions(+), 68 deletions(-)

diff --git a/arch/risc-v/src/esp32c3/Bootloader.mk 
b/arch/risc-v/src/esp32c3/Bootloader.mk
index 580221e..0a4a853 100644
--- a/arch/risc-v/src/esp32c3/Bootloader.mk
+++ b/arch/risc-v/src/esp32c3/Bootloader.mk
@@ -31,66 +31,124 @@ BOOTLOADER_CONFIG  = $(CHIPDIR)/bootloader.conf
 $(BOOTLOADER_SRCDIR):
        $(Q) git clone $(BOOTLOADER_URL) $(BOOTLOADER_SRCDIR) -b 
$(BOOTLOADER_VERSION)
 
+# Helpers for creating the configuration file
+
+cfg_en  = echo "$(1)=$(if $(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),1,y)";
+cfg_val = echo "$(1)=$(2)";
+
+# Commands for colored and formatted output
+
+RED    = \033[1;31m
+YELLOW = \033[1;33m
+BOLD   = \033[1m
+RST    = \033[0m
+
 $(BOOTLOADER_CONFIG): $(TOPDIR)/.config
+ifeq ($(CONFIG_ESP32C3_SECURE_BOOT),y)
+       $(Q) if [ -z "$(ESPSEC_KEYDIR)" ]; then \
+               echo ""; \
+               echo "$(RED)bootloader error:$(RST) Missing argument for secure 
boot keys directory."; \
+               echo "USAGE: make bootloader ESPSEC_KEYDIR=<dir>"; \
+               echo ""; \
+               exit 1; \
+       fi
+endif
        $(Q) echo "Creating Bootloader configuration"
-       $(Q) {                                                                  
                              \
-               [ "$(CONFIG_ESP32C3_FLASH_2M)"        = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_4M)"        = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_8M)"        = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_16M)"       = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y";        \
-               [ "$(CONFIG_ESP32C3_FLASH_MODE_DIO)"  = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHMODE_DIO=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_MODE_DOUT)" = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHMODE_DOUT=y";        \
-               [ "$(CONFIG_ESP32C3_FLASH_MODE_QIO)"  = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHMODE_QIO=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_MODE_QOUT)" = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHMODE_QOUT=y";        \
-               [ "$(CONFIG_ESP32C3_FLASH_FREQ_80M)"  = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHFREQ_80M=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_FREQ_40M)"  = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHFREQ_40M=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_FREQ_26M)"  = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHFREQ_26M=y";         \
-               [ "$(CONFIG_ESP32C3_FLASH_FREQ_20M)"  = "y" ] && echo 
"CONFIG_ESPTOOLPY_FLASHFREQ_20M=y";         \
-               true;                                                           
                                  \
+       $(Q) { \
+               $(if $(CONFIG_ESP32C3_FLASH_2M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHSIZE_2MB)) \
+               $(if $(CONFIG_ESP32C3_FLASH_4M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHSIZE_4MB)) \
+               $(if $(CONFIG_ESP32C3_FLASH_8M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHSIZE_8MB)) \
+               $(if $(CONFIG_ESP32C3_FLASH_16M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHSIZE_16MB)) \
+               $(if $(CONFIG_ESP32C3_FLASH_MODE_DIO),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHMODE_DIO)) \
+               $(if $(CONFIG_ESP32C3_FLASH_MODE_DOUT),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHMODE_DOUT)) \
+               $(if $(CONFIG_ESP32C3_FLASH_MODE_QIO),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHMODE_QIO)) \
+               $(if $(CONFIG_ESP32C3_FLASH_MODE_QOUT),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHMODE_QOUT)) \
+               $(if $(CONFIG_ESP32C3_FLASH_FREQ_80M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_80M)) \
+               $(if $(CONFIG_ESP32C3_FLASH_FREQ_40M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_40M)) \
+               $(if $(CONFIG_ESP32C3_FLASH_FREQ_26M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_26M)) \
+               $(if $(CONFIG_ESP32C3_FLASH_FREQ_20M),$(call 
cfg_en,CONFIG_ESPTOOLPY_FLASHFREQ_20M)) \
        } > $(BOOTLOADER_CONFIG)
 ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
-       $(Q) {                                                                  
                              \
-               echo "CONFIG_ESP_BOOTLOADER_SIZE=0xF000";                       
                                  \
-               echo 
"CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS=$(CONFIG_ESP32C3_OTA_PRIMARY_SLOT_OFFSET)";
    \
-               echo 
"CONFIG_ESP_APPLICATION_SIZE=$(CONFIG_ESP32C3_OTA_SLOT_SIZE)";                  
             \
-               echo 
"CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS=$(CONFIG_ESP32C3_OTA_SECONDARY_SLOT_OFFSET)";\
-               echo "CONFIG_ESP_MCUBOOT_WDT_ENABLE=y";                         
                                  \
-               echo 
"CONFIG_ESP_SCRATCH_OFFSET=$(CONFIG_ESP32C3_OTA_SCRATCH_OFFSET)";               
             \
-               echo 
"CONFIG_ESP_SCRATCH_SIZE=$(CONFIG_ESP32C3_OTA_SCRATCH_SIZE)";                   
             \
+       $(Q) { \
+               $(if $(CONFIG_ESP32C3_SECURE_BOOT),$(call 
cfg_en,CONFIG_SECURE_BOOT)$(call cfg_en,CONFIG_SECURE_BOOT_V2_ENABLED)$(call 
cfg_val,CONFIG_ESP_SIGN_KEY_FILE,$(abspath $(TOPDIR)/$(ESPSEC_KEYDIR)/$(subst 
",,$(CONFIG_ESP32C3_SECURE_BOOT_APP_SIGNING_KEY))))) \
+               $(if 
$(CONFIG_ESP32C3_SECURE_SIGNED_APPS_SCHEME_RSA_2048),$(call 
cfg_en,CONFIG_ESP_USE_MBEDTLS)$(call cfg_en,CONFIG_ESP_SIGN_RSA)$(call 
cfg_val,CONFIG_ESP_SIGN_RSA_LEN,2048)) \
+               $(if 
$(CONFIG_ESP32C3_SECURE_SIGNED_APPS_SCHEME_RSA_3072),$(call 
cfg_en,CONFIG_ESP_USE_MBEDTLS)$(call cfg_en,CONFIG_ESP_SIGN_RSA)$(call 
cfg_val,CONFIG_ESP_SIGN_RSA_LEN,3072)) \
+               $(if 
$(CONFIG_ESP32C3_SECURE_SIGNED_APPS_SCHEME_ECDSA_P256),$(call 
cfg_en,CONFIG_ESP_USE_TINYCRYPT)$(call cfg_en,CONFIG_ESP_SIGN_EC256)) \
+               $(if $(CONFIG_ESP32C3_SECURE_SIGNED_APPS_SCHEME_ED25519),$(call 
cfg_en,CONFIG_ESP_USE_TINYCRYPT)$(call cfg_en,CONFIG_ESP_SIGN_ED25519)) \
+               $(if $(CONFIG_ESP32C3_SECURE_BOOT_ALLOW_ROM_BASIC),$(call 
cfg_en,CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC)) \
+               $(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_INSECURE_ALLOW_DL_MODE),$(call 
cfg_en,CONFIG_SECURE_INSECURE_ALLOW_DL_MODE)) \
+               $(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)) \
+               $(call 
cfg_val,CONFIG_ESP_APPLICATION_SECONDARY_START_ADDRESS,$(CONFIG_ESP32C3_OTA_SECONDARY_SLOT_OFFSET))
 \
+               $(call cfg_en,CONFIG_ESP_MCUBOOT_WDT_ENABLE) \
+               $(call 
cfg_val,CONFIG_ESP_SCRATCH_OFFSET,$(CONFIG_ESP32C3_OTA_SCRATCH_OFFSET)) \
+               $(call 
cfg_val,CONFIG_ESP_SCRATCH_SIZE,$(CONFIG_ESP32C3_OTA_SCRATCH_SIZE)) \
        } >> $(BOOTLOADER_CONFIG)
 else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
-       $(Q) {                                                                  
                              \
-               echo "CONFIG_PARTITION_TABLE_CUSTOM=y";                         
                                  \
-               echo 
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions.csv\"";                    
             \
-               echo 
"CONFIG_PARTITION_TABLE_OFFSET=$(CONFIG_ESP32C3_PARTITION_TABLE_OFFSET)";       
             \
+       $(Q) { \
+               $(call cfg_en,CONFIG_PARTITION_TABLE_CUSTOM) \
+               $(call 
cfg_val,CONFIG_PARTITION_TABLE_CUSTOM_FILENAME,\"partitions.csv\") \
+               $(call 
cfg_val,CONFIG_PARTITION_TABLE_OFFSET,$(CONFIG_ESP32C3_PARTITION_TABLE_OFFSET)) 
\
        } >> $(BOOTLOADER_CONFIG)
 endif
 
 ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
 
-bootloader: $(BOOTLOADER_SRCDIR) $(BOOTLOADER_CONFIG)
-       $(Q) echo "Building Bootloader binaries"
+BOOTLOADER_BIN        = $(TOPDIR)/mcuboot-esp32c3.bin
+BOOTLOADER_SIGNED_BIN = $(TOPDIR)/mcuboot-esp32c3.signed.bin
+
+$(BOOTLOADER_BIN): $(BOOTLOADER_CONFIG)
+       $(Q) echo "Building Bootloader"
        $(Q) $(BOOTLOADER_SRCDIR)/build_mcuboot.sh -c esp32c3 -s -f 
$(BOOTLOADER_CONFIG)
        $(call COPYFILE, 
$(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/mcuboot-esp32c3.bin, $(TOPDIR))
 
+bootloader: $(BOOTLOADER_CONFIG) $(BOOTLOADER_SRCDIR) $(BOOTLOADER_BIN)
+ifeq ($(CONFIG_ESP32C3_SECURE_BOOT),y)
+       $(eval KEYDIR := $(TOPDIR)/$(ESPSEC_KEYDIR))
+       $(eval BOOTLOADER_SIGN_KEY := $(abspath $(KEYDIR)/$(subst 
",,$(CONFIG_ESP32C3_SECURE_BOOT_BOOTLOADER_SIGNING_KEY))))
+ifeq ($(CONFIG_ESP32C3_SECURE_BOOT_BUILD_SIGNED_BINARIES),y)
+       $(Q) if [ ! -f "$(BOOTLOADER_SIGN_KEY)" ]; then \
+               echo ""; \
+               echo "$(RED)bootloader error:$(RST) Bootloader signing key 
$(BOLD)$(CONFIG_ESP32C3_SECURE_BOOT_BOOTLOADER_SIGNING_KEY)$(RST) does not 
exist."; \
+               echo "Generate using:"; \
+               echo "    espsecure.py generate_signing_key --version 2 
$(CONFIG_ESP32C3_SECURE_BOOT_BOOTLOADER_SIGNING_KEY)"; \
+               echo ""; \
+               exit 1; \
+       fi
+       $(Q) echo "Signing Bootloader"
+       espsecure.py sign_data --version 2 --keyfile $(BOOTLOADER_SIGN_KEY) -o 
$(BOOTLOADER_SIGNED_BIN) $(BOOTLOADER_BIN)
+else
+       $(Q) echo ""
+       $(Q) echo "$(YELLOW)Bootloader not signed. Sign the bootloader before 
flashing.$(RST)"
+       $(Q) echo "To sign the bootloader, you can use this command:"
+       $(Q) echo "    espsecure.py sign_data --version 2 --keyfile 
$(BOOTLOADER_SIGN_KEY) -o mcuboot-esp32c3.signed.bin mcuboot-esp32c3.bin"
+       $(Q) echo ""
+endif
+endif
+
 clean_bootloader:
-       $(call DELDIR, $(BOOTLOADER_SRCDIR))
-       $(call DELFILE, $(BOOTLOADER_CONFIG))
-       $(call DELFILE, $(TOPDIR)/mcuboot-esp32c3.bin)
+       $(call DELDIR,$(BOOTLOADER_SRCDIR))
+       $(call DELFILE,$(BOOTLOADER_CONFIG))
+       $(call DELFILE,$(BOOTLOADER_BIN))
+       $(if $(CONFIG_ESP32C3_SECURE_BOOT_BUILD_SIGNED_BINARIES),$(call 
DELFILE,$(BOOTLOADER_SIGNED_BIN)))
 
 else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
 
 bootloader: $(BOOTLOADER_SRCDIR) $(BOOTLOADER_CONFIG)
        $(Q) echo "Building Bootloader binaries"
        $(Q) $(BOOTLOADER_SRCDIR)/build_idfboot.sh -c esp32c3 -s -f 
$(BOOTLOADER_CONFIG)
-       $(call COPYFILE, 
$(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/bootloader-esp32c3.bin, $(TOPDIR))
-       $(call COPYFILE, 
$(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/partition-table-esp32c3.bin, 
$(TOPDIR))
+       $(call 
COPYFILE,$(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/bootloader-esp32c3.bin,$(TOPDIR))
+       $(call 
COPYFILE,$(BOOTLOADER_SRCDIR)/$(BOOTLOADER_OUTDIR)/partition-table-esp32c3.bin,$(TOPDIR))
 
 clean_bootloader:
-       $(call DELDIR, $(BOOTLOADER_SRCDIR))
-       $(call DELFILE, $(BOOTLOADER_CONFIG))
-       $(call DELFILE, $(TOPDIR)/bootloader-esp32c3.bin)
-       $(call DELFILE, $(TOPDIR)/partition-table-esp32c3.bin)
+       $(call DELDIR,$(BOOTLOADER_SRCDIR))
+       $(call DELFILE,$(BOOTLOADER_CONFIG))
+       $(call DELFILE,$(TOPDIR)/bootloader-esp32c3.bin)
+       $(call DELFILE,$(TOPDIR)/partition-table-esp32c3.bin)
 
 endif
 
@@ -106,7 +164,7 @@ bootloader:
        $(Q) curl -L $(BOOTLOADER_URL)/mcuboot-esp32c3.bin -o 
$(TOPDIR)/mcuboot-esp32c3.bin
 
 clean_bootloader:
-       $(call DELFILE, $(TOPDIR)/mcuboot-esp32c3.bin)
+       $(call DELFILE,$(TOPDIR)/mcuboot-esp32c3.bin)
 
 else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
 
@@ -116,8 +174,8 @@ bootloader:
        $(Q) curl -L $(BOOTLOADER_URL)/partition-table-esp32c3.bin -o 
$(TOPDIR)/partition-table-esp32c3.bin
 
 clean_bootloader:
-       $(call DELFILE, $(TOPDIR)/bootloader-esp32c3.bin)
-       $(call DELFILE, $(TOPDIR)/partition-table-esp32c3.bin)
+       $(call DELFILE,$(TOPDIR)/bootloader-esp32c3.bin)
+       $(call DELFILE,$(TOPDIR)/partition-table-esp32c3.bin)
 
 endif
 
diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig
index 2cc5364..03ea2ec 100644
--- a/arch/risc-v/src/esp32c3/Kconfig
+++ b/arch/risc-v/src/esp32c3/Kconfig
@@ -70,6 +70,14 @@ config ESP32C3_FLASH_16M
        bool
        default n
 
+config ESP32C3_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.
+
 config ESP32C3_FLASH_DETECT
        bool "Auto-detect FLASH size (to be used with master esptool)"
        default n
@@ -1089,6 +1097,8 @@ config ESP32C3_PARTITION_TABLE_OFFSET
        default 0x8000
        depends on ESP32C3_APP_FORMAT_LEGACY
 
+source "arch/risc-v/src/esp32c3/Kconfig.security"
+
 endmenu # Application Image Configuration
 
 menu "Brownout Detect Configuration"
diff --git a/arch/risc-v/src/esp32c3/Kconfig.security 
b/arch/risc-v/src/esp32c3/Kconfig.security
new file mode 100644
index 0000000..9d4f12f
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/Kconfig.security
@@ -0,0 +1,212 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+comment "Secure Boot"
+
+config ESP32C3_SECURE_BOOT
+       bool "Enable hardware Secure Boot in bootloader (READ HELP FIRST)"
+       default n
+       depends on ESP32C3_APP_FORMAT_MCUBOOT
+       select ESP32C3_ESPTOOLPY_NO_STUB
+       ---help---
+               Build a bootloader which enables Secure Boot on first boot.
+
+               Once enabled, Secure Boot will not boot a modified bootloader. 
The bootloader will only boot an
+               application firmware image if it has a verified digital 
signature. There are implications for reflashing
+               updated images once Secure Boot is enabled.
+
+               When enabling Secure Boot, JTAG and ROM BASIC Interpreter are 
permanently disabled by default.
+
+if ESP32C3_SECURE_BOOT
+
+comment "Secure Boot support requires building bootloader from source 
(ESP32C3_BOOTLOADER_BUILD_FROM_SOURCE)"
+       depends on !ESP32C3_BOOTLOADER_BUILD_FROM_SOURCE
+
+config ESP32C3_SECURE_BOOT_BUILD_SIGNED_BINARIES
+       bool "Sign binaries during build"
+       default y
+       ---help---
+               Once Secure Boot is enabled, bootloader and application images 
are required to be signed.
+
+               If enabled (default), these binary files are signed as part of 
the build process.
+               The files named in "Bootloader private signing key" and 
"Application private signing key" will
+               be used to sign the bootloader and application images, 
respectively.
+
+               If disabled, unsigned firmware images will be built.
+               They must be then signed manually using imgtool (e.g., on a 
remote signing server).
+
+config ESP32C3_SECURE_BOOT_BOOTLOADER_SIGNING_KEY
+       string "Bootloader private signing key"
+       default "bootloader_signing_key.pem"
+       ---help---
+               Path to the key file used to sign the bootloader image.
+
+               Key file is an RSA private key in PEM format.
+
+               Path is evaluated relative to the directory indicated by the 
ESPSEC_KEYDIR environment
+               variable.
+
+               You can generate a new signing key by running the following 
command:
+               $ espsecure.py generate_signing_key --version 2 
bootloader_signing_key.pem
+
+               See the Secure Boot section of the ESP-IDF Programmer's Guide 
for this version for details.
+
+choice ESP32C3_SECURE_SIGNED_APPS_SCHEME
+       prompt "Application image signing scheme"
+       default ESP32C3_SECURE_SIGNED_APPS_SCHEME_ECDSA_P256
+       ---help---
+               Select the secure application signing scheme.
+
+       config ESP32C3_SECURE_SIGNED_APPS_SCHEME_RSA_2048
+               bool "RSA-2048"
+
+       config ESP32C3_SECURE_SIGNED_APPS_SCHEME_RSA_3072
+               bool "RSA-3072"
+
+       config ESP32C3_SECURE_SIGNED_APPS_SCHEME_ECDSA_P256
+               bool "ECDSA-P256"
+
+       config ESP32C3_SECURE_SIGNED_APPS_SCHEME_ED25519
+               bool "ED25519"
+
+endchoice
+
+config ESP32C3_SECURE_BOOT_APP_SIGNING_KEY
+       string "Application private signing key"
+       default "app_signing_key.pem"
+       ---help---
+               Path to the key file used to sign NuttX application images.
+
+               Key file is in PEM format and its type shall be specified by 
the configuration defined in
+               "Application image signing scheme".
+
+               Path is evaluated relative to the directory indicated by the 
ESPSEC_KEYDIR environment
+               variable.
+
+               You can generate a new signing key by running the following 
command:
+               $ imgtool keygen --key app_signing_key.pem --type 
<ESP32C3_SECURE_SIGNED_APPS_SCHEME>
+
+config ESP32C3_SECURE_BOOT_INSECURE
+       bool "Allow potentially insecure options"
+       default n
+       ---help---
+               You can disable some of the default protections offered by 
Secure Boot, in order to enable testing or a
+               custom combination of security features.
+
+               Only enable these options if you are very sure.
+
+               Refer to the Secure Boot section of the ESP-IDF Programmer's 
Guide for this version before enabling.
+
+endif # ESP32C3_SECURE_BOOT
+
+menu "Potentially insecure options"
+       visible if ESP32C3_SECURE_BOOT_INSECURE
+
+       # 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
+       # itself doesn't enable/disable its children (if it's not set,
+       # it's possible for the insecure menu to be disabled but the insecure 
option
+       # to remain on which is very bad.)
+
+config ESP32C3_SECURE_BOOT_ALLOW_ROM_BASIC
+       bool "Leave ROM BASIC Interpreter available on reset"
+       default n
+       depends on ESP32C3_SECURE_BOOT_INSECURE
+       ---help---
+               By default, the BASIC ROM Console starts on reset if no valid 
bootloader is
+               read from the flash.
+
+               When either Flash Encryption or Secure Boot are enabled, the 
default is to
+               disable this BASIC fallback mode permanently via eFuse.
+
+               If this option is set, this eFuse is not burned and the BASIC 
ROM Console may
+               remain accessible. Only set this option in testing environments.
+
+config ESP32C3_SECURE_BOOT_ALLOW_JTAG
+       bool "Allow JTAG Debugging"
+       default n
+       depends on ESP32C3_SECURE_BOOT_INSECURE
+       ---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.
+
+               Setting this option leaves JTAG on for debugging, which negates 
all protections of Flash Encryption
+               and some of the protections of Secure Boot.
+
+               Only set this option in testing environments.
+
+config ESP32C3_SECURE_BOOT_ALLOW_EFUSE_RD_DIS
+       bool "Allow additional read protecting of efuses"
+       default n
+       depends on ESP32C3_SECURE_BOOT_INSECURE
+       ---help---
+               If not set (default, recommended), on first boot the bootloader 
will burn the WR_DIS_RD_DIS
+               efuse when Secure Boot is enabled. This prevents any more 
efuses from being read protected.
+
+               If this option is set, it will remain possible to write the 
EFUSE_RD_DIS efuse field after Secure
+               Boot is enabled. This may allow an attacker to read-protect the 
BLK2 efuse (for ESP32) and
+               BLOCK4-BLOCK10 (i.e. BLOCK_KEY0-BLOCK_KEY5)(for other chips) 
holding the public key digest, causing an
+               immediate denial of service and possibly allowing an additional 
fault injection attack to
+               bypass the signature protection.
+
+               NOTE: Once a BLOCK is read-protected, the application will read 
all zeros from that block
+
+               NOTE: If UART ROM download mode "Permanently disabled 
(recommended)" is set,
+               then it is __NOT__ possible to read/write efuses using 
espefuse.py utility.
+               However, efuse can be read/written from the application.
+
+endmenu # Potentially insecure options
+
+choice ESP32C3_SECURE_UART_ROM_DL_MODE
+       bool "UART ROM download mode"
+       default ESP32C3_SECURE_INSECURE_ALLOW_DL_MODE
+       depends on ESP32C3_SECURE_BOOT
+
+       config ESP32C3_SECURE_DISABLE_ROM_DL_MODE
+               bool "Permanently disabled (recommended)"
+               ---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 ESP32C3_SECURE_ENABLE_SECURE_ROM_DL_MODE
+               bool "Permanently switch to Secure mode (recommended)"
+               ---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()
+
+       config ESP32C3_SECURE_INSECURE_ALLOW_DL_MODE
+               bool "Enabled (not recommended)"
+               ---help---
+                       This is a potentially insecure option.
+                       Enabling this option will allow the full UART download 
mode to stay enabled.
+                       This option SHOULD NOT BE ENABLED for production use 
cases.
+
+endchoice
diff --git a/tools/esp32c3/Config.mk b/tools/esp32c3/Config.mk
index 685cc2e..601681e 100644
--- a/tools/esp32c3/Config.mk
+++ b/tools/esp32c3/Config.mk
@@ -58,6 +58,10 @@ else
        ESPTOOL_WRITEFLASH_OPTS := -fs $(FLASH_SIZE) -fm dio -ff $(FLASH_FREQ)
 endif
 
+ifeq ($(CONFIG_ESP32C3_SECURE_BOOT),y)
+       ESPTOOL_RESET_OPTS += --after no_reset
+endif
+
 ESPTOOL_FLASH_OPTS := -fs $(FLASH_SIZE) -fm $(FLASH_MODE) -ff $(FLASH_FREQ)
 
 # Configure the variables according to build environment
@@ -73,9 +77,15 @@ ifdef ESPTOOL_BINDIR
                ESPTOOL_BINS    := $(FLASH_BL) $(FLASH_PT)
        else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
                BL_OFFSET       := 0x0
-               BOOTLOADER      := $(ESPTOOL_BINDIR)/mcuboot-esp32c3.bin
-               FLASH_BL        := $(BL_OFFSET) $(BOOTLOADER)
-               ESPTOOL_BINS    := $(FLASH_BL)
+               ifeq ($(CONFIG_ESP32C3_SECURE_BOOT),y)
+                       BOOTLOADER   := 
$(ESPTOOL_BINDIR)/mcuboot-esp32c3.signed.bin
+                       FLASH_BL     := $(BL_OFFSET) $(BOOTLOADER)
+                       ESPTOOL_BINS :=
+               else
+                       BOOTLOADER   := $(ESPTOOL_BINDIR)/mcuboot-esp32c3.bin
+                       FLASH_BL     := $(BL_OFFSET) $(BOOTLOADER)
+                       ESPTOOL_BINS := $(FLASH_BL)
+               endif
        endif
 endif
 
@@ -92,15 +102,43 @@ else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
                APP_OFFSET := $(CONFIG_ESP32C3_OTA_SECONDARY_SLOT_OFFSET)
        endif
 
-       APP_IMAGE      := nuttx.signed.bin
+       ifeq ($(CONFIG_ESP32C3_SECURE_BOOT),y)
+               APP_IMAGE  := nuttx.signed.bin
+       else
+               APP_IMAGE  := nuttx.bin
+       endif
        FLASH_APP      := $(APP_OFFSET) $(APP_IMAGE)
 endif
 
 ESPTOOL_BINS += $(FLASH_APP)
 
+# Commands for colored and formatted output
+
+RED    = \033[1;31m
+YELLOW = \033[1;33m
+BOLD   = \033[1m
+RST    = \033[0m
+
+# Functions for printing help messages
+
+define HELP_SIGN_APP
+       $(Q) echo ""
+       $(Q) echo "$(YELLOW)Application not signed. Sign the application before 
flashing.$(RST)"
+       $(Q) echo "To sign the application, you can use this command:"
+       $(Q) echo "    imgtool sign -k 
$(ESPSEC_KEYDIR)/$(CONFIG_ESP32C3_SECURE_BOOT_APP_SIGNING_KEY) 
--public-key-format hash --pad $(VERIFIED) --align 4 -v 0 -s auto -H 
$(CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE) --pad-header -S 
$(CONFIG_ESP32C3_OTA_SLOT_SIZE) nuttx.hex nuttx.signed.bin"
+       $(Q) echo ""
+endef
+
+define HELP_FLASH_BOOTLOADER
+       $(Q) echo ""
+       $(Q) echo "$(YELLOW)Secure boot enabled, so bootloader not flashed 
automatically.$(RST)"
+       $(Q) echo "Use the following command to flash the bootloader:"
+       $(Q) echo "    esptool.py $(ESPTOOL_OPTS) write_flash 
$(ESPTOOL_WRITEFLASH_OPTS) $(FLASH_BL)"
+       $(Q) echo ""
+endef
+
 # MERGEBIN -- Merge raw binary files into a single file
 
-ifeq ($(CONFIG_ESP32C3_MERGE_BINS),y)
 define MERGEBIN
        $(Q) if [ -z $(ESPTOOL_BINDIR) ]; then \
                echo "MERGEBIN error: Missing argument for binary files 
directory."; \
@@ -115,17 +153,11 @@ define MERGEBIN
        $(Q) echo nuttx.merged.bin >> nuttx.manifest
        $(Q) echo "Generated: nuttx.merged.bin"
 endef
-else
-define MERGEBIN
-
-endef
-endif
 
-# SIGNBIN -- Sign the binary image file
+# SIGNBIN -- Create the signed binary image file for Secure Boot
 
-ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
 define SIGNBIN
-       $(Q) echo "MKIMAGE: ESP32-C3 binary"
+       $(Q) echo "SIGNBIN: ESP32-C3 signed binary"
        $(Q) if ! imgtool version 1>/dev/null 2>&1; then \
                echo ""; \
                echo "imgtool not found.  Please run: \"pip install imgtool\""; 
\
@@ -133,19 +165,41 @@ define SIGNBIN
                echo "Run make again to create the nuttx.signed.bin image."; \
                exit 1; \
        fi
-       imgtool sign --pad --pad-sig $(VERIFIED) --align 4 -v 0 \
+       $(Q) if [ -z "$(ESPSEC_KEYDIR)" ]; then \
+               echo "SIGNBIN error: Missing argument for secure boot keys 
directory."; \
+               echo "USAGE: make ESPSEC_KEYDIR=<dir>"; \
+               exit 1; \
+       fi
+
+       $(eval APP_SIGN_KEY := $(ESPSEC_KEYDIR)/$(subst 
",,$(CONFIG_ESP32C3_SECURE_BOOT_APP_SIGNING_KEY)))
+       $(Q) if [ ! -f "$(APP_SIGN_KEY)" ]; then \
+               echo ""; \
+               echo "$(RED)SIGNBIN error:$(RST) Application signing key 
$(BOLD)$(CONFIG_ESP32C3_SECURE_BOOT_APP_SIGNING_KEY)$(RST) does not exist."; \
+               echo "Generate using:"; \
+               echo "    imgtool keygen --key 
$(CONFIG_ESP32C3_SECURE_BOOT_APP_SIGNING_KEY) --type 
<ESP32C3_SECURE_SIGNED_APPS_SCHEME>"; \
+               echo ""; \
+               exit 1; \
+       fi
+       $(if $(CONFIG_ESP32C3_SECURE_BOOT_BUILD_SIGNED_BINARIES), \
+               $(eval IMGTOOL_KEY_ARGS := -k $(APP_SIGN_KEY) 
--public-key-format hash))
+
+       imgtool sign $(IMGTOOL_KEY_ARGS) --pad $(VERIFIED) --align 4 -v 0 -s 
auto \
                -H $(CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE) --pad-header \
                -S $(CONFIG_ESP32C3_OTA_SLOT_SIZE) \
-               nuttx.bin nuttx.signed.bin
+               nuttx.hex nuttx.signed.bin
        $(Q) echo nuttx.signed.bin >> nuttx.manifest
        $(Q) echo "Generated: nuttx.signed.bin (MCUboot compatible)"
 endef
-endif
 
-# ELF2IMAGE -- Convert an ELF file into a binary file in Espressif application 
image format
+# MKIMAGE -- Convert an ELF file into a compatible binary file
 
+ifeq ($(CONFIG_ESP32C3_SECURE_BOOT),y)
+define MKIMAGE
+       $(if $(CONFIG_ESP32C3_SECURE_BOOT_BUILD_SIGNED_BINARIES),$(call 
SIGNBIN),$(call HELP_SIGN_APP))
+endef
+else
 ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
-define ELF2IMAGE
+define MKIMAGE
        $(Q) echo "MKIMAGE: ESP32-C3 binary"
        $(Q) if ! esptool.py version 1>/dev/null 2>&1; then \
                echo ""; \
@@ -161,21 +215,31 @@ define ELF2IMAGE
        esptool.py -c esp32c3 elf2image $(ESPTOOL_FLASH_OPTS) -o nuttx.bin nuttx
        $(Q) echo "Generated: nuttx.bin (ESP32-C3 compatible)"
 endef
+else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
+define MKIMAGE
+       $(Q) echo "MKIMAGE: ESP32-C3 binary"
+       $(Q) if ! imgtool version 1>/dev/null 2>&1; then \
+               echo ""; \
+               echo "imgtool not found.  Please run: \"pip install imgtool\""; 
\
+               echo ""; \
+               echo "Run make again to create the nuttx.bin image."; \
+               exit 1; \
+       fi
+       imgtool sign --pad $(VERIFIED) --align 4 -v 0 -s auto \
+               -H $(CONFIG_ESP32C3_APP_MCUBOOT_HEADER_SIZE) --pad-header \
+               -S $(CONFIG_ESP32C3_OTA_SLOT_SIZE) \
+               nuttx.hex nuttx.bin
+       $(Q) echo "Generated: nuttx.bin (MCUboot compatible)"
+endef
+endif
 endif
 
 # POSTBUILD -- Perform post build operations
 
-ifeq ($(CONFIG_ESP32C3_APP_FORMAT_MCUBOOT),y)
 define POSTBUILD
-       $(call SIGNBIN)
-       $(call MERGEBIN)
+       $(call MKIMAGE)
+       $(if $(CONFIG_ESP32C3_MERGE_BINS),$(call MERGEBIN))
 endef
-else ifeq ($(CONFIG_ESP32C3_APP_FORMAT_LEGACY),y)
-define POSTBUILD
-       $(call ELF2IMAGE)
-       $(call MERGEBIN)
-endef
-endif
 
 # ESPTOOL_BAUD -- Serial port baud rate used when flashing/reading via 
esptool.py
 
@@ -189,5 +253,9 @@ define FLASH
                echo "USAGE: make flash ESPTOOL_PORT=<port> [ 
ESPTOOL_BAUD=<baud> ]"; \
                exit 1; \
        fi
-       esptool.py -c esp32c3 -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) write_flash 
$(ESPTOOL_WRITEFLASH_OPTS) $(ESPTOOL_BINS)
+
+       $(eval ESPTOOL_OPTS := -c esp32c3 -p $(ESPTOOL_PORT) -b $(ESPTOOL_BAUD) 
$(ESPTOOL_RESET_OPTS) $(if $(CONFIG_ESP32C3_ESPTOOLPY_NO_STUB),--no-stub))
+       esptool.py $(ESPTOOL_OPTS) write_flash $(ESPTOOL_WRITEFLASH_OPTS) 
$(ESPTOOL_BINS)
+
+       $(if $(CONFIG_ESP32C3_SECURE_BOOT),$(call HELP_FLASH_BOOTLOADER))
 endef

Reply via email to