Commit Graph

206 Commits

Author SHA1 Message Date
David Vincze e32483f10f Boot: Add dependency check to multi-image boot
This patch adds the capability to check image dependencies in case
of multi-image boot. The dependencies are described with a new type
of TLV in the manifest.

Change-Id: If45f81a00d4324c881634f50156f9939e1bf8707
Signed-off-by: David Vincze <david.vincze@arm.com>
2019-07-23 09:11:34 -05:00
David Vincze ba3bd606be Boot: Enable multi-image boot
This patch adds the capability to handle multiple firmware images,
to update them independently. Also update the design documentation.
It separates the completion of aborted image swap operations and the
update of images even more as these should be happening at different
stages of the boot process according to the design proposal of
the multiple image support:
https://github.com/JuulLabs-OSS/mcuboot/pull/317.

Change-Id: I7eb5f632298bb08c805bfaee0359703b2ae19e9d
Signed-off-by: David Vincze <david.vincze@arm.com>
2019-07-23 09:11:34 -05:00
David Vincze b75c12a431 Boot: Extend flash layout for multiple images
This patch introduces the BOOT_IMAGE_NUMBER macro and current_image
variable to support multiple updatable images and the associated
extended flash layout.

The FLASH_AREA_IMAGE_* object-like macros are replaced with
function-like ones and therefore some functions have been updated,
because the labels of a switch statement and the initialization
values of objects with static storage duration have to be constant
expressions.

Change-Id: Ib7b26ec3c94233e52db4f97825ddb6a3e55bb1d3
Signed-off-by: David Vincze <david.vincze@arm.com>
2019-07-23 09:11:34 -05:00
David Vincze e24534799b Boot: Save image sequence number to image trailer
Overload the swap_type field in image trailer to store as an addition
the image sequence number. It indicates which image's swap was
interrupted. It is required by multi image boot to determine which
image the trailer belongs to if boot status is found on scratch area
when the swap operation is resumed.

Change-Id: I6820fd8277931aff4f0db408376eae8b42a030ed
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
Signed-off-by: David Vincze <david.vincze@arm.com>
2019-07-23 09:11:34 -05:00
Fabio Utzig 853657c23d Add watchdog feeding macro
When HW / OS provides an always enabled watchdog, this macro can
optionally be implemented to avoid resets which are expected to
occur under normal conditions when swapping very large images or
running on slower devices.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-07-12 08:06:13 -03:00
Alvaro Prieto 63a2bdbda9 Fix bug that prevents split images from working.
There is a bug in split_go that never opens the loader image flash
area, but opens the app/split image flash arta twice. This prevents
split_image_check from passing and the app from ever loading.

Signed-off-by: Alvaro Prieto <source@alvaroprieto.com>
2019-07-05 07:23:17 -03:00
Fabio Utzig 9871cebf2a Update mbedTLS sha256 usage to avoid deprecation
mbedTLS made sha256 functions that do not return errors deprecated. This
updates to use the new functions avoiding the extra functions calls, and
breakage when the deprecated calls are effectively removed.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-06-28 08:47:43 -03:00
Fabio Utzig 9771028579 Add ed25519 verification to sim
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-06-13 19:21:05 -03:00
Fabio Utzig 4876484bce Add bootutil support for ed25519 validation
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-06-13 19:21:05 -03:00
Fabio Utzig a1e8e4334d Add Mynewt ed25519 support
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-06-13 19:21:05 -03:00
Christopher Collins a1c1204f65 Fix double swap on interrupted revert
This fixes #480.

When mcuboot rewrites image trailers during a swap, some information is
lost.  If a reset occurs before the swap completes, mcuboot may not be
able to determine what which swap type to resume upon startup.
Specifically, if a "revert" swap gets interupted, mcuboot will perform
an extraneous swap on the subsequent boot.  See
https://github.com/JuulLabs-OSS/mcuboot/issues/480 for details.

This commit adds an additional field to the image trailer: `swap-type`.
The new trailer structure is illustrated below:

