Move the external mbedtls submodule out of the sim/mcuboot-sys directory
into the ext directory. This will allow the same copy of mbed TLS to be
used by other board support packages, instead of having to make a
duplicate clone.
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>
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>
Test the variations of the situation where we are built for multi-image,
but are only upgrading a single image, including no dependencies,
correct dependencies, and unmet dependencies.
Signed-off-by: David Brown <david.brown@linaro.org>
Signed-off-by: Fabio Utzig <utzig@apache.org>
Add two additional dependency types. The NoUpgrade type indicates that
this slot should not contain an upgrade at all. The OldCorrect
indicates a dependency on the old version of the other slot.
Signed-off-by: David Brown <david.brown@linaro.org>
Signed-off-by: Fabio Utzig <utzig@apache.org>
Instead of allowing a preliminary error if the first image is marked to
be held, allow this error if any of the images are marked to be held.
The error doesn't return which image caused the failure, so just check
if any are supposed to be held.
Signed-off-by: David Brown <david.brown@linaro.org>
Signed-off-by: Fabio Utzig <utzig@apache.org>
Test the configuration where one image has its dependencies met and the
other does not, and make sure in these cases we just hold back from
upgrading entirely.
Signed-off-by: David Brown <david.brown@linaro.org>
Signed-off-by: Fabio Utzig <utzig@apache.org>
When generating dependencies, we were using the slot number instead of
the image number to determine which dependencies to mark invalid. Fix
this, so that we can test configurations where one image is upgradeable
and the other not.
Signed-off-by: David Brown <david.brown@linaro.org>
Signed-off-by: Fabio Utzig <utzig@apache.org>
Before running tests, a sanity upgrade was run to gather the amount of
flash writes to be expected for the operation. This operation fails when
the dependencies hold an upgrade, so the checks were updated to avoid
aborting under those circumstances.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Decode the MCUBOOT_DEBUG_DUMP environment variable into a series of
comma-separated strings, and create debug dumps for any test that
matches one of these strings. Also, the special string 'all' will match
every test, causing every image under test to be dumped.
The dumped images will contain an atomic counter, so that all of the
generated files will be unique for a given run.
Signed-off-by: David Brown <david.brown@linaro.org>
Add a `debug_dump()` method to `Images` to allow the images to be
written to a file. The dependency test will call this if the
environment variable MCUBOOT_DEBUG_DUMP is set.
In order to make these debug dumps more useful, add a simple partition
table to the beginning of the image (where MCUboot would reside on
target). This has a simple header, and then entries for each partition,
using the partition ids used within the simulator. This allows the
image to be more easily used by external tools.
As an example, `scripts/mcubin.bt` is a binary template for the [010
Editor](https://www.sweetscape.com/010editor/), allowing it to decode
and show the details of images from MCUboot.
Signed-off-by: David Brown <david.brown@linaro.org>
With the recent changes in bootutil, now there is no need to lock the
test threads to run sequentially, so the global lock was removed. The
locking now happens to access resources such as flash, flash params,
simulator context, etc on a per thread basis. Some of the global
variables that were used by the simulator itself (FFI) were made into a
context struct passed in to invoke_go.
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>
There are three methods that verify multiple images that essentially
manually implement the `all` and `any` methods of `Iterator`. It makes
it difficult to understand what these do, as there is an early return of
true or false, with various negations of the check.
Replace these with calls directly to `any` or `all` so that it is
clearer what each function is doing. The generated code should be the
same.
Signed-off-by: David Brown <david.brown@linaro.org>
Rather than just make the test images entirely pseudorandom data, add a
small textual header to the front that describes some key information
about each image. This can be helpful when debugging, to determine what
exactly is in each image slot.
Signed-off-by: David Brown <david.brown@linaro.org>
Create a trait `Depender` which is passed down to the image create and
verification to check and test for various types of dependency
resolution. Add a test that uses this to test the simple case of unmet
dependencies preventing an upgrade.
The actual test is disabled (with an `if false ...`) because the code
under test loops forever in this configuration.
Signed-off-by: David Brown <david.brown@linaro.org>
Instead of manually expanding multi-byte encoding, use the byteorder
crate which has its own extension methods to do this. This both makes
the code a bit clearer, and also makes it clear that these encodings are
specific to little endian platforms.
Signed-off-by: David Brown <david.brown@linaro.org>
Many places in the image code pass a pair of
slots: &[SlotInfo], slot: usize,
around as arguments. Simplify this by just passing a `&SlotInfo`. For
the few instances where code needs to know the index of a slot, add an
index field to the `SlotInfo` struct for these to use. This eliminates
an argument from 4 functions/methods, and the numerous places they are
called.
Signed-off-by: David Brown <david.brown@linaro.org>
Instead of a growing number of no-argument methods that just call other
methods with fixed arguments, change the `sim_test` macro to pass
through arguments to the test methods. This will make it easier to
further parameterize the test entrypoints.
Signed-off-by: David Brown <david.brown@linaro.org>
When doing a test with fails, the total number of flash accesses is
first calculated doing an upgrade without fails, which is then used to
fail/resume at all test points. The count was always considering the
setting of a permanent upgrade, which added 1 to the total count in a
non-permanent upgrade. This amount was being discounted when running
the test/revert with fails, although the discount was only ok for single
images. This adds a new image constructor that does not run a permanent
upgrade and thus gets the correct number of flash accesses for a
test/revert no matter how many images are being tested.
Signed-off-by: Fabio Utzig <utzig@apache.org>
This was previously removed because it failed on multi-image tests due
to some image having finished an upgrade and having it's flag already
set. A new method was added that checks that at least one copy_done flag
is unset, thus not all upgrades have finished.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Recent versions of the Rust compile tool `cargo` insert a comment at the
top of `Cargo.lock` indicating that this file is auto-generated. Commit
versions of these files with this comment in, so that users of recent
versions of Rust will not have sprious diffs everytime they compile.
Older versions of Rust will remove these lines. However, this is less
likely to be an issue, as we now depend on at least Rust 1.31 in order
to have Rust 2018 support. We recommend using 'rustup' to keep the Rust
install up to date.
Signed-off-by: David Brown <david.brown@linaro.org>
In case of multi image boot this check fails, because
copy_done flag set per images when an image swap has finished.
When second image update is interrupted then copy_done flag
already has set for first image.
Change-Id: Ic97dd5e4c5cdb5a5a94971f3ca84bfe0d7583dd4
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
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>
Support non-continuous image flash area ID mapping. It was assumed
that the flash area IDs are subsequent and increasing numbers which
might not be true in all cases.
Change-Id: I0d1285d6fcf1e83a64611c9ad4f65abd002c25d3
Signed-off-by: David Vincze <david.vincze@arm.com>
This extends the test+revert case with an interruption on the revert
stage, as it was previously only interrupted on the test stage. For
simplicity the interruption happens on the same interruption point for
both test and revert stages.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Signed-off-by: Christopher Collins <ccollins@apache.org>
Make images slightly larger to allow more swap status metadata to be
written to flash, to increase amount of debugging info and possibility
of failures on random write fails.
Signed-off-by: Fabio Utzig <utzig@apache.org>
Signed-off-by: Christopher Collins <ccollins@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>
This device is similar to the K64f device, but it is twice as large, and
has the extra partitions needed to test multi-image.
Signed-off-by: David Brown <david.brown@linaro.org>
Construct the ImagesBuilder based on the number of images compiled into
the code. If the flash device doesn't have enough areas for the test,
the test will be skipped.
Extend the FlashId to include Image2, and Image3. Remove the unused
ones, so that these can be placed immediately after the scratcharea.
The current simulator code assumes the flash areas are numbered
contiguously, requiring these extraneous partitions to be eliminated.
Signed-off-by: David Brown <david.brown@linaro.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>
Some of the simulated devices aren't large enough to support the 5 slots
needed to test a multi-image configuration. To allow this to work, make
the return from the `ImagesBuilder` return an option, so that it will be
able to indicate (with `None`) that this configuration isn't possible to
test, and that the test should be skipped.
Signed-off-by: David Brown <david.brown@linaro.org>
The Rust community has decided that 'failure' is the future, instead of
'error-chain'. Migrate the flash simulator to this new error handling
package. The changes are relatively minor, and the end result is a
similar `FlashError` type.
Signed-off-by: David Brown <david.brown@linaro.org>
Move the three fields associated with each "Image" into a substructure
where we can have an array. If the array size is 1, the behavior should
be identical to the previous behavior, but this will make it possible to
support multiple images just by creating more than one of these.
Signed-off-by: David Brown <david.brown@linaro.org>
The functions `try_upgrade`, `try_revert`, `try_revert_with_fail_at`,
and `try_random_fails` make more sense as methods. Move them into the
`Images` impl so they have access to `self` and some various fields.
Signed-off-by: David Brown <david.brown@linaro.org>
The name `SimFlashMap` is a bit misleading, as the Map part is more of
an implementation detail when the type really just represents multiple
flash devices.
This is just a rename, but the names `SimFlashMap` and the value
`flashmap` occur in a lot of places in the image module.
Signed-off-by: David Brown <david.brown@linaro.org>
Create an `ImageData` type to represent the stored content of a single
slot. This holds plaintext and optional ciphertext. This fixes a bit
of unclarity with regards to these fields:
- Before, the plaintext was an Option, even though it is always
present. The field is clearly always present now.
- The mapping between slot numbers, and plain and ciphertext was not
made clear. Now that is spelled out in a match statement.
- The type has a name, rather than an anonymous array that looked a
bit too much like it had to do with slot numbers.
Signed-off-by: David Brown <david.brown@linaro.org>
Rename `Run` to `ImagesBuilder`, and move its definition into the
`images` module. This makes much more of the functionality local to
this module. With this locality, all of the fields of `Images` can now
be made private making it easier to add future support for multiple
images.
Signed-off-by: David Brown <david.brown@linaro.org>
Rust convention is to have types before implementation. Move `Images`
up to the top to make it more prominent. This is also a good
opportunity to add a bit of a comment to this struct.
Signed-off-by: David Brown <david.brown@linaro.org>