mirror of https://github.com/wolfSSL/wolfBoot.git
Merge pull request #463 from jpbland1/bad-image-recovery
add emergency fallback test, currently fails due topull/408/head
commit
b9dc7eee46
|
@ -51,6 +51,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-internal-flash-with-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
|
|
||||||
# TEST with NVM_WRITEONCE enabled
|
# TEST with NVM_WRITEONCE enabled
|
||||||
- name: make clean
|
- name: make clean
|
||||||
|
@ -89,6 +97,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-internal-flash-with-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
|
|
||||||
# TEST with NVM_WRITEONCE AND FLAGS_HOME enabled
|
# TEST with NVM_WRITEONCE AND FLAGS_HOME enabled
|
||||||
- name: make clean
|
- name: make clean
|
||||||
|
@ -127,6 +143,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-internal-flash-with-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
|
|
||||||
# TEST with NVM_WRITEONCE AND FLAGS_HOME AND FLAGS_INVERT enabled
|
# TEST with NVM_WRITEONCE AND FLAGS_HOME AND FLAGS_INVERT enabled
|
||||||
- name: make clean
|
- name: make clean
|
||||||
|
@ -165,6 +189,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-external-flash-with-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
|
|
||||||
# TEST with DELTA updates
|
# TEST with DELTA updates
|
||||||
- name: make clean
|
- name: make clean
|
||||||
|
@ -189,7 +221,7 @@ jobs:
|
||||||
|
|
||||||
- name: Rebuild wolfboot.elf
|
- name: Rebuild wolfboot.elf
|
||||||
run: |
|
run: |
|
||||||
make test-sim-internal-flash-with-delta-update
|
make clean && make test-sim-internal-flash-with-delta-update
|
||||||
|
|
||||||
- name: Run update-revert test (DELTA)
|
- name: Run update-revert test (DELTA)
|
||||||
run: |
|
run: |
|
||||||
|
@ -197,7 +229,7 @@ jobs:
|
||||||
|
|
||||||
- name: Rebuild wolfboot.elf
|
- name: Rebuild wolfboot.elf
|
||||||
run: |
|
run: |
|
||||||
make test-sim-internal-flash-with-delta-update
|
make clean && make test-sim-internal-flash-with-delta-update
|
||||||
|
|
||||||
- name: Run update-revert test with power failures (DELTA)
|
- name: Run update-revert test with power failures (DELTA)
|
||||||
run: |
|
run: |
|
||||||
|
@ -248,6 +280,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-external-flash-with-enc-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
# TEST with encryption (aes128) and delta updates
|
# TEST with encryption (aes128) and delta updates
|
||||||
- name: make clean
|
- name: make clean
|
||||||
run: |
|
run: |
|
||||||
|
@ -322,6 +362,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-external-flash-with-enc-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
# TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME
|
# TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME
|
||||||
|
|
||||||
- name: make clean
|
- name: make clean
|
||||||
|
@ -355,6 +403,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-external-flash-with-enc-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
# TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME and FLAGS_INVERT
|
# TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME and FLAGS_INVERT
|
||||||
|
|
||||||
- name: make clean
|
- name: make clean
|
||||||
|
@ -388,6 +444,14 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume.sh
|
tools/scripts/sim-update-powerfail-resume.sh
|
||||||
|
|
||||||
|
- name: Rebuild wolfboot.elf
|
||||||
|
run: |
|
||||||
|
make clean && make test-sim-external-flash-with-enc-update
|
||||||
|
|
||||||
|
- name: Run emergency fallback test
|
||||||
|
run: |
|
||||||
|
tools/scripts/sim-update-emergency-fallback.sh
|
||||||
|
|
||||||
# TEST with encryption (aes128) and NVM_WRITEONCE and DELTA updates
|
# TEST with encryption (aes128) and NVM_WRITEONCE and DELTA updates
|
||||||
- name: make clean
|
- name: make clean
|
||||||
run: |
|
run: |
|
||||||
|
@ -451,6 +515,7 @@ jobs:
|
||||||
- name: Run update test with DISABLE_BACKUP and powefail
|
- name: Run update test with DISABLE_BACKUP and powefail
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume-nobackup.sh
|
tools/scripts/sim-update-powerfail-resume-nobackup.sh
|
||||||
|
|
||||||
# TEST with backup disabled + NVM_WRITEONCE
|
# TEST with backup disabled + NVM_WRITEONCE
|
||||||
- name: make clean
|
- name: make clean
|
||||||
run: |
|
run: |
|
||||||
|
@ -478,6 +543,7 @@ jobs:
|
||||||
- name: Run update test with DISABLE_BACKUP and powefail
|
- name: Run update test with DISABLE_BACKUP and powefail
|
||||||
run: |
|
run: |
|
||||||
tools/scripts/sim-update-powerfail-resume-nobackup.sh
|
tools/scripts/sim-update-powerfail-resume-nobackup.sh
|
||||||
|
|
||||||
# TEST with backup disabled + FLAGS_HOME
|
# TEST with backup disabled + FLAGS_HOME
|
||||||
- name: make clean
|
- name: make clean
|
||||||
run: |
|
run: |
|
||||||
|
|
29
hal/sim.c
29
hal/sim.c
|
@ -45,6 +45,7 @@
|
||||||
uint8_t *sim_ram_base;
|
uint8_t *sim_ram_base;
|
||||||
static uint8_t *flash_base;
|
static uint8_t *flash_base;
|
||||||
|
|
||||||
|
int forceEmergency = 0;
|
||||||
uint32_t erasefail_address = 0xFFFFFFFF;
|
uint32_t erasefail_address = 0xFFFFFFFF;
|
||||||
|
|
||||||
#define INTERNAL_FLASH_FILE "./internal_flash.dd"
|
#define INTERNAL_FLASH_FILE "./internal_flash.dd"
|
||||||
|
@ -105,8 +106,29 @@ void hal_prepare_boot(void)
|
||||||
|
|
||||||
int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
|
int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
if (forceEmergency == 1 && address == WOLFBOOT_PARTITION_BOOT_ADDRESS) {
|
||||||
/* implicit cast abide compiler warning */
|
/* implicit cast abide compiler warning */
|
||||||
memcpy((void*)address, data, len);
|
memset((void*)address, 0, len);
|
||||||
|
/* let the rest of the writes work properly for the emergency update */
|
||||||
|
forceEmergency = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
#ifdef NVM_FLASH_WRITEONCE
|
||||||
|
if (((uint8_t*)address)[i] != FLASH_BYTE_ERASED) {
|
||||||
|
/* no writing to non-erased page in NVM_FLASH_WRITEONCE */
|
||||||
|
printf("NVM_FLASH_WRITEONCE non-erased write detected!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef WOLFBOOT_FLAGS_INVERT
|
||||||
|
((uint8_t*)address)[i] |= data[i];
|
||||||
|
#else
|
||||||
|
((uint8_t*)address)[i] &= data[i];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,8 +172,11 @@ void hal_init(void)
|
||||||
erasefail_address = strtol(main_argv[++i], NULL, 16);
|
erasefail_address = strtol(main_argv[++i], NULL, 16);
|
||||||
fprintf(stderr, "Set power fail to erase at address %x\n",
|
fprintf(stderr, "Set power fail to erase at address %x\n",
|
||||||
erasefail_address);
|
erasefail_address);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
/* force a bad write of the boot partition to trigger and test the
|
||||||
|
* emergency fallback feature */
|
||||||
|
else if (strcmp(main_argv[i], "emergency") == 0)
|
||||||
|
forceEmergency = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,8 @@ extern "C" {
|
||||||
#ifndef WOLFBOOT_FLAGS_INVERT
|
#ifndef WOLFBOOT_FLAGS_INVERT
|
||||||
#define IMG_STATE_NEW 0xFF
|
#define IMG_STATE_NEW 0xFF
|
||||||
#define IMG_STATE_UPDATING 0x70
|
#define IMG_STATE_UPDATING 0x70
|
||||||
|
/* now just an intermediary state, update state will always be either new or
|
||||||
|
* updating before the application boots*/
|
||||||
#define IMG_STATE_FINAL_FLAGS 0x30
|
#define IMG_STATE_FINAL_FLAGS 0x30
|
||||||
#define IMG_STATE_TESTING 0x10
|
#define IMG_STATE_TESTING 0x10
|
||||||
#define IMG_STATE_SUCCESS 0x00
|
#define IMG_STATE_SUCCESS 0x00
|
||||||
|
@ -265,8 +267,8 @@ extern "C" {
|
||||||
#else
|
#else
|
||||||
#define IMG_STATE_NEW 0x00
|
#define IMG_STATE_NEW 0x00
|
||||||
#define IMG_STATE_UPDATING 0x8F
|
#define IMG_STATE_UPDATING 0x8F
|
||||||
#define IMG_STATE_FINAL_FLAGS 0xBF
|
|
||||||
#define IMG_STATE_TESTING 0xEF
|
#define IMG_STATE_TESTING 0xEF
|
||||||
|
#define IMG_STATE_FINAL_FLAGS 0xBF
|
||||||
#define IMG_STATE_SUCCESS 0xFF
|
#define IMG_STATE_SUCCESS 0xFF
|
||||||
#define FLASH_BYTE_ERASED 0x00
|
#define FLASH_BYTE_ERASED 0x00
|
||||||
#define FLASH_WORD_ERASED 0x00000000UL
|
#define FLASH_WORD_ERASED 0x00000000UL
|
||||||
|
|
30
src/image.c
30
src/image.c
|
@ -611,8 +611,6 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
|
||||||
*/
|
*/
|
||||||
static void key_sha256(uint8_t key_slot, uint8_t *hash)
|
static void key_sha256(uint8_t key_slot, uint8_t *hash)
|
||||||
{
|
{
|
||||||
int blksz;
|
|
||||||
unsigned int i = 0;
|
|
||||||
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
||||||
int pubkey_sz = keystore_get_size(key_slot);
|
int pubkey_sz = keystore_get_size(key_slot);
|
||||||
wc_Sha256 sha256_ctx;
|
wc_Sha256 sha256_ctx;
|
||||||
|
@ -621,13 +619,7 @@ static void key_sha256(uint8_t key_slot, uint8_t *hash)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wc_InitSha256(&sha256_ctx);
|
wc_InitSha256(&sha256_ctx);
|
||||||
while (i < (uint32_t)pubkey_sz) {
|
wc_Sha256Update(&sha256_ctx, pubkey, (word32)pubkey_sz);
|
||||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
|
||||||
if ((i + blksz) > (uint32_t)pubkey_sz)
|
|
||||||
blksz = pubkey_sz - i;
|
|
||||||
wc_Sha256Update(&sha256_ctx, (pubkey + i), blksz);
|
|
||||||
i += blksz;
|
|
||||||
}
|
|
||||||
wc_Sha256Final(&sha256_ctx, hash);
|
wc_Sha256Final(&sha256_ctx, hash);
|
||||||
}
|
}
|
||||||
#endif /* WOLFBOOT_NO_SIGN */
|
#endif /* WOLFBOOT_NO_SIGN */
|
||||||
|
@ -700,8 +692,6 @@ static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
|
||||||
*/
|
*/
|
||||||
static void key_sha384(uint8_t key_slot, uint8_t *hash)
|
static void key_sha384(uint8_t key_slot, uint8_t *hash)
|
||||||
{
|
{
|
||||||
int blksz;
|
|
||||||
unsigned int i = 0;
|
|
||||||
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
||||||
int pubkey_sz = keystore_get_size(key_slot);
|
int pubkey_sz = keystore_get_size(key_slot);
|
||||||
wc_Sha384 sha384_ctx;
|
wc_Sha384 sha384_ctx;
|
||||||
|
@ -710,13 +700,7 @@ static void key_sha384(uint8_t key_slot, uint8_t *hash)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wc_InitSha384(&sha384_ctx);
|
wc_InitSha384(&sha384_ctx);
|
||||||
while (i < (uint32_t)(pubkey_sz)) {
|
wc_Sha384Update(&sha384_ctx, pubkey, (word32)pubkey_sz);
|
||||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
|
||||||
if ((i + blksz) > (uint32_t)pubkey_sz)
|
|
||||||
blksz = pubkey_sz - i;
|
|
||||||
wc_Sha384Update(&sha384_ctx, (pubkey + i), blksz);
|
|
||||||
i += blksz;
|
|
||||||
}
|
|
||||||
wc_Sha384Final(&sha384_ctx, hash);
|
wc_Sha384Final(&sha384_ctx, hash);
|
||||||
}
|
}
|
||||||
#endif /* WOLFBOOT_NO_SIGN */
|
#endif /* WOLFBOOT_NO_SIGN */
|
||||||
|
@ -789,8 +773,6 @@ static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
|
||||||
*/
|
*/
|
||||||
static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
|
static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
|
||||||
{
|
{
|
||||||
int blksz;
|
|
||||||
unsigned int i = 0;
|
|
||||||
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
uint8_t *pubkey = keystore_get_buffer(key_slot);
|
||||||
int pubkey_sz = keystore_get_size(key_slot);
|
int pubkey_sz = keystore_get_size(key_slot);
|
||||||
wc_Sha3 sha3_ctx;
|
wc_Sha3 sha3_ctx;
|
||||||
|
@ -798,13 +780,7 @@ static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
|
||||||
if (!pubkey || (pubkey_sz < 0))
|
if (!pubkey || (pubkey_sz < 0))
|
||||||
return;
|
return;
|
||||||
wc_InitSha3_384(&sha3_ctx, NULL, INVALID_DEVID);
|
wc_InitSha3_384(&sha3_ctx, NULL, INVALID_DEVID);
|
||||||
while (i < (uint32_t)pubkey_sz) {
|
wc_Sha3_384_Update(&sha3_ctx, pubkey, (word32)pubkey_sz);
|
||||||
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
|
|
||||||
if ((i + blksz) > (uint32_t)pubkey_sz)
|
|
||||||
blksz = pubkey_sz - i;
|
|
||||||
wc_Sha3_384_Update(&sha3_ctx, pubkey + i, blksz);
|
|
||||||
i += blksz;
|
|
||||||
}
|
|
||||||
wc_Sha3_384_Final(&sha3_ctx, hash);
|
wc_Sha3_384_Final(&sha3_ctx, hash);
|
||||||
}
|
}
|
||||||
#endif /* WOLFBOOT_NO_SIGN */
|
#endif /* WOLFBOOT_NO_SIGN */
|
||||||
|
|
|
@ -350,12 +350,8 @@ static int RAMFUNCTION trailer_write(uint8_t part, uintptr_t addr, uint8_t val)
|
||||||
/* Calculate write address */
|
/* Calculate write address */
|
||||||
addr_write = addr_align - ((!nvm_cached_sector) * NVM_CACHE_SIZE);
|
addr_write = addr_align - ((!nvm_cached_sector) * NVM_CACHE_SIZE);
|
||||||
|
|
||||||
/* Ensure that the destination was erased, or force erase */
|
/* Ensure that the destination was erased */
|
||||||
if (*((uint32_t *)(addr_write + NVM_CACHE_SIZE - sizeof(uint32_t)))
|
|
||||||
!= FLASH_WORD_ERASED)
|
|
||||||
{
|
|
||||||
hal_flash_erase(addr_write, NVM_CACHE_SIZE);
|
hal_flash_erase(addr_write, NVM_CACHE_SIZE);
|
||||||
}
|
|
||||||
#if FLASHBUFFER_SIZE != WOLFBOOT_SECTOR_SIZE
|
#if FLASHBUFFER_SIZE != WOLFBOOT_SECTOR_SIZE
|
||||||
addr_off = 0;
|
addr_off = 0;
|
||||||
while ((addr_off < WOLFBOOT_SECTOR_SIZE) && (ret == 0)) {
|
while ((addr_off < WOLFBOOT_SECTOR_SIZE) && (ret == 0)) {
|
||||||
|
@ -718,17 +714,21 @@ void RAMFUNCTION wolfBoot_erase_partition(uint8_t part)
|
||||||
uint32_t address = 0;
|
uint32_t address = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
if (part == PART_BOOT) {
|
switch (part) {
|
||||||
|
case PART_BOOT:
|
||||||
address = (uint32_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
address = (uint32_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
||||||
size = WOLFBOOT_PARTITION_SIZE;
|
size = WOLFBOOT_PARTITION_SIZE;
|
||||||
}
|
break;
|
||||||
if (part == PART_UPDATE) {
|
case PART_UPDATE:
|
||||||
address = (uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
|
address = (uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
|
||||||
size = WOLFBOOT_PARTITION_SIZE;
|
size = WOLFBOOT_PARTITION_SIZE;
|
||||||
}
|
break;
|
||||||
if (part == PART_SWAP) {
|
case PART_SWAP:
|
||||||
address = (uint32_t)WOLFBOOT_PARTITION_SWAP_ADDRESS;
|
address = (uint32_t)WOLFBOOT_PARTITION_SWAP_ADDRESS;
|
||||||
size = WOLFBOOT_SECTOR_SIZE;
|
size = WOLFBOOT_SECTOR_SIZE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
|
@ -819,16 +819,10 @@ void RAMFUNCTION wolfBoot_success(void)
|
||||||
if (FLAGS_BOOT_EXT()) {
|
if (FLAGS_BOOT_EXT()) {
|
||||||
ext_flash_unlock();
|
ext_flash_unlock();
|
||||||
wolfBoot_set_partition_state(PART_BOOT, st);
|
wolfBoot_set_partition_state(PART_BOOT, st);
|
||||||
/* set update so IMG_STATE_FINAL_FLAGS isn't triggering pointless calls
|
|
||||||
* to wolfBoot update */
|
|
||||||
wolfBoot_set_partition_state(PART_UPDATE, st);
|
|
||||||
ext_flash_lock();
|
ext_flash_lock();
|
||||||
} else {
|
} else {
|
||||||
hal_flash_unlock();
|
hal_flash_unlock();
|
||||||
wolfBoot_set_partition_state(PART_BOOT, st);
|
wolfBoot_set_partition_state(PART_BOOT, st);
|
||||||
/* set update so IMG_STATE_FINAL_FLAGS isn't triggering pointless calls
|
|
||||||
* to wolfBoot update */
|
|
||||||
wolfBoot_set_partition_state(PART_UPDATE, st);
|
|
||||||
hal_flash_lock();
|
hal_flash_lock();
|
||||||
}
|
}
|
||||||
#ifdef EXT_ENCRYPTED
|
#ifdef EXT_ENCRYPTED
|
||||||
|
@ -866,13 +860,9 @@ uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr)
|
||||||
unit_dbg("Explicit end of options reached\n");
|
unit_dbg("Explicit end of options reached\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*p == HDR_PADDING) {
|
/* Sanity check to prevent dereferencing unaligned half-words and skip
|
||||||
/* Padding byte (skip one position) */
|
* past padding bytes */
|
||||||
p++;
|
if ((*p == HDR_PADDING) || ((((size_t)p) & 0x01) != 0)) {
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* Sanity check to prevent dereferencing unaligned half-words */
|
|
||||||
if ((((size_t)p) & 0x01) != 0) {
|
|
||||||
p++;
|
p++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,6 +194,93 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src,
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef DISABLE_BACKUP
|
||||||
|
static int wolfBoot_swap_and_final_erase(int resume)
|
||||||
|
{
|
||||||
|
struct wolfBoot_image boot[1];
|
||||||
|
struct wolfBoot_image update[1];
|
||||||
|
struct wolfBoot_image swap[1];
|
||||||
|
uint8_t st;
|
||||||
|
int eraseLen = WOLFBOOT_SECTOR_SIZE
|
||||||
|
#ifdef NVM_FLASH_WRITEONCE
|
||||||
|
/* need to erase the redundant sector too */
|
||||||
|
* 2
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
int swapDone = 0;
|
||||||
|
uintptr_t tmpBootPos = WOLFBOOT_PARTITION_SIZE - eraseLen -
|
||||||
|
WOLFBOOT_SECTOR_SIZE;
|
||||||
|
/* final swap and erase flag is WOLFBOOT_MAGIC_TRAIL */
|
||||||
|
uint8_t tmpBuffer[sizeof(WOLFBOOT_MAGIC_TRAIL)
|
||||||
|
#ifdef EXT_ENCRYPTED
|
||||||
|
+ ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE
|
||||||
|
#endif
|
||||||
|
];
|
||||||
|
/* open boot */
|
||||||
|
wolfBoot_open_image(boot, PART_BOOT);
|
||||||
|
/* open update */
|
||||||
|
wolfBoot_open_image(update, PART_UPDATE);
|
||||||
|
/* open swap */
|
||||||
|
wolfBoot_open_image(swap, PART_SWAP);
|
||||||
|
wolfBoot_get_partition_state(PART_UPDATE, &st);
|
||||||
|
/* read from tmpBootPos */
|
||||||
|
memcpy((void*)tmpBuffer, (void*)(boot->hdr + tmpBootPos),
|
||||||
|
sizeof(tmpBuffer));
|
||||||
|
/* check for TRAIL */
|
||||||
|
#ifdef EXT_ENCRYPTED
|
||||||
|
if (*(uint32_t*)(tmpBuffer + ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE) ==
|
||||||
|
WOLFBOOT_MAGIC_TRAIL) {
|
||||||
|
swapDone = 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (((uint32_t*)tmpBuffer)[0] == WOLFBOOT_MAGIC_TRAIL) {
|
||||||
|
swapDone = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* if resuming, quit if swap isn't done */
|
||||||
|
if ((resume == 1) && (swapDone == 0) && (st != IMG_STATE_FINAL_FLAGS))
|
||||||
|
return -1;
|
||||||
|
if (swapDone == 0) {
|
||||||
|
/* IMG_STATE_FINAL_FLAGS allows re-entry without blowing away swap */
|
||||||
|
if (st != IMG_STATE_FINAL_FLAGS) {
|
||||||
|
/* store the sector at tmpBootPos into swap */
|
||||||
|
wolfBoot_copy_sector(boot, swap, tmpBootPos / WOLFBOOT_SECTOR_SIZE);
|
||||||
|
/* set FINAL_SWAP for re-entry */
|
||||||
|
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_FINAL_FLAGS);
|
||||||
|
}
|
||||||
|
#ifdef EXT_ENCRYPTED
|
||||||
|
/* get encryption key and iv if encryption is enabled */
|
||||||
|
wolfBoot_get_encrypt_key(tmpBuffer, tmpBuffer + ENCRYPT_KEY_SIZE);
|
||||||
|
#endif
|
||||||
|
/* write TRAIL, encryption key and iv if enabled to tmpBootPos*/
|
||||||
|
#ifdef EXT_ENCRYPTED
|
||||||
|
*(uint32_t*)(tmpBuffer + ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE)
|
||||||
|
= WOLFBOOT_MAGIC_TRAIL;
|
||||||
|
#else
|
||||||
|
((uint32_t*)tmpBuffer)[0] = WOLFBOOT_MAGIC_TRAIL;
|
||||||
|
#endif
|
||||||
|
wb_flash_erase(boot, tmpBootPos, WOLFBOOT_SECTOR_SIZE);
|
||||||
|
wb_flash_write(boot, tmpBootPos, (void*)tmpBuffer, sizeof(tmpBuffer));
|
||||||
|
}
|
||||||
|
/* erase the last boot sector(s) */
|
||||||
|
wb_flash_erase(boot, WOLFBOOT_PARTITION_SIZE - eraseLen, eraseLen);
|
||||||
|
/* set the encryption key */
|
||||||
|
#ifdef EXT_ENCRYPTED
|
||||||
|
wolfBoot_set_encrypt_key(tmpBuffer, tmpBuffer + ENCRYPT_KEY_SIZE);
|
||||||
|
#endif
|
||||||
|
/* write the original contents of tmpBootPos back */
|
||||||
|
if (tmpBootPos < boot->fw_size + IMAGE_HEADER_SIZE)
|
||||||
|
wolfBoot_copy_sector(swap, boot, tmpBootPos / WOLFBOOT_SECTOR_SIZE);
|
||||||
|
else
|
||||||
|
wb_flash_erase(boot, tmpBootPos, WOLFBOOT_SECTOR_SIZE);
|
||||||
|
/* mark boot as TESTING */
|
||||||
|
wolfBoot_set_partition_state(PART_BOOT, IMG_STATE_TESTING);
|
||||||
|
/* erase the last sector(s) of update */
|
||||||
|
wb_flash_erase(update, WOLFBOOT_PARTITION_SIZE - eraseLen, eraseLen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DELTA_UPDATES
|
#ifdef DELTA_UPDATES
|
||||||
|
|
||||||
#ifndef DELTA_BLOCK_SIZE
|
#ifndef DELTA_BLOCK_SIZE
|
||||||
|
@ -202,7 +289,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src,
|
||||||
|
|
||||||
static int wolfBoot_delta_update(struct wolfBoot_image *boot,
|
static int wolfBoot_delta_update(struct wolfBoot_image *boot,
|
||||||
struct wolfBoot_image *update, struct wolfBoot_image *swap, int inverse,
|
struct wolfBoot_image *update, struct wolfBoot_image *swap, int inverse,
|
||||||
int resume_inverse)
|
int resume)
|
||||||
{
|
{
|
||||||
int sector = 0;
|
int sector = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -242,14 +329,14 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
|
||||||
upd_v = wolfBoot_update_firmware_version();
|
upd_v = wolfBoot_update_firmware_version();
|
||||||
delta_base_v = wolfBoot_get_diffbase_version(PART_UPDATE);
|
delta_base_v = wolfBoot_get_diffbase_version(PART_UPDATE);
|
||||||
if (inverse) {
|
if (inverse) {
|
||||||
if (((cur_v == upd_v) && (delta_base_v < cur_v)) || resume_inverse) {
|
if (((cur_v == upd_v) && (delta_base_v < cur_v)) || resume) {
|
||||||
ret = wb_patch_init(&ctx, boot->hdr, boot->fw_size +
|
ret = wb_patch_init(&ctx, boot->hdr, boot->fw_size +
|
||||||
IMAGE_HEADER_SIZE, update->hdr + *img_offset, *img_size);
|
IMAGE_HEADER_SIZE, update->hdr + *img_offset, *img_size);
|
||||||
} else {
|
} else {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!resume_inverse && (cur_v != delta_base_v)) {
|
if (!resume && (cur_v != delta_base_v)) {
|
||||||
/* Wrong base image, cannot apply delta patch */
|
/* Wrong base image, cannot apply delta patch */
|
||||||
ret = -1;
|
ret = -1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -346,14 +433,10 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
|
||||||
wb_flash_erase(boot, sector * WOLFBOOT_SECTOR_SIZE, WOLFBOOT_SECTOR_SIZE);
|
wb_flash_erase(boot, sector * WOLFBOOT_SECTOR_SIZE, WOLFBOOT_SECTOR_SIZE);
|
||||||
sector++;
|
sector++;
|
||||||
}
|
}
|
||||||
/* mark that our sector flags aren't reliable in testing mode */
|
/* start re-entrant final erase, return code is only for resumption in
|
||||||
st = IMG_STATE_FINAL_FLAGS;
|
* wolfBoot_start*/
|
||||||
wolfBoot_set_partition_state(PART_UPDATE, st);
|
wolfBoot_swap_and_final_erase(0);
|
||||||
/* mark boot partition as testing */
|
|
||||||
st = IMG_STATE_TESTING;
|
|
||||||
wolfBoot_set_partition_state(PART_BOOT, st);
|
|
||||||
out:
|
out:
|
||||||
wb_flash_erase(swap, 0, WOLFBOOT_SECTOR_SIZE);
|
|
||||||
#ifdef EXT_FLASH
|
#ifdef EXT_FLASH
|
||||||
ext_flash_lock();
|
ext_flash_lock();
|
||||||
#endif
|
#endif
|
||||||
|
@ -377,7 +460,7 @@ out:
|
||||||
#define MAX_UPDATE_SIZE (size_t)((WOLFBOOT_PARTITION_SIZE - (2 *WOLFBOOT_SECTOR_SIZE)))
|
#define MAX_UPDATE_SIZE (size_t)((WOLFBOOT_PARTITION_SIZE - (2 *WOLFBOOT_SECTOR_SIZE)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline int wolfBoot_get_total_size(struct wolfBoot_image* boot,
|
static int wolfBoot_get_total_size(struct wolfBoot_image* boot,
|
||||||
struct wolfBoot_image* update)
|
struct wolfBoot_image* update)
|
||||||
{
|
{
|
||||||
uint32_t total_size = 0;
|
uint32_t total_size = 0;
|
||||||
|
@ -392,20 +475,28 @@ static inline int wolfBoot_get_total_size(struct wolfBoot_image* boot,
|
||||||
|
|
||||||
static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
||||||
{
|
{
|
||||||
|
int flagRet;
|
||||||
uint32_t total_size = 0;
|
uint32_t total_size = 0;
|
||||||
const uint32_t sector_size = WOLFBOOT_SECTOR_SIZE;
|
const uint32_t sector_size = WOLFBOOT_SECTOR_SIZE;
|
||||||
uint32_t sector = 0;
|
uint32_t sector = 0;
|
||||||
uint8_t flag, st;
|
/* we need to pre-set flag to SECT_FLAG_NEW in case magic hasn't been set
|
||||||
|
* on the update partion as part of the delta update direction check. if
|
||||||
|
* magic has not been set flag will have an un-determined value when we go
|
||||||
|
* to check it */
|
||||||
|
uint8_t flag = SECT_FLAG_NEW;
|
||||||
|
uint8_t st;
|
||||||
struct wolfBoot_image boot, update, swap;
|
struct wolfBoot_image boot, update, swap;
|
||||||
uint16_t update_type;
|
uint16_t update_type;
|
||||||
uint32_t fw_size;
|
uint32_t fw_size;
|
||||||
|
uint32_t size;
|
||||||
#if defined(DISABLE_BACKUP) && defined(EXT_ENCRYPTED)
|
#if defined(DISABLE_BACKUP) && defined(EXT_ENCRYPTED)
|
||||||
uint8_t key[ENCRYPT_KEY_SIZE];
|
uint8_t key[ENCRYPT_KEY_SIZE];
|
||||||
uint8_t nonce[ENCRYPT_NONCE_SIZE];
|
uint8_t nonce[ENCRYPT_NONCE_SIZE];
|
||||||
#endif
|
#endif
|
||||||
#ifdef DELTA_UPDATES
|
#ifdef DELTA_UPDATES
|
||||||
int inverse = 0;
|
int inverse = 0;
|
||||||
int inverse_resume = 0;
|
int resume = 0;
|
||||||
|
int stateRet = -1;
|
||||||
uint32_t cur_v;
|
uint32_t cur_v;
|
||||||
uint32_t up_v;
|
uint32_t up_v;
|
||||||
#endif
|
#endif
|
||||||
|
@ -427,10 +518,9 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
||||||
|
|
||||||
update_type = wolfBoot_get_image_type(PART_UPDATE);
|
update_type = wolfBoot_get_image_type(PART_UPDATE);
|
||||||
|
|
||||||
|
wolfBoot_get_update_sector_flag(0, &flag);
|
||||||
/* Check the first sector to detect interrupted update */
|
/* Check the first sector to detect interrupted update */
|
||||||
if ((wolfBoot_get_update_sector_flag(0, &flag) < 0) ||
|
if (flag == SECT_FLAG_NEW) {
|
||||||
(flag == SECT_FLAG_NEW))
|
|
||||||
{
|
|
||||||
if (((update_type & 0x000F) != HDR_IMG_TYPE_APP) ||
|
if (((update_type & 0x000F) != HDR_IMG_TYPE_APP) ||
|
||||||
((update_type & 0xFF00) != HDR_IMG_TYPE_AUTH))
|
((update_type & 0xFF00) != HDR_IMG_TYPE_AUTH))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -458,20 +548,31 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
||||||
cur_v = wolfBoot_current_firmware_version();
|
cur_v = wolfBoot_current_firmware_version();
|
||||||
up_v = wolfBoot_update_firmware_version();
|
up_v = wolfBoot_update_firmware_version();
|
||||||
inverse = cur_v >= up_v;
|
inverse = cur_v >= up_v;
|
||||||
|
/* if magic isn't set stateRet will be -1 but that means we're on a
|
||||||
|
* fresh partition and aren't resuming */
|
||||||
|
stateRet = wolfBoot_get_partition_state(PART_UPDATE, &st);
|
||||||
|
|
||||||
/* if the first sector flag is not new but we are updating then */
|
/* if we've already written a sector or we've mangled the boot partition
|
||||||
/* we were interrupted */
|
* header we can't determine the direction by version numbers. instead
|
||||||
if (flag != SECT_FLAG_NEW &&
|
* use the update partition state, updating means regular, new means
|
||||||
wolfBoot_get_partition_state(PART_UPDATE, &st) == 0 &&
|
* reverting */
|
||||||
st == IMG_STATE_UPDATING) {
|
if ((stateRet == 0) && ((flag != SECT_FLAG_NEW) || (cur_v == 0))) {
|
||||||
if ((cur_v == 0) || (cur_v == up_v)) {
|
resume = 1;
|
||||||
|
if (st == IMG_STATE_UPDATING) {
|
||||||
|
inverse = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
inverse = 1;
|
inverse = 1;
|
||||||
inverse_resume = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* If we're dealing with a "ping-pong" fallback that wasn't interrupted
|
||||||
|
* we need to set to UPDATING, otherwise there's no way to tell the
|
||||||
|
* original direction of the update once interrupted */
|
||||||
|
else if ((inverse == 0) && (fallback_allowed == 1)) {
|
||||||
|
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING);
|
||||||
|
}
|
||||||
|
|
||||||
return wolfBoot_delta_update(&boot, &update, &swap, inverse,
|
return wolfBoot_delta_update(&boot, &update, &swap, inverse, resume);
|
||||||
inverse_resume);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -486,29 +587,37 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
||||||
* If something goes wrong, the operation will be resumed upon reboot.
|
* If something goes wrong, the operation will be resumed upon reboot.
|
||||||
*/
|
*/
|
||||||
while ((sector * sector_size) < total_size) {
|
while ((sector * sector_size) < total_size) {
|
||||||
if ((wolfBoot_get_update_sector_flag(sector, &flag) != 0) || (flag == SECT_FLAG_NEW)) {
|
flag = SECT_FLAG_NEW;
|
||||||
|
wolfBoot_get_update_sector_flag(sector, &flag);
|
||||||
|
switch (flag) {
|
||||||
|
case SECT_FLAG_NEW:
|
||||||
flag = SECT_FLAG_SWAPPING;
|
flag = SECT_FLAG_SWAPPING;
|
||||||
wolfBoot_copy_sector(&update, &swap, sector);
|
wolfBoot_copy_sector(&update, &swap, sector);
|
||||||
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
|
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
|
||||||
wolfBoot_set_update_sector_flag(sector, flag);
|
wolfBoot_set_update_sector_flag(sector, flag);
|
||||||
}
|
/* FALL THROUGH */
|
||||||
if (flag == SECT_FLAG_SWAPPING) {
|
case SECT_FLAG_SWAPPING:
|
||||||
uint32_t size = total_size - (sector * sector_size);
|
size = total_size - (sector * sector_size);
|
||||||
if (size > sector_size)
|
if (size > sector_size)
|
||||||
size = sector_size;
|
size = sector_size;
|
||||||
flag = SECT_FLAG_BACKUP;
|
flag = SECT_FLAG_BACKUP;
|
||||||
wolfBoot_copy_sector(&boot, &update, sector);
|
wolfBoot_copy_sector(&boot, &update, sector);
|
||||||
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
|
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
|
||||||
wolfBoot_set_update_sector_flag(sector, flag);
|
wolfBoot_set_update_sector_flag(sector, flag);
|
||||||
}
|
/* FALL THROUGH */
|
||||||
if (flag == SECT_FLAG_BACKUP) {
|
case SECT_FLAG_BACKUP:
|
||||||
uint32_t size = total_size - (sector * sector_size);
|
size = total_size - (sector * sector_size);
|
||||||
if (size > sector_size)
|
if (size > sector_size)
|
||||||
size = sector_size;
|
size = sector_size;
|
||||||
flag = SECT_FLAG_UPDATED;
|
flag = SECT_FLAG_UPDATED;
|
||||||
wolfBoot_copy_sector(&swap, &boot, sector);
|
wolfBoot_copy_sector(&swap, &boot, sector);
|
||||||
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
|
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
|
||||||
wolfBoot_set_update_sector_flag(sector, flag);
|
wolfBoot_set_update_sector_flag(sector, flag);
|
||||||
|
break;
|
||||||
|
case SECT_FLAG_UPDATED:
|
||||||
|
/* FALL THROUGH */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
sector++;
|
sector++;
|
||||||
/* headers that can be in different positions depending on when the
|
/* headers that can be in different positions depending on when the
|
||||||
|
@ -526,9 +635,6 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
||||||
|
|
||||||
/* get total size */
|
/* get total size */
|
||||||
total_size = wolfBoot_get_total_size(&boot, &update);
|
total_size = wolfBoot_get_total_size(&boot, &update);
|
||||||
|
|
||||||
if (total_size <= IMAGE_HEADER_SIZE)
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* erase to the last sector, writeonce has 2 sectors */
|
/* erase to the last sector, writeonce has 2 sectors */
|
||||||
|
@ -542,13 +648,9 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
|
||||||
wb_flash_erase(&update, sector * sector_size, sector_size);
|
wb_flash_erase(&update, sector * sector_size, sector_size);
|
||||||
sector++;
|
sector++;
|
||||||
}
|
}
|
||||||
/* mark that our sector flags aren't reliable in testing mode */
|
/* start re-entrant final erase, return code is only for resumption in
|
||||||
st = IMG_STATE_FINAL_FLAGS;
|
* wolfBoot_start*/
|
||||||
wolfBoot_set_partition_state(PART_UPDATE, st);
|
wolfBoot_swap_and_final_erase(0);
|
||||||
/* mark boot partition as testing */
|
|
||||||
st = IMG_STATE_TESTING;
|
|
||||||
wolfBoot_set_partition_state(PART_BOOT, st);
|
|
||||||
wb_flash_erase(&swap, 0, WOLFBOOT_SECTOR_SIZE);
|
|
||||||
/* encryption key was not erased, will be erased by success */
|
/* encryption key was not erased, will be erased by success */
|
||||||
#ifdef EXT_FLASH
|
#ifdef EXT_FLASH
|
||||||
ext_flash_lock();
|
ext_flash_lock();
|
||||||
|
@ -695,11 +797,13 @@ int wolfBoot_unlock_disk(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void RAMFUNCTION wolfBoot_start(void)
|
void RAMFUNCTION wolfBoot_start(void)
|
||||||
{
|
{
|
||||||
int bootRet;
|
int bootRet;
|
||||||
int updateRet;
|
int updateRet;
|
||||||
|
#ifndef DISABLE_BACKUP
|
||||||
|
int resumedFinalErase;
|
||||||
|
#endif
|
||||||
uint8_t bootState;
|
uint8_t bootState;
|
||||||
uint8_t updateState;
|
uint8_t updateState;
|
||||||
struct wolfBoot_image boot;
|
struct wolfBoot_image boot;
|
||||||
|
@ -715,22 +819,26 @@ void RAMFUNCTION wolfBoot_start(void)
|
||||||
bootRet = wolfBoot_get_partition_state(PART_BOOT, &bootState);
|
bootRet = wolfBoot_get_partition_state(PART_BOOT, &bootState);
|
||||||
updateRet = wolfBoot_get_partition_state(PART_UPDATE, &updateState);
|
updateRet = wolfBoot_get_partition_state(PART_UPDATE, &updateState);
|
||||||
|
|
||||||
|
#ifndef DISABLE_BACKUP
|
||||||
|
/* resume the final erase in case the power failed before it finished */
|
||||||
|
resumedFinalErase = wolfBoot_swap_and_final_erase(1);
|
||||||
|
|
||||||
|
if (resumedFinalErase != 0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
/* Check if the BOOT partition is still in TESTING,
|
/* Check if the BOOT partition is still in TESTING,
|
||||||
* to trigger fallback.
|
* to trigger fallback.
|
||||||
*/
|
*/
|
||||||
if (bootRet == 0 && bootState == IMG_STATE_TESTING) {
|
if ((bootRet == 0) && (bootState == IMG_STATE_TESTING)) {
|
||||||
/* wolfBoot_update_trigger now erases all the sector flags, only trigger
|
|
||||||
* if we're not already updating */
|
|
||||||
if (updateRet || updateState != IMG_STATE_UPDATING) {
|
|
||||||
wolfBoot_update_trigger();
|
|
||||||
}
|
|
||||||
wolfBoot_update(1);
|
wolfBoot_update(1);
|
||||||
/* Check for new updates in the UPDATE partition or if we were
|
/* Check for new updates in the UPDATE partition or if we were
|
||||||
* interrupted during the flags setting */
|
* interrupted during the flags setting */
|
||||||
} else if (updateRet == 0 && (updateState == IMG_STATE_UPDATING || updateState == IMG_STATE_FINAL_FLAGS)) {
|
}
|
||||||
|
else if ((updateRet == 0) && (updateState == IMG_STATE_UPDATING)) {
|
||||||
/* Check for new updates in the UPDATE partition */
|
/* Check for new updates in the UPDATE partition */
|
||||||
wolfBoot_update(0);
|
wolfBoot_update(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if ((wolfBoot_open_image(&boot, PART_BOOT) < 0)
|
if ((wolfBoot_open_image(&boot, PART_BOOT) < 0)
|
||||||
|| (wolfBoot_verify_integrity(&boot) < 0)
|
|| (wolfBoot_verify_integrity(&boot) < 0)
|
||||||
|| (wolfBoot_verify_authenticity(&boot) < 0)
|
|| (wolfBoot_verify_authenticity(&boot) < 0)
|
||||||
|
|
|
@ -52,6 +52,11 @@ int do_cmd(const char *cmd)
|
||||||
if (strcmp(cmd, "powerfail") == 0) {
|
if (strcmp(cmd, "powerfail") == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/* forces a bad write of the boot partition to trigger and test the
|
||||||
|
* emergency fallback feature */
|
||||||
|
if (strcmp(cmd, "emergency") == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (strcmp(cmd, "get_version") == 0) {
|
if (strcmp(cmd, "get_version") == 0) {
|
||||||
printf("%d\n", wolfBoot_current_firmware_version());
|
printf("%d\n", wolfBoot_current_firmware_version());
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
V=`./wolfboot.elf update_trigger get_version 2>/dev/null`
|
||||||
|
if [ "x$V" != "x1" ]; then
|
||||||
|
echo "Failed first boot with update_trigger"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
V=`./wolfboot.elf success get_version emergency 2>/dev/null`
|
||||||
|
if [ "x$V" != "x1" ]; then
|
||||||
|
echo "Failed fallback (V: $V)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo Test successful.
|
||||||
|
exit 0
|
|
@ -47,5 +47,27 @@ if [ "x$V" != "x1" ]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# make sure it can double revert
|
||||||
|
./wolfboot.elf powerfail 0 get_version 2>/dev/null
|
||||||
|
./wolfboot.elf powerfail 15000 get_version 2>/dev/null
|
||||||
|
./wolfboot.elf powerfail 18000 get_version 2>/dev/null
|
||||||
|
./wolfboot.elf powerfail 1a000 get_version 2>/dev/null
|
||||||
|
# fail on the last sector to stop the encrypt key save and state update
|
||||||
|
./wolfboot.elf powerfail 3e000 get_version 2>/dev/null
|
||||||
|
# may not trigger on non NVM_FLASH_WRITEONCE
|
||||||
|
V=`./wolfboot.elf powerfail 3f000 get_version` 2>/dev/null
|
||||||
|
if [ "x$V" != "x2" ]; then
|
||||||
|
V=`./wolfboot.elf get_version 2>/dev/null`
|
||||||
|
# if we failed on the final boot state write we need to double fallback
|
||||||
|
if [ "x$V" == "x1" ]; then
|
||||||
|
V=`./wolfboot.elf get_version 2>/dev/null`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "x$V" != "x2" ]; then
|
||||||
|
echo "Failed update (V: $V)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo Test successful.
|
echo Test successful.
|
||||||
exit 0
|
exit 0
|
||||||
|
|
|
@ -977,29 +977,29 @@ test-all: clean
|
||||||
|
|
||||||
|
|
||||||
test-size-all:
|
test-size-all:
|
||||||
make test-size SIGN=NONE LIMIT=4776
|
make test-size SIGN=NONE LIMIT=4913
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ED25519 LIMIT=11424
|
make test-size SIGN=ED25519 LIMIT=11529
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC256 LIMIT=17824
|
make test-size SIGN=ECC256 LIMIT=17857
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13588
|
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13593
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA2048 LIMIT=11104
|
make test-size SIGN=RSA2048 LIMIT=11217
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11804
|
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11797
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA4096 LIMIT=11884
|
make test-size SIGN=RSA4096 LIMIT=11497
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=11980
|
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12093
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC384 LIMIT=17388
|
make test-size SIGN=ECC384 LIMIT=17309
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15024
|
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15013
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=ED448 LIMIT=13536
|
make test-size SIGN=ED448 LIMIT=13645
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA3072 LIMIT=11240
|
make test-size SIGN=RSA3072 LIMIT=11353
|
||||||
make keysclean
|
make keysclean
|
||||||
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11792
|
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11905
|
||||||
make keysclean
|
make keysclean
|
||||||
|
|
Loading…
Reference in New Issue