Commit Graph

273 Commits

Author SHA1 Message Date
Fabio Utzig 34e93a507b boot: zephyr: mynewt: sha-512 from tinycrypt
* Mynewt always uses sha-512 from tinycrypt
* Zephyr can choose either tinycrypt or mbedTLS

Signed-off-by: Fabio Utzig <utzig@apache.org>
2020-02-04 06:09:01 -03:00
David Brown 07e1381d0f Add a capability for querying downgrade prevention
Signed-off-by: Håkon Øye Amundsen <haakon.amundsen@nordicsemi.no>
Signed-off-by: David Brown <david.brown@linaro.org>
2020-01-23 12:47:05 -07:00
Håkon Øye Amundsen 2d1bac164f add option for rollback protection
Depends on 'MCUBOOT_OVERWRITE_ONLY' option since swap info is not protected
by signature

Signed-off-by: Håkon Øye Amundsen <haakon.amundsen@nordicsemi.no>
2020-01-23 12:47:05 -07:00
Fabio Utzig 9e1db9a88f boot: Add free space check for swap without scratch
Add a missing test which ensures that there is enough free sectors to
perform an upgrade when using the move strategy; this basically checks
that the sectors used by the trailer don't overlap the last sector
required for a move up operation.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2020-01-07 17:08:22 -03:00
Fabio Utzig 4741c45293 bootutil: allow encryption key TLVs in swap status
Add a new option that when enabled, allows a swap status to store
an encrypted key TLV instead of plain keys. When a new swap operation is
started the encryption keys are saved to the swap status area to allow
for resuming (because it is challenging to find those TLV in the middle
of a swap operation).

Previously those keys were saved in plain text, so it would be easy to
dump them if the images were stored in external flash. With this new
option one can choose to save the TLV instead, which uses more flash
but does not leak secrets. The amount of flash required varies depending
on the size of the TLV, which is 48 for AES-128-KW, 512 for RSA and 240
for ECIES-P256.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-20 14:57:06 -03:00
Fabio Utzig f616c5494b bootutil: zero memory containing plain text keys
Avoid jumping into an image while still having encryption keys stored in
RAM, which could then be recovered by the app.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-20 14:57:06 -03:00
Fabio Utzig 3fbbdac56a sim: get status area size from bootutil
Add new bootutil function that returns the size of the status area.
The simulator was updated to remove the custom calculation and get
the size directly from bootutil, avoiding breakages the happen when
both are not in sync.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-20 14:57:06 -03:00
Fabio Utzig 07a9a0364d bootutil: avoid save of enc keys in secondary slot
When using swap withouth scratch, if a revert operation is detected there
is a fixup that needs to be done to avoid losing metadata. This fixup
copied metadata from the primary slot to the secondary slot temporarily.

Previously it was also copying the encrypted image keys but this is not
required since a fixup is only run when starting a new swap where the
keys were loaded directly from the images. This also avoids that a
secondary slot in external flash would leak keys (according to our
threat model).

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-20 14:57:06 -03:00
David Brown a36082664e ecdsa: Allow ECDSA signatures to be actual length
ECDSA signatures are variable length.  They are also encoded as ASN.1.
The ASN.1 parser we use is given the length, and will return a decoding
error if the signature block is not sufficiently long.  Instead of
requiring the signature block be padded to the longest possible length a
signature can be, allow them to be their natural length.

This allows image signing tools to be able to generate signatures that
don't have this padding.  Along with removing the pad removal code from
the EC224 code, this will allow this code to correctly validate all
signatures, not just 255 out of 256.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-12-18 11:53:25 -07:00
Fabio Utzig 6f4d8f8597 bootutil: allow RSA encryption keys without DP/DQ/QP
Allow runtime generation of CRT params when not available in the
embedded private key. Also remove parsing/calculation of CRT
parameters when CRT was disabled in the config (mbedTLS does not
use those in this case).

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-17 16:26:53 -03:00
David Brown 590a310366 Implement a simple benchmark framework
Add a `bootutil/bench.h` file that defines two calls
`boot_bench_start()` and `boot_bench_stop()` along with a type for the
state.  These calls can be placed around blocks of code, and with a
properly defined implementation, will print simple performance
information about these operations.

This change merely adds the includes, and the empty implementations that
are used if the bencharking feature is not enabled.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-12-12 14:48:35 -07:00
David Brown 098de833d5 boot: Clean up errors during sim test
There are a few error messages printed by the boot code.  In a normal
platform, these are real errors, and really should print a message.
However, in the simulator, we intentionally create these scenarios, and
these errors only serve to distract from the rest of the test output.

