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
@ -20,12 +20,65 @@ config LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
endchoice
|
||||
|
||||
config LOG_BOOTLOADER_LEVEL
|
||||
int
|
||||
default 0 if LOG_BOOTLOADER_LEVEL_NONE
|
||||
default 1 if LOG_BOOTLOADER_LEVEL_ERROR
|
||||
default 2 if LOG_BOOTLOADER_LEVEL_WARN
|
||||
default 3 if LOG_BOOTLOADER_LEVEL_INFO
|
||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
int
|
||||
default 0 if LOG_BOOTLOADER_LEVEL_NONE
|
||||
default 1 if LOG_BOOTLOADER_LEVEL_ERROR
|
||||
default 2 if LOG_BOOTLOADER_LEVEL_WARN
|
||||
default 3 if LOG_BOOTLOADER_LEVEL_INFO
|
||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
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
|
||||
|
@ -15,6 +15,8 @@ BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader)
|
||||
BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
||||
BOOTLOADER_SDKCONFIG=$(BOOTLOADER_BUILD_DIR)/sdkconfig
|
||||
|
||||
SECURE_BOOT_KEYFILE=$(abspath $(call dequote,$(CONFIG_SECURE_BOOTLOADER_KEY_FILE)))
|
||||
|
||||
# Custom recursive make for bootloader sub-project
|
||||
BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \
|
||||
V=$(V) SDKCONFIG=$(BOOTLOADER_SDKCONFIG) \
|
||||
@ -31,18 +33,67 @@ 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)
|
||||
@echo "$(SEPARATOR)"
|
||||
@echo "Bootloader built. Default flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||
|
||||
all_binaries: $(BOOTLOADER_BIN)
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
||||
|
||||
# bootloader-flash calls flash in the bootloader dummy project
|
||||
bootloader-flash: $(BOOTLOADER_BIN)
|
||||
$(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
|
||||
# config
|
||||
$(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
|
||||
the key, as this generator uses the hardware RNG. */
|
||||
uint32_t buf[32];
|
||||
ets_secure_boot_start();
|
||||
ets_secure_boot_rd_iv(buf);
|
||||
ets_secure_boot_finish();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", 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
|
||||
# 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 := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
|
||||
|
||||
$(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)
|
||||
@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)
|
||||
|
||||
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
|
||||
all: all_binaries # other components will add dependencies to 'all_binaries'
|
||||
@echo "To flash all build output, run 'make flash' or:"
|
||||
@echo $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
|
||||
|
||||
# (the reason all_binaries is used instead of 'all' is so that the flash target
|
||||
# can build everything without triggering the per-component "to flash..."
|
||||
# output targets.)
|
||||
all: all_binaries
|
||||
# see below for recipe of 'all' target
|
||||
#
|
||||
# # other components will add dependencies to 'all_binaries'. The
|
||||
# reason all_binaries is used instead of 'all' is so that the flash
|
||||
# target can build everything without triggering the per-component "to
|
||||
# flash..." output targets.)
|
||||
|
||||
help:
|
||||
@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 $(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
|
||||
|
||||
LDFLAGS ?= -nostdlib \
|
||||
|
Loading…
x
Reference in New Issue
Block a user