mirror of https://github.com/wolfSSL/wolfBoot.git
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 calledpull/379/head
parent
2298da23b5
commit
6c2a37bdea
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue