Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve delta tests + fix delta+encrypt bug #385

Merged
merged 4 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/test-powerfail-simulator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,39 @@ jobs:
- name: Run update-revert test with power failures (AES128 NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT)
run: |
tools/scripts/sim-update-powerfail-resume.sh

# TEST with encryption (aes128) and NVM_WRITEONCE and DELTA updates
- name: make clean
run: |
make distclean
- name: Select config with encrypted updates
run: |
cp config/examples/sim-encrypt-delta-nvm-writeonce-update.config .config

- name: Build tools
run: |
make -C tools/keytools && make -C tools/bin-assemble

- name: Build wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-enc-delta-update

- name: Run sunny day update test (AES128 DELTA)
run: |
tools/scripts/sim-sunnyday-update.sh

- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-enc-delta-update

- name: Run update-revert test (AES128 DELTA)
run: |
tools/scripts/sim-update-fallback.sh

- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-enc-delta-update

- name: Run update-revert test with power failures (AES128 DELTA)
run: |
tools/scripts/sim-update-powerfail-resume.sh
23 changes: 23 additions & 0 deletions config/examples/sim-encrypt-delta-nvm-writeonce-update.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
ARCH=sim
TARGET=sim
SIGN?=ED25519
HASH?=SHA256
WOLFBOOT_SMALL_STACK=1
SPI_FLASH=0
EXT_FLASH=1
ENCRYPT=1
ENCRYPT_WITH_AES128=1
DEBUG=1
DELTA_UPDATES=1
NVM_FLASH_WRITEONCE=1

# sizes should be multiple of system page size
WOLFBOOT_PARTITION_SIZE=0x40000
WOLFBOOT_SECTOR_SIZE=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x20000
# if on external flash, it should be multiple of system page size
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x40000

# required for keytools
WOLFBOOT_FIXED_PARTITIONS=1
2 changes: 1 addition & 1 deletion include/delta.h
Original file line number Diff line number Diff line change
Expand Up @@ -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, uint32_t **img_size);

#endif

5 changes: 3 additions & 2 deletions src/delta.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len)
* base for the sectors that have already been updated.
*/

pa_start = (WOLFBOOT_SECTOR_SIZE + 1) * page_start;
pa_start = WOLFBOOT_SECTOR_SIZE * page_start;
pa = ctx->src_a + pa_start;
while (((uintptr_t)(pa - ctx->src_a) < (uintptr_t)ctx->size_a) && (p_off < len)) {
if ((uintptr_t)(ctx->size_a - (pa - ctx->src_a)) < BLOCK_HDR_SIZE)
Expand Down Expand Up @@ -273,7 +273,8 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len)
/* Don't try matching backwards if the distance between the two
* blocks is smaller than one sector.
*/
if (WOLFBOOT_SECTOR_SIZE > (pb - ctx->src_b) - (page_start * WOLFBOOT_SECTOR_SIZE))
if (WOLFBOOT_SECTOR_SIZE > (page_start * WOLFBOOT_SECTOR_SIZE)
- (pb - ctx->src_b))
break;

