Fixes for encrypt/decrypt with unaligned address. Fix issue with byte count result on Mac. Cleanups for uart-flash-server.

pull/263/head
David Garske 2022-12-12 10:10:50 -08:00 committed by Daniele Lacamera
parent 4ee867b2dd
commit da6d364f1e
6 changed files with 98 additions and 49 deletions

View File

@ -98,7 +98,8 @@ struct wolfBoot_image {
* With ARMORED setup, the flag is redundant, and the information is wrapped in
* between canary variables, to mitigate attacks based on memory corruptions.
*/
static void __attribute__((noinline)) wolfBoot_image_confirm_signature_ok(struct wolfBoot_image *img)
static void __attribute__((noinline)) wolfBoot_image_confirm_signature_ok(
struct wolfBoot_image *img)
{
img->canary_FEED4567 = 0xFEED4567UL;
img->signature_ok = 1UL;
@ -502,7 +503,9 @@ struct wolfBoot_image {
uint8_t sha_ok : 1;
};
static void wolfBoot_image_confirm_signature_ok(struct wolfBoot_image *img)
/* do not warn if this is not used */
static void __attribute__ ((unused)) wolfBoot_image_confirm_signature_ok(
struct wolfBoot_image *img)
{
img->signature_ok = 1;
}

View File

@ -72,6 +72,13 @@
#define NVM_CACHE_SIZE WOLFBOOT_SECTOR_SIZE
#endif
#ifdef BUILD_TOOL
/* Building for a local utility tool */
#undef EXT_FLASH
#undef EXT_ENCRYPTED
#undef WOLFBOOT_FIXED_PARTITIONS
#endif
#ifdef EXT_FLASH
static uint32_t ext_cache;
#endif
@ -123,10 +130,10 @@ static const uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL;
static uint8_t NVM_CACHE[NVM_CACHE_SIZE] __attribute__((aligned(16)));
int RAMFUNCTION hal_trailer_write(uint32_t addr, uint8_t val) {
uint32_t addr_align = addr & (~(NVM_CACHE_SIZE - 1));
size_t addr_align = (size_t)(addr & (~(NVM_CACHE_SIZE - 1)));
uint32_t addr_off = addr & (NVM_CACHE_SIZE - 1);
int ret = 0;
XMEMCPY(NVM_CACHE, (void *)addr_align, NVM_CACHE_SIZE);
XMEMCPY(NVM_CACHE, (void*)addr_align, NVM_CACHE_SIZE);
ret = hal_flash_erase(addr_align, NVM_CACHE_SIZE);
if (ret != 0)
return ret;
@ -147,9 +154,9 @@ int RAMFUNCTION hal_trailer_write(uint32_t addr, uint8_t val) {
int RAMFUNCTION hal_set_partition_magic(uint32_t addr)
{
uint32_t off = addr % NVM_CACHE_SIZE;
uint32_t base = addr - off;
size_t base = (size_t)addr - off;
int ret;
XMEMCPY(NVM_CACHE, (void *)base, NVM_CACHE_SIZE);
XMEMCPY(NVM_CACHE, (void*)base, NVM_CACHE_SIZE);
ret = hal_flash_erase(base, WOLFBOOT_SECTOR_SIZE);
if (ret != 0)
return ret;
@ -164,8 +171,7 @@ int RAMFUNCTION hal_set_partition_magic(uint32_t addr)
(void*)&wolfboot_magic_trail, sizeof(uint32_t));
#endif
#if defined EXT_FLASH
#ifdef EXT_FLASH
static uint8_t* RAMFUNCTION get_trailer_at(uint8_t part, uint32_t at)
{
@ -232,14 +238,20 @@ static void RAMFUNCTION set_partition_magic(uint8_t part)
#elif !defined(WOLFBOOT_FIXED_PARTITIONS)
static uint8_t* RAMFUNCTION get_trailer_at(uint8_t part, uint32_t at)
{
(void)part;
(void)at;
return 0;
}
static void RAMFUNCTION set_trailer_at(uint8_t part, uint32_t at, uint8_t val)
{
(void)part;
(void)at;
(void)val;
return;
}
static void RAMFUNCTION set_partition_magic(uint8_t part)
{
(void)part;
return;
}
@ -809,7 +821,6 @@ int RAMFUNCTION wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce)
int RAMFUNCTION wolfBoot_erase_encrypt_key(void)
{
uint8_t ff[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE];
int i;
uint8_t *mem = (uint8_t *)ENCRYPT_TMP_SECRET_OFFSET +
WOLFBOOT_PARTITION_BOOT_ADDRESS;
XMEMSET(ff, 0xFF, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE);
@ -935,11 +946,11 @@ static uint8_t RAMFUNCTION part_address(uintptr_t a)
int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
{
uint8_t block[ENCRYPT_BLOCK_SIZE];
uint8_t part;
int sz = len;
uint32_t row_address = address, row_offset;
int i;
uint8_t enc_block[ENCRYPT_BLOCK_SIZE];
uint32_t row_address = address, row_offset;
int sz = len, i, step;
uint8_t part;
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
if (row_offset != 0) {
row_address = address & ~(ENCRYPT_BLOCK_SIZE - 1);
@ -948,11 +959,12 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data,
if (sz < ENCRYPT_BLOCK_SIZE) {
sz = ENCRYPT_BLOCK_SIZE;
}
if (!encrypt_initialized)
if (!encrypt_initialized) {
if (crypto_init() < 0)
return -1;
}
part = part_address(address);
switch(part) {
switch (part) {
case PART_UPDATE:
/* do not encrypt flag sector */
if (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS >=
@ -966,34 +978,40 @@ int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data,
default:
return -1;
}
/* encrypt blocks */
if (sz > len) {
int step = ENCRYPT_BLOCK_SIZE - row_offset;
step = ENCRYPT_BLOCK_SIZE - row_offset;
if (ext_flash_read(row_address, block, ENCRYPT_BLOCK_SIZE)
!= ENCRYPT_BLOCK_SIZE)
!= ENCRYPT_BLOCK_SIZE) {
return -1;
}
XMEMCPY(block + row_offset, data, step);
crypto_encrypt(enc_block, block, ENCRYPT_BLOCK_SIZE);
ext_flash_write(row_address, enc_block, ENCRYPT_BLOCK_SIZE);
address += step;
data += step;
sz -= step;
sz = len - step;
}
for (i = 0; i < sz / ENCRYPT_BLOCK_SIZE; i++) {
/* encrypt remainder */
step = sz & ~(ENCRYPT_BLOCK_SIZE - 1);
for (i = 0; i < step / ENCRYPT_BLOCK_SIZE; i++) {
XMEMCPY(block, data + (ENCRYPT_BLOCK_SIZE * i), ENCRYPT_BLOCK_SIZE);
crypto_encrypt(ENCRYPT_CACHE + (ENCRYPT_BLOCK_SIZE * i), block,
ENCRYPT_BLOCK_SIZE);
}
return ext_flash_write(address, ENCRYPT_CACHE, len);
return ext_flash_write(address, ENCRYPT_CACHE, step);
}
int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len)
{
uint32_t iv_counter = 0;
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;
uint8_t part;
int sz = len;
uint32_t row_address = address, row_offset;
int i;
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
if (row_offset != 0) {
@ -1003,11 +1021,12 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
if (sz < ENCRYPT_BLOCK_SIZE) {
sz = ENCRYPT_BLOCK_SIZE;
}
if (!encrypt_initialized)
if (!encrypt_initialized) {
if (crypto_init() < 0)
return -1;
}
part = part_address(row_address);
switch(part) {
switch (part) {
case PART_UPDATE:
iv_counter = (address - WOLFBOOT_PARTITION_UPDATE_ADDRESS) /
ENCRYPT_BLOCK_SIZE;
@ -1025,27 +1044,42 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
default:
return -1;
}
/* decrypt blocks */
if (sz > len) {
uint8_t dec_block[ENCRYPT_BLOCK_SIZE];
int step = ENCRYPT_BLOCK_SIZE - row_offset;
step = ENCRYPT_BLOCK_SIZE - row_offset;
if (ext_flash_read(row_address, block, ENCRYPT_BLOCK_SIZE)
!= 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 -= step;
sz = len - step;
iv_counter++;
}
if (ext_flash_read(address, data, sz) != sz)
/* decrypt remainder */
step = sz & ~(ENCRYPT_BLOCK_SIZE - 1);
if (ext_flash_read(address, data, step) != step)
return -1;
for (i = 0; i < sz / ENCRYPT_BLOCK_SIZE; i++) {
for (i = 0; i < step / 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);
iv_counter++;
}
sz -= step;
if (sz > 0) {
if (ext_flash_read(address + step, 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++;
}
return len;
}
#endif

View File

@ -90,7 +90,7 @@ test-delta-update-ext: distclean factory.bin test-app/image.bin tools/uart-flash
@sleep $(TIMEOUT)
@killall ufserver
@st-flash read boot_full.bin 0x0800C000 0x8000
@SIZE=`wc -c test-app/image_v7_signed.bin | cut -d" " -f 1`; \
@SIZE=`wc -c test-app/image_v7_signed.bin | awk '{$$1=$$1};1' | 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
@ -104,7 +104,7 @@ test-delta-update-ext: distclean factory.bin test-app/image.bin tools/uart-flash
@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`; \
@SIZE=`wc -c test-app/image_v1_signed.bin | awk '{$$1=$$1};1' | 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
@ -136,7 +136,7 @@ test-delta-enc-update-ext: distclean factory.bin test-app/image.bin tools/uart-f
@sleep $(TIMEOUT)
@st-flash reset
@st-flash read boot_full.bin 0x0800C000 0x8000
@SIZE=`wc -c test-app/image_v7_signed.bin | cut -d" " -f 1`; \
@SIZE=`wc -c test-app/image_v7_signed.bin | awk '{$$1=$$1};1' | 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
@ -153,7 +153,7 @@ test-delta-enc-update-ext: distclean factory.bin test-app/image.bin tools/uart-f
@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`; \
@SIZE=`wc -c test-app/image_v1_signed.bin | awk '{$$1=$$1};1' | 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

View File

@ -38,7 +38,7 @@ test-enc-update: factory.bin test-app/image.bin tools/uart-flash-server/ufserver
@sleep 3
@killall ufserver
@st-flash read boot_full.bin 0x08010000 0x8000
@SIZE=`wc -c test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin | cut -d" " -f 1`; \
@SIZE=`wc -c test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin | awk '{$$1=$$1};1' | cut -d" " -f 1`; \
dd if=boot_full.bin of=boot.bin bs=1 count=$$SIZE
@diff boot.bin test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin || (echo "TEST FAILED" && exit 1)
@rm boot.bin boot_full.bin
@ -61,7 +61,7 @@ test-enc-aes128-update: factory.bin test-app/image.bin tools/uart-flash-server/u
@sleep 3
@killall ufserver
@st-flash read boot_full.bin 0x08010000 0x8000
@SIZE=`wc -c test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin | cut -d" " -f 1`; \
@SIZE=`wc -c test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin | awk '{$$1=$$1};1' | cut -d" " -f 1`; \
dd if=boot_full.bin of=boot.bin bs=1 count=$$SIZE
@diff boot.bin test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin || (echo "TEST FAILED" && exit 1)
@rm boot.bin boot_full.bin
@ -84,7 +84,7 @@ test-enc-aes256-update: factory.bin test-app/image.bin tools/uart-flash-server/u
@sleep 3
@killall ufserver
@st-flash read boot_full.bin 0x08010000 0x8000
@SIZE=`wc -c test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin | cut -d" " -f 1`; \
@SIZE=`wc -c test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin | awk '{$$1=$$1};1' | cut -d" " -f 1`; \
dd if=boot_full.bin of=boot.bin bs=1 count=$$SIZE
@diff boot.bin test-app/image_v$(ENC_TEST_UPDATE_VERSION)_signed.bin || (echo "TEST FAILED" && exit 1)
@rm boot.bin boot_full.bin

View File

@ -1,5 +1,9 @@
-include ../../.config
-include ../../tools/config.mk
-include ../../options.mk
CC=$(CROSS_COMPILE)gcc
CFLAGS=-Wall -DWOLFSSL_DEBUG -DTFM_TIMING_RESISTANT -DWOLFBOOT_SIGN_ECC256 -DWOLFBOOT_HASH_SHA256 -g -ggdb -I../../include -I../../hal -Wextra
CFLAGS+=-DBUILD_TOOL -Wall -g -ggdb -I../../include -I../../hal -Wextra
Q?=@
ifeq ($(V),1)
Q=

View File

@ -4,7 +4,7 @@
*
* Run on HOST machine to export an emulated external, non-volatile memory.
*
* Copyright (C) 2021 wolfSSL Inc.
* Copyright (C) 2022 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
@ -67,7 +67,8 @@ const char msgWriteSwap[] = "Writing SWAP blocks ";
const char msgEraseUpdate[] = "Erase update blocks ";
const char msgEraseSwap[] = "Erase swap blocks ";
extern uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr);
extern uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type,
uint8_t **ptr);
const char blinker[]="-\\|/";
static int valid_update = 1;
@ -190,8 +191,7 @@ uint8_t *mmap_firmware(const char *fname)
return (void *)-1;
}
fd = open(fname, O_RDWR);
if (fd < 0)
{
if (fd < 0) {
perror("open");
return (void *)-1;
}
@ -211,7 +211,9 @@ uint8_t *mmap_firmware(const char *fname)
write(fd, &pad, 1);
}
if (strncmp((char *)&signature_word, "WOLF", 4) != 0) {
fprintf(stderr, "Warning: the binary file provided does not appear to contain a valid firmware partition file. (If the update is encrypted, this is OK)\n");
fprintf(stderr, "Warning: the binary file provided does not appear to "
"contain a valid firmware partition file. "
"(If the update is encrypted, this is OK)\n");
valid_update = 0;
} else {
int i;
@ -221,7 +223,8 @@ uint8_t *mmap_firmware(const char *fname)
for (i = 0; i < SWAP_SIZE; i++)
write(fd, update_flags, 5);
}
base_fw = mmap(NULL, FIRMWARE_PARTITION_SIZE + SWAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
base_fw = mmap(NULL, FIRMWARE_PARTITION_SIZE + SWAP_SIZE,
(PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
if (base_fw == (void *)(-1)) {
perror("mmap");
return (void *)-1;
@ -357,7 +360,8 @@ static void serve_update(uint8_t *base, const char *uart_dev)
uint8_t buf[8];
int ud = open_uart(uart_dev);
if (ud < 0) {
fprintf(stderr, "Cannot open serial port %s: %s.\n", uart_dev, strerror(errno));
fprintf(stderr, "Cannot open serial port %s: %s.\n",
uart_dev, strerror(errno));
exit(3);
}
while (1) {
@ -369,7 +373,9 @@ static void serve_update(uint8_t *base, const char *uart_dev)
if (ret == 0)
continue;
if ((buf[0] != CMD_HDR_WOLF) && (buf[0] != CMD_HDR_VER) && (buf[0] != CMD_APP_VER)) {
if ((buf[0] != CMD_HDR_WOLF) &&
(buf[0] != CMD_HDR_VER) &&
(buf[0] != CMD_APP_VER)) {
printf("bad hdr: %02x\n", buf[0]);
continue;
}
@ -441,7 +447,9 @@ static void serve_update(uint8_t *base, const char *uart_dev)
void usage(char *pname)
{
printf("Usage: %s binary_file serial_port\nExample:\n%s firmware_v3_signed.bin /dev/ttyUSB0\n", pname, pname);
printf("Usage: %s binary_file serial_port\nExample:\n"
"%s firmware_v3_signed.bin /dev/ttyUSB0\n",
pname, pname);
exit(1);
}