Commit Graph

215 Commits

Author SHA1 Message Date
David Brown f984b95735 Move mbedtls submodule from sim to ext
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>
2019-10-15 09:29:20 -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
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 2f6c164f9a sim: fix flash padding to use erased val
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-10-01 18:30:05 -03:00
Fabio Utzig ea3d3abe5f sim: add protected TLVs to hash calculation
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
David Brown e4576b888c sim: Test variants of single upgrade with multi-image
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>
2019-09-09 10:00:09 -03:00
David Brown 873be31d5e sim: Add OldCorrect and NoUpgrade dependency types
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>
2019-09-09 10:00:09 -03:00
David Brown 0e6bc7fe1c sim: Fix upgrade check
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>
2019-09-09 10:00:09 -03:00
David Brown 207c457dc6 sim: Derive PartialEq and Eq for UpgradeInfo
This will allow comparisons of the upgrade info.

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
David Brown 18d301f588 sim: Add additional tests for mismatched upgrades
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>
2019-09-09 10:00:09 -03:00
David Brown 179098888c sim: Use image number instead of slot in dep test
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>
2019-09-09 10:00:09 -03:00
Fabio Utzig 135f716bfb Uncomment hold and add correct upgrades
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-09-09 10:00:09 -03:00
Fabio Utzig 7c1d1557f2 Do not panic when upgrade info tells to hold
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>
2019-09-09 10:00:09 -03:00
David Brown fe5ab1c35b sim: Generalize test image dumping
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>
2019-08-15 14:23:37 -05:00
David Brown 297029ab72 sim: Add debugging ptable to image dumps
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>
2019-08-15 14:23:37 -05:00
Fabio Utzig 8000e325f1 Remove global test thread locking
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>
2019-08-07 14:33:36 -03:00
Fabio Utzig b0f0473352 Remove current_image global and macro updates
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>
2019-08-07 14:33:36 -03:00
David Brown f9aec954e3 sim: Simplify verification methods
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>
2019-08-07 11:30:05 -05:00
David Brown cb47dd7415 sim: Add a readable header to test images
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>
2019-08-06 11:26:09 -05:00
David Brown c3898d6168 sim: Add dependency tests to simulator
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>
2019-08-06 11:26:09 -05:00
David Brown 7a81c4b61f sim: Add dependency encoding to TLV generator
The dependencies are kind of a special case, since they have to be
protected by the hashes.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-08-06 11:26:09 -05:00
David Brown 91d6863edc sim: Use byteorder for multi-byte values
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>
2019-08-06 11:26:09 -05:00
David Brown 3b09021269 sim: Simplify `slot` parameters
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>
2019-07-31 09:59:53 -05:00
David Brown eebf502277 sim: Allow arguments to test entrypoints
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>
2019-07-31 09:59:53 -05:00
Fabio Utzig ed4a53635a Fix test/revert upgrade flash count
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>
2019-07-30 11:39:09 -05:00
Fabio Utzig 8af7f793ae Add copy_done check after first boot
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>
2019-07-30 11:39:09 -05:00
David Brown 1e1be9b368 Update Cargo.lock files
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>
2019-07-25 16:24:20 -05:00
Tamas Ban 0c9266f66a sim: Remove copy_done check from revert_with_fails test
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>
2019-07-23 09:11:34 -05:00
David Vincze b75c12a431 Boot: Extend flash layout for multiple images
This patch introduces the BOOT_IMAGE_NUMBER macro and current_image
variable to support multiple updatable images and the associated
extended flash layout.

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

Change-Id: Ib7b26ec3c94233e52db4f97825ddb6a3e55bb1d3
Signed-off-by: David Vincze <david.vincze@arm.com>
2019-07-23 09:11:34 -05:00
David Vincze 6c9b416cd8 sim: Support non-continuous area ID mapping
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>
2019-07-23 09:11:34 -05:00
Fabio Utzig 9771028579 Add ed25519 verification to sim
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-06-13 19:21:05 -03:00
Fabio Utzig fc07eab118 Add interruption at revert step of a test+revert
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>
2019-05-31 10:15:08 -07:00
Fabio Utzig 28d012c1c5 Increase size of swap testing images
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>
2019-05-31 10:15:08 -07:00
Christopher Collins a1c1204f65 Fix double swap on interrupted revert
This fixes #480.

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

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

```
     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                                                               ~
    ~    Swap status (BOOT_MAX_IMG_SECTORS * min-write-size * 3)    ~
    ~                                                               ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                 Encryption key 0 (16 octets) [*]              ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                 Encryption key 1 (16 octets) [*]              ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           Swap size           |    0xff padding (4 octets)    |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Swap type   |           0xff padding (7 octets)             ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Copy done   |           0xff padding (7 octets)             ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |   Image OK    |           0xff padding (7 octets)             ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ~                       MAGIC (16 octets)                       ~
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

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

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

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

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

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

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

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

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

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

Signed-off-by: Christopher Collins <ccollins@apache.org>
2019-05-31 10:15:08 -07:00
Fabio Utzig 3929743408 Add simulator support for RSA-3072 sigs
Signed-off-by: Fabio Utzig <utzig@apache.org>
2019-05-16 14:01:19 -03:00
David Brown 5e6f5e0165 sim: Add multi-image config support to sim
Add support for building with multiple images to the simulator.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-04-17 11:20:21 +07:00
David Brown 2bff647d8f sim: Add a K64fMulti flash device
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>
2019-04-17 11:20:21 +07:00
David Brown 06ef06e69c sim: Base slots on number of images used
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>
2019-04-17 11:20:21 +07:00
David Brown 4c9883b0d8 Add a capability query for image number
In addition to the binary capability flags, add a query function that
returns the number of images MCUboot has been configured to support.

Signed-off-by: David Brown <david.brown@linaro.org>
2019-04-17 11:20:21 +07:00
David Brown 5bc62c6b73 sim: Make the test builder optional
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>
2019-04-17 11:20:21 +07:00
David Brown 96eb0deb76 sim: simflash: Transition to failure
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>
2019-04-17 11:20:21 +07:00
David Brown 84b49f751e sim: Internal support for multiple images
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>
2019-04-17 11:20:21 +07:00
David Brown db505823a4 sim: Make various functions into methods
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>
2019-04-17 11:20:21 +07:00
David Brown 761015712c sim: Rename `SimFlashMap` to `SimMultiFlash`
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>
2019-04-17 11:20:21 +07:00
David Brown ca23469e82 sim: Create an `ImageData` type
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>
2019-04-17 11:20:21 +07:00
David Brown e513324722 sim: Make `Run` into a proper builder
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>
2019-04-17 11:20:21 +07:00
David Brown 998aa8d220 sim: Move `Images` to before code
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>
2019-04-17 11:20:21 +07:00