Skip to content

Conversation

@kYc0o
Copy link
Contributor

@kYc0o kYc0o commented Jul 21, 2017

Third effort to add the RIOT bootloader and the tools to manage internal ROM slots based on @kaspar030 work.

This PR provides the use of a bootloader to verify the integrity of the firmware prior to boot. This ensures the firmware comes from a trusted entity and also ensure its integrity, since two things are verified:

  • A SHA-256 hash value over the whole firmware (integrity check).
  • A Ed25519 signature over the metadata, which also includes the hash.

This prevents to boot firmwares from a non-trusted source, as well as malformed firmwares if they're downloaded over the air.

Compiling a valid image

This PR provides several make targets to build, link, and flash valid images into a selected set of boards. The targets are listed as:

make bootloader: Builds and links the bootloader (only valid for the bootloader application)
make multislot: Builds, links and signs an application for the two slots which are available in the internal ROM of the MCU board.
make combined: Creates Ready-To-Send images for both slots, including metadata and signatures.
make verify: Verifies if the image's signature is valid, using the provided public key.
make flash-multislot: Builds, links, sings and flashes an image including the bootloader and the application on the first slot. Flashing the bootlaoder with the application in slot 2 is not supported.
make multislot-clean: Deletes all the files created by any of the previous targets

With this commands several files are created, namely:

  • <application_name>-slot<slot>-<appid>-<version>.bin: The binary file linked for the given
    slot, with its corresponding metadata ready to be sent over the air.
  • <application_name>-slot1-<appid>-<version>.combined.bin: The binary containing both the
    bootloader and the application on the first slot. It is used to flash it directly on the
    board.
  • <application_name>-slot<slot>.elf: The ELF file linked for the specified slot.
    Very useful for debugging purposes.

You can find these files in the binary folder of your application.

Managing signatures

RIOT already provides tools for creating Ed52219 signatures using tweetnacl. We prefer this implementation for its easy to use and compact presentation, but we're putting efforts to export this to a more robust implementation of this curve.

If you execute one of the above commands, and no keys are given, a pair of keys will be created and stored on the bin folder of your application. This are named ed25519.pub and ed25519.sec. The public key is then exported to the include path which will be embedded on the bootloader firmware.

If you want to provide your own keys (remember, only Ed25519 is supported) you can provide them through the environment variables PUBKEY and SECKEY, e.g.:

PUBKEY = my_ed25519_key.pub
SECKEY = my_ed25519_key.sec

or whatever the name they have. The public key will be automatically exported to the bootloader.

Requirements for building and flashing

You may require bc for building the multislot firmware. This is required since we need to do computations with the provided variables in the Makefile

In Debian based platforms sudo apt-get install bc would suffice.

@kYc0o kYc0o added Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Jul 21, 2017
@kYc0o kYc0o added this to the Release 2017.10 milestone Jul 21, 2017
@kYc0o kYc0o added the State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet label Jul 21, 2017
@kYc0o
Copy link
Contributor Author

kYc0o commented Jul 21, 2017

Marking WIP since I need to remove tweetnacl sources (and rather download them as a package).

Forgot to mention: it only works on samr21-xpro for now. New boards will be added very soon, as only a few defines are needed per board.

@emmanuelsearch emmanuelsearch changed the title Add RIOT Bootloader and multislot firmware management [WIP] Add RIOT Bootloader and multislot firmware management Jul 21, 2017
@emmanuelsearch
Copy link
Member

emmanuelsearch commented Jul 21, 2017

@kYc0o thanks for the work!

Are there dependencies on other PRs?

I added in hello-world example the following lines to try this PR out:

USEMODULE += ota_update_tftp
FW_APPID = 0xBB2 # A 32bit HEX in uppercase
FW_VERSION = 0x2 # A 32bit HEX in lowercase

But when I make multislot I get the following error:

vagrant@vagrant:~/RIOT/examples/hello-world$ BOARD=samr21-xpro make multislot
NON BOOTLOADER BUILD
Building application "hello-world" for "samr21-xpro" with MCU "samd21".

"make" -C /home/vagrant/RIOT/boards/samr21-xpro
"make" -C /home/vagrant/RIOT/core
"make" -C /home/vagrant/RIOT/cpu/samd21
"make" -C /home/vagrant/RIOT/cpu/cortexm_common
"make" -C /home/vagrant/RIOT/cpu/cortexm_common/periph
"make" -C /home/vagrant/RIOT/cpu/sam0_common
"make" -C /home/vagrant/RIOT/cpu/sam0_common/periph
"make" -C /home/vagrant/RIOT/cpu/samd21/periph
"make" -C /home/vagrant/RIOT/drivers
"make" -C /home/vagrant/RIOT/drivers/periph_common
"make" -C /home/vagrant/RIOT/sys
"make" -C /home/vagrant/RIOT/sys/auto_init
"make" -C /home/vagrant/RIOT/sys/isrpipe
"make" -C /home/vagrant/RIOT/sys/newlib_syscalls_default
"make" -C /home/vagrant/RIOT/sys/pm_layered
"make" -C /home/vagrant/RIOT/sys/tsrb
"make" -C /home/vagrant/RIOT/sys/uart_stdio
arm-none-eabi-gcc: error: /home/vagrant/RIOT/examples/hello-world/bin/samr21-xpro/ota_update_tftp.a: No such file or directory
/home/vagrant/RIOT/examples/hello-world/../../Makefile.include:303: recipe for target 'link' failed
make: *** [link] Error 1

