mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
build system: Add espefuse/espsecure support for secure boot
This commit is contained in:
parent
cf732bb663
commit
4ba1b73eba
@ -28,4 +28,57 @@ config LOG_BOOTLOADER_LEVEL
|
|||||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||||
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||||
|
|
||||||
|
choice SECURE_BOOTLOADER
|
||||||
|
bool "Secure bootloader"
|
||||||
|
default SECURE_BOOTLOADER_DISABLED
|
||||||
|
help
|
||||||
|
Build a bootloader with the secure boot flag enabled.
|
||||||
|
|
||||||
|
Secure bootloader can be one-time-flash (chip will only ever
|
||||||
|
boot that particular bootloader), or a digest key can be used
|
||||||
|
to allow the secure bootloader to be re-flashed with
|
||||||
|
modifications. Secure boot also permanently disables JTAG.
|
||||||
|
|
||||||
|
See docs/security/secure-boot.rst for details.
|
||||||
|
|
||||||
|
config SECURE_BOOTLOADER_DISABLED
|
||||||
|
bool "Disabled"
|
||||||
|
|
||||||
|
config SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||||
|
bool "One-time flash"
|
||||||
|
help
|
||||||
|
On first boot, the bootloader will generate a key which is not readable externally or by software. A digest is generated from the bootloader image itself. This digest will be verified on each subsequent boot.
|
||||||
|
|
||||||
|
Enabling this option means that the bootloader cannot be changed after the first time it is booted.
|
||||||
|
|
||||||
|
config SECURE_BOOTLOADER_REFLASHABLE
|
||||||
|
bool "Reflashable"
|
||||||
|
help
|
||||||
|
Generate the bootloader digest key on the computer instead of inside
|
||||||
|
the chip. Allows the secure bootloader to be re-flashed by using the
|
||||||
|
same key.
|
||||||
|
|
||||||
|
This option is less secure than one-time flash, because a leak of the digest key allows reflashing of any device that uses it.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config SECURE_BOOTLOADER_KEY_FILE
|
||||||
|
string "Secure bootloader digest key file"
|
||||||
|
depends on SECURE_BOOTLOADER_REFLASHABLE
|
||||||
|
default secure_boot_key.bin
|
||||||
|
help
|
||||||
|
Path to the key file for a reflashable secure boot digest.
|
||||||
|
File must contain 32 randomly generated bytes.
|
||||||
|
|
||||||
|
Path is evaluated relative to the project directory.
|
||||||
|
|
||||||
|
You can generate a new key by running the following command:
|
||||||
|
espsecure.py generate_key secure_boot_key.bin
|
||||||
|
|
||||||
|
See docs/security/secure-boot.rst for details.
|
||||||
|
|
||||||
|
config SECURE_BOOTLOADER_ENABLED
|
||||||
|
bool
|
||||||
|
default SECURE_BOOTLOADER_ONE_TIME_FLASH || SECURE_BOOTLOADER_REFLASHABLE
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -15,6 +15,8 @@ BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader)
|
|||||||
BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
||||||
BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig
|
BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig
|
||||||
|
|
||||||
|
SECURE_BOOT_KEYFILE=$(abspath $(call dequote,$(CONFIG_SECURE_BOOTLOADER_KEY_FILE)))
|
||||||
|
|
||||||
# Custom recursive make for bootloader sub-project
|
# Custom recursive make for bootloader sub-project
|
||||||
BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \
|
BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \
|
||||||
V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \
|
V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \
|
||||||
@ -31,18 +33,67 @@ bootloader-clean:
|
|||||||
|
|
||||||
clean: bootloader-clean
|
clean: bootloader-clean
|
||||||
|
|
||||||
|
ifdef CONFIG_SECURE_BOOTLOADER_DISABLED
|
||||||
|
# If secure boot disabled, bootloader flashing is integrated
|
||||||
|
# with 'make flash' and no warnings are printed.
|
||||||
|
|
||||||
bootloader: $(BOOTLOADER_BIN)
|
bootloader: $(BOOTLOADER_BIN)
|
||||||
|
@echo "$(SEPARATOR)"
|
||||||
@echo "Bootloader built. Default flash command is:"
|
@echo "Bootloader built. Default flash command is:"
|
||||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||||
|
|
||||||
all_binaries: $(BOOTLOADER_BIN)
|
|
||||||
|
|
||||||
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
||||||
|
|
||||||
# bootloader-flash calls flash in the bootloader dummy project
|
|
||||||
bootloader-flash: $(BOOTLOADER_BIN)
|
bootloader-flash: $(BOOTLOADER_BIN)
|
||||||
$(BOOTLOADER_MAKE) flash
|
$(BOOTLOADER_MAKE) flash
|
||||||
|
|
||||||
|
else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||||
|
# One time flashing requires user to run esptool.py command themselves,
|
||||||
|
# and warning is printed about inability to reflash.
|
||||||
|
|
||||||
|
bootloader: $(BOOTLOADER_BIN)
|
||||||
|
@echo $(SEPARATOR)
|
||||||
|
@echo "Bootloader built. One-time flash command is:"
|
||||||
|
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||||
|
@echo $(SEPARATOR)
|
||||||
|
@echo "* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
||||||
|
|
||||||
|
else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE
|
||||||
|
# Reflashable secure bootloader (recommended for testing only)
|
||||||
|
# generates a digest binary (bootloader + digest) and prints
|
||||||
|
# instructions for reflashing. User must run commands manually.
|
||||||
|
|
||||||
|
BOOTLOADER_DIGEST_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin
|
||||||
|
|
||||||
|
bootloader: $(BOOTLOADER_DIGEST_BIN)
|
||||||
|
@echo $(SEPARATOR)
|
||||||
|
@echo "Bootloader built and secure digest generated. First time flash command is:"
|
||||||
|
@echo "$(ESPEFUSEPY) burn_key secure_boot $(SECURE_BOOT_KEYFILE)"
|
||||||
|
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||||
|
@echo $(SEPARATOR)
|
||||||
|
@echo "To reflash the bootloader after initial flash:"
|
||||||
|
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x0 $(BOOTLOADER_DIGEST_BIN)"
|
||||||
|
@echo $(SEPARATOR)
|
||||||
|
@echo "* After first boot, only re-flashes of this kind (with same key) will be accepted."
|
||||||
|
@echo "* NOT RECOMMENDED TO RE-FLASH the same bootloader-reflash-digest.bin to multiple production devices"
|
||||||
|
|
||||||
|
$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOT_KEYFILE)
|
||||||
|
@echo "DIGEST $< + $(SECURE_BOOT_KEYFILE) -> $@"
|
||||||
|
$(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOT_KEYFILE) -o $@ $<
|
||||||
|
|
||||||
|
$(SECURE_BOOT_KEYFILE):
|
||||||
|
@echo $(SEPARATOR)
|
||||||
|
@echo "Need to generate secure boot digest key first. Run following command:"
|
||||||
|
@echo "$(ESPSECUREPY) generate_key $@"
|
||||||
|
@echo "Keep key file safe after generating."
|
||||||
|
@exit 1
|
||||||
|
|
||||||
|
else
|
||||||
|
$(error Bad sdkconfig - one of CONFIG_SECURE_BOOTLOADER_DISABLED, CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH, CONFIG_SECURE_BOOTLOADER_REFLASHABLE must be set)
|
||||||
|
endif
|
||||||
|
|
||||||
|
all_binaries: $(BOOTLOADER_BIN)
|
||||||
|
|
||||||
# synchronise the project level config to the bootloader's
|
# synchronise the project level config to the bootloader's
|
||||||
# config
|
# config
|
||||||
$(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR)
|
$(BOOTLOADER_SDKCONFIG): $(PROJECT_PATH)/sdkconfig | $(BOOTLOADER_BUILD_DIR)
|
||||||
|
@ -148,7 +148,9 @@ bool secure_boot_generate_bootloader_digest(void) {
|
|||||||
/* reuse the secure boot IV generation function to generate
|
/* reuse the secure boot IV generation function to generate
|
||||||
the key, as this generator uses the hardware RNG. */
|
the key, as this generator uses the hardware RNG. */
|
||||||
uint32_t buf[32];
|
uint32_t buf[32];
|
||||||
|
ets_secure_boot_start();
|
||||||
ets_secure_boot_rd_iv(buf);
|
ets_secure_boot_rd_iv(buf);
|
||||||
|
ets_secure_boot_finish();
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", i, buf[i]);
|
ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||||
REG_WRITE(EFUSE_BLK2_WDATA0_REG + 4*i, buf[i]);
|
REG_WRITE(EFUSE_BLK2_WDATA0_REG + 4*i, buf[i]);
|
||||||
|
@ -11,23 +11,34 @@ PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
|
|||||||
# two commands that can be used from other components
|
# two commands that can be used from other components
|
||||||
# to invoke esptool.py (with or without serial port args)
|
# to invoke esptool.py (with or without serial port args)
|
||||||
#
|
#
|
||||||
# NB: esptool.py lives in the sdk/bin directory not the component directory
|
|
||||||
ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py
|
ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py
|
||||||
ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
||||||
ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD)
|
ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD)
|
||||||
|
|
||||||
|
# Supporting esptool command line tools
|
||||||
|
ESPEFUSEPY := $(PYTHON) $(COMPONENT_PATH)/esptool/espefuse.py
|
||||||
|
ESPSECUREPY := $(PYTHON) $(COMPONENT_PATH)/esptool/espsecure.py
|
||||||
|
|
||||||
ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) --flash_size $(ESPFLASHSIZE)
|
ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) --flash_size $(ESPFLASHSIZE)
|
||||||
|
|
||||||
# the no-stub argument is temporary until esptool.py fully supports compressed uploads
|
ESPTOOL_ELF2IMAGE_OPTIONS :=
|
||||||
|
|
||||||
|
ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||||
|
ESPTOOL_ELF2IMAGE_OPTIONS += "--set-secure-boot-flag"
|
||||||
|
endif
|
||||||
|
|
||||||
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_FLASH_OPTIONS)
|
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_FLASH_OPTIONS)
|
||||||
|
|
||||||
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
|
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
|
||||||
|
|
||||||
$(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC)
|
$(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC)
|
||||||
$(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) -o $@ $<
|
$(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $<
|
||||||
|
|
||||||
flash: all_binaries $(ESPTOOLPY_SRC)
|
flash: all_binaries $(ESPTOOLPY_SRC)
|
||||||
@echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..."
|
@echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..."
|
||||||
|
ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||||
|
@echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)"
|
||||||
|
endif
|
||||||
$(Q) $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
|
$(Q) $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
|
||||||
|
|
||||||
app-flash: $(APP_BIN) $(ESPTOOLPY_SRC)
|
app-flash: $(APP_BIN) $(ESPTOOLPY_SRC)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 5c6962e894e0a118c9a4b5760876433493449260
|
Subproject commit 95dae1651e5aea1adb2b6018b23f65a305f67387
|
@ -11,13 +11,13 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
.PHONY: build-components menuconfig defconfig all build clean all_binaries
|
.PHONY: build-components menuconfig defconfig all build clean all_binaries
|
||||||
all: all_binaries # other components will add dependencies to 'all_binaries'
|
all: all_binaries
|
||||||
@echo "To flash all build output, run 'make flash' or:"
|
# see below for recipe of 'all' target
|
||||||
@echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
|
#
|
||||||
|
# # other components will add dependencies to 'all_binaries'. The
|
||||||
# (the reason all_binaries is used instead of 'all' is so that the flash target
|
# reason all_binaries is used instead of 'all' is so that the flash
|
||||||
# can build everything without triggering the per-component "to flash..."
|
# target can build everything without triggering the per-component "to
|
||||||
# output targets.)
|
# flash..." output targets.)
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Welcome to Espressif IDF build system. Some useful make targets:"
|
@echo "Welcome to Espressif IDF build system. Some useful make targets:"
|
||||||
@ -135,6 +135,15 @@ export PROJECT_PATH
|
|||||||
#Include functionality common to both project & component
|
#Include functionality common to both project & component
|
||||||
-include $(IDF_PATH)/make/common.mk
|
-include $(IDF_PATH)/make/common.mk
|
||||||
|
|
||||||
|
all:
|
||||||
|
ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||||
|
@echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)"
|
||||||
|
@echo "To flash app & partition table, run 'make flash' or:"
|
||||||
|
else
|
||||||
|
@echo "To flash all build output, run 'make flash' or:"
|
||||||
|
endif
|
||||||
|
@echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
|
||||||
|
|
||||||
# Set default LDFLAGS
|
# Set default LDFLAGS
|
||||||
|
|
||||||
LDFLAGS ?= -nostdlib \
|
LDFLAGS ?= -nostdlib \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user