1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #20858 from benpicco/suit_multi_key-2

makefiles/suit: store public keys, make it easier to work with multiple keys
This commit is contained in:
benpicco 2024-09-12 20:39:28 +00:00 committed by GitHub
commit 870fe04dfa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 47 additions and 18 deletions

View File

@ -6,10 +6,14 @@ SUIT_TOOL ?= $(RIOTBASE)/dist/tools/suit/suit-manifest-generator/bin/suit-tool
# SUIT encryption keys
#
# Specify key to use.
# Specify key(s) to use.
# Will use $(SUIT_KEY_DIR)/$(SUIT_KEY).pem as combined private/public key
# files.
# Multiple keys can be specified, that means that the firmware will accept
# updates signed with either one of those keys.
# If the firmware accepts multiple keys, let the first key be the signing key.
SUIT_KEY ?= default
SUIT_KEY_SIGN ?= $(word 1, $(SUIT_KEY))
XDG_DATA_HOME ?= $(HOME)/.local/share
ifeq (1, $(RIOT_CI_BUILD))
@ -18,39 +22,60 @@ else
SUIT_KEY_DIR ?= $(XDG_DATA_HOME)/RIOT/keys
endif
SUIT_SEC ?= $(SUIT_KEY_DIR)/$(SUIT_KEY).pem
# we may accept multiple keys for the firmware
SUIT_SEC ?= $(foreach item,$(SUIT_KEY),$(SUIT_KEY_DIR)/$(item).pem)
# but there can only be one signing key
SUIT_SEC_SIGN ?= $(SUIT_KEY_DIR)/$(SUIT_KEY_SIGN).pem
# Multiple keys can be specified with "key0:pw0 key1:pw1 …" (pw may be empty)
SUIT_SECS ?= $(SUIT_SEC):$(SUIT_SEC_PASSWORD)
# generate a list of the public keys
SUIT_PUBS ?= $(SUIT_SEC:.pem=.pem.pub)
SUIT_PUB_HDR = $(BINDIR)/riotbuild/public_key.h
SUIT_PUB_HDR_DIR = $(dir $(SUIT_PUB_HDR))
CFLAGS += -I$(SUIT_PUB_HDR_DIR)
BUILDDEPS += $(SUIT_PUB_HDR)
# OpenSSL leaves an empty file if key generation fails - remove it manually
# see https://github.com/openssl/openssl/issues/25440
$(SUIT_SEC): | $(CLEAN)
$(Q)echo suit: generating key in $(SUIT_KEY_DIR)
$(Q)mkdir -p $(SUIT_KEY_DIR)
$(Q)$(RIOTBASE)/dist/tools/suit/gen_key.py $(SUIT_SEC) $(SUIT_SEC_PASSWORD)
$(Q)( \
printf "0) none\n"; \
printf "1) aes-256-cbc\n"; \
printf "Choose encryption for key file $@: "; \
if [ -z "$(RIOT_CI_BUILD)" ]; then read encryption; else encryption=0; fi; \
case $$encryption in \
0) \
openssl genpkey -algorithm ed25519 -out $@; \
;; \
1) \
openssl genpkey -algorithm ed25519 -aes-256-cbc -out $@ || :; \
;; \
*) \
echo "Invalid choice"; \
exit 1; \
;; \
esac; \
)
$(Q)if [ ! -s $@ ]; then rm $@; fi
%.pem.pub: %.pem
$(Q)openssl ec -inform pem -in $< -outform pem -pubout -out $@
# Convert public keys to C headers - only last 32 bytes are key material
#
# set FORCE so switching between keys using "SUIT_KEY=foo make ..."
# triggers a rebuild even if the new key would otherwise not (because the other
# key's mtime is too far back).
$(SUIT_PUB_HDR): $(SUIT_SEC) FORCE | $(CLEAN)
$(SUIT_PUB_HDR): $(SUIT_PUBS) FORCE | $(CLEAN)
$(Q)mkdir -p $(SUIT_PUB_HDR_DIR)
$(Q)( \
echo "const uint8_t public_key[][32] = {"; \
for i in $(SUIT_SECS); do \
key=$${i%:*}; \
pw=$${i#*:}; \
if [ "$$key" = "$$pw" ]; then \
unset pw; \
fi; \
if [ -z "$$pw" ]; then \
$(SUIT_TOOL) pubkey -f header -k $$key; \
else \
$(SUIT_TOOL) pubkey -f header -k $$key -p $$pw; \
fi \
for i in $(SUIT_PUBS); do \
echo " {"; \
openssl ec -inform pem -pubin -in $$i -outform der | tail -c 32 | xxd -i; \
echo " },"; \
done; \
echo "};" \
) | '$(LAZYSPONGE)' $(LAZYSPONGE_FLAGS) '$@'

View File

@ -32,6 +32,10 @@ SUIT_MANIFEST_SIGNED_LATEST ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME).latest.b
SUIT_NOTIFY_VERSION ?= latest
SUIT_NOTIFY_MANIFEST ?= $(SUIT_MANIFEST_BASENAME).$(SUIT_NOTIFY_VERSION).bin
ifneq (,$(SUIT_SEC_PASSWORD))
SUIT_TOOL_ARGS += -p $(SUIT_SEC_PASSWORD)
endif
# Long manifest names require more buffer space when parsing
export CFLAGS += -DCONFIG_SOCK_URLPATH_MAXLEN=128
export CFLAGS += -DSUIT_VENDOR_DOMAIN="\"$(SUIT_VENDOR)\""
@ -54,7 +58,7 @@ $(SUIT_MANIFEST): $(SUIT_MANIFEST_PAYLOADS) $(BINDIR_SUIT)
$(Q)rm -f $@.tmp
$(SUIT_MANIFEST_SIGNED): $(SUIT_MANIFEST) $(SUIT_SEC)
$(Q)$(SUIT_TOOL) sign $(SUIT_TOOL_ARGS) -k $(SUIT_SEC) -m $(SUIT_MANIFEST) -o $@
$(Q)$(SUIT_TOOL) sign $(SUIT_TOOL_ARGS) -k $(SUIT_SEC_SIGN) -m $(SUIT_MANIFEST) -o $@
$(SUIT_MANIFEST_LATEST): $(SUIT_MANIFEST)
$(Q)ln -f -s $< $@