remove complicated key saving process and instead

leave the encryption key for wolfBoot_success to erase.
FINAL_SWAP was also stopping the case where the partition was put into testing before the update sector status flags could be erased. now, don't erase the update sector flags. instead put the update partition in IMG_STATE_FINAL_FLAGS state before putting the boot partition in IMG_STATE_TESTING. Then only erase the update sector flags on wolfBoot_update_trigger. under this scheme, the sector flags are intact if the power failed before we could set IMG_STATE_TESTING but are wiped if we do need to swap over after after wolfBoot_success fails to be called
pull/379/head
John Bland 2023-10-08 18:57:30 -04:00 committed by Daniele Lacamera
parent 2298da23b5
commit 6c2a37bdea
7 changed files with 87 additions and 315 deletions

View File

@ -64,8 +64,6 @@ void aes_set_iv(uint8_t *nonce, uint32_t address);
#endif /* ENCRYPT_WITH_CHACHA */
/* Internal read/write functions (not exported in the libwolfboot API) */
int ext_flash_encrypt_write_ex(uintptr_t address,
const uint8_t *data, int len, int forcedEnc);
int ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len);
int ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len);

View File

@ -616,18 +616,10 @@ static inline int wb_flash_erase(struct wolfBoot_image *img, uint32_t off,
}
static inline int wb_flash_write(struct wolfBoot_image *img, uint32_t off,
const void *data, uint32_t size, int forcedEncrypt)
const void *data, uint32_t size)
{
if (PART_IS_EXT(img)) {
#if defined(EXT_ENCRYPTED) && (defined(__WOLFBOOT) || defined(UNIT_TEST))
if (forcedEncrypt == 1)
return ext_flash_encrypt_write_ex((uintptr_t)(img->hdr) + off, data,
size, forcedEncrypt);
else
#endif
return ext_flash_check_write((uintptr_t)(img->hdr) + off, data,
size);
}
if (PART_IS_EXT(img))
return ext_flash_check_write((uintptr_t)(img->hdr) + off, data, size);
else
return hal_flash_write((uintptr_t)(img->hdr) + off, data, size);
}
@ -665,7 +657,7 @@ static inline int wb_flash_write_verify_word(struct wolfBoot_image *img,
# define PARTN_IS_EXT(x) (0)
# define wb_flash_erase(im, of, siz) \
hal_flash_erase(((uintptr_t)(((im)->hdr)) + of), siz)
# define wb_flash_write(im, of, dat, siz, I) \
# define wb_flash_write(im, of, dat, siz) \
hal_flash_write(((uintptr_t)((im)->hdr)) + of, dat, siz)
#endif /* EXT_FLASH */

View File

@ -244,7 +244,7 @@ extern "C" {
#ifndef WOLFBOOT_FLAGS_INVERT
#define IMG_STATE_NEW 0xFF
#define IMG_STATE_UPDATING 0x70
#define IMG_STATE_FINAL_SWAP 0x30
#define IMG_STATE_FINAL_FLAGS 0x30
#define IMG_STATE_TESTING 0x10
#define IMG_STATE_SUCCESS 0x00
#define FLASH_BYTE_ERASED 0xFF
@ -252,7 +252,7 @@ extern "C" {
#else
#define IMG_STATE_NEW 0x00
#define IMG_STATE_UPDATING 0x8F
#define IMG_STATE_FINAL_SWAP 0xBF
#define IMG_STATE_FINAL_FLAGS 0xBF
#define IMG_STATE_TESTING 0xEF
#define IMG_STATE_SUCCESS 0xFF
#define FLASH_BYTE_ERASED 0x00
@ -316,15 +316,9 @@ int wolfBoot_get_diffbase_hdr(uint8_t part, uint8_t **ptr);
#endif
int wolfBoot_set_encrypt_key(const uint8_t *key, const uint8_t *nonce);
int wolfBoot_backup_encrypt_key(const uint8_t* key, const uint8_t* nonce);
int wolfBoot_get_encrypt_key(uint8_t *key, uint8_t *nonce);
int wolfBoot_erase_encrypt_key(void);
#ifdef FLAGS_HOME
int wolfBoot_flags_home_set_final_swap();
int wolfBoot_flags_home_get_final_swap();
#endif
#ifdef __cplusplus
}
#endif

@ -1 +1 @@
Subproject commit 5497830567222e9a278e5a69aaeef32d5f3fc890
Subproject commit cc88dcd4abb191fdccf29950b9f11e65b1bf757e

@ -1 +1 @@
Subproject commit cd02d5140fccd2478dcd4845d1b7cef6be881dde
Subproject commit 05b692d01cb2fa172d8a86e04a1dbbdb5eb88703

View File

@ -741,20 +741,16 @@ void RAMFUNCTION wolfBoot_erase_partition(uint8_t part)
void RAMFUNCTION wolfBoot_update_trigger(void)
{
uint8_t st = IMG_STATE_UPDATING;
#if defined(NVM_FLASH_WRITEONCE) || defined(WOLFBOOT_FLAGS_INVERT)
uintptr_t lastSector = PART_UPDATE_ENDFLAGS -
(PART_UPDATE_ENDFLAGS % WOLFBOOT_SECTOR_SIZE);
#ifdef NVM_FLASH_WRITEONCE
uint8_t selSec = 0;
#endif
#ifndef FLAGS_HOME
/* if PART_UPDATE_ENDFLAGS stradles a sector, (all non FLAGS_HOME builds)
* align it to the correct sector */
if (PART_UPDATE_ENDFLAGS % WOLFBOOT_SECTOR_SIZE == 0)
lastSector -= WOLFBOOT_SECTOR_SIZE;
#endif
#endif
#ifdef NVM_FLASH_WRITEONCE
uint8_t selSec = 0;
#endif
/* erase the sector flags */
if (FLAGS_UPDATE_EXT()) {
@ -767,11 +763,12 @@ void RAMFUNCTION wolfBoot_update_trigger(void)
* partition based on how many flags are non-erased
* FLAGS_INVERT needs erased flags because the bin-assemble's fill byte may
* not match what's in wolfBoot */
#if defined(NVM_FLASH_WRITEONCE) || defined(WOLFBOOT_FLAGS_INVERT)
if (FLAGS_UPDATE_EXT()) {
ext_flash_erase(lastSector, SECTOR_FLAGS_SIZE);
} else {
#ifdef NVM_FLASH_WRITEONCE
#ifndef NVM_FLASH_WRITEONCE
hal_flash_erase(lastSector, SECTOR_FLAGS_SIZE);
#else
selSec = nvm_select_fresh_sector(PART_UPDATE);
XMEMCPY(NVM_CACHE,
(uint8_t*)(lastSector - WOLFBOOT_SECTOR_SIZE * selSec),
@ -783,11 +780,8 @@ void RAMFUNCTION wolfBoot_update_trigger(void)
/* erase the previously selected sector */
hal_flash_erase(lastSector - WOLFBOOT_SECTOR_SIZE * selSec,
WOLFBOOT_SECTOR_SIZE);
#elif defined(WOLFBOOT_FLAGS_INVERT)
hal_flash_erase(lastSector, SECTOR_FLAGS_SIZE);
#endif
}
#endif
wolfBoot_set_partition_state(PART_UPDATE, st);
@ -812,10 +806,16 @@ void RAMFUNCTION wolfBoot_success(void)
if (FLAGS_BOOT_EXT()) {
ext_flash_unlock();
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();
} else {
hal_flash_unlock();
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();
}
#ifdef EXT_ENCRYPTED
@ -1431,23 +1431,6 @@ int RAMFUNCTION wolfBoot_set_encrypt_key(const uint8_t *key,
return 0;
}
int RAMFUNCTION wolfBoot_backup_encrypt_key(const uint8_t* key,
const uint8_t* nonce)
{
#ifndef MMU
uint32_t magic[2] = {WOLFBOOT_MAGIC, WOLFBOOT_MAGIC_TRAIL};
hal_flash_write(WOLFBOOT_PARTITION_BOOT_ADDRESS, key,
ENCRYPT_KEY_SIZE);
hal_flash_write(WOLFBOOT_PARTITION_BOOT_ADDRESS +
ENCRYPT_KEY_SIZE, nonce, ENCRYPT_NONCE_SIZE);
/* write magic so we know we finished in case of a powerfail */
hal_flash_write(WOLFBOOT_PARTITION_BOOT_ADDRESS +
ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE, (uint8_t*)magic, sizeof(magic));
#endif
return 0;
}
#ifndef UNIT_TEST
/**
* @brief Get the encryption key.
@ -1463,39 +1446,21 @@ int RAMFUNCTION wolfBoot_backup_encrypt_key(const uint8_t* key,
*/
int RAMFUNCTION wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce)
{
int ret = 0;
#if defined(MMU)
XMEMCPY(k, ENCRYPT_KEY, ENCRYPT_KEY_SIZE);
XMEMCPY(nonce, ENCRYPT_KEY + ENCRYPT_KEY_SIZE, ENCRYPT_NONCE_SIZE);
#else
uint8_t* mem;
uint32_t magic[2];
/* see if we've backed up the key, this will only matter for final swap */
XMEMCPY(magic, (uint8_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS +
ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE, sizeof(magic));
if (magic[0] == WOLFBOOT_MAGIC && magic[1] == WOLFBOOT_MAGIC_TRAIL) {
mem = (uint8_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS;
/* not a failure but finalize needs to know that it's safe to erase and
* write the key to the normal spot */
ret = 1;
}
else {
mem = (uint8_t *)(ENCRYPT_TMP_SECRET_OFFSET +
WOLFBOOT_PARTITION_BOOT_ADDRESS);
#ifdef NVM_FLASH_WRITEONCE
int sel_sec = 0;
sel_sec = nvm_select_fresh_sector(PART_BOOT);
mem -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
#endif
}
uint8_t *mem = (uint8_t *)(ENCRYPT_TMP_SECRET_OFFSET +
WOLFBOOT_PARTITION_BOOT_ADDRESS);
int sel_sec = 0;
#ifdef NVM_FLASH_WRITEONCE
sel_sec = nvm_select_fresh_sector(PART_BOOT);
mem -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
#endif
XMEMCPY(k, mem, ENCRYPT_KEY_SIZE);
XMEMCPY(nonce, mem + ENCRYPT_KEY_SIZE, ENCRYPT_NONCE_SIZE);
#endif
return ret;
return 0;
}
#endif
/**
@ -1539,12 +1504,16 @@ int RAMFUNCTION chacha_init(void)
#if defined(MMU) || defined(UNIT_TEST)
uint8_t *key = ENCRYPT_KEY;
#else
uint8_t key[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE];
wolfBoot_get_encrypt_key(key, key + ENCRYPT_KEY_SIZE);
uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS +
ENCRYPT_TMP_SECRET_OFFSET);
#endif
uint8_t ff[ENCRYPT_KEY_SIZE];
uint8_t* stored_nonce;
#ifdef NVM_FLASH_WRITEONCE
key -= WOLFBOOT_SECTOR_SIZE * nvm_select_fresh_sector(PART_BOOT);
#endif
stored_nonce = key + ENCRYPT_KEY_SIZE;
XMEMSET(&chacha, 0, sizeof(chacha));
@ -1581,13 +1550,17 @@ int aes_init(void)
#if defined(MMU) || defined(UNIT_TEST)
uint8_t *key = ENCRYPT_KEY;
#else
uint8_t key[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE];
wolfBoot_get_encrypt_key(key, key + ENCRYPT_KEY_SIZE);
uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS +
ENCRYPT_TMP_SECRET_OFFSET);
#endif
uint8_t ff[ENCRYPT_KEY_SIZE];
uint8_t iv_buf[ENCRYPT_NONCE_SIZE];
uint8_t* stored_nonce;
#ifdef NVM_FLASH_WRITEONCE
key -= WOLFBOOT_SECTOR_SIZE * nvm_select_fresh_sector(PART_BOOT);
#endif
stored_nonce = key + ENCRYPT_KEY_SIZE;
XMEMSET(&aes_enc, 0, sizeof(aes_enc));
@ -1703,8 +1676,8 @@ static uint8_t RAMFUNCTION part_address(uintptr_t a)
*
* @return int 0 if successful, -1 on failure.
*/
int RAMFUNCTION ext_flash_encrypt_write_ex(uintptr_t address,
const uint8_t *data, int len, int forcedEnc)
int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data,
int len)
{
uint8_t block[ENCRYPT_BLOCK_SIZE];
uint8_t enc_block[ENCRYPT_BLOCK_SIZE];
@ -1739,9 +1712,7 @@ int RAMFUNCTION ext_flash_encrypt_write_ex(uintptr_t address,
break;
case PART_SWAP:
/* data is coming from update and is already encrypted */
if (forcedEnc == 0)
return ext_flash_write(address, data, len);
break;
return ext_flash_write(address, data, len);
default:
return -1;
}
@ -1772,22 +1743,6 @@ int RAMFUNCTION ext_flash_encrypt_write_ex(uintptr_t address,
return ext_flash_write(address, ENCRYPT_CACHE, step);
}
/**
* @brief Write encrypted data to an external flash.
*
* This function calls ext_flash_encrypt_write_ex with forced encryption off
*
* @param address The address in the external flash to write the data to.
* @param data Pointer to the data buffer to be written.
* @param len The length of the data to be written.
*
* @return int 0 if successful, -1 on failure.
*/
int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
{
return ext_flash_encrypt_write_ex(address, data, len, 0);
}
/**
* @brief Read and decrypt data from an external flash.
*
@ -1934,39 +1889,3 @@ int wolfBoot_ram_decrypt(uint8_t *src, uint8_t *dst)
}
#endif /* MMU */
#endif /* EXT_ENCRYPTED */
#ifdef FLAGS_HOME
/* we need to write a marker to update since the boot and update flags are all
* in the same sector so write magic to the first sector of boot */
int wolfBoot_flags_home_set_final_swap()
{
/* EXT_ENCRYPTED uses the first sector to store the key and magic, don't
* overwrite it */
#ifndef EXT_ENCRYPTED
uint32_t magic[2] = {WOLFBOOT_MAGIC, WOLFBOOT_MAGIC_TRAIL};
uintptr_t addr = (uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
hal_flash_write(addr, (uint8_t*)magic, sizeof(magic));
#endif /* !EXT_ENCRYPTED */
return 0;
}
int wolfBoot_flags_home_get_final_swap()
{
uint32_t magic[2];
uintptr_t addr = (uintptr_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
/* if encryption is on magic will be after the key and nonce */
#ifdef EXT_ENCRYPTED
addr += ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE;
#endif
XMEMCPY((uint8_t*)magic, (uint8_t*)addr, sizeof(magic));
if (magic[0] == WOLFBOOT_MAGIC && magic[1] == WOLFBOOT_MAGIC_TRAIL)
return 1;
return 0;
}
#endif /* FLAGS_HOME */

View File

@ -124,7 +124,7 @@ void wolfBoot_check_self_update(void)
#endif /* RAM_CODE for self_update */
static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src,
struct wolfBoot_image *dst, uint32_t sector, int forcedEncrypt)
struct wolfBoot_image *dst, uint32_t sector)
{
uint32_t pos = 0;
uint32_t src_sector_offset = (sector * WOLFBOOT_SECTOR_SIZE);
@ -175,7 +175,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src,
}
wb_flash_write(dst, dst_sector_offset + pos, buffer,
FLASHBUFFER_SIZE, forcedEncrypt);
FLASHBUFFER_SIZE);
}
pos += FLASHBUFFER_SIZE;
}
@ -187,105 +187,13 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src,
if (src_sector_offset + pos < (src->fw_size + IMAGE_HEADER_SIZE +
FLASHBUFFER_SIZE)) {
uint8_t *orig = (uint8_t*)(src->hdr + src_sector_offset + pos);
wb_flash_write(dst, dst_sector_offset + pos, orig, FLASHBUFFER_SIZE,
forcedEncrypt);
wb_flash_write(dst, dst_sector_offset + pos, orig, FLASHBUFFER_SIZE);
}
pos += FLASHBUFFER_SIZE;
}
return pos;
}
static int wolfBoot_finalize(struct wolfBoot_image *boot,
struct wolfBoot_image *update, struct wolfBoot_image *swap)
{
uint8_t st;
uint32_t sector = (WOLFBOOT_PARTITION_SIZE / WOLFBOOT_SECTOR_SIZE) - 1;
#ifdef FLAGS_HOME
/* set the UPDATE state as FINAL_SWAP in case it was erased in a later
* step last boot */
st = IMG_STATE_FINAL_SWAP;
wolfBoot_set_partition_state(PART_UPDATE, st);
#endif
#ifdef EXT_ENCRYPTED
int ret = 0;
uint8_t key[ENCRYPT_KEY_SIZE];
uint8_t nonce[ENCRYPT_NONCE_SIZE];
/* get the encryption key, this will check the backup */
ret = wolfBoot_get_encrypt_key(key, nonce);
/* key came from the backup, this means it's safe and neccassary to erase
* and re-write the key to the normal spot */
if (ret == 1) {
hal_flash_lock();
wolfBoot_set_encrypt_key(key, nonce);
hal_flash_unlock();
}
/* erase the first sector of boot */
wb_flash_erase(boot, 0, WOLFBOOT_SECTOR_SIZE);
/* backup the key */
wolfBoot_backup_encrypt_key(key, nonce);
#elif defined(FLAGS_HOME)
/* erase the first sector of boot */
wb_flash_erase(boot, 0, WOLFBOOT_SECTOR_SIZE);
/* write magic to sector 0 so we know it's final swap */
wolfBoot_flags_home_set_final_swap();
#endif
#ifdef NVM_FLASH_WRITEONCE
/* erase the alternate sector */
wb_flash_erase(boot, (sector - 1) * WOLFBOOT_SECTOR_SIZE,
WOLFBOOT_SECTOR_SIZE);
#endif
/* erase the last sector of boot */
wb_flash_erase(boot, sector * WOLFBOOT_SECTOR_SIZE, WOLFBOOT_SECTOR_SIZE);
#ifdef EXT_ENCRYPTED
hal_flash_lock();
/* write the key back to the last sector */
wolfBoot_set_encrypt_key(key, nonce);
hal_flash_unlock();
#endif
#if defined(EXT_ENCRYPTED) || defined(FLAGS_HOME)
/* decrypt and copy the first sector back to boot */
wolfBoot_copy_sector(swap, boot, 0, 0);
#endif
/* set the boot state to testing */
st = IMG_STATE_TESTING;
wolfBoot_set_partition_state(PART_BOOT, st);
#ifdef NVM_FLASH_WRITEONCE
/* erase the alternate sector */
wb_flash_erase(update, (sector - 1) * WOLFBOOT_SECTOR_SIZE,
WOLFBOOT_SECTOR_SIZE);
#endif
/* erase the last sector of update */
wb_flash_erase(update, sector * WOLFBOOT_SECTOR_SIZE, WOLFBOOT_SECTOR_SIZE);
/* erase swap */
wb_flash_erase(swap, 0, WOLFBOOT_SECTOR_SIZE);
#ifdef EXT_FLASH
ext_flash_lock();
#endif
hal_flash_lock();
return 0;
}
#ifdef DELTA_UPDATES
#ifndef DELTA_BLOCK_SIZE
@ -370,7 +278,7 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
goto out;
}
#else
wb_flash_write(swap, len, delta_blk, ret, 0);
wb_flash_write(swap, len, delta_blk, ret);
#endif
len += ret;
} else if (ret == 0) {
@ -395,7 +303,7 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
}
}
if (flag == SECT_FLAG_SWAPPING) {
wolfBoot_copy_sector(swap, boot, sector, 0);
wolfBoot_copy_sector(swap, boot, sector);
flag = SECT_FLAG_UPDATED;
if (((sector + 1) * WOLFBOOT_SECTOR_SIZE) < WOLFBOOT_PARTITION_SIZE)
wolfBoot_set_update_sector_flag(sector, flag);
@ -433,26 +341,19 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
wb_flash_erase(boot, sector * WOLFBOOT_SECTOR_SIZE, WOLFBOOT_SECTOR_SIZE);
sector++;
}
#if defined(EXT_ENCRYPTED) || defined(FLAGS_HOME)
/* copy the first sector of boot to swap so we can use it for the final
* swap, force encryption */
wolfBoot_copy_sector(boot, swap, 0, 1);
#endif
/* set the UPDATE state as FINAL_SWAP */
st = IMG_STATE_FINAL_SWAP;
/* mark that our sector flags aren't reliable in testing mode */
st = IMG_STATE_FINAL_FLAGS;
wolfBoot_set_partition_state(PART_UPDATE, st);
#ifdef FLAGS_HOME
/* erase the first sector of boot */
wb_flash_erase(boot, 0, WOLFBOOT_SECTOR_SIZE);
/* set final swap */
wolfBoot_flags_home_set_final_swap();
#endif
/* finalize the boot sector */
wolfBoot_finalize(boot, update, swap);
/* mark boot partition as testing */
st = IMG_STATE_TESTING;
wolfBoot_set_partition_state(PART_BOOT, st);
out:
wb_flash_erase(swap, 0, WOLFBOOT_SECTOR_SIZE);
#ifdef EXT_FLASH
ext_flash_lock();
#endif
hal_flash_lock();
/* encryption key was not erased, will be erased by success */
return ret;
}
@ -493,7 +394,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
struct wolfBoot_image boot, update, swap;
uint16_t update_type;
uint32_t fw_size;
#ifdef EXT_ENCRYPTED
#if defined(DISABLE_BACKUP) && defined(EXT_ENCRYPTED)
uint8_t key[ENCRYPT_KEY_SIZE];
uint8_t nonce[ENCRYPT_NONCE_SIZE];
#endif
@ -509,26 +410,6 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
wolfBoot_open_image(&boot, PART_BOOT);
wolfBoot_open_image(&swap, PART_SWAP);
#ifndef DISABLE_BACKUP
/* if we were on the final swap just finish it */
if ((wolfBoot_get_partition_state(PART_UPDATE, &st) == 0 &&
st == IMG_STATE_FINAL_SWAP)
#ifdef FLAGS_HOME
|| wolfBoot_flags_home_get_final_swap()
#endif
) {
hal_flash_unlock();
#ifdef EXT_FLASH
ext_flash_unlock();
#endif
wolfBoot_finalize(&boot, &update, &swap);
return 0;
}
#endif
/* get total size */
total_size = wolfBoot_get_total_size(&boot, &update);
@ -605,7 +486,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
while ((sector * sector_size) < total_size) {
if ((wolfBoot_get_update_sector_flag(sector, &flag) != 0) || (flag == SECT_FLAG_NEW)) {
flag = SECT_FLAG_SWAPPING;
wolfBoot_copy_sector(&update, &swap, sector, 0);
wolfBoot_copy_sector(&update, &swap, sector);
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
wolfBoot_set_update_sector_flag(sector, flag);
}
@ -614,7 +495,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
if (size > sector_size)
size = sector_size;
flag = SECT_FLAG_BACKUP;
wolfBoot_copy_sector(&boot, &update, sector, 0);
wolfBoot_copy_sector(&boot, &update, sector);
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
wolfBoot_set_update_sector_flag(sector, flag);
}
@ -623,7 +504,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
if (size > sector_size)
size = sector_size;
flag = SECT_FLAG_UPDATED;
wolfBoot_copy_sector(&swap, &boot, sector, 0);
wolfBoot_copy_sector(&swap, &boot, sector);
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
wolfBoot_set_update_sector_flag(sector, flag);
}
@ -648,7 +529,6 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
return -1;
}
}
/* erase to the last sector, writeonce has 2 sectors */
while((sector * sector_size) < WOLFBOOT_PARTITION_SIZE -
sector_size
@ -660,26 +540,18 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
wb_flash_erase(&update, sector * sector_size, sector_size);
sector++;
}
#if defined(EXT_ENCRYPTED) || defined(FLAGS_HOME)
/* copy the first sector of boot to swap so we can use it for the final
* swap, force encryption */
wolfBoot_copy_sector(&boot, &swap, 0, 1);
#endif
/* set the UPDATE state as FINAL_SWAP */
st = IMG_STATE_FINAL_SWAP;
/* mark that our sector flags aren't reliable in testing mode */
st = IMG_STATE_FINAL_FLAGS;
wolfBoot_set_partition_state(PART_UPDATE, st);
#ifdef FLAGS_HOME
/* erase the first sector of boot */
wb_flash_erase(&boot, 0, WOLFBOOT_SECTOR_SIZE);
/* set final swap */
wolfBoot_flags_home_set_final_swap();
/* 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 */
#ifdef EXT_FLASH
ext_flash_lock();
#endif
/* finalize the boot sector */
wolfBoot_finalize(&boot, &update, &swap);
hal_flash_lock();
#else /* DISABLE_BACKUP */
#warning "Backup mechanism disabled! Update installation will not be interruptible"
/* Read encryption key/IV before starting the update */
@ -694,7 +566,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
while ((sector * sector_size) < total_size) {
if ((wolfBoot_get_update_sector_flag(sector, &flag) != 0) || (flag == SECT_FLAG_NEW)) {
flag = SECT_FLAG_SWAPPING;
wolfBoot_copy_sector(&update, &boot, sector, 0);
wolfBoot_copy_sector(&update, &boot, sector);
if (((sector + 1) * sector_size) < WOLFBOOT_PARTITION_SIZE)
wolfBoot_set_update_sector_flag(sector, flag);
}
@ -834,7 +706,10 @@ int wolfBoot_unlock_disk(void)
void RAMFUNCTION wolfBoot_start(void)
{
uint8_t st;
int bootRet;
int updateRet;
uint8_t bootState;
uint8_t updateState;
struct wolfBoot_image boot;
#if defined(ARCH_SIM) && defined(WOLFBOOT_TPM) && defined(WOLFBOOT_TPM_SEAL)
@ -845,28 +720,22 @@ void RAMFUNCTION wolfBoot_start(void)
wolfBoot_check_self_update();
#endif
bootRet = wolfBoot_get_partition_state(PART_BOOT, &bootState);
updateRet = wolfBoot_get_partition_state(PART_UPDATE, &updateState);
/* Check if the BOOT partition is still in TESTING,
* to trigger fallback.
*/
if ((wolfBoot_get_partition_state(PART_BOOT, &st) == 0) && (st == IMG_STATE_TESTING)) {
/* these flags require erasing the sector flags when
* wolfBoot_update_trigger is called and thus it shouldn't be called
* if an update is already in progress */
#if defined(NVM_FLASH_WRITEONCE) || defined(WOLFBOOT_FLAGS_INVERT)
if ((wolfBoot_get_partition_state(PART_UPDATE, &st) != 0) || (st != IMG_STATE_UPDATING && st != IMG_STATE_FINAL_SWAP))
#endif
{
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);
/* Check for new updates in the UPDATE partition or if we were
* interrupted during the final sector write */
} else if (((wolfBoot_get_partition_state(PART_UPDATE, &st) == 0) &&
(st == IMG_STATE_UPDATING || st == IMG_STATE_FINAL_SWAP))
#ifdef FLAGS_HOME
|| wolfBoot_flags_home_get_final_swap()
#endif
) {
* interrupted during the flags setting */
} else if (updateRet == 0 && (updateState == IMG_STATE_UPDATING || updateState == IMG_STATE_FINAL_FLAGS)) {
/* Check for new updates in the UPDATE partition */
wolfBoot_update(0);
}