```
     0                   1                   2                   3
     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
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                                                               ~
    ~    Swap status (BOOT_MAX_IMG_SECTORS * min-write-size * 3)    ~
    ~                                                               ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                 Encryption key 0 (16 octets) [*]              ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                 Encryption key 1 (16 octets) [*]              ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           Swap size           |    0xff padding (4 octets)    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Swap type   |           0xff padding (7 octets)             ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Copy done   |           0xff padding (7 octets)             ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Image OK    |           0xff padding (7 octets)             ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                       MAGIC (16 octets)                       ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

The `swap-type` field contains one of the `BOOT_SWAP_TYPE_[...]` constants.
Every time a trailer is written, this field is written along with it.
When resuming an interrupted swap, mcuboot uses this field alone to
determine the type of swap being resumed. For new swap operations
(non-resume case), this field is not read at all; instead, mcuboot
consults the `boot_swap_tables` array to determine the swap operation to
perform (as it did prior to this commit).

Some additional changes were necessary to make all the simulated unit
tests pass:

* Before initiating a new swap operation, always write the image trailer
to the scratch area.  This step allows mcuboot to persist the
`swap-type` field somewhere before erasing the trailer in the primary
slot.  If a reset occurs immediately after the erase, mcuboot recovers
by using the trailer in the scratch area.

* Related to the above: if the scratch area is being used to hold status
bytes (because there are no spare sectors in the primary slot), erase
the scratch area immediately after the trailer gets written to the
primary slot.  This eliminates ambiguity regarding the location of the
current trailer in case a reset occurs shortly afterwards.

Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-05-31 10:15:08 -07:00
Christopher Collins 2c88e69be7 Add some more debug logging
Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-05-31 10:15:08 -07:00
Christopher Collins 2adef70e33 Use same format for scratch and slot trailer
Prior to this change, the scratch image trailer had a different format
from a slot image trailer.  Specifically:

1. The scratch trailer only contained a single set of status entries
   (three bytes); the slot trailer contained `BOOT_STATUS_MAX_ENTRIES`
   sets of status entries.

2. The scratch trailer did not contain the `copy_done` field.

This inconsistency required some extra conditional logic in the trailer
handling code.  It is simpler to just use the same trailer format
everywhere.

This commit removes this inconsistency.  Now, the scratch trailer
structure is identical to that of the slot trailer.

Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-05-31 10:15:08 -07:00
Fabio Utzig 3929743408 Add simulator support for RSA-3072 sigs
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-05-16 14:01:19 -03:00
Fabio Utzig 3501c01641 Add bootutil support for RSA-3072
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-05-16 14:01:19 -03:00
David Brown 4c9883b0d8 Add a capability query for image number
In addition to the binary capability flags, add a query function that
returns the number of images MCUboot has been configured to support.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-04-17 11:20:21 +07:00
David Brown 74b161ea22 bootutil: Fix indentation in caps query
Fix indentation to match the rest of the source tree: 4 spaces, no tabs.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-04-17 11:20:21 +07:00
David Brown 8d66c92047 boot: bootutil: Change conditional to valid C
The change

    boot: bootutil: Simplify check for crypto backends to reduce complexity

    Adding multiple crypto backends will grow quadraticly. This change will
    ensure that the growth will be linear and generate less complexity.

unfortunately is not legal C.  It can be fixed by eliminating the
intermediate macro, so that the `defined` keywords are within the `#if`.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-04-17 05:28:18 +07:00
Szymon Janc 30f68b854e Remove bootutil unit test for Mynewt
mcuboot tests are done under sim and there is no need to maintain
separate tests just for Mynewt. Especially that those no longer
compile nor are maintained.

