Add fault attack mitigation measures to code vital for the correct
validation of images.
Change-Id: If6eb1110a8c2966faf105d07ad2e95482a80a8d9
Signed-off-by: Raef Coles <raef.coles@arm.com>
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
- The enc_context needs to initialize.
boot_enc_load seems to always be used to start the process, so calling
init inside makes sense.
- Handle boot_encrypt getting called with size of 0.
- No need to free contexts because Zephyr sets MBEDTLS_PLATFORM_NO_STD_FUNCTIONS.
I don't quite like this because it's implicit and will leak memory on
other ports.
Signed-off-by: Blaž Hrastnik <blaz@mxxn.io>
bootutil already handles ASSERT definition, allowing us to override it
with a custom implementation. Importing assert.h would pull in stdio.h
and a whole bunch of other stuff by TI compiler into the final
firmware.
Signed-off-by: Blaž Hrastnik <blaz@mxxn.io>
This patch introduces the ram-load mode in addition to the other
upgrade modes (swap strategies, overwrite-only, direct-XIP). When
ram-load is enabled with the MCUBOOT_RAM_LOAD option, mcuboot
selects the newest valid image based on the image version numbers from
the image header, thereafter the selected image loaded to the RAM and
executed from there. Load address is extracted from the image header.
Therefore the images must be linked to the RAM memory region.
The ram-load mode is very similar to the direct-XIP mode, main
difference is to load the newest image to the RAM beforehand the
authentication and execution. Similar to direct-XIP mode either
of the primary and the secondary slots can hold the active image.
Ram-load can be useful in case of a bit more powerful SoC, which
is not constrained in terms of internal RAM. It could be that image
is stored in external and therefore untrusted flash. Loading image
to internal (trusted) RAM is essential from the security point
of view the system. Furthermore execution from internal RAM is much
faster than from external flash.
This patch is based on the RAM_LOADING upgrade strategy which was
first introduced in the Trusted Firmware-M project.
Source TF-M version: TF-Mv1.0.
Change-Id: I95f02ff07c1dee51244ac372284f449c2efab362
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
This patch introduces the direct execute-in-place (XIP) mode in addition
to the other upgrade modes (swap strategies, overwrite-only). When
direct-XIP is enabled with the MCUBOOT_DIRECT_XIP option, mcuboot
selects the newest valid image based on the image version numbers from
the image header, thereafter the selected image runs directly from its
flash partition (slot) instead of moving it. Therefore the images must
be linked to be executed from the given image slot. It means that in
direct-XIP mode either of the primary and the secondary slots can hold
the active image.
This patch is based on the NO_SWAP upgrade strategy which was first
introduced in the Trusted Firmware-M project.
Source TF-M version: TF-Mv1.0.
Change-Id: If584cf01ae5aa7208845f6a6fa206f0595e0e61e
Signed-off-by: David Vincze <david.vincze@linaro.org>
Replace the boot_is_version_sufficient() function with a new,
boot_version_cmp() function which is more straightforward and
distinguishes the 3 possible results of the comparison.
Update the error handling accordingly.
Change-Id: Ie7d4f892dc3df2c6ef82769c4d0676965b75b7b8
Signed-off-by: David Vincze <david.vincze@linaro.org>
When using swap in move mode, the current compatibility test only allows
for same size and layout between slots. This results in one sector that
can never be used in the secondary slot, which corresponds to the first
move up operation in the primary slot. This relaxes and checking a bit,
so both same size slots and a primary with one extra sector are valid.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This fixes an issue where an image might be erased, but a trailer left
behind. It can happen if the image in the secondary slot did not pass
validation, in which case the whole slot is erased. If during the erase
operation, a reset occurs, parts of the slot might have been erased
while some have not. The concerning part is the trailer because it
might disable a new image from being loaded through mcumgr; so just get
rid of the trailer here, if the header is erased.
Signed-off-by: Fabio Utzig <fabio.utzig@nordicsemi.no>
Fix uninitialized variable warning that may occur when
compiler optimization is enabled (especially for size).
Change-Id: Id56669a2079ac20edbf74c17f943c974f1e8bf93
Signed-off-by: David Vincze <david.vincze@linaro.org>
- If MCUBOOT_SIGN_RSA, MCUBOOT_SIGN_EC, MCUBOOT_SIGN_EC256 are not
defined cryptographic signature check is skipped during validation.
sha256 check is still retained. This reduces the binary size, at the
expense of greatly reduced security. However this can be acceptable
in some scenarios where cryptographic check is not required.
Signed-off-by: Arvin Farahmand <arvinf@ip-logix.com>
To make contributions easier, place explicit copyrights by the major
contributors, along with an SPDX license identifier. Files that came
from the mynewt project, which was an Apache project will retain the
Apache project license text, although this does not apply to new
contributions, which are being made by individual contributors.
Hopefully, this will keep everyone happy, but allow contributors that
need to add an explicit copyright to have a place they can add that.
Fixes#501
Signed-off-by: David Brown <david.brown@linaro.org>
This macro is part of the C11 standard. Remove the use of a specialized macro
just for Zephyr, and use the standard macro for all platforms. This reduces
dependencies on specific versions of Zephyr.
In addition. The Zephyr-specific code was using toolchain/gcc.h which
would only work with gcc.h, so doesn't actually address any of the
objections. If this ever becomes a problem with Zephyr, we can figure
out a proper way to fix this.
Signed-off-by: David Brown <david.brown@linaro.org>
- Define new TLV for carrying information for x25519 based encrypted
images.
- Add routines to parse embedded encryption key, generated shared
secret and image decryption key.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This change enables the public key (used for image authentication) to
be removed from MCUboot and be appended to the image instead. In this
case the key or its hash must be provisioned to the device and MCUboot
must be able to retrieve the key-hash from the hardware to compare it
with the calculated hash of the public key from the image manifest in
order to verify its validity before image authentication.
The source of this change:
https://review.trustedfirmware.org/c/trusted-firmware-m/+/1581
Change-Id: I36fe699732e0e4c113eaed331c22e707c722ed6e
Signed-off-by: David Vincze <david.vincze@linaro.org>
Replay of reverted to early committed patch 6d417c9:
Replace BUILD_ASSERT_MSG() with BUILD_ASSERT()
after merging BUILD_ASSERT() and BUILD_ASSERT_MSG().
Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
Modify the definition of certain shared data TLV entry header fields to
be aligned with the image TLV's behaviour (the meaning of the tlv_len
field was different) and achieve unified interpretation.
Modify some macro definitions that use bitwise shift operators to
prevent certain errors from occurring due to implementation-defined
behaviour.
Change-Id: Ib736703a391d390a87d629a8ac4e77e1789120a5
Signed-off-by: David Vincze <david.vincze@linaro.org>
Implement the functions declared in boot_record.h and add
each BOOT_RECORD TLV's CBOR encoded binary data (one TLV entry per
image) to a shared data area between the bootloader and the runtime SW.
These data units are stored in a TLV format (in the shared area too) and
contain certain attributes of the given image / SW component such as:
- SW type (role of the software component)
- SW version
- Signer ID (identifies the signing authority)
- Measurement value (hash of the image)
- Measurement type (algorithm used to calculate the measurement value)
Preserving all these image attributes from the boot stage for use by
later runtime services is known as a measured boot. The list of the
shared attributes is based on the recommendations of Arm's Platform
Security Architecture (PSA).
The main purpose of this patch is to create the prerequisites of an
attestation service by providing these measurements.
The boot_record.c and boot_status.h (originally tfm_boot_status.h) files
were copied (with modifications) from the Trusted Firmware-M project
(https://www.trustedfirmware.org/about/).
Hash of the source commit: 08d5572b4bcee306d8cf709c2200359a22d5b72c.
Change-Id: I37a8e7b10d5bf80a581651ffaf65b3cba45eaff2
Signed-off-by: David Vincze <david.vincze@arm.com>
Define interface for sharing boot status (certain attributes of the
authenticated images) and adding arbitrary data in TLV encoded format
to a shared data area between the bootloader and runtime SW.
The boot_record.h file was copied (with minor modifications) from the
Trusted Firmware-M project (https://www.trustedfirmware.org/about/).
Hash of the source commit: 08d5572b4bcee306d8cf709c2200359a22d5b72c.
Change-Id: Ia25bac27e9f1ce7faa5043c5a0455c804a24701e
Signed-off-by: David Vincze <david.vincze@arm.com>
Replace BUILD_ASSERT_MSG() with BUILD_ASSERT()
after merging BUILD_ASSERT() and BUILD_ASSERT_MSG().
Signed-off-by: Oleg Zhurakivskyy <oleg.zhurakivskyy@intel.com>
- Add image security counter verification (read security counter value
from the image manifest and compare it against the stored/active
security counter) as an optional part of the image validation process
to prevent the restoration of older, potentially vulnerable images.
- This feature can be enabled with the MCUBOOT_HW_ROLLBACK_PROT option.
- Add security counter interface to MCUBoot. If HW rollback protection
is enabled then the platform must provide a mechanism to store and
read the security counter value in a robust and secure way.
Change-Id: Iee4961c1da5275a98ef17982a65b361370d2a178
Signed-off-by: David Vincze <david.vincze@arm.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
* 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
`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>
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>
While iterating over the swap table looking for swap type,
avoid asserting on errors; let caller handle error handling.
Signed-off-by: Fabio Utzig <utzig@apache.org>
`boot_read_image_size` was already receiving the bootloader state and
slot; since the image_header is part of the state and can be gathered
from it, it was removed from the list of parameters.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This adds a single trailer writing routine that can write any amount of
data (upto BOOT_MAX_ALIGN); the functions that were writing to the
trailer now just call this one passing the offset and data/len.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Update each function to calculate the offset based on a previous
function offset, so that if one has to be changed not all functions have
to be updated.
Signed-off-by: Fabio Utzig <utzig@apache.org>
When doing a swap some of the information required by the process
is temporarily written to the status area; previously each data
writing routines tried to find the correct area by looking for the
magic and assuming that data is located there (because everything
fits a single sector). This moves the code to find the magic into
a separate routine that is now used by others.
Signed-off-by: Fabio Utzig <utzig@apache.org>
When the hash key length parameter is invalid (bigger than allowed) just
return an error for the caller routines; this will work like a not found
key and allows the removal of assert() code in this module.
Signed-off-by: Fabio Utzig <utzig@apache.org>
TLV offset was determined by manually adding the header and image
size in many places; this makes the addition into a macro receiving
a image_header to ease future changes.
Signed-off-by: Fabio Utzig <utzig@apache.org>
The boot loader state currently exists as global variable (boot_data)
which is accessed by all routines; this updates all routines that
require access to the state to receive it by parameter.
Variables that are declared as "static" (globals) were #ifdef'ed to
only use static when building a native bootloader, to avoid stack
allocation. When bootutil is built to run in the simulator they are
stack allocated to avoid thread share.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Currently to determine which image is being operated on, there is a global
variable called current_image which is used by most macros and APIs to
correctly access the flash areas required by the bootloader. This moves
this variable to the already existing state struct and refactors all
macros and APIs to receive the current image by parameters. To maintain
compatibility some of the macros were not updated and use image 0 when
called.
The definitions of FLASH_AREA_IMAGE_PRIMARY and FLASH_AREA_IMAGE_SECONDARY
for Mynewt compatibility were moved out of bootutil sources to a Mynewt
specific include file.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This struct currently relies on padding being done by the C compiler.
Although this is generally done the same across targets, this isn't
required, and it is better to make any padding explicit. This also
makes it clear that there is extra space in this structure that can be
used for another purpose.
The python imgtool is also fixed to match. It was using a 32-bit int,
which only worked in the little endian case.
Signed-off-by: David Brown <david.brown@linaro.org>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
This compliments the previous change on `image_ok` and also removes
`flash_area_erased_val` call that is not needed anymore.
Signed-off-by: Fabio Utzig <utzig@apache.org>
It was impossible to set confirm flag due to incorrect comparison.
In this point of time state->image_ok is already decoded and contains
one of following values:
If BOOT_FLAG_UNSET then we are ok to set a confirm flag.
Signed-off-by: Łukasz Rymanowski <lukasz.rymanowski@codecoup.pl>
This will fix#335 by defining the array size of the magic word and
give it to the relevant functions.
Signed-off-by: Hovland, Sigvart <sigvart.hovland@nordicsemi.no>
This extends mcuboot to allow use on devices which don't follow the
typical erased at 0xff. This was tested on some previously supported
devices (erased at 0xff) and STM32L1/L0 which are erased at 0.
Signed-off-by: Fabio Utzig <utzig@apache.org>
The swap status area is used to maintain information that allows
recovery when interrupted in the middle of a swap. This area has no
usefulness when doing a overwrite-only upgrade, which always copies the
entire slot.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This removes settings of log level on a per file basis. The log level
should be set by the global config, while per file log configuration can
still be set, don't enforce them.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Now bootutil_log.h was converted to use per platform logging primitives
defined according to documentation established on the template file.
Some "null" macros were left to avoid breaking per source logging level
definition when MCUBOOT_HAVE_LOGGING was not defined.
Signed-off-by: Fabio Utzig <utzig@apache.org>
The patch introduce usage of zephyr flas_map module instead
of mcuboot zephyr-only implementation. Unused flash_area_to_sectors
API of former flash_map was removed as well.
Size of sector-status-update-map entry is now defined thanks to the
minimum write size supported by the flash driver.
For avoid ambiguity former zephyr-only files flash_map.c
were renamed to flash_map_extended.c (its code now implements
only addition to this what zephyr flash_map implements).
flash_map.h header include is now warped by flash_map_backedn.h headre
because implementations and include pathes are diferent in Zephyr and Mynewt.
Usage of hal_flash_align() were replaced by usage flash_area_align().
This provide consistency between MyNewt and Zephyr implementation as
this API is available in both RTOSes.
flash_map.h was moved to the simulator c-support files as now missing in
the boot/zephyr subdirectories.
f. boot_scratch_fa_device_id was removed as unused.
f. boot_img_fa_device_id was and expanded the only use of it
(on loader.c).
Signed-off-by: Andrzej Puzdrowski <andrzej.puzdrowski@nordicsemi.no>
This removes the old "TLV size" and "keyId" fields that used to exist
in the old image header format and updates it to use `load_addr`. Also
fixes the name of reserved fields to index from 1.
This fixes#279
Signed-off-by: Fabio Utzig <utzig@apache.org>
The unit tests depend on a few Mynewt packages (`test/testutil` and
`sys/console/stub`). If there is no repo prefix in the dependency
specifier, newt assumes the package is in the local repo (mcuboot)`.
This commit adds the `@apache-mynewt-core/` prefix to these
dependencies.
Signed-off-by: Christopher Collins <ccollins@apache.org>
Continue removing platform-specific conditional compilation from
bootutil by adding a new MCUBOOT_HAVE_ASSERT_H configuration option
and associated header file. Right now, that's only used by the
simulator.
That leaves just bootutil_log.h with platform-specific contents, but
since it's meant to be an abstraction layer for logging, we'll let it
stand for now.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
Take the opportunity to clean up a bit of platform cruft that has
gotten into bootutil by moving it to mcuboot_config.h, and ensuring it
is documented in the template config file.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
Mynewt uses this file to convert MYNEWT_VAL(xxx) to MCUBOOT_xxx config
options. Zephyr currently adds config options via the compiler command
line, but it should use this instead.
As prep work for that conversion, add an empty mcuboot_config.h to the
Zephyr port, and include this file unconditionally wherever it's
needed. This takes care of the simulator as well, since that puts
boot/zephyr/include on its C file include path.
This turned up a couple of files (bootutil_priv.h and caps.c) that
were using the MCUBOOT_xxx config values without including the
file. Add the includes there, as they'll be needed later.
To make this official, add it to the requirements in the porting guide
and provide a template file porters can use while getting started.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
fixup! Mandate the presence of mcuboot_config/mcuboot_config.h
This still defaults to 128 for compatibility, but allows users to
specify less elements to save space, or more elements for devices that
have massive flash size and/or too small sectors.
Signed-off-by: Fabio Utzig <utzig@apache.org>
BOOT_STATUS_ASSERT increments the variable if the macro argument
is evaluated as true, which is incorrect behavior compared to the
ASSERT macro.
Signed-off-by: Johann Fischer <j.fischer@phytec.de>
In 2f8f06aa25
commit 2f8f06aa25e9d5ee4fc9fe217543c872b39e4d05
Author: Hanno Becker <hanno.becker@arm.com>
Date: Fri Sep 29 11:47:26 2017 +0100
Don't always recompute context length in mbedtls_rsa_get_len
mbed TLS begins assuming that the 'len' field of the context has been
set properly. Previously, we relied on this not being true, and various
tests fail for all keys without setting this.
The fix is to simply set the length based on the value we read.
fixes#235.
Signed-off-by: David Brown <david.brown@linaro.org>
Since boot_read_image_headers only failed when reading headers from
both Slots failed, it could happen that even with a failure reading
Slot 1, this data would still be used by split booting. Now when
reading image headers an extra parameter allows the caller to ask
for failure when any slot read failed.
JIRA: MCUB-56
Signed-off-by: Fabio Utzig <utzig@apache.org>
Assertions that are expected to fail under sim test, are now marked as such
using the macro ASSERT which allows to programmatically switch between normal
assert() behavior and captured assertion.
Assertion changes were moved to more appropriate owners and code duplication
was removed.
Signed-off-by: Fabio Utzig <utzig@apache.org>
The rationale behind this change is that while performing a swap
operation, writes to the status area are not important enough
to abort the operation. If the swap is not interrupted, status
writes are ignored. If the swap is interrupted, failures to write
status area are detected during the next boot and an appropriate
measure is taken.
If MCUBOOT_VALIDATE_SLOT0 is set we ignore the status write fail
and allow slot0 to be validated by its hash/signature. Otherwise,
the old behavior is maintained, which is to abort on any write
failures.
Signed-off-by: Fabio Utzig <utzig@apache.org>
When building in simulator mode, mock assert() to call an simulator
function which will enable other code to check if some path failed.
The assert checking interface, was added to boot_go which now
returns the low-level invocation results as well as the number of
asserts triggered.
Some new added tests check for assert() and expect it to happen. To not
abort tests, assert() was changed under sim env to not call c assert()
and instead just do some internal calculation which could be checked
by the simulator after a bootloader run and assert() catching behavior
was made optional (each test choses the behavior it needs).
Signed-off-by: Fabio Utzig <utzig@apache.org>
This commit removes the pseudo tinycrypt package based on symlinks
by adding a new pkg.yml to ext/tinycrypt and using it directly. It
also uses the new mbed-tls bundled ASN1 parser when EC256 is selected.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This fixes a comparison issue that was previously fixed by doing a
cast. Since tinycrypt and mbed-tls both already use an unsigned for
the size, the mcuboot interface was updated to also use an unsigned
value (size_t to be more precise!).
Signed-off-by: Fabio Utzig <utzig@apache.org>
Fixes warnings treated as errors when upgrading gcc crate to 0.3.54.
Warnings are due to non-used variables and comparison between signed
and unsigned.
Signed-off-by: Fabio Utzig <utzig@apache.org>
When not validating slot 0, we could be booting into an empty
chip. This means we jump based on garbage data.
Try to make this better by at least checking the magic number. Without
this patch, booting with just the bootloader fails the Zephyr release
tests.
Signed-off-by: Marti Bolivar <marti@opensourcefoundries.com>
This add a new option to overwrite-only mode that enables copy/erase of
only the amount of sectors that are required to store the source image.
This is enabled by default when overwrite-only mode is used.
MCUB-70
Signed-off-by: Fabio Utzig <utzig@apache.org>
This function is unused in overwrite-only mode. Clang seems to catch
this, whereas gcc does not. Add the proper ifdefs so that the
simulator tests all pass on MacOS.
Signed-off-by: David Brown <david.brown@linaro.org>
Fixes a bug when MCUBOOT_VALIDATE_SLOT0 is enabled which caused the
header in Slot 1 to be used for calculating the bootstrap offset. This
bug is masked when MCUBOOT_OVERWRITE_ONLY is not enabled because both
slots have the same header size (usually!). With MCUBOOT_OVERWRITE_ONLY
Slot 1 was erased and the header size would be read as 0xffff resulting
in a jump to the wrong address.
Signed-off-by: Fabio Utzig <utzig@apache.org>
When building in overwrite-only, there is no status/trailer management.
This commit fixes an issue where there was a write to image_ok/copy_done
where those flags where already set (copied from slot 1) which would
cause a write over non-erased flash.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This removes the dependency on tinycrypt lib provided by mynewt and
switches to the one bundled in mcuboot. Also fixes a bug where tc
was only being used when eliptic curve 256 was selected as sign
algorithm.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Add a flag `IMAGE_F_RAM_LOAD` and an associated header field
`ih_load_addr` to indicate that a particular image should be loaded into
RAM instead of being executed directly out of flash. If the flag is not
set, this field will be ignored. If it is set, and this feature is
supported by the bootloader, the image will be loaded into RAM at the
address specified in the new header field.
None of this functionality is implemented at this time. This is merely
to define the header format to avoid having to change the image format
later.
JIRA: MCUB-79
Signed-off-by: David Brown <david.brown@linaro.org>
The keyhash should be able to have any size up to the maximum allowed
size of 32, but the assert was not allowing images created with newt to
be accepted as valid (newt currently uses only 4 bytes for keyhash).
Signed-off-by: Fabio Utzig <utzig@apache.org>
Signed-off-by: David Brown <david.brown@linaro.org>
When starting a swap upgrade, the total size of data to be swapped is
calculated only at the beginning and saved to the trailer. This avoids
having to use complicated heuristics to find the total swap size, which
might depend on data that was already moved. When resuming a swap, the
size is found in the trailer and used.
Also includes some small comment fixes and refactors.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Signed-off-by: David Brown <david.brown@linaro.org>
The local variable 'size' is actually the offset of the end, and not the
size. Rename it to reflect this reality.
Signed-off-by: David Brown <david.brown@linaro.org>
Clarify the name of the TLV field to more fully describe the signature
type.
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
Since we are changing the image header format, there is no reason to
continue to support the old PKCS#1 v1.5 signatures. Remove the
definitions, and conditional complication related to this, and only
support the newer PSS signatures.
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
Since we've changed the meaning of several fields in the header, bump
the header to a new magic number. The fields that are still present are
in the same place, but all of the signature and TLV information is moved
into the TLV itself, which is still immediately after the image.
As of this commit, this defines the new image header/TLV format used for
1.0.
Based on work by Marko Kiiskila <marko@runtime.io>
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
To allow the signatures to be replaced, move the size of the TLV into a
small "info" header at the start of the TLV.
Note that this causes image swapping to lose robustness. This is fixed
by a later commit.
Based on work by Marko Kiiskila <marko@runtime.io>
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
JIRA: MCUB-65
Remove the key_id field from the image header. There are two problems
with this field. First, it is only an integer offset, and so causes an
unnecessarily tight coupling between the particular keys built into the
bootloader, and the key that is used to sign. Second, it makes the
key_id part of the image header, which is included in the signature.
This makes it impossible to later sign the image with a different
signature.
Instead of the key-id, add a TLV KEYHASH entry. This will hold the
SHA256 of the public key that the signature is against. Each signature
placed in the TLV should be preceeded by this entry to indicate the
public key used.
The signature check will check each signature, and if the KEYHASH is
known and the signature type is supported, it will be checked. As long
as at least one signature is considered valid, the image will be
considered signed. This also allows the image to be signed with
multiple signatures to support having different devices with possibly
different keys compiled into the bootloaders.
Based on work by Marko Kiiskila <marko@runtime.io>
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
In preparation for moving the signature related values out of the main
image header and into the TLV, renumber the existing TLV values to be
grouped together better.
The SHA256 is moved into the first group, at 0x10, and the signature
values themselves are moved to start with 0x20.
This change is the first in a series of changes toward the new v1.0
image format. The intermediate results are all internally consistent
(meaning that the simulator, and the builtin imgtool.py will all work
together), but until all patches are applied, the image format is not
valid with any external tools.
Based on work by Marko Kiiskila <marko@runtime.io>.
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
The comment for BOOT_SWAP_TYPE_NONE says "Just boot whatever is in
slot 0". That's not correct: if configured to do so (and this the
strongly recommended configuration), mcuboot will first
cryptographically validate the contents of slot 0 before booting it.
Fix the comment to be more accurate.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Adjust alignment and add missing leading zero to
IMAGE_F_PKCS1_PSS_RSA2048_SHA256. This needed some comment changes to
keep things 80 column clean.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
This enables mynewt to use mcuboot as a remote repository, which is only
required when using newtmgr to manage images. Since mcuboot has slightly
changed the trailer format, newtmgr built against the bundled mynewt
bootloader writes the magic and flags to the wrong location.
To build a mynewt app the wants to run with mcuboot as the bootloader
and requires newtmgr one needs to change the app's pkg.yml dependencies
as follows:
- - boot/bootutil
+ - "@mcuboot/boot/bootutil"
Signed-off-by: Fabio Utzig <utzig@apache.org>
When image is slot 1 had bad signature, the swap would fail and
try to write image_ok in slot 0 which if that was already a
permanent image would cause a overwrite in flash.
Fix warning/error when slot 0 validation is not enabled.
Signed-off-by: Fabio Utzig <utzig@apache.org>
After a swap operation is finished trailer control flags are written
according to the type of swap that was performed. The function names
that execute those operations were renamed to explicity reflect what
they do, and all "less deterministic" behaviors, of the type
"if flash is not set, set it", were removed.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This adds handling of the copy_done bit while evaluation a swap state.
Since copy_done is only ever written when a swap finishes, it can be
safely assumed that if copy_done is not set no swap was ever performed
and the image was written directly to flash, and thus no revert is run.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This reworks much of the code, as well as tables, handling swap
state to make them simpler. Only states that require an actual
swap to be performed, perm/test/revert are checked for and acted
upon. Other possible states try to default to no operation
performed.
One extra state, BOOT_SWAP_TYPE_PANIC, was added to differentiate
between "soft" errors and unrecoverable ones (as flash read/write
errors).
Non well defined state changes after swap failures, as described
in MCUB-59 were also clean up.
This should also fix situations as described in MCUB-63, where
images generated using imgtool (magic + image_ok set) are written
to slot 0 and cause an incorrect "revert".
Signed-off-by: Fabio Utzig <utzig@apache.org>
The MCUBOOT_VALIDATE_SLOT0 feature only verifies the signature when
there is no swapping happening. The assumption was that if there is a
swap being done, the code will verify the signature of slot 1 before
doing the slot.
However, either due to bugs, or intentional trickery, it may be possible
to confuse the code into continuing a swap operation. If the data is
modified before this, the bootloader can be tricked into booting the
resulting image in slot 0 without having verified the signature.
Fix this by always verifying slot 0's signature before booting it.
JIRA: MCUB-64
Signed-off-by: David Brown <david.brown@linaro.org>
This implements changes according to MCUB-14, easing the process
of making external apps parse and read/write the trailer.
Signed-off-by: Fabio Utzig <utzig@apache.org>
For mynewt flash map only accepts values for slot 0 and 1. This
code was trying to read the image header on the scratch area using
the same interface and was segfaulting when slot0 and slot1 had
similarly sized images.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This error was catched by Coverity and it happens when a fail occurs
opening a flash map handle, which is not checked by the close
routine.
Right now this only affects Zephyr, but extra checking was added
assuming that in a future Mynewt implementation close could actually
be changed to do something.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Use flash_device_base() in the boot code to compute a real address,
given the offset returned by boot_go().
Provide an implementation on mynewt that preserves existing
behavior. If mynewt needs to support devices with nonzero flash base
addresses, this can be migrated to the core OS.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Similarly, it's confusing whether br_flash_id is a flash device ID or
a flash area ID. Make this unambiguous.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
The boot response returns a flash offset, not a flash address. This is
causing confusion and leading to crashes on some platforms which don't
have flash at address 0.
Rename the field to make it more clear what its purpose is; future
patches can start fixing up usages.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Add a typedef which lets us use flash_sector or flash_area to contain
the sectors within the boot_data global. When
MCUBOOT_USE_FLASH_AREA_GET_SECTORS is defined, this is struct
flash_sector.
Also add struct boot_loader_state accessors to handle this case, and
make the appropriate changes to where the sectors are allocated to use
the new typedef.
Finally, ensure MCUBOOT_USE_FLASH_AREA_GET_SECTORS is defined in the
Zephyr Makefile, since flash_area_get_sectors() is already provided
there.
This lets mcuboot users convert to the new flash API gradually.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Move helpers which are needed for using flash_area_to_sectors() to the
end of file. This is just to keep things clean when we add support for
flash_area_get_sectors().
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Keep both image areas and the scratch area open while we are
bootloading. This fixes up a hack and will make it easier to use
flash_area_get_sectors() later.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Add abstractions for calculating the starting offset of a sector from
the beginning of its image, and the starting offset of an image slot
from the beginning of its flash device.
Using this tweaks a check in boot_swap_sectors(), but doesn't change
its outcome.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Add an abstraction for initializing bootloader state for a particular
flash area.
For now, we preserve some existing hacky behavior related to the
scratch area. This will get cleaned up more later in the series.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Taking the opportunity to move some signed integers over to unsigned
size_t as we go. (Depending on compiler settings, signed / unsigned
comparisons can generate warnings, so it's nice to use the signedness
we mean when possible).
Having boot_img_set_num_sectors() is just an intermediate step; this
gets cleaned up as we go forward.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
This begins some preparatory work to using flash_area_get_sectors() in
loader.c. Subsequent commits will add and use additional accessors for
the contents of this struct.
Making the struct contents opaque will allow it to contain struct
flash_area or struct flash_sector values in its sectors field. This
will allow use of either flash_area_get_sectors() or the
now-deprecated flash_area_to_sectors().
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
Allow the size of bignums in mbed TLS to be configured larger than
needed for RSA2048. This will waste memory holding the large numbers,
but will still work.
The PKCS#1 standards, which define RSA signatures, are currently at
version 2.2. Starting in v2.1, the standard defines a new signature
method RSA-PSS, which has a stronger security proof than the signature
method used in earlier versions. The standard recommends that RSA-PSS
be used in new designs, instead of the older algorithm.
This patch implements RSA-PSS verification for a specific set of
parameters:
- RSA-2048
- SHA256 for both the message digest and the internal hash
- 32-byte salt
- 2047 bit message
Although RSA-PSS supports other parameters, due to size constraints,
this verificatino code only supports these specific parameters, and
signatures with other parameters will be considered invalid.
To encourage the use of the more secure algorithm, the default build
configuration is RSA-PSS. BOOTUTIL_RSA_PKCS1_15 needs to be defined in
order to support the older signature algorithm.
Remove most of mynewt specific stuff to a separate port package. This
should make mcuboot less "mynewt'y" and slightly easier to port to.
- Mynewt specific stuff moved to boot/mynewt.
- Sample app moved from apps/boot to boot/mynewt.
- Use MYNEWT_VAL macro only on mynewt port.
- BOOTUTIL_* and MYNEWT_VAL() usage moved to MCUBOOT_ defines.