Skip to content

Commit dd11fad

Browse files
authored
Merge pull request #385 from danielinux/test-delta
Improve delta tests + fix delta+encrypt bug
2 parents d541d65 + f4e0cc6 commit dd11fad

File tree

9 files changed

+138
-33
lines changed

9 files changed

+138
-33
lines changed

.github/workflows/test-powerfail-simulator.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,3 +380,39 @@ jobs:
380380
- name: Run update-revert test with power failures (AES128 NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT)
381381
run: |
382382
tools/scripts/sim-update-powerfail-resume.sh
383+
384+
# TEST with encryption (aes128) and NVM_WRITEONCE and DELTA updates
385+
- name: make clean
386+
run: |
387+
make distclean
388+
- name: Select config with encrypted updates
389+
run: |
390+
cp config/examples/sim-encrypt-delta-nvm-writeonce-update.config .config
391+
392+
- name: Build tools
393+
run: |
394+
make -C tools/keytools && make -C tools/bin-assemble
395+
396+
- name: Build wolfboot.elf
397+
run: |
398+
make clean && make test-sim-external-flash-with-enc-delta-update
399+
400+
- name: Run sunny day update test (AES128 DELTA)
401+
run: |
402+
tools/scripts/sim-sunnyday-update.sh
403+
404+
- name: Rebuild wolfboot.elf
405+
run: |
406+
make clean && make test-sim-external-flash-with-enc-delta-update
407+
408+
- name: Run update-revert test (AES128 DELTA)
409+
run: |
410+
tools/scripts/sim-update-fallback.sh
411+
412+
- name: Rebuild wolfboot.elf
413+
run: |
414+
make clean && make test-sim-external-flash-with-enc-delta-update
415+
416+
- name: Run update-revert test with power failures (AES128 DELTA)
417+
run: |
418+
tools/scripts/sim-update-powerfail-resume.sh
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
ARCH=sim
2+
TARGET=sim
3+
SIGN?=ED25519
4+
HASH?=SHA256
5+
WOLFBOOT_SMALL_STACK=1
6+
SPI_FLASH=0
7+
EXT_FLASH=1
8+
ENCRYPT=1
9+
ENCRYPT_WITH_AES128=1
10+
DEBUG=1
11+
DELTA_UPDATES=1
12+
NVM_FLASH_WRITEONCE=1
13+
14+
# sizes should be multiple of system page size
15+
WOLFBOOT_PARTITION_SIZE=0x40000
16+
WOLFBOOT_SECTOR_SIZE=0x1000
17+
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x20000
18+
# if on external flash, it should be multiple of system page size
19+
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00000
20+
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x40000
21+
22+
# required for keytools
23+
WOLFBOOT_FIXED_PARTITIONS=1

include/delta.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ int wb_diff_init(WB_DIFF_CTX *ctx, uint8_t *src_a, uint32_t len_a, uint8_t *src_
6767
int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len);
6868
int wb_patch_init(WB_PATCH_CTX *bm, uint8_t *src, uint32_t ssz, uint8_t *patch, uint32_t psz);
6969
int wb_patch(WB_PATCH_CTX *ctx, uint8_t *dst, uint32_t len);
70-
int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset, uint16_t **img_size);
70+
int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset, uint32_t **img_size);
7171

7272
#endif
7373

src/delta.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ int wb_diff(WB_DIFF_CTX *ctx, uint8_t *patch, uint32_t len)
209209
* base for the sectors that have already been updated.
210210
*/
211211

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