Also Mynewt code will rather depend on release and not master so
there is no need to run those on Mynewt anyway.

Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
2019-04-16 15:59:31 -03:00
Sigvart Hovland 0a14d6b558 boot: bootutil: Simplify check for crypto backends to reduce complexity
Adding multiple crypto backends will grow quadraticly. This change will
ensure that the growth will be linear and generate less complexity.

Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
2019-04-04 11:30:59 -03:00
Sigvart Hovland 65a6ab2735 boot: bootutil: Add cc310 interface for ecdsa
Adds cc310 functions for sha256 and ecdsa verify for secp256r1.

Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
2019-03-25 07:12:34 -03:00
Sigvart Hovland 795cd0d593 boot: bootutil: Change ec256 so that it can support multiple interfaces
Change ec256 interface so that it could support multiple interfaces in
the future.

Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
2019-03-25 07:12:34 -03:00
Christopher Collins 3999a759d2 Mynewt: Partial fix for bootutil unit test
The bootutil unit tests fail to build with the following error:

    Testing package @mcuboot/boot/bootutil/test
    Unsatisfied APIs detected:
        * log, required by: sys/log/modlog

This commit adds a `sys/log/stub` dependency to the bootutil unit test
package.

NOTE: This unit test package still fails to build because the code is
out of date.  This commit just fixes one of several issues.

Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-03-21 09:05:22 -07:00
Christopher Collins 01dfbb62e5 Mynewt: Make PRIMARY/SECONDARY macros public
This change only affects the Mynewt port.

Prior to this commit, the `FLASH_AREA_IMAGE_{PRIMARY,SECONDARY}` macros
were private to the bootutil package (defined in `bootutil_priv.h`).
Some other packages require these symbols (e.g., the boot_serial unit
tests), so they should be made public.

This commit moves these definitions into the public `bootutil.h` header.

Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-03-21 09:05:22 -07:00
Andrzej Puzdrowski cf97dd08bd encryption: changed boot_enc_valid() return value to bool
boot_enc_valid() is supposed to return boolena so
changed it return type in order to reflect this.

Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
2019-03-14 16:10:54 +01:00
Andrzej Puzdrowski e575fe9ead image encryption: fix enc_state array indexing for zephyr
enc_state table was indexed with assumption that
image flash area are subsequent and increasing numbers.
It might not be true while building zephyr.

Patch introduce flash_area_id_to_image_slot() implementation for
the zephyr port and uses it to assign proper slot number.
This API is already available in MyNewt.

Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
2019-03-14 16:10:54 +01:00
Fabio Utzig ad0e9b8077 Add Mynewt configuration to enable HW crypto
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-03-14 07:29:01 -03:00
David Vincze 2d736ad4c5 Replace flash partitioning terminology
This change replaces the slot 0/1 terminology with primary/secondary
slot and replaces FLASH_AREA_IMAGE_0/1 with
FLASH_AREA_IMAGE_PRIMARY/SECONDARY. This naming convention may be more
understandable, fits better to MCUs with multiple images and it is an
architecture agnostic alternative as well.

Change-Id: I655a585f6ae023852c671ee6635399efe25209c9
Signed-off-by: David Vincze <david.vincze@arm.com>
Signed-off-by: David Brown <david.brown@linaro.org>
2019-03-13 15:40:21 -06:00
Johannes Bruder 4b4ac906e3 Do not use an ASSERT to catch the case if no image is loaded
Signed-off-by: Johannes Bruder <johannes.bruder@plating.de>
2019-02-19 11:54:45 -07:00
Christopher Collins ae01f153b1 Set pending: don't crash when image slot corrupt
This change affects the "set pending" operation.  That is, the operation
that configures mcuboot to temporarily swap images on the next boot.

PRIOR TO COMMIT:

If the slot 1 trailer contained an invalid 128-bit magic number, an
assertion would fail, causing a crash.

AFTER COMMIT:

If corruption is detected in the slot 1 trailer, the entire image slot
is erased, and the "set pending" operation fails with a `BOOT_EBADIMAGE`
status.

RATIONALE:

mcuboot cannot meaningfully recover from data corruption.  The only
recourse is to erase the bad data so that future upgrades can be
performed.  I was tempted to add a build-time setting to control whether
the image slot gets erased when corruption is detected, but I dont think this
freedom justifies the cost of extra config.  A device with a corrupt
image slot can no longer be upgraded, so the only reason someone would
want to preserve the corrupt data would be for debugging.

Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-01-31 18:13:52 -02:00
Fabio Utzig ed0ca4356a Fix trailer erase for some devices
Previously it was assumed that the trailer would fit one sector. While
this works for most devices, some which happen to have lots of sectors
end up using lots of space for their swap status area. The same issue
could also happen if sectors are small (less than 2K/4K, for example).