@emmanuelsearch emmanuelsearch removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jul 21, 2017
@kYc0o
Copy link
Contributor Author

kYc0o commented Jul 21, 2017

Oh! Not really, I didn't rebase yet to include the ota_update_tftp. Will do asap.

@kaspar030
Copy link
Contributor

please check my multislot branch. it basically does the same (based on your prior work). I'm afk still, so cannot comment on differences, other than it uses simple tftp push (and verification on the fly). it also has a slightly more sophisticated tool for key mansgement and signing images.

@kYc0o
Copy link
Contributor Author

kYc0o commented Jul 21, 2017

@kaspar030 Actually this PR is the merge of the your multislot branch and my previous work. I didn't see any OTA mechanism though. This also includes your key management with some bugs corrected, as well as a better management of the keys.

The OTA module is almost done, the download is successful but the node reboots in a loop, I'm investigating...

@kYc0o
Copy link
Contributor Author

kYc0o commented Jul 22, 2017

The OTA module is pushed on #7398. This can be reviewed separately as it only includes the multislot approach to divide the internal ROM in 3 slots.

I tested it with the OTA module with success on a samr21-xpro.

@kYc0o kYc0o force-pushed the multislot_tests branch 7 times, most recently from 4eafb13 to 928339c Compare July 28, 2017 00:59
@kYc0o
Copy link
Contributor Author

kYc0o commented Jul 28, 2017

Tweetnacl sources removed and added support for iotlab-m3. No more WIP.

@kYc0o kYc0o added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet labels Jul 28, 2017
@ghost
Copy link

ghost commented Aug 2, 2017

@kYc0o Hi, can you tell me what is wrong here?

dimitri@dimitri-Latitude-E6410:~/RIOT/examples/hello-world$ BOARD=samr21-xpro make multislot
make: Entering directory '/home/dimitri/RIOT/dist/tools/firmware_metadata'
rm -Rf tweetnacl
mkdir -p tweetnacl
../git/git-cache clone "https://github.com/RIOT-OS/tweetnacl.git" "7ea05c7098a16c87fa66e9166ce301666f3f2623" "tweetnacl"
Cloning into 'tweetnacl'...
remote: Counting objects: 26, done.
remote: Total 26 (delta 0), reused 0 (delta 0), pack-reused 26
Unpacking objects: 100% (26/26), done.
HEAD is now at 7ea05c7... Update README.md
touch git-fetch-tweetnacl
cc -g -I. -O3 -Wall -Wextra -pedantic -std=c99 -I../../../sys/include -Itweetnacl common.c tweetnacl/tweetnacl.c randombytes.c ../../../sys/hashes/sha256.c ../../../sys/checksum/fletcher32.c ../../../sys/firmware/firmware.c firmware.c verify.c genkeys.c genmeta.c -o bin/firmware
../../../sys/firmware/firmware.c: In function 'firmware_metadata_print':
../../../sys/firmware/firmware.c:42:30: warning: format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'uint32_t {aka unsigned int}' [-Wformat=]
printf("Firmware Size: %lu\n", metadata->size);
^
../../../sys/firmware/firmware.c:43:32: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'uint32_t {aka unsigned int}' [-Wformat=]
printf("Firmware APPID: %#lx\n", metadata->appid);
^
../../../sys/firmware/firmware.c:44:34: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'uint32_t {aka unsigned int}' [-Wformat=]
printf("Firmware Version: %#lx\n", metadata->version);
^
make: Leaving directory '/home/dimitri/RIOT/dist/tools/firmware_metadata'

Providing default crypto keys to current firmware.
Please provide PUBKEY and SECKEY env variables to use your keys \

Building application "hello-world" for "samr21-xpro" with MCU "samd21".

"make" -C /home/dimitri/RIOT/boards/samr21-xpro
"make" -C /home/dimitri/RIOT/core
"make" -C /home/dimitri/RIOT/cpu/samd21
"make" -C /home/dimitri/RIOT/cpu/cortexm_common
"make" -C /home/dimitri/RIOT/cpu/cortexm_common/periph
"make" -C /home/dimitri/RIOT/cpu/sam0_common
"make" -C /home/dimitri/RIOT/cpu/sam0_common/periph
"make" -C /home/dimitri/RIOT/cpu/samd21/periph
"make" -C /home/dimitri/RIOT/drivers
"make" -C /home/dimitri/RIOT/drivers/periph_common
"make" -C /home/dimitri/RIOT/sys
"make" -C /home/dimitri/RIOT/sys/auto_init
"make" -C /home/dimitri/RIOT/sys/isrpipe
"make" -C /home/dimitri/RIOT/sys/newlib_syscalls_default
"make" -C /home/dimitri/RIOT/sys/pm_layered
"make" -C /home/dimitri/RIOT/sys/tsrb
"make" -C /home/dimitri/RIOT/sys/uart_stdio
text data bss dec hex filename
11428 136 2748 14312 37e8 /home/dimitri/RIOT/examples/hello-world/bin/samr21-xpro/hello-world.elf
make: Entering directory '/home/dimitri/RIOT/bootloader'
BOOTLOADER BUILD
make: Nothing to be done for 'clean'.
Building application "bootloader" for "samr21-xpro" with MCU "samd21".

