mirror of https://github.com/wolfSSL/wolfBoot.git
Support encrypted images in MMU targets
parent
cb1eaff8e8
commit
2f2a6d416d
|
@ -0,0 +1,24 @@
|
|||
ARCH?=AARCH64
|
||||
TARGET?=raspi3
|
||||
SIGN?=RSA4096
|
||||
HASH?=SHA3
|
||||
DEBUG?=1
|
||||
VTOR?=1
|
||||
SPMATH?=1
|
||||
IMAGE_HEADER_SIZE?=1024
|
||||
PKA?=0
|
||||
WOLFTPM?=0
|
||||
|
||||
WOLFBOOT_NO_PARTITIONS=1
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x140000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x1140000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS=0xFFFFFFFF
|
||||
WOLFBOOT_PARTITION_SIZE=0x1000000
|
||||
WOLFBOOT_SECTOR_SIZE=0x400
|
||||
EXT_FLASH=0
|
||||
MMU=1
|
||||
ENCRYPT=1
|
||||
NO_XIP=1
|
||||
ENCRYPT_WITH_AES256=1
|
||||
WOLFBOOT_LOAD_ADDRESS?=0x3080000
|
||||
WOLFBOOT_LOAD_DTS_ADDRESS?=0x400000
|
|
@ -854,6 +854,48 @@ qemu-system-aarch64 -M raspi3b -m 1024 -serial stdio -kernel wolfboot_linux_rasp
|
|||
```
|
||||
|
||||
|
||||
### Testing with kernel encryption
|
||||
|
||||
The raspberry pi target is used to demonstrate the end-to-end encryption when booting
|
||||
images from RAM. The image is encrypted after being signed. The bootloader uses
|
||||
the same symmetric key to decrypt the image to RAM before performing the
|
||||
validity checks. Here are the steps to enable this feature:
|
||||
|
||||
* Build wolfboot using the example configuration (RSA4096, SHA3, ENCRYPT=1)
|
||||
|
||||
```
|
||||
cp config/examples/raspi3-encrypted.config .config
|
||||
make clean
|
||||
make wolfboot.bin CROSS_COMPILE=aarch64-linux-gnu-
|
||||
```
|
||||
|
||||
* Create the decrypt key + nonce
|
||||
|
||||
```
|
||||
printf "0123456789abcdef0123456789abcdef0123456789ab" > /tmp/enc_key.der
|
||||
```
|
||||
|
||||
* Sign and encrypt Linux kernel image
|
||||
```
|
||||
make keytools
|
||||
./tools/keytools/sign --aes256 --encrypt /tmp/enc_key.der --rsa4096 --sha3 Image wolfboot_signing_private_key.der 1
|
||||
```
|
||||
|
||||
* Compose the image
|
||||
|
||||
```
|
||||
tools/bin-assemble/bin-assemble wolfboot_linux_raspi.bin 0x0 wolfboot.bin \
|
||||
0xc0000 Image_v1_signed_and_encrypted.bin
|
||||
dd if=bcm2710-rpi-3-b.dtb of=wolfboot_linux_raspi.bin bs=1 seek=128K conv=notrunc
|
||||
```
|
||||
|
||||
* Test boot using qemu
|
||||
|
||||
```
|
||||
qemu-system-aarch64 -M raspi3b -m 1024 -serial stdio -kernel wolfboot_linux_raspi.bin -cpu cortex-a53
|
||||
```
|
||||
|
||||
|
||||
## Xilinx Zynq UltraScale
|
||||
|
||||
Xilinx UltraScale+ ZCU102 (Aarch64)
|
||||
|
|
48
hal/raspi3.c
48
hal/raspi3.c
|
@ -27,30 +27,60 @@
|
|||
# error "wolfBoot raspi3 HAL: wrong architecture selected. Please compile with ARCH=AARCH64."
|
||||
#endif
|
||||
|
||||
#define TEST_ENCRYPT
|
||||
|
||||
|
||||
#define CORTEXA53_0_CPU_CLK_FREQ_HZ 1099989014
|
||||
#define CORTEXA53_0_TIMESTAMP_CLK_FREQ 99998999
|
||||
|
||||
/* Fixed addresses */
|
||||
static const void* kernel_addr = (void*)0x0140000;
|
||||
static const void* update_addr = (void*)0x1140000;
|
||||
static const void* dts_addr = (void*)0x00a0000;
|
||||
extern void *kernel_addr, *update_addr, *dts_addr;
|
||||
|
||||
void* hal_get_primary_address(void)
|
||||
{
|
||||
return (void*)kernel_addr;
|
||||
return (void*)&kernel_addr;
|
||||
}
|
||||
|
||||
void* hal_get_update_address(void)
|
||||
{
|
||||
return (void*)update_addr;
|
||||
return (void*)&update_addr;
|
||||
}
|
||||
|
||||
void* hal_get_dts_address(void)
|
||||
{
|
||||
return (void*)dts_addr;
|
||||
return (void*)&dts_addr;
|
||||
}
|
||||
|
||||
#ifdef EXT_FLASH
|
||||
int ext_flash_read(unsigned long address, uint8_t *data, int len)
|
||||
{
|
||||
XMEMCPY(data, (void *)address, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
int ext_flash_erase(unsigned long address, int len)
|
||||
{
|
||||
XMEMSET((void *)address, 0xFF, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
int ext_flash_write(unsigned long address, const uint8_t *data, int len)
|
||||
{
|
||||
XMEMCPY((void *)address, data, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
void ext_flash_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void ext_flash_unlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void* hal_get_dts_update_address(void)
|
||||
{
|
||||
return NULL; /* Not yet supported */
|
||||
|
@ -71,6 +101,12 @@ void zynq_init(uint32_t cpu_clock)
|
|||
/* public HAL functions */
|
||||
void hal_init(void)
|
||||
{
|
||||
#if defined(TEST_ENCRYPT) && defined (EXT_ENCRYPTED)
|
||||
char enc_key[] = "0123456789abcdef0123456789abcdef"
|
||||
"0123456789abcdef";
|
||||
wolfBoot_set_encrypt_key((uint8_t *)enc_key,(uint8_t *)(enc_key + 32));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void hal_prepare_boot(void)
|
||||
|
|
|
@ -53,3 +53,12 @@ SECTIONS
|
|||
}
|
||||
|
||||
END_STACK = _start_text;
|
||||
kernel_addr = 0x0140000;
|
||||
update_addr = 0x1140000;
|
||||
dts_addr = 0x00a0000;
|
||||
kernel_load_addr = 0x20000000;
|
||||
dts_load_addr = 0x21000000;
|
||||
|
||||
_wolfboot_partition_boot_address = kernel_addr;
|
||||
_wolfboot_partition_update_address = update_addr;
|
||||
|
||||
|
|
|
@ -194,7 +194,6 @@ extern "C" {
|
|||
|
||||
#endif /* defined WOLFBOOT */
|
||||
|
||||
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
||||
#define PART_BOOT 0
|
||||
#define PART_UPDATE 1
|
||||
#define PART_SWAP 2
|
||||
|
@ -203,7 +202,6 @@ extern "C" {
|
|||
#define PART_DTS (0x10)
|
||||
#define PART_DTS_BOOT (PART_DTS | PART_BOOT)
|
||||
#define PART_DTS_UPDATE (PART_DTS | PART_UPDATE)
|
||||
#endif /* WOLFBOOT_FIXED_PARTITIONS */
|
||||
|
||||
#ifndef WOLFBOOT_FLAGS_INVERT
|
||||
#define IMG_STATE_NEW 0xFF
|
||||
|
@ -265,6 +263,8 @@ int wolfBoot_dualboot_candidate_addr(void**);
|
|||
# error "Encryption ON, but no encryption algorithm selected."
|
||||
#endif
|
||||
|
||||
int wolfBoot_ram_decrypt(uint8_t *src, uint8_t *dst);
|
||||
|
||||
#endif /* EXT_ENCRYPTED */
|
||||
|
||||
#ifdef DELTA_UPDATES
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include <stddef.h> /* for size_t */
|
||||
|
||||
#if defined(EXT_ENCRYPTED)
|
||||
static int encrypt_initialized = 0;
|
||||
static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE];
|
||||
#if defined(__WOLFBOOT)
|
||||
#include "encrypt.h"
|
||||
#else
|
||||
|
@ -48,6 +50,9 @@
|
|||
#define XMEMCPY memcpy
|
||||
#define XMEMCMP memcmp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(EXT_FLASH) && defined(EXT_ENCRYPTED)
|
||||
#define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - \
|
||||
(TRAILER_SKIP + ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE))
|
||||
#define TRAILER_OVERHEAD (4 + 1 + (WOLFBOOT_PARTITION_SIZE / \
|
||||
|
@ -56,7 +61,7 @@
|
|||
#define START_FLAGS_OFFSET (ENCRYPT_TMP_SECRET_OFFSET - TRAILER_OVERHEAD)
|
||||
#else
|
||||
#define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - (TRAILER_SKIP))
|
||||
#endif
|
||||
#endif /* EXT_FLASH && EXT_ENCRYPTED */
|
||||
|
||||
#if !defined(__WOLFBOOT)
|
||||
#define XMEMSET memset
|
||||
|
@ -676,15 +681,44 @@ int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset,
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(EXT_ENCRYPTED) && defined(MMU)
|
||||
static uint8_t dec_hdr[IMAGE_HEADER_SIZE];
|
||||
|
||||
static int decrypt_header(uint8_t *src)
|
||||
{
|
||||
int i;
|
||||
uint32_t magic;
|
||||
uint32_t len;
|
||||
for (i = 0; i < IMAGE_HEADER_SIZE; i+=ENCRYPT_BLOCK_SIZE) {
|
||||
crypto_set_iv(encrypt_iv_nonce, i / ENCRYPT_BLOCK_SIZE);
|
||||
crypto_decrypt(dec_hdr + i, src + i, ENCRYPT_BLOCK_SIZE);
|
||||
}
|
||||
magic = *((uint32_t*)(dec_hdr));
|
||||
len = *((uint32_t*)(dec_hdr + sizeof(uint32_t)));
|
||||
if (magic != WOLFBOOT_MAGIC)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint32_t wolfBoot_get_blob_version(uint8_t *blob)
|
||||
{
|
||||
uint32_t *volatile version_field = NULL;
|
||||
uint32_t *magic = NULL;
|
||||
|
||||
magic = (uint32_t *)blob;
|
||||
uint8_t *img_bin = blob;
|
||||
#if defined(EXT_ENCRYPTED) && defined(MMU)
|
||||
if (!encrypt_initialized)
|
||||
if (crypto_init() < 0)
|
||||
return 0;
|
||||
decrypt_header(blob);
|
||||
img_bin = dec_hdr;
|
||||
#endif
|
||||
magic = (uint32_t *)img_bin;
|
||||
if (*magic != WOLFBOOT_MAGIC)
|
||||
return 0;
|
||||
if (wolfBoot_find_header(blob + IMAGE_HEADER_OFFSET, HDR_VERSION,
|
||||
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_VERSION,
|
||||
(void *)&version_field) == 0)
|
||||
return 0;
|
||||
if (version_field)
|
||||
|
@ -696,10 +730,18 @@ uint32_t wolfBoot_get_blob_type(uint8_t *blob)
|
|||
{
|
||||
uint32_t *volatile type_field = NULL;
|
||||
uint32_t *magic = NULL;
|
||||
magic = (uint32_t *)blob;
|
||||
uint8_t *img_bin = blob;
|
||||
#if defined(EXT_ENCRYPTED) && defined(MMU)
|
||||
if (!encrypt_initialized)
|
||||
if (crypto_init() < 0)
|
||||
return 0;
|
||||
decrypt_header(blob);
|
||||
img_bin = dec_hdr;
|
||||
#endif
|
||||
magic = (uint32_t *)img_bin;
|
||||
if (*magic != WOLFBOOT_MAGIC)
|
||||
return 0;
|
||||
if (wolfBoot_find_header(blob + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE,
|
||||
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_TYPE,
|
||||
(void *)&type_field) == 0)
|
||||
return 0;
|
||||
if (type_field)
|
||||
|
@ -712,10 +754,18 @@ uint32_t wolfBoot_get_blob_diffbase_version(uint8_t *blob)
|
|||
{
|
||||
uint32_t *volatile delta_base = NULL;
|
||||
uint32_t *magic = NULL;
|
||||
magic = (uint32_t *)blob;
|
||||
uint8_t *img_bin = blob;
|
||||
#if defined(EXT_ENCRYPTED) && defined(MMU)
|
||||
if (!encrypt_initialized)
|
||||
if (crypto_init() < 0)
|
||||
return 0;
|
||||
decrypt_header(blob);
|
||||
img_bin = dec_hdr;
|
||||
#endif
|
||||
magic = (uint32_t *)img_bin;
|
||||
if (*magic != WOLFBOOT_MAGIC)
|
||||
return 0;
|
||||
if (wolfBoot_find_header(blob + IMAGE_HEADER_OFFSET, HDR_IMG_DELTA_BASE,
|
||||
if (wolfBoot_find_header(img_bin + IMAGE_HEADER_OFFSET, HDR_IMG_DELTA_BASE,
|
||||
(void *)&delta_base) == 0)
|
||||
return 0;
|
||||
if (delta_base)
|
||||
|
@ -862,8 +912,8 @@ int wolfBoot_fallback_is_possible(void)
|
|||
|
||||
#ifdef EXT_ENCRYPTED
|
||||
#include "encrypt.h"
|
||||
#ifndef EXT_FLASH
|
||||
#error option EXT_ENCRYPTED requires EXT_FLASH
|
||||
#if !defined(EXT_FLASH) && !defined(MMU)
|
||||
#error option EXT_ENCRYPTED requires EXT_FLASH or MMU mode
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -874,17 +924,27 @@ int wolfBoot_fallback_is_possible(void)
|
|||
static uint8_t ENCRYPT_CACHE[NVM_CACHE_SIZE] __attribute__((aligned(32)));
|
||||
#endif
|
||||
|
||||
#if defined(EXT_ENCRYPTED) && defined(MMU)
|
||||
static uint8_t ENCRYPT_KEY[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE];
|
||||
#endif
|
||||
|
||||
static int RAMFUNCTION hal_set_key(const uint8_t *k, const uint8_t *nonce)
|
||||
{
|
||||
uint32_t addr = ENCRYPT_TMP_SECRET_OFFSET + WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
||||
uint32_t addr_align = addr & (~(WOLFBOOT_SECTOR_SIZE - 1));
|
||||
uint32_t addr_off = addr & (WOLFBOOT_SECTOR_SIZE - 1);
|
||||
uint32_t addr, addr_align, addr_off;
|
||||
int ret = 0;
|
||||
int sel_sec = 0;
|
||||
#ifdef NVM_FLASH_WRITEONCE
|
||||
sel_sec = nvm_select_fresh_sector(PART_BOOT);
|
||||
addr_align -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
|
||||
#endif
|
||||
#ifdef MMU
|
||||
XMEMCPY(ENCRYPT_KEY, k, ENCRYPT_KEY_SIZE);
|
||||
XMEMCPY(ENCRYPT_KEY + ENCRYPT_KEY_SIZE, nonce, ENCRYPT_NONCE_SIZE);
|
||||
return 0;
|
||||
#else
|
||||
addr = ENCRYPT_TMP_SECRET_OFFSET + WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
||||
addr_align = addr & (~(WOLFBOOT_SECTOR_SIZE - 1));
|
||||
addr_off = addr & (WOLFBOOT_SECTOR_SIZE - 1);
|
||||
#ifdef NVM_FLASH_WRITEONCE
|
||||
sel_sec = nvm_select_fresh_sector(PART_BOOT);
|
||||
addr_align -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
|
||||
#endif
|
||||
hal_flash_unlock();
|
||||
/* casting to unsigned long to abide compilers on 64bit architectures */
|
||||
XMEMCPY(ENCRYPT_CACHE,
|
||||
|
@ -899,6 +959,7 @@ static int RAMFUNCTION hal_set_key(const uint8_t *k, const uint8_t *nonce)
|
|||
ret = hal_flash_write(addr_align, ENCRYPT_CACHE, WOLFBOOT_SECTOR_SIZE);
|
||||
hal_flash_lock();
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
int RAMFUNCTION wolfBoot_set_encrypt_key(const uint8_t *key,
|
||||
|
@ -910,20 +971,28 @@ int RAMFUNCTION wolfBoot_set_encrypt_key(const uint8_t *key,
|
|||
|
||||
int RAMFUNCTION wolfBoot_get_encrypt_key(uint8_t *k, uint8_t *nonce)
|
||||
{
|
||||
#if defined(MMU)
|
||||
XMEMCPY(k, ENCRYPT_KEY, ENCRYPT_KEY_SIZE);
|
||||
XMEMCPY(nonce, ENCRYPT_KEY + ENCRYPT_KEY_SIZE, ENCRYPT_NONCE_SIZE);
|
||||
#else
|
||||
uint8_t *mem = (uint8_t *)(ENCRYPT_TMP_SECRET_OFFSET +
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS);
|
||||
int sel_sec = 0;
|
||||
#ifdef NVM_FLASH_WRITEONCE
|
||||
#ifdef NVM_FLASH_WRITEONCE
|
||||
sel_sec = nvm_select_fresh_sector(PART_BOOT);
|
||||
mem -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
|
||||
#endif
|
||||
#endif
|
||||
XMEMCPY(k, mem, ENCRYPT_KEY_SIZE);
|
||||
XMEMCPY(nonce, mem + ENCRYPT_KEY_SIZE, ENCRYPT_NONCE_SIZE);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RAMFUNCTION wolfBoot_erase_encrypt_key(void)
|
||||
{
|
||||
#if defined(MMU)
|
||||
ForceZero(ENCRYPT_KEY, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE);
|
||||
#else
|
||||
uint8_t ff[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE];
|
||||
uint8_t *mem = (uint8_t *)ENCRYPT_TMP_SECRET_OFFSET +
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
||||
|
@ -935,13 +1004,12 @@ int RAMFUNCTION wolfBoot_erase_encrypt_key(void)
|
|||
XMEMSET(ff, 0xFF, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE);
|
||||
if (XMEMCMP(mem, ff, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE) != 0)
|
||||
hal_set_key(ff, ff + ENCRYPT_KEY_SIZE);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __WOLFBOOT
|
||||
|
||||
static int encrypt_initialized = 0;
|
||||
static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE];
|
||||
|
||||
#ifdef ENCRYPT_WITH_CHACHA
|
||||
|
||||
|
@ -949,8 +1017,12 @@ ChaCha chacha;
|
|||
|
||||
int RAMFUNCTION chacha_init(void)
|
||||
{
|
||||
#if defined(MMU)
|
||||
uint8_t *key = ENCRYPT_KEY;
|
||||
#else
|
||||
uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS +
|
||||
ENCRYPT_TMP_SECRET_OFFSET);
|
||||
#endif
|
||||
uint8_t ff[ENCRYPT_KEY_SIZE];
|
||||
uint8_t *stored_nonce = key + ENCRYPT_KEY_SIZE;
|
||||
|
||||
|
@ -976,8 +1048,12 @@ Aes aes_dec, aes_enc;
|
|||
|
||||
int aes_init(void)
|
||||
{
|
||||
#if defined(MMU)
|
||||
uint8_t *key = ENCRYPT_KEY;
|
||||
#else
|
||||
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_BLOCK_SIZE];
|
||||
uint8_t *stored_nonce = key + ENCRYPT_KEY_SIZE;
|
||||
|
@ -1037,6 +1113,7 @@ void aes_set_iv(uint8_t *nonce, uint32_t iv_ctr)
|
|||
|
||||
static uint8_t RAMFUNCTION part_address(uintptr_t a)
|
||||
{
|
||||
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
||||
if ( 1 &&
|
||||
#if WOLFBOOT_PARTITION_UPDATE_ADDRESS != 0
|
||||
(a >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) &&
|
||||
|
@ -1049,9 +1126,11 @@ static uint8_t RAMFUNCTION part_address(uintptr_t a)
|
|||
#endif
|
||||
(a < WOLFBOOT_PARTITION_SWAP_ADDRESS + WOLFBOOT_SECTOR_SIZE))
|
||||
return PART_SWAP;
|
||||
#endif
|
||||
return PART_NONE;
|
||||
}
|
||||
|
||||
#ifdef EXT_FLASH
|
||||
int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
|
||||
{
|
||||
uint8_t block[ENCRYPT_BLOCK_SIZE];
|
||||
|
@ -1121,6 +1200,10 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
|
|||
uint32_t row_address = address, row_offset, iv_counter = 0;
|
||||
int sz = len, i, step;
|
||||
uint8_t part;
|
||||
uintptr_t base_address;
|
||||
|
||||
(void)base_address;
|
||||
(void)part;
|
||||
|
||||
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
|
||||
if (row_offset != 0) {
|
||||
|
@ -1153,7 +1236,6 @@ 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;
|
||||
|
@ -1191,6 +1273,39 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
|
|||
}
|
||||
return len;
|
||||
}
|
||||
#endif
|
||||
#endif /* EXT_FLASH */
|
||||
#endif /* __WOLFBOOT */
|
||||
|
||||
#if defined(MMU)
|
||||
int wolfBoot_ram_decrypt(uint8_t *src, uint8_t *dst)
|
||||
{
|
||||
uint8_t block[ENCRYPT_BLOCK_SIZE];
|
||||
uint8_t dec_block[ENCRYPT_BLOCK_SIZE];
|
||||
uint8_t *row_address = src;
|
||||
uint32_t dst_offset = 0, iv_counter = 0;
|
||||
uint32_t magic, len;
|
||||
|
||||
|
||||
if (!encrypt_initialized) {
|
||||
if (crypto_init() < 0)
|
||||
return -1;
|
||||
}
|
||||
/* Attempt to decrypt firmware header */
|
||||
|
||||
if (decrypt_header(src) != 0)
|
||||
return -1;
|
||||
len = *((uint32_t*)(dec_hdr + sizeof(uint32_t)));
|
||||
|
||||
/* decrypt content */
|
||||
while (dst_offset < (len + IMAGE_HEADER_SIZE)) {
|
||||
crypto_set_iv(encrypt_iv_nonce, iv_counter);
|
||||
crypto_decrypt(dec_block, row_address, ENCRYPT_BLOCK_SIZE);
|
||||
XMEMCPY(dst + dst_offset, dec_block, ENCRYPT_BLOCK_SIZE);
|
||||
row_address += ENCRYPT_BLOCK_SIZE;
|
||||
dst_offset += ENCRYPT_BLOCK_SIZE;
|
||||
iv_counter++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* EXT_ENCRYPTED */
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
extern void hal_flash_dualbank_swap(void);
|
||||
extern int wolfBoot_get_dts_size(void *dts_addr);
|
||||
|
||||
extern uint32_t kernel_load_addr;
|
||||
extern uint32_t dts_load_addr;
|
||||
|
||||
void RAMFUNCTION wolfBoot_start(void)
|
||||
{
|
||||
|
@ -40,51 +42,66 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
struct wolfBoot_image os_image;
|
||||
uint8_t *image_ptr;
|
||||
uint8_t p_state;
|
||||
uint32_t *load_address;
|
||||
uint32_t *load_address = NULL;
|
||||
uint32_t *source_address = NULL;
|
||||
uint8_t *dts_buf = NULL;
|
||||
uint32_t dts_size = 0;
|
||||
|
||||
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
||||
active = wolfBoot_dualboot_candidate();
|
||||
if (active == PART_BOOT)
|
||||
load_address = (uint32_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
||||
else
|
||||
load_address = (uint32_t*)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
|
||||
#else
|
||||
active = wolfBoot_dualboot_candidate_addr((void**)&load_address);
|
||||
#endif
|
||||
|
||||
wolfBoot_printf("Part: Active %d, Address %x\n", active, load_address);
|
||||
|
||||
if (active < 0) { /* panic if no images available */
|
||||
wolfBoot_panic();
|
||||
}
|
||||
|
||||
memset(&os_image, 0, sizeof(struct wolfBoot_image));
|
||||
for (;;) {
|
||||
if (((ret = wolfBoot_open_image_address(&os_image, (uint8_t*)load_address)) < 0) ||
|
||||
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
||||
active = wolfBoot_dualboot_candidate();
|
||||
if (active == PART_BOOT)
|
||||
source_address = (uint32_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
||||
else
|
||||
source_address = (uint32_t*)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
|
||||
#else
|
||||
active = wolfBoot_dualboot_candidate_addr((void**)&source_address);
|
||||
#endif
|
||||
|
||||
wolfBoot_printf("Part: Active %d, Address %x\n", active, load_address);
|
||||
if (active < 0) { /* panic if no images available */
|
||||
wolfBoot_panic();
|
||||
}
|
||||
#if defined (EXT_ENCRYPTED)
|
||||
load_address = (uint32_t *)(WOLFBOOT_LOAD_ADDRESS - IMAGE_HEADER_SIZE);
|
||||
if (wolfBoot_ram_decrypt((uint8_t *)source_address, (uint8_t *)load_address) != 0) {
|
||||
goto backup_on_failure;
|
||||
}
|
||||
#else
|
||||
load_address = source_address;
|
||||
#endif
|
||||
#if defined (WOLFBOOT_FIXED_PARTITIONS)
|
||||
ret = wolfBoot_open_image(&os_image, active);
|
||||
#else
|
||||
ret = wolfBoot_open_image_address(&os_image, (uint8_t*)load_address);
|
||||
#endif
|
||||
if ( (ret < 0) ||
|
||||
((ret = wolfBoot_verify_integrity(&os_image) < 0)) ||
|
||||
((ret = wolfBoot_verify_authenticity(&os_image)) < 0)) {
|
||||
goto backup_on_failure;
|
||||
|
||||
wolfBoot_printf("Failure %d: Part %d, Hdr %d, Hash %d, Sig %d\n", ret,
|
||||
active, os_image.hdr_ok, os_image.sha_ok, os_image.signature_ok);
|
||||
|
||||
/* panic if authentication fails and no backup */
|
||||
if (!wolfBoot_fallback_is_possible())
|
||||
wolfBoot_panic();
|
||||
else {
|
||||
/* Invalidate failing image and switch to the
|
||||
* other partition
|
||||
*/
|
||||
active ^= 1;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* Success */
|
||||
break;
|
||||
}
|
||||
backup_on_failure:
|
||||
wolfBoot_printf("Failure %d: Part %d, Hdr %d, Hash %d, Sig %d\n", ret,
|
||||
active, os_image.hdr_ok, os_image.sha_ok, os_image.signature_ok);
|
||||
/* panic if authentication fails and no backup */
|
||||
if (!wolfBoot_fallback_is_possible())
|
||||
wolfBoot_panic();
|
||||
else {
|
||||
/* Invalidate failing image and switch to the
|
||||
* other partition
|
||||
*/
|
||||
active ^= 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
wolfBoot_printf("Firmware Valid\n");
|
||||
|
||||
/* First time we boot this update, set to TESTING to await
|
||||
* confirmation from the system
|
||||
*/
|
||||
|
@ -116,7 +133,7 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
wolfBoot_printf("Loading %d bytes to RAM at %08lx\n",
|
||||
os_image.fw_size, WOLFBOOT_LOAD_ADDRESS);
|
||||
|
||||
ext_flash_read((uintptr_t)os_image.fw_base,
|
||||
ext_flash_check_read((uintptr_t)os_image.fw_base,
|
||||
(uint8_t*)WOLFBOOT_LOAD_ADDRESS,
|
||||
os_image.fw_size);
|
||||
}
|
||||
|
@ -129,7 +146,7 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
|
||||
wolfBoot_printf("Loading DTS (size %lu) to RAM at %08lx\n",
|
||||
dts_size, dts_buf);
|
||||
ext_flash_read((uintptr_t)os_image.fw_base,
|
||||
ext_flash_check_read((uintptr_t)os_image.fw_base,
|
||||
(uint8_t*)dts_buf, dts_size);
|
||||
}
|
||||
#endif /* MMU */
|
||||
|
@ -144,7 +161,9 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
#pragma GCC diagnostic ignored "-Wnonnull"
|
||||
#endif
|
||||
|
||||
#ifndef EXT_ENCRYPTED
|
||||
memcpy((void*)WOLFBOOT_LOAD_ADDRESS, os_image.fw_base, os_image.fw_size);
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
Loading…
Reference in New Issue