This fixes the issue by checking the trailer size and erasing all
sectors that encompass it.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-01-23 14:04:47 -07:00
Fabio Utzig 006994b754 Fix a buffer overflow on EC point load
While loading a new EC point, when it was smaller than the expected
number of bytes, a zero padding was being written beyond the end of the
buffer instead of at the initial position.

While this has been working before, it broke when images were signed using
the ring API.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-01-18 09:44:48 -07:00
David Brown 8d0afa737c boot: bootutil add cap for slot 0 validation
Add a capability to query if MCUboot has been built to verify slot 0.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-01-12 14:35:54 -07:00
David Brown c4a60a3686 boot: bootutil: Add caps for encryption
Add a capability query for the two encryption options.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-01-12 14:35:54 -07:00
Emanuele Di Santo 9f1933d1a5 boot: zephyr: migrate to new log subystem
The old log subsystem has been deprecated in Zephyr.
Migrate to the new subsystem to avoid compilation warnings.

In-place log processing is selected as it is required as MCUBoot is
one thread application.

Signed-off-by: Emanuele Di Santo <emdi@nordicsemi.no>
Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
2019-01-10 19:11:15 +01:00
Emanuele Di Santo 2733f515cd boot: bootutil: remove unused BOOT_LOG_LEVEL macros
Remove unnused BOOT_LOG_LEVEL macros.
These are not honored, nor usable since they are supposed to be
defined before including the header in which they are defined.

Signed-off-by: Emanuele Di Santo <emdi@nordicsemi.no>
2019-01-10 19:11:15 +01:00
Emanuele Di Santo 0752d8aee4 boot: bootutil: include mcuboot_logging.h unconditionally
The mcuboot_logging.h header includes the header for the log subystem,
which needs to be included regardless of whether logging is enabled
for logging macros to compile correctly.

Signed-off-by: Emanuele Di Santo <emdi@nordicsemi.no>
2019-01-10 19:11:15 +01:00
Fabio Utzig a32f1af386 Fix overwrite-only under Zephyr
As reported by issue #384, some #ifdefery was wrongly done, which broke
overwrite-only mode under Zephyr.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-01-07 10:59:20 -02:00
Christopher Collins 4b2591285a boot/bootutil: Add missing #include
Mynewt builds require the `mcuboot_config.h` file to translate syscfg
setting names to MCUboot setting names.  This change fixes a build error
that occurs when MCUboot is built with mbedTLS support:

Error: In file included from keys/bootkeys/src/bootkeys.c:2:0:
repos/mcuboot/boot/bootutil/include/bootutil/enc_key.h:29:10: fatal error: tinycrypt/aes.h: No such file or directory
 #include "tinycrypt/aes.h"
          ^~~~~~~~~~~~~~~~~

Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-01-04 14:57:41 -08:00
Fabio Utzig 38f5ffea35 Add key unwrap functionality using tinycrypt
This implements AES key unwrapping following RFC-3394 section 2.2.2
using tinycrypt for AES-128 decryption. It is enabled when ECDSA was
chosen as the signature algorithm.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-01-03 11:22:05 -02:00
Fabio Utzig 338a19f70d Add boostrapping from slot1 support
This adds a new option that allows copying slot0, from the contents
of slot1, if slot0 is found out to be erased and not validated, and
the contents of slot1 are validated.

This mechanism basically enables a device to "bootstrap" from the
contents of an external flash that has a valid image, given that the
only flashed thing in the internal flash is the bootloader.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2018-12-27 10:58:50 -02:00
Rajavardhan Gundi 1b8d7fb355 Use BUILD_ASSERT_MSG instead of _Static_assert in Zephyr
Signed-off-by: Rajavardhan Gundi <rajavardhan.gundi@intel.com>
2018-12-27 08:13:41 -02:00
Timo Kröger e280e1166e Remove unused hal includes from bootutil
Signed-off-by: Timo Kröger <timokroeger93@gmail.com>
2018-12-21 06:47:40 -02:00
Fabio Utzig 2bd980a50d Add support for slots with different sector sizes
This adds bootutil support for slots on different flash devices
the happen to have different sector sizes.

