Skip to content

Commit

Permalink
Initial bootloader update solution
Browse files Browse the repository at this point in the history
Connected: #9
  • Loading branch information
szszszsz committed Mar 21, 2020
1 parent 071f901 commit c39bd6f
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 6 deletions.
10 changes: 7 additions & 3 deletions fido2/ctap.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,8 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
check_retr(but);
authData->head.flags = (1 << 0); // User presence
}


device_set_status(CTAPHID_STATUS_PROCESSING);

authData->head.flags |= (ctap_is_pin_set() << 2);
Expand Down Expand Up @@ -1765,7 +1765,7 @@ static void ctap_state_init()

/** Overwrite master secret from external source.
* @param keybytes an array of KEY_SPACE_BYTES length.
*
*
* This function should only be called from a privilege mode.
*/
void ctap_load_external_keys(uint8_t * keybytes){
Expand All @@ -1775,6 +1775,7 @@ void ctap_load_external_keys(uint8_t * keybytes){
crypto_load_master_secret(STATE.key_space);
}

#include "device-bootloader-update.h"
#include "version.h"
void ctap_init()
{
Expand Down Expand Up @@ -1840,6 +1841,9 @@ void ctap_init()
wallet_init();
#endif

#if !defined(IS_BOOTLOADER) && defined(APP_UPDATE_BOOTLOADER)
update_bootloader();
#endif

}

Expand Down
15 changes: 12 additions & 3 deletions fido2/extensions/solo.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "log.h"
#include APP_CONFIG


#include "device-bootloader-update.h"

// output must be at least 71 bytes
int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen)
Expand Down Expand Up @@ -60,7 +60,17 @@ int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen)
}
break;
#endif
case WalletRng:
#ifdef APP_UPDATE_BOOTLOADER
case WalletBootloaderUpdate: {
ret = 0;
update_bootloader();
memset(output, 0, 71);
bootloader_calculate_hash(output);
break;
}
#endif

case WalletRng:
printf1(TAG_WALLET,"SoloRng\n");

ret = ctap_generate_rng(output, 71);
Expand All @@ -71,7 +81,6 @@ int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen)
goto cleanup;
}
ret = 0;

break;

#ifdef ENABLE_WALLET
Expand Down
1 change: 1 addition & 0 deletions fido2/extensions/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ typedef enum
WalletVersion= 0x14,
WalletRng = 0x15,
WalletBootloader = 0x20,
WalletBootloaderUpdate = 0x21,
} WalletOperation;


Expand Down
1 change: 1 addition & 0 deletions fido2/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ int main(int argc, char *argv[])
TAG_RED|
TAG_EXT|
TAG_CCID|
TAG_TIME |
TAG_ERR
);

