diff --git a/.travis.yml b/.travis.yml index 87ba9f2ff..042970fb7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,56 +2,63 @@ language: rust -cache: cargo +cache: + directories: + - $HOME/TOOLCHAIN + - cargo matrix: include: # Runs each value defined in $SINGLE_FEATURES by itself in the order # the were defined. - os: linux - env: SINGLE_FEATURES="sig-ecdsa enc-kw bootstrap" + env: SINGLE_FEATURES="sig-ecdsa enc-kw bootstrap" TEST=sim - os: linux - env: SINGLE_FEATURES="none sig-rsa overwrite-only validate-slot0" + env: SINGLE_FEATURES="none sig-rsa overwrite-only validate-primary-slot" TEST=sim - os: linux - env: SINGLE_FEATURES="enc-rsa" + env: SINGLE_FEATURES="enc-rsa" TEST=sim # Values defined in $MULTI_FEATURES consist of any number of features # to be enabled at the same time. The list of multi-values should be # separated by ',' and each list of values is run sequentially in the # defined order. - os: linux - env: MULTI_FEATURES="sig-rsa overwrite-only,sig-ecdsa overwrite-only" + env: MULTI_FEATURES="sig-rsa overwrite-only,sig-ecdsa overwrite-only" TEST=sim - os: linux - env: MULTI_FEATURES="sig-rsa validate-slot0,sig-ecdsa validate-slot0" + env: MULTI_FEATURES="sig-rsa validate-primary-slot,sig-ecdsa validate-primary-slot" TEST=sim - os: linux - env: MULTI_FEATURES="enc-kw overwrite-only,enc-rsa overwrite-only" + env: MULTI_FEATURES="enc-kw overwrite-only,enc-rsa overwrite-only" TEST=sim - os: linux - env: MULTI_FEATURES="sig-rsa enc-rsa validate-slot0" + env: MULTI_FEATURES="sig-rsa enc-rsa validate-primary-slot" TEST=sim - os: linux - env: MULTI_FEATURES="sig-rsa enc-kw validate-slot0 bootstrap" + env: MULTI_FEATURES="sig-rsa enc-kw validate-primary-slot bootstrap" TEST=sim - os: linux - env: MULTI_FEATURES="sig-ecdsa enc-kw validate-slot0" + env: MULTI_FEATURES="sig-ecdsa enc-kw validate-primary-slot" TEST=sim # FIXME: this test actually fails and must be fixed #- os: linux - # env: MULTI_FEATURES="sig-rsa validate-slot0 overwrite-only" + # env: MULTI_FEATURES="sig-rsa validate-primary-slot overwrite-only" + + - os: linux + language: go + env: TEST=mynewt + go: + - "1.10" before_install: - | if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then - ./scripts/check-signed-off-by.sh + ./ci/check-signed-off-by.sh if [ $? -ne 0 ]; then exit 1 fi fi install: - - pushd sim - - cargo fetch - - popd + - ./ci/${TEST}_install.sh script: - - ./scripts/run_tests.sh + - ./ci/${TEST}_run.sh notifications: slack: diff --git a/boot/boot_serial/test/pkg.yml b/boot/boot_serial/test/pkg.yml index c2de66736..d0b91f73c 100644 --- a/boot/boot_serial/test/pkg.yml +++ b/boot/boot_serial/test/pkg.yml @@ -30,3 +30,6 @@ pkg.deps: pkg.deps.SELFTEST: - "@apache-mynewt-core/sys/console/stub" + +pkg.cflags: + - '-DMCUBOOT_MYNEWT' diff --git a/boot/boot_serial/test/src/boot_test.h b/boot/boot_serial/test/src/boot_test.h index 402d5b145..2139d9f47 100644 --- a/boot/boot_serial/test/src/boot_test.h +++ b/boot/boot_serial/test/src/boot_test.h @@ -33,11 +33,12 @@ #include "testutil/testutil.h" #include "hal/hal_flash.h" #include "flash_map_backend/flash_map_backend.h" +#include "bootutil/bootutil.h" #include "boot_serial_priv.h" #ifdef __cplusplus -#extern "C" { +extern "C" { #endif void tx_msg(void *src, int len); diff --git a/boot/boot_serial/test/src/testcases/boot_serial_img_msg.c b/boot/boot_serial/test/src/testcases/boot_serial_img_msg.c index a1aaf2f02..e2c7dbde1 100644 --- a/boot/boot_serial/test/src/testcases/boot_serial_img_msg.c +++ b/boot/boot_serial/test/src/testcases/boot_serial_img_msg.c @@ -59,9 +59,9 @@ TEST_CASE(boot_serial_img_msg) tx_msg(buf, len); /* - * Validate contents inside image 0 slot + * Validate contents inside the primary slot */ - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); assert(rc == 0); rc = flash_area_read(fap, 0, enc_img, sizeof(img)); diff --git a/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c b/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c index 1f4aa09b7..506000dd3 100644 --- a/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c +++ b/boot/boot_serial/test/src/testcases/boot_serial_upload_bigger_image.c @@ -103,9 +103,9 @@ TEST_CASE(boot_serial_upload_bigger_image) } /* - * Validate contents inside image 0 slot + * Validate contents inside the primary slot */ - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); assert(rc == 0); for (off = 0; off < sizeof(img); off += sizeof(enc_img)) { diff --git a/boot/bootutil/include/bootutil/bootutil.h b/boot/bootutil/include/bootutil/bootutil.h index 5f6586616..3e9a835d3 100644 --- a/boot/bootutil/include/bootutil/bootutil.h +++ b/boot/bootutil/include/bootutil/bootutil.h @@ -26,13 +26,24 @@ extern "C" { #endif -/** Attempt to boot the contents of slot 0. */ +#if defined(MCUBOOT_MYNEWT) +#define FLASH_AREA_IMAGE_PRIMARY FLASH_AREA_IMAGE_0 +#define FLASH_AREA_IMAGE_SECONDARY FLASH_AREA_IMAGE_1 +#endif + +/** Attempt to boot the contents of the primary slot. */ #define BOOT_SWAP_TYPE_NONE 1 -/** Swap to slot 1. Absent a confirm command, revert back on next boot. */ +/** + * Swap to the secondary slot. + * Absent a confirm command, revert back on next boot. + */ #define BOOT_SWAP_TYPE_TEST 2 -/** Swap to slot 1, and permanently switch to booting its contents. */ +/** + * Swap to the secondary slot, + * and permanently switch to booting its contents. + */ #define BOOT_SWAP_TYPE_PERM 3 /** Swap back to alternate slot. A confirm changes this state to NONE. */ diff --git a/boot/bootutil/include/bootutil/caps.h b/boot/bootutil/include/bootutil/caps.h index 6376683b7..dc4ba4a9b 100644 --- a/boot/bootutil/include/bootutil/caps.h +++ b/boot/bootutil/include/bootutil/caps.h @@ -32,14 +32,14 @@ extern "C" { */ uint32_t bootutil_get_caps(void); -#define BOOTUTIL_CAP_RSA2048 (1<<0) -#define BOOTUTIL_CAP_ECDSA_P224 (1<<1) -#define BOOTUTIL_CAP_ECDSA_P256 (1<<2) -#define BOOTUTIL_CAP_SWAP_UPGRADE (1<<3) -#define BOOTUTIL_CAP_OVERWRITE_UPGRADE (1<<4) -#define BOOTUTIL_CAP_ENC_RSA (1<<5) -#define BOOTUTIL_CAP_ENC_KW (1<<6) -#define BOOTUTIL_CAP_VALIDATE_SLOT0 (1<<7) +#define BOOTUTIL_CAP_RSA2048 (1<<0) +#define BOOTUTIL_CAP_ECDSA_P224 (1<<1) +#define BOOTUTIL_CAP_ECDSA_P256 (1<<2) +#define BOOTUTIL_CAP_SWAP_UPGRADE (1<<3) +#define BOOTUTIL_CAP_OVERWRITE_UPGRADE (1<<4) +#define BOOTUTIL_CAP_ENC_RSA (1<<5) +#define BOOTUTIL_CAP_ENC_KW (1<<6) +#define BOOTUTIL_CAP_VALIDATE_PRIMARY_SLOT (1<<7) #ifdef __cplusplus } diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h index d2477ca38..0f4ab57cb 100644 --- a/boot/bootutil/include/bootutil/enc_key.h +++ b/boot/bootutil/include/bootutil/enc_key.h @@ -20,6 +20,7 @@ #ifndef BOOTUTIL_ENC_KEY_H #define BOOTUTIL_ENC_KEY_H +#include #include #include "mcuboot_config/mcuboot_config.h" #include "bootutil/image.h" @@ -51,7 +52,7 @@ extern const struct bootutil_key bootutil_enc_key; int boot_enc_set_key(uint8_t slot, uint8_t *enckey); int boot_enc_load(const struct image_header *hdr, const struct flash_area *fap, uint8_t *enckey); -int boot_enc_valid(const struct flash_area *fap); +bool boot_enc_valid(const struct flash_area *fap); void boot_encrypt(const struct flash_area *fap, uint32_t off, uint32_t sz, uint32_t blk_off, uint8_t *buf); void boot_enc_zeroize(void); diff --git a/boot/bootutil/include/bootutil/sha256.h b/boot/bootutil/include/bootutil/sha256.h index 63ad4800e..f82776135 100644 --- a/boot/bootutil/include/bootutil/sha256.h +++ b/boot/bootutil/include/bootutil/sha256.h @@ -31,12 +31,14 @@ #include "mcuboot_config/mcuboot_config.h" -#if defined(MCUBOOT_USE_MBED_TLS) && defined(MCUBOOT_USE_TINYCRYPT) - #error "Cannot define both MBED_TLS and TINYCRYPT" +#if (defined(MCUBOOT_USE_MBED_TLS) && defined(MCUBOOT_USE_TINYCRYPT))\ + ||(defined MCUBOOT_USE_MBED_TLS) && defined(MCUBOOT_USE_CC310)\ + ||(defined(MCUBOOT_USE_TINYCRYPT) && defined(MCUBOOT_USE_CC310)) + #error "Cannot define CC310, MBED_TLS and TINYCRYPT" #endif -#if !defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_TINYCRYPT) - #error "One of MBED_TLS or TINYCRYPT must be defined" +#if !defined(MCUBOOT_USE_MBED_TLS) && !defined(MCUBOOT_USE_TINYCRYPT) && !defined(MCUBOOT_USE_CC310) + #error "One of CC310, MBED_TLS or TINYCRYPT must be defined" #endif #ifdef MCUBOOT_USE_MBED_TLS @@ -47,6 +49,10 @@ #include #endif /* MCUBOOT_USE_TINYCRYPT */ +#ifdef MCUBOOT_USE_CC310 + #include +#endif /* MCUBOOT_USE_CC310 */ + #include #ifdef __cplusplus @@ -97,6 +103,26 @@ static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx, } #endif /* MCUBOOT_USE_TINYCRYPT */ +#ifdef MCUBOOT_USE_CC310 +static inline void bootutil_sha256_init(bootutil_sha256_context *ctx) +{ + cc310_sha256_init(ctx); +} + +static inline void bootutil_sha256_update(bootutil_sha256_context *ctx, + const void *data, + uint32_t data_len) +{ + cc310_sha256_update(ctx, data, data_len); +} + +static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx, + uint8_t *output) +{ + cc310_sha256_finalize(ctx, output); +} +#endif /* MCUBOOT_USE_CC310 */ + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/pkg.yml b/boot/bootutil/pkg.yml index 9a1ff7148..1837163d0 100644 --- a/boot/bootutil/pkg.yml +++ b/boot/bootutil/pkg.yml @@ -31,6 +31,9 @@ pkg.apis: pkg.cflags: - "-DMCUBOOT_MYNEWT" +pkg.cflags.BOOTUTIL_USE_MBED_TLS: + - '-DMBEDTLS_USER_CONFIG_FILE="mbedtls/config_mynewt.h"' + pkg.deps: - "@mcuboot/boot/mynewt/mcuboot_config" - "@apache-mynewt-core/hw/hal" diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 47b41fda3..514d6698e 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -51,11 +51,11 @@ const uint32_t BOOT_MAGIC_SZ = sizeof boot_img_magic; const uint32_t BOOT_MAX_ALIGN = MAX_FLASH_ALIGN; struct boot_swap_table { - uint8_t magic_slot0; - uint8_t magic_slot1; - uint8_t image_ok_slot0; - uint8_t image_ok_slot1; - uint8_t copy_done_slot0; + uint8_t magic_primary_slot; + uint8_t magic_secondary_slot; + uint8_t image_ok_primary_slot; + uint8_t image_ok_secondary_slot; + uint8_t copy_done_primary_slot; uint8_t swap_type; }; @@ -64,36 +64,37 @@ struct boot_swap_table { * This set of tables maps image trailer contents to swap operation type. * When searching for a match, these tables must be iterated sequentially. * - * NOTE: the table order is very important. The settings in Slot 1 always - * are priority to Slot 0 and should be located earlier in the table. + * NOTE: the table order is very important. The settings in the secondary + * slot always are priority to the primary slot and should be located + * earlier in the table. * * The table lists only states where there is action needs to be taken by * the bootloader, as in starting/finishing a swap operation. */ static const struct boot_swap_table boot_swap_tables[] = { { - .magic_slot0 = BOOT_MAGIC_ANY, - .magic_slot1 = BOOT_MAGIC_GOOD, - .image_ok_slot0 = BOOT_FLAG_ANY, - .image_ok_slot1 = BOOT_FLAG_UNSET, - .copy_done_slot0 = BOOT_FLAG_ANY, - .swap_type = BOOT_SWAP_TYPE_TEST, + .magic_primary_slot = BOOT_MAGIC_ANY, + .magic_secondary_slot = BOOT_MAGIC_GOOD, + .image_ok_primary_slot = BOOT_FLAG_ANY, + .image_ok_secondary_slot = BOOT_FLAG_UNSET, + .copy_done_primary_slot = BOOT_FLAG_ANY, + .swap_type = BOOT_SWAP_TYPE_TEST, }, { - .magic_slot0 = BOOT_MAGIC_ANY, - .magic_slot1 = BOOT_MAGIC_GOOD, - .image_ok_slot0 = BOOT_FLAG_ANY, - .image_ok_slot1 = BOOT_FLAG_SET, - .copy_done_slot0 = BOOT_FLAG_ANY, - .swap_type = BOOT_SWAP_TYPE_PERM, + .magic_primary_slot = BOOT_MAGIC_ANY, + .magic_secondary_slot = BOOT_MAGIC_GOOD, + .image_ok_primary_slot = BOOT_FLAG_ANY, + .image_ok_secondary_slot = BOOT_FLAG_SET, + .copy_done_primary_slot = BOOT_FLAG_ANY, + .swap_type = BOOT_SWAP_TYPE_PERM, }, { - .magic_slot0 = BOOT_MAGIC_GOOD, - .magic_slot1 = BOOT_MAGIC_UNSET, - .image_ok_slot0 = BOOT_FLAG_UNSET, - .image_ok_slot1 = BOOT_FLAG_ANY, - .copy_done_slot0 = BOOT_FLAG_SET, - .swap_type = BOOT_SWAP_TYPE_REVERT, + .magic_primary_slot = BOOT_MAGIC_GOOD, + .magic_secondary_slot = BOOT_MAGIC_UNSET, + .image_ok_primary_slot = BOOT_FLAG_UNSET, + .image_ok_secondary_slot = BOOT_FLAG_ANY, + .copy_done_primary_slot = BOOT_FLAG_SET, + .swap_type = BOOT_SWAP_TYPE_REVERT, }, }; @@ -157,8 +158,8 @@ int boot_status_entries(const struct flash_area *fap) { switch (fap->fa_id) { - case FLASH_AREA_IMAGE_0: - case FLASH_AREA_IMAGE_1: + case FLASH_AREA_IMAGE_PRIMARY: + case FLASH_AREA_IMAGE_SECONDARY: return BOOT_STATUS_STATE_COUNT * BOOT_STATUS_MAX_ENTRIES; case FLASH_AREA_IMAGE_SCRATCH: return BOOT_STATUS_STATE_COUNT; @@ -262,7 +263,8 @@ boot_read_swap_state(const struct flash_area *fap, } off = boot_image_ok_off(fap); - rc = flash_area_read_is_empty(fap, off, &state->image_ok, sizeof state->image_ok); + rc = flash_area_read_is_empty(fap, off, &state->image_ok, + sizeof state->image_ok); if (rc < 0) { return BOOT_EFLASH; } @@ -286,8 +288,8 @@ boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state) switch (flash_area_id) { case FLASH_AREA_IMAGE_SCRATCH: - case FLASH_AREA_IMAGE_0: - case FLASH_AREA_IMAGE_1: + case FLASH_AREA_IMAGE_PRIMARY: + case FLASH_AREA_IMAGE_SECONDARY: rc = flash_area_open(flash_area_id, &fap); if (rc != 0) { return BOOT_EFLASH; @@ -312,13 +314,13 @@ boot_read_swap_size(uint32_t *swap_size) /* * In the middle a swap, tries to locate the saved swap size. Looks - * for a valid magic, first on Slot 0, then on scratch. Both "slots" - * can end up being temporary storage for a swap and it is assumed - * that if magic is valid then swap size is too, because magic is - * always written in the last step. + * for a valid magic, first on the primary slot, then on scratch. + * Both "slots" can end up being temporary storage for a swap and it + * is assumed that if magic is valid then swap size is too, because + * magic is always written in the last step. */ - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); if (rc != 0) { return BOOT_EFLASH; } @@ -332,7 +334,7 @@ boot_read_swap_size(uint32_t *swap_size) if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) != 0) { /* - * If Slot 0 's magic is not valid, try scratch... + * If the primary slot's magic is not valid, try scratch... */ flash_area_close(fap); @@ -372,7 +374,7 @@ boot_read_enc_key(uint8_t slot, uint8_t *enckey) const struct flash_area *fap; int rc; - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); if (rc != 0) { return BOOT_EFLASH; } @@ -386,7 +388,7 @@ boot_read_enc_key(uint8_t slot, uint8_t *enckey) if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) != 0) { /* - * If Slot 0 's magic is not valid, try scratch... + * If the primary slot's magic is not valid, try scratch... */ flash_area_close(fap); @@ -528,17 +530,18 @@ int boot_swap_type(void) { const struct boot_swap_table *table; - struct boot_swap_state slot0; - struct boot_swap_state slot1; + struct boot_swap_state primary_slot; + struct boot_swap_state secondary_slot; int rc; size_t i; - rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_0, &slot0); + rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY, &primary_slot); if (rc) { return BOOT_SWAP_TYPE_PANIC; } - rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_1, &slot1); + rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SECONDARY, + &secondary_slot); if (rc) { return BOOT_SWAP_TYPE_PANIC; } @@ -546,16 +549,16 @@ boot_swap_type(void) for (i = 0; i < BOOT_SWAP_TABLES_COUNT; i++) { table = boot_swap_tables + i; - if ((table->magic_slot0 == BOOT_MAGIC_ANY || - table->magic_slot0 == slot0.magic) && - (table->magic_slot1 == BOOT_MAGIC_ANY || - table->magic_slot1 == slot1.magic) && - (table->image_ok_slot0 == BOOT_FLAG_ANY || - table->image_ok_slot0 == slot0.image_ok) && - (table->image_ok_slot1 == BOOT_FLAG_ANY || - table->image_ok_slot1 == slot1.image_ok) && - (table->copy_done_slot0 == BOOT_FLAG_ANY || - table->copy_done_slot0 == slot0.copy_done)) { + if ((table->magic_primary_slot == BOOT_MAGIC_ANY || + table->magic_primary_slot == primary_slot.magic) && + (table->magic_secondary_slot == BOOT_MAGIC_ANY || + table->magic_secondary_slot == secondary_slot.magic) && + (table->image_ok_primary_slot == BOOT_FLAG_ANY || + table->image_ok_primary_slot == primary_slot.image_ok) && + (table->image_ok_secondary_slot == BOOT_FLAG_ANY || + table->image_ok_secondary_slot == secondary_slot.image_ok) && + (table->copy_done_primary_slot == BOOT_FLAG_ANY || + table->copy_done_primary_slot == primary_slot.copy_done)) { BOOT_LOG_INF("Swap type: %s", table->swap_type == BOOT_SWAP_TYPE_TEST ? "test" : table->swap_type == BOOT_SWAP_TYPE_PERM ? "perm" : @@ -573,8 +576,8 @@ boot_swap_type(void) } /** - * Marks the image in slot 1 as pending. On the next reboot, the system will - * perform a one-time boot of the slot 1 image. + * Marks the image in the secondary slot as pending. On the next reboot, + * the system will perform a one-time boot of the the secondary slot image. * * @param permanent Whether the image should be used permanently or * only tested once: @@ -587,21 +590,22 @@ int boot_set_pending(int permanent) { const struct flash_area *fap; - struct boot_swap_state state_slot1; + struct boot_swap_state state_secondary_slot; int rc; - rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_1, &state_slot1); + rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SECONDARY, + &state_secondary_slot); if (rc != 0) { return rc; } - switch (state_slot1.magic) { + switch (state_secondary_slot.magic) { case BOOT_MAGIC_GOOD: /* Swap already scheduled. */ return 0; case BOOT_MAGIC_UNSET: - rc = flash_area_open(FLASH_AREA_IMAGE_1, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY, &fap); if (rc != 0) { rc = BOOT_EFLASH; } else { @@ -619,7 +623,7 @@ boot_set_pending(int permanent) /* The image slot is corrupt. There is no way to recover, so erase the * slot to allow future upgrades. */ - rc = flash_area_open(FLASH_AREA_IMAGE_1, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY, &fap); if (rc != 0) { return BOOT_EFLASH; } @@ -635,7 +639,9 @@ boot_set_pending(int permanent) } /** - * Marks the image in slot 0 as confirmed. The system will continue booting into the image in slot 0 until told to boot from a different slot. + * Marks the image in the primary slot as confirmed. The system will continue + * booting into the image in the primary slot until told to boot from a + * different slot. * * @return 0 on success; nonzero on failure. */ @@ -643,15 +649,16 @@ int boot_set_confirmed(void) { const struct flash_area *fap; - struct boot_swap_state state_slot0; + struct boot_swap_state state_primary_slot; int rc; - rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_0, &state_slot0); + rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY, + &state_primary_slot); if (rc != 0) { return rc; } - switch (state_slot0.magic) { + switch (state_primary_slot.magic) { case BOOT_MAGIC_GOOD: /* Confirm needed; proceed. */ break; @@ -665,19 +672,19 @@ boot_set_confirmed(void) return BOOT_EBADVECT; } - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); if (rc) { rc = BOOT_EFLASH; goto done; } - if (state_slot0.copy_done == BOOT_FLAG_UNSET) { + if (state_primary_slot.copy_done == BOOT_FLAG_UNSET) { /* Swap never completed. This is unexpected. */ rc = BOOT_EBADVECT; goto done; } - if (state_slot0.image_ok != BOOT_FLAG_UNSET) { + if (state_primary_slot.image_ok != BOOT_FLAG_UNSET) { /* Already confirmed. */ goto done; } diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index bc9c61f97..dba19c645 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -24,6 +24,7 @@ #include +#include "bootutil/bootutil.h" #include "bootutil/image.h" #include "mcuboot_config/mcuboot_config.h" @@ -129,18 +130,21 @@ struct boot_swap_state { #endif /** Number of image slots in flash; currently limited to two. */ -#define BOOT_NUM_SLOTS 2 +#define BOOT_NUM_SLOTS 2 /** Maximum number of image sectors supported by the bootloader. */ -#define BOOT_STATUS_STATE_COUNT 3 -#define BOOT_STATUS_MAX_ENTRIES BOOT_MAX_IMG_SECTORS +#define BOOT_STATUS_STATE_COUNT 3 +#define BOOT_STATUS_MAX_ENTRIES BOOT_MAX_IMG_SECTORS -#define BOOT_STATUS_SOURCE_NONE 0 -#define BOOT_STATUS_SOURCE_SCRATCH 1 -#define BOOT_STATUS_SOURCE_SLOT0 2 +#define BOOT_PRIMARY_SLOT 0 +#define BOOT_SECONDARY_SLOT 1 -#define BOOT_FLAG_IMAGE_OK 0 -#define BOOT_FLAG_COPY_DONE 1 +#define BOOT_STATUS_SOURCE_NONE 0 +#define BOOT_STATUS_SOURCE_SCRATCH 1 +#define BOOT_STATUS_SOURCE_PRIMARY_SLOT 2 + +#define BOOT_FLAG_IMAGE_OK 0 +#define BOOT_FLAG_COPY_DONE 1 extern const uint32_t BOOT_MAGIC_SZ; @@ -265,16 +269,19 @@ boot_initialize_area(struct boot_loader_state *state, int flash_area) int rc; switch (flash_area) { - case FLASH_AREA_IMAGE_0: - rc = flash_area_to_sectors(flash_area, &num_sectors, state->imgs[0].sectors); - state->imgs[0].num_sectors = (size_t)num_sectors; + case FLASH_AREA_IMAGE_PRIMARY: + rc = flash_area_to_sectors(flash_area, &num_sectors, + state->imgs[BOOT_PRIMARY_SLOT].sectors); + state->imgs[BOOT_PRIMARY_SLOT].num_sectors = (size_t)num_sectors; break; - case FLASH_AREA_IMAGE_1: - rc = flash_area_to_sectors(flash_area, &num_sectors, state->imgs[1].sectors); - state->imgs[1].num_sectors = (size_t)num_sectors; + case FLASH_AREA_IMAGE_SECONDARY: + rc = flash_area_to_sectors(flash_area, &num_sectors, + state->imgs[BOOT_SECONDARY_SLOT].sectors); + state->imgs[BOOT_SECONDARY_SLOT].num_sectors = (size_t)num_sectors; break; case FLASH_AREA_IMAGE_SCRATCH: - rc = flash_area_to_sectors(flash_area, &num_sectors, state->scratch.sectors); + rc = flash_area_to_sectors(flash_area, &num_sectors, + state->scratch.sectors); state->scratch.num_sectors = (size_t)num_sectors; break; default: @@ -310,15 +317,15 @@ boot_initialize_area(struct boot_loader_state *state, int flash_area) int rc; switch (flash_area) { - case FLASH_AREA_IMAGE_0: + case FLASH_AREA_IMAGE_PRIMARY: num_sectors = BOOT_MAX_IMG_SECTORS; - out_sectors = state->imgs[0].sectors; - out_num_sectors = &state->imgs[0].num_sectors; + out_sectors = state->imgs[BOOT_PRIMARY_SLOT].sectors; + out_num_sectors = &state->imgs[BOOT_PRIMARY_SLOT].num_sectors; break; - case FLASH_AREA_IMAGE_1: + case FLASH_AREA_IMAGE_SECONDARY: num_sectors = BOOT_MAX_IMG_SECTORS; - out_sectors = state->imgs[1].sectors; - out_num_sectors = &state->imgs[1].num_sectors; + out_sectors = state->imgs[BOOT_SECONDARY_SLOT].sectors; + out_num_sectors = &state->imgs[BOOT_SECONDARY_SLOT].num_sectors; break; case FLASH_AREA_IMAGE_SCRATCH: num_sectors = BOOT_MAX_IMG_SECTORS; diff --git a/boot/bootutil/src/caps.c b/boot/bootutil/src/caps.c index 85bd6fd08..43e1bf69f 100644 --- a/boot/bootutil/src/caps.c +++ b/boot/bootutil/src/caps.c @@ -41,8 +41,8 @@ uint32_t bootutil_get_caps(void) #if defined(MCUBOOT_ENCRYPT_KW) res |= BOOTUTIL_CAP_ENC_KW; #endif -#if defined(MCUBOOT_VALIDATE_SLOT0) - res |= BOOTUTIL_CAP_VALIDATE_SLOT0; +#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) + res |= BOOTUTIL_CAP_VALIDATE_PRIMARY_SLOT; #endif return res; diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c index fa502fe91..6ac10d66a 100644 --- a/boot/bootutil/src/encrypted.c +++ b/boot/bootutil/src/encrypted.c @@ -233,7 +233,11 @@ boot_enc_load(const struct image_header *hdr, const struct flash_area *fap, uint8_t enckey_type; int rc; - slot = fap->fa_id - FLASH_AREA_IMAGE_0; + rc = flash_area_id_to_image_slot(fap->fa_id); + if (rc < 0) { + return rc; + } + slot = rc; /* Already loaded... */ if (enc_state[slot].valid) { @@ -302,10 +306,19 @@ boot_enc_load(const struct image_header *hdr, const struct flash_area *fap, return rc; } -int +bool boot_enc_valid(const struct flash_area *fap) { - return enc_state[fap->fa_id - FLASH_AREA_IMAGE_0].valid; + int rc; + + rc = flash_area_id_to_image_slot(fap->fa_id); + if (rc < 0) { + /* can't get proper slot number - skip encryption, */ + /* postpone the erro for a upper layer */ + return false; + } + + return enc_state[rc].valid; } void @@ -317,6 +330,7 @@ boot_encrypt(const struct flash_area *fap, uint32_t off, uint32_t sz, uint8_t u8; uint8_t nonce[16]; uint8_t blk[16]; + int rc; memset(nonce, 0, 12); off >>= 4; @@ -325,7 +339,13 @@ boot_encrypt(const struct flash_area *fap, uint32_t off, uint32_t sz, nonce[14] = (uint8_t)(off >> 8); nonce[15] = (uint8_t)off; - enc = &enc_state[fap->fa_id - FLASH_AREA_IMAGE_0]; + rc = flash_area_id_to_image_slot(fap->fa_id); + if (rc < 0) { + assert(0); + return; + } + + enc = &enc_state[rc]; assert(enc->valid == 1); for (i = 0; i < sz; i++) { if (i == 0 || blk_off == 0) { diff --git a/boot/bootutil/src/image_ec256.c b/boot/bootutil/src/image_ec256.c index dbaea76e1..a121e6da6 100644 --- a/boot/bootutil/src/image_ec256.c +++ b/boot/bootutil/src/image_ec256.c @@ -27,7 +27,13 @@ #include "mbedtls/oid.h" #include "mbedtls/asn1.h" +#ifdef MCUBOOT_USE_TINYCRYPT #include "tinycrypt/ecc_dsa.h" +#endif +#ifdef MCUBOOT_USE_CC310 +#include "cc310_glue.h" +#define NUM_ECC_BYTES (4*8) +#endif #include "bootutil_priv.h" /* @@ -40,7 +46,7 @@ static const uint8_t ec_secp256r1_oid[] = MBEDTLS_OID_EC_GRP_SECP256R1; * Parse the public key used for signing. */ static int -tinycrypt_import_key(uint8_t **cp, uint8_t *end) +bootutil_import_key(uint8_t **cp, uint8_t *end) { size_t len; mbedtls_asn1_buf alg; @@ -91,7 +97,7 @@ tinycrypt_import_key(uint8_t **cp, uint8_t *end) * Verify the tag, and that the length is 32 bytes. */ static int -tinycrypt_read_bigint(uint8_t i[NUM_ECC_BYTES], uint8_t **cp, uint8_t *end) +bootutil_read_bigint(uint8_t i[NUM_ECC_BYTES], uint8_t **cp, uint8_t *end) { size_t len; @@ -113,7 +119,7 @@ tinycrypt_read_bigint(uint8_t i[NUM_ECC_BYTES], uint8_t **cp, uint8_t *end) * Read in signature. Signature has r and s encoded as integers. */ static int -tinycrypt_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp, uint8_t *end) +bootutil_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp, uint8_t *end) { int rc; size_t len; @@ -127,17 +133,18 @@ tinycrypt_decode_sig(uint8_t signature[NUM_ECC_BYTES * 2], uint8_t *cp, uint8_t return -2; } - rc = tinycrypt_read_bigint(signature, &cp, end); + rc = bootutil_read_bigint(signature, &cp, end); if (rc) { return -3; } - rc = tinycrypt_read_bigint(signature + NUM_ECC_BYTES, &cp, end); + rc = bootutil_read_bigint(signature + NUM_ECC_BYTES, &cp, end); if (rc) { return -4; } return 0; } +#ifdef MCUBOOT_USE_TINYCRYPT int bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, uint8_t key_id) @@ -151,12 +158,12 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, pubkey = (uint8_t *)bootutil_keys[key_id].key; end = pubkey + *bootutil_keys[key_id].len; - rc = tinycrypt_import_key(&pubkey, end); + rc = bootutil_import_key(&pubkey, end); if (rc) { return -1; } - rc = tinycrypt_decode_sig(signature, sig, sig + slen); + rc = bootutil_decode_sig(signature, sig, sig + slen); if (rc) { return -1; } @@ -175,4 +182,49 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen, return -2; } } +#endif /* MCUBOOT_USE_TINYCRYPT */ +#ifdef MCUBOOT_USE_CC310 +int +bootutil_verify_sig(uint8_t *hash, + uint32_t hlen, + uint8_t *sig, + size_t slen, + uint8_t key_id) +{ + int rc; + uint8_t *pubkey; + uint8_t *end; + uint8_t signature[2 * NUM_ECC_BYTES]; + + pubkey = (uint8_t *)bootutil_keys[key_id].key; + end = pubkey + *bootutil_keys[key_id].len; + + rc = bootutil_import_key(&pubkey, end); + if (rc) { + return -1; + } + + /* Decode signature */ + rc = bootutil_decode_sig(signature, sig, sig + slen); + if (rc) { + return -1; + } + + /* + * This is simplified, as the hash length is also 32 bytes. + */ + if (hlen != NUM_ECC_BYTES) { + return -1; + } + + /* Initialize and verify in one go */ + rc = cc310_ecdsa_verify_secp256r1(hash, pubkey, signature, hlen); + + if (rc != 0) { + return -2; + } + + return rc; +} +#endif /* MCUBOOT_USE_CC310 */ #endif /* MCUBOOT_SIGN_EC256 */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index de2aa0e5f..9a5fe57b8 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -70,8 +70,10 @@ bootutil_img_hash(struct image_header *hdr, const struct flash_area *fap, } #ifdef MCUBOOT_ENC_IMAGES - /* Encrypted images only exist in slot1 */ - if (fap->fa_id == FLASH_AREA_IMAGE_1 && IS_ENCRYPTED(hdr) && !boot_enc_valid(fap)) { + /* Encrypted images only exist in the secondary slot */ + if (fap->fa_id == FLASH_AREA_IMAGE_SECONDARY && + IS_ENCRYPTED(hdr) && + !boot_enc_valid(fap)) { return -1; } #endif @@ -101,7 +103,9 @@ bootutil_img_hash(struct image_header *hdr, const struct flash_area *fap, return rc; } #ifdef MCUBOOT_ENC_IMAGES - if (fap->fa_id == FLASH_AREA_IMAGE_1 && IS_ENCRYPTED(hdr) && off >= hdr_size) { + if (fap->fa_id == FLASH_AREA_IMAGE_SECONDARY && + IS_ENCRYPTED(hdr) && + off >= hdr_size) { blk_off = (off - hdr_size) & 0xf; boot_encrypt(fap, off - hdr_size, blk_sz, blk_off, tmp_buf); } diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index af54b8766..ac26bd25a 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -44,7 +44,7 @@ MCUBOOT_LOG_MODULE_DECLARE(mcuboot); static struct boot_loader_state boot_data; -#if defined(MCUBOOT_VALIDATE_SLOT0) && !defined(MCUBOOT_OVERWRITE_ONLY) +#if defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) && !defined(MCUBOOT_OVERWRITE_ONLY) static int boot_status_fails = 0; #define BOOT_STATUS_ASSERT(x) \ do { \ @@ -57,9 +57,9 @@ static int boot_status_fails = 0; #endif struct boot_status_table { - uint8_t bst_magic_slot0; + uint8_t bst_magic_primary_slot; uint8_t bst_magic_scratch; - uint8_t bst_copy_done_slot0; + uint8_t bst_copy_done_primary_slot; uint8_t bst_status_source; }; @@ -69,66 +69,66 @@ struct boot_status_table { */ static const struct boot_status_table boot_status_tables[] = { { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | Good | Any | - * copy-done | Set | N/A | - * ----------+------------+------------' - * source: none | - * ------------------------------------' + /* | primary slot | scratch | + * ----------+--------------+--------------| + * magic | Good | Any | + * copy-done | Set | N/A | + * ----------+--------------+--------------' + * source: none | + * ----------------------------------------' */ - .bst_magic_slot0 = BOOT_MAGIC_GOOD, - .bst_magic_scratch = BOOT_MAGIC_ANY, - .bst_copy_done_slot0 = BOOT_FLAG_SET, - .bst_status_source = BOOT_STATUS_SOURCE_NONE, + .bst_magic_primary_slot = BOOT_MAGIC_GOOD, + .bst_magic_scratch = BOOT_MAGIC_ANY, + .bst_copy_done_primary_slot = BOOT_FLAG_SET, + .bst_status_source = BOOT_STATUS_SOURCE_NONE, }, { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | Good | Any | - * copy-done | Unset | N/A | - * ----------+------------+------------' - * source: slot 0 | - * ------------------------------------' + /* | primary slot | scratch | + * ----------+--------------+--------------| + * magic | Good | Any | + * copy-done | Unset | N/A | + * ----------+--------------+--------------' + * source: primary slot | + * ----------------------------------------' */ - .bst_magic_slot0 = BOOT_MAGIC_GOOD, - .bst_magic_scratch = BOOT_MAGIC_ANY, - .bst_copy_done_slot0 = BOOT_FLAG_UNSET, - .bst_status_source = BOOT_STATUS_SOURCE_SLOT0, + .bst_magic_primary_slot = BOOT_MAGIC_GOOD, + .bst_magic_scratch = BOOT_MAGIC_ANY, + .bst_copy_done_primary_slot = BOOT_FLAG_UNSET, + .bst_status_source = BOOT_STATUS_SOURCE_PRIMARY_SLOT, }, { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | Any | Good | - * copy-done | Any | N/A | - * ----------+------------+------------' - * source: scratch | - * ------------------------------------' + /* | primary slot | scratch | + * ----------+--------------+--------------| + * magic | Any | Good | + * copy-done | Any | N/A | + * ----------+--------------+--------------' + * source: scratch | + * ----------------------------------------' */ - .bst_magic_slot0 = BOOT_MAGIC_ANY, - .bst_magic_scratch = BOOT_MAGIC_GOOD, - .bst_copy_done_slot0 = BOOT_FLAG_ANY, - .bst_status_source = BOOT_STATUS_SOURCE_SCRATCH, + .bst_magic_primary_slot = BOOT_MAGIC_ANY, + .bst_magic_scratch = BOOT_MAGIC_GOOD, + .bst_copy_done_primary_slot = BOOT_FLAG_ANY, + .bst_status_source = BOOT_STATUS_SOURCE_SCRATCH, }, { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | Unset | Any | - * copy-done | Unset | N/A | - * ----------+------------+------------| - * source: varies | - * ------------------------------------+------------------------------+ + /* | primary slot | scratch | + * ----------+--------------+--------------| + * magic | Unset | Any | + * copy-done | Unset | N/A | + * ----------+--------------+--------------| + * source: varies | + * ----------------------------------------+--------------------------+ * This represents one of two cases: | * o No swaps ever (no status to read, so no harm in checking). | - * o Mid-revert; status in slot 0. | + * o Mid-revert; status in primary slot. | * -------------------------------------------------------------------' */ - .bst_magic_slot0 = BOOT_MAGIC_UNSET, - .bst_magic_scratch = BOOT_MAGIC_ANY, - .bst_copy_done_slot0 = BOOT_FLAG_UNSET, - .bst_status_source = BOOT_STATUS_SOURCE_SLOT0, + .bst_magic_primary_slot = BOOT_MAGIC_UNSET, + .bst_magic_scratch = BOOT_MAGIC_ANY, + .bst_copy_done_primary_slot = BOOT_FLAG_UNSET, + .bst_status_source = BOOT_STATUS_SOURCE_PRIMARY_SLOT, }, }; @@ -145,46 +145,49 @@ static const struct boot_status_table boot_status_tables[] = { (state)->image_ok) /** - * Determines where in flash the most recent boot status is stored. The boot + * Determines where in flash the most recent boot status is stored. The boot * status is necessary for completing a swap that was interrupted by a boot * loader reset. * - * @return A BOOT_STATUS_SOURCE_[...] code indicating where * status should be read from. + * @return A BOOT_STATUS_SOURCE_[...] code indicating where status should + * be read from. */ static int boot_status_source(void) { const struct boot_status_table *table; struct boot_swap_state state_scratch; - struct boot_swap_state state_slot0; + struct boot_swap_state state_primary_slot; int rc; size_t i; uint8_t source; - rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_0, &state_slot0); + rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY, + &state_primary_slot); assert(rc == 0); rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SCRATCH, &state_scratch); assert(rc == 0); - BOOT_LOG_SWAP_STATE("Image 0", &state_slot0); + BOOT_LOG_SWAP_STATE("Primary image", &state_primary_slot); BOOT_LOG_SWAP_STATE("Scratch", &state_scratch); for (i = 0; i < BOOT_STATUS_TABLES_COUNT; i++) { table = &boot_status_tables[i]; - if ((table->bst_magic_slot0 == BOOT_MAGIC_ANY || - table->bst_magic_slot0 == state_slot0.magic) && - (table->bst_magic_scratch == BOOT_MAGIC_ANY || - table->bst_magic_scratch == state_scratch.magic) && - (table->bst_copy_done_slot0 == BOOT_FLAG_ANY || - table->bst_copy_done_slot0 == state_slot0.copy_done)) { + if ((table->bst_magic_primary_slot == BOOT_MAGIC_ANY || + table->bst_magic_primary_slot == state_primary_slot.magic) && + (table->bst_magic_scratch == BOOT_MAGIC_ANY || + table->bst_magic_scratch == state_scratch.magic) && + (table->bst_copy_done_primary_slot == BOOT_FLAG_ANY || + table->bst_copy_done_primary_slot == state_primary_slot.copy_done)) + { source = table->bst_status_source; BOOT_LOG_INF("Boot source: %s", source == BOOT_STATUS_SOURCE_NONE ? "none" : source == BOOT_STATUS_SOURCE_SCRATCH ? "scratch" : - source == BOOT_STATUS_SOURCE_SLOT0 ? "slot 0" : - "BUG; can't happen"); + source == BOOT_STATUS_SOURCE_PRIMARY_SLOT ? + "primary slot" : "BUG; can't happen"); return source; } } @@ -317,7 +320,7 @@ boot_write_sz(void) * on what the minimum write size is for scratch area, active image slot. * We need to use the bigger of those 2 values. */ - elem_sz = flash_area_align(boot_data.imgs[0].area); + elem_sz = flash_area_align(boot_data.imgs[BOOT_PRIMARY_SLOT].area); align = flash_area_align(boot_data.scratch.area); if (align > elem_sz) { elem_sz = align; @@ -335,17 +338,20 @@ boot_write_sz(void) static int boot_slots_compatible(void) { - size_t num_sectors_0; - size_t num_sectors_1; + size_t num_sectors_primary; + size_t num_sectors_secondary; size_t sz0, sz1; - size_t slot0_sz, slot1_sz; + size_t primary_slot_sz, secondary_slot_sz; size_t scratch_sz; size_t i, j; int8_t smaller; - num_sectors_0 = boot_img_num_sectors(&boot_data, 0); - num_sectors_1 = boot_img_num_sectors(&boot_data, 1); - if (num_sectors_0 > BOOT_MAX_IMG_SECTORS || num_sectors_1 > BOOT_MAX_IMG_SECTORS) { + num_sectors_primary = + boot_img_num_sectors(&boot_data, BOOT_PRIMARY_SLOT); + num_sectors_secondary = + boot_img_num_sectors(&boot_data, BOOT_SECONDARY_SLOT); + if ((num_sectors_primary > BOOT_MAX_IMG_SECTORS) || + (num_sectors_secondary > BOOT_MAX_IMG_SECTORS)) { BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed"); return 0; } @@ -359,18 +365,20 @@ boot_slots_compatible(void) * number of a slot's sectors are able to fit into another, which only * excludes cases where sector sizes are not a multiple of each other. */ - i = sz0 = slot0_sz = 0; - j = sz1 = slot1_sz = 0; + i = sz0 = primary_slot_sz = 0; + j = sz1 = secondary_slot_sz = 0; smaller = 0; - while (i < num_sectors_0 || j < num_sectors_1) { + while (i < num_sectors_primary || j < num_sectors_secondary) { if (sz0 == sz1) { - sz0 += boot_img_sector_size(&boot_data, 0, i); - sz1 += boot_img_sector_size(&boot_data, 1, j); + sz0 += boot_img_sector_size(&boot_data, BOOT_PRIMARY_SLOT, i); + sz1 += boot_img_sector_size(&boot_data, BOOT_SECONDARY_SLOT, j); i++; j++; } else if (sz0 < sz1) { - sz0 += boot_img_sector_size(&boot_data, 0, i); - /* guarantee that multiple sectors of slot1 fit into slot0 */ + sz0 += boot_img_sector_size(&boot_data, BOOT_PRIMARY_SLOT, i); + /* Guarantee that multiple sectors of the secondary slot + * fit into the primary slot. + */ if (smaller == 2) { BOOT_LOG_WRN("Cannot upgrade: slots have non-compatible sectors"); return 0; @@ -378,8 +386,10 @@ boot_slots_compatible(void) smaller = 1; i++; } else { - sz1 += boot_img_sector_size(&boot_data, 1, j); - /* guarantee that multiple sectors of slot0 fit into slot1 */ + sz1 += boot_img_sector_size(&boot_data, BOOT_SECONDARY_SLOT, j); + /* Guarantee that multiple sectors of the primary slot + * fit into the secondary slot. + */ if (smaller == 1) { BOOT_LOG_WRN("Cannot upgrade: slots have non-compatible sectors"); return 0; @@ -388,10 +398,10 @@ boot_slots_compatible(void) j++; } if (sz0 == sz1) { - slot0_sz += sz0; - slot1_sz += sz1; - /* scratch has to fit each swap operation to the size of the larger - * sector among slot0 and slot1 + primary_slot_sz += sz0; + secondary_slot_sz += sz1; + /* Scratch has to fit each swap operation to the size of the larger + * sector among the primary slot and the secondary slot. */ if (sz0 > scratch_sz || sz1 > scratch_sz) { BOOT_LOG_WRN("Cannot upgrade: not all sectors fit inside scratch"); @@ -401,7 +411,9 @@ boot_slots_compatible(void) } } - if (i != num_sectors_0 || j != num_sectors_1 || slot0_sz != slot1_sz) { + if ((i != num_sectors_primary) || + (j != num_sectors_secondary) || + (primary_slot_sz != secondary_slot_sz)) { BOOT_LOG_WRN("Cannot upgrade: slots are not compatible"); return 0; } @@ -420,12 +432,12 @@ boot_read_sectors(void) { int rc; - rc = boot_initialize_area(&boot_data, FLASH_AREA_IMAGE_0); + rc = boot_initialize_area(&boot_data, FLASH_AREA_IMAGE_PRIMARY); if (rc != 0) { return BOOT_EFLASH; } - rc = boot_initialize_area(&boot_data, FLASH_AREA_IMAGE_1); + rc = boot_initialize_area(&boot_data, FLASH_AREA_IMAGE_SECONDARY); if (rc != 0) { return BOOT_EFLASH; } @@ -499,9 +511,9 @@ boot_read_status_bytes(const struct flash_area *fap, struct boot_status *bs) */ BOOT_LOG_ERR("Detected inconsistent status!"); -#if !defined(MCUBOOT_VALIDATE_SLOT0) - /* With validation of slot0 disabled, there is no way to be sure the - * swapped slot0 is OK, so abort! +#if !defined(MCUBOOT_VALIDATE_PRIMARY_SLOT) + /* With validation of the primary slot disabled, there is no way + * to be sure the swapped primary slot is OK, so abort! */ assert(0); #endif @@ -551,8 +563,8 @@ boot_read_status(struct boot_status *bs) area_id = FLASH_AREA_IMAGE_SCRATCH; break; - case BOOT_STATUS_SOURCE_SLOT0: - area_id = FLASH_AREA_IMAGE_0; + case BOOT_STATUS_SOURCE_PRIMARY_SLOT: + area_id = FLASH_AREA_IMAGE_PRIMARY; break; default: @@ -592,16 +604,17 @@ boot_write_status(struct boot_status *bs) uint8_t erased_val; /* NOTE: The first sector copied (that is the last sector on slot) contains - * the trailer. Since in the last step SLOT 0 is erased, the first - * two status writes go to the scratch which will be copied to SLOT 0! + * the trailer. Since in the last step the primary slot is erased, the + * first two status writes go to the scratch which will be copied to + * the primary slot! */ if (bs->use_scratch) { /* Write to scratch. */ area_id = FLASH_AREA_IMAGE_SCRATCH; } else { - /* Write to slot 0. */ - area_id = FLASH_AREA_IMAGE_0; + /* Write to the primary slot. */ + area_id = FLASH_AREA_IMAGE_PRIMARY; } rc = flash_area_open(area_id, &fap); @@ -645,7 +658,7 @@ boot_image_check(struct image_header *hdr, const struct flash_area *fap, (void)bs; (void)rc; #else - if (fap->fa_id == FLASH_AREA_IMAGE_1 && IS_ENCRYPTED(hdr)) { + if ((fap->fa_id == FLASH_AREA_IMAGE_SECONDARY) && IS_ENCRYPTED(hdr)) { rc = boot_enc_load(hdr, fap, bs->enckey[1]); if (rc < 0) { return BOOT_EBADIMAGE; @@ -746,24 +759,25 @@ boot_validate_slot(int slot, struct boot_status *bs) hdr = boot_img_hdr(&boot_data, slot); if (boot_check_header_erased(slot) == 0 || (hdr->ih_flags & IMAGE_F_NON_BOOTABLE)) { - /* No bootable image in slot; continue booting from slot 0. */ + /* No bootable image in slot; continue booting from the primary slot. */ rc = -1; goto out; } if ((hdr->ih_magic != IMAGE_MAGIC || boot_image_check(hdr, fap, bs) != 0)) { - if (slot != 0) { + if (slot != BOOT_PRIMARY_SLOT) { flash_area_erase(fap, 0, fap->fa_size); - /* Image in slot 1 is invalid. Erase the image and - * continue booting from slot 0. + /* Image in the secondary slot is invalid. Erase the image and + * continue booting from the primary slot. */ } - BOOT_LOG_ERR("Image in slot %d is not valid!", slot); + BOOT_LOG_ERR("Image in the %s slot is not valid!", + (slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary"); rc = -1; goto out; } - /* Image in slot 1 is valid. */ + /* Image in the secondary slot is valid. */ rc = 0; out: @@ -773,9 +787,9 @@ boot_validate_slot(int slot, struct boot_status *bs) /** * Determines which swap operation to perform, if any. If it is determined - * that a swap operation is required, the image in the second slot is checked - * for validity. If the image in the second slot is invalid, it is erased, and - * a swap type of "none" is indicated. + * that a swap operation is required, the image in the secondary slot is checked + * for validity. If the image in the secondary slot is invalid, it is erased, + * and a swap type of "none" is indicated. * * @return The type of swap to perform (BOOT_SWAP_TYPE...) */ @@ -789,8 +803,10 @@ boot_validated_swap_type(struct boot_status *bs) case BOOT_SWAP_TYPE_TEST: case BOOT_SWAP_TYPE_PERM: case BOOT_SWAP_TYPE_REVERT: - /* Boot loader wants to switch to slot 1. Ensure image is valid. */ - if (boot_validate_slot(1, bs) != 0) { + /* Boot loader wants to switch to the secondary slot. + * Ensure image is valid. + */ + if (boot_validate_slot(BOOT_SECONDARY_SLOT, bs) != 0) { swap_type = BOOT_SWAP_TYPE_FAIL; } } @@ -824,11 +840,11 @@ boot_copy_sz(int last_sector_idx, int *out_first_sector_idx) scratch_sz = boot_scratch_area_size(&boot_data); for (i = last_sector_idx; i >= 0; i--) { - new_sz = sz + boot_img_sector_size(&boot_data, 0, i); + new_sz = sz + boot_img_sector_size(&boot_data, BOOT_PRIMARY_SLOT, i); /* - * slot1 is not being checked here, because `boot_slots_compatible` - * already provides assurance that the copy size will be compatible - * with slot0 and scratch. + * The secondary slot is not being checked here, because + * `boot_slots_compatible` already provides assurance that the copy size + * will be compatible with the primary slot and scratch. */ if (new_sz > scratch_sz) { break; @@ -906,14 +922,14 @@ boot_copy_sector(const struct flash_area *fap_src, } #ifdef MCUBOOT_ENC_IMAGES - if (fap_src->fa_id == FLASH_AREA_IMAGE_1 || - fap_dst->fa_id == FLASH_AREA_IMAGE_1) { - /* assume slot1 as src, needs decryption */ - hdr = boot_img_hdr(&boot_data, 1); + if ((fap_src->fa_id == FLASH_AREA_IMAGE_SECONDARY) || + (fap_dst->fa_id == FLASH_AREA_IMAGE_SECONDARY)) { + /* assume the secondary slot as src, needs decryption */ + hdr = boot_img_hdr(&boot_data, BOOT_SECONDARY_SLOT); off = off_src; - if (fap_dst->fa_id == FLASH_AREA_IMAGE_1) { - /* might need encryption (metadata from slot0) */ - hdr = boot_img_hdr(&boot_data, 0); + if (fap_dst->fa_id == FLASH_AREA_IMAGE_SECONDARY) { + /* might need encryption (metadata from the primary slot) */ + hdr = boot_img_hdr(&boot_data, BOOT_PRIMARY_SLOT); off = off_dst; } if (IS_ENCRYPTED(hdr)) { @@ -959,7 +975,7 @@ boot_status_init(const struct flash_area *fap, const struct boot_status *bs) struct boot_swap_state swap_state; int rc; - rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_1, &swap_state); + rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_SECONDARY, &swap_state); assert(rc == 0); if (swap_state.image_ok == BOOT_FLAG_SET) { @@ -998,11 +1014,11 @@ boot_erase_trailer_sectors(const struct flash_area *fap) int rc; switch (fap->fa_id) { - case FLASH_AREA_IMAGE_0: - slot = 0; + case FLASH_AREA_IMAGE_PRIMARY: + slot = BOOT_PRIMARY_SLOT; break; - case FLASH_AREA_IMAGE_1: - slot = 1; + case FLASH_AREA_IMAGE_SECONDARY: + slot = BOOT_SECONDARY_SLOT; break; default: return BOOT_EFLASH; @@ -1041,8 +1057,8 @@ boot_erase_trailer_sectors(const struct flash_area *fap) static void boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) { - const struct flash_area *fap_slot0; - const struct flash_area *fap_slot1; + const struct flash_area *fap_primary_slot; + const struct flash_area *fap_secondary_slot; const struct flash_area *fap_scratch; uint32_t copy_sz; uint32_t trailer_sz; @@ -1053,7 +1069,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) int rc; /* Calculate offset from start of image area. */ - img_off = boot_img_sector_off(&boot_data, 0, idx); + img_off = boot_img_sector_off(&boot_data, BOOT_PRIMARY_SLOT, idx); copy_sz = sz; trailer_sz = boot_slots_trailer_sz(BOOT_WRITE_SZ(&boot_data)); @@ -1067,17 +1083,18 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) * NOTE: `use_scratch` is a temporary flag (never written to flash) which * controls if special handling is needed (swapping last sector). */ - last_sector = boot_img_num_sectors(&boot_data, 0) - 1; - if (img_off + sz > boot_img_sector_off(&boot_data, 0, last_sector)) { + last_sector = boot_img_num_sectors(&boot_data, BOOT_PRIMARY_SLOT) - 1; + if (img_off + sz > boot_img_sector_off(&boot_data, BOOT_PRIMARY_SLOT, + last_sector)) { copy_sz -= trailer_sz; } bs->use_scratch = (bs->idx == BOOT_STATUS_IDX_0 && copy_sz != sz); - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap_slot0); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap_primary_slot); assert (rc == 0); - rc = flash_area_open(FLASH_AREA_IMAGE_1, &fap_slot1); + rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY, &fap_secondary_slot); assert (rc == 0); rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap_scratch); @@ -1087,7 +1104,8 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) rc = boot_erase_sector(fap_scratch, 0, sz); assert(rc == 0); - rc = boot_copy_sector(fap_slot1, fap_scratch, img_off, 0, copy_sz); + rc = boot_copy_sector(fap_secondary_slot, fap_scratch, + img_off, 0, copy_sz); assert(rc == 0); if (bs->idx == BOOT_STATUS_IDX_0) { @@ -1098,10 +1116,10 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) * last sector is not being used by the image data so it's * safe to erase. */ - rc = boot_erase_trailer_sectors(fap_slot0); + rc = boot_erase_trailer_sectors(fap_primary_slot); assert(rc == 0); - boot_status_init(fap_slot0, bs); + boot_status_init(fap_primary_slot, bs); } } @@ -1111,17 +1129,18 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) } if (bs->state == BOOT_STATUS_STATE_1) { - rc = boot_erase_sector(fap_slot1, img_off, sz); + rc = boot_erase_sector(fap_secondary_slot, img_off, sz); assert(rc == 0); - rc = boot_copy_sector(fap_slot0, fap_slot1, img_off, img_off, copy_sz); + rc = boot_copy_sector(fap_primary_slot, fap_secondary_slot, + img_off, img_off, copy_sz); assert(rc == 0); if (bs->idx == BOOT_STATUS_IDX_0 && !bs->use_scratch) { /* If not all sectors of the slot are being swapped, - * guarantee here that only slot0 will have the state. + * guarantee here that only the primary slot will have the state. */ - rc = boot_erase_trailer_sectors(fap_slot1); + rc = boot_erase_trailer_sectors(fap_secondary_slot); assert(rc == 0); } @@ -1131,19 +1150,20 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) } if (bs->state == BOOT_STATUS_STATE_2) { - rc = boot_erase_sector(fap_slot0, img_off, sz); + rc = boot_erase_sector(fap_primary_slot, img_off, sz); assert(rc == 0); /* NOTE: also copy trailer from scratch (has status info) */ - rc = boot_copy_sector(fap_scratch, fap_slot0, 0, img_off, copy_sz); + rc = boot_copy_sector(fap_scratch, fap_primary_slot, + 0, img_off, copy_sz); assert(rc == 0); if (bs->use_scratch) { scratch_trailer_off = boot_status_off(fap_scratch); /* copy current status that is being maintained in scratch */ - rc = boot_copy_sector(fap_scratch, fap_slot0, scratch_trailer_off, - img_off + copy_sz, + rc = boot_copy_sector(fap_scratch, fap_primary_slot, + scratch_trailer_off, img_off + copy_sz, BOOT_STATUS_STATE_COUNT * BOOT_WRITE_SZ(&boot_data)); BOOT_STATUS_ASSERT(rc == 0); @@ -1152,22 +1172,22 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) assert(rc == 0); if (swap_state.image_ok == BOOT_FLAG_SET) { - rc = boot_write_image_ok(fap_slot0); + rc = boot_write_image_ok(fap_primary_slot); assert(rc == 0); } - rc = boot_write_swap_size(fap_slot0, bs->swap_size); + rc = boot_write_swap_size(fap_primary_slot, bs->swap_size); assert(rc == 0); #ifdef MCUBOOT_ENC_IMAGES - rc = boot_write_enc_key(fap_slot0, 0, bs->enckey[0]); + rc = boot_write_enc_key(fap_primary_slot, 0, bs->enckey[0]); assert(rc == 0); - rc = boot_write_enc_key(fap_slot0, 1, bs->enckey[1]); + rc = boot_write_enc_key(fap_primary_slot, 1, bs->enckey[1]); assert(rc == 0); #endif - rc = boot_write_magic(fap_slot0); + rc = boot_write_magic(fap_primary_slot); assert(rc == 0); } @@ -1178,16 +1198,16 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs) BOOT_STATUS_ASSERT(rc == 0); } - flash_area_close(fap_slot0); - flash_area_close(fap_slot1); + flash_area_close(fap_primary_slot); + flash_area_close(fap_secondary_slot); flash_area_close(fap_scratch); } #endif /* !MCUBOOT_OVERWRITE_ONLY */ /** - * Overwrite slot 0 with the image contained in slot 1. If a prior copy - * operation was interrupted by a system reset, this function redos the - * copy. + * Overwrite primary slot with the image contained in the secondary slot. + * If a prior copy operation was interrupted by a system reset, this function + * redos the copy. * * @param bs The current boot status. This function reads * this struct to determine if it is resuming @@ -1207,30 +1227,33 @@ boot_copy_image(struct boot_status *bs) size_t size; size_t this_size; size_t last_sector; - const struct flash_area *fap_slot0; - const struct flash_area *fap_slot1; + const struct flash_area *fap_primary_slot; + const struct flash_area *fap_secondary_slot; + (void)bs; #if defined(MCUBOOT_OVERWRITE_ONLY_FAST) uint32_t src_size = 0; - rc = boot_read_image_size(1, boot_img_hdr(&boot_data, 1), &src_size); + rc = boot_read_image_size(BOOT_SECONDARY_SLOT, + boot_img_hdr(&boot_data, BOOT_SECONDARY_SLOT), + &src_size); assert(rc == 0); #endif - BOOT_LOG_INF("Image upgrade slot1 -> slot0"); - BOOT_LOG_INF("Erasing slot0"); + BOOT_LOG_INF("Image upgrade secondary slot -> primary slot"); + BOOT_LOG_INF("Erasing the primary slot"); - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap_slot0); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap_primary_slot); assert (rc == 0); - rc = flash_area_open(FLASH_AREA_IMAGE_1, &fap_slot1); + rc = flash_area_open(FLASH_AREA_IMAGE_SECONDARY, &fap_secondary_slot); assert (rc == 0); - sect_count = boot_img_num_sectors(&boot_data, 0); + sect_count = boot_img_num_sectors(&boot_data, BOOT_PRIMARY_SLOT); for (sect = 0, size = 0; sect < sect_count; sect++) { - this_size = boot_img_sector_size(&boot_data, 0, sect); - rc = boot_erase_sector(fap_slot0, size, this_size); + this_size = boot_img_sector_size(&boot_data, BOOT_PRIMARY_SLOT, sect); + rc = boot_erase_sector(fap_primary_slot, size, this_size); assert(rc == 0); size += this_size; @@ -1243,8 +1266,11 @@ boot_copy_image(struct boot_status *bs) } #ifdef MCUBOOT_ENC_IMAGES - if (IS_ENCRYPTED(boot_img_hdr(&boot_data, 1))) { - rc = boot_enc_load(boot_img_hdr(&boot_data, 1), fap_slot1, bs->enckey[1]); + if (IS_ENCRYPTED(boot_img_hdr(&boot_data, BOOT_SECONDARY_SLOT))) { + rc = boot_enc_load(boot_img_hdr(&boot_data, BOOT_SECONDARY_SLOT), + fap_secondary_slot, + bs->enckey[1]); + if (rc < 0) { return BOOT_EBADIMAGE; } @@ -1254,28 +1280,33 @@ boot_copy_image(struct boot_status *bs) } #endif - BOOT_LOG_INF("Copying slot 1 to slot 0: 0x%zx bytes", size); - rc = boot_copy_sector(fap_slot1, fap_slot0, 0, 0, size); + BOOT_LOG_INF("Copying the secondary slot to the primary slot: 0x%zx bytes", + size); + rc = boot_copy_sector(fap_secondary_slot, fap_primary_slot, 0, 0, size); /* * Erases header and trailer. The trailer is erased because when a new * image is written without a trailer as is the case when using newt, the * trailer that was left might trigger a new upgrade. */ - rc = boot_erase_sector(fap_slot1, - boot_img_sector_off(&boot_data, 1, 0), - boot_img_sector_size(&boot_data, 1, 0)); + rc = boot_erase_sector(fap_secondary_slot, + boot_img_sector_off(&boot_data, + BOOT_SECONDARY_SLOT, 0), + boot_img_sector_size(&boot_data, + BOOT_SECONDARY_SLOT, 0)); assert(rc == 0); - last_sector = boot_img_num_sectors(&boot_data, 1) - 1; - rc = boot_erase_sector(fap_slot1, - boot_img_sector_off(&boot_data, 1, last_sector), - boot_img_sector_size(&boot_data, 1, last_sector)); + last_sector = boot_img_num_sectors(&boot_data, BOOT_SECONDARY_SLOT) - 1; + rc = boot_erase_sector(fap_secondary_slot, + boot_img_sector_off(&boot_data, + BOOT_SECONDARY_SLOT, last_sector), + boot_img_sector_size(&boot_data, + BOOT_SECONDARY_SLOT, last_sector)); assert(rc == 0); - flash_area_close(fap_slot0); - flash_area_close(fap_slot1); + flash_area_close(fap_primary_slot); + flash_area_close(fap_secondary_slot); - /* TODO: Perhaps verify slot 0's signature again? */ + /* TODO: Perhaps verify the primary slot's signature again? */ return 0; } @@ -1300,7 +1331,7 @@ boot_swap_image(struct boot_status *bs) uint32_t sz; int first_sector_idx; int last_sector_idx; - int last_idx_slot1; + int last_idx_secondary_slot; uint32_t swap_idx; struct image_header *hdr; #ifdef MCUBOOT_ENC_IMAGES @@ -1310,8 +1341,8 @@ boot_swap_image(struct boot_status *bs) #endif uint32_t size; uint32_t copy_size; - uint32_t slot0_size; - uint32_t slot1_size; + uint32_t primary_slot_size; + uint32_t secondary_slot_size; int rc; /* FIXME: just do this if asked by user? */ @@ -1323,15 +1354,15 @@ boot_swap_image(struct boot_status *bs) * No swap ever happened, so need to find the largest image which * will be used to determine the amount of sectors to swap. */ - hdr = boot_img_hdr(&boot_data, 0); + hdr = boot_img_hdr(&boot_data, BOOT_PRIMARY_SLOT); if (hdr->ih_magic == IMAGE_MAGIC) { - rc = boot_read_image_size(0, hdr, ©_size); + rc = boot_read_image_size(BOOT_PRIMARY_SLOT, hdr, ©_size); assert(rc == 0); } #ifdef MCUBOOT_ENC_IMAGES if (IS_ENCRYPTED(hdr)) { - fap = BOOT_IMG_AREA(&boot_data, 0); + fap = BOOT_IMG_AREA(&boot_data, BOOT_PRIMARY_SLOT); rc = boot_enc_load(hdr, fap, bs->enckey[0]); assert(rc >= 0); @@ -1346,16 +1377,16 @@ boot_swap_image(struct boot_status *bs) } #endif - hdr = boot_img_hdr(&boot_data, 1); + hdr = boot_img_hdr(&boot_data, BOOT_SECONDARY_SLOT); if (hdr->ih_magic == IMAGE_MAGIC) { - rc = boot_read_image_size(1, hdr, &size); + rc = boot_read_image_size(BOOT_SECONDARY_SLOT, hdr, &size); assert(rc == 0); } #ifdef MCUBOOT_ENC_IMAGES - hdr = boot_img_hdr(&boot_data, 1); + hdr = boot_img_hdr(&boot_data, BOOT_SECONDARY_SLOT); if (IS_ENCRYPTED(hdr)) { - fap = BOOT_IMG_AREA(&boot_data, 1); + fap = BOOT_IMG_AREA(&boot_data, BOOT_SECONDARY_SLOT); rc = boot_enc_load(hdr, fap, bs->enckey[1]); assert(rc >= 0); @@ -1404,31 +1435,37 @@ boot_swap_image(struct boot_status *bs) #endif } - slot0_size = 0; - slot1_size = 0; + primary_slot_size = 0; + secondary_slot_size = 0; last_sector_idx = 0; - last_idx_slot1 = 0; + last_idx_secondary_slot = 0; /* * Knowing the size of the largest image between both slots, here we - * find what is the last sector in slot0 that needs swapping. Since we - * already know that both slots are compatible, slot1's last sector is - * not really required after this check is finished. + * find what is the last sector in the primary slot that needs swapping. + * Since we already know that both slots are compatible, the secondary + * slot's last sector is not really required after this check is finished. */ while (1) { - if (slot0_size < copy_size || slot0_size < slot1_size) { - slot0_size += boot_img_sector_size(&boot_data, 0, last_sector_idx); + if ((primary_slot_size < copy_size) || + (primary_slot_size < secondary_slot_size)) { + primary_slot_size += boot_img_sector_size(&boot_data, + BOOT_PRIMARY_SLOT, + last_sector_idx); } - if (slot1_size < copy_size || slot1_size < slot0_size) { - slot1_size += boot_img_sector_size(&boot_data, 1, last_idx_slot1); + if ((secondary_slot_size < copy_size) || + (secondary_slot_size < primary_slot_size)) { + secondary_slot_size += boot_img_sector_size(&boot_data, + BOOT_SECONDARY_SLOT, + last_idx_secondary_slot); } - if (slot0_size >= copy_size && - slot1_size >= copy_size && - slot0_size == slot1_size) { + if (primary_slot_size >= copy_size && + secondary_slot_size >= copy_size && + primary_slot_size == secondary_slot_size) { break; } last_sector_idx++; - last_idx_slot1++; + last_idx_secondary_slot++; } swap_idx = 0; @@ -1442,7 +1479,7 @@ boot_swap_image(struct boot_status *bs) swap_idx++; } -#ifdef MCUBOOT_VALIDATE_SLOT0 +#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT if (boot_status_fails > 0) { BOOT_LOG_WRN("%d status write fails performing the swap", boot_status_fails); } @@ -1453,7 +1490,7 @@ boot_swap_image(struct boot_status *bs) #endif /** - * Marks the image in slot 0 as fully copied. + * Marks the image in the primary slot as fully copied. */ #ifndef MCUBOOT_OVERWRITE_ONLY static int @@ -1462,7 +1499,7 @@ boot_set_copy_done(void) const struct flash_area *fap; int rc; - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); if (rc != 0) { return BOOT_EFLASH; } @@ -1474,13 +1511,13 @@ boot_set_copy_done(void) #endif /* !MCUBOOT_OVERWRITE_ONLY */ /** - * Marks a reverted image in slot 0 as confirmed. This is necessary to ensure - * the status bytes from the image revert operation don't get processed on a - * subsequent boot. + * Marks a reverted image in the primary slot as confirmed. This is necessary to + * ensure the status bytes from the image revert operation don't get processed + * on a subsequent boot. * * NOTE: image_ok is tested before writing because if there's a valid permanent - * image installed on slot0 and the new image to be upgrade to has a bad sig, - * image_ok would be overwritten. + * image installed on the primary slot and the new image to be upgrade to has a + * bad sig, image_ok would be overwritten. */ #ifndef MCUBOOT_OVERWRITE_ONLY static int @@ -1490,7 +1527,7 @@ boot_set_image_ok(void) struct boot_swap_state state; int rc; - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); if (rc != 0) { return BOOT_EFLASH; } @@ -1574,12 +1611,13 @@ boot_swap_if_needed(int *out_swap_type) * Header checks are done first because they are inexpensive. * Since overwrite-only copies starting from offset 0, if * interrupted, it might leave a valid header magic, so also - * run validation on slot0 to be sure it's not OK. + * run validation on the primary slot to be sure it's not OK. */ - if (boot_check_header_erased(0) == 0 || - boot_validate_slot(0, &bs) != 0) { - if (boot_img_hdr(&boot_data, 1)->ih_magic == IMAGE_MAGIC && - boot_validate_slot(1, &bs) == 0) { + if (boot_check_header_erased(BOOT_PRIMARY_SLOT) == 0 || + boot_validate_slot(BOOT_PRIMARY_SLOT, &bs) != 0) { + if ((boot_img_hdr(&boot_data, BOOT_SECONDARY_SLOT)->ih_magic + == IMAGE_MAGIC ) && + (boot_validate_slot(BOOT_SECONDARY_SLOT, &bs) == 0)) { rc = boot_copy_image(&bs); assert(rc == 0); @@ -1618,11 +1656,11 @@ boot_go(struct boot_rsp *rsp) * necessary because the gcc option "-fdata-sections" doesn't seem to have * any effect in older gcc versions (e.g., 4.8.4). */ - static boot_sector_t slot0_sectors[BOOT_MAX_IMG_SECTORS]; - static boot_sector_t slot1_sectors[BOOT_MAX_IMG_SECTORS]; + static boot_sector_t primary_slot_sectors[BOOT_MAX_IMG_SECTORS]; + static boot_sector_t secondary_slot_sectors[BOOT_MAX_IMG_SECTORS]; static boot_sector_t scratch_sectors[BOOT_MAX_IMG_SECTORS]; - boot_data.imgs[0].sectors = slot0_sectors; - boot_data.imgs[1].sectors = slot1_sectors; + boot_data.imgs[BOOT_PRIMARY_SLOT].sectors = primary_slot_sectors; + boot_data.imgs[BOOT_SECONDARY_SLOT].sectors = secondary_slot_sectors; boot_data.scratch.sectors = scratch_sectors; #ifdef MCUBOOT_ENC_IMAGES @@ -1655,7 +1693,7 @@ boot_go(struct boot_rsp *rsp) } /* If the image slots aren't compatible, no swap is possible. Just boot - * into slot 0. + * into the primary slot. */ if (boot_slots_compatible()) { rc = boot_swap_if_needed(&swap_type); @@ -1668,7 +1706,8 @@ boot_go(struct boot_rsp *rsp) * The following states need image_ok be explicitly set after the * swap was finished to avoid a new revert. */ - if (swap_type == BOOT_SWAP_TYPE_REVERT || swap_type == BOOT_SWAP_TYPE_FAIL) { + if (swap_type == BOOT_SWAP_TYPE_REVERT || + swap_type == BOOT_SWAP_TYPE_FAIL) { #ifndef MCUBOOT_OVERWRITE_ONLY rc = boot_set_image_ok(); if (rc != 0) { @@ -1682,13 +1721,13 @@ boot_go(struct boot_rsp *rsp) switch (swap_type) { case BOOT_SWAP_TYPE_NONE: - slot = 0; + slot = BOOT_PRIMARY_SLOT; break; case BOOT_SWAP_TYPE_TEST: /* fallthrough */ case BOOT_SWAP_TYPE_PERM: /* fallthrough */ case BOOT_SWAP_TYPE_REVERT: - slot = 1; + slot = BOOT_SECONDARY_SLOT; reload_headers = true; #ifndef MCUBOOT_OVERWRITE_ONLY rc = boot_set_copy_done(); @@ -1699,11 +1738,11 @@ boot_go(struct boot_rsp *rsp) break; case BOOT_SWAP_TYPE_FAIL: - /* The image in slot 1 was invalid and is now erased. Ensure we don't - * try to boot into it again on the next reboot. Do this by pretending - * we just reverted back to slot 0. + /* The image in the secondary slot was invalid and is now erased. + * Ensure we don't try to boot into it again on the next reboot. + * Do this by pretending we just reverted back to the primary slot. */ - slot = 0; + slot = BOOT_PRIMARY_SLOT; reload_headers = true; break; @@ -1726,33 +1765,34 @@ boot_go(struct boot_rsp *rsp) } /* Since headers were reloaded, it can be assumed we just performed a * swap or overwrite. Now the header info that should be used to - * provide the data for the bootstrap, which previously was at Slot 1, - * was updated to Slot 0. + * provide the data for the bootstrap, which previously was at the + * secondary slot, was updated to the primary slot. */ - slot = 0; + slot = BOOT_PRIMARY_SLOT; } -#ifdef MCUBOOT_VALIDATE_SLOT0 - rc = boot_validate_slot(0, NULL); +#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT + rc = boot_validate_slot(BOOT_PRIMARY_SLOT, NULL); if (rc != 0) { rc = BOOT_EBADIMAGE; goto out; } #else - /* Even if we're not re-validating slot 0, we could be booting + /* Even if we're not re-validating the primary slot, we could be booting * onto an empty flash chip. At least do a basic sanity check that * the magic number on the image is OK. */ - if (boot_data.imgs[0].hdr.ih_magic != IMAGE_MAGIC) { - BOOT_LOG_ERR("bad image magic 0x%lx", (unsigned long)boot_data.imgs[0].hdr.ih_magic); + if (boot_data.imgs[BOOT_PRIMARY_SLOT].hdr.ih_magic != IMAGE_MAGIC) { + BOOT_LOG_ERR("bad image magic 0x%lx", + (unsigned long)boot_data.imgs[BOOT_PRIMARY_SLOT].hdr.ih_magic); rc = BOOT_EBADIMAGE; goto out; } #endif /* Always boot from the primary slot. */ - rsp->br_flash_dev_id = boot_data.imgs[0].area->fa_device_id; - rsp->br_image_off = boot_img_slot_off(&boot_data, 0); + rsp->br_flash_dev_id = boot_data.imgs[BOOT_PRIMARY_SLOT].area->fa_device_id; + rsp->br_image_off = boot_img_slot_off(&boot_data, BOOT_PRIMARY_SLOT); rsp->br_hdr = boot_img_hdr(&boot_data, slot); out: diff --git a/boot/bootutil/test/pkg.yml b/boot/bootutil/test/pkg.yml index 5da5fd79c..74da52566 100644 --- a/boot/bootutil/test/pkg.yml +++ b/boot/bootutil/test/pkg.yml @@ -28,3 +28,4 @@ pkg.deps: pkg.deps.SELFTEST: - "@apache-mynewt-core/sys/console/stub" + - "@apache-mynewt-core/sys/log/stub" diff --git a/boot/bootutil/test/src/boot_test.h b/boot/bootutil/test/src/boot_test.h index eec85b182..08c9c0837 100644 --- a/boot/bootutil/test/src/boot_test.h +++ b/boot/bootutil/test/src/boot_test.h @@ -73,9 +73,9 @@ void boot_test_util_verify_area(const struct flash_area *area_desc, uint32_t image_addr, int img_msb); void boot_test_util_verify_status_clear(void); void boot_test_util_verify_flash(const struct image_header *hdr0, - int orig_slot_0, + int orig_primary_slot, const struct image_header *hdr1, - int orig_slot_1); + int orig_secondary_slot); void boot_test_util_verify_all(int expected_swap_type, const struct image_header *hdr0, const struct image_header *hdr1); diff --git a/boot/bootutil/test/src/boot_test_utils.c b/boot/bootutil/test/src/boot_test_utils.c index bf66d2480..3758743e5 100644 --- a/boot/bootutil/test/src/boot_test_utils.c +++ b/boot/bootutil/test/src/boot_test_utils.c @@ -62,7 +62,7 @@ boot_test_util_flash_align(void) const struct flash_area *fap; int rc; - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY, &fap); TEST_ASSERT_FATAL(rc == 0); return flash_area_align(fap); @@ -130,7 +130,7 @@ boot_test_util_area_write_size(int dst_idx, uint32_t off, uint32_t size) return size; } - /* Don't include trailer in copy to second slot. */ + /* Don't include trailer in copy to the secondary slot. */ desc = boot_test_area_descs + dst_idx; elem_sz = boot_test_util_flash_align(); trailer_start = desc->fa_size - boot_trailer_sz(elem_sz); @@ -202,7 +202,7 @@ boot_test_util_write_image(const struct image_header *hdr, int slot) int rc; int i; - TEST_ASSERT(slot == 0 || slot == 1); + TEST_ASSERT(slot == BOOT_PRIMARY_SLOT || slot == BOOT_SECONDARY_SLOT); flash_id = boot_test_img_addrs[slot].flash_id; off = boot_test_img_addrs[slot].address; @@ -313,25 +313,27 @@ boot_test_util_write_swap_state(int flash_area_id, void boot_test_util_mark_revert(void) { - struct boot_swap_state state_slot0 = { + struct boot_swap_state state_primary_slot = { .magic = BOOT_MAGIC_GOOD, .copy_done = 0x01, .image_ok = 0xff, }; - boot_test_util_write_swap_state(FLASH_AREA_IMAGE_0, &state_slot0); + boot_test_util_write_swap_state(FLASH_AREA_IMAGE_PRIMARY, + &state_primary_slot); } void boot_test_util_mark_swap_perm(void) { - struct boot_swap_state state_slot0 = { + struct boot_swap_state state_primary_slot = { .magic = BOOT_MAGIC_GOOD, .copy_done = 0x01, .image_ok = 0x01, }; - boot_test_util_write_swap_state(FLASH_AREA_IMAGE_0, &state_slot0); + boot_test_util_write_swap_state(FLASH_AREA_IMAGE_PRIMARY, + &state_primary_slot); } void @@ -412,20 +414,22 @@ boot_test_util_verify_area(const struct flash_area *area_desc, void boot_test_util_verify_status_clear(void) { - struct boot_swap_state state_slot0; + struct boot_swap_state state_primary_slot; int rc; - rc = boot_read_swap_state_img(0, &state_slot0); + rc = boot_read_swap_state_img(0, &state_primary_slot); assert(rc == 0); - TEST_ASSERT(state_slot0.magic != BOOT_MAGIC_UNSET || - state_slot0.copy_done != 0); + TEST_ASSERT(state_primary_slot.magic != BOOT_MAGIC_UNSET || + state_primary_slot.copy_done != 0); } void -boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0, - const struct image_header *hdr1, int orig_slot_1) +boot_test_util_verify_flash(const struct image_header *hdr0, + int orig_primary_slot, + const struct image_header *hdr1, + int orig_secondary_slot) { const struct flash_area *area_desc; int area_idx; @@ -440,7 +444,8 @@ boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0, } boot_test_util_verify_area(area_desc, hdr0, - boot_test_img_addrs[0].address, orig_slot_0); + boot_test_img_addrs[0].address, + orig_primary_slot); area_idx++; } @@ -451,7 +456,8 @@ boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0, area_desc = boot_test_area_descs + area_idx; boot_test_util_verify_area(area_desc, hdr1, - boot_test_img_addrs[1].address, orig_slot_1); + boot_test_img_addrs[1].address, + orig_secondary_slot); area_idx++; } } @@ -461,12 +467,12 @@ boot_test_util_verify_all(int expected_swap_type, const struct image_header *hdr0, const struct image_header *hdr1) { - const struct image_header *slot0hdr; - const struct image_header *slot1hdr; + const struct image_header *primary_slot_hdr; + const struct image_header *secondary_slot_hdr; struct boot_rsp rsp; uintptr_t flash_base; - int orig_slot_0; - int orig_slot_1; + int orig_primary_slot; + int orig_secondary_slot; int num_swaps; int rc; int i; @@ -484,36 +490,37 @@ boot_test_util_verify_all(int expected_swap_type, if (num_swaps % 2 == 0) { if (hdr0 != NULL) { - slot0hdr = hdr0; - slot1hdr = hdr1; + primary_slot_hdr = hdr0; + secondary_slot_hdr = hdr1; } else { - slot0hdr = hdr1; - slot1hdr = hdr0; + primary_slot_hdr = hdr1; + secondary_slot_hdr = hdr0; } - orig_slot_0 = 0; - orig_slot_1 = 1; + orig_primary_slot = BOOT_PRIMARY_SLOT; + orig_secondary_slot = BOOT_SECONDARY_SLOT; } else { if (hdr1 != NULL) { - slot0hdr = hdr1; - slot1hdr = hdr0; + primary_slot_hdr = hdr1; + secondary_slot_hdr = hdr0; } else { - slot0hdr = hdr0; - slot1hdr = hdr1; + primary_slot_hdr = hdr0; + secondary_slot_hdr = hdr1; } - orig_slot_0 = 1; - orig_slot_1 = 0; + orig_primary_slot = BOOT_SECONDARY_SLOT; + orig_secondary_slot = BOOT_PRIMARY_SLOT; } rc = flash_device_base(rsp->br_flash_dev_id, &flash_base); TEST_ASSERT_FATAL(rc == 0); - TEST_ASSERT(memcmp(rsp.br_hdr, slot0hdr, sizeof *slot0hdr) == 0); + TEST_ASSERT(memcmp(rsp.br_hdr, primary_slot_hdr, + sizeof *primary_slot_hdr) == 0); TEST_ASSERT(rsp.br_flash_dev_id == boot_test_img_addrs[0].flash_id); TEST_ASSERT(flash_base + rsp.br_image_off == boot_test_img_addrs[0].address); - boot_test_util_verify_flash(slot0hdr, orig_slot_0, - slot1hdr, orig_slot_1); + boot_test_util_verify_flash(primary_slot_hdr, orig_primary_slot, + secondary_slot_hdr, orig_secondary_slot); boot_test_util_verify_status_clear(); if (expected_swap_type != BOOT_SWAP_TYPE_NONE) { diff --git a/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c b/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c index bac3f7ed0..dedde95ba 100644 --- a/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c +++ b/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c @@ -44,9 +44,9 @@ TEST_CASE(boot_test_invalid_hash) .it_len = 32 }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); rc = hal_flash_write(boot_test_img_addrs[1].flash_id, boot_test_img_addrs[1].address + hdr1.ih_hdr_size + hdr1.ih_img_size, &tlv, sizeof(tlv)); diff --git a/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c b/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c index b6a8ec55f..30e098db4 100644 --- a/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c +++ b/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c @@ -40,10 +40,10 @@ TEST_CASE(boot_test_no_flag_has_hash) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); TEST_ASSERT(rc == 0); diff --git a/boot/bootutil/test/src/testcases/boot_test_no_hash.c b/boot/bootutil/test/src/testcases/boot_test_no_hash.c index 13fe7e155..ff40482b7 100644 --- a/boot/bootutil/test/src/testcases/boot_test_no_hash.c +++ b/boot/bootutil/test/src/testcases/boot_test_no_hash.c @@ -40,9 +40,9 @@ TEST_CASE(boot_test_no_hash) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); TEST_ASSERT(rc == 0); diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_bs_10.c b/boot/bootutil/test/src/testcases/boot_test_nv_bs_10.c index 1d8d50c16..46548e02d 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_bs_10.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_bs_10.c @@ -30,8 +30,8 @@ TEST_CASE(boot_test_nv_bs_10) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 0); - boot_test_util_write_hash(&hdr, 0); + boot_test_util_write_image(&hdr, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr, BOOT_PRIMARY_SLOT); boot_test_util_swap_areas(boot_test_slot_areas[1], BOOT_TEST_AREA_IDX_SCRATCH); diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c index eae13bda0..26a5989ea 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c @@ -42,10 +42,10 @@ TEST_CASE(boot_test_nv_bs_11) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); boot_test_util_copy_area(5, BOOT_TEST_AREA_IDX_SCRATCH); diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c index ba09ea13a..ae5e1c429 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c @@ -42,10 +42,10 @@ TEST_CASE(boot_test_nv_bs_11_2areas) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); TEST_ASSERT_FATAL(rc == 0); diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c b/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c index 8abd90e96..7fdc0fd90 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c @@ -30,8 +30,8 @@ TEST_CASE(boot_test_nv_ns_01) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 1); - boot_test_util_write_hash(&hdr, 1); + boot_test_util_write_image(&hdr, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr, BOOT_SECONDARY_SLOT); boot_set_pending(0); diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_ns_10.c b/boot/bootutil/test/src/testcases/boot_test_nv_ns_10.c index 429416e00..d548e0511 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_ns_10.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_ns_10.c @@ -30,8 +30,8 @@ TEST_CASE(boot_test_nv_ns_10) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 0); - boot_test_util_write_hash(&hdr, 0); + boot_test_util_write_image(&hdr, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr, BOOT_PRIMARY_SLOT); boot_test_util_verify_all(BOOT_SWAP_TYPE_NONE, &hdr, NULL); } diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_ns_11.c b/boot/bootutil/test/src/testcases/boot_test_nv_ns_11.c index 971a2cfad..6e7bb47b3 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_ns_11.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_ns_11.c @@ -39,10 +39,10 @@ TEST_CASE(boot_test_nv_ns_11) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); boot_test_util_verify_all(BOOT_SWAP_TYPE_NONE, &hdr0, &hdr1); } diff --git a/boot/bootutil/test/src/testcases/boot_test_permanent.c b/boot/bootutil/test/src/testcases/boot_test_permanent.c index 489ebd6ea..839e65cd5 100644 --- a/boot/bootutil/test/src/testcases/boot_test_permanent.c +++ b/boot/bootutil/test/src/testcases/boot_test_permanent.c @@ -41,10 +41,10 @@ TEST_CASE(boot_test_permanent) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(1); TEST_ASSERT_FATAL(rc == 0); diff --git a/boot/bootutil/test/src/testcases/boot_test_permanent_continue.c b/boot/bootutil/test/src/testcases/boot_test_permanent_continue.c index 2417df062..9b5fe6832 100644 --- a/boot/bootutil/test/src/testcases/boot_test_permanent_continue.c +++ b/boot/bootutil/test/src/testcases/boot_test_permanent_continue.c @@ -42,12 +42,12 @@ TEST_CASE(boot_test_permanent_continue) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); - /* Indicate that the image in slot 0 is being permanently used. */ + /* Indicate that the image in the primary slot is being permanently used. */ boot_test_util_mark_swap_perm(); boot_test_util_swap_areas(2, 5); diff --git a/boot/bootutil/test/src/testcases/boot_test_revert.c b/boot/bootutil/test/src/testcases/boot_test_revert.c index 4b78fb6c9..b44fbe14e 100644 --- a/boot/bootutil/test/src/testcases/boot_test_revert.c +++ b/boot/bootutil/test/src/testcases/boot_test_revert.c @@ -38,12 +38,12 @@ TEST_CASE(boot_test_revert) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); - /* Indicate that the image in slot 0 is being tested. */ + /* Indicate that the image in the primary slot is being tested. */ boot_test_util_mark_revert(); boot_test_util_verify_all(BOOT_SWAP_TYPE_REVERT, &hdr0, &hdr1); diff --git a/boot/bootutil/test/src/testcases/boot_test_revert_continue.c b/boot/bootutil/test/src/testcases/boot_test_revert_continue.c index 99826462a..3887f4f1f 100644 --- a/boot/bootutil/test/src/testcases/boot_test_revert_continue.c +++ b/boot/bootutil/test/src/testcases/boot_test_revert_continue.c @@ -42,12 +42,12 @@ TEST_CASE(boot_test_revert_continue) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); - /* Indicate that the image in slot 0 is being tested. */ + /* Indicate that the image in the primary slot is being tested. */ boot_test_util_mark_revert(); boot_test_util_swap_areas(2, 5); diff --git a/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c b/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c index e9b961db4..8b19f8783 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c +++ b/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c @@ -41,10 +41,10 @@ TEST_CASE(boot_test_vb_ns_11) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); TEST_ASSERT(rc == 0); diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c index a539fa2d9..fb1983f40 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c @@ -32,8 +32,8 @@ TEST_CASE(boot_test_vm_ns_01) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 1); - boot_test_util_write_hash(&hdr, 1); + boot_test_util_write_image(&hdr, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); TEST_ASSERT(rc == 0); diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_10.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_10.c index d6d217ec1..16bf5e96d 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_10.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_10.c @@ -30,8 +30,8 @@ TEST_CASE(boot_test_vm_ns_10) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr, 0); - boot_test_util_write_hash(&hdr, 0); + boot_test_util_write_image(&hdr, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr, BOOT_PRIMARY_SLOT); boot_test_util_verify_all(BOOT_SWAP_TYPE_NONE, &hdr, NULL); } diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c index 24b5da2b6..ab1723ad4 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c @@ -41,10 +41,10 @@ TEST_CASE(boot_test_vm_ns_11_2areas) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); TEST_ASSERT(rc == 0); diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_a.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_a.c index 433be2579..0d46762ea 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_a.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_a.c @@ -39,10 +39,10 @@ TEST_CASE(boot_test_vm_ns_11_a) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); boot_test_util_verify_all(BOOT_SWAP_TYPE_NONE, &hdr0, &hdr1); } diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c index e1a87c7f0..628ca5818 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c @@ -41,10 +41,10 @@ TEST_CASE(boot_test_vm_ns_11_b) }; boot_test_util_init_flash(); - boot_test_util_write_image(&hdr0, 0); - boot_test_util_write_hash(&hdr0, 0); - boot_test_util_write_image(&hdr1, 1); - boot_test_util_write_hash(&hdr1, 1); + boot_test_util_write_image(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_hash(&hdr0, BOOT_PRIMARY_SLOT); + boot_test_util_write_image(&hdr1, BOOT_SECONDARY_SLOT); + boot_test_util_write_hash(&hdr1, BOOT_SECONDARY_SLOT); rc = boot_set_pending(0); TEST_ASSERT(rc == 0); diff --git a/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h b/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h index fb2ec6bcb..e826865a5 100644 --- a/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h +++ b/boot/mynewt/mcuboot_config/include/mcuboot_config/mcuboot_config.h @@ -25,7 +25,7 @@ #define MCUBOOT_SERIAL 1 #endif #if MYNEWT_VAL(BOOTUTIL_VALIDATE_SLOT0) -#define MCUBOOT_VALIDATE_SLOT0 1 +#define MCUBOOT_VALIDATE_PRIMARY_SLOT 1 #endif #if MYNEWT_VAL(BOOTUTIL_USE_MBED_TLS) #define MCUBOOT_USE_MBED_TLS 1 diff --git a/boot/mynewt/src/main.c b/boot/mynewt/src/main.c index 891e19dc4..aadda3657 100755 --- a/boot/mynewt/src/main.c +++ b/boot/mynewt/src/main.c @@ -218,8 +218,8 @@ main(void) assert(rc == 0); #endif -#if defined(MCUBOOT_SERIAL) || defined(MCUBOOT_HAVE_LOGGING) - /* initialize uart without os */ +#if defined(MCUBOOT_SERIAL) || defined(MCUBOOT_HAVE_LOGGING) || MYNEWT_VAL(CRYPTO) + /* initialize uart/crypto without os */ os_dev_initialize_all(OS_DEV_INIT_PRIMARY); os_dev_initialize_all(OS_DEV_INIT_SECONDARY); sysinit(); diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 470103cf0..fa7b03b44 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -7,17 +7,6 @@ cmake_minimum_required(VERSION 3.8.2) # Board-specific CONF_FILES should get merged into the build as well. -# -# Do this by defining the set_conf_file macro: -# http://docs.zephyrproject.org/application/application.html#application-configuration -macro(set_conf_file) - if (EXISTS ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf) - set(CONF_FILE "prj.conf ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf") - else() - set(CONF_FILE prj.conf) - endif() -endmacro() - # Default to qemu_x86 if no board has been specified. set(BOARD qemu_x86) @@ -68,8 +57,18 @@ get_filename_component(BOOT_DIR ${APPLICATION_SOURCE_DIR} DIRECTORY) get_filename_component(MCUBOOT_DIR ${BOOT_DIR} DIRECTORY) # Path to tinycrypt library source subdirectory of MCUBOOT_DIR. set(TINYCRYPT_DIR "${MCUBOOT_DIR}/ext/tinycrypt/lib") +assert_exists(TINYCRYPT_DIR) # Path to mbed-tls' asn1 parser library. set(MBEDTLS_ASN1_DIR "${MCUBOOT_DIR}/ext/mbedtls") +assert_exists(MBEDTLS_ASN1_DIR) +set(NRF_DIR "${MCUBOOT_DIR}/ext/nrf") + +if(CONFIG_BOOT_USE_NRF_CC310_BL) +set(NRFXLIB_DIR ${MCUBOOT_DIR}/../nrfxlib) +assert_exists(NRFXLIB_DIR) +# Don't include this if we are using west + add_subdirectory(${NRFXLIB_DIR} ${PROJECT_BINARY_DIR}/nrfxlib) +endif() zephyr_library_include_directories( include @@ -106,11 +105,19 @@ zephyr_library_sources( ) if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) + zephyr_library_include_directories( + ${MBEDTLS_ASN1_DIR}/include + ) + zephyr_library_sources( + # Additionally pull in just the ASN.1 parser from mbedTLS. + ${MBEDTLS_ASN1_DIR}/src/asn1parse.c + ${MBEDTLS_ASN1_DIR}/src/platform_util.c + ) + if(CONFIG_BOOT_USE_TINYCRYPT) # When using ECDSA signatures, pull in our copy of the tinycrypt library. zephyr_library_include_directories( ${BOOT_DIR}/zephyr/include ${TINYCRYPT_DIR}/include - ${MBEDTLS_ASN1_DIR}/include ) zephyr_library_sources( @@ -118,11 +125,12 @@ if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) ${TINYCRYPT_DIR}/source/ecc_dsa.c ${TINYCRYPT_DIR}/source/sha256.c ${TINYCRYPT_DIR}/source/utils.c - - # Additionally pull in just the ASN.1 parser from mbedTLS. - ${MBEDTLS_ASN1_DIR}/src/asn1parse.c - ${MBEDTLS_ASN1_DIR}/src/platform_util.c - ) + ) + elseif(CONFIG_BOOT_USE_NRF_CC310_BL) + zephyr_library_sources(${NRF_DIR}/cc310_glue.c) + zephyr_library_include_directories(${NRF_DIR}) + zephyr_link_libraries(nrfxlib_crypto) + endif() # Since here we are not using Zephyr's mbedTLS but rather our own, we need # to set MBEDTLS_CONFIG_FILE ourselves. When using Zephyr's copy, this @@ -175,3 +183,4 @@ if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "") ) zephyr_library_sources(${GENERATED_PUBKEY}) endif() + diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 77c5b6300..ac0176d85 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -12,6 +12,7 @@ config MCUBOOT default y bool select MPU_ALLOW_FLASH_WRITE if ARM_MPU + select USE_CODE_PARTITION if HAS_FLASH_LOAD_OFFSET if BOARD_HAS_NRF5_BOOTLOADER @@ -43,6 +44,29 @@ config BOOT_USE_TINYCRYPT help Use TinyCrypt for crypto primitives. +config BOOT_USE_CC310 + bool + # Hidden option + default n + # When building for ECDSA, we use our own copy of mbedTLS, so the + # Zephyr one must not be enabled or the MBEDTLS_CONFIG_FILE macros + # will collide. + depends on ! MBEDTLS + help + Use cc310 for crypto primitives. + +config BOOT_USE_NRF_CC310_BL + bool + default n + +config NRFXLIB_CRYPTO + bool + default n + +config NRF_CC310_BL + bool + default n + menu "MCUBoot settings" choice @@ -56,8 +80,22 @@ config BOOT_SIGNATURE_TYPE_RSA config BOOT_SIGNATURE_TYPE_ECDSA_P256 bool "Elliptic curve digital signatures with curve P-256" - select BOOT_USE_TINYCRYPT +if BOOT_SIGNATURE_TYPE_ECDSA_P256 +choice + prompt "Ecdsa implementation" + default BOOT_TINYCRYPT +config BOOT_TINYCRYPT + bool "Use tinycrypt" + select BOOT_USE_TINYCRYPT +config BOOT_CC310 + bool "Use CC310" + select BOOT_USE_NRF_CC310_BL if HAS_HW_NRF_CC310 + select NRF_CC310_BL if HAS_HW_NRF_CC310 + select NRFXLIB_CRYPTO if SOC_FAMILY_NRF + select BOOT_USE_CC310 +endchoice +endif endchoice config BOOT_SIGNATURE_KEY_FILE @@ -72,11 +110,11 @@ config MBEDTLS_CFG_FILE default "mcuboot-mbedtls-cfg.h" config BOOT_VALIDATE_SLOT0 - bool "Validate image slot 0 on every boot" + bool "Validate image in the primary slot on every boot" default y help - If y, the bootloader attempts to validate the signature of - slot0 every boot. This adds the signature check time to + If y, the bootloader attempts to validate the signature of the + primary slot every boot. This adds the signature check time to every boot, but can mitigate against some changes that are able to modify the flash image itself. @@ -84,25 +122,25 @@ config BOOT_UPGRADE_ONLY bool "Overwrite image updates instead of swapping" default n help - If y, overwrite slot0 with the upgrade image instead of - swapping them. This prevents the fallback recovery, but + If y, overwrite the primary slot with the upgrade image instead + of swapping them. This prevents the fallback recovery, but uses a much simpler code path. config BOOT_BOOTSTRAP - bool "Boostrap erased slot0 from slot1" + bool "Boostrap erased the primary slot from the secondary slot" default n help If y, enables bootstraping support. Bootstrapping allows an erased - slot0 to be initialized from a valid image in slot1. + primary slot to be initialized from a valid image in the secondary slot. If unsure, leave at the default value. config BOOT_ENCRYPT_RSA bool "Support for encrypted upgrade images" default n help - If y, images in slot 1 can be encrypted and are decrypted - on the fly when upgrading to slot 0, as well as encrypted - back when swapping from slot 0 to slot 1. + If y, images in the secondary slot can be encrypted and are decrypted + on the fly when upgrading to the primary slot, as well as encrypted + back when swapping from the primary slot to the secondary slot. config BOOT_MAX_IMG_SECTORS int "Maximum number of sectors per image slot" @@ -122,6 +160,17 @@ config BOOT_ERASE_PROGRESSIVELY on some hardware that has long erase times, to prevent long wait times at the beginning of the DFU process. +config BOOT_WAIT_FOR_USB_DFU + bool "Wait for a prescribed duration to see if USB DFU is invoked" + default n + select USB + select USB_DFU_CLASS + select IMG_MANAGER + help + If y, MCUboot waits for a prescribed duration of time to allow + for USB DFU to be invoked. Please note DFU always updates the + slot1 image. + config ZEPHYR_TRY_MASS_ERASE bool "Try to mass erase flash when flashing MCUboot image" default y diff --git a/boot/zephyr/boards/intel_s1000_crb.conf b/boot/zephyr/boards/intel_s1000_crb.conf index 429209b8b..e3c5ee430 100644 --- a/boot/zephyr/boards/intel_s1000_crb.conf +++ b/boot/zephyr/boards/intel_s1000_crb.conf @@ -1,8 +1,5 @@ -CONFIG_BOOT_HAVE_LOGGING=n -CONFIG_USB_DRIVER_LOG_LEVEL_ERR=n -CONFIG_USB_DEVICE_LOG_LEVEL_ERR=n - CONFIG_DEBUG=n CONFIG_I2C=n CONFIG_BOOT_MAX_IMG_SECTORS=512 CONFIG_MULTITHREADING=y +CONFIG_BOOT_WAIT_FOR_USB_DFU=y diff --git a/boot/zephyr/flash_map_extended.c b/boot/zephyr/flash_map_extended.c index 86ca21f61..1fd89da56 100644 --- a/boot/zephyr/flash_map_extended.c +++ b/boot/zephyr/flash_map_extended.c @@ -51,12 +51,13 @@ int flash_device_base(uint8_t fd_id, uintptr_t *ret) /* * This depends on the mappings defined in sysflash.h. - * MCUBoot uses continuous numbering for slot 0, slot 1, and the scratch - * while zephyr might number it differently. + * MCUBoot uses continuous numbering for the primary slot, the secondary slot, + * and the scratch while zephyr might number it differently. */ int flash_area_id_from_image_slot(int slot) { - static const int area_id_tab[] = {FLASH_AREA_IMAGE_0, FLASH_AREA_IMAGE_1, + static const int area_id_tab[] = {FLASH_AREA_IMAGE_PRIMARY, + FLASH_AREA_IMAGE_SECONDARY, FLASH_AREA_IMAGE_SCRATCH}; if (slot >= 0 && slot < ARRAY_SIZE(area_id_tab)) { @@ -66,6 +67,19 @@ int flash_area_id_from_image_slot(int slot) return -EINVAL; /* flash_area_open will fail on that */ } +int flash_area_id_to_image_slot(int area_id) +{ + switch (area_id) { + case FLASH_AREA_IMAGE_PRIMARY: + return 0; + case FLASH_AREA_IMAGE_SECONDARY: + return 1; + default: + BOOT_LOG_ERR("invalid flash area ID"); + return -1; + } +} + int flash_area_sector_from_off(off_t off, struct flash_sector *sector) { int rc; diff --git a/boot/zephyr/include/config-kw.h b/boot/zephyr/include/config-kw.h index 8ff31aee2..41e5baa35 100644 --- a/boot/zephyr/include/config-kw.h +++ b/boot/zephyr/include/config-kw.h @@ -38,11 +38,15 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY #define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/* STD functions */ +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +#define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_PLATFORM_PRINTF_ALT +#define MBEDTLS_PLATFORM_SNPRINTF_ALT #define MBEDTLS_ASN1_PARSE_C diff --git a/boot/zephyr/include/config-rsa-kw.h b/boot/zephyr/include/config-rsa-kw.h index 3568cc01c..eb9143c6a 100644 --- a/boot/zephyr/include/config-rsa-kw.h +++ b/boot/zephyr/include/config-rsa-kw.h @@ -38,11 +38,15 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY #define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/* STD functions */ +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +#define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_PLATFORM_PRINTF_ALT +#define MBEDTLS_PLATFORM_SNPRINTF_ALT #if !defined(CONFIG_ARM) #define MBEDTLS_HAVE_ASM diff --git a/boot/zephyr/include/config-rsa.h b/boot/zephyr/include/config-rsa.h index d27acf9b5..2e1153d28 100644 --- a/boot/zephyr/include/config-rsa.h +++ b/boot/zephyr/include/config-rsa.h @@ -38,11 +38,15 @@ #define MBEDTLS_PLATFORM_C #define MBEDTLS_PLATFORM_MEMORY #define MBEDTLS_MEMORY_BUFFER_ALLOC_C -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_NO_PLATFORM_ENTROPY #define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/* STD functions */ +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +#define MBEDTLS_PLATFORM_EXIT_ALT #define MBEDTLS_PLATFORM_PRINTF_ALT +#define MBEDTLS_PLATFORM_SNPRINTF_ALT #if !defined(CONFIG_ARM) #define MBEDTLS_HAVE_ASM diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h index 178c34f06..c082dd6b9 100644 --- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h +++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h @@ -52,6 +52,14 @@ int flash_device_base(uint8_t fd_id, uintptr_t *ret); int flash_area_id_from_image_slot(int slot); +/** + * Converts the specified flash area ID to an image slot index. + * + * Returns image slot index (0 or 1), or -1 if ID doesn't correspond to an image + * slot. + */ +int flash_area_id_to_image_slot(int area_id); + /* Retrieve the flash sector a given offset belongs to. * * Returns 0 on success, or an error code on failure. diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index d30e108b2..406d7ba99 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -28,10 +28,15 @@ #define MCUBOOT_USE_MBED_TLS #elif defined(CONFIG_BOOT_USE_TINYCRYPT) #define MCUBOOT_USE_TINYCRYPT +#elif defined(CONFIG_BOOT_USE_CC310) +#define MCUBOOT_USE_CC310 +#ifdef CONFIG_BOOT_USE_NRF_CC310_BL +#define MCUBOOT_USE_NRF_CC310_BL +#endif #endif #ifdef CONFIG_BOOT_VALIDATE_SLOT0 -#define MCUBOOT_VALIDATE_SLOT0 +#define MCUBOOT_VALIDATE_PRIMARY_SLOT #endif #ifdef CONFIG_BOOT_UPGRADE_ONLY diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 0fef02607..24922444d 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -5,8 +5,8 @@ #include -#define FLASH_AREA_IMAGE_0 DT_FLASH_AREA_IMAGE_0_ID -#define FLASH_AREA_IMAGE_1 DT_FLASH_AREA_IMAGE_1_ID -#define FLASH_AREA_IMAGE_SCRATCH DT_FLASH_AREA_IMAGE_SCRATCH_ID +#define FLASH_AREA_IMAGE_PRIMARY DT_FLASH_AREA_IMAGE_0_ID +#define FLASH_AREA_IMAGE_SECONDARY DT_FLASH_AREA_IMAGE_1_ID +#define FLASH_AREA_IMAGE_SCRATCH DT_FLASH_AREA_IMAGE_SCRATCH_ID #endif /* __SYSFLASH_H__ */ diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index 236f80c41..e276454ca 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -40,6 +40,10 @@ const struct boot_uart_funcs boot_funcs = { }; #endif +#ifdef CONFIG_BOOT_WAIT_FOR_USB_DFU +#include +#endif + MCUBOOT_LOG_MODULE_REGISTER(mcuboot); void os_heap_init(void); @@ -197,6 +201,12 @@ void main(void) } #endif +#ifdef CONFIG_BOOT_WAIT_FOR_USB_DFU + BOOT_LOG_INF("Waiting for USB DFU"); + wait_for_usb_dfu(); + BOOT_LOG_INF("USB DFU wait time elapsed"); +#endif + rc = boot_go(&rsp); if (rc != 0) { BOOT_LOG_ERR("Unable to find bootable image"); diff --git a/scripts/check-signed-off-by.sh b/ci/check-signed-off-by.sh similarity index 100% rename from scripts/check-signed-off-by.sh rename to ci/check-signed-off-by.sh diff --git a/ci/mynewt_install.sh b/ci/mynewt_install.sh new file mode 100755 index 000000000..abadfb383 --- /dev/null +++ b/ci/mynewt_install.sh @@ -0,0 +1,65 @@ +#!/bin/bash -x + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +install_newt() { + pushd $HOME + git clone --depth=1 https://github.com/apache/mynewt-newt + [[ $? -ne 0 ]] && exit 1 + + pushd mynewt-newt && ./build.sh + [[ $? -ne 0 ]] && exit 1 + + cp newt/newt $HOME/bin + popd + popd +} + +shallow_clone_mynewt() { + mkdir -p repos/apache-mynewt-core + git clone --depth=1 https://github.com/apache/mynewt-core repos/apache-mynewt-core + [[ $? -ne 0 ]] && exit 1 +} + +arm_toolchain_install() { + TOOLCHAIN_PATH=$HOME/TOOLCHAIN + + GCC_URL=https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2017q4/gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2 + GCC_BASE=gcc-arm-none-eabi-7-2017-q4-major + + mkdir -p $TOOLCHAIN_PATH + + if [ ! -s ${TOOLCHAIN_PATH}/$GCC_BASE/bin/arm-none-eabi-gcc ]; then + wget -O ${TOOLCHAIN_PATH}/${GCC_BASE}.tar.bz2 $GCC_URL + [[ $? -ne 0 ]] && exit 1 + + tar xfj ${TOOLCHAIN_PATH}/${GCC_BASE}.tar.bz2 -C $TOOLCHAIN_PATH + fi + + for i in ${TOOLCHAIN_PATH}/${GCC_BASE}/bin/arm-none-eabi-* ; do + rm -f $HOME/bin/${i##*/} + ln -s $i $HOME/bin/${i##*/} + done +} + +mkdir -p $HOME/bin +export PATH=$HOME/bin:$PATH + +install_newt +shallow_clone_mynewt +arm_toolchain_install diff --git a/ci/mynewt_keys/enc_kw/pkg.yml b/ci/mynewt_keys/enc_kw/pkg.yml new file mode 100644 index 000000000..0e993a46e --- /dev/null +++ b/ci/mynewt_keys/enc_kw/pkg.yml @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: keys/enc_kw +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" diff --git a/ci/mynewt_keys/enc_kw/src/keys.c b/ci/mynewt_keys/enc_kw/src/keys.c new file mode 100644 index 000000000..ae4c5c7bb --- /dev/null +++ b/ci/mynewt_keys/enc_kw/src/keys.c @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +unsigned char enc_key[] = { + 0x96, 0x69, 0xd2, 0xcf, 0x0e, 0xb1, 0xc6, 0x56, 0xf2, 0xa0, 0x1f, 0x46, + 0x06, 0xd3, 0x49, 0x31, +}; +static unsigned int enc_key_len = 16; +const struct bootutil_key bootutil_enc_key = { + .key = enc_key, + .len = &enc_key_len, +}; diff --git a/ci/mynewt_keys/enc_rsa/pkg.yml b/ci/mynewt_keys/enc_rsa/pkg.yml new file mode 100644 index 000000000..61918f1b4 --- /dev/null +++ b/ci/mynewt_keys/enc_rsa/pkg.yml @@ -0,0 +1,25 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: keys/enc_rsa +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" + +pkg.cflags: + - '-DMBEDTLS_USER_CONFIG_FILE="mbedtls/config_mynewt.h"' diff --git a/ci/mynewt_keys/enc_rsa/src/keys.c b/ci/mynewt_keys/enc_rsa/src/keys.c new file mode 100644 index 000000000..201d6ad12 --- /dev/null +++ b/ci/mynewt_keys/enc_rsa/src/keys.c @@ -0,0 +1,128 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include +#include +unsigned char enc_key[] = { + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, + 0xb4, 0x26, 0x14, 0x49, 0x3d, 0x16, 0x13, 0x3a, 0x6d, 0x9c, 0x84, 0xa9, + 0x8b, 0x6a, 0x10, 0x20, 0x61, 0xef, 0x48, 0x04, 0xa4, 0x4b, 0x24, 0xf3, + 0x00, 0x32, 0xac, 0x22, 0xe0, 0x30, 0x27, 0x70, 0x18, 0xe5, 0x55, 0xc8, + 0xb8, 0x05, 0x34, 0x03, 0xb0, 0xf8, 0xa5, 0x96, 0xd2, 0x48, 0x58, 0xef, + 0x70, 0xb0, 0x09, 0xdb, 0xe3, 0x58, 0x62, 0xef, 0x99, 0x63, 0x01, 0xb2, + 0x89, 0xc4, 0xb3, 0xf6, 0x9e, 0x62, 0xbf, 0x4d, 0xc2, 0x8a, 0xd0, 0xc9, + 0x4d, 0x43, 0xa3, 0xd8, 0xe5, 0x1d, 0xec, 0x62, 0x63, 0x08, 0xe2, 0x20, + 0xa5, 0xfc, 0x78, 0xd0, 0x3e, 0x74, 0xc8, 0xa4, 0x1b, 0x36, 0xad, 0x7b, + 0xf5, 0x06, 0xae, 0x4d, 0x51, 0x9b, 0x40, 0xce, 0x30, 0x4f, 0x6c, 0xea, + 0xf9, 0xe9, 0x74, 0xea, 0x06, 0xee, 0x9c, 0xe4, 0x14, 0x68, 0x20, 0xb9, + 0x3d, 0xe7, 0x11, 0x14, 0x8b, 0x25, 0xa3, 0xff, 0x4c, 0x8a, 0xf3, 0x53, + 0xee, 0x6b, 0x3e, 0xef, 0x34, 0xcd, 0x6a, 0x3f, 0x62, 0x68, 0xc0, 0xff, + 0x78, 0x4c, 0xb0, 0xc3, 0xe6, 0x96, 0x61, 0xfc, 0x1f, 0x18, 0xf1, 0x7a, + 0x82, 0xe2, 0x8f, 0x35, 0xa8, 0x2b, 0x86, 0x16, 0xa4, 0x46, 0xfb, 0xac, + 0x7e, 0x41, 0xdb, 0x02, 0x05, 0x91, 0x6d, 0xdf, 0xc1, 0xde, 0x13, 0x95, + 0x9c, 0xf9, 0x9e, 0x5e, 0x72, 0xba, 0xa7, 0x25, 0x93, 0xfb, 0xdc, 0xe8, + 0xab, 0x86, 0x45, 0x88, 0x47, 0x2d, 0xed, 0xee, 0xee, 0x97, 0x9e, 0xce, + 0x5d, 0x9b, 0x04, 0x04, 0x40, 0x7c, 0xcb, 0x7c, 0x3d, 0x2c, 0x74, 0xab, + 0xa4, 0xcc, 0x64, 0xa3, 0x5c, 0x95, 0x3d, 0xd4, 0xa2, 0xdc, 0x92, 0xb2, + 0xc8, 0x18, 0xcb, 0xf9, 0x00, 0x39, 0x81, 0x8f, 0x8f, 0x40, 0xc2, 0xdf, + 0x99, 0x29, 0xac, 0x8a, 0xc2, 0x3b, 0xd8, 0xa4, 0xf2, 0xad, 0xaf, 0x74, + 0xc0, 0x11, 0xc7, 0x99, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x00, 0x42, 0x47, 0x80, 0x4f, 0x31, 0xda, 0x5d, 0x58, 0xb1, 0xdb, 0x54, + 0x33, 0xcc, 0xc7, 0x49, 0x07, 0xa1, 0x00, 0x98, 0x4e, 0x9c, 0xe3, 0xc8, + 0xc4, 0x5e, 0xde, 0x45, 0xd6, 0xcf, 0x04, 0xe8, 0x7d, 0xa5, 0xab, 0x3a, + 0xd4, 0x8e, 0x5f, 0xdb, 0xb3, 0x3f, 0xf9, 0x3b, 0x73, 0x32, 0x0a, 0xcc, + 0x2d, 0xcc, 0x17, 0xf8, 0x88, 0x9e, 0x2c, 0x76, 0xba, 0x10, 0x85, 0x0c, + 0xaa, 0xd3, 0x65, 0x3b, 0x91, 0x10, 0xd4, 0xe3, 0xed, 0x88, 0x15, 0xea, + 0x9b, 0x25, 0x82, 0x2d, 0x56, 0x2f, 0x75, 0xc2, 0xf2, 0xaf, 0xdd, 0x24, + 0xd5, 0x3e, 0x3c, 0x95, 0x76, 0x88, 0x84, 0x0f, 0x0d, 0xd1, 0xb5, 0x5c, + 0x3e, 0xae, 0xf7, 0xb6, 0x49, 0x5c, 0x2c, 0xf2, 0xba, 0xe9, 0xab, 0x4f, + 0x37, 0x64, 0x9b, 0x30, 0x18, 0xaa, 0x54, 0x40, 0x04, 0xea, 0x3d, 0x25, + 0x4d, 0x02, 0x29, 0x71, 0x6f, 0x4d, 0x82, 0x9b, 0xc3, 0x44, 0x2a, 0x9d, + 0x0c, 0x98, 0xd3, 0xc8, 0x15, 0x0d, 0x04, 0x93, 0x60, 0x30, 0xc7, 0x5e, + 0x79, 0xea, 0x53, 0x9d, 0xc0, 0x0e, 0x81, 0xac, 0x90, 0xbc, 0x9e, 0x1e, + 0xd2, 0x28, 0x0f, 0x10, 0xf5, 0x1f, 0xdf, 0x38, 0x7f, 0x8a, 0x90, 0x8d, + 0x49, 0x07, 0x7d, 0x78, 0xcb, 0xa7, 0xef, 0x92, 0x6d, 0x3b, 0x13, 0x95, + 0x9b, 0xba, 0x83, 0xc6, 0xb3, 0x71, 0x25, 0x27, 0x07, 0x99, 0x54, 0x82, + 0x3d, 0xec, 0xc5, 0xf8, 0xb4, 0xa0, 0x38, 0x7a, 0x59, 0x6a, 0x0b, 0xca, + 0x69, 0x6c, 0x17, 0xa4, 0x18, 0xe0, 0xb4, 0xaa, 0x89, 0x99, 0x8f, 0xcb, + 0x71, 0x34, 0x09, 0x1b, 0x6e, 0xe6, 0x87, 0x00, 0xb5, 0xba, 0x70, 0x8a, + 0x29, 0x3d, 0x9a, 0x06, 0x18, 0x2d, 0x66, 0x5e, 0x61, 0x37, 0xeb, 0xdd, + 0x5e, 0xc8, 0x28, 0x92, 0x05, 0x30, 0xfd, 0xb8, 0x65, 0xb1, 0x7f, 0xbf, + 0x2d, 0x55, 0x12, 0x91, 0xc1, 0x02, 0x81, 0x81, 0x00, 0xda, 0x65, 0xda, + 0x38, 0x7c, 0x18, 0xfb, 0x00, 0x11, 0x60, 0xeb, 0x37, 0x65, 0xb8, 0x83, + 0x62, 0x88, 0xc4, 0x3a, 0x4e, 0x64, 0x6a, 0xf3, 0x3e, 0x4e, 0xc0, 0x34, + 0x19, 0x8a, 0xcb, 0x4a, 0xca, 0x2f, 0x5d, 0x50, 0x7a, 0xac, 0xf7, 0x9e, + 0x87, 0x5a, 0xfc, 0x4d, 0x49, 0xd7, 0xf9, 0x21, 0xf5, 0x0b, 0x6f, 0x57, + 0x41, 0x3d, 0x8f, 0xb8, 0xec, 0x7f, 0xcc, 0x92, 0x09, 0xbe, 0xd3, 0xa4, + 0xc3, 0x14, 0x85, 0x21, 0x5d, 0x05, 0xa3, 0xaa, 0x20, 0xf6, 0x62, 0x44, + 0x50, 0x03, 0x5e, 0x53, 0x4a, 0xcd, 0x6a, 0xb6, 0x65, 0x8e, 0x4e, 0x4b, + 0x3f, 0x25, 0xc6, 0x16, 0x31, 0xf5, 0x99, 0x13, 0x77, 0x42, 0xda, 0xdc, + 0x70, 0x4d, 0x65, 0xb0, 0x99, 0x0f, 0xdf, 0x5a, 0xb1, 0x45, 0xf0, 0xb9, + 0x8e, 0xa0, 0xae, 0x4f, 0x4d, 0x65, 0x09, 0x84, 0xb5, 0x38, 0x29, 0xbf, + 0x69, 0xe0, 0x88, 0x1f, 0x27, 0x02, 0x81, 0x81, 0x00, 0xd3, 0x2a, 0x59, + 0xec, 0x28, 0xc3, 0x0d, 0x4f, 0x92, 0x96, 0xca, 0x67, 0x94, 0xfc, 0x2e, + 0xa6, 0x86, 0x68, 0x45, 0x53, 0x92, 0xcc, 0x86, 0x7f, 0x8a, 0xe1, 0x5d, + 0xe8, 0x1d, 0x9e, 0xbb, 0x1e, 0x00, 0x26, 0x1d, 0x80, 0x12, 0xff, 0x9c, + 0x11, 0x0a, 0xbd, 0xa6, 0xc3, 0x8d, 0x48, 0xda, 0xfc, 0x10, 0xf7, 0x7a, + 0x16, 0x07, 0x15, 0xa0, 0x3a, 0xd3, 0x94, 0xfb, 0x52, 0x87, 0x39, 0xee, + 0xe7, 0xc4, 0x26, 0x49, 0x16, 0xc6, 0xc0, 0x83, 0x25, 0xbf, 0x6a, 0x4e, + 0x8c, 0x0b, 0x10, 0x85, 0x66, 0xab, 0x7e, 0xae, 0xac, 0x4c, 0x69, 0x3c, + 0x44, 0xeb, 0xcd, 0xe9, 0xf6, 0x64, 0x8b, 0x4a, 0xd8, 0x6a, 0x4d, 0x6d, + 0x47, 0xa9, 0xb8, 0x55, 0x72, 0xc1, 0xfd, 0xf4, 0x81, 0x4c, 0x66, 0xbe, + 0x49, 0xf2, 0x75, 0x4f, 0x80, 0xf1, 0x20, 0x38, 0xb8, 0x6a, 0x1b, 0x75, + 0x41, 0x30, 0x0f, 0x1b, 0x3f, 0x02, 0x81, 0x80, 0x09, 0x35, 0xfa, 0x7a, + 0x1f, 0x61, 0xbe, 0x54, 0x46, 0x67, 0x5c, 0x04, 0x3e, 0x1a, 0x06, 0x10, + 0x85, 0xcc, 0x20, 0xd9, 0x65, 0x8a, 0xcd, 0x2f, 0x77, 0x8a, 0xcb, 0xa7, + 0xb8, 0x1e, 0xd2, 0xcc, 0xac, 0x2a, 0xb7, 0x56, 0x35, 0x2d, 0x4c, 0x56, + 0x51, 0x14, 0x0a, 0xfe, 0x6e, 0x49, 0x67, 0x91, 0x3a, 0x26, 0x3b, 0xfb, + 0xd8, 0x68, 0xd3, 0x57, 0xc6, 0x1c, 0x0e, 0x9c, 0xb2, 0x9b, 0xa2, 0x7b, + 0x47, 0xc6, 0x45, 0x9d, 0xf2, 0xba, 0xf0, 0x55, 0xeb, 0x8e, 0x41, 0x6b, + 0x4e, 0x79, 0x0f, 0xf2, 0x3b, 0xaf, 0xa0, 0x79, 0xb0, 0x02, 0xc5, 0x51, + 0xa8, 0x7a, 0x2e, 0x3d, 0x75, 0x2a, 0x3b, 0x93, 0xf0, 0x11, 0xe2, 0xf2, + 0x29, 0x91, 0x7c, 0x5d, 0x38, 0x3a, 0x27, 0x4d, 0x0a, 0xb2, 0x18, 0x61, + 0x57, 0x8d, 0x82, 0x72, 0xb5, 0x2c, 0x2d, 0x98, 0xa7, 0x01, 0xbb, 0xbc, + 0xef, 0x67, 0x4e, 0x49, 0x02, 0x81, 0x81, 0x00, 0xb2, 0x70, 0x53, 0x54, + 0x70, 0x8d, 0x82, 0xad, 0xff, 0x1d, 0x55, 0x24, 0x7a, 0x8d, 0x2f, 0x8e, + 0xa0, 0x7d, 0x74, 0x37, 0xcf, 0x10, 0xed, 0x86, 0xd1, 0x80, 0xe7, 0xad, + 0xc1, 0x79, 0xe4, 0x7c, 0xd1, 0x7b, 0x63, 0xea, 0x5a, 0x23, 0x8d, 0x6a, + 0x09, 0x3d, 0x81, 0xb2, 0x35, 0xad, 0x9e, 0xfe, 0xea, 0x07, 0x76, 0x2f, + 0x2f, 0x05, 0x63, 0x44, 0xd2, 0x8e, 0x4e, 0x61, 0xca, 0xcb, 0x75, 0xca, + 0x7b, 0xc2, 0x2e, 0x79, 0x04, 0xb2, 0xa1, 0x20, 0x40, 0xc4, 0x40, 0x63, + 0xae, 0xe5, 0xe3, 0x14, 0x83, 0x4e, 0xa5, 0xa4, 0x0b, 0x5d, 0xd2, 0x04, + 0x1b, 0x8f, 0x01, 0x69, 0xa8, 0x44, 0xdc, 0x96, 0x4c, 0x1d, 0xe9, 0x7e, + 0x69, 0x38, 0xcf, 0x5c, 0x0d, 0xf9, 0xdf, 0xa7, 0x73, 0x3c, 0x4f, 0x08, + 0x85, 0xce, 0x03, 0xc4, 0xdd, 0xfd, 0x70, 0x70, 0xc5, 0x99, 0x36, 0x58, + 0x43, 0x98, 0x40, 0x59, 0x02, 0x81, 0x81, 0x00, 0xd5, 0xaa, 0xfb, 0xec, + 0x8d, 0xc6, 0xdd, 0xfa, 0x2b, 0x5a, 0x24, 0xd0, 0xda, 0x58, 0xbd, 0x87, + 0x92, 0x1a, 0x29, 0x62, 0x13, 0x1d, 0x4b, 0x79, 0x1b, 0xbe, 0x79, 0x7d, + 0xad, 0x79, 0xca, 0x17, 0x75, 0xda, 0xe8, 0x32, 0xe8, 0xa0, 0x9e, 0xa8, + 0x77, 0x53, 0xac, 0x38, 0xd6, 0xeb, 0xe6, 0x22, 0x65, 0xc4, 0xaa, 0x4c, + 0xc8, 0xd0, 0x33, 0x1a, 0x1e, 0xbe, 0xbd, 0x73, 0x09, 0x4a, 0xfa, 0x85, + 0x5c, 0xf3, 0x0c, 0x9c, 0x81, 0x56, 0x30, 0xa7, 0xf7, 0x9b, 0xf4, 0x92, + 0x9c, 0x6b, 0x93, 0x6a, 0x00, 0x33, 0xdc, 0x2f, 0x54, 0x1e, 0x78, 0xd4, + 0x97, 0xec, 0x24, 0xa2, 0xdb, 0x3d, 0x03, 0x33, 0x09, 0xb2, 0x2c, 0x03, + 0x05, 0x40, 0xde, 0x52, 0xf2, 0x9b, 0xfa, 0x00, 0x8d, 0x4b, 0xfe, 0x5b, + 0x9b, 0x9c, 0x73, 0xad, 0xfb, 0x7a, 0x00, 0x42, 0x62, 0x9e, 0xa0, 0x95, + 0x55, 0x50, 0x32, 0x87 +}; +static unsigned int enc_key_len = 1192; +const struct bootutil_key bootutil_enc_key = { + .key = enc_key, + .len = &enc_key_len, +}; diff --git a/ci/mynewt_run.sh b/ci/mynewt_run.sh new file mode 100755 index 000000000..c84dccfb6 --- /dev/null +++ b/ci/mynewt_run.sh @@ -0,0 +1,28 @@ +#!/bin/bash -x + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +export PATH=$HOME/bin:$PATH +pwd + +for target in $(ls ci/mynewt_targets); do + newt build $target + [[ $? -ne 0 ]] && exit 1 +done + +exit 0 diff --git a/ci/mynewt_targets/basic/pkg.yml b/ci/mynewt_targets/basic/pkg.yml new file mode 100644 index 000000000..736f2788f --- /dev/null +++ b/ci/mynewt_targets/basic/pkg.yml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/basic" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" diff --git a/ci/mynewt_targets/basic/syscfg.yml b/ci/mynewt_targets/basic/syscfg.yml new file mode 100644 index 000000000..e4044685d --- /dev/null +++ b/ci/mynewt_targets/basic/syscfg.yml @@ -0,0 +1,45 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +syscfg.vals: + BOOT_SERIAL: 0 + BOOT_SERIAL_DETECT_PIN: 11 + BOOT_SERIAL_DETECT_PIN_VAL: 0 + BOOT_SERIAL_REPORT_PIN: 13 + BOOTUTIL_VALIDATE_SLOT0: 0 + BOOTUTIL_MAX_IMG_SECTORS: 256 + BOOTUTIL_SIGN_EC256: 0 + BOOTUTIL_SIGN_RSA: 0 + BOOTUTIL_ENCRYPT_RSA: 0 + BOOTUTIL_ENCRYPT_KW: 0 + BOOTUTIL_USE_MBED_TLS: 0 + BOOTUTIL_USE_TINYCRYPT: 1 + BOOTUTIL_OVERWRITE_ONLY: 0 + BOOTUTIL_OVERWRITE_ONLY_FAST: 1 + BOOTUTIL_HAVE_LOGGING: 0 + BOOTUTIL_NO_LOGGING: 1 + BOOTUTIL_LOG_LEVEL: 'BOOTUTIL_LOG_LEVEL_INFO' + CONSOLE_COMPAT: 1 + CONSOLE_INPUT: 0 + CONSOLE_UART: 0 + CONSOLE_RTT: 0 + OS_CPUTIME_TIMER_NUM: 0 + TIMER_0: 1 + UART_0: 0 + BOOTUTIL_BOOTSTRAP: 0 + MBEDTLS_NIST_KW_C: 0 diff --git a/ci/mynewt_targets/basic/target.yml b/ci/mynewt_targets/basic/target.yml new file mode 100644 index 000000000..6cb85a9fc --- /dev/null +++ b/ci/mynewt_targets/basic/target.yml @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" diff --git a/ci/mynewt_targets/bootserial/pkg.yml b/ci/mynewt_targets/bootserial/pkg.yml new file mode 100644 index 000000000..b7dd9e292 --- /dev/null +++ b/ci/mynewt_targets/bootserial/pkg.yml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/bootserial" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" diff --git a/ci/mynewt_targets/bootserial/syscfg.yml b/ci/mynewt_targets/bootserial/syscfg.yml new file mode 100644 index 000000000..304cca565 --- /dev/null +++ b/ci/mynewt_targets/bootserial/syscfg.yml @@ -0,0 +1,24 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOT_SERIAL: 1 + UART_0: 1 diff --git a/ci/mynewt_targets/bootserial/target.yml b/ci/mynewt_targets/bootserial/target.yml new file mode 100644 index 000000000..6cb85a9fc --- /dev/null +++ b/ci/mynewt_targets/bootserial/target.yml @@ -0,0 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" diff --git a/ci/mynewt_targets/ecdsa/pkg.yml b/ci/mynewt_targets/ecdsa/pkg.yml new file mode 100644 index 000000000..81bc2b42e --- /dev/null +++ b/ci/mynewt_targets/ecdsa/pkg.yml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/ecdsa" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" diff --git a/ci/mynewt_targets/ecdsa/syscfg.yml b/ci/mynewt_targets/ecdsa/syscfg.yml new file mode 100644 index 000000000..5162df85a --- /dev/null +++ b/ci/mynewt_targets/ecdsa/syscfg.yml @@ -0,0 +1,24 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOTUTIL_VALIDATE_SLOT0: 1 + BOOTUTIL_SIGN_EC256: 1 diff --git a/ci/mynewt_targets/ecdsa/target.yml b/ci/mynewt_targets/ecdsa/target.yml new file mode 100644 index 000000000..931cda047 --- /dev/null +++ b/ci/mynewt_targets/ecdsa/target.yml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" +target.key_file: "root-ec-p256.pem" diff --git a/ci/mynewt_targets/ecdsa_kw/pkg.yml b/ci/mynewt_targets/ecdsa_kw/pkg.yml new file mode 100644 index 000000000..d56caeb8e --- /dev/null +++ b/ci/mynewt_targets/ecdsa_kw/pkg.yml @@ -0,0 +1,28 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/ecdsa_kw" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" + - "@mcuboot/keys/enc_kw" diff --git a/ci/mynewt_targets/ecdsa_kw/syscfg.yml b/ci/mynewt_targets/ecdsa_kw/syscfg.yml new file mode 100644 index 000000000..6065e56c8 --- /dev/null +++ b/ci/mynewt_targets/ecdsa_kw/syscfg.yml @@ -0,0 +1,25 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOTUTIL_VALIDATE_SLOT0: 1 + BOOTUTIL_SIGN_EC256: 1 + BOOTUTIL_ENCRYPT_KW: 1 diff --git a/ci/mynewt_targets/ecdsa_kw/target.yml b/ci/mynewt_targets/ecdsa_kw/target.yml new file mode 100644 index 000000000..931cda047 --- /dev/null +++ b/ci/mynewt_targets/ecdsa_kw/target.yml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" +target.key_file: "root-ec-p256.pem" diff --git a/ci/mynewt_targets/rsa/pkg.yml b/ci/mynewt_targets/rsa/pkg.yml new file mode 100644 index 000000000..8e3264cad --- /dev/null +++ b/ci/mynewt_targets/rsa/pkg.yml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/rsa" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" diff --git a/ci/mynewt_targets/rsa/syscfg.yml b/ci/mynewt_targets/rsa/syscfg.yml new file mode 100644 index 000000000..b40d0ab21 --- /dev/null +++ b/ci/mynewt_targets/rsa/syscfg.yml @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOTUTIL_VALIDATE_SLOT0: 1 + BOOTUTIL_SIGN_EC256: 0 + BOOTUTIL_SIGN_RSA: 1 + BOOTUTIL_USE_MBED_TLS: 1 + BOOTUTIL_USE_TINYCRYPT: 0 diff --git a/ci/mynewt_targets/rsa/target.yml b/ci/mynewt_targets/rsa/target.yml new file mode 100644 index 000000000..34590feeb --- /dev/null +++ b/ci/mynewt_targets/rsa/target.yml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" +target.key_file: "root-rsa-2048.pem" diff --git a/ci/mynewt_targets/rsa_kw/pkg.yml b/ci/mynewt_targets/rsa_kw/pkg.yml new file mode 100644 index 000000000..99af67b09 --- /dev/null +++ b/ci/mynewt_targets/rsa_kw/pkg.yml @@ -0,0 +1,28 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/rsa_kw" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" + - "@mcuboot/keys/enc_kw" diff --git a/ci/mynewt_targets/rsa_kw/syscfg.yml b/ci/mynewt_targets/rsa_kw/syscfg.yml new file mode 100644 index 000000000..4b44287d7 --- /dev/null +++ b/ci/mynewt_targets/rsa_kw/syscfg.yml @@ -0,0 +1,29 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOTUTIL_VALIDATE_SLOT0: 1 + BOOTUTIL_SIGN_EC256: 0 + BOOTUTIL_SIGN_RSA: 1 + BOOTUTIL_USE_MBED_TLS: 1 + BOOTUTIL_USE_TINYCRYPT: 0 + BOOTUTIL_ENCRYPT_KW: 1 + MBEDTLS_NIST_KW_C: 1 diff --git a/ci/mynewt_targets/rsa_kw/target.yml b/ci/mynewt_targets/rsa_kw/target.yml new file mode 100644 index 000000000..34590feeb --- /dev/null +++ b/ci/mynewt_targets/rsa_kw/target.yml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" +target.key_file: "root-rsa-2048.pem" diff --git a/ci/mynewt_targets/rsa_overwriteonly/pkg.yml b/ci/mynewt_targets/rsa_overwriteonly/pkg.yml new file mode 100644 index 000000000..12256075b --- /dev/null +++ b/ci/mynewt_targets/rsa_overwriteonly/pkg.yml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/rsa_overwriteonly" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" diff --git a/ci/mynewt_targets/rsa_overwriteonly/syscfg.yml b/ci/mynewt_targets/rsa_overwriteonly/syscfg.yml new file mode 100644 index 000000000..8dabbe80b --- /dev/null +++ b/ci/mynewt_targets/rsa_overwriteonly/syscfg.yml @@ -0,0 +1,28 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOTUTIL_VALIDATE_SLOT0: 1 + BOOTUTIL_SIGN_EC256: 0 + BOOTUTIL_SIGN_RSA: 1 + BOOTUTIL_USE_MBED_TLS: 1 + BOOTUTIL_USE_TINYCRYPT: 0 + BOOTUTIL_OVERWRITE_ONLY: 1 diff --git a/ci/mynewt_targets/rsa_overwriteonly/target.yml b/ci/mynewt_targets/rsa_overwriteonly/target.yml new file mode 100644 index 000000000..34590feeb --- /dev/null +++ b/ci/mynewt_targets/rsa_overwriteonly/target.yml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" +target.key_file: "root-rsa-2048.pem" diff --git a/ci/mynewt_targets/rsa_rsaoaep/pkg.yml b/ci/mynewt_targets/rsa_rsaoaep/pkg.yml new file mode 100644 index 000000000..fc69f109a --- /dev/null +++ b/ci/mynewt_targets/rsa_rsaoaep/pkg.yml @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/rsa_rsaoaep" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" + - "@mcuboot/keys/enc_rsa" diff --git a/ci/mynewt_targets/rsa_rsaoaep/syscfg.yml b/ci/mynewt_targets/rsa_rsaoaep/syscfg.yml new file mode 100644 index 000000000..649077ca3 --- /dev/null +++ b/ci/mynewt_targets/rsa_rsaoaep/syscfg.yml @@ -0,0 +1,28 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOTUTIL_VALIDATE_SLOT0: 1 + BOOTUTIL_SIGN_EC256: 0 + BOOTUTIL_SIGN_RSA: 1 + BOOTUTIL_USE_MBED_TLS: 1 + BOOTUTIL_USE_TINYCRYPT: 0 + BOOTUTIL_ENCRYPT_RSA: 1 diff --git a/ci/mynewt_targets/rsa_rsaoaep/target.yml b/ci/mynewt_targets/rsa_rsaoaep/target.yml new file mode 100644 index 000000000..34590feeb --- /dev/null +++ b/ci/mynewt_targets/rsa_rsaoaep/target.yml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" +target.key_file: "root-rsa-2048.pem" diff --git a/ci/mynewt_targets/rsa_rsaoaep_bootstrap/pkg.yml b/ci/mynewt_targets/rsa_rsaoaep_bootstrap/pkg.yml new file mode 100644 index 000000000..d0b3619e2 --- /dev/null +++ b/ci/mynewt_targets/rsa_rsaoaep_bootstrap/pkg.yml @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +pkg.name: "targets/rsa_rsaoaep_bootstrap" +pkg.type: "target" +pkg.description: +pkg.author: +pkg.homepage: + +pkg.deps: + - "@mcuboot/boot/mynewt" + - "@mcuboot/keys/enc_rsa" diff --git a/ci/mynewt_targets/rsa_rsaoaep_bootstrap/syscfg.yml b/ci/mynewt_targets/rsa_rsaoaep_bootstrap/syscfg.yml new file mode 100644 index 000000000..a2ec07459 --- /dev/null +++ b/ci/mynewt_targets/rsa_rsaoaep_bootstrap/syscfg.yml @@ -0,0 +1,29 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$import: + - '@mcuboot/ci/mynewt_targets/basic/syscfg.yml' + +syscfg.vals: + BOOTUTIL_VALIDATE_SLOT0: 1 + BOOTUTIL_SIGN_EC256: 0 + BOOTUTIL_SIGN_RSA: 1 + BOOTUTIL_USE_MBED_TLS: 1 + BOOTUTIL_USE_TINYCRYPT: 0 + BOOTUTIL_ENCRYPT_RSA: 1 + BOOTUTIL_BOOTSTRAP: 1 diff --git a/ci/mynewt_targets/rsa_rsaoaep_bootstrap/target.yml b/ci/mynewt_targets/rsa_rsaoaep_bootstrap/target.yml new file mode 100644 index 000000000..34590feeb --- /dev/null +++ b/ci/mynewt_targets/rsa_rsaoaep_bootstrap/target.yml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +target.app: "@mcuboot/boot/mynewt" +target.bsp: "@apache-mynewt-core/hw/bsp/nordic_pca10056" +target.build_profile: "optimized" +target.key_file: "root-rsa-2048.pem" diff --git a/ci/sim_install.sh b/ci/sim_install.sh new file mode 100755 index 000000000..b9a4caea2 --- /dev/null +++ b/ci/sim_install.sh @@ -0,0 +1,17 @@ +#!/bin/bash -x + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +pushd sim && cargo fetch +[[ $? -ne 0 ]] && exit 1 +popd diff --git a/scripts/run_tests.sh b/ci/sim_run.sh similarity index 92% rename from scripts/run_tests.sh rename to ci/sim_run.sh index 2f631668f..b0b70f73e 100755 --- a/scripts/run_tests.sh +++ b/ci/sim_run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -x # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ pushd sim EXIT_CODE=0 if [[ ! -z $SINGLE_FEATURES ]]; then - all_features="sig-rsa sig-ecdsa overwrite-only validate-slot0 enc-rsa enc-kw boostrap" + all_features="sig-rsa sig-ecdsa overwrite-only validate-primary-slot enc-rsa enc-kw boostrap" if [[ $SINGLE_FEATURES =~ "none" ]]; then echo "Running cargo with no features" diff --git a/docs/PORTING.md b/docs/PORTING.md index e2ffb8a9f..2a63d50f3 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -86,9 +86,9 @@ struct flash_area { `fa_id` is can be one of the following options: ```c -#define FLASH_AREA_IMAGE_0 1 -#define FLASH_AREA_IMAGE_1 2 -#define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_IMAGE_PRIMARY 1 +#define FLASH_AREA_IMAGE_SECONDARY 2 +#define FLASH_AREA_IMAGE_SCRATCH 3 ``` The functions that must be defined for working with the `flash_area`s are: @@ -109,7 +109,7 @@ int flash_area_erase(const struct flash_area *, uint32_t off, uint32_t len); uint8_t flash_area_align(const struct flash_area *); /*< Initializes an array of flash_area elements for the slot's sectors */ int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret); -/*< Returns the `fa_id` for slot, where slot is 0 or 1 */ +/*< Returns the `fa_id` for slot, where slot is 0 (primary) or 1 (secondary) */ int flash_area_id_from_image_slot(int slot); /*< Returns the slot, for the `fa_id` supplied */ int flash_area_id_to_image_slot(int area_id); diff --git a/docs/design.md b/docs/design.md index 4da4c9969..13f60b146 100644 --- a/docs/design.md +++ b/docs/design.md @@ -116,10 +116,10 @@ region of disk with the following properties: The boot loader uses the following flash area IDs: ``` c -#define FLASH_AREA_BOOTLOADER 0 -#define FLASH_AREA_IMAGE_0 1 -#define FLASH_AREA_IMAGE_1 2 -#define FLASH_AREA_IMAGE_SCRATCH 3 +#define FLASH_AREA_BOOTLOADER 0 +#define FLASH_AREA_IMAGE_PRIMARY 1 +#define FLASH_AREA_IMAGE_SECONDARY 2 +#define FLASH_AREA_IMAGE_SCRATCH 3 ``` The bootloader area contains the bootloader image itself. The other areas are @@ -140,14 +140,14 @@ strategies. In addition to the two image slots, the boot loader requires a scratch area to allow for reliable image swapping. The scratch area must have a size that is enough to store at least the largest sector that is going to be swapped. Many -devices have small equally sized flash sectors, eg 4K, while others have variable -sized sectors where the largest sectors might be 128K or 256K, so the scratch -must be big enough to store that. The scratch is only ever used when swapping -firmware, which means only when doing an upgrade. Given that, the main reason -for using a larger size for the scratch is that flash wear will be more evenly -distributed, because a single sector would be written twice the number of times -than using two sectors, for example. To evaluate the ideal size of the scratch -for your use case the following parameters are relevant: +devices have small equally sized flash sectors, eg 4K, while others have +variable sized sectors where the largest sectors might be 128K or 256K, so the +scratch must be big enough to store that. The scratch is only ever used when +swapping firmware, which means only when doing an upgrade. Given that, the main +reason for using a larger size for the scratch is that flash wear will be more +evenly distributed, because a single sector would be written twice the number of +times than using two sectors, for example. To evaluate the ideal size of the +scratch for your use case the following parameters are relevant: * the ratio of image size / scratch size * the number of erase cycles supported by the flash hardware @@ -174,9 +174,9 @@ Increasing the scratch to 16K would give us: There is no *best* ratio, as the right size is use-case dependent. Factors to consider include the number of times a device will be upgraded both in the field -and during development, as well as any desired safety margin on the manufacturer's -specified number of erase cycles. In general, using a ratio that allows hundreds -to thousands of field upgrades in production is recommended. +and during development, as well as any desired safety margin on the +manufacturer's specified number of erase cycles. In general, using a ratio that +allows hundreds to thousands of field upgrades in production is recommended. The overwrite upgrade strategy is substantially simpler to implement than the image swapping strategy, especially since the bootloader must work properly @@ -187,10 +187,10 @@ during an upgrade. ## Boot Swap Types When the device first boots under normal circumstances, there is an up-to-date -firmware image in slot 0, which mcuboot can validate and then chain-load. In -this case, no image swaps are necessary. During device upgrades, however, new -candidate images are present in slot 1, which mcuboot must swap into slot 0 -before booting as discussed above. +firmware image in the primary slot, which mcuboot can validate and then +chain-load. In this case, no image swaps are necessary. During device upgrades, +however, new candidate images are present in the secondary slot, which mcuboot +must swap into the primary slot before booting as discussed above. Upgrading an old image with a new one by swapping can be a two-step process. In this process, mcuboot performs a "test" swap of image data in flash and boots @@ -217,17 +217,18 @@ On startup, mcuboot inspects the contents of flash to decide which of these The possible swap types, and their meanings, are: - `BOOT_SWAP_TYPE_NONE`: The "usual" or "no upgrade" case; attempt to boot the - contents of slot 0. + contents of the primary slot. -- `BOOT_SWAP_TYPE_TEST`: Boot the contents of slot 1 by swapping images. Unless - the swap is made permanent, revert back on the next boot. +- `BOOT_SWAP_TYPE_TEST`: Boot the contents of the secondary slot by swapping + images. Unless the swap is made permanent, revert back on the next boot. - `BOOT_SWAP_TYPE_PERM`: Permanently swap images, and boot the upgraded image firmware. -- `BOOT_SWAP_TYPE_REVERT`: A previous test swap was not made permanent; swap back - to the old image whose data are now in slot 1. If the old image marks itself - "OK" when it boots, the next boot will have swap type `BOOT_SWAP_TYPE_NONE`. +- `BOOT_SWAP_TYPE_REVERT`: A previous test swap was not made permanent; + swap back to the old image whose data are now in the secondary slot. If the + old image marks itself "OK" when it boots, the next boot will have swap type + `BOOT_SWAP_TYPE_NONE`. - `BOOT_SWAP_TYPE_FAIL`: Swap failed because image to be run is not valid. @@ -278,28 +279,30 @@ then min-write-size is 2, and so on. An image trailer contains the following fields: 1. Swap status: A series of records which records the progress of an image - swap. To swap entire images, data are swapped between the two image areas one - or more sectors at a time, like this: + swap. To swap entire images, data are swapped between the two image areas + one or more sectors at a time, like this: - - sector data in slot 0 is copied into scratch, then erased - - sector data in slot 1 is copied into slot 0, then erased - - sector data in scratch is copied into slot 1 + - sector data in the primary slot is copied into scratch, then erased + - sector data in the secondary slot is copied into the primary slot, + then erased + - sector data in scratch is copied into the secondary slot As it swaps images, the bootloader updates the swap status field in a way that allows it to compute how far this swap operation has progressed for each sector. The swap status field can thus used to resume a swap operation if the bootloader is halted while a swap operation is ongoing and later reset. The -`BOOT_MAX_IMG_SECTORS` value is the configurable maximum number of sectors mcuboot -supports for each image; its value defaults to 128, but allows for either -decreasing this size, to limit RAM usage, or to increase it in devices that have -massive amounts of Flash or very small sized sectors and thus require a bigger -configuration to allow for the handling of all slot's sectors. The factor of -min-write-sz is due to the behavior of flash hardware. The factor of 3 is -explained below. +`BOOT_MAX_IMG_SECTORS` value is the configurable maximum number of sectors +mcuboot supports for each image; its value defaults to 128, but allows for +either decreasing this size, to limit RAM usage, or to increase it in devices +that have massive amounts of Flash or very small sized sectors and thus require +a bigger configuration to allow for the handling of all slot's sectors. +The factor of min-write-sz is due to the behavior of flash hardware. The factor +of 3 is explained below. 2. Swap size: When beginning a new swap operation, the total size that needs - to be swapped (based on the slot with largest image + tlvs) is written to this - location for easier recovery in case of a reset while performing the swap. + to be swapped (based on the slot with largest image + tlvs) is written to + this location for easier recovery in case of a reset while performing the + swap. 3. Copy done: A single byte indicating whether the image in this slot is complete (0x01=done; 0xff=not done). @@ -324,9 +327,9 @@ At startup, the boot loader determines the boot swap type by inspecting the image trailers. When using the term "image trailers" what is meant is the aggregate information provided by both image slot's trailers. -The image trailers records are structured around the limitations imposed by flash -hardware. As a consequence, they do not have a very intuitive design, and it -is difficult to get a sense of the state of the device just by looking at the +The image trailers records are structured around the limitations imposed by +flash hardware. As a consequence, they do not have a very intuitive design, and +it is difficult to get a sense of the state of the device just by looking at the image trailers. It is better to map all the possible trailer states to the swap types described above via a set of tables. These tables are reproduced below. @@ -336,36 +339,36 @@ higher priority when testing the image trailers. ``` State I - | slot-0 | slot-1 | - -----------------+--------+--------| - magic | Any | Good | - image-ok | Any | Unset | - copy-done | Any | Any | - -----------------+--------+--------' - result: BOOT_SWAP_TYPE_TEST | - -----------------------------------' + | primary slot | secondary slot | + -----------------+--------------+----------------| + magic | Any | Good | + image-ok | Any | Unset | + copy-done | Any | Any | + -----------------+--------------+----------------' + result: BOOT_SWAP_TYPE_TEST | + -------------------------------------------------' State II - | slot-0 | slot-1 | - -----------------+--------+--------| - magic | Any | Good | - image-ok | Any | 0x01 | - copy-done | Any | Any | - -----------------+--------+--------' - result: BOOT_SWAP_TYPE_PERM | - -----------------------------------' + | primary slot | secondary slot | + -----------------+--------------+----------------| + magic | Any | Good | + image-ok | Any | 0x01 | + copy-done | Any | Any | + -----------------+--------------+----------------' + result: BOOT_SWAP_TYPE_PERM | + -------------------------------------------------' State III - | slot-0 | slot-1 | - -----------------+--------+--------| - magic | Good | Unset | - image-ok | 0xff | Any | - copy-done | 0x01 | Any | - -----------------+--------+--------' - result: BOOT_SWAP_TYPE_REVERT | - -----------------------------------' + | primary slot | secondary slot | + -----------------+--------------+----------------| + magic | Good | Unset | + image-ok | 0xff | Any | + copy-done | 0x01 | Any | + -----------------+--------------+----------------' + result: BOOT_SWAP_TYPE_REVERT | + -------------------------------------------------' ``` Any of the above three states results in mcuboot attempting to swap images. @@ -375,30 +378,30 @@ other three swap types, as illustrated by State IV. ``` State IV - | slot-0 | slot-1 | - -----------------+--------+--------| - magic | Any | Any | - image-ok | Any | Any | - copy-done | Any | Any | - -----------------+--------+--------' - result: BOOT_SWAP_TYPE_NONE, | - BOOT_SWAP_TYPE_FAIL, or | - BOOT_SWAP_TYPE_PANIC | - -----------------------------------' + | primary slot | secondary slot | + -----------------+--------------+----------------| + magic | Any | Any | + image-ok | Any | Any | + copy-done | Any | Any | + -----------------+--------------+----------------' + result: BOOT_SWAP_TYPE_NONE, | + BOOT_SWAP_TYPE_FAIL, or | + BOOT_SWAP_TYPE_PANIC | + -------------------------------------------------' ``` In State IV, when no errors occur, mcuboot will attempt to boot the contents of -slot 0 directly, and the result is `BOOT_SWAP_TYPE_NONE`. If the image in slot 0 -is not valid, the result is `BOOT_SWAP_TYPE_FAIL`. If a fatal error occurs during -boot, the result is `BOOT_SWAP_TYPE_PANIC`. If the result is either -`BOOT_SWAP_TYPE_FAIL` or `BOOT_SWAP_TYPE_PANIC`, mcuboot hangs rather than booting -an invalid or compromised image. +the primary slot directly, and the result is `BOOT_SWAP_TYPE_NONE`. If the image +in the primary slot is not valid, the result is `BOOT_SWAP_TYPE_FAIL`. If a +fatal error occurs during boot, the result is `BOOT_SWAP_TYPE_PANIC`. If the +result is either `BOOT_SWAP_TYPE_FAIL` or `BOOT_SWAP_TYPE_PANIC`, mcuboot hangs +rather than booting an invalid or compromised image. Note: An important caveat to the above is the result when a swap is requested - and the image in slot 1 fails to validate, due to a hashing or signing - error. This state behaves as State IV with the extra action of marking - the image in slot 0 as "OK", to prevent further attempts to swap. - + and the image in the secondary slot fails to validate, due to a hashing or + signing error. This state behaves as State IV with the extra action of + marking the image in the primary slot as "OK", to prevent further attempts + to swap. ## High-Level Operation @@ -414,27 +417,27 @@ Procedure: 2. Inspect image trailers; is a swap requested? Yes. - 1. Is the requested image valid (integrity and security check)? - Yes. - a. Perform swap operation. - b. Persist completion of swap procedure to image trailers. - c. Proceed to step 3. - No. - a. Erase invalid image. - b. Persist failure of swap procedure to image trailers. - c. Proceed to step 3. + ​ 1. Is the requested image valid (integrity and security check)? + ​ Yes. + ​ a. Perform swap operation. + ​ b. Persist completion of swap procedure to image trailers. + ​ c. Proceed to step 3. + ​ No. + ​ a. Erase invalid image. + ​ b. Persist failure of swap procedure to image trailers. + ​ c. Proceed to step 3. No: Proceed to step 3. -3. Boot into image in slot 0. +3. Boot into image in primary slot. ## Image Swapping The boot loader swaps the contents of the two image slots for two reasons: - * User has issued a "set pending" operation; the image in slot-1 should be - run once (state II) or repeatedly (state III), depending on whether a - permanent swap was specified. - * Test image rebooted without being confirmed; the boot loader should - revert to the original image currently in slot-1 (state IV). + * User has issued a "set pending" operation; the image in the secondary slot + should be run once (state II) or repeatedly (state III), depending on + whether a permanent swap was specified. +​ * Test image rebooted without being confirmed; the boot loader should + revert to the original image currently in the secondary slot (state IV). If the image trailers indicates that the image in the secondary slot should be run, the boot loader needs to copy it to the primary slot. The image currently @@ -445,73 +448,70 @@ according to the following procedure: - 1. Determine how many flash sectors each image slot consists of. This - number must be the same for both slots. - 2. Iterate the list of sector indices in descending order (i.e., starting - with the greatest index); current element = "index". - b. Erase scratch area. - c. Copy slot1[index] to scratch area. - - If these are the last sectors (i.e., first swap being perfomed), - copy the full sector *except* the image trailer. - - Else, copy entire sector contents. - d. Write updated swap status (i). - - e. Erase slot1[index] - f. Copy slot0[index] to slot1[index] - - If these are the last sectors (i.e., first swap being perfomed), - copy the full sector *except* the image trailer. - - Else, copy entire sector contents. - g. Write updated swap status (ii). - - h. Erase slot0[index]. - i. Copy scratch area to slot0[index]. - - If these are the last sectors (i.e., first swap being perfomed), - copy the full sector *except* the image trailer. - - Else, copy entire sector contents. - j. Write updated swap status (iii). - - 3. Persist completion of swap procedure to slot 0 image trailer. - -The additional caveats in step 2f are necessary so that the slot 1 image +​ 1. Determine how many flash sectors each image slot consists of. This +​ number must be the same for both slots. +​ 2. Iterate the list of sector indices in descending order (i.e., starting +​ with the greatest index); current element = "index". +​ b. Erase scratch area. +​ c. Copy secondary_slot[index] to scratch area. +​ - If these are the last sectors (i.e., first swap being perfomed), +​ copy the full sector *except* the image trailer. +​ - Else, copy entire sector contents. +​ d. Write updated swap status (i). +​ e. Erase secondary_slot[index] +​ f. Copy primary_slot[index] to secondary_slot[index] +​ - If these are the last sectors (i.e., first swap being perfomed), +​ copy the full sector *except* the image trailer. +​ - Else, copy entire sector contents. +​ g. Write updated swap status (ii). +​ h. Erase primary_slot[index]. +​ i. Copy scratch area to primary_slot[index]. +​ - If these are the last sectors (i.e., first swap being perfomed), +​ copy the full sector *except* the image trailer. +​ - Else, copy entire sector contents. +​ j. Write updated swap status (iii). +​ 3. Persist completion of swap procedure to the primary slot image trailer. + +The additional caveats in step 2f are necessary so that the secondary slot image trailer can be written by the user at a later time. With the image trailer -unwritten, the user can test the image in slot 1 (i.e., transition to state -II). +unwritten, the user can test the image in the secondary slot +(i.e., transition to state II). Note1: If the sector being copied is the last sector, then swap status is temporarily maintained on scratch for the duration of this operation, always -using slot0's area otherwise. +using the primary slot's area otherwise. Note2: The bootloader tries to copy only used sectors (based on largest image installed on any of the slots), minimizing the amount of sectors copied and reducing the amount of time required for a swap operation. The particulars of step 3 vary depending on whether an image is being tested, -permanently used, reverted or a validation failure of slot 1 happened when a -swap was requested: +permanently used, reverted or a validation failure of the secondary slot +happened when a swap was requested: * test: - o Write slot0.copy_done = 1 + o Write primary_slot.copy_done = 1 (swap caused the following values to be written: - slot0.magic = BOOT_MAGIC - slot0.image_ok = Unset) + primary_slot.magic = BOOT_MAGIC + primary_slot.image_ok = Unset) * permanent: - o Write slot0.copy_done = 1 + o Write primary_slot.copy_done = 1 (swap caused the following values to be written: - slot0.magic = BOOT_MAGIC - slot0.image_ok = 0x01) + primary_slot.magic = BOOT_MAGIC + primary_slot.image_ok = 0x01) * revert: - o Write slot0.copy_done = 1 - o Write slot0.image_ok = 1 + o Write primary_slot.copy_done = 1 + o Write primary_slot.image_ok = 1 (swap caused the following values to be written: - slot0.magic = BOOT_MAGIC) + primary_slot.magic = BOOT_MAGIC) - * failure to validate slot 1: - o Write slot0.image_ok = 1 + * failure to validate the secondary slot: + o Write primary_slot.image_ok = 1 -After completing the operations as described above the image in slot 0 should -be booted. +After completing the operations as described above the image in the primary slot +should be booted. ## Swap Status @@ -547,17 +547,18 @@ Each image slot is partitioned into a sequence of flash sectors. If we were to enumerate the sectors in a single slot, starting at 0, we would have a list of sector indices. Since there are two image slots, each sector index would correspond to a pair of sectors. For example, sector index 0 corresponds to -the first sector in slot 0 and the first sector in slot 1. Finally, reverse -the list of indices such that the list starts with index `BOOT_MAX_IMG_SECTORS - 1` -and ends with 0. The swap status region is a representation of this reversed list. +the first sector in the primary slot and the first sector in the secondary slot. +Finally, reverse the list of indices such that the list starts with index +`BOOT_MAX_IMG_SECTORS - 1` and ends with 0. The swap status region is a +representation of this reversed list. During a swap operation, each sector index transitions through four separate states: ``` - 0. slot 0: image 0, slot 1: image 1, scratch: N/A - 1. slot 0: image 0, slot 1: N/A, scratch: image 1 (1->s, erase 1) - 2. slot 0: N/A, slot 1: image 0, scratch: image 1 (0->1, erase 0) - 3. slot 0: image 1, slot 1: image 0, scratch: N/A (s->0) +0. primary slot: image 0, secondary slot: image 1, scratch: N/A +1. primary slot: image 0, secondary slot: N/A, scratch: image 1 (1->s, erase 1) +2. primary slot: N/A, secondary slot: image 0, scratch: image 1 (0->1, erase 0) +3. primary slot: image 1, secondary slot: image 0, scratch: N/A (s->0) ``` Each time a sector index transitions to a new state, the boot loader writes a @@ -580,14 +581,15 @@ values map to the above four states as follows ``` The swap status region can accommodate `BOOT_MAX_IMG_SECTORS` sector indices. -Hence, the size of the region, in bytes, is `BOOT_MAX_IMG_SECTORS * min-write-size * 3`. -The only requirement for the index count is that it is great enough to account for a -maximum-sized image (i.e., at least as great as the total sector count in an -image slot). If a device's image slots have been configured with -`BOOT_MAX_IMG_SECTORS: 128` and use less than 128 sectors, the first -record that gets written will be somewhere in the middle of the region. For -example, if a slot uses 64 sectors, the first sector index that gets swapped is -63, which corresponds to the exact halfway point within the region. +Hence, the size of the region, in bytes, is +`BOOT_MAX_IMG_SECTORS * min-write-size * 3`. The only requirement for the index +count is that it is great enough to account for a maximum-sized image +(i.e., at least as great as the total sector count in an image slot). If a +device's image slots have been configured with `BOOT_MAX_IMG_SECTORS: 128` and +use less than 128 sectors, the first record that gets written will be somewhere +in the middle of the region. For example, if a slot uses 64 sectors, the first +sector index that gets swapped is 63, which corresponds to the exact halfway +point within the region. Note: since the scratch area only ever needs to record swapping of the last sector, it uses at most min-write-size * 3 bytes for its own status area. @@ -605,53 +607,53 @@ contents to swap status location. In these tables, the "source" field indicates where the swap status region is located. ``` - | slot-0 | scratch | - ----------+------------+------------| - magic | Good | Any | - copy-done | 0x01 | N/A | - ----------+------------+------------' - source: none | - ------------------------------------' - - | slot-0 | scratch | - ----------+------------+------------| - magic | Good | Any | - copy-done | 0xff | N/A | - ----------+------------+------------' - source: slot 0 | - ------------------------------------' - - | slot-0 | scratch | - ----------+------------+------------| - magic | Any | Good | - copy-done | Any | N/A | - ----------+------------+------------' - source: scratch | - ------------------------------------' - - | slot-0 | scratch | - ----------+------------+------------| - magic | Unset | Any | - copy-done | 0xff | N/A | - ----------+------------+------------| - source: slot 0 | - ------------------------------------+------------------------------+ - This represents one of two cases: | - o No swaps ever (no status to read, so no harm in checking). | - o Mid-revert; status in slot 0. | - For this reason we assume slot 0 as source, to trigger a check | - of the status area and find out if there was swapping under way. | - -------------------------------------------------------------------' + | primary slot | scratch | + ----------+--------------+--------------| + magic | Good | Any | + copy-done | 0x01 | N/A | + ----------+--------------+--------------' + source: none | + ----------------------------------------' + + | primary slot | scratch | + ----------+--------------+--------------| + magic | Good | Any | + copy-done | 0xff | N/A | + ----------+--------------+--------------' + source: primary slot | + ----------------------------------------' + + | primary slot | scratch | + ----------+--------------+--------------| + magic | Any | Good | + copy-done | Any | N/A | + ----------+--------------+--------------' + source: scratch | + ----------------------------------------' + + | primary slot | scratch | + ----------+--------------+--------------| + magic | Unset | Any | + copy-done | 0xff | N/A | + ----------+--------------+--------------| + source: primary slot | + ----------------------------------------+------------------------------+ + This represents one of two cases: | + o No swaps ever (no status to read, so no harm in checking). | + o Mid-revert; status in the primary slot. | + For this reason we assume the primary slot as source, to trigger a | + check of the status area and find out if there was swapping under way. | + -----------------------------------------------------------------------' ``` If the swap status region indicates that the images are not contiguous, bootutil completes the swap operation that was in progress when the system was reset. In other words, it applies the procedure defined in the previous -section, moving image 1 into slot 0 and image 0 into slot 1. If the boot -status file indicates that an image part is present in the scratch area, this -part is copied into the correct location by starting at step e or step h in the -area-swap procedure, depending on whether the part belongs to image 0 or image -1. +section, moving image 1 into the primary slot and image 0 into the secondary +slot. If the boot status file indicates that an image part is present in the +scratch area, this part is copied into the correct location by starting at step +e or step h in the area-swap procedure, depending on whether the part belongs to +image 0 or image 1. After the swap operation has been completed, the boot loader proceeds as though it had just been started. @@ -660,20 +662,21 @@ it had just been started. An image is checked for integrity immediately before it gets copied into the primary slot. If the boot loader doesn't perform an image swap, then it can -perform an optional integrity check of the image in slot0 if -`MCUBOOT_VALIDATE_SLOT0` is set, otherwise it doesn't perform an integrity check. +perform an optional integrity check of the image in the primary slot if +`MCUBOOT_VALIDATE_PRIMARY_SLOT` is set, otherwise it doesn't perform an +integrity check. During the integrity check, the boot loader verifies the following aspects of an image: - * 32-bit magic number must be correct (0x96f3b83d). - * Image must contain an `image_tlv_info` struct, identified by its magic - (0x6907) exactly following the firmware (hdr_size + img_size). - * Image must contain a SHA256 TLV. - * Calculated SHA256 must match SHA256 TLV contents. - * Image *may* contain a signature TLV. If it does, it must also have a - KEYHASH TLV with the hash of the key that was used to sign. The list of - keys will then be iterated over looking for the matching key, which then - will then be used to verify the image contents. +​ * 32-bit magic number must be correct (0x96f3b83d). +​ * Image must contain an `image_tlv_info` struct, identified by its magic +​ (0x6907) exactly following the firmware (hdr_size + img_size). +​ * Image must contain a SHA256 TLV. +​ * Calculated SHA256 must match SHA256 TLV contents. +​ * Image *may* contain a signature TLV. If it does, it must also have a +​ KEYHASH TLV with the hash of the key that was used to sign. The list of +​ keys will then be iterated over looking for the matching key, which then +​ will then be used to verify the image contents. ## Security diff --git a/docs/encrypted_images.md b/docs/encrypted_images.md index 82700e32e..bc38ae75b 100644 --- a/docs/encrypted_images.md +++ b/docs/encrypted_images.md @@ -27,16 +27,16 @@ for encrypting/decrypting images on-the-fly while upgrading. The image header needs to flag this image as `ENCRYPTED` (0x04) and a TLV with the key must be present in the image. When upgrading the -image from `slot1` to `slot0` it is automatically decrypted (after -validation). If swap upgrades are enabled, the image located in `slot0`, -also having the `ENCRYPTED` flag set and the TLV present, is -re-encrypted while swapping to `slot1`. +image from the `secondary slot` to the `primary slot` it is automatically +decrypted (after validation). If swap upgrades are enabled, the image +located in the `primary slot`, also having the `ENCRYPTED` flag set and the +TLV present, is re-encrypted while swapping to the `secondary slot`. ## Threat model The encrypted image support is supposed to allow for confidentiality if the image is not residing on the device or is written to external -storage, eg a SPI flash being used for slot1. +storage, eg a SPI flash being used for the secondary slot. It does not protect against the possibility of attaching a JTAG and reading the internal flash memory, or using some attack vector that @@ -79,24 +79,25 @@ AES-CTR-128 key. ## Upgrade process -When starting a new upgrade process, `MCUBoot` checks that the image in -`slot1` has the `ENCRYPTED` flag set and has the required TLV with the +When starting a new upgrade process, `MCUBoot` checks that the image in the +`secondary slot` has the `ENCRYPTED` flag set and has the required TLV with the encrypted key. It then uses its internal private/secret key to decrypt the TLV containing the key. Given that no errors are found, it will then start the validation process, decrypting the blocks before check. A good image being determined, the upgrade consists in reading the blocks from -`slot1`, decrypting and writing to `slot0`. +the `secondary slot`, decrypting and writing to the `primary slot`. If swap is used for the upgrade process, the encryption happens when -copying the sectors of `slot1` to the scratch area. +copying the sectors of the `secondary slot` to the scratch area. The `scratch` area is not encrypted, so it must reside in the internal flash of the MCU to avoid attacks that could interrupt the upgrade and dump the data. -Also when swap is used, the image in `slot0` is checked for presence of -the `ENCRYPTED` flag and the key TLV. If those are present the sectors -are re-encrypted when copying from `slot0` to `slot1`. +Also when swap is used, the image in the `primary slot` is checked for +presence of the `ENCRYPTED` flag and the key TLV. If those are present the +sectors are re-encrypted when copying from the `primary slot` to +the `secondary slot`. PS: Each encrypted image must have its own key TLV that should be unique and used only for this particular image. diff --git a/docs/imgtool.md b/docs/imgtool.md index 1d5a7d778..baace5f4c 100644 --- a/docs/imgtool.md +++ b/docs/imgtool.md @@ -47,8 +47,8 @@ into the key file. ## Signing images -Image signing takes an image in binary or Intel Hex format intended for Slot 0 -and adds a header and trailer that the bootloader is expecting: +Image signing takes an image in binary or Intel Hex format intended for the +primary slot and adds a header and trailer that the bootloader is expecting: Usage: imgtool.py sign [OPTIONS] INFILE OUTFILE @@ -61,8 +61,8 @@ and adds a header and trailer that the bootloader is expecting: -H, --header-size INTEGER [required] --pad-header Add --header-size zeroed bytes at the beginning of the image - -S, --slot-size INTEGER Size of the slot where the image will be written - [required] + -S, --slot-size INTEGER Size of the slot where the image will be + written [required] --pad Pad image to --slot-size bytes, adding trailer magic -M, --max-sectors INTEGER When padding allow for this amount of sectors @@ -93,5 +93,5 @@ not being used, `--overwrite-only` can be passed to avoid adding the swap status area size when calculating overflow. The optional `--pad` argument will place a trailer on the image that -indicates that the image should be considered an upgrade. Writing -this image in slot 1 will then cause the bootloader to upgrade to it. +indicates that the image should be considered an upgrade. Writing this image +in the secondary slot will then cause the bootloader to upgrade to it. diff --git a/docs/readme-zephyr.md b/docs/readme-zephyr.md index fd072447f..ac183c5eb 100644 --- a/docs/readme-zephyr.md +++ b/docs/readme-zephyr.md @@ -13,8 +13,8 @@ The first step required for Zephyr is making sure your board has flash partitions defined in its device tree. These partitions are: - `boot_partition`: for MCUboot itself -- `slot0_partition`: the primary image slot -- `slot1_partition`: the secondary image slot +- `primary_slot_partition`: the primary image slot +- `secondary_slot_partition`: the secondary image slot - `scratch_partition`: the scratch slot Currently, the two image slots must be contiguous. If you are running @@ -43,7 +43,7 @@ Zephyr's point of view. There is a bit of configuration that needs to be made before building it. Most of this can be done as documented in the `CMakeLists.txt` file in boot/zephyr. There are comments there for guidance. It is important to select a signature algorithm, and decide -if slot0 should be validated on every boot. +if the primary slot should be validated on every boot. To build MCUboot, create a build directory in boot/zephyr, and build it as usual: @@ -96,7 +96,7 @@ With this, build the application as your normally would. ### Signing the application In order to upgrade to an image (or even boot it, if -`MCUBOOT_VALIDATE_SLOT0` is enabled), the images must be signed. +`MCUBOOT_VALIDATE_PRIMARY_SLOT` is enabled), the images must be signed. To make development easier, MCUboot is distributed with some example keys. It is important to stress that these should never be used for production, since the private key is publicly available in this @@ -108,17 +108,17 @@ to look at `samples/zephyr/Makefile` for examples on how to use this. ### Flashing the application The application itself can flashed with regular flash tools, but will -need to be programmed at the offset of slot-0 for this particular target. -Depending on the platform and flash tool you might need to manually specify a -flash offset corresponding to the slot-0 starting address. This is usually -not relevant for flash tools that use Intel Hex images (.hex) instead of raw -binary images (.bin) since the former include destination address information. -Additionally you will need to make sure that the flash tool does not perform -a mass erase (erasing the whole of the flash) or else you would be deleting -MCUboot. -These images can also be marked for upgrade, and loaded into slot-1, +need to be programmed at the offset of the primary slot for this particular +target. Depending on the platform and flash tool you might need to manually +specify a flash offset corresponding to the primary slot starting address. This +is usually not relevant for flash tools that use Intel Hex images (.hex) instead +of raw binary images (.bin) since the former include destination address +information. Additionally you will need to make sure that the flash tool does +not perform a mass erase (erasing the whole of the flash) or else you would be +deleting MCUboot. +These images can also be marked for upgrade, and loaded into the secondary slot, at which point the bootloader should perform an upgrade. It is up to -the image to mark slot-0 as "image ok" before the next reboot, +the image to mark the primary slot as "image ok" before the next reboot, otherwise the bootloader will revert the application. ## Managing signing keys diff --git a/ext/nrf/README.md b/ext/nrf/README.md new file mode 100644 index 000000000..a22f06a48 --- /dev/null +++ b/ext/nrf/README.md @@ -0,0 +1,18 @@ +# Building MCUBoot with nRF52840 CC310 enabled + +## Pre-prerequisites + +Clone [nrfxlib](https://github.com/NordicPlayground/nrfxlib) next to the mcuboot root folder. So that it's located `../nrfxlib` from mcuboots root folder. + +## Building + +make sure `root-ec-p256.pem` is set as the certificate and that `CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256` is selected not `CONFIG_BOOT_SIGNATURE_TYPE_RSA` in `prj.conf` of `boot/zephyr`. +Since it defaults to tinycrypt you'll have to go into `menuconfig` and change the implementation selection to `cc310` or also set this in `prj.conf`. + +``` +mkdir build && cd build +cmake -GNinja -DBOARD=nrf52840_pca10056 +ninja flash +``` + +Build a hello world example in zephyr and sign it with imgtool.py with the `root-ec-p256.pem` and flash it at `FLASH_AREA_IMAGE_0`. diff --git a/ext/nrf/cc310_glue.c b/ext/nrf/cc310_glue.c new file mode 100644 index 000000000..14b9ac600 --- /dev/null +++ b/ext/nrf/cc310_glue.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2019 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic + */ + +#include "cc310_glue.h" + +int cc310_init(void) +{ + /* Only initialize once */ + static bool initialized; + + if (!initialized) { + nrf_cc310_enable(); + if (nrf_cc310_bl_init() != 0) { + return -1; + } + initialized = true; + nrf_cc310_disable(); + } + + return 0; +} + +void cc310_sha256_update(nrf_cc310_bl_hash_context_sha256_t *ctx, + const void *data, + uint32_t data_len) +{ + /* + * NRF Cryptocell can only read from RAM this allocates a buffer on the stack + * if the data provided is not located in RAM. + */ + + if ((uint32_t) data < CONFIG_SRAM_BASE_ADDRESS) { + uint8_t stack_buffer[data_len]; + uint32_t block_len = data_len; + memcpy(stack_buffer, data, block_len); + nrf_cc310_bl_hash_sha256_update(ctx, stack_buffer, block_len); + } else { + nrf_cc310_bl_hash_sha256_update(ctx, data, data_len); + } +}; + +int cc310_ecdsa_verify_secp256r1(uint8_t *hash, + uint8_t *public_key, + uint8_t *signature, + size_t hash_len) +{ + int rc; + nrf_cc310_bl_ecdsa_verify_context_secp256r1_t ctx; + cc310_init(); + nrf_cc310_enable(); + rc = nrf_cc310_bl_ecdsa_verify_secp256r1(&ctx, + (nrf_cc310_bl_ecc_public_key_secp256r1_t *) public_key, + (nrf_cc310_bl_ecc_signature_secp256r1_t *) signature, + hash, + hash_len); + nrf_cc310_disable(); + return rc; +} + diff --git a/ext/nrf/cc310_glue.h b/ext/nrf/cc310_glue.h new file mode 100644 index 000000000..db34c341f --- /dev/null +++ b/ext/nrf/cc310_glue.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic + */ +#ifndef NRF_CC310_GLUE_H__ +#define NRF_CC310_GLUE_H__ + +#include +#include +#include +#include +#include +#include + +typedef nrf_cc310_bl_hash_context_sha256_t bootutil_sha256_context; + +int cc310_ecdsa_verify_secp256r1(uint8_t *hash, + uint8_t *public_key, + uint8_t *signature, + size_t hash_len); + + +int cc310_init(void); + +static inline void cc310_sha256_init(nrf_cc310_bl_hash_context_sha256_t *ctx); + +void cc310_sha256_update(nrf_cc310_bl_hash_context_sha256_t *ctx, + const void *data, + uint32_t data_len); + +static inline void nrf_cc310_enable(void) +{ + NRF_CRYPTOCELL->ENABLE=1; +} + +static inline void nrf_cc310_disable(void) +{ + NRF_CRYPTOCELL->ENABLE=1; +} + +/* Enable and disable cc310 to reduce power consumption */ +static inline void cc310_sha256_init(nrf_cc310_bl_hash_context_sha256_t * ctx) +{ + cc310_init(); + nrf_cc310_enable(); + nrf_cc310_bl_hash_sha256_init(ctx); +} + +static inline void cc310_sha256_finalize(bootutil_sha256_context *ctx, + uint8_t *output) +{ + nrf_cc310_bl_hash_sha256_finalize(ctx, + (nrf_cc310_bl_hash_digest_sha256_t *)output); + nrf_cc310_disable(); +} + +#endif /* NRF_CC310_GLUE_H__ */ diff --git a/ptest/src/main.rs b/ptest/src/main.rs index 1ef497958..df8f155e0 100644 --- a/ptest/src/main.rs +++ b/ptest/src/main.rs @@ -186,7 +186,14 @@ impl Matrix { None => continue, }; - let fset = FeatureSet::decode(env)?; + // Skip features not targeted to this build. + let fset = match FeatureSet::decode(env) { + Ok(fset) => fset, + Err(err) => { + warn!("Skipping: {:?}", err); + continue; + } + }; debug!("fset: {:?}", fset); if false { @@ -220,7 +227,9 @@ impl Matrix { impl FeatureSet { fn decode(text: &str) -> Result { - let re = Regex::new(r#"^([A-Z_]+)="(.*)"$"#)?; + // This is not general environment settings, but specific to the + // travis file. + let re = Regex::new(r#"^([A-Z_]+)="(.*)" TEST=sim$"#)?; match re.captures(text) { None => Err(format_err!("Invalid line: {:?}", text)), @@ -246,7 +255,7 @@ impl FeatureSet { fn run(&self) -> Result> { for v in &self.values { let output = Command::new("bash") - .arg("./scripts/run_tests.sh") + .arg("./ci/sim_run.sh") .current_dir("..") .env(&self.env, v) .output()?; diff --git a/samples/mcuboot_config/mcuboot_config.template.h b/samples/mcuboot_config/mcuboot_config.template.h index 3dee47ecd..d29f4f6fb 100644 --- a/samples/mcuboot_config/mcuboot_config.template.h +++ b/samples/mcuboot_config/mcuboot_config.template.h @@ -45,7 +45,7 @@ /* #define MCUBOOT_OVERWRITE_ONLY */ #ifdef MCUBOOT_OVERWRITE_ONLY -/* Uncomment to only erase and overwrite those slot 0 sectors needed +/* Uncomment to only erase and overwrite those primary slot sectors needed * to install the new image, rather than the entire image slot. */ /* #define MCUBOOT_OVERWRITE_ONLY_FAST */ #endif @@ -64,11 +64,11 @@ /* #define MCUBOOT_USE_TINYCRYPT */ /* - * Always check the signature of the image in slot 0 before booting, + * Always check the signature of the image in the primary slot before booting, * even if no upgrade was performed. This is recommended if the boot * time penalty is acceptable. */ -#define MCUBOOT_VALIDATE_SLOT0 +#define MCUBOOT_VALIDATE_PRIMARY_SLOT /* * Flash abstraction diff --git a/samples/zephyr/Makefile b/samples/zephyr/Makefile index 938468e3e..62291e3ca 100644 --- a/samples/zephyr/Makefile +++ b/samples/zephyr/Makefile @@ -39,11 +39,11 @@ # time, you should see a message about the bootloader not being able # to find a bootable image. # -# "make flash_hello1" will then flash the first application into -# "slot0". This should boot into this app, print a small message, and +# "make flash_hello1" will then flash the first application into the +# "primary slot". This should boot into this app, print a small message, and # give the zephyr console. # -# "make flash_hello2" will flash hello2 into the second slot. The +# "make flash_hello2" will flash hello2 into the "secondary slot". The # reset should upgrade and run the new image. Resetting again should # then revert back to the first app, since we did not mark this image # as good. @@ -140,7 +140,7 @@ clean_hello1: check # This is the same signing command as above, except that it adds the # "--pad" argument. This will also add the trailer that indicates # this image is intended to be an upgrade. It should be flashed into -# slot1 instead of slot0. +# the secondary slot instead of the primary slot. hello2: check (mkdir -p $(BUILD_DIR_HELLO2) && \ cd $(BUILD_DIR_HELLO2) && \ @@ -244,7 +244,7 @@ test-bad-ecdsa-upgrade: clean SIGNING_KEY=../../root-rsa-2048.pem \ hello2 -# Test that when configured to not validate slot0, we still boot, but +# Test that when configured to not validate the primary slot, we still boot, but # don't upgrade. # flash_boot: tries to boot and resets # flash_hello1: hello1 runs @@ -252,7 +252,7 @@ test-bad-ecdsa-upgrade: clean # reset: hello1 runs test-no-bootcheck: clean $(MAKE) \ - BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-skip-slot0-validate.conf \ + BOOTLOADER_OVERLAY_CONFIG=$(PWD)/overlay-skip-primary-slot-validate.conf \ SIGNING_KEY=../../root-ec-p256.pem \ all diff --git a/samples/zephyr/overlay-skip-primary-slot-validate.conf b/samples/zephyr/overlay-skip-primary-slot-validate.conf new file mode 100644 index 000000000..e94518e79 --- /dev/null +++ b/samples/zephyr/overlay-skip-primary-slot-validate.conf @@ -0,0 +1,3 @@ +# Kconfig overlay for building without validating primary slot. + +# CONFIG_BOOT_VALIDATE_SLOT0 is not set diff --git a/samples/zephyr/overlay-skip-slot0-validate.conf b/samples/zephyr/overlay-skip-slot0-validate.conf deleted file mode 100644 index dd3b2c214..000000000 --- a/samples/zephyr/overlay-skip-slot0-validate.conf +++ /dev/null @@ -1,3 +0,0 @@ -# Kconfig overlay for building without validating slot 0. - -# CONFIG_BOOT_VALIDATE_SLOT0 is not set diff --git a/scripts/flash.sh b/scripts/flash.sh index 7353dd7cd..a2c58c750 100755 --- a/scripts/flash.sh +++ b/scripts/flash.sh @@ -8,8 +8,8 @@ cat >$lscript < 0 } - // Tests a new image written to slot0 that already has magic and image_ok set - // while there is no image on slot1, so no revert should ever happen... + // Tests a new image written to the primary slot that already has magic and + // image_ok set while there is no image on the secondary slot, so no revert + // should ever happen... pub fn run_norevert_newimage(&self) -> bool { let mut flashmap = self.flashmap.clone(); let mut fails = 0; @@ -240,10 +245,11 @@ impl Images { mark_upgrade(&mut flashmap, &self.slots[0]); - // This simulates writing an image created by imgtool to Slot 0 + // This simulates writing an image created by imgtool to + // the primary slot if !verify_trailer(&flashmap, &self.slots, 0, BOOT_MAGIC_GOOD, BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) { - warn!("Mismatched trailer for Slot 0"); + warn!("Mismatched trailer for the primary slot"); fails += 1; } @@ -261,12 +267,12 @@ impl Images { } if !verify_trailer(&flashmap, &self.slots, 0, BOOT_MAGIC_GOOD, BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) { - warn!("Mismatched trailer for Slot 0"); + warn!("Mismatched trailer for the primary slot"); fails += 1; } if !verify_trailer(&flashmap, &self.slots, 1, BOOT_MAGIC_UNSET, BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) { - warn!("Mismatched trailer for Slot 1"); + warn!("Mismatched trailer for the secondary slot"); fails += 1; } @@ -277,8 +283,9 @@ impl Images { fails > 0 } - // Tests a new image written to slot0 that already has magic and image_ok set - // while there is no image on slot1, so no revert should ever happen... + // Tests a new image written to the primary slot that already has magic and + // image_ok set while there is no image on the secondary slot, so no revert + // should ever happen... pub fn run_signfail_upgrade(&self) -> bool { let mut flashmap = self.flashmap.clone(); let mut fails = 0; @@ -291,7 +298,7 @@ impl Images { if !verify_trailer(&flashmap, &self.slots, 0, BOOT_MAGIC_GOOD, BOOT_FLAG_SET, BOOT_FLAG_UNSET) { - warn!("Mismatched trailer for Slot 0"); + warn!("Mismatched trailer for the primary slot"); fails += 1; } @@ -309,7 +316,7 @@ impl Images { } if !verify_trailer(&flashmap, &self.slots, 0, BOOT_MAGIC_GOOD, BOOT_FLAG_SET, BOOT_FLAG_UNSET) { - warn!("Mismatched trailer for Slot 0"); + warn!("Mismatched trailer for the primary slot"); fails += 1; } @@ -339,7 +346,7 @@ impl Images { /// allowing for fails in the status area. This should run to the end /// and warn that write fails were detected... pub fn run_with_status_fails_complete(&self) -> bool { - if !Caps::ValidateSlot0.present() { + if !Caps::ValidatePrimarySlot.present() { return false; } @@ -366,7 +373,7 @@ impl Images { if !verify_trailer(&flashmap, &self.slots, 0, BOOT_MAGIC_GOOD, BOOT_FLAG_SET, BOOT_FLAG_SET) { - warn!("Mismatched trailer for Slot 0"); + warn!("Mismatched trailer for the primary slot"); fails += 1; } @@ -375,7 +382,8 @@ impl Images { fails += 1; } - info!("validate slot0 enabled; re-run of boot_go should just work"); + info!("validate primary slot enabled; \ + re-run of boot_go should just work"); let (result, _) = c::boot_go(&mut flashmap, &self.areadesc, None, false); if result != 0 { warn!("Failed!"); @@ -395,7 +403,7 @@ impl Images { pub fn run_with_status_fails_with_reset(&self) -> bool { if Caps::OverwriteUpgrade.present() { false - } else if Caps::ValidateSlot0.present() { + } else if Caps::ValidatePrimarySlot.present() { let mut flashmap = self.flashmap.clone(); let mut fails = 0; @@ -425,7 +433,8 @@ impl Images { // or throw a single assert for small sector devices that fail // multiple times... if asserts > 1 { - warn!("Expected single assert validating slot0, more detected {}", asserts); + warn!("Expected single assert validating the primary slot, \ + more detected {}", asserts); fails += 1; } @@ -473,7 +482,7 @@ impl Images { } fn reset_bad_status(&self, flashmap: &mut SimFlashMap, slot: usize) { - if !Caps::ValidateSlot0.present() { + if !Caps::ValidatePrimarySlot.present() { return; } @@ -553,21 +562,23 @@ fn try_revert_with_fail_at(flashmap: &SimFlashMap, images: &Images, } if !verify_image(&flashmap, &images.slots, 0, &images.upgrades) { - warn!("Image in slot 0 before revert is invalid at stop={}", stop); + warn!("Image in the primary slot before revert is invalid at stop={}", + stop); fails += 1; } if !verify_image(&flashmap, &images.slots, 1, &images.primaries) { - warn!("Image in slot 1 before revert is invalid at stop={}", stop); + warn!("Image in the secondary slot before revert is invalid at stop={}", + stop); fails += 1; } if !verify_trailer(&flashmap, &images.slots, 0, BOOT_MAGIC_GOOD, BOOT_FLAG_UNSET, BOOT_FLAG_SET) { - warn!("Mismatched trailer for Slot 0 before revert"); + warn!("Mismatched trailer for the primary slot before revert"); fails += 1; } if !verify_trailer(&flashmap, &images.slots, 1, BOOT_MAGIC_UNSET, BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) { - warn!("Mismatched trailer for Slot 1 before revert"); + warn!("Mismatched trailer for the secondary slot before revert"); fails += 1; } @@ -579,21 +590,23 @@ fn try_revert_with_fail_at(flashmap: &SimFlashMap, images: &Images, } if !verify_image(&flashmap, &images.slots, 0, &images.primaries) { - warn!("Image in slot 0 after revert is invalid at stop={}", stop); + warn!("Image in the primary slot after revert is invalid at stop={}", + stop); fails += 1; } if !verify_image(&flashmap, &images.slots, 1, &images.upgrades) { - warn!("Image in slot 1 after revert is invalid at stop={}", stop); + warn!("Image in the secondary slot after revert is invalid at stop={}", + stop); fails += 1; } if !verify_trailer(&flashmap, &images.slots, 0, BOOT_MAGIC_GOOD, BOOT_FLAG_SET, BOOT_FLAG_SET) { - warn!("Mismatched trailer for Slot 1 after revert"); + warn!("Mismatched trailer for the secondary slot after revert"); fails += 1; } if !verify_trailer(&flashmap, &images.slots, 1, BOOT_MAGIC_UNSET, BOOT_FLAG_UNSET, BOOT_FLAG_UNSET) { - warn!("Mismatched trailer for Slot 1 after revert"); + warn!("Mismatched trailer for the secondary slot after revert"); fails += 1; } @@ -723,10 +736,10 @@ pub fn install_image(flashmap: &mut SimFlashMap, slots: &[SlotInfo], slot: usize let result: [Option>; 2]; - // Since images are always non-encrypted in slot0, we first write an - // encrypted image, re-read to use for verification, erase + flash - // un-encrypted. In slot1 the image is written un-encrypted, and if - // encryption is requested, it follows an erase + flash encrypted. + // Since images are always non-encrypted in the primary slot, we first write + // an encrypted image, re-read to use for verification, erase + flash + // un-encrypted. In the secondary slot the image is written un-encrypted, + // and if encryption is requested, it follows an erase + flash encrypted. let flash = flashmap.get_mut(&dev_id).unwrap(); diff --git a/sim/src/lib.rs b/sim/src/lib.rs index 8131a701b..ce3abfc4d 100644 --- a/sim/src/lib.rs +++ b/sim/src/lib.rs @@ -162,32 +162,34 @@ impl Run { pub fn new(device: DeviceName, align: u8, erased_val: u8) -> Run { let (flashmap, areadesc) = make_device(device, align, erased_val); - let (slot0_base, slot0_len, slot0_dev_id) = areadesc.find(FlashId::Image0); - let (slot1_base, slot1_len, slot1_dev_id) = areadesc.find(FlashId::Image1); + let (primary_slot_base, primary_slot_len, primary_slot_dev_id) = + areadesc.find(FlashId::Image0); + let (secondary_slot_base, secondary_slot_len, secondary_slot_dev_id) = + areadesc.find(FlashId::Image1); // NOTE: not accounting "swap_size" because it is not used by sim... let offset_from_end = c::boot_magic_sz() + c::boot_max_align() * 2; // Construct a primary image. - let slot0 = SlotInfo { - base_off: slot0_base as usize, - trailer_off: slot0_base + slot0_len - offset_from_end, - len: slot0_len as usize, - dev_id: slot0_dev_id, + let primary_slot = SlotInfo { + base_off: primary_slot_base as usize, + trailer_off: primary_slot_base + primary_slot_len - offset_from_end, + len: primary_slot_len as usize, + dev_id: primary_slot_dev_id, }; // And an upgrade image. - let slot1 = SlotInfo { - base_off: slot1_base as usize, - trailer_off: slot1_base + slot1_len - offset_from_end, - len: slot1_len as usize, - dev_id: slot1_dev_id, + let secondary_slot = SlotInfo { + base_off: secondary_slot_base as usize, + trailer_off: secondary_slot_base + secondary_slot_len - offset_from_end, + len: secondary_slot_len as usize, + dev_id: secondary_slot_dev_id, }; Run { flashmap: flashmap, areadesc: areadesc, - slots: [slot0, slot1], + slots: [primary_slot, secondary_slot], } } @@ -236,7 +238,7 @@ impl Run { images } - pub fn make_bad_slot1_image(&self) -> Images { + pub fn make_bad_secondary_slot_image(&self) -> Images { let mut bad_flashmap = self.flashmap.clone(); let primaries = install_image(&mut bad_flashmap, &self.slots, 0, 32784, false); let upgrades = install_image(&mut bad_flashmap, &self.slots, 1, 41928, true); @@ -272,11 +274,11 @@ impl RunStatus { let mut failed = false; - // Creates a badly signed image in slot1 to check that it is not - // upgraded to - let bad_slot1_image = run.make_bad_slot1_image(); + // Creates a badly signed image in the secondary slot to check that + // it is not upgraded to + let bad_secondary_slot_image = run.make_bad_secondary_slot_image(); - failed |= bad_slot1_image.run_signfail_upgrade(); + failed |= bad_secondary_slot_image.run_signfail_upgrade(); let images = run.make_no_upgrade_image(); failed |= images.run_norevert_newimage(); diff --git a/sim/tests/core.rs b/sim/tests/core.rs index 4a6cde31e..4a1931f49 100644 --- a/sim/tests/core.rs +++ b/sim/tests/core.rs @@ -18,7 +18,7 @@ macro_rules! sim_test { }; } -sim_test!(bad_slot1, make_bad_slot1_image, run_signfail_upgrade); +sim_test!(bad_secondary_slot, make_bad_secondary_slot_image, run_signfail_upgrade); sim_test!(norevert_newimage, make_no_upgrade_image, run_norevert_newimage); sim_test!(basic_revert, make_image, run_basic_revert); sim_test!(revert_with_fails, make_image, run_revert_with_fails); diff --git a/testplan/mynewt/Makefile b/testplan/mynewt/Makefile index c98107376..86e7b9c7e 100644 --- a/testplan/mynewt/Makefile +++ b/testplan/mynewt/Makefile @@ -25,22 +25,22 @@ NEWTMGR_IMG := newtmgr $(NEWTMGR_CONN) image all: build-apps build-mcuboot build-blinky: - @echo "* Building blinky for slot 0... \c" + @echo "* Building blinky for the primary slot... \c" @newt build -q $(BLINKY) @echo "ok" build-blinky2: - @echo "* Building blinky2 for slot 1... \c" + @echo "* Building blinky2 for the secondary slot... \c" @newt build -q $(BLINKY2) @echo "ok" build-slinky: - @echo "* Building slinky for slot 0... \c" + @echo "* Building slinky for the primary slot... \c" @newt build -q $(SLINKY) @echo "ok" build-slinky2: - @echo "* Building slinky2 for slot 1... \c" + @echo "* Building slinky2 for the secondary slot... \c" @newt build -q $(SLINKY2) @echo "ok" @@ -71,7 +71,7 @@ build-boot-rsa-ec: @echo "ok" build-boot-rsa-validate0: - @echo "* Building mcuboot with slot 0 validation... \c" + @echo "* Building mcuboot with primary slot validation... \c" @newt build -q $(BOOT_RSA_VALIDATE0) @echo "ok"