if ((memcmp(pb, (ctx->src_b + ctx->off_b), BLOCK_HDR_SIZE) == 0)) {
Expand Down
65 changes: 38 additions & 27 deletions src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1690,7 +1690,7 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data,
uint32_t row_address = address, row_offset;
int sz = len, i, step;
uint8_t part;
uint32_t iv_counter;
uint32_t iv_counter = 0;

row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
if (row_offset != 0) {
Expand Down Expand Up @@ -1768,7 +1768,10 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
uint8_t block[ENCRYPT_BLOCK_SIZE];
uint8_t dec_block[ENCRYPT_BLOCK_SIZE];
uint32_t row_address = address, row_offset, iv_counter = 0;
int sz = len, i, step;
int i;
int flash_read_size;
int read_remaining = len;
int unaligned_head_size, unaligned_tail_size;
uint8_t part;
uintptr_t base_address;

Expand All @@ -1778,10 +1781,6 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
if (row_offset != 0) {
row_address = address & ~(ENCRYPT_BLOCK_SIZE - 1);
sz += ENCRYPT_BLOCK_SIZE - row_offset;
}
if (sz < ENCRYPT_BLOCK_SIZE) {
sz = ENCRYPT_BLOCK_SIZE;
}
if (!encrypt_initialized) {
if (crypto_init() < 0)
Expand All @@ -1806,42 +1805,54 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
default:
return -1;
}
/* decrypt blocks */
if (sz > len) {
step = ENCRYPT_BLOCK_SIZE - row_offset;
/* Decrypt block. If the address does not align with the encryption block,
* decrypt then copy only the bytes from the requested address.
*/
if (row_offset != 0) {
unaligned_head_size = ENCRYPT_BLOCK_SIZE - row_offset;
if (ext_flash_read(row_address, block, ENCRYPT_BLOCK_SIZE)
!= ENCRYPT_BLOCK_SIZE) {
return -1;
}
crypto_decrypt(dec_block, block, ENCRYPT_BLOCK_SIZE);
XMEMCPY(data, dec_block + row_offset, step);
address += step;
data += step;
sz = len - step;
XMEMCPY(data, dec_block + row_offset, unaligned_head_size);
address += unaligned_head_size;
data += unaligned_head_size;
read_remaining -= unaligned_head_size;
iv_counter++;
}

/* decrypt remainder */
step = sz & ~(ENCRYPT_BLOCK_SIZE - 1);
if (ext_flash_read(address, data, step) != step)
/* Trim the read size to align with the Encryption Blocks. Read the
* remaining unaligned tail bytes after, since the `data` buffer won't have
* enough space to handle the extra bytes.
*/
flash_read_size = read_remaining & ~(ENCRYPT_BLOCK_SIZE - 1);
if (ext_flash_read(address, data, flash_read_size) != flash_read_size)
return -1;
for (i = 0; i < step / ENCRYPT_BLOCK_SIZE; i++) {
for (i = 0; i < flash_read_size / ENCRYPT_BLOCK_SIZE; i++)
{
XMEMCPY(block, data + (ENCRYPT_BLOCK_SIZE * i), ENCRYPT_BLOCK_SIZE);
crypto_decrypt(data + (ENCRYPT_BLOCK_SIZE * i), block,
ENCRYPT_BLOCK_SIZE);
ENCRYPT_BLOCK_SIZE);
iv_counter++;
}
sz -= step;
if (sz > 0) {
if (ext_flash_read(address + step, block, ENCRYPT_BLOCK_SIZE)
!= ENCRYPT_BLOCK_SIZE) {

address += flash_read_size;
data += flash_read_size;
read_remaining -= flash_read_size;

/* Read the unaligned tail bytes. */
unaligned_tail_size = read_remaining;
if (unaligned_tail_size > 0)
{
uint8_t dec_block[ENCRYPT_BLOCK_SIZE];
if (ext_flash_read(address, block, ENCRYPT_BLOCK_SIZE)
!= ENCRYPT_BLOCK_SIZE)
return -1;
}
crypto_decrypt(dec_block, block, ENCRYPT_BLOCK_SIZE);
XMEMCPY(data + step, dec_block, sz);
iv_counter++;
XMEMCPY(data, dec_block, unaligned_tail_size);
read_remaining -= unaligned_tail_size;
}
return len;
return (len - read_remaining);
}
#endif /* EXT_FLASH */
#endif /* __WOLFBOOT */
Expand Down
2 changes: 1 addition & 1 deletion src/update_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
uint32_t offset = 0;
uint16_t ptr_len;
uint32_t *img_offset;
uint16_t *img_size;
uint32_t *img_size;
uint32_t total_size;
WB_PATCH_CTX ctx;
#ifdef EXT_ENCRYPTED
Expand Down
10 changes: 8 additions & 2 deletions test-app/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ ARCH?=ARM
MCUXPRESSO_CMSIS?=$(MCUXPRESSO)/CMSIS
CFLAGS+=-I.
CFLAGS+=-I./wcs
DEBUG=1
DEBUG?=1
DELTA_DATA_SIZE?=2000

ifeq ($(SIGN),RSA2048)
IMAGE_HEADER_SIZE:=512
Expand Down Expand Up @@ -166,7 +167,7 @@ endif
ifeq ($(TARGET),sim)
APP_OBJS=app_$(TARGET).o ../test-app/libwolfboot.o ../hal/$(TARGET).o
# Override linker flags
LDFLAGS=
LDFLAGS=-Wl,-Map=image.map
endif

ifeq ($(EXT_FLASH),1)
Expand Down Expand Up @@ -327,6 +328,9 @@ CFLAGS+=-I../lib/wolfssl
standalone:CFLAGS+=-D"TEST_APP_STANDALONE"
standalone:LDFLAGS:=-T standalone.ld -Wl,-gc-sections -Wl,-Map=image.map

delta-extra-data:CFLAGS+=-D"TEST_DELTA_DATA=$(DELTA_DATA_SIZE)" -ffunction-sections -fdata-sections
delta-extra-data:LDFLAGS=-Wl,-Map=image.map

image.bin: image.elf
@echo "\t[BIN] $@"
$(Q)$(OBJCOPY) --gap-fill $(FILL_BYTE) -O binary $^ $@
Expand All @@ -338,6 +342,8 @@ image.elf: $(APP_OBJS) $(LSCRIPT)

standalone: image.bin

delta-extra-data: image.bin

../test-app/libwolfboot.o: ../src/libwolfboot.c FORCE
@echo "\t[CC-$(ARCH)] $@"
$(Q)$(CC) $(CFLAGS) -c $(OUTPUT_FLAG) $@ ../src/libwolfboot.c
Expand Down
5 changes: 5 additions & 0 deletions test-app/app_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
char enc_key[] = "0123456789abcdef0123456789abcdef"
"0123456789abcdef";

#ifdef TEST_DELTA_DATA
static volatile char __attribute__((used)) garbage[TEST_DELTA_DATA] = {0x01, 0x02, 0x03, 0x04 };

#endif

void hal_init(void);

int do_cmd(const char *cmd)
Expand Down
23 changes: 23 additions & 0 deletions tools/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SPI_CHIP=SST25VF080B
SPI_OPTIONS=SPI_FLASH=1 WOLFBOOT_PARTITION_SIZE=0x80000 WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00000 WOLFBOOT_PARTITION_SWAP_ADDRESS=0x80000
SIGN_ARGS=
SIGN_ENC_ARGS=
DELTA_DATA_SIZE?=2000

# python version only supported using
# KEYGEN_TOOL="python3 $(WOLFBOOT_ROOT)/tools/keytools/keygen.py"
Expand Down Expand Up @@ -159,6 +160,28 @@ test-sim-external-flash-with-update: wolfboot.bin test-app/image.elf FORCE
$(Q)$(BINASSEMBLE) external_flash.dd 0 test-app/image_v$(TEST_UPDATE_VERSION)_signed.bin \
$(WOLFBOOT_PARTITION_SIZE) erased_sec.dd

test-sim-external-flash-with-enc-delta-update-extradata:DELTA_UPDATE_OPTIONS=--delta test-app/image_v1_signed.bin
test-sim-external-flash-with-enc-delta-update-extradata:SIGN_ENC_ARGS=--encrypt /tmp/enc_key.der --aes128
test-sim-external-flash-with-enc-delta-update-extradata: wolfboot.bin test-app/image.elf FORCE
@printf "0123456789abcdef0123456789abcdef0123456789abcdef" > /tmp/enc_key.der
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) test-app/image.elf $(PRIVATE_KEY) 1
$(Q)cp test-app/image_v1_signed.bin test-app/image_v1_signed.bak
$(Q)rm -f test-app/image.elf test-app/app_sim.o
$(Q)make -C test-app delta-extra-data DELTA_DATA_SIZE=$(DELTA_DATA_SIZE)
$(Q)cp test-app/image_v1_signed.bak test-app/image_v1_signed.bin
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) $(SIGN_ENC_ARGS) test-app/image.elf $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
$(Q)$(SIGN_TOOL) $(SIGN_ARGS) $(DELTA_UPDATE_OPTIONS) $(SIGN_ENC_ARGS) \
test-app/image.elf $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
$(Q)dd if=/dev/zero bs=$$(($(WOLFBOOT_PARTITION_SIZE))) count=1 2>/dev/null | tr "\000" "\377" > v1_part.dd
$(Q)dd if=test-app/image_v1_signed.bin bs=256 of=v1_part.dd conv=notrunc
$(Q)$(BINASSEMBLE) internal_flash.dd \
0 wolfboot.bin \
$$(($(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET))) v1_part.dd
$(Q)dd if=/dev/zero bs=$$(($(WOLFBOOT_SECTOR_SIZE))) count=1 2>/dev/null | tr "\000" "\377" > erased_sec.dd
$(Q)$(BINASSEMBLE) external_flash.dd 0 test-app/image_v$(TEST_UPDATE_VERSION)_signed_diff_encrypted.bin \
$(WOLFBOOT_PARTITION_SIZE) erased_sec.dd
$(Q)ls -l test-app/*.bin


test-sim-external-flash-with-enc-update:SIGN_ENC_ARGS=--encrypt /tmp/enc_key.der --aes128
test-sim-external-flash-with-enc-update: wolfboot.bin test-app/image.elf FORCE
Expand Down
Loading