Commit Graph

174 Commits

Author SHA1 Message Date
Marti Bolivar c0b47916f5 bootutil: keep image areas open while bootloading
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>
2017-06-15 13:24:15 -04:00
Marti Bolivar ea08887858 bootutil: add image and area offset abstractions
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>
2017-06-15 13:24:15 -04:00
Marti Bolivar cca28a9a56 bootutil: add abstraction for area initialization
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>
2017-06-15 13:24:15 -04:00
Marti Bolivar d3269fd67c bootutil: add accessors for sector size and number
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>
2017-06-15 13:24:14 -04:00
Marti Bolivar e258715a2a bootutil: add flash device ID accessor
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
2017-06-15 13:24:14 -04:00
Marti Bolivar f804f62e1f bootutil: add private image header accessor
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
2017-06-15 13:24:14 -04:00
Marti Bolivar 9b1f8bb553 bootutil: move loader state definition to private header
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>
2017-06-15 13:24:14 -04:00
David Brown cdb968f70a rsa: Allow RSA key to be larger than we need
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.
2017-06-13 16:02:48 -04:00
David Brown f4e904d4be rsa: Add support for RSA-PSS
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.
2017-06-13 16:02:48 -04:00
Fabio Utzig b119424aa8 Merge pull request #64 from utzig/fix-build-config-leftovers
Fix some leftovers after mynewt move (PR #52)
2017-06-13 13:16:04 -03:00
David Brown d6369707b9 Merge pull request #63 from utzig/fix-tinycrypt-dependency
Fix importing tinycrypt dependency on mynewt
2017-06-13 12:14:13 -04:00
David Brown 9ebd1f5a38 Merge pull request #51 from d3zd3z/pr/logging
sim: Allow Rust logging level to control C logging
2017-06-13 12:09:26 -04:00
Fabio Utzig 3488eef598 Fix some leftovers after mynewt move (PR #52)
- caps.c was now updated (missed this one!).
- *_OVERWRITE_ONLY flag was now also updated.
2017-06-12 10:25:43 -03:00
Fabio Utzig 32befd5cb4 Fix importing tinycrypt dependency on mynewt 2017-06-12 10:08:43 -03:00
Fabio Utzig eed80b65a0 Fix broken Mynewt BOOTUTIL_ -> MCUBOOT_ mapping
Fix mapping of syscfg.yml BOOTUTIL_* vars to C #defines, which was broken
on most .c files for lacking inclusion of mynewt "config.h"
2017-06-10 08:03:05 -03:00
Fabio Utzig 19356bf45f Make mcuboot less mynewt style
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.
2017-06-02 10:55:27 -07:00
Fabio Utzig 9678c97128 Add comment about trailer swap logic 2017-05-24 09:16:15 -04:00
Fabio Utzig de8a38abb3 Use better naming for flags 2017-05-24 09:16:15 -04:00
Fabio Utzig 34e393ee2d Remove newline from log message 2017-05-24 09:16:15 -04:00
Fabio Utzig acfba2e86e Fix for boot_read_swap_state_by_id to close flash area on errors 2017-05-24 09:16:15 -04:00
Fabio Utzig 856f783d7d Fix some error return codes 2017-05-24 09:16:14 -04:00
Fabio Utzig 94d998c61b Remove special cases, non needed tests 2017-05-24 09:16:14 -04:00
Fabio Utzig 4cee4f758f Move trailer status size calculation to its own function 2017-05-24 09:16:14 -04:00
Fabio Utzig ba49f84f03 Add macros for image ok values 2017-05-24 09:16:14 -04:00
Fabio Utzig 2473ac0e5b Add support for swapping only fw sectors in use
Before this patch, the swapping would process all sectors in a slot
not matter what the size of the binary firmware was. This changes the
swap process to swap only sectors that are in use by firmware.

Also, if the last slot sector, which stores the trailer, is actually not
in use by the binary firmware, now trailer is never written to scratch.
`use_scratch` temp variable was added to boot_status struct to control
this (this var is never written to disk).

Random other small refactorings were applied.
2017-05-24 08:58:59 -04:00
Fabio Utzig 7ebb7c23d9 Update how trailer is handled during a swap
Before this change, trailer was handled as part of the binary image,
which during a swap was just copied around together with the image.
This had issues if some fault happened while the trailer copy was
underway.

This patch changes how trailer is handled by making by non-copying.
The trailer is now updated step-by-step based on the current status.
Magic, copy_done and image_ok are also handled by writing them
individually, not by copying.

The trailer on scratch area was reduced to include at most swap state for
one sector, since it is only used temporarily while erasing the last
sector of the slot that stores the final trailer.

Many other small fixes were applied.
2017-05-24 08:45:53 -04:00
Fabio Utzig afc517e4b8 Move signed image doc to docs dir 2017-05-17 19:37:41 -04:00
David Brown b706777993 log: fix message for "info" logs in sim
Messages logged at "info" level were printing as "WRN" which was
misleading.
2017-05-11 09:20:02 -06:00
David Brown 51b6b81b47 sim: Set compiled log level to INFO
In order to allow messages to be printed, set the compiled level to
INFO.  This allows messages at this level to be printed without having
to recompile.
2017-05-11 09:17:03 -06:00
David Brown 2d1d7cfd47 sim: Allow Rust logging level to control C logging
Change the C logging code, when in the simulator, to query what the rust
logging level is set to.  This allows the level of logging from the C
code to be set through the environment.  For example

    RUST_LOG=bootsim=info cargo run --release runall

will enable logging at the "info" level for all of the C code as well as
the simulator code.  The C code's logging can be selected specifically
by using bootsim::api instead of just bootsim in the above.
2017-05-11 09:17:03 -06:00
David Brown 17609d8a7e Add "upgrade only" support
Add a configuration option "BOOTUTIL_OVERWRITE_ONLY" that avoids using
the image swap code.  Instead, when an upgrade is detected in slot 1, it
is copied directly onto slot 0.  As long as the image in slot 1 is
valid, this should work robustly (it will redo it if power is lost
during the upgrade).

This doesn't protect against the case of deploying an image that fails
to boot on some devices.  But, the behavior is similar to the swap
upgrade approach when the slot 1 image is marked initially as "image
ok", but without the complexity (or need of a swap partition) of the
swap code.
2017-05-10 08:33:19 -06:00
David Brown 902d617687 Add capabilities query
Add a simple function to query the bootloader for capabilities.
Ultimately, this API should be available to the running app, but the
simulator can use this to determine what to test.
2017-05-10 08:32:42 -06:00
David Brown 585fa14456 logging: Simplify sim logging
Instead of a separate invocation of printf to print the trailing
newline, use some modern cpp trickery to expand the format string
explicitly.  The ## will remove the preceding comma of the argument list
if empty.
2017-05-05 11:07:42 -06:00
David Brown 75fd5dc05e sim: Generate logging within the sim
Add logging support for when running in the simulator.  Log messages are
still based on compile-time determinations, and log using printf.

Based on a patch from Marti Bolivar <marti.bolivar@linaro.org>.
2017-05-05 11:07:42 -06:00
David Brown a5c12c6ad7 Merge pull request #44 from utzig/create-doc
Move design doc to doc dir
2017-05-01 09:38:38 -06:00
Fabio Utzig 9d6ee9de31 Move design doc to doc dir 2017-05-01 07:41:59 -03:00
David Brown e629bf3745 Generalize SHA256 code to allow tinycrypt support
When building with ECDSA P-256 as the signature algorithm, we are still
bringing in SHA256 and some ASN.1 code from mbed TLS.  Fix part of this
by wrapping the hash functions with general routines (inline functions)
allowing to select between mbed TLS and Tinycrypt for the
implementation.

Update the Zephyr config files so that the Tinycrypt version is used
when building the ECDSA P-256 signing variant.
2017-04-27 16:31:12 -06:00
David Brown d7e350df7d zephyr: Fix up mbed TLS configuration
There are some problems with how mbed TLS is configured in Zephyr.
First, include the makefile stub in the Makefile that uses these
defines.  This makes sure the right definitions get made so that our
custom config gets used for all compiled files, rather than a mixed set.

Also, fix up the wrappers on the custom configs so that each is
different, making it easier to detect if multiple configs are being
included.

Lastly, only include the right header in the image validation.  The mbed
TLS includes don't seem to want to allow both RSA and ECDSA to be used
(due to the key size), and including the wrong header results in a
compilation error.
2017-04-27 16:31:04 -06:00
David Brown 3e1c38c624 Merge pull request #38 from utzig/magic-sz-const
Use constant for magic size
2017-04-25 15:01:24 -06:00
Fabio Utzig 24a273d451 Use constant for magic size
- This also fixes an issue that could arrive if the magic is only partly
  erased.
2017-04-20 08:21:31 -03:00
Fabio Utzig 644b8d4f06 Make max align size a #define 2017-04-20 07:56:05 -03:00
Fabio Utzig fb291e4467 Add descriptions to syscfg.yml options 2017-04-11 16:20:16 -03:00
David Brown e482000015 Merge pull request #21 from ccollins476ad/assert-flash-ops
Assert flash ops
2017-03-14 17:42:35 +01:00
Fabio Utzig 150ea968e2 Add new ECDSA256 flags to design 2017-03-08 11:25:09 -03:00
Christopher Collins 4772ac4464 Assert flash ops succeed during swap.
Previously, the return of boot_swap_sectors() was discarded.  If a flash
operation failed, this information was lost.

Now, boot_swap_sectors() returns void.  Rather than returning a result,
success is asserted for all flash operations during function execution
(boot_copy_sector() and boot_erase_sector()).
2017-02-27 20:10:50 -08:00
Christopher Collins abfd75b144 Remove dead code. 2017-02-27 20:07:51 -08:00
David Brown b38e04494b Fix slot0 validation
commit d930ec69c8
    Author: David Brown <david.brown@linaro.org>
    Date:   Wed Dec 14 07:59:48 2016 -0700

        Validate slot zero before booting

adds a feature to validate slot 0 before booting it.  However, there
is an error in the logic, and if the magic number is written to an
invalid value, but not all 0xFF, it will consider any image to be
valid.

Fix this logic so that slot zero is always validated.
2017-02-24 17:31:21 -07:00
Christopher Collins 871054f067 This closes #11.
Merge remote-tracking branch 'd3zd3z/zephyr'

* d3zd3z/zephyr:
  zephyr: Make makefile clearer about configuration
  zephyr: Support RSA, and ECDSA P-256 signing
  bootutil: ecdsa P-256: Fix handling of sizes
2017-02-09 15:25:16 -08:00
Marti Bolivar fd20c7652a bootutil: log the boot source
Use the bootutil_log.h APIs to log the boot source chosen by the
loader, as well as the image trailer state that led it to its
conclusion.

Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
2017-02-07 16:59:50 -05:00
Marti Bolivar d652f27470 bootutil: add logging
This patch adds platform-independent logging to bootutil.

When bootutil is compiled as part of an application, the
application environment can provide logging hooks using this
file. Initially, hooks for Zephyr are provided. When built for
simulation or unit testing, the logging macros produce no
code (the ignore.h used by mynewt is used to avoid unused
variable warnings in this case).

Before including this file, users may define BOOT_LOG_LEVEL.  If
they do, it must be one of BOOT_LOG_LEVEL_OFF,
BOOT_LOG_LEVEL_ERROR, ..., BOOT_LOG_LEVEL_DEBUG. This determines
the log level for the current translation unit. If they do not, a
default log level is determined in a target-specific way.

After including bootutil_log.h, the macros BOOT_LOG_ERR(),
BOOT_LOG_WRN(), etc. may be used to log messages. These take
printf-like arguments.

Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
2017-02-07 16:59:50 -05:00
David Brown 3869e76090 zephyr: Support RSA, and ECDSA P-256 signing
Make it clear in the top-level Makefile how to configure mcuboot for
Zephyr for a particular signing algorithm.  Currently supported, are the
RSA signatures, and ECDSA with the P-256 curve.  These configuration
lines will select the code built in the bootloader, as well as which
public key gets included with the image.

This also adds a demo public key for the P-256 signatures.
2017-02-02 08:39:18 -07:00
David Brown d930ec69c8 Validate slot zero before booting
Instead of just checking the upgrade image signature, check the
signature on each boot.  This helps to prevent rogue images being flash
by a means other than the upgrade process.

This feature is controlled by whether BOOTUTIL_VALIDATE_SLOT0 is
defined.
2017-02-02 08:39:00 -07:00
David Brown baff96ff23 bootutil: ecdsa P-256: Fix handling of sizes
The ECDSA signature is written as two DER-encoded INTEGERS.  Although
the values are always 256 bits, the encoding ends up being variable
length, because the encoding is signed, and therefore needs an extra
zero byte to keep the number positive.  This means that the length can
vary by up to two bytes.

The 'newt' tool handles this for signature by allowing space for the
largest encoding, and padding with one or two zeros.  However, the
bootutil image check code insists that the length is exact, resulting in
a decoding error on about 3/4 signatures.

Fix this by only verifying that we have at least enough payload to hold
the signature.  There are later checks that will fail if the integers
themselves are too large.
2017-02-02 08:28:40 -07:00
David Brown 9d72546f02 bootutil: Fix issue with align > 1
Some flash devices not only require writes to occur on an `align` byte
boundary, but also require that the writes be done in chunks of this
size as well.  Enhance the sections that write status bytes to write
more than a single status byte.
2017-01-23 16:01:02 -07:00
Ricardo Salveti a2d5b1ac2d image_rsa: include missing string.h
Avoid warning when using memcmp.

Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
2017-01-19 19:51:01 -02:00
Christopher Collins 034a62016d bootutil - Fix warning on 64-bit architectures. 2017-01-11 12:20:22 -08:00
Christopher Collins 0960365ba4 Revert "boot - don't interpet end of image as trailer."
This reverts commit 920fc16b89.

The boot loader records its current state in the form of a pair of image
trailers, each located at the end of the corresponding image slot.  If
an image is so big that it extends into the trailer space of a slot, the
boot loader would read the end of the image and interpet it as the start
of a trailer.  The fix was to determine the size of each image upfront
by reading their headers, and only attempt to read an image's trailer if
the image is small enough that it doesn't extend into the trailer space.
If an image is too big to allow for a trailer, the boot loader fails
over to its "rescue mode": just boot into whatever is in slot 0.

The problem arises when the boot loader reads the image headers.  There
are certain points during a swap when an image header is not in the
expected location.  That is, if the device reboots at the wrong time
during an image swap, the boot loader will fail to read the image
headers when it comes up.

The image sectors are swapped in reverse order.  When a swap is
performed, the final sectors of each slot are swapped first, and the
first sectors (containing the image headers) get swapped last.  During
the final swap operation, there are two points at which the image
headers are not in the expected place:

    1. slot 1 erased; header 1 in scratch area.
    2. slot 0 erased; header 0 in scratch area.

In each case, the image header is not actually missing.  Rather, the
boot loader is just looking in the wrong place.  It should be looking in
the scratch area, not the start of the image slot.

The fix is to revert the original commit.  Now, the boot loader won't
fail when an image header read fails.  It is the user's responsibility
to ensure an image isn't too big.
2017-01-10 15:52:53 -08:00
Christopher Collins 4c2662d811 This closes #1.
Merge remote-tracking branch 'd3zd3z/zephyr'
2017-01-06 14:02:06 -08:00
David Brown 5315d50a0c bootutil: Create Zephyr Makefile
Create a small Makefile for the Zephyr build system to use.
2017-01-06 11:08:03 -07:00
David Brown db1d9d38e2 loader: Remove malloc dependency
Allocate a static tmpbuf instead of calling malloc.  This is the only
direct call to malloc in the code.
2017-01-06 11:07:54 -07:00
Marko Kiiskila bd14468fd8 bootutil; need to include string.h when building for native. 2017-01-05 17:57:51 -08:00
Marko Kiiskila 755daedde9 bootutil; fix issues in parsing signature with ECDSA256. 2017-01-05 17:57:51 -08:00
Marko Kiiskila 8eeba12f2a bootutil; add info about how to create keys for ECC 256. 2017-01-05 17:57:51 -08:00
Marko Kiiskila 351a0b231b boot; drop unnecessary include from image_ec.c. 2017-01-05 17:57:51 -08:00
Marko Kiiskila bf94339025 boot; first cut at adding support for signatures with ECSDA using NIST P-256. 2017-01-05 17:57:46 -08:00
Marko Kiiskila 919eaf4111 signed_images.md; include ECC key generation steps in the doc. 2017-01-05 17:56:50 -08:00
Christopher Collins 920fc16b89 boot - don't interpet end of image as trailer.
This fix handles the case where the image is so big that there is not
room for a trailer.  In this case, the boot loader always boots into
slot 0.
2017-01-05 17:56:50 -08:00
Christopher Collins fd7eb5cc5e MYNEWT-518 - Clean up previous commit.
The previous commit for this ticket left the code in a working state.
However, it was not possible for image management to distinguish between
the test and permanent states.

Now, these two states are indicated by the addition of a new swap type:
BOOT_SWAP_TYPE_PERMANENT.
2017-01-05 17:56:50 -08:00
Christopher Collins 553ba4feb2 MYNEWT-518 Update comments and design doc. 2017-01-05 17:56:50 -08:00
Christopher Collins 0ff3c6c033 MYNEWT-520 boot - Allow incompatible image slots 2017-01-05 17:56:50 -08:00
Christopher Collins 7835c1e4db MYNEWT-518 boot - Allow test+confirm as single act
Currently, to permanently run the alternate image, the boot loader
requires the following sequence:

1. image test <slot-01-hash>
2. reboot
3. image confirm

The new feature is to remove the need for the third step. The user
should be able to permanently switch images with this sequence:

1. image confirm <slot-01-hash>
2. reboot
2017-01-05 17:56:50 -08:00
Marko Kiiskila bf986da2c3 bootutil; update signed_images.md with the new location of bootutil. 2017-01-05 17:56:40 -08:00
Christopher Collins 3569c37894 bootutil tests - Don't assume min-write-sz==1. 2016-12-13 14:52:19 -08:00
Christopher Collins 39a5fa95c3 Move packages into "boot" top-level directory. 2016-12-12 17:51:23 -08:00