blob: f0a856e09b195381f44c4477b66fb6bdaac7eef3 [file] [log] [blame] [view]
David Brown17e20d12017-09-12 11:53:20 -06001<!--
David Brownaac71112020-02-03 16:13:42 -07002 - SPDX-License-Identifier: Apache-2.0
David Brown17e20d12017-09-12 11:53:20 -06003
David Vinczee574f2d2020-07-10 11:42:03 +02004 - Copyright (c) 2017-2020 Linaro LTD
David Brownaac71112020-02-03 16:13:42 -07005 - Copyright (c) 2017-2019 JUUL Labs
6 - Copyright (c) 2019-2020 Arm Limited
7
8 - Original license:
9
10 - Licensed to the Apache Software Foundation (ASF) under one
11 - or more contributor license agreements. See the NOTICE file
12 - distributed with this work for additional information
13 - regarding copyright ownership. The ASF licenses this file
14 - to you under the Apache License, Version 2.0 (the
15 - "License"); you may not use this file except in compliance
16 - with the License. You may obtain a copy of the License at
17
18 - http://www.apache.org/licenses/LICENSE-2.0
19
20 - Unless required by applicable law or agreed to in writing,
21 - software distributed under the License is distributed on an
22 - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23 - KIND, either express or implied. See the License for the
24 - specific language governing permissions and limitations
25 - under the License.
David Vinczeba3bd602019-06-17 16:01:43 +020026-->
27
David Brown17e20d12017-09-12 11:53:20 -060028# Boot Loader
29
Fabio Utzigd37d8772019-12-03 10:32:18 -030030## [Summary](#summary)
Christopher Collins92ea77f2016-12-12 15:59:26 -080031
Fabio Utzigac834962017-07-20 13:20:48 -030032mcuboot comprises two packages:
Christopher Collins92ea77f2016-12-12 15:59:26 -080033
David Brown17e20d12017-09-12 11:53:20 -060034* The bootutil library (boot/bootutil)
35* The boot application (each port has its own at boot/<port>)
Christopher Collins92ea77f2016-12-12 15:59:26 -080036
37The bootutil library performs most of the functions of a boot loader. In
38particular, the piece that is missing is the final step of actually jumping to
39the main image. This last step is instead implemented by the boot application.
40Boot loader functionality is separated in this manner to enable unit testing of
41the boot loader. A library can be unit tested, but an application can't.
42Therefore, functionality is delegated to the bootutil library when possible.
43
Fabio Utzigd37d8772019-12-03 10:32:18 -030044## [Limitations](#limitations)
Christopher Collins92ea77f2016-12-12 15:59:26 -080045
46The boot loader currently only supports images with the following
47characteristics:
David Brown17e20d12017-09-12 11:53:20 -060048* Built to run from flash.
49* Built to run from a fixed location (i.e., not position-independent).
Christopher Collins92ea77f2016-12-12 15:59:26 -080050
Fabio Utzigd37d8772019-12-03 10:32:18 -030051## [Image Format](#image-format)
Christopher Collins92ea77f2016-12-12 15:59:26 -080052
53The following definitions describe the image format.
54
David Brown17e20d12017-09-12 11:53:20 -060055``` c
Fabio Utzigea422c22017-09-11 11:02:47 -030056#define IMAGE_MAGIC 0x96f3b83d
Christopher Collins92ea77f2016-12-12 15:59:26 -080057
58#define IMAGE_HEADER_SIZE 32
59
60struct image_version {
61 uint8_t iv_major;
62 uint8_t iv_minor;
63 uint16_t iv_revision;
64 uint32_t iv_build_num;
65};
66
67/** Image header. All fields are in little endian byte order. */
68struct image_header {
69 uint32_t ih_magic;
Fabio Utzigea422c22017-09-11 11:02:47 -030070 uint32_t ih_load_addr;
David Vinczee32483f2019-06-13 10:46:24 +020071 uint16_t ih_hdr_size; /* Size of image header (bytes). */
72 uint16_t ih_protect_tlv_size; /* Size of protected TLV area (bytes). */
73 uint32_t ih_img_size; /* Does not include header. */
74 uint32_t ih_flags; /* IMAGE_F_[...]. */
Christopher Collins92ea77f2016-12-12 15:59:26 -080075 struct image_version ih_ver;
David Vinczee32483f2019-06-13 10:46:24 +020076 uint32_t _pad1;
Christopher Collins92ea77f2016-12-12 15:59:26 -080077};
78
Fabio Utzigfd140ec2019-09-12 14:37:48 -030079#define IMAGE_TLV_INFO_MAGIC 0x6907
80#define IMAGE_TLV_PROT_INFO_MAGIC 0x6908
81
Fabio Utzigea422c22017-09-11 11:02:47 -030082/** Image TLV header. All fields in little endian. */
83struct image_tlv_info {
84 uint16_t it_magic;
85 uint16_t it_tlv_tot; /* size of TLV area (including tlv_info header) */
86};
87
Christopher Collins92ea77f2016-12-12 15:59:26 -080088/** Image trailer TLV format. All fields in little endian. */
89struct image_tlv {
90 uint8_t it_type; /* IMAGE_TLV_[...]. */
91 uint8_t _pad;
Marti Bolivar49b29172017-08-04 14:50:51 -040092 uint16_t it_len; /* Data length (not including TLV header). */
Christopher Collins92ea77f2016-12-12 15:59:26 -080093};
94
95/*
96 * Image header flags.
97 */
Marti Bolivar7c057e92017-08-04 14:46:39 -040098#define IMAGE_F_PIC 0x00000001 /* Not supported. */
Marti Bolivar7c057e92017-08-04 14:46:39 -040099#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
Fabio Utzigea422c22017-09-11 11:02:47 -0300100#define IMAGE_F_RAM_LOAD 0x00000020
Christopher Collins92ea77f2016-12-12 15:59:26 -0800101
102/*
103 * Image trailer TLV types.
104 */
Fabio Utzigea422c22017-09-11 11:02:47 -0300105#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
David Brown27648b82017-08-31 10:40:29 -0600106#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
Marko Kiiskila8dd56f32017-08-22 21:40:49 -0700107#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
David Brown27648b82017-08-31 10:40:29 -0600108#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output */
109#define IMAGE_TLV_ECDSA256 0x22 /* ECDSA of hash output */
Fabio Utzig3501c012019-05-13 15:07:25 -0700110#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
Fabio Utzig195411f2019-06-28 07:48:21 -0300111#define IMAGE_TLV_ED25519 0x24 /* ED25519 of hash output */
David Vinczee32483f2019-06-13 10:46:24 +0200112#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
113#define IMAGE_TLV_ENC_KW128 0x31 /* Key encrypted with AES-KW-128 */
Fabio Utzig5eaa5762020-04-02 13:30:43 -0300114#define IMAGE_TLV_ENC_EC256 0x32 /* Key encrypted with ECIES-P256 */
115#define IMAGE_TLV_ENC_X25519 0x33 /* Key encrypted with ECIES-X25519 */
David Vinczee32483f2019-06-13 10:46:24 +0200116#define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */
David Vinczec3084132020-02-18 14:50:47 +0100117#define IMAGE_TLV_SEC_CNT 0x50 /* security counter */
David Brown17e20d12017-09-12 11:53:20 -0600118```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800119
120Optional type-length-value records (TLVs) containing image metadata are placed
121after the end of the image.
122
David Vinczee32483f2019-06-13 10:46:24 +0200123The `ih_protect_tlv_size` field indicates the length of the protected TLV area.
Fabio Utzigfd140ec2019-09-12 14:37:48 -0300124If protected TLVs are present then a TLV info header with magic equal to
125`IMAGE_TLV_PROT_INFO_MAGIC` must be present and the protected TLVs (plus the
126info header itself) have to be included in the hash calculation. Otherwise the
127hash is only calculated over the image header and the image itself. In this
David Vinczee32483f2019-06-13 10:46:24 +0200128case the value of the `ih_protect_tlv_size` field is 0.
129
David Brown17e20d12017-09-12 11:53:20 -0600130The `ih_hdr_size` field indicates the length of the header, and therefore the
Christopher Collins92ea77f2016-12-12 15:59:26 -0800131offset of the image itself. This field provides for backwards compatibility in
132case of changes to the format of the image header.
133
Fabio Utzigd37d8772019-12-03 10:32:18 -0300134## [Flash Map](#flash-map)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800135
Fabio Utzigac834962017-07-20 13:20:48 -0300136A device's flash is partitioned according to its _flash map_. At a high
Christopher Collins92ea77f2016-12-12 15:59:26 -0800137level, the flash map maps numeric IDs to _flash areas_. A flash area is a
138region of disk with the following properties:
David Brown17e20d12017-09-12 11:53:20 -06001391. An area can be fully erased without affecting any other areas.
1402. A write to one area does not restrict writes to other areas.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800141
Marti Bolivar4e64d562017-08-04 14:53:33 -0400142The boot loader uses the following flash area IDs:
David Vinczeb75c12a2019-03-22 14:58:33 +0100143```c
144/* Independent from multiple image boot */
David Vincze2d736ad2019-02-18 11:50:22 +0100145#define FLASH_AREA_BOOTLOADER 0
David Vinczeb75c12a2019-03-22 14:58:33 +0100146#define FLASH_AREA_IMAGE_SCRATCH 3
147```
148```c
149/* If the boot loader is working with the first image */
David Vincze2d736ad2019-02-18 11:50:22 +0100150#define FLASH_AREA_IMAGE_PRIMARY 1
151#define FLASH_AREA_IMAGE_SECONDARY 2
David Vinczeb75c12a2019-03-22 14:58:33 +0100152```
153```c
154/* If the boot loader is working with the second image */
155#define FLASH_AREA_IMAGE_PRIMARY 5
156#define FLASH_AREA_IMAGE_SECONDARY 6
David Brown17e20d12017-09-12 11:53:20 -0600157```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800158
Marti Bolivar4e64d562017-08-04 14:53:33 -0400159The bootloader area contains the bootloader image itself. The other areas are
David Vinczeb75c12a2019-03-22 14:58:33 +0100160described in subsequent sections. The flash could contain multiple executable
161images therefore the flash area IDs of primary and secondary areas are mapped
162based on the number of the active image (on which the bootloader is currently
163working).
Marti Bolivar4e64d562017-08-04 14:53:33 -0400164
Fabio Utzigd37d8772019-12-03 10:32:18 -0300165## [Image Slots](#image-slots)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800166
David Vinczeb75c12a2019-03-22 14:58:33 +0100167A portion of the flash memory can be partitioned into multiple image areas, each
168contains two image slots: a primary slot and a secondary slot.
David Vinczee574f2d2020-07-10 11:42:03 +0200169Normally, the boot loader will only run an image from the primary slot, so
170images must be built such that they can run from that fixed location in flash
Tamas Banfe031092020-09-10 17:32:39 +0200171(the exception to this is the [direct-xip](#direct-xip) and the
172[ram-load](#ram-load) upgrade mode). If the boot loader needs to run the
173image resident in the secondary slot, it must copy its contents into the primary
174slot before doing so, either by swapping the two images or by overwriting the
175contents of the primary slot. The bootloader supports either swap- or
176overwrite-based image upgrades, but must be configured at build time to choose
177one of these two strategies.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800178
David Vinczeb75c12a2019-03-22 14:58:33 +0100179In addition to the slots of image areas, the boot loader requires a scratch
180area to allow for reliable image swapping. The scratch area must have a size
181that is enough to store at least the largest sector that is going to be swapped.
182Many devices have small equally sized flash sectors, eg 4K, while others have
David Vincze2d736ad2019-02-18 11:50:22 +0100183variable sized sectors where the largest sectors might be 128K or 256K, so the
184scratch must be big enough to store that. The scratch is only ever used when
185swapping firmware, which means only when doing an upgrade. Given that, the main
186reason for using a larger size for the scratch is that flash wear will be more
187evenly distributed, because a single sector would be written twice the number of
188times than using two sectors, for example. To evaluate the ideal size of the
189scratch for your use case the following parameters are relevant:
Fabio Utziga722f5a2017-12-12 14:04:53 -0200190
191* the ratio of image size / scratch size
192* the number of erase cycles supported by the flash hardware
193
194The image size is used (instead of slot size) because only the slot's sectors
195that are actually used for storing the image are copied. The image/scratch ratio
196is the number of times the scratch will be erased on every upgrade. The number
197of erase cycles divided by the image/scratch ratio will give you the number of
198times an upgrade can be performed before the device goes out of spec.
199
200```
201num_upgrades = number_of_erase_cycles / (image_size / scratch_size)
202```
203
204Let's assume, for example, a device with 10000 erase cycles, an image size of
205150K and a scratch of 4K (usual minimum size of 4K sector devices). This would
206result in a total of:
207
208`10000 / (150 / 4) ~ 267`
209
210Increasing the scratch to 16K would give us:
211
212`10000 / (150 / 16) ~ 1067`
213
214There is no *best* ratio, as the right size is use-case dependent. Factors to
215consider include the number of times a device will be upgraded both in the field
David Vincze2d736ad2019-02-18 11:50:22 +0100216and during development, as well as any desired safety margin on the
217manufacturer's specified number of erase cycles. In general, using a ratio that
218allows hundreds to thousands of field upgrades in production is recommended.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800219
David Vinczee574f2d2020-07-10 11:42:03 +0200220### [Equal slots (direct-xip)](#direct-xip)
221
222When the direct-xip mode is enabled the active image flag is "moved" between the
223slots during image upgrade and in contrast to the above, the bootloader can
224run an image directly from either the primary or the secondary slot (without
225having to move/copy it into the primary slot). Therefore the image update
226client, which downloads the new images must be aware, which slot contains the
227active image and which acts as a staging area and it is responsible for loading
228the proper images into the proper slot. All this requires that the images be
229built to be executed from the corresponding slot. At boot time the bootloader
230first looks for images in the slots and then inspects the version numbers in the
231image headers. It selects the newest image (with the highest version number) and
232then checks its validity (integrity check, signature verification etc.). If the
233image is invalid MCUboot erases its memory slot and starts to validate the other
234image. After a successful validation of the selected image the bootloader
235chain-loads it.
236Handling the primary and secondary slots as equals has its drawbacks. Since the
237images are not moved between the slots, the on-the-fly image
238encryption/decryption can't be supported (it only applies to storing the image
239in an external flash on the device, the transport of encrypted image data is
240still feasible).
241
242The overwrite and the direct-xip upgrade strategies are substantially simpler to
243implement than the image swapping strategy, especially since the bootloader must
244work properly even when it is reset during the middle of an image swap. For this
245reason, the rest of the document describes its behavior when configured to swap
246images during an upgrade.
Marti Bolivara91674f2017-08-04 14:56:08 -0400247
Tamas Banfe031092020-09-10 17:32:39 +0200248### [RAM Loading](#ram-load)
249
250In ram-load mode the slots are equal. Like the direct-xip mode, this mode
251also selects the newest image by reading the image version numbers in the image
252headers. But instead of executing it in place, the newest image is copied to the
253RAM for execution. The load address, the location in RAM where the image is
254copied to, is stored in the image header. The ram-load upgrade mode can be
255useful when there is no internal flash in the SoC, but there is a big enough
256internal RAM to hold the images. Usually in this case the images are stored
257in an external storage device. Execution from external storage has some
258drawbacks (lower execution speed, image is exposed to attacks) therefore the
259image is always copied to the internal RAM before the authentication and
260execution. Ram-load mode requires the image to be built to be executed from
261the RAM address range instead of the storage device address range. If
262ram-load is enabled then platform must define the following parameters:
263
264```c
265#define IMAGE_EXECUTABLE_RAM_START <area_base_addr>
266#define IMAGE_EXECUTABLE_RAM_SIZE <area_size_in_bytes>
267```
268
269When ram-load is enabled, the `--load-addr <addr>` option of the `imgtool`
270script must also be used when signing the images. This option set the `RAM_LOAD`
271flag in the image header which indicates that the image should be loaded to the
272RAM and also set the load address in the image header.
273
274The ram-load mode currently supports only the single image boot and the image
275encryption feature is not supported.
276
Fabio Utzigd37d8772019-12-03 10:32:18 -0300277## [Boot Swap Types](#boot-swap-types)
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800278
Marti Bolivar048d8d82017-08-04 17:14:24 -0400279When the device first boots under normal circumstances, there is an up-to-date
David Vinczeba3bd602019-06-17 16:01:43 +0200280firmware image in each primary slot, which mcuboot can validate and then
David Vincze2d736ad2019-02-18 11:50:22 +0100281chain-load. In this case, no image swaps are necessary. During device upgrades,
David Vinczeba3bd602019-06-17 16:01:43 +0200282however, new candidate image(s) is present in the secondary slot(s), which
283mcuboot must swap into the primary slot(s) before booting as discussed above.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800284
Marti Bolivar048d8d82017-08-04 17:14:24 -0400285Upgrading an old image with a new one by swapping can be a two-step process. In
286this process, mcuboot performs a "test" swap of image data in flash and boots
David Vinczeba3bd602019-06-17 16:01:43 +0200287the new image or it will be executed during operation. The new image can then
288update the contents of flash at runtime to mark itself "OK", and mcuboot will
289then still choose to run it during the next boot. When this happens, the swap is
290made "permanent". If this doesn't happen, mcuboot will perform a "revert" swap
291during the next boot by swapping the image(s) back into its original location(s)
292, and attempting to boot the old image(s).
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800293
Marti Bolivar048d8d82017-08-04 17:14:24 -0400294Depending on the use case, the first swap can also be made permanent directly.
295In this case, mcuboot will never attempt to revert the images on the next reset.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800296
Marti Bolivar048d8d82017-08-04 17:14:24 -0400297Test swaps are supported to provide a rollback mechanism to prevent devices
298from becoming "bricked" by bad firmware. If the device crashes immediately
299upon booting a new (bad) image, mcuboot will revert to the old (working) image
300at the next device reset, rather than booting the bad image again. This allows
301device firmware to make test swaps permanent only after performing a self-test
302routine.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800303
David Vinczeba3bd602019-06-17 16:01:43 +0200304On startup, mcuboot inspects the contents of flash to decide for each images
305which of these "swap types" to perform; this decision determines how it
306proceeds.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800307
Marti Bolivar048d8d82017-08-04 17:14:24 -0400308The possible swap types, and their meanings, are:
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800309
David Brown17e20d12017-09-12 11:53:20 -0600310- `BOOT_SWAP_TYPE_NONE`: The "usual" or "no upgrade" case; attempt to boot the
David Vincze2d736ad2019-02-18 11:50:22 +0100311 contents of the primary slot.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800312
David Vincze2d736ad2019-02-18 11:50:22 +0100313- `BOOT_SWAP_TYPE_TEST`: Boot the contents of the secondary slot by swapping
314 images. Unless the swap is made permanent, revert back on the next boot.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800315
David Brown17e20d12017-09-12 11:53:20 -0600316- `BOOT_SWAP_TYPE_PERM`: Permanently swap images, and boot the upgraded image
Marti Bolivar048d8d82017-08-04 17:14:24 -0400317 firmware.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800318
David Vincze2d736ad2019-02-18 11:50:22 +0100319- `BOOT_SWAP_TYPE_REVERT`: A previous test swap was not made permanent;
320 swap back to the old image whose data are now in the secondary slot. If the
321 old image marks itself "OK" when it boots, the next boot will have swap type
322 `BOOT_SWAP_TYPE_NONE`.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800323
David Brown17e20d12017-09-12 11:53:20 -0600324- `BOOT_SWAP_TYPE_FAIL`: Swap failed because image to be run is not valid.
Marti Bolivar048d8d82017-08-04 17:14:24 -0400325
David Brown17e20d12017-09-12 11:53:20 -0600326- `BOOT_SWAP_TYPE_PANIC`: Swapping encountered an unrecoverable error.
Marti Bolivar048d8d82017-08-04 17:14:24 -0400327
328The "swap type" is a high-level representation of the outcome of the
329boot. Subsequent sections describe how mcuboot determines the swap type from
330the bit-level contents of flash.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800331
Fabio Utzigd37d8772019-12-03 10:32:18 -0300332## [Image Trailer](#image-trailer)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800333
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300334For the bootloader to be able to determine the current state and what actions
Marti Bolivar42818032017-08-04 15:45:01 -0400335should be taken during the current boot operation, it uses metadata stored in
336the image flash areas. While swapping, some of this metadata is temporarily
337copied into and out of the scratch area.
338
339This metadata is located at the end of the image flash areas, and is called an
340image trailer. An image trailer has the following structure:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800341
David Brown17e20d12017-09-12 11:53:20 -0600342```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800343 0 1 2 3
344 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
345 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collins92ea77f2016-12-12 15:59:26 -0800346 ~ ~
Fabio Utzig2c05f1b2018-04-04 10:35:17 -0300347 ~ Swap status (BOOT_MAX_IMG_SECTORS * min-write-size * 3) ~
Christopher Collins92ea77f2016-12-12 15:59:26 -0800348 ~ ~
349 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700350 | Encryption key 0 (16 octets) [*] |
351 | |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700353 | Encryption key 1 (16 octets) [*] |
354 | |
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300355 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700356 | Swap size (4 octets) |
Fabio Utzigea422c22017-09-11 11:02:47 -0300357 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Vinczee2453472019-06-17 12:31:59 +0200358 | Swap info | 0xff padding (7 octets) |
Fabio Utzigea422c22017-09-11 11:02:47 -0300359 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700360 | Copy done | 0xff padding (7 octets) |
361 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
362 | Image OK | 0xff padding (7 octets) |
363 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
364 | MAGIC (16 octets) |
365 | |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800366 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Brown17e20d12017-09-12 11:53:20 -0600367```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800368
Christopher Collinsa1c12042019-05-23 14:00:28 -0700369[*]: Only present if the encryption option is enabled (`MCUBOOT_ENC_IMAGES`).
370
Marti Bolivar42818032017-08-04 15:45:01 -0400371The offset immediately following such a record represents the start of the next
372flash area.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800373
374Note: "min-write-size" is a property of the flash hardware. If the hardware
375allows individual bytes to be written at arbitrary addresses, then
376min-write-size is 1. If the hardware only allows writes at even addresses,
377then min-write-size is 2, and so on.
378
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400379An image trailer contains the following fields:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800380
Marti Bolivar1dcb6852017-08-04 15:59:32 -04003811. Swap status: A series of records which records the progress of an image
David Vincze2d736ad2019-02-18 11:50:22 +0100382 swap. To swap entire images, data are swapped between the two image areas
383 one or more sectors at a time, like this:
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400384
David Vincze2d736ad2019-02-18 11:50:22 +0100385 - sector data in the primary slot is copied into scratch, then erased
386 - sector data in the secondary slot is copied into the primary slot,
387 then erased
388 - sector data in scratch is copied into the secondary slot
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400389
390As it swaps images, the bootloader updates the swap status field in a way that
391allows it to compute how far this swap operation has progressed for each
392sector. The swap status field can thus used to resume a swap operation if the
393bootloader is halted while a swap operation is ongoing and later reset. The
David Vincze2d736ad2019-02-18 11:50:22 +0100394`BOOT_MAX_IMG_SECTORS` value is the configurable maximum number of sectors
395mcuboot supports for each image; its value defaults to 128, but allows for
396either decreasing this size, to limit RAM usage, or to increase it in devices
397that have massive amounts of Flash or very small sized sectors and thus require
398a bigger configuration to allow for the handling of all slot's sectors.
399The factor of min-write-sz is due to the behavior of flash hardware. The factor
400of 3 is explained below.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300401
Christopher Collinsa1c12042019-05-23 14:00:28 -07004022. Encryption keys: key-encrypting keys (KEKs). These keys are needed for
403 image encryption and decryption. See the
404 [encrypted images](encrypted_images.md) document for more information.
405
4063. Swap size: When beginning a new swap operation, the total size that needs
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +0000407 to be swapped (based on the slot with largest image + TLVs) is written to
David Vincze2d736ad2019-02-18 11:50:22 +0100408 this location for easier recovery in case of a reset while performing the
409 swap.
Fabio Utzigea422c22017-09-11 11:02:47 -0300410
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +00004114. Swap info: A single byte which encodes the following information:
David Vinczee2453472019-06-17 12:31:59 +0200412 - Swap type: Stored in bits 0-3. Indicating the type of swap operation in
413 progress. When mcuboot resumes an interrupted swap, it uses this field to
414 determine the type of operation to perform. This field contains one of the
415 following values in the table below.
416 - Image number: Stored in bits 4-7. It has always 0 value at single image
417 boot. In case of multi image boot it indicates, which image was swapped when
418 interrupt happened. The same scratch area is used during in case of all
419 image swap operation. Therefore this field is used to determine which image
420 the trailer belongs to if boot status is found on scratch area when the swap
421 operation is resumed.
Christopher Collinsa1c12042019-05-23 14:00:28 -0700422
423| Name | Value |
424| ------------------------- | ----- |
425| `BOOT_SWAP_TYPE_TEST` | 2 |
426| `BOOT_SWAP_TYPE_PERM` | 3 |
427| `BOOT_SWAP_TYPE_REVERT` | 4 |
428
429
4305. Copy done: A single byte indicating whether the image in this slot is
David Brown17e20d12017-09-12 11:53:20 -0600431 complete (0x01=done; 0xff=not done).
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300432
Christopher Collinsa1c12042019-05-23 14:00:28 -07004336. Image OK: A single byte indicating whether the image in this slot has been
David Brown17e20d12017-09-12 11:53:20 -0600434 confirmed as good by the user (0x01=confirmed; 0xff=not confirmed).
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300435
Christopher Collinsa1c12042019-05-23 14:00:28 -07004367. MAGIC: The following 16 bytes, written in host-byte-order:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800437
David Brown17e20d12017-09-12 11:53:20 -0600438``` c
Christopher Collins92ea77f2016-12-12 15:59:26 -0800439 const uint32_t boot_img_magic[4] = {
440 0xf395c277,
441 0x7fefd260,
442 0x0f505235,
443 0x8079b62c,
444 };
David Brown17e20d12017-09-12 11:53:20 -0600445```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800446
Fabio Utzigd37d8772019-12-03 10:32:18 -0300447## [IMAGE TRAILERS](#image-trailers)
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300448
Marti Bolivar048d8d82017-08-04 17:14:24 -0400449At startup, the boot loader determines the boot swap type by inspecting the
450image trailers. When using the term "image trailers" what is meant is the
451aggregate information provided by both image slot's trailers.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300452
Fabio Utzigd37d8772019-12-03 10:32:18 -0300453### [New swaps (non-resumes)](#new-swaps-non-resumes)
Christopher Collinsa1c12042019-05-23 14:00:28 -0700454
455For new swaps, mcuboot must inspect a collection of fields to determine which
456swap operation to perform.
457
David Vincze2d736ad2019-02-18 11:50:22 +0100458The image trailers records are structured around the limitations imposed by
459flash hardware. As a consequence, they do not have a very intuitive design, and
460it is difficult to get a sense of the state of the device just by looking at the
Marti Bolivar048d8d82017-08-04 17:14:24 -0400461image trailers. It is better to map all the possible trailer states to the swap
462types described above via a set of tables. These tables are reproduced below.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300463
464Note: An important caveat about the tables described below is that they must
465be evaluated in the order presented here. Lower state numbers must have a
466higher priority when testing the image trailers.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800467
David Brown17e20d12017-09-12 11:53:20 -0600468```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800469 State I
David Vincze2d736ad2019-02-18 11:50:22 +0100470 | primary slot | secondary slot |
471 -----------------+--------------+----------------|
472 magic | Any | Good |
473 image-ok | Any | Unset |
474 copy-done | Any | Any |
475 -----------------+--------------+----------------'
476 result: BOOT_SWAP_TYPE_TEST |
477 -------------------------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300478
Christopher Collins92ea77f2016-12-12 15:59:26 -0800479
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300480 State II
David Vincze2d736ad2019-02-18 11:50:22 +0100481 | primary slot | secondary slot |
482 -----------------+--------------+----------------|
483 magic | Any | Good |
484 image-ok | Any | 0x01 |
485 copy-done | Any | Any |
486 -----------------+--------------+----------------'
487 result: BOOT_SWAP_TYPE_PERM |
488 -------------------------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300489
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800490
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300491 State III
David Vincze2d736ad2019-02-18 11:50:22 +0100492 | primary slot | secondary slot |
493 -----------------+--------------+----------------|
494 magic | Good | Unset |
495 image-ok | 0xff | Any |
496 copy-done | 0x01 | Any |
497 -----------------+--------------+----------------'
498 result: BOOT_SWAP_TYPE_REVERT |
499 -------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600500```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800501
Marti Bolivar048d8d82017-08-04 17:14:24 -0400502Any of the above three states results in mcuboot attempting to swap images.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800503
Marti Bolivar048d8d82017-08-04 17:14:24 -0400504Otherwise, mcuboot does not attempt to swap images, resulting in one of the
505other three swap types, as illustrated by State IV.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300506
David Brown17e20d12017-09-12 11:53:20 -0600507```
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300508 State IV
David Vincze2d736ad2019-02-18 11:50:22 +0100509 | primary slot | secondary slot |
510 -----------------+--------------+----------------|
511 magic | Any | Any |
512 image-ok | Any | Any |
513 copy-done | Any | Any |
514 -----------------+--------------+----------------'
515 result: BOOT_SWAP_TYPE_NONE, |
516 BOOT_SWAP_TYPE_FAIL, or |
517 BOOT_SWAP_TYPE_PANIC |
518 -------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600519```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800520
Marti Bolivar048d8d82017-08-04 17:14:24 -0400521In State IV, when no errors occur, mcuboot will attempt to boot the contents of
David Vincze2d736ad2019-02-18 11:50:22 +0100522the primary slot directly, and the result is `BOOT_SWAP_TYPE_NONE`. If the image
523in the primary slot is not valid, the result is `BOOT_SWAP_TYPE_FAIL`. If a
524fatal error occurs during boot, the result is `BOOT_SWAP_TYPE_PANIC`. If the
525result is either `BOOT_SWAP_TYPE_FAIL` or `BOOT_SWAP_TYPE_PANIC`, mcuboot hangs
526rather than booting an invalid or compromised image.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300527
Marti Bolivar048d8d82017-08-04 17:14:24 -0400528Note: An important caveat to the above is the result when a swap is requested
David Vincze2d736ad2019-02-18 11:50:22 +0100529 and the image in the secondary slot fails to validate, due to a hashing or
530 signing error. This state behaves as State IV with the extra action of
531 marking the image in the primary slot as "OK", to prevent further attempts
532 to swap.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300533
Fabio Utzigd37d8772019-12-03 10:32:18 -0300534### [Resumed swaps](#resumed-swaps)
Christopher Collinsa1c12042019-05-23 14:00:28 -0700535
536If mcuboot determines that it is resuming an interrupted swap (i.e., a reset
537occurred mid-swap), it fully determines the operation to resume by reading the
David Vinczee2453472019-06-17 12:31:59 +0200538`swap info` field from the active trailer and extracting the swap type from bits
5390-3. The set of tables in the previous section are not necessary in the resume
540case.
Christopher Collinsa1c12042019-05-23 14:00:28 -0700541
Fabio Utzigd37d8772019-12-03 10:32:18 -0300542## [High-Level Operation](#high-level-operation)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800543
544With the terms defined, we can now explore the boot loader's operation. First,
545a high-level overview of the boot process is presented. Then, the following
546sections describe each step of the process in more detail.
547
548Procedure:
549
David Brown17e20d12017-09-12 11:53:20 -06005501. Inspect swap status region; is an interrupted swap being resumed?
Fabio Utzig75b34412019-09-06 08:30:43 -0300551 + Yes: Complete the partial swap operation; skip to step 3.
552 + No: Proceed to step 2.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800553
David Brown17e20d12017-09-12 11:53:20 -06005542. Inspect image trailers; is a swap requested?
Fabio Utzig75b34412019-09-06 08:30:43 -0300555 + Yes:
556 1. Is the requested image valid (integrity and security check)?
557 + Yes.
558 a. Perform swap operation.
559 b. Persist completion of swap procedure to image trailers.
560 c. Proceed to step 3.
561 + No.
562 a. Erase invalid image.
563 b. Persist failure of swap procedure to image trailers.
564 c. Proceed to step 3.
565
566 + No: Proceed to step 3.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800567
David Vincze2d736ad2019-02-18 11:50:22 +01005683. Boot into image in primary slot.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800569
Fabio Utzigd37d8772019-12-03 10:32:18 -0300570### [Multiple Image Boot](#multiple-image-boot)
David Vinczeba3bd602019-06-17 16:01:43 +0200571
572When the flash contains multiple executable images the boot loader's operation
573is a bit more complex but similar to the previously described procedure with
574one image. Every image can be updated independently therefore the flash is
575partitioned further to arrange two slots for each image.
576```
577+--------------------+
578| MCUBoot |
579+--------------------+
580 ~~~~~ <- memory might be not contiguous
581+--------------------+
582| Image 0 |
583| primary slot |
584+--------------------+
585| Image 0 |
586| secondary slot |
587+--------------------+
588 ~~~~~ <- memory might be not contiguous
589+--------------------+
590| Image N |
591| primary slot |
592+--------------------+
593| Image N |
594| secondary slot |
595+--------------------+
596| Scratch |
597+--------------------+
598```
David Vinczee32483f2019-06-13 10:46:24 +0200599MCUBoot is also capable of handling dependencies between images. For example
600if an image needs to be reverted it might be necessary to revert another one too
601(e.g. due to API incompatibilities) or simply to prevent from being updated
602because of an unsatisfied dependency. Therefore all aborted swaps have to be
603completed and all the swap types have to be determined for each image before
604the dependency checks. Dependency handling is described in more detail in a
605following section. The multiple image boot procedure is organized in loops which
606iterate over all the firmware images. The high-level overview of the boot
607process is presented below.
David Vinczeba3bd602019-06-17 16:01:43 +0200608
609+ ###### Loop 1. Iterate over all images
610 1. Inspect swap status region of current image; is an interrupted swap being
611 resumed?
612 + Yes:
613 + Review the validity of previously determined swap types
614 of other images.
615 + Complete the partial swap operation.
616 + Mark the swap type as `None`.
617 + Skip to next image.
618 + No: Proceed to step 2.
619
620 2. Inspect image trailers in the primary and secondary slot; is an image
621 swap requested?
622 + Yes: Review the validity of previously determined swap types of other
623 images. Is the requested image valid (integrity and security
624 check)?
625 + Yes:
626 + Set the previously determined swap type for the current image.
627 + Skip to next image.
628 + No:
629 + Erase invalid image.
630 + Persist failure of swap procedure to image trailers.
631 + Mark the swap type as `Fail`.
632 + Skip to next image.
633 + No:
634 + Mark the swap type as `None`.
635 + Skip to next image.
636
637+ ###### Loop 2. Iterate over all images
David Vinczee32483f2019-06-13 10:46:24 +0200638 1. Does the current image depend on other image(s)?
639 + Yes: Are all the image dependencies satisfied?
640 + Yes: Skip to next image.
641 + No:
642 + Modify swap type depending on what the previous type was.
643 + Restart dependency check from the first image.
644 + No: Skip to next image.
David Vinczeba3bd602019-06-17 16:01:43 +0200645
David Vinczee32483f2019-06-13 10:46:24 +0200646+ ###### Loop 3. Iterate over all images
David Vinczeba3bd602019-06-17 16:01:43 +0200647 1. Is an image swap requested?
648 + Yes:
649 + Perform image update operation.
650 + Persist completion of swap procedure to image trailers.
651 + Skip to next image.
652 + No: Skip to next image.
653
David Vinczee32483f2019-06-13 10:46:24 +0200654+ ###### Loop 4. Iterate over all images
David Vinczeba3bd602019-06-17 16:01:43 +0200655 1. Validate image in the primary slot (integrity and security check) or
656 at least do a basic sanity check to avoid booting into an empty flash
657 area.
658
659+ Boot into image in the primary slot of the 0th image position\
660 (other image in the boot chain is started by another image).
661
Fabio Utzigd37d8772019-12-03 10:32:18 -0300662## [Image Swapping](#image-swapping)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800663
664The boot loader swaps the contents of the two image slots for two reasons:
Fabio Utzig75b34412019-09-06 08:30:43 -0300665
666 * User has issued a "set pending" operation; the image in the secondary slot
Håkon Øye Amundsen11d91c32020-03-04 08:49:47 +0000667 should be run once (state I) or repeatedly (state II), depending on
Fabio Utzig75b34412019-09-06 08:30:43 -0300668 whether a permanent swap was specified.
669 * Test image rebooted without being confirmed; the boot loader should
Håkon Øye Amundsen11d91c32020-03-04 08:49:47 +0000670 revert to the original image currently in the secondary slot (state III).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800671
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300672If the image trailers indicates that the image in the secondary slot should be
Christopher Collins92ea77f2016-12-12 15:59:26 -0800673run, the boot loader needs to copy it to the primary slot. The image currently
674in the primary slot also needs to be retained in flash so that it can be used
675later. Furthermore, both images need to be recoverable if the boot loader
676resets in the middle of the swap operation. The two images are swapped
677according to the following procedure:
678
Fabio Utzig60319ac2019-09-06 08:29:50 -03006791. Determine if both slots are compatible enough to have their images swapped.
680 To be compatible, both have to have only sectors that can fit into the
681 scratch area and if one of them has larger sectors than the other, it must
682 be able to entirely fit some rounded number of sectors from the other slot.
Fabio Utzigc28005b2019-09-10 12:18:29 -0300683 In the next steps we'll use the terminology "region" for the total amount of
684 data copied/erased because this can be any amount of sectors depending on
685 how many the scratch is able to fit for some swap operation.
6862. Iterate the list of region indices in descending order (i.e., starting
687 with the greatest index); only regions that are predetermined to be part of
Fabio Utzig60319ac2019-09-06 08:29:50 -0300688 the image are copied; current element = "index".
689 + a. Erase scratch area.
690 + b. Copy secondary_slot[index] to scratch area.
Fabio Utzigc28005b2019-09-10 12:18:29 -0300691 - If this is the last region in the slot, scratch area has a temporary
Fabio Utzig60319ac2019-09-06 08:29:50 -0300692 status area initialized to store the initial state, because the
Fabio Utzigc28005b2019-09-10 12:18:29 -0300693 primary slot's last region will have to be erased. In this case,
Fabio Utzig60319ac2019-09-06 08:29:50 -0300694 only the data that was calculated to amount to the image is copied.
Fabio Utzigc28005b2019-09-10 12:18:29 -0300695 - Else if this is the first swapped region but not the last region in
Fabio Utzig60319ac2019-09-06 08:29:50 -0300696 the slot, initialize the status area in primary slot and copy the
Fabio Utzigc28005b2019-09-10 12:18:29 -0300697 full region contents.
698 - Else, copy entire region contents.
Fabio Utzig60319ac2019-09-06 08:29:50 -0300699 + c. Write updated swap status (i).
700 + d. Erase secondary_slot[index]
701 + e. Copy primary_slot[index] to secondary_slot[index] according to amount
702 previosly copied at step b.
Fabio Utzigc28005b2019-09-10 12:18:29 -0300703 - If this is not the last region in the slot, erase the trailer in the
Fabio Utzig60319ac2019-09-06 08:29:50 -0300704 secondary slot, to always use the one in the primary slot.
705 + f. Write updated swap status (ii).
706 + g. Erase primary_slot[index].
707 + h. Copy scratch area to primary_slot[index] according to amount
708 previously copied at step b.
Fabio Utzigc28005b2019-09-10 12:18:29 -0300709 - If this is the last region in the slot, the status is read from
Fabio Utzig60319ac2019-09-06 08:29:50 -0300710 scratch (where it was stored temporarily) and written anew in the
711 primary slot.
712 + i. Write updated swap status (iii).
7133. Persist completion of swap procedure to the primary slot image trailer.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800714
David Vincze2d736ad2019-02-18 11:50:22 +0100715The additional caveats in step 2f are necessary so that the secondary slot image
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800716trailer can be written by the user at a later time. With the image trailer
David Vincze2d736ad2019-02-18 11:50:22 +0100717unwritten, the user can test the image in the secondary slot
Håkon Øye Amundsen11d91c32020-03-04 08:49:47 +0000718(i.e., transition to state I).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800719
Fabio Utzigc28005b2019-09-10 12:18:29 -0300720Note1: If the region being copied contains the last sector, then swap status is
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300721temporarily maintained on scratch for the duration of this operation, always
David Vincze2d736ad2019-02-18 11:50:22 +0100722using the primary slot's area otherwise.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300723
724Note2: The bootloader tries to copy only used sectors (based on largest image
725installed on any of the slots), minimizing the amount of sectors copied and
726reducing the amount of time required for a swap operation.
727
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800728The particulars of step 3 vary depending on whether an image is being tested,
David Vincze2d736ad2019-02-18 11:50:22 +0100729permanently used, reverted or a validation failure of the secondary slot
730happened when a swap was requested:
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300731
Christopher Collins92ea77f2016-12-12 15:59:26 -0800732 * test:
David Vincze2d736ad2019-02-18 11:50:22 +0100733 o Write primary_slot.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800734 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100735 primary_slot.magic = BOOT_MAGIC
Håkon Øye Amundsencdf94c22020-03-04 08:52:31 +0000736 secondary_slot.magic = UNSET
David Vincze2d736ad2019-02-18 11:50:22 +0100737 primary_slot.image_ok = Unset)
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800738
739 * permanent:
David Vincze2d736ad2019-02-18 11:50:22 +0100740 o Write primary_slot.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800741 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100742 primary_slot.magic = BOOT_MAGIC
Håkon Øye Amundsencdf94c22020-03-04 08:52:31 +0000743 secondary_slot.magic = UNSET
David Vincze2d736ad2019-02-18 11:50:22 +0100744 primary_slot.image_ok = 0x01)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800745
746 * revert:
David Vincze2d736ad2019-02-18 11:50:22 +0100747 o Write primary_slot.copy_done = 1
748 o Write primary_slot.image_ok = 1
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300749 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100750 primary_slot.magic = BOOT_MAGIC)
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300751
David Vincze2d736ad2019-02-18 11:50:22 +0100752 * failure to validate the secondary slot:
753 o Write primary_slot.image_ok = 1
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300754
David Vincze2d736ad2019-02-18 11:50:22 +0100755After completing the operations as described above the image in the primary slot
756should be booted.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800757
Fabio Utzigd37d8772019-12-03 10:32:18 -0300758## [Swap Status](#swap-status)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800759
760The swap status region allows the boot loader to recover in case it restarts in
761the middle of an image swap operation. The swap status region consists of a
762series of single-byte records. These records are written independently, and
763therefore must be padded according to the minimum write size imposed by the
764flash hardware. In the below figure, a min-write-size of 1 is assumed for
765simplicity. The structure of the swap status region is illustrated below. In
766this figure, a min-write-size of 1 is assumed for simplicity.
767
David Brown17e20d12017-09-12 11:53:20 -0600768```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800769 0 1 2 3
770 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
771 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
772 |sec127,state 0 |sec127,state 1 |sec127,state 2 |sec126,state 0 |
773 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
774 |sec126,state 1 |sec126,state 2 |sec125,state 0 |sec125,state 1 |
775 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
776 |sec125,state 2 | |
777 +-+-+-+-+-+-+-+-+ +
778 ~ ~
779 ~ [Records for indices 124 through 1 ~
780 ~ ~
781 ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
782 ~ |sec000,state 0 |sec000,state 1 |sec000,state 2 |
783 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Brown17e20d12017-09-12 11:53:20 -0600784```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800785
786The above is probably not helpful at all; here is a description in English.
787
788Each image slot is partitioned into a sequence of flash sectors. If we were to
789enumerate the sectors in a single slot, starting at 0, we would have a list of
790sector indices. Since there are two image slots, each sector index would
791correspond to a pair of sectors. For example, sector index 0 corresponds to
David Vincze2d736ad2019-02-18 11:50:22 +0100792the first sector in the primary slot and the first sector in the secondary slot.
793Finally, reverse the list of indices such that the list starts with index
794`BOOT_MAX_IMG_SECTORS - 1` and ends with 0. The swap status region is a
795representation of this reversed list.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800796
797During a swap operation, each sector index transitions through four separate
798states:
David Brown17e20d12017-09-12 11:53:20 -0600799```
David Vincze2d736ad2019-02-18 11:50:22 +01008000. primary slot: image 0, secondary slot: image 1, scratch: N/A
8011. primary slot: image 0, secondary slot: N/A, scratch: image 1 (1->s, erase 1)
8022. primary slot: N/A, secondary slot: image 0, scratch: image 1 (0->1, erase 0)
8033. primary slot: image 1, secondary slot: image 0, scratch: N/A (s->0)
David Brown17e20d12017-09-12 11:53:20 -0600804```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800805
806Each time a sector index transitions to a new state, the boot loader writes a
807record to the swap status region. Logically, the boot loader only needs one
808record per sector index to keep track of the current swap state. However, due
809to limitations imposed by flash hardware, a record cannot be overwritten when
810an index's state changes. To solve this problem, the boot loader uses three
811records per sector index rather than just one.
812
813Each sector-state pair is represented as a set of three records. The record
814values map to the above four states as follows
815
David Brown17e20d12017-09-12 11:53:20 -0600816```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800817 | rec0 | rec1 | rec2
818 --------+------+------+------
819 state 0 | 0xff | 0xff | 0xff
820 state 1 | 0x01 | 0xff | 0xff
821 state 2 | 0x01 | 0x02 | 0xff
822 state 3 | 0x01 | 0x02 | 0x03
David Brown17e20d12017-09-12 11:53:20 -0600823```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800824
Fabio Utzig2c05f1b2018-04-04 10:35:17 -0300825The swap status region can accommodate `BOOT_MAX_IMG_SECTORS` sector indices.
David Vincze2d736ad2019-02-18 11:50:22 +0100826Hence, the size of the region, in bytes, is
827`BOOT_MAX_IMG_SECTORS * min-write-size * 3`. The only requirement for the index
828count is that it is great enough to account for a maximum-sized image
829(i.e., at least as great as the total sector count in an image slot). If a
830device's image slots have been configured with `BOOT_MAX_IMG_SECTORS: 128` and
831use less than 128 sectors, the first record that gets written will be somewhere
832in the middle of the region. For example, if a slot uses 64 sectors, the first
833sector index that gets swapped is 63, which corresponds to the exact halfway
834point within the region.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800835
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300836Note: since the scratch area only ever needs to record swapping of the last
837sector, it uses at most min-write-size * 3 bytes for its own status area.
838
Fabio Utzigd37d8772019-12-03 10:32:18 -0300839## [Reset Recovery](#reset-recovery)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800840
841If the boot loader resets in the middle of a swap operation, the two images may
842be discontiguous in flash. Bootutil recovers from this condition by using the
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300843image trailers to determine how the image parts are distributed in flash.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800844
845The first step is determine where the relevant swap status region is located.
846Because this region is embedded within the image slots, its location in flash
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300847changes during a swap operation. The below set of tables map image trailers
Christopher Collins92ea77f2016-12-12 15:59:26 -0800848contents to swap status location. In these tables, the "source" field
David Vinczeba3bd602019-06-17 16:01:43 +0200849indicates where the swap status region is located. In case of multi image boot
850the images primary area and the single scratch area is always examined in pairs.
851If swap status found on scratch area then it might not belong to the current
852image. The swap_info field of swap status stores the corresponding image number.
853If it does not match then "source: none" is returned.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800854
David Brown17e20d12017-09-12 11:53:20 -0600855```
David Vincze2d736ad2019-02-18 11:50:22 +0100856 | primary slot | scratch |
857 ----------+--------------+--------------|
858 magic | Good | Any |
859 copy-done | 0x01 | N/A |
860 ----------+--------------+--------------'
861 source: none |
862 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400863
David Vincze2d736ad2019-02-18 11:50:22 +0100864 | primary slot | scratch |
865 ----------+--------------+--------------|
866 magic | Good | Any |
867 copy-done | 0xff | N/A |
868 ----------+--------------+--------------'
869 source: primary slot |
870 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400871
David Vincze2d736ad2019-02-18 11:50:22 +0100872 | primary slot | scratch |
873 ----------+--------------+--------------|
874 magic | Any | Good |
875 copy-done | Any | N/A |
876 ----------+--------------+--------------'
877 source: scratch |
878 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400879
David Vincze2d736ad2019-02-18 11:50:22 +0100880 | primary slot | scratch |
881 ----------+--------------+--------------|
882 magic | Unset | Any |
883 copy-done | 0xff | N/A |
884 ----------+--------------+--------------|
885 source: primary slot |
886 ----------------------------------------+------------------------------+
887 This represents one of two cases: |
888 o No swaps ever (no status to read, so no harm in checking). |
889 o Mid-revert; status in the primary slot. |
890 For this reason we assume the primary slot as source, to trigger a |
891 check of the status area and find out if there was swapping under way. |
892 -----------------------------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600893```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800894
Christopher Collinsa1c12042019-05-23 14:00:28 -0700895If the swap status region indicates that the images are not contiguous, mcuboot
896determines the type of swap operation that was interrupted by reading the `swap
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +0000897info` field in the active image trailer and extracting the swap type from bits
David Vinczee2453472019-06-17 12:31:59 +02008980-3 then resumes the operation. In other words, it applies the procedure defined
899in the previous section, moving image 1 into the primary slot and image 0 into
900the secondary slot. If the boot status indicates that an image part is present
901in the scratch area, this part is copied into the correct location by starting
902at step e or step h in the area-swap procedure, depending on whether the part
903belongs to image 0 or image 1.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800904
905After the swap operation has been completed, the boot loader proceeds as though
906it had just been started.
907
Fabio Utzigd37d8772019-12-03 10:32:18 -0300908## [Integrity Check](#integrity-check)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800909
910An image is checked for integrity immediately before it gets copied into the
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300911primary slot. If the boot loader doesn't perform an image swap, then it can
David Vincze2d736ad2019-02-18 11:50:22 +0100912perform an optional integrity check of the image in the primary slot if
913`MCUBOOT_VALIDATE_PRIMARY_SLOT` is set, otherwise it doesn't perform an
914integrity check.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800915
916During the integrity check, the boot loader verifies the following aspects of
917an image:
Fabio Utzig75b34412019-09-06 08:30:43 -0300918
Fabio Utzigfd140ec2019-09-12 14:37:48 -0300919 * 32-bit magic number must be correct (`IMAGE_MAGIC`).
Fabio Utzig75b34412019-09-06 08:30:43 -0300920 * Image must contain an `image_tlv_info` struct, identified by its magic
Fabio Utzigfd140ec2019-09-12 14:37:48 -0300921 (`IMAGE_TLV_PROT_INFO_MAGIC` or `IMAGE_TLV_INFO_MAGIC`) exactly following
922 the firmware (`hdr_size` + `img_size`). If `IMAGE_TLV_PROT_INFO_MAGIC` is
923 found then after `ih_protect_tlv_size` bytes, another `image_tlv_info`
924 with magic equal to `IMAGE_TLV_INFO_MAGIC` must be present.
Fabio Utzig75b34412019-09-06 08:30:43 -0300925 * Image must contain a SHA256 TLV.
926 * Calculated SHA256 must match SHA256 TLV contents.
927 * Image *may* contain a signature TLV. If it does, it must also have a
928 KEYHASH TLV with the hash of the key that was used to sign. The list of
929 keys will then be iterated over looking for the matching key, which then
930 will then be used to verify the image contents.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800931
Fabio Utzigd37d8772019-12-03 10:32:18 -0300932## [Security](#security)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800933
934As indicated above, the final step of the integrity check is signature
935verification. The boot loader can have one or more public keys embedded in it
936at build time. During signature verification, the boot loader verifies that an
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +0000937image was signed with a private key that corresponds to the embedded KEYHASH
Fabio Utzigea422c22017-09-11 11:02:47 -0300938TLV.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800939
940For information on embedding public keys in the boot loader, as well as
Fabio Utzig4dce6aa2018-02-12 15:31:32 -0200941producing signed images, see: [signed_images](signed_images.md).
Fabio Utzigcdfa11a2018-10-01 09:45:54 -0300942
943If you want to enable and use encrypted images, see:
944[encrypted_images](encrypted_images.md).
David Vinczee32483f2019-06-13 10:46:24 +0200945
Tamas Banfe031092020-09-10 17:32:39 +0200946Note: Image encryption is not supported when the direct-xip or the ram-load
947upgrade strategy is selected.
David Vinczee574f2d2020-07-10 11:42:03 +0200948
David Vincze25459bf2020-04-21 17:11:20 +0200949### [Using Hardware Keys for Verification](#hw-key-support)
950
951By default, the whole public key is embedded in the bootloader code and its
952hash is added to the image manifest as a KEYHASH TLV entry. As an alternative
953the bootloader can be made independent of the keys by setting the
954`MCUBOOT_HW_KEY` option. In this case the hash of the public key must be
955provisioned to the target device and mcuboot must be able to retrieve the
956key-hash from there. For this reason the target must provide a definition
957for the `boot_retrieve_public_key_hash()` function which is declared in
958`boot/bootutil/include/bootutil/sign_key.h`. It is also required to use
959the `full` option for the `--public-key-format` imgtool argument in order to
960add the whole public key (PUBKEY TLV) to the image manifest instead of its
961hash (KEYHASH TLV). During boot the public key is validated before using it for
962signature verification, mcuboot calculates the hash of the public key from the
963TLV area and compares it with the key-hash that was retrieved from the device.
964This way mcuboot is independent from the public key(s). The key(s) can be
965provisioned any time and by different parties.
966
Fabio Utzigd37d8772019-12-03 10:32:18 -0300967## [Protected TLVs](#protected-tlvs)
Fabio Utzigfd140ec2019-09-12 14:37:48 -0300968
969If the TLV area contains protected TLV entries, by beginning with a `struct
970image_tlv_info` with a magic value of `IMAGE_TLV_PROT_INFO_MAGIC` then the
971data of those TLVs must also be integrity and authenticity protected. Beyond
972the full size of the protected TLVs being stored in the `image_tlv_info`,
973the size of the protected TLVs together with the size of the `image_tlv_info`
974struct itself are also saved in the `ih_protected_size` field inside the
975header.
976
977Whenever an image has protected TLVs the SHA256 has to be calculated over
978not just the image header and the image but also the TLV info header and the
979protected TLVs.
980
981```
982A +---------------------+
983 | Header | <- struct image_header
984 +---------------------+
985 | Payload |
986 +---------------------+
987 | TLV area |
988 | +-----------------+ | struct image_tlv_info with
989 | | TLV area header | | <- IMAGE_TLV_PROT_INFO_MAGIC (optional)
990 | +-----------------+ |
991 | | Protected TLVs | | <- Protected TLVs (struct image_tlv)
992B | +-----------------+ |
993 | | TLV area header | | <- struct image_tlv_info with IMAGE_TLV_INFO_MAGIC
994C | +-----------------+ |
995 | | SHA256 hash | | <- hash from A - B (struct image_tlv)
996D | +-----------------+ |
997 | | Keyhash | | <- indicates which pub. key for sig (struct image_tlv)
998 | +-----------------+ |
999 | | Signature | | <- signature from C - D (struct image_tlv), only hash
1000 | +-----------------+ |
1001 +---------------------+
1002```
1003
Fabio Utzigd37d8772019-12-03 10:32:18 -03001004## [Dependency Check](#dependency-check)
David Vinczee32483f2019-06-13 10:46:24 +02001005
1006MCUBoot can handle multiple firmware images. It is possible to update them
1007independently but in many cases it can be desired to be able to describe
1008dependencies between the images (e.g. to ensure API compliance and avoid
1009interoperability issues).
1010
1011The dependencies between images can be described with additional TLV entries in
Fabio Utzigfd140ec2019-09-12 14:37:48 -03001012the protected TLV area after the end of an image. There can be more than one
1013dependency entry, but in practice if the platform only supports two individual
1014images then there can be maximum one entry which reflects to the other image.
David Vinczee32483f2019-06-13 10:46:24 +02001015
David Vinczee32483f2019-06-13 10:46:24 +02001016At the phase of dependency check all aborted swaps are finalized if there were
1017any. During the dependency check the boot loader verifies whether the image
1018dependencies are all satisfied. If at least one of the dependencies of an image
1019is not fulfilled then the swap type of that image has to be modified
1020accordingly and the dependency check needs to be restarted. This way the number
1021of unsatisfied dependencies will decrease or remain the same. There is always at
1022least 1 valid configuration. In worst case, the system returns to the initial
1023state after dependency check.
1024
1025For more information on adding dependency entries to an image,
1026see: [imgtool](imgtool.md).
Håkon Øye Amundsen2d1bac12020-01-03 13:08:09 +00001027
1028## [Downgrade Prevention](#downgrade-prevention)
1029
1030Downgrade prevention is a feature which enforces that the new image must have a
David Vinczec3084132020-02-18 14:50:47 +01001031higher version/security counter number than the image it is replacing, thus
1032preventing the malicious downgrading of the device to an older and possibly
1033vulnerable version of its firmware.
1034
1035### [SW Based Downgrade Prevention](#sw-downgrade-prevention)
1036
1037During the software based downgrade prevention the image version numbers are
1038compared. This feature is enabled with the `MCUBOOT_DOWNGRADE_PREVENTION`
1039option. In this case downgrade prevention is only available when the
1040overwrite-based image update strategy is used (i.e. `MCUBOOT_OVERWRITE_ONLY`
1041is set).
1042
1043### [HW Based Downgrade Prevention](#hw-downgrade-prevention)
1044
David Vincze25459bf2020-04-21 17:11:20 +02001045Each signed image can contain a security counter in its protected TLV area, which
1046can be added to the image using the `-s` option of the [imgtool](imgtool.md) script.
David Vinczec3084132020-02-18 14:50:47 +01001047During the hardware based downgrade prevention (alias rollback protection) the
1048new image's security counter will be compared with the currently active security
1049counter value which must be stored in a non-volatile and trusted component of
David Vincze25459bf2020-04-21 17:11:20 +02001050the device. It is beneficial to handle this counter independently from image
1051version number:
David Vinczec3084132020-02-18 14:50:47 +01001052
1053 * It does not need to increase with each software release,
1054 * It makes it possible to do software downgrade to some extent: if the
1055 security counter has the same value in the older image then it is accepted.
David Vincze25459bf2020-04-21 17:11:20 +02001056
1057It is an optional step of the image validation process and can be enabled with
1058the `MCUBOOT_HW_ROLLBACK_PROT` config option. When enabled, the target must
1059provide an implementation of the security counter interface defined in
1060`boot/bootutil/include/security_cnt.h`.
1061
1062## [Measured boot and data sharing](#boot-data-sharing)
1063
1064MCUBoot defines a mechanism for sharing boot status information (also known as
1065measured boot) and an interface for sharing application specific information
1066with the runtime software. If any of these are enabled the target must provide
1067a shared data area between the bootloader and runtime firmware and define the
1068following parameters:
1069
1070```c
1071#define MCUBOOT_SHARED_DATA_BASE <area_base_addr>
1072#define MCUBOOT_SHARED_DATA_SIZE <area_size_in_bytes>
1073```
1074
1075In the shared memory area all data entries are stored in a type-length-value
1076(TLV) format. Before adding the first data entry, the whole area is overwritten
1077with zeros and a TLV header is added at the beginning of the area during an
1078initialization phase. This TLV header contains a `tlv_magic` field with a value
1079of `SHARED_DATA_TLV_INFO_MAGIC` and a `tlv_tot_len` field which is indicating
1080the total length of shared TLV area including this header. The header is
1081followed by the the data TLV entries which are composed from a
1082`shared_data_tlv_entry` header and the data itself. In the data header there is
1083a `tlv_type` field which identifies the consumer of the entry (in the runtime
1084software) and specifies the subtype of that data item. More information about
1085the `tlv_type` field and data types can be found in the
1086`boot/bootutil/include/bootutil/boot_status.h` file. The type is followed by a
1087`tlv_len` field which indicates the size of the data entry in bytes, not
1088including the entry header. After this header structure comes the actual data.
1089
1090```c
1091/** Shared data TLV header. All fields in little endian. */
1092struct shared_data_tlv_header {
1093 uint16_t tlv_magic;
1094 uint16_t tlv_tot_len; /* size of whole TLV area (including this header) */
1095};
1096
1097/** Shared data TLV entry header format. All fields in little endian. */
1098struct shared_data_tlv_entry {
1099 uint16_t tlv_type;
1100 uint16_t tlv_len; /* TLV data length (not including this header). */
1101};
1102```
1103
1104The measured boot can be enabled with the `MCUBOOT_MEASURED_BOOT` config option.
1105When enabled, the `--boot_record` argument of the imgtool script must also be
1106used during the image signing process to add a BOOT_RECORD TLV to the image
1107manifest. This TLV contains the following attributes/measurements of the
1108image in CBOR encoded format:
1109
1110 * Software type (role of the software component)
1111 * Software version
1112 * Signer ID (identifies the signing authority)
1113 * Measurement value (hash of the image)
1114 * Measurement type (algorithm used to calculate the measurement value)
1115
1116The `sw_type` string that is passed as the `--boot_record` option's parameter
1117will be the value of the "Software type" attribute in the generated BOOT_RECORD
1118TLV. The target must also define the `MAX_BOOT_RECORD_SZ` macro which indicates
1119the maximum size of the CBOR encoded boot record in bytes.
1120During boot, MCUBoot will look for these TLVs (in case of multiple images) in
1121the manifests of the active images (the latest and validated) and copy the CBOR
1122encoded binary data to the shared data area. Preserving all these image
1123attributes from the boot stage for use by later runtime services (such as an
1124attestation service) is known as a measured boot.
1125
1126Setting the `MCUBOOT_DATA_SHARING` option enables the sharing of application
1127specific data using the same shared data area as for the measured boot. For
1128this, the target must provide a definition for the `boot_save_shared_data()`
1129function which is declared in `boot/bootutil/include/bootutil/boot_record.h`.
1130The `boot_add_data_to_shared_area()` function can be used for adding new TLV
1131entries to the shared data area.