It consists basically in relaxing the `boot_slots_compatible` to
allow swaps as long as the sectors that are required to fit both
images are able to fit inside scratch and both slot's sectors have
sizes that are multiple of each other.

This is now tested on the simulator and was tested in a Nordic's
pca10056 using slot0 in internal flash, and slot1 in the external
QSPI flash, configured with 4K, 8K and 16K sized sectors (the HW
is 4KB but Mynewt allows emulating multiples of that!)

Signed-off-by: Fabio Utzig <utzig@apache.org>
2018-12-18 15:16:11 -02:00
Fabio Utzig 2fc80df49f Fix handling of encrypted images
Encrypted images were known to be failing when the header size was larger
than 256 bytes because of incorrect handling of blocks sent to decryption
and hashing routines. An assert was previously added to check the header
and read block sizes matched to avoid incurring into the know error, but
it was incorrectly enabled also for non-encrypted images.

Now the handling of the header, which is not encrypted, is correctly
separated from the handling of the remaining image, when encryption is
used, to avoid ever sending header data into the decryption routines.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2018-12-17 14:41:02 -02:00
Fabio Utzig e641ea5ee5 Fix overwrite only encrypted to not use local var
Use existing global var instead of using locally declared variable,
reducing RAM usage.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2018-12-04 14:21:52 -02:00
Fabio Utzig 1c7d959eeb Fix rebase issue
Signed-off-by: Fabio Utzig <utzig@apache.org>
2018-12-04 14:21:52 -02:00
Yiping Peng 3393992943 Fixed an issue that supported later versions of mbedtls than mbedtls-2.6.1
Signed-off-by: Yiping Peng <836885645@qq.com>
Signed-off-by: Yiping Peng <yibingp@internal.synopsys.com>
2018-11-09 08:12:29 -03:00
Fabio Utzig ba829049ea Add bootutil support for encrypted images
This allows storing encrypted images in slot1, that are automatically
decrypted when copying to slot0 and re-encrypted when copying from slot0
to slot1.

The encryption works by applying AES-CTR-128 on the image blocks
(excluding the header and TLVs) using a random key. This random key
is itself encrypted using either RSA-OAEP-2048 or AES-KW-128 (AES keywrap
as defined by RFC3394), and appended to the image as newly defined TLVs.

AES-CTR-128 was chosen primarily for having stream cipher proporties,
which basically means that any block being encrypted/decrypted does not
depend on any other previous blocks results.

The TLV adds about 256 bytes to the image in RSA-OAEP-2048 mode, and 24
bytes in AES-KW-128 mode. Resulting sizes for a Mynewt generated mcuboot
(frdm-k64f):

- swap mode and no signing: 12KB
- adding encryption with RSA-OAEP-2048: 28KB
- adding encryption with AES-KW-128: 20KB

Some extra comments:

- AES-KW-128 requires a fairly new mbedtls with nist_kw support.
- An alternative methods which could be added later are ECIES.
- Key-wrapping seems easy enough to implement using just standard
  AES-ECB mode that it should be straight-forward to also add support to
  tinycrypt.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2018-10-12 13:36:13 -03:00
Fabio Utzig 178be54bd6 Test erased flash with "flash_area_read_is_empty()"
Mynewt has recently added an encrypted flash layer driver, that runs
transparently on any flash, handling reads and writes, and bypassing
other flash operations to the HW driver. As a result of this change,
checking for erased data cannot be done by read + compare to erased_val
but need to be routed to an empty check on the lower level. To do this
Mynewt added a new flash_map function called "flash_area_read_is_empty"
which checks for erased blocks (and reads/decrypts the data as well).

This commit uses `flash_area_read_is_empty` to determine if magic,
flags and swap status are erased. For Zephyr/sim commits were added
previously that mimic this functionality by simply doing the
read/compare.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2018-10-01 21:42:20 -03:00