Conditionalize the error prints based on whether we are running in the
simulator.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-12-10 12:42:21 -07:00
Fabio Utzig e92df93461 sim: log: add new level targetting simulator
* Adds a new level (BOOT_LOG_SIM) to be used only for messages that
  are interesting while debugging bootutil in the simulator. This should
  be used for extra verbose prints.

* Also added fflushs after fprints to guarantee that messages are printed
  even when assertions are raised.

* For abstraction completeness, add "do nothing" definitions of _LOG_SIM
  to the other ports.

* Make DEBUG the default level when building the simulator (one can
  still lower verbosity using any other value for RUST_LOG).

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-10 16:04:44 -03:00
Fabio Utzig b86e688286 bootutil: fix random upgrade failure using swap move
Fix an issue where an upgrade could fail to execute.

This happened randomly in the "perm_with_fails" test in the simulator;
for it to happen the first reset had to occur just after writing the
metadata to mark the start of a new upgrade, but before any swap happened;
if followed by a new reset happening at a point where the metadata was
erased and rewritten, it would result in an upgrade failure. The images
would still be valid though although in their original slots.

The fix stores the detected boot status source in the state. When
metadata was found in the primary slot we assume a swap has already
started (even though no sector swap has happened) and avoid
erasing/rewriting it.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-10 12:02:15 -03:00
Fabio Utzig 5e6ea22cff bootutil: Add debug for encrypted key writing
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-10 12:02:15 -03:00
Fabio Utzig f5480c74e9 bootutil: sim: add cap for swap using move
Add cap for swap using move and rename old swap upgrade cap to swap
using scratch. Update sim to allow swapping tests to also run using
move.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-09 14:21:09 -03:00
Fabio Utzig 74aef312df bootutil: add swap without scratch strategy
This implements a swap upgrade that does not use a scratch area. It
works by first moving all sectors in the primary slot up one position,
and then looping on moving sector of index X of the secondary slot to
index X of the primary slot, followed by moving sector X+1 of the
primary slot to X on the secondary slot, for each sector X.