279280
if ((memcmp(pb, (ctx->src_b + ctx->off_b), BLOCK_HDR_SIZE) == 0)) {

src/libwolfboot.c

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,7 +1690,7 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data,
16901690
uint32_t row_address = address, row_offset;
16911691
int sz = len, i, step;
16921692
uint8_t part;
1693-
uint32_t iv_counter;
1693+
uint32_t iv_counter = 0;
16941694

16951695
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
16961696
if (row_offset != 0) {
@@ -1768,7 +1768,10 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
17681768
uint8_t block[ENCRYPT_BLOCK_SIZE];
17691769
uint8_t dec_block[ENCRYPT_BLOCK_SIZE];
17701770
uint32_t row_address = address, row_offset, iv_counter = 0;
1771-
int sz = len, i, step;
1771+
int i;
1772+
int flash_read_size;
1773+
int read_remaining = len;
1774+
int unaligned_head_size, unaligned_tail_size;
17721775
uint8_t part;
17731776
uintptr_t base_address;
17741777

@@ -1778,10 +1781,6 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
17781781
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
17791782
if (row_offset != 0) {
17801783
row_address = address & ~(ENCRYPT_BLOCK_SIZE - 1);
1781-
sz += ENCRYPT_BLOCK_SIZE - row_offset;
1782-
}
1783-
if (sz < ENCRYPT_BLOCK_SIZE) {
1784-
sz = ENCRYPT_BLOCK_SIZE;
17851784
}
17861785
if (!encrypt_initialized) {
17871786
if (crypto_init() < 0)
@@ -1806,42 +1805,54 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
18061805
default:
18071806
return -1;
18081807
}
1809-
/* decrypt blocks */
1810-
if (sz > len) {
1811-
step = ENCRYPT_BLOCK_SIZE - row_offset;
1808+
/* Decrypt block. If the address does not align with the encryption block,
1809+
* decrypt then copy only the bytes from the requested address.
1810+
*/
1811+
if (row_offset != 0) {
1812+
unaligned_head_size = ENCRYPT_BLOCK_SIZE - row_offset;
18121813
if (ext_flash_read(row_address, block, ENCRYPT_BLOCK_SIZE)
18131814
!= ENCRYPT_BLOCK_SIZE) {
18141815
return -1;
18151816
}
18161817
crypto_decrypt(dec_block, block, ENCRYPT_BLOCK_SIZE);
1817-
XMEMCPY(data, dec_block + row_offset, step);
1818-
address += step;
1819-
data += step;
1820-
sz = len - step;
1818+
XMEMCPY(data, dec_block + row_offset, unaligned_head_size);
1819+
address += unaligned_head_size;
1820+
data += unaligned_head_size;
1821+
read_remaining -= unaligned_head_size;
18211822
iv_counter++;
18221823
}
1823-
1824-
/* decrypt remainder */
1825-
step = sz & ~(ENCRYPT_BLOCK_SIZE - 1);
1826-
if (ext_flash_read(address, data, step) != step)
1824+
/* Trim the read size to align with the Encryption Blocks. Read the
1825+
* remaining unaligned tail bytes after, since the `data` buffer won't have
1826+
* enough space to handle the extra bytes.
1827+
*/
1828+
flash_read_size = read_remaining & ~(ENCRYPT_BLOCK_SIZE - 1);
1829+
if (ext_flash_read(address, data, flash_read_size) != flash_read_size)
18271830
return -1;
1828-
for (i = 0; i < step / ENCRYPT_BLOCK_SIZE; i++) {
1831+
for (i = 0; i < flash_read_size / ENCRYPT_BLOCK_SIZE; i++)
1832+
{
18291833
XMEMCPY(block, data + (ENCRYPT_BLOCK_SIZE * i), ENCRYPT_BLOCK_SIZE);
18301834
crypto_decrypt(data + (ENCRYPT_BLOCK_SIZE * i), block,
1831-
ENCRYPT_BLOCK_SIZE);
1835+
ENCRYPT_BLOCK_SIZE);
18321836
iv_counter++;
18331837
}
1834-
sz -= step;
1835-
if (sz > 0) {
1836-
if (ext_flash_read(address + step, block, ENCRYPT_BLOCK_SIZE)
1837-
!= ENCRYPT_BLOCK_SIZE) {
1838+
1839+
address += flash_read_size;
1840+
data += flash_read_size;
1841+
read_remaining -= flash_read_size;
1842+
1843+
/* Read the unaligned tail bytes. */
1844+
unaligned_tail_size = read_remaining;
1845+
if (unaligned_tail_size > 0)
1846+
{
1847+
uint8_t dec_block[ENCRYPT_BLOCK_SIZE];
1848+
if (ext_flash_read(address, block, ENCRYPT_BLOCK_SIZE)
1849+
!= ENCRYPT_BLOCK_SIZE)
18381850
return -1;
1839-
}
18401851
crypto_decrypt(dec_block, block, ENCRYPT_BLOCK_SIZE);
1841-
XMEMCPY(data + step, dec_block, sz);
1842-
iv_counter++;
1852+
XMEMCPY(data, dec_block, unaligned_tail_size);
1853+
read_remaining -= unaligned_tail_size;
18431854
}
1844-
return len;
1855+
return (len - read_remaining);
18451856
}
18461857
#endif /* EXT_FLASH */
18471858
#endif /* __WOLFBOOT */

src/update_flash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
212212
uint32_t offset = 0;
213213
uint16_t ptr_len;
214214
uint32_t *img_offset;
215-
uint16_t *img_size;
215+
uint32_t *img_size;
216216
uint32_t total_size;
217217
WB_PATCH_CTX ctx;
218218
#ifdef EXT_ENCRYPTED

test-app/Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ ARCH?=ARM
88
MCUXPRESSO_CMSIS?=$(MCUXPRESSO)/CMSIS
99
CFLAGS+=-I.
1010
CFLAGS+=-I./wcs
11-
DEBUG=1
11+
DEBUG?=1
12+
DELTA_DATA_SIZE?=2000
1213

1314
ifeq ($(SIGN),RSA2048)
1415
IMAGE_HEADER_SIZE:=512
@@ -166,7 +167,7 @@ endif
166167
ifeq ($(TARGET),sim)
167168
APP_OBJS=app_$(TARGET).o ../test-app/libwolfboot.o ../hal/$(TARGET).o
168169
# Override linker flags
169-
LDFLAGS=
170+
LDFLAGS=-Wl,-Map=image.map
170171
endif
171172

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

331+
delta-extra-data:CFLAGS+=-D"TEST_DELTA_DATA=$(DELTA_DATA_SIZE)" -ffunction-sections -fdata-sections
332+
delta-extra-data:LDFLAGS=-Wl,-Map=image.map
333+
330334
image.bin: image.elf
331335
@echo "\t[BIN] $@"
332336
$(Q)$(OBJCOPY) --gap-fill $(FILL_BYTE) -O binary $^ $@
@@ -338,6 +342,8 @@ image.elf: $(APP_OBJS) $(LSCRIPT)
338342

339343
standalone: image.bin
340344

345+
delta-extra-data: image.bin
346+
341347
../test-app/libwolfboot.o: ../src/libwolfboot.c FORCE
342348
@echo "\t[CC-$(ARCH)] $@"
343349
$(Q)$(CC) $(CFLAGS) -c $(OUTPUT_FLAG) $@ ../src/libwolfboot.c

test-app/app_sim.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
char enc_key[] = "0123456789abcdef0123456789abcdef"
4141
"0123456789abcdef";
4242

43+
#ifdef TEST_DELTA_DATA
44+
static volatile char __attribute__((used)) garbage[TEST_DELTA_DATA] = {0x01, 0x02, 0x03, 0x04 };
45+
46+
#endif
47+
4348
void hal_init(void);
4449

4550
int do_cmd(const char *cmd)

tools/test.mk

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SPI_CHIP=SST25VF080B
77
SPI_OPTIONS=SPI_FLASH=1 WOLFBOOT_PARTITION_SIZE=0x80000 WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00000 WOLFBOOT_PARTITION_SWAP_ADDRESS=0x80000
88
SIGN_ARGS=
99
SIGN_ENC_ARGS=
10+
DELTA_DATA_SIZE?=2000
1011

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

166+
test-sim-external-flash-with-enc-delta-update-extradata:DELTA_UPDATE_OPTIONS=--delta test-app/image_v1_signed.bin
167+
test-sim-external-flash-with-enc-delta-update-extradata:SIGN_ENC_ARGS=--encrypt /tmp/enc_key.der --aes128
168+
test-sim-external-flash-with-enc-delta-update-extradata: wolfboot.bin test-app/image.elf FORCE
169+
@printf "0123456789abcdef0123456789abcdef0123456789abcdef" > /tmp/enc_key.der
170+
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) test-app/image.elf $(PRIVATE_KEY) 1
171+
$(Q)cp test-app/image_v1_signed.bin test-app/image_v1_signed.bak
172+
$(Q)rm -f test-app/image.elf test-app/app_sim.o
173+
$(Q)make -C test-app delta-extra-data DELTA_DATA_SIZE=$(DELTA_DATA_SIZE)
174+
$(Q)cp test-app/image_v1_signed.bak test-app/image_v1_signed.bin
175+
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) $(SIGN_ENC_ARGS) test-app/image.elf $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
176+
$(Q)$(SIGN_TOOL) $(SIGN_ARGS) $(DELTA_UPDATE_OPTIONS) $(SIGN_ENC_ARGS) \
177+
test-app/image.elf $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
178+
$(Q)dd if=/dev/zero bs=$$(($(WOLFBOOT_PARTITION_SIZE))) count=1 2>/dev/null | tr "\000" "\377" > v1_part.dd
179+
$(Q)dd if=test-app/image_v1_signed.bin bs=256 of=v1_part.dd conv=notrunc
180+
$(Q)$(BINASSEMBLE) internal_flash.dd \
181+
0 wolfboot.bin \
182+
$$(($(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET))) v1_part.dd
183+
$(Q)dd if=/dev/zero bs=$$(($(WOLFBOOT_SECTOR_SIZE))) count=1 2>/dev/null | tr "\000" "\377" > erased_sec.dd
184+
$(Q)$(BINASSEMBLE) external_flash.dd 0 test-app/image_v$(TEST_UPDATE_VERSION)_signed_diff_encrypted.bin \
185+
$(WOLFBOOT_PARTITION_SIZE) erased_sec.dd
186+
$(Q)ls -l test-app/*.bin
187+
165188

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

0 commit comments

Comments
 (0)