Fixed delta updates from external devices (+ test)

pull/150/head
Daniele Lacamera 2021-10-06 15:20:39 +02:00
parent aaf780fae9
commit f26dd61e23
6 changed files with 59 additions and 35 deletions

View File

@ -67,7 +67,7 @@ int wb_diff_init(WB_DIFF_CTX *ctx, uint8_t *src_a, uint32_t len_a, uint8_t *src_
int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len);
int wb_patch_init(WB_PATCH_CTX *bm, uint8_t *src, uint32_t ssz, uint8_t *patch, uint32_t psz);
int wb_patch(WB_PATCH_CTX *ctx, uint8_t *dst, uint32_t len);
int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t *img_offset, uint16_t *img_size);
int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset, uint16_t **img_size);
#endif

View File

@ -467,7 +467,7 @@ static inline uint16_t im2ns(uint16_t val)
}
#ifdef DELTA_UPDATES
int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t *img_offset, uint16_t *img_size)
int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset, uint16_t **img_size)
{
uint32_t *version_field = NULL;
uint32_t *magic = NULL;
@ -500,17 +500,17 @@ int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t *img_offset, uin
return -1;
if (inverse) {
if (wolfBoot_find_header((uint8_t *)(image + IMAGE_HEADER_OFFSET),
HDR_IMG_DELTA_INVERSE, (void *)img_offset) != sizeof(uint32_t)) {
HDR_IMG_DELTA_INVERSE, (uint8_t **) img_offset) != sizeof(uint32_t)) {
return -1;
}
if (wolfBoot_find_header((uint8_t *)(image + IMAGE_HEADER_OFFSET),
HDR_IMG_DELTA_INVERSE_SIZE, (void *)img_size) != sizeof(uint16_t)) {
HDR_IMG_DELTA_INVERSE_SIZE, (uint8_t **) img_size) != sizeof(uint16_t)) {
return -1;
}
} else {
*img_offset = 0x0000000;
if (wolfBoot_find_header((uint8_t *)(image + IMAGE_HEADER_OFFSET),
HDR_IMG_DELTA_SIZE, (void *)img_size) != sizeof(uint16_t)) {
HDR_IMG_DELTA_SIZE, (uint8_t **)img_size) != sizeof(uint16_t)) {
return -1;
}
}

View File