The idea behind this implementation was initially suggested by Jehudi
Maes (@Laczen) and implemented on his own bootloader (ZEPboot).

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-09 14:21:09 -03:00
Fabio Utzig 12d5916adf boot: bootutil: move scratch swap functionality
This moves the functionality that is unique to a scratch based swap
upgrade into a separate file. Later other upgrade strategies can be
added by reimplementing those functions.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-09 14:21:09 -03:00
Fabio Utzig e60c2fb07f bootutil: remove unused function prototype
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-12-09 14:21:09 -03:00
David Brown d13318a14f boot: Change TLV tag to 16 bits
The current TLV tag is an unsigned 8-bit integer, that is stored with 8
bits of padding.  As the TLV tag is defined to be little endian
(although the code doesn't properly handle this), we can use the 8 bits
of padding as the upper 8-bits, treating the TLV tag as a 16 bit value,
and all existing tags will operate as they did before.

Change the types used throughout the code to represent the TLV to a
`uint16_t`.  Change the ANY tag type to `0xffff` instead of `0xff`.
This value is never stored, but will avoid conflicts with any future
allocated tags.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-12-09 09:47:26 -07:00
Fabio Utzig 3c44607e16 bootutil: fix enckey issue when reverting
While doing a revert, the image encryption keys might be saved temporarily
in the scratch area; this is required in situations that we need to swap
one of the last sectors of the primary slot. When this happens, and the
device is interrupted just after restarting the revert swap, bootutil will
try to load the encrypted keys from the primary slot, and possibly use them
in reverted order (image in primary uses key of image in secondary and
vice-versa) which was saved in the test upgrade.

This fixes the issue by reverting the order used to check for the swap
metadata, with scratch being checked before the primary slot.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-11-22 15:15:29 -03:00
Fabio Utzig 23e99b0d7e boot: encrypted: fix HKDF input size macro
Use correct macro for the size of a DH shared secret. The previously
used macro had the same size (SHA-256 digest length) but incorrect
semantics.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-11-22 13:56:18 -03:00
David Brown ab449187b4 boot: store write align as uint32_t
In overwrite-only mode, the write alignment is not used for much.
Making this a larger value will allow the alignment for a particular
device to be larger than a uint8_t.  This will make the trailer size
very large for these devices (and prevent
!defined(MCUBOOT_OVERWRITE_ONLY) from being used), but at least allows
the overwrite only mode to be used on these devices.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-11-18 10:48:11 -07:00
Fabio Utzig 5fde832bbf bootutil: add ECIES-P256 support
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-11-06 06:55:25 -03:00
Fabio Utzig 5ef883a9b9 caps: add ECIES-P256
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-11-06 06:55:25 -03:00
Sam Bristow d0ca0ffc27 Fix up typos
Ran automated checker for common typos [1]. Most of these changes have
no functional change *except* for `./ci/sim_run.sh` where, previously
the `bootstrap` feature wasn't being selected properly.

I didn't touch anything in the `./ext/` folder as anything in there
should probably be fixed in the upstream repo.

[1] https://github.com/codespell-project/codespell

Signed-off-by: Sam Bristow <sam@bristow.nz>
2019-10-30 06:24:10 -03:00
Andy Gross 441e997891 mynewt: Make cflags consistent for if or ifdef usage
This patch changes the cflag entry for MCUBOOT_MYNEWT to make it
consistent when using #if or #ifdef.

Signed-off-by: Andy Gross <andy.gross@juul.com>
2019-10-21 17:22:34 -03:00
David Brown 9bf95afd43 boot: Check overflow/bounds on image header size
Before using the image and header size fields from the image header,
verify that both of these values are sane.  In this case, sanity means
that there is no arithmetic overflow when they are added, and that the
result is within the bounds of the containing flash region.  This is
done in addition to the check of the header's magic number.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-10-15 09:41:01 -06:00
David Brown effb06e367 boot: Add overflow-safe 32 and 16-bit add functions
To facility better checking for integer overflow, add these two
functions to add while checking for overflow.  If the result overflows,
they will return an error, instead of performing the addition.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-10-15 09:41:01 -06:00
David Brown b748f6fa2a Rename ext/mbedtls to ext/mbedtls-asn1
The ext/mbedtls directory has a copy of the ASN.1 parser from the mbed
TLS library.  To allow a future change to bring the entire mbed TLS
library in as a submodule under ext, rename this to mbedtls-asn1 to make
it clear this is only a subset.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-10-15 09:29:20 -06:00
Fabio Utzig ecbea70ba4 Fix overflow in offset variable
In the TLV iterator code a variable is used to save the offset in flash
where the protected TLVs end; this was declared as uint16_t and could
easily overflow so fix it by updating the type to uint32_t.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-10-15 12:27:00 -03:00
David Brown 2b8a695be1 Convert BOOT_MAGIC_SZ to #define
Convert this `extern const uint32_t` to a simple define.  Provide an
accessor function so that the simulator is able to access the value as
well.  This has a minor improvement on the generated code within MCUboot
itself.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-10-02 10:17:22 -07:00
David Brown e0bb1f956f Change BOOT_MAX_ALIGN to #define
BOOT_MAX_ALIGN is defined as

    extern const uint32_t BOOT_MAX_ALIGN;

and is assigned a value in a single file.  This causes extra work when
this is used as the size of a local variable in a function.

The value was made a constant in order for the simulator to be able to
access the value.  Instead of making it a "real" constant, keep it as a
define, unifying the value of FLASH_MAX_ALIGN and this one, and provide
an accessor function for the test code to be able to access this value.

This causes a minor improvement in the code generated in
`boot_write_status`, but more importantly, eliminates a VLA from the
code, which increases the possible compilers supported by MCUboot.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-10-02 10:17:22 -07:00
Fabio Utzig e52c08edf0 bootutil: update to new protected TLV format
Implements the validation system where hashing is performed over header
+ payload + protected TLVs.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-10-01 18:30:05 -03:00
Fabio Utzig 61fd888a7f Add TLV iterator API
This introduces an API which allows for iteration over an image's TLVs
without resorting to low-level implementation details. All previous TLV
low-level handling was updated to comply with this new interface, and it
also makes it easier for external code to handle TLVs.

The API provides two functions:

1) To start a new iterator:

```
int bootutil_tlv_iter_begin(struct image_tlv_iter *it,
                            const struct image_header *hdr,
                            const struct flash_area *fap, uint8_t type,
                            bool prot);
```

2) To iterate over existing TLVs of given type:

```
int bootutil_tlv_iter_next(struct image_tlv_iter *it, uint32_t *off,
                           uint16_t *len, uint8_t *type);
```

A type of IMAGE_TLV_ANY was added to allow for iteration over all TLVs.

Low-level TLV access functions were removed from API, but low-level
structs are still visible in the namespace.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-18 07:38:50 -05:00
Marti Bolivar 99ec383ea1 bootutil_misc: fix printf types in log macros
Upstream PR #547

The recent changes to these are tripping GCC printf-like macro
attribute warnings on my platform. Just cast all the values to ulong
to make everybody's compilers happy.

Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
2019-09-13 15:54:36 -06:00
Fabio Utzig e575b0b8ef Add macro to check if swap_type is an upgrade
This allows refactoring a check that was done in multiple places looking
for the same swap types.

Also fixes an issue where dependency checks would be run if a swap type
had a value that indicates fail.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-12 14:08:35 -03:00
Fabio Utzig b1adb1ed2e Fix validation when no image is present
The slot validation routine would result in a non-installed image to be
equivalent to a failed validation, which would set the swap type to
*_FAIL and require special handling in the dependency checks. This
routine was updated, so that it now returns a value that can be used to
check that the error was due to an image not found.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-12 14:08:35 -03:00
Fabio Utzig 59b63e5625 Fix identation
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-10 13:41:58 -03:00
Fabio Utzig c28005b04f Use better naming for swap copy/erase functions
Since a copy/erase during a swap can result in some number of sectors
erased and copied, which is not necessarily equal to 1, update design
document and bootloader function naming to reflect this fact, by using
the postfix "_region" instead of "_sector" in those cases.

This fixes #541

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-10 13:41:58 -03:00
Fabio Utzig c21c210b82 Fix encrypted images with dependencies
This fixes an issue where dependencies were being decrypted before
hashing when encrypted images are used. When using dependencies, some
"protected" TLVs are added to the image. Those TLVs take part into the
image hash calculation, but are not encrypted and must be sent plain
to the hash update routine.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-10 12:13:56 -03:00
Ben McCrea 4c0ee9567c botutil/botutil_misc: fix compile error for debug log
BOOTUTIL_LOG_LEVEL_DEBUG was giving printf format compile errors

This patch fixes the issue.

Signed-off-by: Ben McCrea <bmccrea@juul.com>
2019-09-10 08:54:35 -06:00
Fabio Utzig 4d7396d7f2 Fix swap status control
This fixes two issues related to swap status control:

1. During a swap, the status was written offset by one, because it was
   being incremented before it was written to flash. With the increment
   happening early the offset was calculated always one position after
   where it should be, which would leave the first status index free,
   and override the last one (worst case scenario).
2. When an image is too big it requires the swap status to be
   temporarily stored on scratch, to allow the last sector on the
   primary slot to be erased. The status is written to scratch for 2
   status updates, and afterwards copied back to the primary slot, which
   then receives future status updates. The code that copied the status
   back from scratch to the primary slot was erroneously copying the space
   of 3 status writes, which would result in a write over non-erased area
   for the third byte.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
David Brown e6ab34c367 Allow upgrades of only one slot
When only upgrading one slot, the swap type for the non upgraded slot is
BOOT_SWAP_TYPE_FAIL instead of NONE.  Account for this, and check slot 0
in this case.

This is probably not the correct solution, but it is unclear of the
timing of when the dependencies of the other images first slot would be
checked.

Signed-off-by: David Brown <david.brown@linaro.org>
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
Fabio Utzig 298913b940 Fix dependency check infinite loop
This fixes the issue where an unmet dependency would result in a restart
of image dependency checks. To make the code easier to follow, some
function nesting was removed, functions that check slot dependencies
were renamed appropriately and dependency check is not done when no
upgrades are marked.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
Fabio Utzig 019a81a4f4 Move boot_is_version_sufficient to module scope
The checking of image version compatibility is only used by dependencies
code; this moves the version checking function static, and removes it
from the exported API.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
Fabio Utzig 75e9a59d40 Remove boot_swap_type usage in the bootloader
`boot_swap_type_multi` should be used instead. The `BOOT_CURR_IMG` macro
already returns the correct value in single image mode.

For compatibility with external tools like mcumgr, `boot_swap_type`
remains available and always returns the swap type of image 0.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
Fabio Utzig 233af7d7b3 Add utility function to find offset/len of TLVs
Add a new function, boot_find_tlv_offs, that loads the beginning and end
offset of the TLV region.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
Fabio Utzig a87cc7d98c Use local var instead of repeated macro call
Store TLV offset in a variable to avoid repeating many calls to the
calculation macro.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
Fabio Utzig bc07793ab2 Add macro to check if image must be decrypted
An image must be decrypted when it is loaded on the secondary slot and
its header flag indicates it is encrypted. Instead of checking both
things every time the image is read, add a new macro, MUST_DECRYPT, that
does both checks.

Also `BOOT_CURR_ENC` was simplified to be used directly on
`bootutil_img_validate` calls, returning NULL for no encrypted images.

Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00