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 Zynq UltraScale
|
||||||
|
|
||||||
Xilinx UltraScale+ ZCU102 (Aarch64)
|
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."
|
# error "wolfBoot raspi3 HAL: wrong architecture selected. Please compile with ARCH=AARCH64."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TEST_ENCRYPT
|
||||||
|
|
||||||
|
|
||||||
#define CORTEXA53_0_CPU_CLK_FREQ_HZ 1099989014
|
#define CORTEXA53_0_CPU_CLK_FREQ_HZ 1099989014
|
||||||
#define CORTEXA53_0_TIMESTAMP_CLK_FREQ 99998999
|
#define CORTEXA53_0_TIMESTAMP_CLK_FREQ 99998999
|
||||||
|
|
||||||
/* Fixed addresses */
|
/* Fixed addresses */
|
||||||
static const void* kernel_addr = (void*)0x0140000;
|
extern void *kernel_addr, *update_addr, *dts_addr;
|
||||||
static const void* update_addr = (void*)0x1140000;
|
|
||||||
static const void* dts_addr = (void*)0x00a0000;
|
|
||||||
|
|
||||||
void* hal_get_primary_address(void)
|
void* hal_get_primary_address(void)
|
||||||
{
|
{
|
||||||
return (void*)kernel_addr;
|
return (void*)&kernel_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* hal_get_update_address(void)
|
void* hal_get_update_address(void)
|
||||||
{
|
{
|
||||||
return (void*)update_addr;
|
return (void*)&update_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* hal_get_dts_address(void)
|
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)
|
void* hal_get_dts_update_address(void)
|
||||||
{
|
{
|
||||||
return NULL; /* Not yet supported */
|
return NULL; /* Not yet supported */
|
||||||
|
@ -71,6 +101,12 @@ void zynq_init(uint32_t cpu_clock)
|
||||||
/* public HAL functions */
|
/* public HAL functions */
|
||||||
void hal_init(void)
|
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)
|
void hal_prepare_boot(void)
|
||||||
|
|
|
@ -53,3 +53,12 @@ SECTIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
END_STACK = _start_text;
|
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 */
|
#endif /* defined WOLFBOOT */
|
||||||
|
|
||||||
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
|
||||||
#define PART_BOOT 0
|
#define PART_BOOT 0
|
||||||
#define PART_UPDATE 1
|
#define PART_UPDATE 1
|
||||||
#define PART_SWAP 2
|
#define PART_SWAP 2
|
||||||
|
@ -203,7 +202,6 @@ extern "C" {
|
||||||
#define PART_DTS (0x10)
|
#define PART_DTS (0x10)
|
||||||
#define PART_DTS_BOOT (PART_DTS | PART_BOOT)
|
#define PART_DTS_BOOT (PART_DTS | PART_BOOT)
|
||||||
#define PART_DTS_UPDATE (PART_DTS | PART_UPDATE)
|
#define PART_DTS_UPDATE (PART_DTS | PART_UPDATE)
|
||||||
#endif /* WOLFBOOT_FIXED_PARTITIONS */
|
|
||||||
|
|
||||||
#ifndef WOLFBOOT_FLAGS_INVERT
|
#ifndef WOLFBOOT_FLAGS_INVERT
|
||||||
#define IMG_STATE_NEW 0xFF
|
#define IMG_STATE_NEW 0xFF
|
||||||
|
@ -265,6 +263,8 @@ int wolfBoot_dualboot_candidate_addr(void**);
|
||||||
# error "Encryption ON, but no encryption algorithm selected."
|
# error "Encryption ON, but no encryption algorithm selected."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int wolfBoot_ram_decrypt(uint8_t *src, uint8_t *dst);
|
||||||
|
|
||||||
#endif /* EXT_ENCRYPTED */
|
#endif /* EXT_ENCRYPTED */
|
||||||
|
|
||||||
#ifdef DELTA_UPDATES
|
#ifdef DELTA_UPDATES
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include <stddef.h> /* for size_t */
|
#include <stddef.h> /* for size_t */
|
||||||
|
|
||||||
#if defined(EXT_ENCRYPTED)
|
#if defined(EXT_ENCRYPTED)
|
||||||
|
static int encrypt_initialized = 0;
|
||||||
|
static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE];
|
||||||
#if defined(__WOLFBOOT)
|
#if defined(__WOLFBOOT)
|
||||||
#include "encrypt.h"
|
#include "encrypt.h"
|
||||||
#else
|
#else
|
||||||
|
@ -48,6 +50,9 @@
|
||||||
#define XMEMCPY memcpy
|
#define XMEMCPY memcpy
|
||||||
#define XMEMCMP memcmp
|
#define XMEMCMP memcmp
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(EXT_FLASH) && defined(EXT_ENCRYPTED)
|
||||||
#define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - \
|
#define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - \
|
||||||
(TRAILER_SKIP + ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE))
|
(TRAILER_SKIP + ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE))
|
||||||
#define TRAILER_OVERHEAD (4 + 1 + (WOLFBOOT_PARTITION_SIZE / \
|
#define TRAILER_OVERHEAD (4 + 1 + (WOLFBOOT_PARTITION_SIZE / \
|
||||||
|
@ -56,7 +61,7 @@
|
||||||
#define START_FLAGS_OFFSET (ENCRYPT_TMP_SECRET_OFFSET - TRAILER_OVERHEAD)
|
#define START_FLAGS_OFFSET (ENCRYPT_TMP_SECRET_OFFSET - TRAILER_OVERHEAD)
|
||||||
#else
|
#else
|
||||||
#define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - (TRAILER_SKIP))
|
#define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - (TRAILER_SKIP))
|
||||||
#endif
|
#endif /* EXT_FLASH && EXT_ENCRYPTED */
|
||||||
|
|
||||||
#if !defined(__WOLFBOOT)
|
#if !defined(__WOLFBOOT)
|
||||||
#define XMEMSET memset
|
#define XMEMSET memset
|
||||||
|
@ -676,15 +681,44 @@ int wolfBoot_get_delta_info(uint8_t part, int inverse, uint32_t **img_offset,
|
||||||
}
|
}
|
||||||
#endif
|
#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 wolfBoot_get_blob_version(uint8_t *blob)
|
||||||
{
|
{
|
||||||
uint32_t *volatile version_field = NULL;
|
uint32_t *volatile version_field = NULL;
|
||||||
uint32_t *magic = NULL;
|
uint32_t *magic = NULL;
|
||||||
|
uint8_t *img_bin = blob;
|
||||||
magic = (uint32_t *)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)
|
if (*magic != WOLFBOOT_MAGIC)
|
||||||
return 0;
|
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)
|
(void *)&version_field) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (version_field)
|
if (version_field)
|
||||||
|
@ -696,10 +730,18 @@ uint32_t wolfBoot_get_blob_type(uint8_t *blob)
|
||||||
{
|
{
|
||||||
uint32_t *volatile type_field = NULL;
|
uint32_t *volatile type_field = NULL;
|
||||||
uint32_t *magic = 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)
|
if (*magic != WOLFBOOT_MAGIC)
|
||||||
return 0;
|
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)
|
(void *)&type_field) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (type_field)
|
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 *volatile delta_base = NULL;
|
||||||
uint32_t *magic = 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)
|
if (*magic != WOLFBOOT_MAGIC)
|
||||||
return 0;
|
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)
|
(void *)&delta_base) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (delta_base)
|
if (delta_base)
|
||||||
|
@ -862,8 +912,8 @@ int wolfBoot_fallback_is_possible(void)
|
||||||
|
|
||||||
#ifdef EXT_ENCRYPTED
|
#ifdef EXT_ENCRYPTED
|
||||||
#include "encrypt.h"
|
#include "encrypt.h"
|
||||||
#ifndef EXT_FLASH
|
#if !defined(EXT_FLASH) && !defined(MMU)
|
||||||
#error option EXT_ENCRYPTED requires EXT_FLASH
|
#error option EXT_ENCRYPTED requires EXT_FLASH or MMU mode
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -874,17 +924,27 @@ int wolfBoot_fallback_is_possible(void)
|
||||||
static uint8_t ENCRYPT_CACHE[NVM_CACHE_SIZE] __attribute__((aligned(32)));
|
static uint8_t ENCRYPT_CACHE[NVM_CACHE_SIZE] __attribute__((aligned(32)));
|
||||||
#endif
|
#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)
|
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, addr_align, addr_off;
|
||||||
uint32_t addr_align = addr & (~(WOLFBOOT_SECTOR_SIZE - 1));
|
|
||||||
uint32_t addr_off = addr & (WOLFBOOT_SECTOR_SIZE - 1);
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int sel_sec = 0;
|
int sel_sec = 0;
|
||||||
#ifdef NVM_FLASH_WRITEONCE
|
#ifdef MMU
|
||||||
sel_sec = nvm_select_fresh_sector(PART_BOOT);
|
XMEMCPY(ENCRYPT_KEY, k, ENCRYPT_KEY_SIZE);
|
||||||
addr_align -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
|
XMEMCPY(ENCRYPT_KEY + ENCRYPT_KEY_SIZE, nonce, ENCRYPT_NONCE_SIZE);
|
||||||
#endif
|
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();
|
hal_flash_unlock();
|
||||||
/* casting to unsigned long to abide compilers on 64bit architectures */
|
/* casting to unsigned long to abide compilers on 64bit architectures */
|
||||||
XMEMCPY(ENCRYPT_CACHE,
|
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);
|
ret = hal_flash_write(addr_align, ENCRYPT_CACHE, WOLFBOOT_SECTOR_SIZE);
|
||||||
hal_flash_lock();
|
hal_flash_lock();
|
||||||
return ret;
|
return ret;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int RAMFUNCTION wolfBoot_set_encrypt_key(const uint8_t *key,
|
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)
|
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 +
|
uint8_t *mem = (uint8_t *)(ENCRYPT_TMP_SECRET_OFFSET +
|
||||||
WOLFBOOT_PARTITION_BOOT_ADDRESS);
|
WOLFBOOT_PARTITION_BOOT_ADDRESS);
|
||||||
int sel_sec = 0;
|
int sel_sec = 0;
|
||||||
#ifdef NVM_FLASH_WRITEONCE
|
#ifdef NVM_FLASH_WRITEONCE
|
||||||
sel_sec = nvm_select_fresh_sector(PART_BOOT);
|
sel_sec = nvm_select_fresh_sector(PART_BOOT);
|
||||||
mem -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
|
mem -= (sel_sec * WOLFBOOT_SECTOR_SIZE);
|
||||||
#endif
|
#endif
|
||||||
XMEMCPY(k, mem, ENCRYPT_KEY_SIZE);
|
XMEMCPY(k, mem, ENCRYPT_KEY_SIZE);
|
||||||
XMEMCPY(nonce, mem + ENCRYPT_KEY_SIZE, ENCRYPT_NONCE_SIZE);
|
XMEMCPY(nonce, mem + ENCRYPT_KEY_SIZE, ENCRYPT_NONCE_SIZE);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int RAMFUNCTION wolfBoot_erase_encrypt_key(void)
|
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 ff[ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE];
|
||||||
uint8_t *mem = (uint8_t *)ENCRYPT_TMP_SECRET_OFFSET +
|
uint8_t *mem = (uint8_t *)ENCRYPT_TMP_SECRET_OFFSET +
|
||||||
WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
||||||
|
@ -935,13 +1004,12 @@ int RAMFUNCTION wolfBoot_erase_encrypt_key(void)
|
||||||
XMEMSET(ff, 0xFF, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE);
|
XMEMSET(ff, 0xFF, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE);
|
||||||
if (XMEMCMP(mem, ff, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE) != 0)
|
if (XMEMCMP(mem, ff, ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE) != 0)
|
||||||
hal_set_key(ff, ff + ENCRYPT_KEY_SIZE);
|
hal_set_key(ff, ff + ENCRYPT_KEY_SIZE);
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __WOLFBOOT
|
#ifdef __WOLFBOOT
|
||||||
|
|
||||||
static int encrypt_initialized = 0;
|
|
||||||
static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE];
|
|
||||||
|
|
||||||
#ifdef ENCRYPT_WITH_CHACHA
|
#ifdef ENCRYPT_WITH_CHACHA
|
||||||
|
|
||||||
|
@ -949,8 +1017,12 @@ ChaCha chacha;
|
||||||
|
|
||||||
int RAMFUNCTION chacha_init(void)
|
int RAMFUNCTION chacha_init(void)
|
||||||
{
|
{
|
||||||
|
#if defined(MMU)
|
||||||
|
uint8_t *key = ENCRYPT_KEY;
|
||||||
|
#else
|
||||||
uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS +
|
uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS +
|
||||||
ENCRYPT_TMP_SECRET_OFFSET);
|
ENCRYPT_TMP_SECRET_OFFSET);
|
||||||
|
#endif
|
||||||
uint8_t ff[ENCRYPT_KEY_SIZE];
|
uint8_t ff[ENCRYPT_KEY_SIZE];
|
||||||
uint8_t *stored_nonce = key + ENCRYPT_KEY_SIZE;
|
uint8_t *stored_nonce = key + ENCRYPT_KEY_SIZE;
|
||||||
|
|
||||||
|
@ -976,8 +1048,12 @@ Aes aes_dec, aes_enc;
|
||||||
|
|
||||||
int aes_init(void)
|
int aes_init(void)
|
||||||
{
|
{
|
||||||
|
#if defined(MMU)
|
||||||
|
uint8_t *key = ENCRYPT_KEY;
|
||||||
|
#else
|
||||||
uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS +
|
uint8_t *key = (uint8_t *)(WOLFBOOT_PARTITION_BOOT_ADDRESS +
|
||||||
ENCRYPT_TMP_SECRET_OFFSET);
|
ENCRYPT_TMP_SECRET_OFFSET);
|
||||||
|
#endif
|
||||||
uint8_t ff[ENCRYPT_KEY_SIZE];
|
uint8_t ff[ENCRYPT_KEY_SIZE];
|
||||||
uint8_t iv_buf[ENCRYPT_BLOCK_SIZE];
|
uint8_t iv_buf[ENCRYPT_BLOCK_SIZE];
|
||||||
uint8_t *stored_nonce = key + ENCRYPT_KEY_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)
|
static uint8_t RAMFUNCTION part_address(uintptr_t a)
|
||||||
{
|
{
|
||||||
|
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
||||||
if ( 1 &&
|
if ( 1 &&
|
||||||
#if WOLFBOOT_PARTITION_UPDATE_ADDRESS != 0
|
#if WOLFBOOT_PARTITION_UPDATE_ADDRESS != 0
|
||||||
(a >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) &&
|
(a >= WOLFBOOT_PARTITION_UPDATE_ADDRESS) &&
|
||||||
|
@ -1049,9 +1126,11 @@ static uint8_t RAMFUNCTION part_address(uintptr_t a)
|
||||||
#endif
|
#endif
|
||||||
(a < WOLFBOOT_PARTITION_SWAP_ADDRESS + WOLFBOOT_SECTOR_SIZE))
|
(a < WOLFBOOT_PARTITION_SWAP_ADDRESS + WOLFBOOT_SECTOR_SIZE))
|
||||||
return PART_SWAP;
|
return PART_SWAP;
|
||||||
|
#endif
|
||||||
return PART_NONE;
|
return PART_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef EXT_FLASH
|
||||||
int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
|
int RAMFUNCTION ext_flash_encrypt_write(uintptr_t address, const uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
uint8_t block[ENCRYPT_BLOCK_SIZE];
|
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;
|
uint32_t row_address = address, row_offset, iv_counter = 0;
|
||||||
int sz = len, i, step;
|
int sz = len, i, step;
|
||||||
uint8_t part;
|
uint8_t part;
|
||||||
|
uintptr_t base_address;
|
||||||
|
|
||||||
|
(void)base_address;
|
||||||
|
(void)part;
|
||||||
|
|
||||||
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
|
row_offset = address & (ENCRYPT_BLOCK_SIZE - 1);
|
||||||
if (row_offset != 0) {
|
if (row_offset != 0) {
|
||||||
|
@ -1153,7 +1236,6 @@ int RAMFUNCTION ext_flash_decrypt_read(uintptr_t address, uint8_t *data, int len
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decrypt blocks */
|
/* decrypt blocks */
|
||||||
if (sz > len) {
|
if (sz > len) {
|
||||||
step = ENCRYPT_BLOCK_SIZE - row_offset;
|
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;
|
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 */
|
#endif /* EXT_ENCRYPTED */
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
extern void hal_flash_dualbank_swap(void);
|
extern void hal_flash_dualbank_swap(void);
|
||||||
extern int wolfBoot_get_dts_size(void *dts_addr);
|
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)
|
void RAMFUNCTION wolfBoot_start(void)
|
||||||
{
|
{
|
||||||
|
@ -40,51 +42,66 @@ void RAMFUNCTION wolfBoot_start(void)
|
||||||
struct wolfBoot_image os_image;
|
struct wolfBoot_image os_image;
|
||||||
uint8_t *image_ptr;
|
uint8_t *image_ptr;
|
||||||
uint8_t p_state;
|
uint8_t p_state;
|
||||||
uint32_t *load_address;
|
uint32_t *load_address = NULL;
|
||||||
|
uint32_t *source_address = NULL;
|
||||||
uint8_t *dts_buf = NULL;
|
uint8_t *dts_buf = NULL;
|
||||||
uint32_t dts_size = 0;
|
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 (;;) {
|
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_integrity(&os_image) < 0)) ||
|
||||||
((ret = wolfBoot_verify_authenticity(&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 {
|
} else {
|
||||||
|
/* Success */
|
||||||
break;
|
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");
|
wolfBoot_printf("Firmware Valid\n");
|
||||||
|
|
||||||
/* First time we boot this update, set to TESTING to await
|
/* First time we boot this update, set to TESTING to await
|
||||||
* confirmation from the system
|
* confirmation from the system
|
||||||
*/
|
*/
|
||||||
|
@ -116,7 +133,7 @@ void RAMFUNCTION wolfBoot_start(void)
|
||||||
wolfBoot_printf("Loading %d bytes to RAM at %08lx\n",
|
wolfBoot_printf("Loading %d bytes to RAM at %08lx\n",
|
||||||
os_image.fw_size, WOLFBOOT_LOAD_ADDRESS);
|
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,
|
(uint8_t*)WOLFBOOT_LOAD_ADDRESS,
|
||||||
os_image.fw_size);
|
os_image.fw_size);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +146,7 @@ void RAMFUNCTION wolfBoot_start(void)
|
||||||
|
|
||||||
wolfBoot_printf("Loading DTS (size %lu) to RAM at %08lx\n",
|
wolfBoot_printf("Loading DTS (size %lu) to RAM at %08lx\n",
|
||||||
dts_size, dts_buf);
|
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);
|
(uint8_t*)dts_buf, dts_size);
|
||||||
}
|
}
|
||||||
#endif /* MMU */
|
#endif /* MMU */
|
||||||
|
@ -144,7 +161,9 @@ void RAMFUNCTION wolfBoot_start(void)
|
||||||
#pragma GCC diagnostic ignored "-Wnonnull"
|
#pragma GCC diagnostic ignored "-Wnonnull"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EXT_ENCRYPTED
|
||||||
memcpy((void*)WOLFBOOT_LOAD_ADDRESS, os_image.fw_base, os_image.fw_size);
|
memcpy((void*)WOLFBOOT_LOAD_ADDRESS, os_image.fw_base, os_image.fw_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
Loading…
Reference in New Issue