Added docs, fixed copyright notice

pull/1/head
Daniele Lacamera 2018-10-15 07:40:49 +02:00
parent efa8d63200
commit 836cfbc608
9 changed files with 258 additions and 2 deletions

4
NOTICE
View File

@ -16,7 +16,7 @@ More information can be found on the wolfSSL website at www.wolfssl.com.
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/)
and previously released under an Open Source permissive license.
and previously released under the Apache License, Version 2.0.
Portions of this software were developed at
Runtime Inc, copyright 2015 and previously released under an Open Source permissive license.
Runtime Inc, copyright 2015 and previously released under the the Apache License, Version 2.0.

View File

@ -1,2 +1,73 @@
# wolfBoot
wolfSSL Secure Bootloader
wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers,
relying on wolfCrypt for firmware authentication, and a modified version of
[mcuboot](https://www.mcuboot.com/)'s *bootutil* library to implement firmware upgrade mechanisms.
Due to the minimalist design of the bootloader and the tiny HAL API, wolfBoot is completely independent
from any OS or bare-metal application, and can be easily ported and integrated in existing embedded software
projects to provide a secure firmware upgrade mechanism.
## Features
- Multi-slot partitioning of the flash device
- Integrity verification of the firmware image(s)
- Authenticity verification of the firmware image(s) using wolfCrypt's Digital Signature Algorithms (DSA)
- Minimalist hardware abstraction layer (HAL) interface to facilitate portability across different vendors/MCUs
- In-place chain-loading of the firmware image in the primary slot
- Copy/swap images from secondary slots into the primary slots to consent firmware upgrade operations
## Components
This repository contains the following components:
- the bootloader
- Ed25519 key generator and image signing tools
- Baremetal test applications
### The bootloader
The bootloader is a memory-safe standalone bare-metal application, designed to run on a generic 32bit MCU,
with no dynamic memory allocation mechanism or linkage to any standard C library.
The core application depends on the following libraries:
- wolfCrypt, which is used to verify the Ed25519 signature of the images
- A modified version of mcuboot's bootutil, to handle the firmware image slots and the upgrade state-machine
- A minimalist Hardware Abstraction Layer, with an implementation provided for the supported target, which is in charge for IAP flash access and clock setting on the specific MCU
The goal of this application is to perform image verification and/or requested firmware upgrade tasks
before chain-loading the actual firmware from a specific location in flash.
Only ARM Cortex-M is supported at this stage. Support for more architectures and
microcontrollers will be added later.
## Integrating wolfBoot in an existing project
Requirements:
- Provide a HAL implementation for the target platform (see [Hardware Abstraction Layer](docs/HAL.md))
- Decide a flash partition strategy and modify `include/target.h` accordingly (see [Flash partitions](docs/flash_partitions.md)
The following steps are automated in the default `Makefile` target, using the baremetal test
application as an example to create the factory image:
- Create a Ed25519 Key-pair using the `ed25519_keygen` tool
- Compile the bootloader. The public key generated in the step above is included in the build
- Compile the firmware image
- Re-link the firmware to change the entry-point to the start address of the primary partition
- Sign the firmware image using the `ed25519_sign` tool
- Create a factory image by concatenating the bootloader and the firmware image
- Flash the factory image to the target
For more detailed information about the firmware image format, see [Firmware image](docs/firmware_image.md)
## Upgrading the firmware
- Compile the new firmware image, and link it so that its entry point is at the start address of the primary partition
- Sign the firmware using the `ed25519_sign` tool and the private key generated for the factory image
- Transfer the image using a secure connection, and store it to the secondary firmware slot
- Trigger the image swap using bootutil's `boot_set_pending()` function
- Reboot to let the bootloader begin the image swap
For more detailed information about firmware upgrade procedures, see [Firmware Upgrade](docs/firmware_upgrade.md)

71
docs/HAL.md 100644
View File

@ -0,0 +1,71 @@
# Hardware abstraction layer
In order to run wolfBoot on a target microcontroller, an implementation of the HAL
must be provided.
The HAL only purposes are allowing write/erase operations from the bootloader
and the application initiating the firmware upgrade through the bootutil library, and
ensuring that the MCU is running at full speed during boot, to optimize the
verification of the signatures.
The implementation of the hardware-specific calls for each platform are grouped in
a single c file in the [hal](hal) directory.
The directory also contains a platform-specific linker script for each supported MCU,
with the same name and the `.ld` extension. This is used to link the bootloader's
firmware on the specific hardware, exporting all the necessary symbols for flash
and RAM boundaries.
## Supported platforms
The following platforms are supported in the current version:
- STM32F4
- nRF52
## API
The Hardware Abstraction Layer (HAL) consists of six function calls
be implemented for each supported target:
`void hal_init(void)`
This function is called by the bootloader at the very beginning of the execution.
Ideally, the implementation provided configures the clock settings for the target
microcontroller, to ensure that it runs at at the required speed to shorten the
time required for the cryptography primitives to verify the firmware images.
`void hal_flash_unlock(void)`
If the IAP interface of the flash memory of the target requires it, this function
is called before every write and erase operations to unlock write access to the
flash. On some targets, this function may be empty.
`int hal_flash_write(uint32_t address, const uint8_t *data, int len)`
This function provides an implementation of the flash write function, using the
target's IAP interface. `address` is the offset from the beginning of the
flash area, `data` is the payload to be stored in the flash using the IAP interface,
and `len` is the size of the payload. `hal_flash_write` should return 0 upon success,
or a negative value in case of failure.
`void hal_flash_lock(void)`
If the IAP interface of the flash memory requires locking/unlocking, this function
restores the flash write protection by excluding write accesses. This function is called
by the bootloader at the end of every write and erase operations.
`int hal_flash_erase(uint32_t address, int len)`
Called by the bootloader to erase part of the flash memory to allow subsequent boots.
Erase operations must be performed via the specific IAP interface of the target microcontroller.
`address` marks the start of the area that the bootloader wants to erase, and `len` specifies
the size of the area to be erased. This function must take into account the geometry of the flash
sectors, and erase all the sectors in between.
`void hal_prepare_boot(void)`
This function is called by the bootloader at a very late stage, before chain-loading the firmware
in the next stage. This can be used to revert all the changes made to the clock settings, to ensure
that the state of the microcontroller is restored to its original settings.

View File

@ -0,0 +1,47 @@
# Firmware image
## Firmware entry point
WolfBoot can only chain-load and execute firmware images from a specific entry point in memory,
which must be specified as the origin of the FLASH memory in the linker script of the embedded
application. This correspond to the first partition in the flash memory.
Multiple firmware images can be created this way, and stored in different partitions. The bootloader
will take care of moving the selected firmware to the first boot partition before chain-loading the image.
Due to the presence of an image header, the entry point of the application has a fixed additional offset
of 256B from the beginning of the flash partition.
## Firmware image header
Each (signed) firmware image is pre-pended with a fixed-size **image header**, containing
useful information about the firmware. The **image header** is padded to fit in 256B, in order
to guarantee that the entry point of the actual firmware is stored on the flash starting from
a 256-Bytes aligned address. This ensures that the bootloader can relocate the vector table before
chain-loading the firmware the interrupt continue to work properly after the boot is complete.
![Image header](docs/png/image_header.png)
*The image header is stored at the beginning of the slot and the actual firmware image starts 256 Bytes after it*
## Firmware trailer
At the end of the actual firmware image, the signing tool stores three trailer "TLV" (type-length-value) records,
respectively containing:
- A hash digest of the firmware, including its firmware header, obtained using SHA-256
- A hash digest of the public key that can be used by the bootloader to verify the authenticity of the firmware. The key must already be stored with the bootloader, and this field is only used as sanity check.
- The signature obtained by signing the hash digest of the firmware with the factory private key
These three fields are required by the bootloader to verify the integrity and the origin of the firmware image.
![Image trailers](docs/png/image_tlv.png)
*The trailer of a signed firmware contains a TLV header and three TLV records that are used by the bootloader to verify the image*
## Image signing tool
The image signing tool generates the header and trailers for the compiled image, and add them to the output file that can be then
stored on the primary slot on the device.

View File

@ -0,0 +1,67 @@
# Flash partitions
## Flash memory partitions
To integrate wolfBoot you need to partition the flash into
separate areas (slots), according to the geometry of the flash memory.
Images boundaries **must** be aligned to physical sectors, because the
bootloader erases all the flash sectors before storing a firmware image.
The flash memory of the target is partitioned into the following areas:
- Bootloader partition, at the beginning of the flash
- Primary slot (boot partition) starting at address `FLASH_AREA_IMAGE_0_OFFSET`
- Secondary slot (upgrade partition) starting at address `FLASH_AREA_IMAGE_1_OFFSET`
- Scratch space (swap partition) starting at address `FLASH_AREA_IMAGE_SCRATCH_OFFSET`
A proper partitioning configuration must be set up for the specific use, by setting
the values for offsets and sizes in [include/target.h](include/target.h).
### Bootloader partition
This partition is usually very small, and only contains the bootloader code and data.
Public keys pre-authorized during factory image creations are automatically stored
as part of the firmware image.
### Primary slot (boot partition)
This is the only partition from where it is possible to chain-load and execute a
firmware image. The firmware image must be linked so that its entry-point is at address
`FLASH_AREA_IMAGE_0_OFFSET + 256`.
### Secondary slot (upgrade partition)
The running firmware is responsible of transferring a new firmware image through a secure channel,
and store it in the secondary slot. If an upgrade is initiated, the bootloader will replace or swap
the firmware in the boot partition at the next reboot.
## Example 512KB partitioning on STM32-F407
The example firmware provided in the `test-app` is configured to boot from the primary partition
starting at address 0x20000. The flash layout is provided by the default example using the following
configuration in `target.h`:
```C
#define FLASH_AREA_IMAGE_0_OFFSET 0x20000
#define FLASH_AREA_IMAGE_0_SIZE 0x20000
#define FLASH_AREA_IMAGE_1_OFFSET 0x40000
#define FLASH_AREA_IMAGE_1_SIZE 0x20000
#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x60000
#define FLASH_AREA_IMAGE_SCRATCH_SIZE 0x20000
```
which results in the following partition configuration:
![example partitions](docs/png/example_partitions.png)
This configuration demonstrates one of the possible layouts, with the slots
aligned to the beginning of the physical sector on the flash.
The entry point for all the runnable firmware images on this target will be `0x20100`,
256 Bytes after the beginning of the first flash partition. This is due to the presence
of the firmware image header at the beginning of the partition, as explained more in details
in [Firmware image](docs/firmware_image.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.