Initial commit

Initial commit.
This commit is contained in:
kntran1
2026-03-23 14:40:39 -05:00
parent e84b2b4166
commit 4e2a5258a5
872 changed files with 165227 additions and 0 deletions

2
bootloader/mcuboot/docs/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.sass-cache/
_site/

View File

@@ -0,0 +1 @@
docs.mcuboot.com

View File

@@ -0,0 +1,26 @@
source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
# bundle exec jekyll serve
# This is the default theme for new Jekyll sites. You may change this to anything you like.
# gem "jekyll-theme-cayman", "~> 0.1"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
gem "github-pages", group: :jekyll_plugins
# If you have any plugins, put them here!
# group :jekyll_plugins do
# gem "jekyll-feed", "~> 0.6"
# end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem "jemoji", "~> 0.12.0"
gem "webrick", "~> 1.8"

View File

@@ -0,0 +1,266 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (7.0.7.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
commonmarker (0.23.10)
concurrent-ruby (1.2.2)
dnsruby (1.70.0)
simpleidn (~> 0.2.1)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
ethon (0.16.0)
ffi (>= 1.15.0)
eventmachine (1.2.7)
execjs (2.8.1)
faraday (2.7.10)
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-net_http (3.0.2)
ffi (1.15.5)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (228)
github-pages-health-check (= 1.17.9)
jekyll (= 3.9.3)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.4.0)
jekyll-default-layout (= 0.1.4)
jekyll-feed (= 0.15.1)
jekyll-gist (= 1.5.0)
jekyll-github-metadata (= 2.13.0)
jekyll-include-cache (= 0.2.1)
jekyll-mentions (= 1.6.0)
jekyll-optional-front-matter (= 0.3.2)
jekyll-paginate (= 1.1.0)
jekyll-readme-index (= 0.3.0)
jekyll-redirect-from (= 0.16.0)
jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.3)
jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.8.0)
jekyll-sitemap (= 1.4.0)
jekyll-swiss (= 1.0.0)
jekyll-theme-architect (= 0.2.0)
jekyll-theme-cayman (= 0.2.0)
jekyll-theme-dinky (= 0.2.0)
jekyll-theme-hacker (= 0.2.0)
jekyll-theme-leap-day (= 0.2.0)
jekyll-theme-merlot (= 0.2.0)
jekyll-theme-midnight (= 0.2.0)
jekyll-theme-minimal (= 0.2.0)
jekyll-theme-modernist (= 0.2.0)
jekyll-theme-primer (= 0.6.0)
jekyll-theme-slate (= 0.2.0)
jekyll-theme-tactile (= 0.2.0)
jekyll-theme-time-machine (= 0.2.0)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.12.0)
kramdown (= 2.3.2)
kramdown-parser-gfm (= 1.1.0)
liquid (= 4.0.4)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.13.6, < 2.0)
rouge (= 3.26.0)
terminal-table (~> 1.4)
github-pages-health-check (1.17.9)
addressable (~> 2.3)
dnsruby (~> 1.60)
octokit (~> 4.0)
public_suffix (>= 3.0, < 5.0)
typhoeus (~> 1.3)
html-pipeline (2.14.3)
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.8.0)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
jekyll (3.9.3)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (>= 0.7, < 2)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 2.0)
kramdown (>= 1.17, < 3)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
safe_yaml (~> 1.0)
jekyll-avatar (0.7.0)
jekyll (>= 3.0, < 5.0)
jekyll-coffeescript (1.1.1)
coffee-script (~> 2.2)
coffee-script-source (~> 1.11.1)
jekyll-commonmark (1.4.0)
commonmarker (~> 0.22)
jekyll-commonmark-ghpages (0.4.0)
commonmarker (~> 0.23.7)
jekyll (~> 3.9.0)
jekyll-commonmark (~> 1.4.0)
rouge (>= 2.0, < 5.0)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
jekyll-feed (0.15.1)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
jekyll-github-metadata (2.13.0)
jekyll (>= 3.4, < 5.0)
octokit (~> 4.0, != 4.4.0)
jekyll-include-cache (0.2.1)
jekyll (>= 3.7, < 5.0)
jekyll-mentions (1.6.0)
html-pipeline (~> 2.3)
jekyll (>= 3.7, < 5.0)
jekyll-optional-front-matter (0.3.2)
jekyll (>= 3.0, < 5.0)
jekyll-paginate (1.1.0)
jekyll-readme-index (0.3.0)
jekyll (>= 3.0, < 5.0)
jekyll-redirect-from (0.16.0)
jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-remote-theme (0.4.3)
addressable (~> 2.0)
jekyll (>= 3.5, < 5.0)
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
rubyzip (>= 1.3.0, < 3.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.8.0)
jekyll (>= 3.8, < 5.0)
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-swiss (1.0.0)
jekyll-theme-architect (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-cayman (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-dinky (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-merlot (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-midnight (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.6.0)
jekyll (> 3.5, < 5.0)
jekyll-github-metadata (~> 2.9)
jekyll-seo-tag (~> 2.0)
jekyll-theme-slate (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-tactile (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-time-machine (0.2.0)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-titles-from-headings (0.5.3)
jekyll (>= 3.3, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
jemoji (0.12.0)
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
kramdown (2.3.2)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.4)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.8.6)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.19.0)
nokogiri (1.16.5)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
octokit (4.25.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (4.0.7)
racc (1.7.3)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rexml (3.2.8)
strscan (>= 3.0.9)
rouge (3.26.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
simpleidn (0.2.1)
unf (~> 0.1.4)
strscan (3.1.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (1.8.0)
webrick (1.8.1)
PLATFORMS
ruby
DEPENDENCIES
github-pages
jemoji (~> 0.12.0)
tzinfo-data
webrick (~> 1.8)
BUNDLED WITH
1.17.2

View File

@@ -0,0 +1,195 @@
# Porting how-to
This document describes the requirements and necessary steps required to port
`MCUboot` to a new target `OS`.
# Requirements
* `MCUboot` requires a configuration file, which can be included as
mcuboot_config/mcuboot_config.h, which configures various options
(that begin with MCUBOOT_).
* `MCUboot` requires that the target provides a `flash` API with ability to
get the flash's minimum write size, and read/write/erase individual sectors.
* `MCUboot` doesn't bundle a cryptographic library, which means the target
OS must already have it bundled. The supported libraries at the moment are
either `Mbed TLS` or the set `tinycrypt` + `Mbed TLS` (where `Mbed TLS` is
used to provide functionality not existing in `tinycrypt`).
# Steps to port
## Main app and calling the bootloader
From the perspective of the target OS, the bootloader can be seen as a library,
so an entry point must be provided. This is likely a typical `app` for the
target OS, and it must call the following function to run the bootloader:
```c
int boot_go(struct boot_rsp *rsp);
```
This function is located at `boot/bootutil/loader.c` and receives a `struct
boot_rsp` pointer. The `struct boot_rsp` is defined as:
```c
struct boot_rsp {
/** A pointer to the header of the image to be executed. */
const struct image_header *br_hdr;
/**
* The flash offset of the image to execute. Indicates the position of
* the image header.
*/
uint8_t br_flash_id;
uint32_t br_image_addr;
};
```
After running the management functions of the bootloader, `boot_go` returns
an initialized `boot_rsp` which has pointers to the location of the image
where the target firmware is located which can be used to jump to.
## Configuration file
You must provide a file, mcuboot_config/mcuboot_config.h. This is
included by several files in the "library" portion of MCUboot; it
provides preprocessor definitions that configure the library's
build.
See the file samples/mcuboot_config/mcuboot_config.template.h for a
starting point and more information. This is a good place to convert
settings in your environment's configuration system to those required
by MCUboot. For example, Mynewt uses MYNEWT_VAL() and Zephyr uses
Kconfig; these configuration systems are converted to MCUBOOT_ options
in the following files:
- boot/zephyr/include/mcuboot_config/mcuboot_config.h
- boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h
## Flash Map
The bootloader requires to be able to address flash regions where the code
for MCUboot and images of applications are stored, in system-agnostic way.
For that purpose the MCUboot uses ID, which is integer (uint8_t) number
that should uniquely identify each flash region.
Such flash regions are served by object of `const struct flash_area` type while
layout of these objects is gathered under `flash_map`.
The common code of MCUboot, that is non-system specific, does not directly
access contents of that object and never modifies it, instead it calls
`flash_area_` API to perform any actions on that object.
This way systems are free to implement internal logic of flash map or define
`struct flash_area` as they wish; the only restriction is that ID should be
uniquely tied to region characterized by device, offset and size.
Changes to common MCUboot code should not affect system specific internals
of flash map, on the other side system specific code, within MCUboot, is
is not restricted from directly accessing `struct flash_area` elements.
An implementation of `struct flash_area` may take form of:
```c
struct flash_area {
uint8_t fa_id; /** The slot/scratch identification */
uint8_t fa_device_id; /** The device id (usually there's only one) */
uint16_t pad16;
uint32_t fa_off; /** The flash offset from the beginning */
uint32_t fa_size; /** The size of this sector */
};
```
The above example of structure hold all information that is currently required
by MCUboot, although the MCUboot will not be trying to access them directly,
instead a system is required to provide following mandatory getter functions:
```c
/*< Obtains ID of the flash area characterized by `fa` */
int flash_area_get_id(const struct flash_area *fa);
/*< Obtains ID of a device the flash area `fa` described region resides on */
int flash_area_get_device_id(const struct flash_area *fa)
/*< Obtains offset, from the beginning of a device, the flash area described
* region starts at */
uint32_t flash_area_get_off(const struct flash_area *fa)
/*< Obtains size, from the offset, of the flash area `fa` characterized region */
uint32_t flash_area_get_size(const struct flash_area *fa)
```
The MCUboot common code uses following defines that should be defined by system
specific header files and are used to identify destination of flash area by ID:
```c
/* Independent from multiple image boot */
#define FLASH_AREA_BOOTLOADER 0
#define FLASH_AREA_IMAGE_SCRATCH 3
```
```c
/* Flash area IDs of the first image in case of multiple images */
#define FLASH_AREA_IMAGE_PRIMARY 1
#define FLASH_AREA_IMAGE_SECONDARY 2
```
```c
/* Flash area IDs of the second image in case of multiple images */
#define FLASH_AREA_IMAGE_PRIMARY 5
#define FLASH_AREA_IMAGE_SECONDARY 6
```
The numbers, given above, are provided as an example and depend on system
implementation.
The main, also required, set of API functions that perform operations on
flash characterized by `struct flash_area` objects is as follows:
```c
/*< Opens the area for use. id is one of the `fa_id`s */
int flash_area_open(uint8_t id, const struct flash_area **);
void flash_area_close(const struct flash_area *);
/*< Reads `len` bytes of flash memory at `off` to the buffer at `dst` */
int flash_area_read(const struct flash_area *, uint32_t off, void *dst,
uint32_t len);
/*< Writes `len` bytes of flash memory at `off` from the buffer at `src` */
int flash_area_write(const struct flash_area *, uint32_t off,
const void *src, uint32_t len);
/*< Erases `len` bytes of flash memory at `off` */
int flash_area_erase(const struct flash_area *, uint32_t off, uint32_t len);
/*< Returns this `flash_area`s alignment */
uint32_t flash_area_align(const struct flash_area *);
/*< What is value is read from erased flash bytes. */
uint8_t flash_area_erased_val(const struct flash_area *);
/*< Given flash area ID, return info about sectors within the area. */
int flash_area_get_sectors(int fa_id, uint32_t *count,
struct flash_sector *sectors);
/*< Returns the `fa_id` for slot, where slot is 0 (primary) or 1 (secondary).
`image_index` (0 or 1) is the index of the image. Image index is
relevant only when multi-image support support is enabled */
int flash_area_id_from_multi_image_slot(int image_index, int slot);
/*< Returns the slot (0 for primary or 1 for secondary), for the supplied
`image_index` and `area_id`. `area_id` is unique and is represented by
`fa_id` in the `flash_area` struct. */
int flash_area_id_to_multi_image_slot(int image_index, int area_id);
```
---
***Note***
*As of writing, it is possible that MCUboot will open a flash area multiple times simultaneously (through nested calls to `flash_area_open`). As a result, MCUboot may call `flash_area_close` on a flash area that is still opened by another part of MCUboot. As a workaround when porting, it may be necessary to implement a counter of the number of times a given flash area has been opened by MCUboot. The `flash_area_close` implementation should only fully deinitialize the underlying flash area when the open counter is decremented to 0. See [this GitHub PR](https://github.com/mcu-tools/mcuboot/pull/894/) for a more detailed discussion.*
---
## Memory management for Mbed TLS
`Mbed TLS` employs dynamic allocation of memory, making use of the pair
`calloc/free`. If `Mbed TLS` is to be used for crypto, your target RTOS
needs to provide this pair of function.
To configure the what functions are called when allocating/deallocating
memory `Mbed TLS` uses the following call:
```
int mbedtls_platform_set_calloc_free (void *(*calloc_func)(size_t, size_t),
void (*free_func)(void *));
```
For reference see [Mbed TLS platform.h](https://tls.mbed.org/api/platform_8h.html).
If your system already provides functions with compatible signatures, those can
be used directly here, otherwise create new functions that glue to your
`calloc/free` implementations.

View File

@@ -0,0 +1,56 @@
# Project security policy
The MCUboot team takes security, vulnerabilities, and weaknesses
seriously.
## Reporting security issues
The preferred way to report security issues with MCUboot is via the "Report a
security vulnerability" button on the main [security
page](https://github.com/mcu-tools/mcuboot/security).
You can also directly contact the following maintainers of the project:
- David Brown: davidb@davidb.org or david.brown@linaro.org
- Fabio Utzig: utzig@apache.org
If you wish to send an encrypted email, you may use these PGP keys:
```
pub rsa4096 2011-10-14 [SC]
DAFD760825AE2636AEA9CB19E6BA9F5C5E54DF82
uid [ultimate] David Brown <davidb@davidb.org>
uid [ultimate] David Brown <david.brown@linaro.org>
sub rsa4096 2011-10-14 [E]
```
and
```
pub rsa4096 2017-07-28 [SC]
126087C7E725625BC7E89CC7537097EDFD4A7339
uid [ unknown] Fabio Utzig <utzig@apache.org>
uid [ unknown] Fabio Utzig <utzig@utzig.org>
sub rsa4096 2017-07-28 [E]
```
Please include the word "SECURITY" as well as "MCUboot" in the subject
of any message.
We will make our best effort to respond in a timely manner. Most
vulnerabilities found within published code will undergo an embargo of
90 days to allow time fixes to be developed and deployed.
## Vulnerability advisories
Vulnerability reports and published fixes will be reported as follows:
- Issues will be entered into MCUboot's [security advisory
system](https://github.com/mcu-tools/mcuboot/security/advisories) on GitHub, with
the interested parties (including the reporter) added as viewers.
- The release notes will contain a reference to any allocated CVE(s).
- When the embargo is lifted, the security advisory page will be made
public, and the public CVE database will be updated with all
relevant information.

View File

@@ -0,0 +1,89 @@
# Patch submission
The development of MCUboot takes place in the [MCUboot GitHub
repository](https://github.com/mcu-tools/mcuboot).
To submit patches, use GitHub pull requests.
Each commit has to have, in the commit message, a "Signed-off-by" line
that mentions the author (and the committer, if that is different). You
must add this line at the end of the commit text, separated by a blank
line. You can also add a line linking the commit to a specific GitHub
issue, as this section supports multiple lines, similarly to RFC-2822.
The supported trailer lines are structured as follows:
- A line that indicates that the signer agrees to the "Developer
Certificate of Origin" located at the bottom of this page:
```
Signed-off-by: Developer Name <devname@example.com>
```
- A line that links this commit to specific GitHub issues, if present:
```
Keyword #GH_issue_number
```
For more details about linking a GitHub pull request to a GitHub issue,
see this [link]
(https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue).
## Release notes
To facilitate creating release notes at release time, all non-trivial
changes must include a release note snippet in the pull request.
This can be either a separate commit, or as part of a single commit
(generally, if there are multiple commits to the pull request, the
release note snippet should be a separate commit, and a pull request
that is a single commit can include the release note snippet in that
commit). In either case, the release notes must be included in the
same PR that makes the given change.
The release notes should be placed in the `docs/release-notes.d`
directory. Please see the readme file in that directory for specifics.
## Developer certificate of origin
The following is the "Developer Certificate of Origin":
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```

View File

@@ -0,0 +1,3 @@
theme: jekyll-theme-cayman
plugins:
- jemoji

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
# ECDSA signature format
When the ECDSA SECP256R1 (EC256) signature support was added to MCUboot, a
shortcut was taken, and these signatures were padded to make them
always a fixed length. Unfortunately, this padding was done in a way
that is not easily reversible. Some crypto libraries (specifically, Mbed
TLS) are fairly strict about the formatting of the ECDSA signature.
There are two ways to fix this:
- Use a reversible padding scheme. This solution requires
at least one pad byte to always be added (to set the length). This
padding would be somewhat incompatible across versions (older
EC256 would work, while newer MCUboot code would reject old
signatures. The EC code would work reliably only in the new
combination).
- Remove the padding entirely. Depending on the tool used, this solution
requires some rethinking of how TLV generation is implemented so
that the length does not need to be known until the signature is
generated. These tools are usually written in higher-level
languages, so this change should not be difficult.
However, this will also break compatibility with older versions,
because images generated with newer tools will not
work with older versions of MCUboot.
This document proposes a multi-stage approach to give a transition
period:
1. Add a `--no-pad-sig` argument to the sign command in
`imgtool.py`.
Without this argument, the images are padded with the
existing scheme. With this argument, the ECDSA is encoded
without any padding. The `--pad-sig` argument is also
accepted, but it is already the default.
2. MCUboot will be modified to allow unpadded signatures right away.
The existing EC256 implementations will still work (with or
without padding), and the existing EC implementation will be able
to accept padded and unpadded signatures.
3. An Mbed TLS implementation of EC256 can be added, but it will require
the `--no-pad-sig` signature to be able to boot all generated
images. Without the argument, 3 out of 4 images generated will have
padding and will be considered invalid.
After one or more MCUboot release cycles and announcements in the
relevant channels, the arguments to `imgtool.py` will change:
- `--no-pad-sig` will still be accepted but will have no effect.
- `--pad-sig` will now bring back the old padding behavior.
This will require an update to any scripts that will rely on the default
behavior, but will not specify a specific version of imgtool.
The signature generation in the simulator can be changed at the same
time the boot code begins to accept unpadded signatures. The simulator is
always run out of the same tree as the MCUboot code, so there should
not be any compatibility issues.
## Background
ECDSA signatures are encoded as ASN.1, notably with the signature
itself encoded as follows:
```
ECDSA-Sig-Value ::= SEQUENCE {
r INTEGER,
s INTEGER
}
```
Both `r` and `s` are 256-bit numbers. Because these are
unsigned numbers that are being encoded in ASN.1 as signed values, if
the high bit of the number is set, the DER-encoded representation will
require 33 bytes instead of 32. This means that the length of the
signature will vary by a couple of bytes, depending on whether one or
both of these numbers have the high bit set.
Originally, MCUboot added padding to the entire signature and just
removed any trailing 0 bytes from the data block. This turned out to be fine 255 out of 256
times, each time the last byte of the signature was non-zero, but if the
signature ended in a zero, MCUboot would remove too many bytes and render the
signature invalid.
The correct approach here is to accept that ECDSA signatures are of
variable length, and to make sure that we can handle them as such.

View File

@@ -0,0 +1,175 @@
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-
-->
# Encrypted images
## [Rationale](#rationale)
To provide confidentiality of image data while in transport to the
device or while residing on an external flash, `MCUboot` has support
for encrypting/decrypting images on-the-fly while upgrading.
The image header needs to flag this image as `ENCRYPTED` (0x04) and
a TLV with the key must be present in the image. When upgrading the
image from the `secondary slot` to the `primary slot` it is automatically
decrypted (after validation). If swap upgrades are enabled, the image
located in the `primary slot`, also having the `ENCRYPTED` flag set and the
TLV present, is re-encrypted while swapping to the `secondary slot`.
## [Threat model](#threat-model)
The encrypted image support is supposed to allow for confidentiality
if the image is not residing on the device or is written to external
storage, eg a SPI flash being used for the secondary slot.
It does not protect against the possibility of attaching a JTAG and
reading the internal flash memory, or using some attack vector that
enables dumping the internal flash in any way.
Since decrypting requires a private key (or secret if using symmetric
crypto) to reside inside the device, it is the responsibility of the
device manufacturer to guarantee that this key is already in the device
and not possible to extract.
## [Design](#design)
When encrypting an image, only the payload (FW) is encrypted. The header,
TLVs are still sent as plain data.
Hashing and signing also remain functionally the same way as before,
applied over the un-encrypted data. Validation on encrypted images, checks
that the encrypted flag is set and TLV data is OK, then it decrypts each
image block before sending the data to the hash routines.
The image is encrypted using AES-CTR-128 or AES-CTR-256, with a counter
that starts from zero (over the payload blocks) and increments by 1 for each
16-byte block. AES-CTR was chosen for speed/simplicity and allowing for any
block to be encrypted/decrypted without requiring knowledge of any other
block (allowing for simple resume operations on swap interruptions).
The key used is a randomized when creating a new image, by `imgtool` or
`newt`. This key should never be reused and no checks are done for this,
but randomizing a 16-byte block with a TRNG should make it highly
improbable that duplicates ever happen.
To distribute this AES-CTR key, new TLVs were defined. The key can be
encrypted using either RSA-OAEP, AES-KW (128 or 256 bits depending on the
AES-CTR key length), ECIES-P256 or ECIES-X25519.
For RSA-OAEP a new TLV with value `0x30` is added to the image, for
AES-KW a new TLV with value `0x31` is added to the image, for
ECIES-P256 a new TLV with value `0x32` is added, and for ECIES-X25519 a
newt TLV with value `0x33` is added. The contents of those TLVs
are the results of applying the given operations over the AES-CTR key.
## [ECIES encryption](#ecies-encryption)
ECIES follows a well defined protocol to generate an encryption key. There are
multiple standards which differ only on which building blocks are used; for
MCUboot we settled on some primitives that are easily found on our crypto
libraries. The whole key encryption can be summarized as:
* Generate a new private key and derive the public key; when using ECIES-P256
this is a secp256r1 keypair, when using ECIES-X25519 this will be a x25519
keypair. Those keys will be our ephemeral keys.
* Generate a new secret (DH) using the ephemeral private key and the public key
that corresponds to the private key embedded in the HW.
* Derive the new keys from the secret using HKDF (built on HMAC-SHA256). We
are not using a `salt` and using an `info` of `MCUBoot_ECIES_v1`, generating
48 bytes of key material.
* A new random encryption key is generated (for AES). This is
the AES key used to encrypt the images.
* The key is encrypted with AES-128-CTR or AES-256-CTR and a `nonce` of 0 using
the first 16 bytes of key material generated previously by the HKDF.
* The encrypted key now goes through a HMAC-SHA256 using the remaining 32
bytes of key material from the HKDF.
The final TLV is built from the 65 bytes for ECIES-P256 or 32 bytes for
ECIES-X25519, which correspond to the ephemeral public key, followed by the
32 bytes of MAC tag and the 16 or 32 bytes of the encrypted key, resulting in
a TLV of 113 or 129 bytes for ECIES-P256 and 80 or 96 bytes for ECIES-X25519.
The implemenation of ECIES-P256 is named ENC_EC256 in the source code and
artifacts while ECIES-X25519 is named ENC_X25519.
## [Upgrade process](#upgrade-process)
When starting a new upgrade process, `MCUboot` checks that the image in the
`secondary slot` has the `ENCRYPTED` flag set and has the required TLV with the
encrypted key. It then uses its internal private/secret key to decrypt
the TLV containing the key. Given that no errors are found, it will then
start the validation process, decrypting the blocks before check. A good
image being determined, the upgrade consists in reading the blocks from
the `secondary slot`, decrypting and writing to the `primary slot`.
If swap using scratch is used for the upgrade process, the decryption happens
when copying the content of the scratch area to the `primary slot`, which means
the scratch area does not contain the image unencrypted. However, unless
`MCUBOOT_SWAP_SAVE_ENCTLV` is enabled, the decryption keys are stored in
plaintext in the scratch area. Therefore, `MCUBOOT_SWAP_SAVE_ENCTLV` must be
enabled if the scratch area does not reside in the internal flash memory of the
MCU, to avoid attacks that could interrupt the upgrade and read the plaintext
decryption keys from external flash memory.
Also when swap is used, the image in the `primary slot` is checked for
presence of the `ENCRYPTED` flag and the key TLV. If those are present the
sectors are re-encrypted when copying from the `primary slot` to
the `secondary slot`.
---
***Note***
*Each encrypted image must have its own key TLV that should be unique*
*and used only for this particular image.*
---
Also when swap method is employed, the sizes of both images are saved to
the status area just before starting the upgrade process, because it
would be very hard to determine this information when an interruption
occurs and the information is spread across multiple areas.
## [Creating your keys with imgtool](#creating-your-keys-with-imgtool)
`imgtool` can generate keys by using `imgtool keygen -k <output.pem> -t <type>`,
where type can be one of `rsa-2048`, `rsa-3072`, `ecdsa-p256`
or `ed25519`. This will generate a keypair or private key.
To extract the public key in source file form, use
`imgtool getpub -k <input.pem> -e <encoding>`, where `encoding` can be one of
`lang-c` or `lang-rust` (defaults to `lang-c`). To extract a public key in PEM
format, use `imgtool getpub -k <input.pem> -e pem`.
If using AES-KW, follow the steps in the next section to generate the
required keys.
## [Creating your keys with Unix tooling](#creating-your-keys-with-unix-tooling)
* If using RSA-OAEP, generate a keypair following steps similar to those
described in [signed_images](signed_images.md) to create RSA keys.
* If using ECIES-P256, generate a keypair following steps similar to those
described in [signed_images](signed_images.md) to create ECDSA256 keys.
* If using ECIES-X25519, generate a private key passing the option `-t x25519`
to `imgtool keygen` command. To generate public key PEM file the following
command can be used: `openssl pkey -in <generated-private-key.pem> -pubout`
* If using AES-KW (`newt` only), the `kek` can be generated with a
command like (change count to 32 for a 256 bit key)
`dd if=/dev/urandom bs=1 count=16 | base64 > my_kek.b64`

View File

@@ -0,0 +1,135 @@
# Image tool
The Python program `scripts/imgtool.py` can be used to perform the
operations that are necessary to manage keys and sign images. Using
this script should be preferred to the manual steps described in
`doc/signed_images.md`.
This program is written for Python3, and has several dependencies on
Python libraries. These can be installed using 'pip3':
pip3 install --user -r scripts/requirements.txt
## [Managing keys](#managing-keys)
This tool currently supports rsa-2048, rsa-3072, ecdsa-p256 and ed25519 keys.
You can generate a keypair for one of these types using the 'keygen' command:
./scripts/imgtool.py keygen -k filename.pem -t rsa-2048
or use rsa-3072, ecdsa-p256, or ed25519 for the type. The key type used
should match what MCUboot is configured to verify.
This key file is what is used to sign images, this file should be
protected, and not widely distributed.
You can add the `-p` argument to `keygen`, which will cause it to
prompt for a password. You will need to enter this password in every
time you use the private key.
## [Incorporating the public key into the code](#incorporating-the-public-key-into-the-code)
There is a development key distributed with MCUboot that can be used
for testing. Since this private key is widely distributed, it should
never be used for production. Once you have generated a production
key, as described above, you should replace the public key in the
bootloader with the generated one.
For Zephyr, the keys live in the file `boot/zephyr/keys.c`. For
mynewt, follow the instructions in `doc/signed_images.md` to generate
the key file.
./scripts/imgtool.py getpub -k filename.pem
will extract the public key from the given private key file, and
output it as a C data structure. You can replace or insert this code
into the key file. However, when the `MCUBOOT_HW_KEY` config option is
enabled, this last step is unnecessary and can be skipped.
## [Signing images](#signing-images)
Image signing takes an image in binary or Intel Hex format intended for the
primary slot and adds a header and trailer that the bootloader is expecting:
Usage: imgtool.py sign [OPTIONS] INFILE OUTFILE
Create a signed or unsigned image
INFILE and OUTFILE are parsed as Intel HEX if the params have .hex
extension, otherwise binary format is used
Options:
-k, --key filename
--public-key-format [hash|full]
--align [1|2|4|8|16|32] Alignment used by swap update modes.
-v, --version TEXT [required]
-s, --security-counter TEXT Specify the value of security counter. Use
the `auto` keyword to automatically generate
it from the image version.
-d, --dependencies TEXT
--pad-sig Add 0-2 bytes of padding to ECDSA signature
(for MCUboot <1.5)
-H, --header-size INTEGER [required]
--pad-header Add --header-size zeroed bytes at the
beginning of the image
-S, --slot-size INTEGER Size of the slot where the image will be
written [required]
--pad Pad image to --slot-size bytes, adding
trailer magic
--confirm When padding the image, mark it as confirmed
-M, --max-sectors INTEGER When padding allow for this amount of
sectors (defaults to 128)
--boot-record sw_type Create CBOR encoded boot record TLV. The
sw_type represents the role of the software
component (e.g. CoFM for coprocessor
firmware). [max. 12 characters]
--overwrite-only Use overwrite-only instead of swap upgrades
-e, --endian [little|big] Select little or big endian
-E, --encrypt filename Encrypt image using the provided public key
--save-enctlv When upgrading, save encrypted key TLVs
instead of plain keys. Enable when
BOOT_SWAP_SAVE_ENCTLV config option was set.
-L, --load-addr INTEGER Load address for image when it should run
from RAM.
-x, --hex-addr INTEGER Adjust address in hex output file.
-R, --erased-val [0|0xff] The value that is read back from erased
flash.
-h, --help Show this message and exit.
The main arguments given are the key file generated above, a version
field to place in the header (1.2.3 for example), the alignment of the
flash device in question, and the header size.
The header size depends on the operating system and the particular
flash device. For Zephyr, it will be configured as part of the build,
and will be a small power of two. By default, the Zephyr build system will
already prepended a zeroed header to the image. If another build system is
in use that does not automatically add this zeroed header, `--pad-header` can
be passed and the `--header-size` will be added by imgtool. If `--pad-header`
is used with an Intel Hex file, `--header-size` bytes will be subtracted from
the load address (in Intel Hex terms, the Extended Linear Address record) to
adjust for the new bytes prepended to the file. The load address of all data
existing in the file should not change.
The `--slot-size` argument is required and used to check that the firmware
does not overflow into the swap status area (metadata). If swap upgrades are
not being used, `--overwrite-only` can be passed to avoid adding the swap
status area size when calculating overflow.
The optional `--pad` argument will place a trailer on the image that
indicates that the image should be considered an upgrade. Writing this image
in the secondary slot will then cause the bootloader to upgrade to it.
A dependency can be specified in the following way:
`-d "(image_id, image_version)"`. The `image_id` is the number of the image
which the current image depends on. The `image_version` is the minimum version
of that image to satisfy compliance. For example `-d "(1, 1.2.3+0)"` means this
image depends on Image 1 which version has to be at least 1.2.3+0.
The `--public-key-format` argument can be used to distinguish where the public
key is stored for image authentication. The `hash` option is used by default, in
which case only the hash of the public key is added to the TLV area (the full
public key is incorporated into the bootloader). When the `full` option is used
instead, the TLV area will contain the whole public key and thus the bootloader
can be independent from the key(s). For more information on the additional
requirements of this option, see the [design](design.md) document.

View File

@@ -0,0 +1,93 @@
# MCUboot
MCUboot is a secure bootloader for 32-bits microcontrollers.
## Overview
MCUboot defines a common infrastructure for the bootloader and the system flash
layout on microcontroller systems, and provides a secure bootloader that
enables easy software upgrade.
MCUboot is not dependent on any specific operating system and hardware and
relies on hardware porting layers from the operating system it works with.
Currently MCUboot works with the following operating systems and SoCs:
- [Zephyr](https://www.zephyrproject.org/)
- [Apache Mynewt](https://mynewt.apache.org/)
- [Apache NuttX](https://nuttx.apache.org/)
- [RIOT](https://www.riot-os.org/)
- [Mbed OS](https://os.mbed.com/)
- [Espressif](https://www.espressif.com/)
- [Cypress/Infineon](https://www.cypress.com/)
RIOT is supported only as a boot target. We will accept any new port
contributed by the community once it is good enough.
MCUboot is an open governance project. See the [membership
list](https://github.com/mcu-tools/mcuboot/wiki/Members) for current
members, and the
[project charter](https://github.com/mcu-tools/mcuboot/wiki/MCUboot-Project-Charter)
for more details.
## Documentation
The MCUboot documentation is composed of the following pages:
- General - this document
- [Release notes](release-notes.md)
- [Bootloader design](design.md)
- [Encrypted images](encrypted_images.md)
- [imgtool](imgtool.md) - image signing and key management
- [ECDSA](ecdsa.md) - information about ECDSA signature formats
- [Serial Recovery](serial_recovery.md) - MCUmgr as the serial recovery protocol
- Usage instructions:
- [Zephyr](readme-zephyr.md)
- [Apache Mynewt](readme-mynewt.md)
- [Apache NuttX](readme-nuttx.md)
- [RIOT](readme-riot.md)
- [Mbed OS](readme-mbed.md)
- [Espressif](readme-espressif.md)
- [Cypress/Infineon](https://github.com/mcu-tools/mcuboot/tree/main/boot/cypress/README.md)
- [Simulator](https://github.com/mcu-tools/mcuboot/tree/main/sim/README.rst)
- Testing
- [Zephyr](testplan-zephyr.md) - Zephyr test plan
- [Apache Mynewt](testplan-mynewt.md) - Apache Mynewt test plan
- [Release process](release.md)
- [Project security policy](SECURITY.md)
- [Patch submission](SubmittingPatches.md) - information
on how to contribute to MCUboot
The documentation page about [signed images](signed_images.md) is currently
outdated. Follow the instructions in [imgtool](imgtool.md) instead.
## Roadmap
The issues being planned and worked on are tracked using GitHub issues. To
give your input, visit [MCUboot GitHub
Issues](https://github.com/mcu-tools/mcuboot/issues).
## Source files
You can find additional documentation on the bootloader in the source files.
For more information, use the following links:
- [boot/bootutil](https://github.com/mcu-tools/mcuboot/tree/main/boot/bootutil) - The core of the bootloader itself.
- [boot/boot\_serial](https://github.com/mcu-tools/mcuboot/tree/main/boot/boot_serial) - Support for serial upgrade within the bootloader itself.
- [boot/zephyr](https://github.com/mcu-tools/mcuboot/tree/main/boot/zephyr) - Port of the bootloader to Zephyr.
- [boot/mynewt](https://github.com/mcu-tools/mcuboot/tree/main/boot/mynewt) - Bootloader application for Apache Mynewt.
- [boot/nuttx](https://github.com/mcu-tools/mcuboot/tree/main/boot/nuttx) - Bootloader application and port of MCUboot interfaces for Apache NuttX.
- [boot/mbed](https://github.com/mcu-tools/mcuboot/tree/main/boot/mbed) - Port of the bootloader to Mbed OS.
- [boot/espressif](https://github.com/mcu-tools/mcuboot/tree/main/boot/espressif) - Bootloader application and MCUboot port for Espressif SoCs.
- [boot/cypress](https://github.com/mcu-tools/mcuboot/tree/main/boot/cypress) - Bootloader application and MCUboot port for Cypress/Infineon SoCs.
- [imgtool](https://github.com/mcu-tools/mcuboot/tree/main/scripts/imgtool.py) - A tool to securely sign firmware images for booting by MCUboot.
- [sim](https://github.com/mcu-tools/mcuboot/tree/main/sim) - A bootloader simulator for testing and regression.
## Joining the project
Developers are welcome!
Use the following links to join or see more about the project:
* [Our developer mailing list](https://groups.io/g/MCUBoot)
* [Our Discord channel](https://discord.com/channels/1106321706588577904/1106322802308550716) <br />
Get [your invite](https://discord.com/invite/5PpXhvda5p)
* [Current members](https://github.com/mcu-tools/mcuboot/wiki/Members)
* [Project charter](https://github.com/mcu-tools/mcuboot/wiki/MCUboot-Project-Charter)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
# MCUboot port for Mbed OS
This is an MCUboot port for Mbed OS.
## Using MCUboot
Note: The following is a general overview. It does not cover MCUboot or Mbed OS basics.
See https://github.com/AGlass0fMilk/mbed-mcuboot-demo as a detailed example.
### Basic configurations
To use MCUboot, you need to create an Mbed OS project with the following configurations:
* `"mcuboot.primary-slot-address"`: address of the primary slot in the internal flash
* `"mcuboot.slot-size"`: size of an image slot (only one image, two slots are currently supported)
* `"mcuboot.max-img-sectors"`: maximum number of sectors, should be at least the number of sectors in each slot
* `"target.restrict_size"`: the maximum size of the bootloader, such that it does not overlap with the primary slot
More configurations such as signing algorithm, slot swapping, etc. can be found in [mbed_lib.json](https://github.com/mcu-tools/mcuboot/tree/main/boot/mbed/mbed_lib.json). Please note that certain features are not currently supported.
### Providing a secondary slot
You need to provide an instance of `mbed::BlockDevice` as the secondary slot. It can be any types of internal or external storage provided that:
* Its size equals the `"mcuboot.slot-size"` you have set
* Its minimum supported read and write sizes (granularities) are _no larger than_ 16 byte, which MCUboot's read/write operations are aligned to. If the read size is larger than _one byte_, you need to set `"mcuboot.read-granularity"` to the read size of the storage - this buffers smaller read operations.
In order for MCUboot to access your secondary slot, the interface to implement is
```cpp
mbed::BlockDevice* get_secondary_bd(void);
```
which should return an uninitialized instance of BlockDevice.
### Building the bootloader
To build a bootloader based on MCUboot, make sure `"mcuboot.bootloader-build"` is `true` (already the default) and you have provided configurations and a secondary slot BlockDevice as explained above.
### Building a user application
To build a user application, set `"mcuboot.bootloader-build"` to `false` so MCUboot is built as a _library only_ without a bootloader application. This is useful if your user application needs to confirm the current image with `boot_set_confirmed()` after an update, or set a new image in the secondary slot as pending with `boot_set_pending()` in order to trigger an update upon reboot.
As your application starts in the primary slots (instead of the beginning of the whole flash), you need to set the start address (`"target.mbed_app_start"`) to be equal to `"mcuboot.primary-slot-address"` + `"mcuboot.header-size"` of your bootloader. And its size (`"target.mbed_app_size"`) must be no larger than `"mcuboot.slot-size"` - `"mcuboot.header-size"`, and some space must be left for the image trailer too (see [this](design.md#image-trailer)).

View File

@@ -0,0 +1,52 @@
# Running mynewt apps with MCUboot
Due to small differences between Mynewt's bundled bootloader and MCUboot,
when building an app that will be run with MCUboot as the bootloader and
which at the same time requires to use `newtmgr` to manage images, MCUboot
must be added as a new dependency for this app.
First you need to add the repo to your `project.yml`:
```
project.repositories:
- mcuboot
repository.mcuboot:
type: github
vers: 0-dev
user: mcu-tools
repo: mcuboot
```
Then update your app's `pkg.yml` adding the extra dependency:
```
pkg.deps:
- "@mcuboot/boot/bootutil"
```
Also remove any dependency on `boot/bootutil` (mynewt's bundled bootloader)
which might exist.
To configure MCUboot check all the options available in
`boot/mynewt/mcuboot_config/syscfg.yml`.
Also, MCUboot uses a different image header struct as well as slightly
different TLV structure, so images created by `newt` have to be generated
in this new format. That is done by passing the extra parameter `-2` as in:
`newt create-image <target> <version> <pubkey> -2`
# Boot serial functionality with Mynewt
Building with `BOOT_SERIAL: 1` enables some basic management functionality
like listing images and uploading a new image to `slot0`. The serial bootloader
requires that `mtu` is set to a value that is less than or equal to `256`.
This can be done either by editing `~/.newtmgr.cp.json` and setting the `mtu`
for the connection profile, or specifying you connection string manually as in:
```
newtmgr --conntype serial --connstring "dev=/dev/ttyUSB0,mtu=256" image upload -e blinky.img
```
where `/dev/ttyUSB0` is your serial port.

View File

@@ -0,0 +1,52 @@
# MCUboot port for NuttX
## Description
The NuttX port of MCUboot secure boot library expects that the platform provides a Flash storage with the following partitions:
- `CONFIG_MCUBOOT_PRIMARY_SLOT_PATH`: MTD partition for the application firmware image PRIMARY slot;
- `CONFIG_MCUBOOT_SECONDARY_SLOT_PATH`: MTD partition for the application firmware image SECONDARY slot;
- `CONFIG_MCUBOOT_SCRATCH_PATH`: MTD partition for the Scratch area;
Also, these are optional features that may be enabled:
- `CONFIG_MCUBOOT_WATCHDOG`: If `CONFIG_WATCHDOG` is enabled, MCUboot shall reset the watchdog timer indicated by `CONFIG_MCUBOOT_WATCHDOG_DEVPATH` to the current timeout value, preventing any imminent watchdog timeouts.
The porting layer of MCUboot library consists of the following interfaces:
- `<flash_map_backend/flash_map_backend.h>`, for enabling MCUboot to manage the application firmware image slots in the device storage.
- `<mcuboot_config/mcuboot_config.h>`, for configuration of MCUboot's features.
- `<mcuboot_config/mcuboot_logging.h>`, for providing logging capabilities.
- `<os/os_malloc.h>`, for providing MCUboot access to the OS memory management interfaces.
- `<sysflash/sysflash.h>`, for configuration of the system's flash area organization.
The NuttX port of MCUboot is implemented at application-level and requires minimal knowledge about characteristics of the underlying storage device. This is achieved by means of the `BCH` and `FTL` subsystems, which enable MCUboot to manage MTD partitions via character device drivers using standard POSIX filesystem operations (e.g. `open()` / `close()` / `read()` / `write()`).
## Creating MCUboot-compatible application firmware images
One common use case for MCUboot is to integrate it to a firmware update agent, which is an important component of a secure firmware update subsystem. Through MCUboot APIs an application is able to install a newly received application firmware image and, once this application firmware image is assured to be valid, the application may confirm it as a stable image. In case that application firmware image is deemed bogus, MCUboot provides an API for invalidating that update, which will induce a rollback procedure to the most recent stable application firmware image.
The `CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE` example demonstrates this workflow by downloading an application firmware image from a webserver, installing it and triggering the firmware update process for the next boot after a system reset. There is also the `CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE`, which is a fairly simple example that just calls an MCUboot API for confirming the executing application firmware image as stable.
## Using MCUboot on NuttX as a secure boot solution
NuttX port for MCUboot also enables the creation of a secure bootloader application requiring minimal platform-specific implementation. The logical implementation for the secure boot is performed at application-level by the MCUboot library. Once MCUboot validates the application firmware image, it delegates the loading and execution of the application firmware image to a platform-specific routine, which is accessed via `boardctl(BOARDIOC_BOOT_IMAGE)` call. Each platform must then provide an implementation for the `board_boot_image()` for executing the required actions in order to boot a new application firmware image (e.g. deinitialize peripherals, load the Program Counter register with the application firmware image entry point address).
The MCUboot bootloader application may be enabled by selecting the `CONFIG_MCUBOOT_BOOTLOADER` option.
## Assumptions
### IOCTL MTD commands
The implementation of `<flash_map_backend/flash_map_backend.h>` expects that the MTD driver for a given image partition handles the following `ioctl` commands:
- `MTDIOC_GEOMETRY`, for retrieving information about the geometry of the MTD, required for the configuration of the size of each flash area.
- `MTDIOC_ERASESTATE`, for retrieving the byte value of an erased cell of the MTD, required for the implementation of `flash_area_erased_val()` interface.
### Write access alignment
Through `flash_area_align()` interface MCUboot expects that the implementation provides the shortest data length that may be written via `flash_area_write()` interface. The NuttX implementation passes through the `BCH` and `FTL` layers, which appropriately handle the write alignment restrictions of the underlying MTD. So The NuttX implementation of `flash_area_align()` is able to return a fixed value of 1 byte, even if the MTD does not support byte operations.
## Limitations
### `<flash_map_backend/flash_map_backend.h>` functions are not multitasking-safe
MCUboot's documentation imposes no restrictions regarding the usage of its public interfaces, which doesn't mean they are thread-safe.
But, regarding NuttX implementation of the `<flash_map_backend/flash_map_backend.h>`, it is safe to state that they are **not** multitasking-safe. NuttX implementation manages the MTD partitions via character device drivers. As file-descriptors cannot be shared between different tasks, if one task calls `flash_area_open` and another task calls `flash_area_<read/write/close>` passing the same `struct flash_area` instance, it will result in failure.

View File

@@ -0,0 +1,47 @@
# Building and using MCUboot with RIOT
MCUboot began its life as the bootloader for Mynewt. It has since
acquired the ability to be used as a bootloader for RIOT as well.
Currently the support is limited to the nrf52dk platform.
## Building the bootloader itself
In this first version, a prebuilt Mynewt binary is downloaded at
compile time. This binary was compiled to do an integrity check, but
not a signature check. In order to configure the bootloader for
signature check it is necessary to re-compile it either with Mynewt
or Zephyr, following the provided instructions.
In the next version, it is planned to compile MCUboot using RIOT,
which should be able to boot any of the supported OS images.
## Building applications for the bootloader
A compatible MCUboot image can be compiled by typing: `make mcuboot`.
The only variable which needs to be set is `IMAGE_VERSION` loaded
with a valid formatted value. The format is `major.minor.patch+other`
(e.g. `export IMAGE_VERSION= 1.1.1+1`. This variable can be either
exported in the Makefile or manually, prior to the compilation process.
The goal is to produce an ELF file which is linked to be flashed at a
`BOOTLOADER_OFFSET` offset rather than the beginning of ROM. MCUboot
also expects an image padded with some specific headers containing the
version information, and trailer type-length-value records (TLVs) with
hash and signing information. This is done through the imgtool.py
application, which is executed automatically by the RIOT build system.
### Signing the application
The application will be automatically signed with the provided key.
If no key is provided, a new key will be automatically generated. The
default key type is RSA-2048.
In order to use your provided key, you need to recompile the bootloader
using you public key, either in Zephyr or Mynewt by following the
provided procedure for the selected OS.
### Flashing the application
The application can be flashed by typing: `make flash-mcuboot`.
This will flash both the bootloader and the application.

View File

@@ -0,0 +1,256 @@
# Building and using MCUboot with Zephyr
MCUboot began its life as the bootloader for Mynewt. It has since
acquired the ability to be used as a bootloader for Zephyr as well.
There are some pretty significant differences in how apps are built
for Zephyr, and these are documented here.
Please see the [design document](design.md) for documentation on the design
and operation of the bootloader itself. This functionality should be the same
on all supported RTOSs.
The first step required for Zephyr is making sure your board has flash
partitions defined in its device tree. These partitions are:
- `boot_partition`: for MCUboot itself
- `slot0_partition`: the primary slot of Image 0
- `slot1_partition`: the secondary slot of Image 0
It is not recommended to use the swap-using-scratch algorithm of MCUboot, but
if this operating mode is desired then the following flash partition is also
needed (see end of this help file for details on creating a scratch partition
and how to use the swap-using-scratch algorithm):
- `scratch_partition`: the scratch slot
Currently, the two image slots must be contiguous. If you are running
MCUboot as your stage 1 bootloader, `boot_partition` must be configured
so your SoC runs it out of reset. If there are multiple updateable images
then the corresponding primary and secondary partitions must be defined for
the rest of the images too (for example, `slot2_partition` and
`slot3_partition` for Image 1).
The flash partitions are typically defined in the Zephyr boards folder, in a
file named `boards/<arch>/<board>/<board>.dts`. An example `.dts` file with
flash partitions defined is the frdm_k64f's in
`boards/arm/frdm_k64f/frdm_k64f.dts`. Make sure the DT node labels in your board's
`.dts` file match the ones used there.
## Installing requirements and dependencies
Install additional packages required for development with MCUboot:
```
cd ~/mcuboot # or to your directory where MCUboot is cloned
pip3 install --user -r scripts/requirements.txt
```
## Building the bootloader itself
The bootloader is an ordinary Zephyr application, at least from
Zephyr's point of view. There is a bit of configuration that needs to
be made before building it. Most of this can be done as documented in
the `CMakeLists.txt` file in boot/zephyr. There are comments there for
guidance. It is important to select a signature algorithm, and decide
if the primary slot should be validated on every boot.
To build MCUboot, create a build directory in boot/zephyr, and build
it as usual:
```
cd boot/zephyr
west build -b <board>
```
In addition to the partitions defined in DTS, some additional
information about the flash layout is currently required to build
MCUboot itself. All the needed configuration is collected in
`boot/zephyr/include/target.h`. Depending on the board, this information
may come from board-specific headers, Device Tree, or be configured by
MCUboot on a per-SoC family basis.
After building the bootloader, the binaries should reside in
`build/zephyr/zephyr.{bin,hex,elf}`, where `build` is the build
directory you chose when running `west build`. Use `west flash`
to flash these binaries from the build directory. Depending
on the target and flash tool used, this might erase the whole of the flash
memory (mass erase) or only the sectors where the bootloader resides prior to
programming the bootloader image itself.
## Building applications for the bootloader
In addition to flash partitions in DTS, some additional configuration
is required to build applications for MCUboot.
This is handled internally by the Zephyr configuration system and is wrapped
in the `CONFIG_BOOTLOADER_MCUBOOT` Kconfig variable, which must be enabled in
the application's `prj.conf` file.
The directory `samples/zephyr/hello-world` in the MCUboot tree contains
a simple application with everything you need. You can try it on your
board and then just make a copy of it to get started on your own
application; see samples/zephyr/README.md for a tutorial.
The Zephyr `CONFIG_BOOTLOADER_MCUBOOT` configuration option
[documentation](https://docs.zephyrproject.org/latest/kconfig.html#CONFIG_BOOTLOADER_MCUBOOT)
provides additional details regarding the changes it makes to the image
placement and generation in order for an application to be bootable by MCUboot.
With this, build the application as your normally would.
### Signing the application
In order to upgrade to an image (or even boot it, if
`MCUBOOT_VALIDATE_PRIMARY_SLOT` is enabled), the images must be signed.
To make development easier, MCUboot is distributed with some example
keys. It is important to stress that these should never be used for
production, since the private key is publicly available in this
repository. See below on how to make your own signatures.
Images can be signed with the `scripts/imgtool.py` script. It is best
to look at `samples/zephyr/Makefile` for examples on how to use this.
### Flashing the application
The application itself can flashed with regular flash tools, but will
need to be programmed at the offset of the primary slot for this particular
target. Depending on the platform and flash tool you might need to manually
specify a flash offset corresponding to the primary slot starting address. This
is usually not relevant for flash tools that use Intel Hex images (.hex) instead
of raw binary images (.bin) since the former include destination address
information. Additionally you will need to make sure that the flash tool does
not perform a mass erase (erasing the whole of the flash) or else you would be
deleting MCUboot.
These images can also be marked for upgrade, and loaded into the secondary slot,
at which point the bootloader should perform an upgrade. It is up to
the image to mark the primary slot as "image ok" before the next reboot,
otherwise the bootloader will revert the application.
## Managing signing keys
The signing keys used by MCUboot are represented in standard formats,
and can be generated and processed using conventional tools. However,
`scripts/imgtool.py` is able to generate key pairs in all of the
supported formats. See [the docs](imgtool.md) for more details on
this tool.
### Generating a new keypair
Generating a keypair with imgtool is a matter of running the keygen
subcommand:
```
$ ./scripts/imgtool.py keygen -k mykey.pem -t rsa-2048
```
The argument to `-t` should be the desired key type. See the
[the docs](imgtool.md) for more details on the possible key types.
### Extracting the public key
The generated keypair above contains both the public and the private
key. It is necessary to extract the public key and insert it into the
bootloader. Use the ``CONFIG_BOOT_SIGNATURE_KEY_FILE`` Kconfig option to
provide the path to the key file so the build system can extract
the public key in a format usable by the C compiler.
The generated public key is saved in `build/zephyr/autogen-pubkey.h`, which is included
by the `boot/zephyr/keys.c`.
Currently, the Zephyr RTOS port limits its support to one keypair at the time,
although MCUboot's key management infrastructure supports multiple keypairs.
Once MCUboot is built, this new keypair file (`mykey.pem` in this
example) can be used to sign images.
## Using swap-using-scratch flash algorithm
To use the swap-using-scratch flash algorithm, a scratch partition needs to be
present for the target board which is used for holding the data being swapped
from both slots, this section must be at least as big as the largest sector
size of the 2 partitions (e.g. if a device has a primary slot in main flash
with a sector size of 512 bytes and secondar slot in external off-chip flash
with a sector size of 4KB then the scratch area must be at least 4KB in size).
The number of sectors must also be evenly divisable by this sector size, e.g.
4KB, 8KB, 12KB, 16KB are allowed, 7KB, 7.5KB are not. This scratch partition
needs adding to the .dts file for the board, e.g. for the nrf52dk_nrf52832
board thus would involve updating
`<zephyr>/boards/nordic/nrf52dk/nrf52dk_nrf52832.dts` with:
```
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0xc000>;
};
slot0_partition: partition@c000 {
label = "image-0";
reg = <0x0000C000 0x37000>;
};
slot1_partition: partition@43000 {
label = "image-1";
reg = <0x00043000 0x37000>;
};
scratch_partition: partition@7a000 {
label = "image-scratch";
reg = <0x0007a000 0x00006000>;
};
```
Which would make the application size 220KB and scratch size 24KB (the nRF52832
has a 4KB sector size so the size of the scratch partition can be reduced at
the cost of vastly reducing flash lifespan, e.g. for a 32KB firmware update
with an 8KB scratch area, the scratch area would be erased and programmed 8
times per image upgrade/revert). To configure MCUboot to work in
swap-using-scratch mode, the Kconfig value must be set when building it:
`CONFIG_BOOT_SWAP_USING_SCRATCH=y`.
Note that it is possible for an application to get into a stuck state when
swap-using-scratch is used whereby an application has loaded a firmware update
and marked it as test/confirmed but MCUboot will not swap the images and
erasing the secondary slot from the zephyr application returns an error
because the slot is marked for upgrade.
## Serial recovery
### Interface selection
A serial recovery protocol is available over either a hardware serial port or a USB CDC ACM virtual serial port.
The SMP server implementation can be enabled by the ``CONFIG_MCUBOOT_SERIAL=y`` Kconfig option.
To set a type of an interface, use the ``BOOT_SERIAL_DEVICE`` Kconfig choice, and select either the ``CONFIG_BOOT_SERIAL_UART`` or the ``CONFIG_BOOT_SERIAL_CDC_ACM`` value.
Which interface belongs to the protocol shall be set by the devicetree-chosen node:
- `zephyr,console` - If a hardware serial port is used.
- `zephyr,cdc-acm-uart` - If a virtual serial port is used.
### Entering the serial recovery mode
To enter the serial recovery mode, the device has to initiate rebooting, and a triggering event has to occur (for example, pressing a button).
By default, the serial recovery GPIO pin active state enters the serial recovery mode.
Use the ``mcuboot_button0`` devicetree button alias to assign the GPIO pin to the MCUboot.
Alternatively, MCUboot can wait for a limited time to check if DFU is invoked by receiving an MCUmgr command.
Select ``CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y`` to use this mode. ``CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT`` option defines
the amount of time in milliseconds the device will wait for the trigger.
### Direct image upload
By default, the SMP server implementation will only use the first slot.
To change it, invoke the `image upload` MCUmgr command with a selected image number, and make sure the ``CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y`` Kconfig option is enabled.
Note that the ``CONFIG_UPDATEABLE_IMAGE_NUMBER`` Kconfig option adjusts the number of image-pairs supported by the MCUboot.
The mapping of image number to partition is as follows:
* 0 and 1 - image-0, the primary slot of the first image.
* 2 - image-1, the secondary slot of the first image.
* 3 - image-2.
* 4 - image-3.
0 is a default upload target when no explicit selection is done.
### System-specific commands
Use the ``CONFIG_ENABLE_MGMT_PERUSER=y`` Kconfig option to enable the following additional commands:
* Storage erase - This command allows erasing the storage partition (enable with ``CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y``).
* Custom image list - This command allows fetching version and installation status (custom properties) for all images (enable with ``CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST=y``).
### More configuration
For details on other available configuration options for the serial recovery protocol, check the Kconfig options (for example by using ``menuconfig``).

View File

@@ -0,0 +1,29 @@
# Pending release notes directory
This directory contains release note entries that have not been merged
into the main release-notes.md document.
Generally a release note entry should be created for changes that:
- Fix bugs in the code.
- Implement new features.
- Change existing behavior.
Release notes are generally not needed for:
- Some documentation improvements.
- Strictly internal changes to the code that won't be visible to users
of the code.
## Release note format
Release notes are included in files under this `docs/release-notes.d`
directory and have a name of `*.md`. They will be included in the
`release-notes.md` file, and should be formatted as a Markdown list
entry. (A script will be developed to collect these, ordered by when
the commits were added to the tree.)
Choose a filename that is related to what this change does. The names
are not used for anything in particular, but to keep the files
distinct so that there isn't a concern with merge conflicts as
different pull requests merge in different orders.

View File

@@ -0,0 +1,2 @@
- Added support for retrieving hw embed private keys for image encryption
(The private key can be retrieved from trusted sources like OTP, TPM.).

View File

@@ -0,0 +1,4 @@
- Changed bootutil's order of events to verify the image header
before checking the image.
- Added the bootloader state object to the bootutil
boot_is_header_valid() function

View File

@@ -0,0 +1,3 @@
- When using swap with scratch, the image is now decrypted when copying from
the scratch partition to the primary slot. Therefore, the sratch partition
doesn't contain plaintext firmware data anymore.

View File

@@ -0,0 +1,2 @@
- Fixed errors when building for ``thingy52``, ``thingy53`` and
``nrf9160dk`` boards.

View File

@@ -0,0 +1,2 @@
- Fixed chain load address output log message for RAM load
mode in Zephyr

View File

@@ -0,0 +1,2 @@
- Fixed clash when using sysbuild with other
applications (i.e. tests) using the name sysbuild

View File

@@ -0,0 +1,2 @@
- imgtool: added initial sanity tests for imgtool commands,
- imgtool: added and enabled unittests in GitGub workflow,

View File

@@ -0,0 +1,4 @@
- Fixed wrong maximum application size calculation when
operating in swap using move mode
- Added additional images max size support to shared data
function

View File

@@ -0,0 +1 @@
- Added slot info command support to serial recovery mode

View File

@@ -0,0 +1,5 @@
- Added support for automatically calculating the maximum number
of sectors that are needed for a build by checking the erase
sizes of the partitions using CMake for Zephyr. This behaviour
can be reverted to the old manual behaviour by disabling
``CONFIG_BOOT_MAX_IMG_SECTORS_AUTO``

View File

@@ -0,0 +1,7 @@
- Added protected TLV size to image size check in bootutil
- Added Kconfig for decompression support in Zephyr
- Added compressed image flags and TLV to bootutil
- Added support for removing images with conflicting flags in
bootutil
- Added support for removing encrypted/compressed images when
MCUboot is compiled without support for them

View File

@@ -0,0 +1,553 @@
# MCUboot release notes
- Table of Contents
{:toc}
## Version 2.1.0
- Boot serial: Add response to echo command if support is not
enabled, previously the command would have been accepted but no
response indicating that the command is not supported would have
been sent.
- Added support for using builtin keys for image validation
(available with the PSA Crypto API based crypto backend for ECDSA signatures).
- Enforce that TLV entries that should be protected are.
This can be disabled by defining `ALLOW_ROGUE_TLVS`
- bootutil: Fixed issue with comparing sector sizes for
compatibility, this now also checks against the number of usable
sectors (which is the slot size minus the swap status and moved
up by one sector).
- bootutil: Added debug logging to show write location of swap status
and details on sectors including if slot sizes are not optimal for
a given board.
- Update ptest to support test selection. Ptest can now be invoked with `list`
to show the available tests and `run` to run them. The `-t` argument will
select specific tests to run.
- Allow sim tests to skip slow tests. By setting `MCUBOOT_SKIP_SLOW_TESTS` in
the environment, the sim will skip two tests that are very slow. In one
instance this reduces the test time from 2 hours to about 5 minutes. These
slow tests are useful, in that they test bad powerdown recovery, but are
inconvenient when testing other areas.
- Zephyr: Fixes support for disabling instruction/data caches prior
to chain-loading an application, this will be automatically
enabled if one or both of these caches are present. This feature
can be disabled by setting `CONFIG_BOOT_DISABLE_CACHES` to `n`.
- Zephyr: Fix issue with single application slot mode, serial
recovery and encryption whereby an encrypted image is loaded
and being wrongly treated as encrypted after decryption.
- Zephyr: Add estimated image footer size to cache in sysbuild.
- Added firmware loader configuration type support for Zephyr, this
allows for a single application slot and firmware loader image in
the secondary slot which is used to update the primary image
(loading it in any way it sees fit e.g. via Bluetooth).
- Zephyr: Remove deprecated ZEPHYR_TRY_MASS_ERASE Kconfig option.
- Zephyr: Prevent MBEDTLS Kconfig selection when tinycrypt is used.
- Zephyr: Add USB CDC serial recovery check that now causes a build
failure if console is enabled and device is the same as the USB
CDC device.
- Zephyr: Add USB CDC serial recovery check that now causes a build
failure if the main thread priority is below 0 (cooperative
thread), this would prevent USB CDC from working as the driver
would not have been able to fire callbacks.
- Use general flash operations to determine the flash reset vector. This
improves support a bit for some configurations of external flash.
- fix a memory leak in the HKDF implementation.
- Zephyr: Added a MCUboot banner which displays the version of
MCUboot being used and the version of zephyr. This can be
disabled by setting ``CONFIG_MCUBOOT_BOOT_BANNER=n`` which
will revert back to the default zephyr boot banner.
## Version 2.0.0
Note that this release, 2.0.0 is a new major number, and contains a small API
change in the interface between mcuboot and the platform. All platforms
contained within the MCUboot tree have been updated, but any external platforms
will have to be adjusted. The following commit makes the API change, in the
function `boot_save_shared_data`.
commit 3016d00cd765e7c09a14af55fb4dcad945e4b982
Author: Jamie McCrae <jamie.mccrae@nordicsemi.no>
Date: Tue Mar 14 12:35:51 2023 +0000
bootutil: Add active slot number and max app size to shared data
### About this release
- Add error when flash device fails to open.
- Panic bootloader when flash device fails to open.
- Fixed issue with serial recovery not showing image details for
decrypted images.
- Fixes issue with serial recovery in single slot mode wrongly
iterating over 2 image slots.
- CDDL auto-generated function code has been replaced with zcbor function
calls, this now allows the parameters to be supplied in any order.
- Added currently running slot ID and maximum application size to
shared data function definition.
- Make the ECDSA256 TLV curve agnostic and rename it to ECDSA_SIG.
- imgtool: add P384 support along with SHA384.
- espressif: refactor after removing IDF submodule
- espressif: add ESP32-C6, ESP32-C2 and ESP32-H2 new chips support
- espressif: adjustments after IDF v5.1 compatibility, secure boot build and memory map organization
- Serial recovery image state and image set state optional commands added
- imgtool: add 'dumpinfo' command for signed image parsing.
- imgtool: add 'getpubhash' command to dump the sha256 hash of the public key
- imgtool's getpub can print the output to a file
- imgtool can dump the raw versions of the public keys
- Drop ECDSA P224 support
- Fixed an issue with boot_serial repeats not being processed when
output was sent, this would lead to a divergence of commands
whereby later commands being sent would have the previous command
output sent instead.
- Fixed an issue with the boot_serial zcbor setup encoder function
wrongly including the buffer address in the size which caused
serial recovery to fail on some platforms.
- zcbor library files have been updated to version 0.7.0
- Reworked boot serial extensions so that they can be used by modules
or from user repositories by switching to iterable sections.
- Removed Zephyr custom img list boot serial extension support.
- (Zephyr) Adds support for sharing boot information with
application via retention subsystem
- Zephyr no longer builds in optimize for debug mode, this saves a
significant amount of flash space.
- Reworked image encryption support for Zephyr, static dummy key files
are no longer in the code, a pem file must be supplied to extract
the private and public keys. The Kconfig menu has changed to only
show a single option for enabling encryption and selecting the key
file.
- Serial recovery can now read and handle encrypted seondary slot
partitions.
- Serial recovery with MBEDTLS no longer has undefined operations which
led to usage faults when the secondary slot image was encrypted.
- espressif: allow the use of a different toolchain for building
## Version 1.10.0
The 1.10.0 release of MCUboot contains...
### About this release
- Various fixes to boot serial.
- Various fixes to the mbed target.
- Various fixes to the Espressif native target.
- Various fixes to the Zephyr target.
- Workflow improvements with Zephyr CI.
- Add multi image support to the espressif esp32 target.
- Improvements and corrections to the simulator.
- Improve imgtool, including adding 3rd party signing support.
- Various fixes to the mynewt target.
- Various fixes to the nuttx target.
- Dates to dependencies for doc generation.
- Add downgrade prevention for modes using swap.
- Various general fixes to the boot code.
- Prefer swap move on zephyr if the scratch partition is not enabled.
- Upgrade fault-injection hardening, improving cases injections are detected.
- Add a new flash api `flash_area_get_sector`, along with support for each
target, that replaces `flash_area_sector_from_off`. This is a step in cleaning
up the flash API used by MCUboot.
### Security fixes
There are no security vulnerabilities reported on the MCUboot code for this
release. There have been several updates to the dependencies in the Ruby code
used to generate the documentation. This should only affect users that generate
their own documentation.
## Version 1.9.0
The 1.9.0 release of MCUboot contains various bug fixes, improves
support on some recent targets, and adds support for devices with a
write alignment larger than 8.
This change introduces a potentially incompatible change to the format
of the image trailer. If `BOOT_MAX_ALIGN` is kept at 8, the trailer
format does not change. However, to support larger write alignments,
this value can be increased, which will result in a different magic
number value. These targets were previously unsupported in MCUboot,
so this change should not affect any existing targets. The change has
been tested with a `BOOT_MAX_ALIGN` up to 32 bytes.
### About this release
- Add native flash encryption to Espressif targets
- Numerous documentation improvements
- Increase coverage of large images in the simulator
- Add stm32 watchdog support
- Add support for the `mimxrt685_evk` board
- Add support for "partial multi-image booting"
- Add support for clear image generation with encryption capability to
imgtool
- Fix Zephyr when `CONFIG_BOOT_ENCRYPTION_KEY_FILE` is not defined
- Remove zephyr example test running in shell. The Go version is
primary and much more featureful.
- imgtool: make `--max-align` default reasonable in most cases.
- Implement the mcumgr echo command in serial boot mode
### Security fixes
## Version 1.8.0
The 1.8.0 release of MCUboot contains numerous fixes, and adds support
for the NuttX RTOS, and the Espressif ESP32 SDK.
### About this release
- Add support for the NuttX RTOS.
- Add support for the Espressif ESP32 SDK.
- `boot_serial` changed to use cddl-gen, which removes the dependency
on tinycbor.
- Add various hooks to be able to change how image data is accessed.
- Cypress supports Mbed TLS for encryption.
- Support using Mbed TLS for ECDSA. This can be useful if Mbed TLS is
brought in for another reason.
- Add simulator support for testing direct-XIP and ramload.
- Support Mbed TLS 3.0. Updates the submodule for Mbed TLS to 3.0.
- Enable direct-xip mode in Mbed-OS port.
- extract `bootutil_public` library, a common interface for MCUboot
and the application.
- Allow to boot primary image if secondary one is unreachable.
- Add AES256 image encryption support.
- Add Multiimage boot for direct-xip and ram-load mode.
- Cargo files moved to top level, now `cargo test` can be run from the
top level directory.
- Fault injection tests use updated TF-M.
- Thingy:53 now supports multi-image DFU.
- ram load and image encryption can be used together, allowing the
entire contents of flash to always remain encrypted.
### Security fixes
- [GHSA-gcxh-546h-phg4](https://github.com/mcu-tools/mcuboot/security/advisories/GHSA-gcxh-546h-phg4)
has been published. There is not a fix at this time, but a caution
to be sure to follow the instructions carefully, and make sure that
the development keys in the repo are never used in a production
system.
## Version 1.7.0
The 1.7.0 release of MCUboot adds support for the Mbed-OS platform,
Equal slots (direct-xip) upgrade mode, RAM loading upgrade mode,
hardening against hardware level fault injection and timing attacks
and single image mode.
There are bug fixes, and associated imgtool updates as well.
### About this release
- Initial support for the Mbed-OS platform.
- Added possibility to enter deep sleep mode after MCUboot app execution
for cypress platform.
- Added hardening against hardware level fault injection and timing attacks.
- Introduced Abstract crypto primitives to simplify porting.
- Added RAM-load upgrade mode.
- Renamed single-image mode to single-slot mode.
- Allow larger primary slot in swap-move
- Fixed boostrapping in swap-move mode.
- Fixed issue causing that interrupted swap-move operation might brick device
if the primary image was padded.
- Abstracting MCUboot crypto functions for cleaner porting
- Droped flash_area_read_is_empty() porting API.
- boot/zephyr: Added watchdog feed on nRF devices.
See `CONFIG_BOOT_WATCHDOG_FEED` option.
- boot/zephyr: Added patch for turning off cache for Cortex M7 before
chain-loading.
- boot/zephyr: added option to relocate interrupts to application
- boot/zephyr: clean ARM core configuration only when selected by user
- boot/boot_serial: allow nonaligned last image data chunk
- imgtool: added custom TLV support.
- imgtool: added possibility to set confirm flag for hex files as well.
- imgtool: Print image digest during verify.
### Zephyr-RTOS compatibility
This release of MCUboot works with the Zephyr "main" at the time of the
release. It was tested as of has 7a3b253ce. This version of MCUboot also
works with the Zephyr v2.4.0, however it is recommended to enable
`CONFIG_MCUBOOT_CLEANUP_ARM_CORE` while using that version.
## Version 1.6.0
The 1.6.0 release of MCUboot adds support for the PSOC6 platform,
X25519 encrypted images, rollback protection, hardware keys, and a
shared boot record to communicate boot attestation information to
later boot stages. There are bug fixes, and associated imgtool
updates as well.
### About this release
- Initial support for the Cypress PSOC6 plaformt. This platform
builds using the Cypress SDK, which has been added as submodules.
- CBOR decoding in serial recovery replaced by code generated from a
CDDL description.
- Add support for X25519 encrypted images.
- Add rollback protection. There is support for a HW rollback counter
(which must be provided as part of the platform), as well as a SW
solution that protects against some types of rollback.
- Add an optional boot record in shared memory to communicate boot
attributes to later-run code.
- Add support for hardware keys.
- Various fixes to work with the latest Zephyr version.
### Security issues addressed
- CVE-2020-7595 "xmlStringLenDecodeEntities in parser.c in libxml2
2.9.10 has an infinite loop in a certain end-of-file situation." Fix
by updating a dependency in documentation generation.
### Zephyr-RTOS compatibility
This release of MCUboot works the Zephyr "main" at the time of the
release. It was tested as of has 1a89ca1238. When Zephyr v2.3.0 is
released, there will be a possible 1.6.1 or similar release of Zephyr
if needed to address any issues. There also may be branch releases of
MCUboot specifically for the current version of Zephyr, e.g.
v1.6.0-zephyr-2.2.1.
## Version 1.5.0
The 1.5.0 release of MCUboot adds support for encrypted images using
ECIES with secp256r1 as an Elliptic Curve alternative to RSA-OAEP. A
new swap method was added which allows for upgrades without using a
scratch partition. There are also lots of bug fixes, extra simulator
testing coverage and some imgtool updates.
### About this release
- TLVs were updated to use 16-bit lengths (from previous 8). This
should work with no changes for little-endian targets, but will
break compatibility with big-endian targets.
- A benchmark framework was added to Zephyr
- ed25519 signature validation can now build without using Mbed TLS
by relying on a bundled tinycrypt based sha-512 implementation.
- imgtool was updated to correctly detect trailer overruns by image.
- Encrypted image TLVs can be saved in swap metadata during a swap
upgrade instead of the plain AES key.
- imgtool can dump private keys in C format (getpriv command), which
can be added as decryption keys. Optionally can remove superfluous
fields from the ASN1 by passing it `--minimal`.
- Lots of other smaller bugs fixes.
- Added downgrade prevention feature (available when the overwrite-based
image update strategy is used)
### Known issues
- TLV size change breaks compatibility with big-endian targets.
## Version 1.4.0
The 1.4.0 release of MCUboot primarily adds support for multi-image
booting. With this release, MCUboot can manage two images that can be
updated independently. With this, it also supports additions to the
TLV that allow these dependencies to be specified.
Multi-image support adds backward-incompatible changes to the format
of the images: specifically adding support for protected TLV entries.
If multiple images and dependencies are not used, the images will be
compatible with previous releases of MCUboot.
### About this release
- Fixed CVE-2019-5477, and CVE-2019-16892. These fix issue with
dependencies used in the generation of the documentation on github.
- Numerous code cleanups and refactorings
- Documentation updates for multi-image features
- Update imgtool.py to support the new features
- Updated the Mbed TLS submodule to current stable version 2.16.3
- Moved the Mbed TLS submodule from within sim/mcuboot-sys to ext.
This will make it easier for other board supports to use this code.
- Added some additional overflow and bound checks to data in the image
header, and TLV data.
- Add a `-x` (or `--hex_addr`) flag to imgtool to set the base address
written to a hex-format image. This allows the image to be flashed
at an offset, without having to use additional tools to modify the
image.
## Version 1.3.1
The 1.3.1 release of MCUboot consists mostly of small bug fixes and updates.
There are no breaking changes in functionality. This release should work with
Mynewt 1.6.0 and up, and any Zephyr `main` after sha
f51e3c296040f73bca0e8fe1051d5ee63ce18e0d.
### About this release
- Fixed a revert interruption bug
- Added ed25519 signing support
- Added RSA-3072 signing support
- Allow ec256 to run on CC310 interface
- Some preparation work was done to allow for multi image support, which
should land in 1.4.0. This includes a simulator update for testing
multi-images, and a new name for slot0/slot1 which are now called
"primary slot" and "secondary slot".
- Other minor bugfixes and improvements
## Version 1.3.0
The 1.3.0 release of MCUboot brings in many fixes and updates. There
are no breaking changes in functionality. Many of the changes are
refactorings that will make the code easier to maintain going forward.
In addition, support has been added for encrypted images. See [the
docs](encrypted_images.md) for more information.
### About this release
- Modernize the Zephyr build scripts.
- Add a `ptest` utility to help run the simulator in different
configurations.
- Migrate the simulator to Rust 2018 edition. The sim now requires at
least Rust 1.32 to build.
- Simulator cleanups. The simulator code is now built the same way
for every configuration, and queries the MCUboot code for how it was
compiled.
- Abstract logging in MCUboot. This was needed to support the new
logging system used in Zephyr.
- Add multiple flash support. Allows slot1/scratch to be stored in an
external flash device.
- Add support for [encrypted images](encrypted_images.md).
- Add support for flash devices that read as '0' when erased.
- Add support to Zephyr for the `nrf52840_pca10059`. This board
supports serial recovery over USB with CDC ACM.
- imgtool is now also available as a python package on pypi.org.
- Add an option to erase flash pages progressively during recovery to
avoid possible timeouts (required especially by serial recovery
using USB with CDC ACM).
- imgtool: big-endian support
- imgtool: saves in intel-hex format when output filename has `.hex`
extension; otherwise saves in binary format.
## Version 1.2.0
The 1.2.0 release of MCUboot brings a lot of fixes/updates, where much of the
changes were on the boot serial functionality and imgtool utility. There are
no breaking changes in MCUboot functionality, but some of the CLI parameters
in imgtool were changed (either removed or added or updated).
### About this release
- imgtool accepts .hex formatted input
- Logging system is now configurable
- Most Zephyr configuration has been switched to Kconfig
- Build system accepts .pem files in build system to autogenerate required
key arrays used internally
- Zephyr build switched to using built-in flash_map and TinyCBOR modules
- Serial boot has substantially decreased in space usage after refactorings
- Serial boot build doesn't require newlib-c anymore on Zephyr
- imgtool updates:
+ "create" subcommand can be used as an alias for "sign"
+ To allow imgtool to always perform the check that firmware does not
overflow the status area, `--slot-size` was added and `--pad` was updated
to act as a flag parameter.
+ `--overwrite-only` can be passed if not using swap upgrades
+ `--max-sectors` can be used to adjust the maximum amount of sectors that
a swap can handle; this value must also be configured for the bootloader
+ `--pad-header` substitutes `--included-header` with reverted semantics,
so it's not required for firmware built by Zephyr build system
### Known issues
None
## Version 1.1.0
The 1.1.0 release of MCUboot brings a lot of fixes/updates to its
inner workings, specially to its testing infrastructure which now
enables a more thorough quality assurance of many of the available
options. As expected of the 1.x.x release cycle, no breaking changes
were made. From the tooling perpective the main addition is
newt/imgtool support for password protected keys.
### About this release
- serial recovery functionality support under Zephyr
- simulator: lots of refactors were applied, which result in the
simulator now leveraging the Rust testing infrastructure; testing
of ecdsa (secp256r1) was added
- imgtool: removed PKCS1.5 support, added support for password
protected keys
- tinycrypt 0.2.8 and the Mbed TLS ASN1 parser are now bundled with
MCUboot (eg secp256r1 is now free of external dependencies!)
- Overwrite-only mode was updated to erase/copy only sectors that
actually store firmware
- A lot of small code and documentation fixes and updates.
### Known issues
None
## Version 1.0.0
The 1.0.0 release of MCUboot introduces a format change. It is
important to either use the `imgtool.py` also from this release, or
pass the `-2` to recent versions of the `newt` tool in order to
generate image headers with the new format. There should be no
incompatible format changes throughout the 1.x.y release series.
### About this release
- Header format change. This change was made to move all of the
information about signatures out of the header and into the TLV
block appended to the image. This allows
- The signature to be replaced without changing the image.
- Multiple signatures to be applied. This can be used, for example,
to sign an image with two algorithms, to support different
bootloader configurations based on these image.
- The public key is referred to by its SHA1 hash (or a prefix of the
hash), instead of an index that has to be maintained with the
bootloader.
- Allow new types of signatures in the future.
- Support for PKCS#1 v1.5 signatures has been dropped. All RSA
signatures should be made with PSS. The tools have been changed to
reflect this.
- The source for Tinycrypt has been placed in the MCUboot tree. A
recent version of Tinycrypt introduced breaking API changes. To
allow MCUboot to work across various platforms, we stop using the
Tinycrypt bundled with the OS platform, and use our own version. A
future release of MCUboot will update the Tinycrypt version.
- Support for some new targets:
- Nordic nRF51 and nRF52832 dev kits
- Hexiwear K64
- Clearer sample applications have been added under `samples`.
- Test plans for [zephyr](testplan-zephyr.md), and
[mynewt](testplan-mynewt.md).
- The simulator is now able to test RSA signatures.
- There is an unimplemented `load_addr` header for future support for
RAM loading in the bootloader.
- Numerous documentation.
### Known issues
None
## Version 0.9.0
This is the first release of MCUboot, a secure bootloader for 32-bit MCUs.
It is designed to be operating system-agnostic and works over any transport -
wired or wireless. It is also hardware independent, and relies on hardware
porting layers from the operating system it works with. For the first release,
we have support for three open source operating systems: Apache Mynewt, Zephyr
and RIOT.
### About this release
- This release supports building with and running Apache Mynewt and Zephyr
targets.
- RIOT is supported as a running target.
- Image integrity is provided with SHA256.
- Image originator authenticity is provided supporting the following
signature algorithms:
- RSA 2048 and RSA PKCS#1 v1.5 or v2.1
- Elliptic curve DSA with secp224r1 and secp256r1
- Two firmware upgrade algorithms are provided:
- An overwrite only which upgrades slot 0 with the image in slot 1.
- A swapping upgrade which enables image test, allowing for rollback to a
previous known good image.
- Supports both Mbed TLS and tinycrypt as backend crypto libraries. One of them
must be defined and the chosen signing algorithm will require a particular
library according to this list:
- RSA 2048 needs Mbed TLS
- ECDSA secp224r1 needs Mbed TLS
- ECDSA secp256r1 needs tinycrypt as well as the ASN.1 code from Mbed TLS
(so still needs that present).
### Known issues
- The image header and TLV formats are planned to change with release 1.0:
https://runtimeco.atlassian.net/browse/MCUB-66

View File

@@ -0,0 +1,133 @@
# Release process
This page describes the release process used with MCUboot.
## Version numbering
MCUboot uses [semantic versioning][semver], where version numbers
follow a `MAJOR.MINOR.PATCH` format with the following guidelines on
incrementing the numbers:
1. MAJOR version when there are incompatible API changes.
2. MINOR version when new functionalities were added in a
backward-compatible manner.
3. PATCH version when there are backward-compatible bug fixes.
We add pre-release tags using the format `MAJOR.MINOR.PATCH-rc1`.
In the documentation, we mark an MCUBoot development version using the
format `MAJOR.MINOR.PATCH-dev`.
## Release notes
Before making a release, update the `docs/release-notes.md` file
to describe the release. This should be a high-level description of
the changes, not a list of the git commits.
Provided that changes going into the release have followed the
contribution guidelines, this should mostly consist of collecting the
various snippets in the `docs/release-notes.d` directory. After
incorporating these snippets into the release notes, the snippet files
should be removed to ready the directory for the next release cycle.
## Release candidates
Before each release, tags are made (see below) for at least one
release candidate (a.b.c-rc1, followed by a.b.c-rc2 and the subsequent
release candidates, followed by the official a.b.c release). The intent
is to freeze the code and allow testing.
During the time between the rc1 and the final release, the only changes
that should be merged into the main branch are those to fix bugs found
in the RC and in the Mynewt metadata, as described in the next section.
## Imgtool release
imgtool is released through pypi.org (The Python package index).
It requires its version to be updated by editing
`scripts/imgtool/__init__.py` and modifying the exported version:
```
imgtool_version = "A.B.CrcN"
```
This version should match the current release number of MCUboot. The
suffix `rcN` (with no dash) is accepted only for the pre-release versions
under test, while numbers are accepted only for the final releases.
For more information, see [this
link](https://www.python.org/dev/peps/pep-0440/#pre-releases).
## Mynewt release information
On Mynewt, `newt` always fetches a versioned MCUboot release, so after
the RC step is finished, the release needs to be exported by modifying
`repository.yml` in the root directory; it must be updated with the
new release version, including updates to the pseudo keys
(`*-(latest|dev)`).
## Zephyr release information
There is a version file used by Zephyr builds to indicate the version
of MCUboot being used which needs to be updated at
`boot/zephyr/VERSION`. For alignment with Zephyr versions, development
versions should set `PATCHLEVEL` to `99` and `EXTRAVERSION` to `dev`,
whilst production versions should correctly set `PATCHLEVEL` and clear
`EXTRAVERSION`.
## Tagging and release
To make a release, make sure your local repo is on the tip version by
fetching from origin. Typically, the releaser should create a branch
named after the particular release.
Create a commit on top of the branch that modifies the version number
in the top-level `README.md`, and create a commit, with just this
change, with a commit text similar to "Bump to version a.b.c".
Having the version bump helps to make the releases
easier to find, as each release has a commit associated with it, and
not just a tag pointing to another commit.
Once this is done, the release should create a signed tag with the
appropriate tag name:
``` bash
git tag -s va.b.c-rcn
```
The releaser will need to make sure that git is configured to use the
proper signing key, and that the public key is signed by enough parties to
be trusted.
At this point, the tag can be pushed to GitHub to make the actual release
happen:
``` bash
git push origin HEAD:refs/heads/main
git push origin va.b.c-rcn
```
## Branching after a release
After the final (non-`rc`) a.b.0 release is made, a new branch must
be created and pushed:
``` bash
git checkout va.b.c
git checkout -b va.b-branch
git push origin va.b-branch
```
This branch will be used to generate new incremental `PATCH` releases
for bug fixes or required minor updates (for example, new `imgtool` features).
## Post release actions
Mark the MCUboot version as a development version.
The version number used should be specified for the next expected release.
It should be larger than the last release version by incrementing the MAJOR or
the MINOR number. It is not necessary to define the next version precisely as
the next release version might still be different as it might be needed to do:
- a patch release
- a MINOR release while a MAJOR release was expected
- a MAJOR release while a MINOR release was expected
[semver]: http://semver.org/

View File

@@ -0,0 +1,128 @@
<!--
- SPDX-License-Identifier: Apache-2.0
- Copyright (c) 2022 Nordic Semiconductor ASA
- Original license:
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-->
# Serial recovery
MCUboot implements a Simple Management Protocol (SMP) server.
SMP is a basic transfer encoding for use with the MCUmgr management protocol.
See the Zephyr [Device Management](https://docs.zephyrproject.org/latest/services/device_mgmt/index.html#device-mgmt) documentation for more information about MCUmgr and SMP.
MCUboot supports the following subset of the MCUmgr commands:
* echo (OS group)
* reset (OS group)
* image list (IMG group)
* image upload (IMG group)
It can also support system-specific MCUmgr commands depending on the given mcuboot-port
if the ``MCUBOOT_PERUSER_MGMT_GROUP_ENABLED`` option is enabled.
The serial recovery feature can use any serial interface provided by the platform.
## Image uploading
Uploading an image is targeted to the primary slot by default.
An image can be loaded to other slots only when the ``MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD`` option is enabled for the platform.
MCUboot supports progressive erasing of a slot to which an image is uploaded to if the ``MCUBOOT_ERASE_PROGRESSIVELY`` option is enabled.
As a result, a device can receive images smoothly, and can erase required part of a flash automatically.
## Configuration of serial recovery
How to enable and configure the serial recovery feature depends on the given mcuboot-port implementation.
Refer to the respective documentation and source code for more details.
## Entering serial recovery mode
Entering the serial recovery mode is usually possible right after a device reset, for instance as a reaction on a GPIO pin state.
Refer to the given mcuboot-port details to get information on how to enter the serial recovery mode.
## Serial recovery mode usage
### MCU Manager CLI installation
The MCUmgr command line tool can be used as an SMP client for evaluation purposes.
The tool is available under the [MCU Manager](https://github.com/apache/mynewt-mcumgr-cli)
Github page and is described in the Zephyr
[MCU Manager CLI](https://docs.zephyrproject.org/latest/services/device_mgmt/mcumgr.html#mcumgr-cli) documentation.
Use the following command to install the MCU Manager CLI tool:
``` console
go install github.com/apache/mynewt-mcumgr-cli/mcumgr@latest
```
Enter serial recovery mode in the device and use an SMP client application for communication with the MCUboot's SMP server.
### Connection configuration
Use the following command to set the connection configuration,
for linux:
``` console
mcumgr conn add serial_1 type="serial" connstring="dev=/dev/ttyACM0,baud=115200"
```
for windows:
``` console
mcumgr conn add serial_1 type="serial" connstring="COM1,baud=115200"
```
### Image management
The connection configuration must be established to perform the following image-related commands:
* Upload the image:
``` console
mcumgr image upload <path-to-signed-image-bin-file> -c serial_1
```
Once done successfully, the following notification will be displayed:
``` console
20.25 KiB / 20.25 KiB [=================================] 100.00% 3.08 KiB/s 6s
Done
```
* List all images:
``` console
mcumgr image list -c serial_1
```
The terminal will show the response from the module:
``` console
Images:
image=0 slot=0
version: 0.0.0.0
bootable: false
flags:
hash: Unavailable
Split status: N/A (0)
```
### Device reset
Reset your device with the following command:
``` console
mcumgr reset -c serial_1
```
The terminal should respond:
``` console
Done
```

View File

@@ -0,0 +1,100 @@
<!--
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-
-->
## Image signing
This signs the image by computing hash over the image, and then
signing that hash. Signature is computed by newt tool when it's
creating the image. This signature is placed in the image trailer.
The public key of this keypair must be included in the bootloader,
as it verifies it before allowing the image to run.
This facility allows you to use multiple signing keys. This would
be useful when you want to prevent production units from booting
development images, but want development units to be able to boot
both production images and development images.
For an alternative solution when the public key(s) doesn't need to be
included in the bootloader, see the [design](design.md) document.
## Creating signing keys
First you need a keypair to use for signing. You can create
one with openssl command line tool.
openssl genrsa -out image_sign.pem 2048
This created a file which contains both the private and public key,
and will be used when signing images.
Then you need to extract the public key from this to include it
in the bootloader. Bootloader need to keep key parsing minimal,
so it expects simple key format.
openssl rsa -in image_sign.pem -pubout -out image_sign_pub.der -outform DER -RSAPublicKey_out
Now the public key is in file called image_sign_pub.der.
For ECDSA256 these commands are similar.
openssl ecparam -name prime256v1 -genkey -noout -out image_sign.pem
openssl ec -in image_sign.pem -pubout -outform DER -out image_sign_pub.der
## Creating a key package
xxd -i image_sign_pub.der image_sign_pub.c.import
Then you need to create a package containing this key, or keys.
## Sample pkg.yml
This gets bootutil to turn on image signature validation.
pkg.name: libs/mykeys
pkg.deps:
- "@apache-mynewt-core/boot/bootutil"
## Sample source file
This exports the keys.
#include <bootutil/sign_key.h>
#include "image_sign_pub.c.import"
const struct bootutil_key bootutil_keys[] = {
[0] = {
.key = image_sign_pub_der,
.len = &image_sign_pub_der_len,
}
};
const int bootutil_key_cnt = sizeof(bootutil_keys) / sizeof(bootutil_keys[0]);
## Building the bootloader
Enable the BOOTUTIL_SIGN_RSA syscfg setting in your app or target syscfg.yml
file
syscfg.vals:
BOOTUTIL_SIGN_RSA: 1
After you've created the key package, you must include it in the build
for bootloader. So modify the pkg.yml for apps/boot to include it.
The syscfg variable to enable ECDSA256 is BOOTUTIL_SIGN_EC256.

View File

@@ -0,0 +1,162 @@
## MCUboot test plan
The current target for running the tests is the Freedom K64F board.
### Basic sign support (RSA/EC/EC256)
For each supported signing algorithm, check that non-signed, and signed
with wrong key images are not swapped to, and image signed with correct key
is swapped to.
For the 3 algorithms supported, rsa, ec and ec256, two files are provided:
key_<sign-algo>.pem, key_<sign-algo>_2.pem. And a keys file with the C public
key data for key_<sign-algo>.pem.
Build and load MCUboot:
* `newt build k64f_boot_<sign-algo>`
* `newt load k64f_boot_<sign-algo>`
Build and load good image in slot 0:
* `newt create-image k64f_blinky 1.0.1 key_<sign-algo>.pem`
* `newt load k64f_blinky`
---
***Note***
*If testing RSA/PSS `newt create-image` needs to be passed in the extra*
*flag `--rsa-pss` eg:*
`newt create-image k64f_blinky 1.0.1 key_rsa.pem --rsa-pss`
---
Build and load image in slot 1 with no signing, signed with
key_<sign-algo>_2.pem and signed with key_<sign-algo>.pem. Mark each one as
test image and check that swap only happens for image signed with
key_<sign-algo>.pem. Both others should be erased.
* `newt create-image k64f_blinky2 1.0.2 <one-of-the-sign-keys-or-none>`
* `newtmgr image upload k64f_blinky2`
* `newtmgr image list`
* `newtmgr image test <hash of slot 1>`
### Image signed with more than one key
FIXME: this is currently not functional, skip this section!
Build and load MCUboot:
* `newt build k64f_boot_rsa_ec`
* `newt load k64f_boot_rsa_ec`
Build and load good image in slot 0:
* `newt create-image k64f_blinky 1.0.1 key_rsa.pem`
* `newt load k64f_blinky`
Build and load image in slot 1 with no signing, signed with
key_<sign-algo>_2.pem and signed with key_<sign-algo>.pem. Mark each one as
test image and check that swap only happens for image signed with
key_<sign-algo>.pem. Both others should be erased.
Use all of this options:
* `newt create-image k64f_blinky2 1.0.2`
And load
* `newtmgr image upload k64f_blinky2`
* `newtmgr image list`
* `newtmgr image test <hash of slot 1>`
### Overwrite only functionality
Build/load MCUboot:
* `newt build k64f_boot_rsa_noswap`
* `newt load k64f_boot_rsa_noswap`
Build/load blinky to slot 0:
* `newt create-image k64f_blinky 1.0.1 key_rsa.pem`
* `newt load k64f_blinky`
Build/load blinky2 both with bad and good key, followed by a permanent swap
request:
* `newt create-image k64f_blinky2 1.0.2 <bad and good rsa keys>.pem`
* `newtmgr image upload k64f_blinky2`
* `newtmgr image list`
* `newtmgr image confirm <hash of slot 1>`
This should not swap and delete the image in slot 1 when signed with the wrong
key, otherwise the image in slot 1 should be *moved* to slot 0 and slot 1 should
be empty.
### Validate slot 0 option
Build/load MCUboot:
* `newt build k64f_boot_rsa_validate0`
* `newt load k64f_boot_rsa_validate0`
Build non-signed image:
* `newt create-image k64f_blinky 1.0.1`
* `newt load k64f_blinky`
* Reset and no image should be run
Build signed image with invalid key:
* `newt create-image k64f_blinky 1.0.1 key_rsa_2.pem`
* `newt load k64f_blinky`
* Reset and no image should be run
Build signed image with *valid* key:
* `newt create-image k64f_blinky 1.0.1 key_rsa.pem`
* `newt load k64f_blinky`
* Reset and image *should* run
### Swap with random failures
DISCLAIMER: be careful with copy/paste of commands, this test uses another
target/app!
Build/load MCUboot:
* `newt build k64f_boot_rsa`
* `newt load k64f_boot_rsa`
Build/load slinky to slot 0:
* `newt create-image k64f_slinky 1.0.1 key_rsa.pem`
* `newt load k64f_slinky`
Build/load slinky2 to slot 1:
* `newt create-image k64f_slinky2 1.0.2 key_rsa.pem`
* `newtmgr image upload k64f_slinky2`
Confirm that both images are installed, request a permanent request to the
image in slot 1 and check that it works.
* `newtmgr image list`
* `newtmgr image confirm <hash of slot 1>`
If everything works, now proceed with requests for permanent swap to the image
in slot 1 and do random swaps (as much as you like!). When the swap finishes
confirm that the swap was finished with the previous slot 1 image now in
slot 0 and vice-versa.
### Help
* Mass erase MCU
$ pyocd erase --chip
* Flashing image in slot 1:
$ pyocd flash -e sector -a 0x80000 ${IMG_FILE} bin

View File

@@ -0,0 +1,71 @@
# Zephyr test plan
The following roughly describes how MCUboot is tested on Zephyr. The
testing is done with the code in `samples/zephyr`. These examples
were written using the FRDM-K64F, but other boards should be similar.
At this time, however, the partitions are hardcoded in the Makefile
targets to flash.
Note that the script "run-tests.sh" in that directory is helpful for
automating the process, and provides simple "y or n" prompts for each
test case and expected result.
## Building and running.
The tests are build using the various `test-*` targets in
`samples/zephyr/Makefile`. For each test, invoke `make` with that
target:
$ make test-good-rsa
Begin by doing a full erase, and programming the bootloader itself:
$ pyocd erase --chip
$ make flash_boot
After it resets, look for "main: Starting bootloader", a few debug
messages, and lastly: "main: Unable to find bootable image".
Then, load hello1:
$ make flash_hello1
This should print "main: Jumping to the first image slot", and you
should get an image "hello1".
Note that there are comments with each test target describing the
intended behavior for each of these steps. Sometimes an upgrade will
happen and sometimes it will not.
$ make flash_hello2
This should print a message: `boot_swap_type: Swap type: test`, and
you should see "hello2".
Now reset the target::
$ pyocd commander -c reset
And you should see a revert and "hello1" running.
## Testing that mark ok works
Repeat this, to make sure we can mark the image as OK, and that a
revert doesn't happen:
$ make flash_hello1
$ make flash_hello2
We should have just booted the hello2. Mark this as OK:
$ pyocd flash -a 0x7ffe8 image_ok.bin
$ pyocd commander -c reset
And make sure this stays in the "hello2" image.
This step doesn't make sense on the tests where the upgrade doesn't
happen.
## Testing all configurations
Repeat these steps for each of the `test-*` targest in the Makefile.