Skip to content

Commit 836cfbc

Browse files
committed
Added docs, fixed copyright notice
1 parent efa8d63 commit 836cfbc

9 files changed

Lines changed: 258 additions & 2 deletions

File tree

NOTICE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ More information can be found on the wolfSSL website at www.wolfssl.com.
1616

1717
This product includes software developed at
1818
The Apache Software Foundation (http://www.apache.org/)
19-
and previously released under an Open Source permissive license.
19+
and previously released under the Apache License, Version 2.0.
2020

2121
Portions of this software were developed at
22-
Runtime Inc, copyright 2015 and previously released under an Open Source permissive license.
22+
Runtime Inc, copyright 2015 and previously released under the the Apache License, Version 2.0.

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,73 @@
11
# wolfBoot
22
wolfSSL Secure Bootloader
3+
4+
wolfBoot is a portable, OS-agnostic, secure bootloader solution for 32-bit microcontrollers,
5+
relying on wolfCrypt for firmware authentication, and a modified version of
6+
[mcuboot](https://www.mcuboot.com/)'s *bootutil* library to implement firmware upgrade mechanisms.
7+
8+
Due to the minimalist design of the bootloader and the tiny HAL API, wolfBoot is completely independent
9+
from any OS or bare-metal application, and can be easily ported and integrated in existing embedded software
10+
projects to provide a secure firmware upgrade mechanism.
11+
12+
13+
## Features
14+
- Multi-slot partitioning of the flash device
15+
- Integrity verification of the firmware image(s)
16+
- Authenticity verification of the firmware image(s) using wolfCrypt's Digital Signature Algorithms (DSA)
17+
- Minimalist hardware abstraction layer (HAL) interface to facilitate portability across different vendors/MCUs
18+
- In-place chain-loading of the firmware image in the primary slot
19+
- Copy/swap images from secondary slots into the primary slots to consent firmware upgrade operations
20+
21+
## Components
22+
23+
This repository contains the following components:
24+
- the bootloader
25+
- Ed25519 key generator and image signing tools
26+
- Baremetal test applications
27+
28+
### The bootloader
29+
30+
The bootloader is a memory-safe standalone bare-metal application, designed to run on a generic 32bit MCU,
31+
with no dynamic memory allocation mechanism or linkage to any standard C library.
32+
33+
The core application depends on the following libraries:
34+
- wolfCrypt, which is used to verify the Ed25519 signature of the images
35+
- A modified version of mcuboot's bootutil, to handle the firmware image slots and the upgrade state-machine
36+
- 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
37+
38+
The goal of this application is to perform image verification and/or requested firmware upgrade tasks
39+
before chain-loading the actual firmware from a specific location in flash.
40+
41+
Only ARM Cortex-M is supported at this stage. Support for more architectures and
42+
microcontrollers will be added later.
43+
44+
## Integrating wolfBoot in an existing project
45+
46+
Requirements:
47+
48+
- Provide a HAL implementation for the target platform (see [Hardware Abstraction Layer](docs/HAL.md))
49+
- Decide a flash partition strategy and modify `include/target.h` accordingly (see [Flash partitions](docs/flash_partitions.md)
50+
51+
The following steps are automated in the default `Makefile` target, using the baremetal test
52+
application as an example to create the factory image:
53+
54+
- Create a Ed25519 Key-pair using the `ed25519_keygen` tool
55+
- Compile the bootloader. The public key generated in the step above is included in the build
56+
- Compile the firmware image
57+
- Re-link the firmware to change the entry-point to the start address of the primary partition
58+
- Sign the firmware image using the `ed25519_sign` tool
59+
- Create a factory image by concatenating the bootloader and the firmware image
60+
- Flash the factory image to the target
61+
62+
For more detailed information about the firmware image format, see [Firmware image](docs/firmware_image.md)
63+
64+
## Upgrading the firmware
65+
66+
- Compile the new firmware image, and link it so that its entry point is at the start address of the primary partition
67+
- Sign the firmware using the `ed25519_sign` tool and the private key generated for the factory image
68+
- Transfer the image using a secure connection, and store it to the secondary firmware slot
69+
- Trigger the image swap using bootutil's `boot_set_pending()` function
70+
- Reboot to let the bootloader begin the image swap
71+
72+
For more detailed information about firmware upgrade procedures, see [Firmware Upgrade](docs/firmware_upgrade.md)
73+

docs/HAL.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Hardware abstraction layer
2+
3+
In order to run wolfBoot on a target microcontroller, an implementation of the HAL
4+
must be provided.
5+
6+
The HAL only purposes are allowing write/erase operations from the bootloader
7+
and the application initiating the firmware upgrade through the bootutil library, and
8+
ensuring that the MCU is running at full speed during boot, to optimize the
9+
verification of the signatures.
10+
11+
The implementation of the hardware-specific calls for each platform are grouped in
12+
a single c file in the [hal](hal) directory.
13+
14+
The directory also contains a platform-specific linker script for each supported MCU,
15+
with the same name and the `.ld` extension. This is used to link the bootloader's
16+
firmware on the specific hardware, exporting all the necessary symbols for flash
17+
and RAM boundaries.
18+
19+
## Supported platforms
20+
21+
The following platforms are supported in the current version:
22+
- STM32F4
23+
- nRF52
24+
25+
## API
26+
27+
The Hardware Abstraction Layer (HAL) consists of six function calls
28+
be implemented for each supported target:
29+
30+
`void hal_init(void)`
31+
32+
This function is called by the bootloader at the very beginning of the execution.
33+
Ideally, the implementation provided configures the clock settings for the target
34+
microcontroller, to ensure that it runs at at the required speed to shorten the
35+
time required for the cryptography primitives to verify the firmware images.
36+
37+
`void hal_flash_unlock(void)`
38+
39+
If the IAP interface of the flash memory of the target requires it, this function
40+
is called before every write and erase operations to unlock write access to the
41+
flash. On some targets, this function may be empty.
42+
43+
`int hal_flash_write(uint32_t address, const uint8_t *data, int len)`
44+
45+
This function provides an implementation of the flash write function, using the
46+
target's IAP interface. `address` is the offset from the beginning of the
47+
flash area, `data` is the payload to be stored in the flash using the IAP interface,
48+
and `len` is the size of the payload. `hal_flash_write` should return 0 upon success,
49+
or a negative value in case of failure.
50+
51+
`void hal_flash_lock(void)`
52+
53+
If the IAP interface of the flash memory requires locking/unlocking, this function
54+
restores the flash write protection by excluding write accesses. This function is called
55+
by the bootloader at the end of every write and erase operations.
56+
57+
`int hal_flash_erase(uint32_t address, int len)`
58+
59+
Called by the bootloader to erase part of the flash memory to allow subsequent boots.
60+
Erase operations must be performed via the specific IAP interface of the target microcontroller.
61+
`address` marks the start of the area that the bootloader wants to erase, and `len` specifies
62+
the size of the area to be erased. This function must take into account the geometry of the flash
63+
sectors, and erase all the sectors in between.
64+
65+
`void hal_prepare_boot(void)`
66+
67+
This function is called by the bootloader at a very late stage, before chain-loading the firmware
68+
in the next stage. This can be used to revert all the changes made to the clock settings, to ensure
69+
that the state of the microcontroller is restored to its original settings.
70+
71+

docs/firmware_image.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Firmware image
2+
3+
## Firmware entry point
4+
5+
WolfBoot can only chain-load and execute firmware images from a specific entry point in memory,
6+
which must be specified as the origin of the FLASH memory in the linker script of the embedded
7+
application. This correspond to the first partition in the flash memory.
8+
9+
Multiple firmware images can be created this way, and stored in different partitions. The bootloader
10+
will take care of moving the selected firmware to the first boot partition before chain-loading the image.
11+
12+
Due to the presence of an image header, the entry point of the application has a fixed additional offset
13+
of 256B from the beginning of the flash partition.
14+
15+
## Firmware image header
16+
17+
Each (signed) firmware image is pre-pended with a fixed-size **image header**, containing
18+
useful information about the firmware. The **image header** is padded to fit in 256B, in order
19+
to guarantee that the entry point of the actual firmware is stored on the flash starting from
20+
a 256-Bytes aligned address. This ensures that the bootloader can relocate the vector table before
21+
chain-loading the firmware the interrupt continue to work properly after the boot is complete.
22+
23+
![Image header](docs/png/image_header.png)
24+
25+
*The image header is stored at the beginning of the slot and the actual firmware image starts 256 Bytes after it*
26+
27+
28+
## Firmware trailer
29+
30+
At the end of the actual firmware image, the signing tool stores three trailer "TLV" (type-length-value) records,
31+
respectively containing:
32+
- A hash digest of the firmware, including its firmware header, obtained using SHA-256
33+
- 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.
34+
- The signature obtained by signing the hash digest of the firmware with the factory private key
35+
36+
These three fields are required by the bootloader to verify the integrity and the origin of the firmware image.
37+
38+
![Image trailers](docs/png/image_tlv.png)
39+
40+
*The trailer of a signed firmware contains a TLV header and three TLV records that are used by the bootloader to verify the image*
41+
42+
## Image signing tool
43+
44+
The image signing tool generates the header and trailers for the compiled image, and add them to the output file that can be then
45+
stored on the primary slot on the device.
46+
47+

docs/flash_partitions.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Flash partitions
2+
3+
4+
## Flash memory partitions
5+
6+
To integrate wolfBoot you need to partition the flash into
7+
separate areas (slots), according to the geometry of the flash memory.
8+
9+
Images boundaries **must** be aligned to physical sectors, because the
10+
bootloader erases all the flash sectors before storing a firmware image.
11+
12+
The flash memory of the target is partitioned into the following areas:
13+
14+
- Bootloader partition, at the beginning of the flash
15+
- Primary slot (boot partition) starting at address `FLASH_AREA_IMAGE_0_OFFSET`
16+
- Secondary slot (upgrade partition) starting at address `FLASH_AREA_IMAGE_1_OFFSET`
17+
- Scratch space (swap partition) starting at address `FLASH_AREA_IMAGE_SCRATCH_OFFSET`
18+
19+
A proper partitioning configuration must be set up for the specific use, by setting
20+
the values for offsets and sizes in [include/target.h](include/target.h).
21+
22+
### Bootloader partition
23+
24+
This partition is usually very small, and only contains the bootloader code and data.
25+
Public keys pre-authorized during factory image creations are automatically stored
26+
as part of the firmware image.
27+
28+
### Primary slot (boot partition)
29+
30+
This is the only partition from where it is possible to chain-load and execute a
31+
firmware image. The firmware image must be linked so that its entry-point is at address
32+
`FLASH_AREA_IMAGE_0_OFFSET + 256`.
33+
34+
### Secondary slot (upgrade partition)
35+
36+
The running firmware is responsible of transferring a new firmware image through a secure channel,
37+
and store it in the secondary slot. If an upgrade is initiated, the bootloader will replace or swap
38+
the firmware in the boot partition at the next reboot.
39+
40+
## Example 512KB partitioning on STM32-F407
41+
42+
The example firmware provided in the `test-app` is configured to boot from the primary partition
43+
starting at address 0x20000. The flash layout is provided by the default example using the following
44+
configuration in `target.h`:
45+
46+
```C
47+
#define FLASH_AREA_IMAGE_0_OFFSET 0x20000
48+
#define FLASH_AREA_IMAGE_0_SIZE 0x20000
49+
#define FLASH_AREA_IMAGE_1_OFFSET 0x40000
50+
#define FLASH_AREA_IMAGE_1_SIZE 0x20000
51+
#define FLASH_AREA_IMAGE_SCRATCH_OFFSET 0x60000
52+
#define FLASH_AREA_IMAGE_SCRATCH_SIZE 0x20000
53+
```
54+
55+
which results in the following partition configuration:
56+
57+
![example partitions](docs/png/example_partitions.png)
58+
59+
This configuration demonstrates one of the possible layouts, with the slots
60+
aligned to the beginning of the physical sector on the flash.
61+
62+
The entry point for all the runnable firmware images on this target will be `0x20100`,
63+
256 Bytes after the beginning of the first flash partition. This is due to the presence
64+
of the firmware image header at the beginning of the partition, as explained more in details
65+
in [Firmware image](docs/firmware_image.md)
66+
67+

docs/png/example_partitions.png

20.6 KB
Loading

docs/png/image_header.png

8.94 KB
Loading

docs/png/image_tlv.png

14.4 KB
Loading

src/.run.c.swp

-16 KB
Binary file not shown.

0 commit comments

Comments
 (0)