"make" -C /home/dimitri/RIOT/pkg/tweetnacl
"make" -C /home/dimitri/RIOT/bootloader/bin/pkg/samr21-xpro/tweetnacl
"make" -C /home/dimitri/RIOT/boards/samr21-xpro
"make" -C /home/dimitri/RIOT/core
"make" -C /home/dimitri/RIOT/cpu/samd21
"make" -C /home/dimitri/RIOT/cpu/cortexm_common
"make" -C /home/dimitri/RIOT/cpu/cortexm_common/periph
"make" -C /home/dimitri/RIOT/cpu/sam0_common
"make" -C /home/dimitri/RIOT/cpu/sam0_common/periph
"make" -C /home/dimitri/RIOT/cpu/samd21/periph
"make" -C /home/dimitri/RIOT/drivers
"make" -C /home/dimitri/RIOT/drivers/periph_common
"make" -C /home/dimitri/RIOT/sys
"make" -C /home/dimitri/RIOT/sys/auto_init
"make" -C /home/dimitri/RIOT/sys/checksum
"make" -C /home/dimitri/RIOT/sys/firmware
"make" -C /home/dimitri/RIOT/sys/isrpipe
"make" -C /home/dimitri/RIOT/sys/newlib_syscalls_default
"make" -C /home/dimitri/RIOT/sys/pm_layered
"make" -C /home/dimitri/RIOT/sys/tsrb
"make" -C /home/dimitri/RIOT/sys/uart_stdio
text data bss dec hex filename
18476 168 6464 25108 6214 /home/dimitri/RIOT/bootloader/bin/samr21-xpro/bootloader.elf
/usr/lib/gcc/arm-none-eabi/5.4.1/../../../arm-none-eabi/bin/ld: /home/dimitri/RIOT/bootloader/bin/samr21-xpro/bootloader.elf section .text' will not fit in region rom'
/usr/lib/gcc/arm-none-eabi/5.4.1/../../../arm-none-eabi/bin/ld: region `rom' overflowed by 2092 bytes
collect2: error: ld returned 1 exit status
/home/dimitri/RIOT/makefiles/multislot.mk:134: recipe for target 'bootloader' failed
make: *** [bootloader] Error 1
make: Leaving directory '/home/dimitri/RIOT/bootloader'
/home/dimitri/RIOT/makefiles/multislot.mk:130: die Regel für Ziel „/home/dimitri/RIOT/bootloader/bin/samr21-xpro/bootloader.bin“ scheiterte
make: *** [/home/dimitri/RIOT/bootloader/bin/samr21-xpro/bootloader.bin] Fehler 2

@kYc0o
Copy link
Contributor Author

kYc0o commented Aug 2, 2017

Uhm... did you modify the bootloader? According to the message you're using more ROM than its allowed for the bootloader (16KB). With the default configuration the bootloader should be ~15KB

@ghost
Copy link

ghost commented Aug 2, 2017

No, the bootloader is unchanged.

@kYc0o
Copy link
Contributor Author

kYc0o commented Aug 2, 2017

I just built the same example and it gives me these sizes:

Hello world:

   text	   data	    bss	    dec	    hex	filename
   8612	    136	   2748	  11496	   2ce8	/Users/facosta/git/RIOT2/RIOT/examples/hello-world/bin/samr21-xpro/hello-world.elf

Bootloader:

   text	   data	    bss	    dec	    hex	filename
  15432	    168	   6464	  22064	   5630	/Users/facosta/git/RIOT2/RIOT/bootloader/bin/samr21-xpro/bootloader.elf

I see that you're using arm-none-eabi-gcc 5.4, I was in that version before and the numbers were quite similar... Did you have a special config? because your firmwares are 2K bigger in any situation.

@kYc0o kYc0o force-pushed the multislot_tests branch from 928339c to 9ebe0ba Compare August 2, 2017 12:12
@ghost
Copy link

ghost commented Aug 2, 2017

@kYc0o Thanks, it works with arm-none-eabi-gcc 6.3.1.

@kYc0o
Copy link
Contributor Author

kYc0o commented May 30, 2018

Closing this PR as it's a subset of #8902, that one offers a similar bootloader and the multislot approach.

@kYc0o kYc0o closed this May 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants