Skip to content

Commit

Permalink
Merge branch '67-smaller-flash'
Browse files Browse the repository at this point in the history
Allow to use MCUs with smaller flash size

1. Manual (Chrome Version 92.0.4484.7 (Official Build) dev (64-bit)):
    - [x] https://webauthn.me
    - [x] https://webauthn.io/
    - [x] https://webauthn.bin.coffee/
2. Automatic
    - [x]  https://github.com/google/CTAP2-test-tool , google/CTAP2-test-tool@3109eec via Nitrokey/CTAP2-test-tool@f7af9e7
3. Raw flash dumps compared and verified wrt. user and attestation key data
4. Firmware downgrade protection (development key)

Fixes #67
Fixes #68
  • Loading branch information
szszszsz committed May 11, 2021
2 parents 7ac5a1e + 8e576c8 commit 407553f
Show file tree
Hide file tree
Showing 12 changed files with 262 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ RUN set -eux; \

ENV PATH="/opt/${GCC_NAME}/bin/:${PATH}"

RUN pip install -U pynitrokey
RUN pip install -U git+https://github.com/Nitrokey/pynitrokey
RUN pip install -U fido2==0.8.1
RUN nitropy version && arm-none-eabi-gcc --version | head -1
8 changes: 5 additions & 3 deletions in-docker-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@ function build() {
part=${1}
output=${2}
release=${3}
pages=${4}
what="${part}"

rm -rf release/*
make ${what} RELEASE=${release}
make ${what} RELEASE=${release} PAGES=${pages}
mkdir -p ${out_dir}/${output}/
cp release/* ${out_dir}/${output}/
}

build debug-release-buildv debug 0
build release-buildv release 1
build debug-release-buildv debug-256 0 128
build release-buildv release-256 1 128
build release-buildv release-128 1 64

arm-none-eabi-gcc --version | head -1
find ${out_dir} | xargs sha256sum | sort || true
Expand Down
30 changes: 17 additions & 13 deletions targets/stm32l432/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ DEBUG ?= 0
HWREV ?= 3
SZ ?= $(PREFIX)arm-none-eabi-size
SOLO=nitropy fido2 util
PAGES ?= 128

PAGESHR = $(shell echo $$(( $(PAGES)*2 ))kB )

# development - debug enabled, debug console, debug bootloader keys and certificates, no flash protection
# test - development minus debug console
Expand All @@ -18,17 +20,15 @@ include build/common.mk
APPMAKE=build/application.mk VERSION_FULL=${VERSION_FULL}
BOOTMAKE=build/bootloader.mk VERSION_FULL=${VERSION_FULL}

merge_hex=$(SOLO) mergehex

KEY_PATH ?= "../../keys/attestation/device_key-dummy.hex"
KEY=$(shell cat $(KEY_PATH))
ATTEST_PATH ?= "../../keys/attestation/device_cert.der"
merge_hex_release=$(SOLO) mergehex --attestation-key "$(KEY)" --attestation-cert $(ATTEST_PATH) --lock
merge_hex_release=$(SOLO) mergehex --attestation-key "$(KEY)" --attestation-cert $(ATTEST_PATH) --lock --pages $(PAGES)

ATTEST_PATH_DEV ?= "../../keys/attestation/dev/device_cert.der"
KEY_PATH_DEV ?= "../../keys/attestation/dev/device_key.hex"
KEY_DEV=$(shell cat $(KEY_PATH_DEV))
merge_hex_dev=$(SOLO) mergehex --attestation-key "$(KEY_DEV)" --attestation-cert $(ATTEST_PATH_DEV) --lock
merge_hex_dev=$(SOLO) mergehex --attestation-key "$(KEY_DEV)" --attestation-cert $(ATTEST_PATH_DEV) --lock --pages $(PAGES)

.PHONY: all all-hacker all-locked debugboot-app debugboot-boot boot-sig-checking boot-no-sig build-release-locked build-release build-release build-hacker build-debugboot clean clean2 flash flash_dfu flashboot detach cbor test

Expand All @@ -42,11 +42,11 @@ endif
# The following are the main targets for reproducible builds.
# TODO: better explanation
firmware:
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=0 EXTRA_DEFINES='-DHWREV=$(HWREV) $(TEST_MODE_DEFINE)' 2>&1 | tee build.log
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) PAGES=$(PAGES) DEBUG=0 EXTRA_DEFINES='-DHWREV=$(HWREV) -DPAGES=$(PAGES) $(TEST_MODE_DEFINE)' 2>&1 | tee build.log
test -f solo.hex || false

firmware-debug-1:
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=1 EXTRA_DEFINES='-DHWREV=$(HWREV) $(TEST_MODE_DEFINE)' 2>&1 | tee build.log
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=1 EXTRA_DEFINES='-DHWREV=$(HWREV) -DPAGES=$(PAGES) $(TEST_MODE_DEFINE)' 2>&1 | tee build.log
test -f solo.hex || false

.PHONY: show-warnings
Expand All @@ -58,36 +58,36 @@ show-warnings:
@echo

firmware-debug-2:
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=2 EXTRA_DEFINES='-DHWREV=$(HWREV) $(TEST_MODE_DEFINE)'
$(MAKE) -f $(APPMAKE) -j8 solo.hex PREFIX=$(PREFIX) DEBUG=2 EXTRA_DEFINES='-DHWREV=$(HWREV) -DPAGES=$(PAGES) $(TEST_MODE_DEFINE)'

bootloader-nonverifying:
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) EXTRA_DEFINES='-DSOLO_HACKER $(TEST_MODE_DEFINE)' DEBUG=0
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) PAGES=$(PAGES) EXTRA_DEFINES='-DSOLO_HACKER $(TEST_MODE_DEFINE) -DPAGES=$(PAGES)' DEBUG=0

bootloader-verifying:
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) EXTRA_DEFINES='$(TEST_MODE_DEFINE)' DEBUG=0 2>&1 | tee build-bootloader.log
$(MAKE) -f $(BOOTMAKE) -j8 bootloader.hex PREFIX=$(PREFIX) PAGES=$(PAGES) EXTRA_DEFINES='$(TEST_MODE_DEFINE) -DPAGES=$(PAGES)' DEBUG=0 2>&1 | tee build-bootloader.log
test -f bootloader.hex || false


full-clean: clean2

.PHONY: debug-release-buildv
ver=$(VERSION_FULL)
signamedev=release/nitrokey-fido2-firmware-dev-$(ver)
signamedev=release/nitrokey-fido2-firmware-dev-$(ver)-$(PAGESHR)
debug-release-buildv: | full-clean cbor bootloader-verifying clean firmware-debug-1 show-warnings
mkdir -p release/
$(VENV) $(merge_hex) solo.hex bootloader.hex all.hex
cp all.hex $(signamedev)-all-to_flash.hex
cp solo.hex $(signamedev)-app-to_sign.hex
sha256sum $(signamedev)-app-to_sign.hex $(signamedev)-all-to_flash.hex *.hex | sort
$(SOLO) sign ../../keys/bootloader-dev.pem solo.hex $(signamedev).json
$(SOLO) sign ../../keys/bootloader-dev.pem solo.hex $(signamedev).json --pages $(PAGES)
sha256sum $(signamedev).json > $(signamedev).json.sha2
@echo "done"

.PHONY: release-buildv
signame1=release/nitrokey-fido2-firmware-$(ver)
signame1=release/nitrokey-fido2-firmware-$(ver)-$(PAGESHR)
signame=$(signame1).json
ifeq ($(RELEASE),0)
signame1=release/nitrokey-fido2-firmware-$(ver)-test
signame1=release/nitrokey-fido2-firmware-$(ver)-test-$(PAGESHR)
endif

release-buildv: | full-clean cbor bootloader-verifying clean firmware show-warnings
Expand Down Expand Up @@ -211,6 +211,10 @@ run-debug:
run-reset:
STM32_Programmer_CLI -c port=SWD -rst

.PHONY: run-download
run-download:
STM32_Programmer_CLI -c port=SWD -u 0x8000000 $$(($(PAGES)*2*1024)) flash_dump-$(PAGES).bin

.PHONY: run-monitor
run-monitor:
nitropy fido2 util monitor /dev/nitrokey-fido2-serial
10 changes: 10 additions & 0 deletions targets/stm32l432/bootloader/pubkey_bootloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,22 @@ uint8_t pubkey_boot[] = "\xb6\xd1\xd2\x83\xaa\xc9\x67\x72\x28\xdf\x4e\xca\x05\x2
#else
#warning "Using production bootloader key"

#if PAGES==64
#warning "Selecting prod bootloader key for pages==64"
uint8_t pubkey_boot[] = "\xd0\xdd\x90\x21\x45\x9b\x72\x72\xaa\x90\xaa\xcf\x98\x7a\x63\x3a\x4c"
"\xb5\x44\x96\xc5\x70\x43\x4d\x6a\xea\xd3\x0f\xba\x5d\x85\xa3\xd8\xae"
"\xc0\x19\x33\x50\xf1\x5d\xda\xe3\x9d\xa8\x49\x38\x68\xeb\x28\x8e\x46"
"\x7e\x14\xfc\x46\xa2\x95\x9b\xb0\xd6\x35\xf1\x18\x55";
#else
#warning "Selecting prod bootloader key for pages==128"
uint8_t pubkey_boot[] = "\x72\x09\xdc\x50\x1d\xff\xbf\x99\xfd\x2d\x91\x3b\x1a\x29\x6e\xbd\x91"
"\x74\x3a\x15\xb5\x35\xfe\xd3\x91\x9e\x6e\x5f\x66\x02\xb9\x3e\xf7\x0f"
"\x0e\x0a\x59\x08\xb4\x12\x54\xf6\x62\x22\xab\x00\x51\x5b\x68\x49\xe8"
"\x99\xb0\x23\xbe\xcd\x61\xdb\xed\x78\x6d\xfd\x6e\xe8";
#endif

#endif

const uint8_t pubkey_boot_size = sizeof(pubkey_boot)-1;

static_assert(sizeof(pubkey_boot)-1 == 64, "Invalid key size");
Expand Down
14 changes: 11 additions & 3 deletions targets/stm32l432/build/application.mk
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ ECC_CFLAGS = $(CFLAGS) -DuECC_PLATFORM=5 -DuECC_OPTIMIZATION_LEVEL=4 -DuECC_SQUA
all: $(TARGET).elf
$(SZ) $^

%.o: %.c
%.o: %.c $(LDSCRIPT)
@echo "*** $<"
@$(CC) $^ $(HW) $(CFLAGS) -o $@
@$(CC) $< $(HW) $(CFLAGS) -o $@

../../crypto/micro-ecc/uECC.o: ../../crypto/micro-ecc/uECC.c
@echo "*** $<"
Expand All @@ -80,9 +80,10 @@ all: $(TARGET).elf
%.hex: %.elf
$(SZ) $^
$(CP) -O ihex $^ $(TARGET).hex
$(CP) -O binary $^ $(TARGET).bin

clean:
@rm -f *.o src/*.o *.elf bootloader/*.o $(OBJ)
@rm -f *.o src/*.o *.elf bootloader/*.o $(OBJ) $(LDSCRIPT)


cbor:
Expand All @@ -91,3 +92,10 @@ cbor:
LDFLAGS="$(LDFLAGS_LIB)" \
CFLAGS="$(CFLAGS) -Os -g3 -DCBOR_PARSER_MAX_RECURSIONS=3"


ifndef PAGES
PAGES=64
$(warning PAGES is not defined - setting to new value: "$(PAGES)")
endif
$(LDSCRIPT): $(LDSCRIPT).in
sed 's/__PAGES__/$(PAGES)/g' < $< >$@
14 changes: 11 additions & 3 deletions targets/stm32l432/build/bootloader.mk
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ all: $(TARGET).elf
$(SZ) $^


%.o: %.c
%.o: %.c $(LDSCRIPT)
@echo "*** bootloader: $<"
@$(CC) $^ $(HW) -Os $(CFLAGS) -o $@
@$(CC) $< $(HW) -Os $(CFLAGS) -o $@

../../crypto/micro-ecc/uECC.o: ../../crypto/micro-ecc/uECC.c
@echo "*** $<"
Expand All @@ -68,6 +68,13 @@ all: $(TARGET).elf
@echo "*** bootloader: $<"
@$(CC) $^ $(HW) -Os $(CFLAGS) -o $@

ifndef PAGES
PAGES=64
$(warning PAGES is not defined - setting to new value: "$(PAGES)")
endif
$(LDSCRIPT): $(LDSCRIPT).in
sed 's/__PAGES__/$(PAGES)/g' < $< >$@

%.elf: $(OBJ)
$(CC) $^ $(HW) $(LDFLAGS) -o $@ -Wl,--print-memory-usage
$(SZ) $@
Expand All @@ -77,4 +84,5 @@ all: $(TARGET).elf
@echo "Bootloader built flags: $(CFLAGS)"

clean:
rm -f *.o src/*.o bootloader/*.o *.elf $(OBJ)
-cp $(LDSCRIPT){,-} -v
rm -f *.o src/*.o bootloader/*.o *.elf $(OBJ) $(LDSCRIPT)
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ flash_cfg is for storing bootloader data, like last used firmware version.
bootloader_configuration should be equal to (APPLICATION_END_PAGE) page address, from targets/stm32l432/src/memory_layout.h:30; and equal to flash_cfg origin
*/

bootloader_configuration = 0x08000000 + 216*1024+8;
bootloader_configuration = 0x08000000 + (128-40)*1024+8;

MEMORY
{
flash (rx) : ORIGIN = 0x08000000, LENGTH = 20K
flash_cfg (rx) : ORIGIN = 0x08000000 + 216*1024+8, LENGTH = 2K-8
flash_cfg (rx) : ORIGIN = 0x08000000 + (128-40)*1024+8, LENGTH = 2K-8
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
}
Expand Down
90 changes: 90 additions & 0 deletions targets/stm32l432/linker/bootloader_stm32l4xx.ld.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* Copyright 2019 SoloKeys Developers */
/* */
/* Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or */
/* http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or */
/* http://opensource.org/licenses/MIT>, at your option. This file may not be */
/* copied, modified, or distributed except according to those terms. */

ENTRY(Reset_Handler)

/* End of RAM */
_estack = 0x2000c000;

_MIN_STACK_SIZE = 0x400;

/*
flash_cfg is for storing bootloader data, like last used firmware version.
bootloader_configuration should be equal to (APPLICATION_END_PAGE) page address, from targets/stm32l432/src/memory_layout.h:30; and equal to flash_cfg origin

Template parameters:
PAGES=__PAGES__
*/

bootloader_configuration = 0x08000000 + (__PAGES__*2-40)*1024+8;

MEMORY
{
flash (rx) : ORIGIN = 0x08000000, LENGTH = 20K
flash_cfg (rx) : ORIGIN = 0x08000000 + (__PAGES__*2-40)*1024+8, LENGTH = 2K-8
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
}

SECTIONS
{
.isr_vector :
{
. = ALIGN(8);
KEEP(*(.isr_vector))
. = ALIGN(8);
} >flash

.text :
{
. = ALIGN(8);
*(.text*)
*(.rodata*)
KEEP(*(.init))
KEEP(*(.finit))
. = ALIGN(8);
_etext = .;
} >flash

.flag2 bootloader_configuration :
{
KEEP(*(.flag2)) ;
} > flash_cfg

_sidata = LOADADDR(.data);

.data :
{
. = ALIGN(8);
_sdata = .;
*(.data*)
. = ALIGN(8);
_edata = .;
} >ram AT> flash

.bss :
{
. = ALIGN(4);
_sbss = .;
__bss_start__ = _sbss;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end__ = _ebss;
} > ram

._stack :
{
. = ALIGN(8);
end = .;
_end = .;
. = . + _MIN_STACK_SIZE;
. = ALIGN(8);
} > ram

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ desc | bootloader | application | bootloader data | secrets/data

MEMORY
{
flash (rx) : ORIGIN = 0x08000000 + 20K, LENGTH = 216K - 20K - 8 - 38K -2K
flash (rx) : ORIGIN = 0x08000000 + 20K, LENGTH = 128K - 20K - 8 - 38K -2K
ram (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
sram2 (rw) : ORIGIN = 0x10000000, LENGTH = 16K
}
Expand Down
Loading

0 comments on commit 407553f

Please sign in to comment.