Expand Down
6 changes: 6 additions & 0 deletions targets/stm32l432/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ merge_hex_dev=solo mergehex --attestation-key "$(KEY_DEV)" --attestation-cert $(

.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

#For bootloader update support add this to below targets:
#EXTRA_DEFINES="-DAPP_UPDATE_BOOTLOADER" BOOT_UPDATE=1
ifeq ($(RELEASE),0)
TEST_MODE_DEFINE="-DNK_TEST_MODE=1"
merge_hex=$(merge_hex_dev)
Expand Down Expand Up @@ -166,6 +168,10 @@ flash-firmware-final:
-solo program aux enter-bootloader
solo program bootloader $(signamedev)

.PHONY: download-bootloader
download-bootloader:
STM32_Programmer_CLI -c port=SWD -halt -u 0x08000000 0x5000 download-bootloader.hex -rst

# tell ST DFU to enter application
detach:
STM32_Programmer_CLI -c port=usb1 -ob nBOOT0=1
Expand Down
6 changes: 6 additions & 0 deletions targets/stm32l432/build/application.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ SRC += $(DRIVER_LIBS) $(USB_LIB)
SRC += src/gpio.c
SRC += src/user_feedback.c

# Bootloader update - payload and execution
ifdef BOOT_UPDATE
SRC += src/boot_payload.c
SRC += src/device-bootloader-update.c
endif

# FIDO2 lib
SRC += ../../fido2/apdu.c ../../fido2/util.c ../../fido2/u2f.c ../../fido2/test_power.c
SRC += ../../fido2/stubs.c ../../fido2/log.c ../../fido2/ctaphid.c ../../fido2/ctap.c
Expand Down
4 changes: 4 additions & 0 deletions targets/stm32l432/build/bootloader.mk
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ all: $(TARGET).elf

%.hex: %.elf
$(CP) -O ihex $^ $(TARGET).hex
srec_cat bootloader.hex -i -offset -0x08000000 -crop 0 0x0005000 -o boot_payload.c -c-a boot_payload -POSTfix '__attribute__ ((section (".payload"))) __attribute__ ((__used__))' -INClude
# -C_COMpressed
mv -v boot_payload.* src/


clean:
rm -f *.o src/*.o bootloader/*.o *.elf $(OBJ)
6 changes: 6 additions & 0 deletions targets/stm32l432/linker/stm32l4xx.ld
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ SECTIONS
_edata = .;
} >ram AT> flash

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

.flag :
{
. = ALIGN(8);
Expand Down
69 changes: 69 additions & 0 deletions targets/stm32l432/src/device-bootloader-update.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#include APP_CONFIG
#include "flash.h"
#include "log.h"
#include "memory_layout.h"
#include "nfc.h"
#include "crypto.h"
#include "device.h"
#include "device-bootloader-update.h"


#if !defined(IS_BOOTLOADER) && defined(APP_UPDATE_BOOTLOADER)
#include "boot_payload.h"

#warning "Bootloader payload added"

void erase_bootloader(void){
int page;
printf1(TAG_ERR,"Erasing bootloader\r\n");
for(page = 0; page < APPLICATION_START_PAGE; page++)
{
printf1(TAG_ERR,"Erasing page: %d\r\n", page);
flash_erase_page(page);
}
}

void bootloader_calculate_hash(uint8_t *hash){
timestamp();
const uint16_t hashlen = APPLICATION_START_ADDR-BOOTLOADER_START_ADDR;
crypto_sha256_init();
crypto_sha256_update( (uint8_t*) BOOTLOADER_START_ADDR, hashlen);
crypto_sha256_final(hash);
printf1(TAG_TIME,"hash time flash: %d ms\n",timestamp());

printf1(TAG_ERR, "hash: start: %p, len: %d\n", BOOTLOADER_START_ADDR, hashlen);
dump_arrl(TAG_ERR, hash, 32);
}

void update_bootloader(void){
if (device_is_nfc() == NFC_IS_ACTIVE)
{
printf1(TAG_ERR, "NFC is active. Skip bootloader update.\n");
return;
}
#if DEBUG_LEVEL >= 2
uint8_t hash[32];
bootloader_calculate_hash(hash);
#endif
bool success = memcmp((uint8_t*) BOOTLOADER_START_ADDR, boot_payload, boot_payload_length) == 0;
if (success) {
printf1(TAG_ERR, "Bootloader already up-to-date. Skipping.\n");
return;
}
led_rgb(0xFF0000);
timestamp();
erase_bootloader(); //about 250 ms
printf1(TAG_TIME,"boot erase: %d ms\n",timestamp());
printf1(TAG_ERR, "Write: %p %d\n", boot_payload, boot_payload_length);
flash_write(BOOTLOADER_START_ADDR,boot_payload, boot_payload_length); //about 250 ms
printf1(TAG_TIME,"boot write: %d ms\n",timestamp());
led_rgb(0x00FF00);

success = memcmp((uint8_t*) BOOTLOADER_START_ADDR, boot_payload, boot_payload_length) == 0;
#if DEBUG_LEVEL >= 2
bootloader_calculate_hash(hash);
#endif

led_rgb(0x0000FF);
}
#endif
8 changes: 8 additions & 0 deletions targets/stm32l432/src/device-bootloader-update.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef DEVICE_BOOTLOADER_UPDATE_H
#define DEVICE_BOOTLOADER_UPDATE_H

void update_bootloader(void);
void bootloader_calculate_hash(uint8_t *hash);


#endif //DEVICE_BOOTLOADER_UPDATE_H
1 change: 1 addition & 0 deletions targets/stm32l432/src/memory_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
// NOT included in application
#define APPLICATION_END_PAGE ((PAGES - 20))
#define APPLICATION_END_ADDR ((0x08000000 + ((APPLICATION_END_PAGE)*PAGE_SIZE))-8)
#define BOOTLOADER_START_ADDR (0x08000000)

// Bootloader state.
#define AUTH_WORD_ADDR (APPLICATION_END_ADDR)
Expand Down

0 comments on commit c39bd6f

Please sign in to comment.