@ -60,7 +60,7 @@ static int uart_rx_timeout(uint8_t *c)
volatile int count = 0;
while(++count < (WAIT_CYCLES * READ_TIMEOUT)) {
if (uart_rx(c) == 1) /* Success */
return 0;
return 0;
}
*c = 0x00;
return -1;
@ -155,7 +155,7 @@ void ext_flash_unlock(void)
{
wait_ack();
}
void uart_send_current_version(void)
{
uint32_t version = wolfBoot_current_firmware_version();

View File

@ -154,7 +154,7 @@ static int RAMFUNCTION wolfBoot_copy_sector(struct wolfBoot_image *src, struct w
#ifdef DELTA_UPDATES
#ifndef DELTA_BLOCK_SIZE
# define DELTA_BLOCK_SIZE 1024
# define DELTA_BLOCK_SIZE 1024
#endif
static int wolfBoot_delta_update(struct wolfBoot_image *boot,
@ -167,8 +167,8 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
uint8_t delta_blk[DELTA_BLOCK_SIZE];
uint32_t offset = 0;
uint16_t ptr_len;
uint32_t img_offset;
uint16_t img_size;
uint32_t *img_offset;
uint16_t *img_size;
uint32_t total_size;
WB_PATCH_CTX ctx;
@ -177,9 +177,6 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
if ((update->fw_size + IMAGE_HEADER_SIZE) > total_size)
total_size = update->fw_size + IMAGE_HEADER_SIZE;
if (total_size <= IMAGE_HEADER_SIZE)
return -1;
hal_flash_unlock();
#ifdef EXT_FLASH
ext_flash_unlock();
@ -198,16 +195,16 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
delta_base_v = wolfBoot_get_diffbase_version(PART_UPDATE);
if ((cur_v == upd_v) && (delta_base_v < cur_v)) {
ret = wb_patch_init(&ctx, boot->hdr, boot->fw_size + IMAGE_HEADER_SIZE,
update->hdr + img_offset, img_size);
update->hdr + *img_offset, *img_size);
} else {
ret = -1;
}
} else {
ret = wb_patch_init(&ctx, boot->hdr, boot->fw_size + IMAGE_HEADER_SIZE,
update->hdr + IMAGE_HEADER_SIZE, img_size);
update->hdr + IMAGE_HEADER_SIZE, *img_size);
}
if (ret < 0)
return ret;
goto out;
while((sector * WOLFBOOT_SECTOR_SIZE) < (int)total_size) {
if ((wolfBoot_get_update_sector_flag(sector, &flag) != 0) || (flag == SECT_FLAG_NEW)) {
@ -245,13 +242,14 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
if (((sector + 1) * WOLFBOOT_SECTOR_SIZE) < WOLFBOOT_PARTITION_SIZE)
wolfBoot_set_update_sector_flag(sector, flag);
}
#if 0
if (sector == 0) {
/* New total image size after first sector is patched */
volatile uint32_t update_size;
hal_flash_lock();
update_size =
wolfBoot_image_size((uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS)
+ IMAGE_HEADER_SIZE;
hal_flash_unlock();
if (update_size > total_size)
total_size = update_size;
if (total_size <= IMAGE_HEADER_SIZE) {
@ -264,19 +262,21 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
}
}
#endif
sector++;
}
ret = 0;
while((sector * WOLFBOOT_SECTOR_SIZE) < WOLFBOOT_PARTITION_SIZE) {
hal_flash_erase(WOLFBOOT_PARTITION_BOOT_ADDRESS +
hal_flash_erase(WOLFBOOT_PARTITION_BOOT_ADDRESS +
sector * WOLFBOOT_SECTOR_SIZE, WOLFBOOT_SECTOR_SIZE);
sector++;
}
//wb_flash_erase(swap, 0, WOLFBOOT_SECTOR_SIZE);
st = IMG_STATE_TESTING;
wolfBoot_set_partition_state(PART_BOOT, st);
/* On success, reset all flags on update partition */
wb_flash_erase(update, WOLFBOOT_PARTITION_SIZE - WOLFBOOT_SECTOR_SIZE,
WOLFBOOT_SECTOR_SIZE);
out:
wb_flash_erase(swap, 0, WOLFBOOT_SECTOR_SIZE);
#ifdef EXT_FLASH
ext_flash_lock();
#endif
@ -324,11 +324,6 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
update_type = wolfBoot_get_image_type(PART_UPDATE);
#ifdef DELTA_UPDATES
if ((update_type & 0x00F0) == HDR_IMG_TYPE_DIFF) {
return wolfBoot_delta_update(&boot, &update, &swap, fallback_allowed);
}
#endif
/* Check the first sector to detect interrupted update */
if ((wolfBoot_get_update_sector_flag(0, &flag) < 0) || (flag == SECT_FLAG_NEW))
@ -346,11 +341,19 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
#endif
}
#ifdef DELTA_UPDATES
if ((update_type & 0x00F0) == HDR_IMG_TYPE_DIFF) {
return wolfBoot_delta_update(&boot, &update, &swap, fallback_allowed);
}
#endif
hal_flash_unlock();
#ifdef EXT_FLASH
ext_flash_unlock();
#endif
/* Read encryption key/IV before starting the update */
#ifdef EXT_ENCRYPTED
wolfBoot_get_encrypt_key(key, nonce);

View File

@ -1,7 +1,6 @@
test-delta-update:SIGN_ARGS?=--ecc256
test-delta-update:SIGN_DELTA_ARGS?=--ecc256 --encrypt /tmp/enc_key.der
test-delta-update:USBTTY?=/dev/ttyACM0
test-delta-update:TIMEOUT?=60
test-delta-update:EXPVER=tools/test-expect-version/test-expect-version /dev/ttyACM0
test-delta-update-ext:SIGN_ARGS?=--ecc256
@ -26,23 +25,18 @@ test-delta-update: factory.bin test-app/image.bin tools/uart-flash-server/ufserv
@st-flash write test-app/image_v7_signed_diff.bin 0x0802C000
@sleep 2
@st-flash reset
@sleep 20
@echo Expecting version '7'
@(test `$(EXPVER)` -eq 7)
@sleep 2
@st-flash reset
@echo Expecting version '7'
@(test `$(EXPVER)` -eq 7)
@sleep 2
@st-flash reset
@echo Expecting version '1'
@(test `$(EXPVER)` -eq 1)
@st-flash reset
@st-flash erase || st-flash erase
@st-flash write factory.bin 0x08000000
@echo Expecting version '1'
@(test `$(EXPVER)` -eq 1)
@sleep 1
@st-flash reset
@st-flash write test-app/image_v2_signed_diff.bin 0x0802C000
@st-flash reset
@echo Expecting version '2'
@ -69,13 +63,30 @@ test-delta-update-ext: factory.bin test-app/image.bin tools/uart-flash-server/uf
@sync
@echo Waiting $(TIMEOUT) seconds...
@sleep $(TIMEOUT)
@st-flash reset
@sleep 3
@killall ufserver
@st-flash reset
@sleep 3
@st-flash read boot_full.bin 0x0800C000 0x8000
@SIZE=`wc -c test-app/image_v7_signed.bin | cut -d" " -f 1`; \
dd if=boot_full.bin of=boot.bin bs=1 count=$$SIZE
@diff boot.bin test-app/image_v7_signed.bin || (echo "TEST FAILED" && exit 1)
@rm boot.bin boot_full.bin
@echo "TEST SUCCESSFUL"
@sleep 1
@echo
@echo
@st-flash reset
@(tools/uart-flash-server/ufserver test-app/image_v7_signed_diff.bin $(USBTTY))&
@echo TEST INVERSE
@sleep $(TIMEOUT)
@st-flash reset
@killall ufserver
@st-flash reset
@st-flash read boot_full.bin 0x0800C000 0x8000
@SIZE=`wc -c test-app/image_v1_signed.bin | cut -d" " -f 1`; \
dd if=boot_full.bin of=boot.bin bs=1 count=$$SIZE
@diff boot.bin test-app/image_v1_signed.bin || (echo "TEST INVERSE FAILED" && exit 1)
@rm boot.bin boot_full.bin
@echo "TEST SUCCESSFUL"

View File

@ -55,6 +55,10 @@
#define SWAP_SIZE 0x1000
#define UART_BITRATE 115200
/* Change the following to 1 to debug flash access */
#define LOG_FLASH_ADDRESS 0
const char msgSha[] = "Verifying SHA digest...";
const char msgReadUpdate[] = "Fetching update blocks ";
const char msgReadSwap[] = "Reading SWAP blocks ";
@ -280,7 +284,9 @@ static void uart_flash_erase(uint8_t *base, int ud)
} else {
printmsg(msgEraseSwap);
}
#if LOG_FLASH_ADDRESS
printf("Erase @%x\n", address);
#endif
for (i = 0; i < len; i++) {
base[address + i] = 0xFF;
}
@ -307,7 +313,9 @@ static void uart_flash_read(uint8_t *base, int ud)
} else {
printmsg(msgReadSwap);
}
#if LOG_FLASH_ADDRESS
printf("Read @%x\n", address);
#endif
if (address + len > (FIRMWARE_PARTITION_SIZE + SWAP_SIZE))
return;
for (i = 0; i < len; i++) {
@ -330,7 +338,9 @@ static void uart_flash_write(uint8_t *base, int ud)
} else {
printmsg(msgWriteSwap);
}
#if LOG_FLASH_ADDRESS
printf("Write @%x\n", address);
#endif
if (address + len > (FIRMWARE_PARTITION_SIZE + SWAP_SIZE))
return;
for (i = 0; i < len; i++) {
@ -373,7 +383,7 @@ static void serve_update(uint8_t *base, const char *uart_dev)
}
v = buf[4] + (buf[3] << 8) + (buf[2] << 16) + (buf[1] << 24);
printf("Bootloader version from test app: %u\n", v);
printf("Boot partition version from test app: %u\n", v);
continue;
}
if (buf[0] == CMD_HDR_VER) {