boot: boot_serial: Fix issue with encrypted second slot images
Fixes issues whereby encrypted images were not properly listed due to not treating them as encrypted, also removes a piece of wrong hack code that would never run as the primary slot cannot be encrypted. Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
This commit is contained in:
parent
25d2f2cfe0
commit
c9fa60886b
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023 Nordic Semiconductor ASA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef H_BOOT_SERIAL_ENCRYPTION_
|
||||||
|
#define H_BOOT_SERIAL_ENCRYPTION_
|
||||||
|
#include "bootutil/fault_injection_hardening.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate hash of a primary boot image doing on the fly decryption as well
|
||||||
|
*
|
||||||
|
* @param[in] fa_p flash area pointer
|
||||||
|
* @param[in] hdr boot image header pointer
|
||||||
|
* @param[in] buf buffer which is used for validating data
|
||||||
|
* @param[in] buf_size size of input buffer
|
||||||
|
*
|
||||||
|
* @return FIH_SUCCESS on success, error code otherwise
|
||||||
|
*/
|
||||||
|
fih_ret
|
||||||
|
boot_image_validate_encrypted(const struct flash_area *fa_p,
|
||||||
|
struct image_header *hdr, uint8_t *buf,
|
||||||
|
uint16_t buf_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an encrypted firmware in the main flash.
|
||||||
|
* This will decrypt the image inplace
|
||||||
|
*/
|
||||||
|
int boot_handle_enc_fw(const struct flash_area *flash_area);
|
||||||
|
|
||||||
|
#endif
|
|
@ -73,7 +73,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MCUBOOT_ENC_IMAGES
|
#ifdef MCUBOOT_ENC_IMAGES
|
||||||
#include "single_loader.h"
|
#include "boot_serial/boot_serial_encryption.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "bootutil/boot_hooks.h"
|
#include "bootutil/boot_hooks.h"
|
||||||
|
@ -293,18 +293,16 @@ bs_list(char *buf, int len)
|
||||||
if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
|
if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
|
||||||
{
|
{
|
||||||
#ifdef MCUBOOT_ENC_IMAGES
|
#ifdef MCUBOOT_ENC_IMAGES
|
||||||
if (slot == 0 && IS_ENCRYPTED(&hdr)) {
|
if (IS_ENCRYPTED(&hdr)) {
|
||||||
/* Clear the encrypted flag we didn't supply a key
|
FIH_CALL(boot_image_validate_encrypted, fih_rc, fap,
|
||||||
* This flag could be set if there was a decryption in place
|
&hdr, tmpbuf, sizeof(tmpbuf));
|
||||||
* performed before. We will try to validate the image without
|
} else {
|
||||||
* decryption by clearing the flag in the heder. If
|
#endif
|
||||||
* still encrypted the validation will fail.
|
FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr,
|
||||||
*/
|
fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL);
|
||||||
hdr.ih_flags &= ~(ENCRYPTIONFLAGS);
|
#ifdef MCUBOOT_ENC_IMAGES
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
|
|
||||||
NULL, 0, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,8 +481,17 @@ bs_set(char *buf, int len)
|
||||||
fih_rc, image_index, 1);
|
fih_rc, image_index, 1);
|
||||||
if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
|
if (FIH_EQ(fih_rc, FIH_BOOT_HOOK_REGULAR))
|
||||||
{
|
{
|
||||||
FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap,
|
#ifdef MCUBOOT_ENC_IMAGES
|
||||||
tmpbuf, sizeof(tmpbuf), NULL, 0, NULL);
|
if (IS_ENCRYPTED(&hdr)) {
|
||||||
|
FIH_CALL(boot_image_validate_encrypted, fih_rc, fap,
|
||||||
|
&hdr, tmpbuf, sizeof(tmpbuf));
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr,
|
||||||
|
fap, tmpbuf, sizeof(tmpbuf), NULL, 0, NULL);
|
||||||
|
#ifdef MCUBOOT_ENC_IMAGES
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
||||||
|
@ -862,14 +869,23 @@ out:
|
||||||
zcbor_map_end_encode(cbor_state, 10);
|
zcbor_map_end_encode(cbor_state, 10);
|
||||||
|
|
||||||
boot_serial_output();
|
boot_serial_output();
|
||||||
flash_area_close(fap);
|
|
||||||
|
|
||||||
#ifdef MCUBOOT_ENC_IMAGES
|
#ifdef MCUBOOT_ENC_IMAGES
|
||||||
if (curr_off == img_size) {
|
/* Check if this upload was for the primary slot */
|
||||||
/* Last sector received, now start a decryption on the image if it is encrypted*/
|
#if !defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
|
||||||
rc = boot_handle_enc_fw();
|
if (flash_area_id_from_multi_image_slot(img_num, 0) == FLASH_AREA_IMAGE_PRIMARY(0))
|
||||||
|
#else
|
||||||
|
if (flash_area_id_from_direct_image(img_num) == FLASH_AREA_IMAGE_PRIMARY(0))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (curr_off == img_size) {
|
||||||
|
/* Last sector received, now start a decryption on the image if it is encrypted */
|
||||||
|
rc = boot_handle_enc_fw(fap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif //#ifdef MCUBOOT_ENC_IMAGES
|
#endif
|
||||||
|
|
||||||
|
flash_area_close(fap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MCUBOOT_BOOT_MGMT_ECHO
|
#ifdef MCUBOOT_BOOT_MGMT_ECHO
|
||||||
|
|
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-2023 Nordic Semiconductor ASA
|
||||||
|
* Copyright (c) 2020 Arm Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include "bootutil/image.h"
|
||||||
|
#include <../src/bootutil_priv.h>
|
||||||
|
#include "bootutil/bootutil_log.h"
|
||||||
|
#include "bootutil/bootutil_public.h"
|
||||||
|
#include "bootutil/fault_injection_hardening.h"
|
||||||
|
#include "bootutil/enc_key.h"
|
||||||
|
|
||||||
|
#include "mcuboot_config/mcuboot_config.h"
|
||||||
|
|
||||||
|
#ifdef MCUBOOT_ENC_IMAGES
|
||||||
|
|
||||||
|
BOOT_LOG_MODULE_DECLARE(serial_encryption);
|
||||||
|
|
||||||
|
fih_ret
|
||||||
|
boot_image_validate_encrypted(const struct flash_area *fa_p,
|
||||||
|
struct image_header *hdr, uint8_t *buf,
|
||||||
|
uint16_t buf_size)
|
||||||
|
{
|
||||||
|
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||||
|
|
||||||
|
struct boot_loader_state boot_data;
|
||||||
|
struct boot_loader_state *state = &boot_data;
|
||||||
|
struct boot_status _bs;
|
||||||
|
struct boot_status *bs = &_bs;
|
||||||
|
uint8_t image_index;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
||||||
|
image_index = BOOT_CURR_IMG(state);
|
||||||
|
if(IS_ENCRYPTED(hdr)) {
|
||||||
|
rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs);
|
||||||
|
if (rc < 0) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
rc = flash_area_id_to_multi_image_slot(image_index, flash_area_get_id(fa_p));
|
||||||
|
if (rc < 0) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
rc = boot_enc_set_key(BOOT_CURR_ENC(state), 1, bs);
|
||||||
|
if (rc < 0) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index,
|
||||||
|
hdr, fa_p, buf, buf_size, NULL, 0, NULL);
|
||||||
|
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the total size of the given image. Includes the size of
|
||||||
|
* the TLVs.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
read_image_size(const struct flash_area *fa_p,
|
||||||
|
struct image_header *hdr,
|
||||||
|
uint32_t *size)
|
||||||
|
{
|
||||||
|
struct image_tlv_info info;
|
||||||
|
uint32_t off;
|
||||||
|
uint32_t protect_tlv_size;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
off = BOOT_TLV_OFF(hdr);
|
||||||
|
|
||||||
|
if (flash_area_read(fa_p, off, &info, sizeof(info))) {
|
||||||
|
rc = BOOT_EFLASH;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
protect_tlv_size = hdr->ih_protect_tlv_size;
|
||||||
|
if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
|
||||||
|
if (protect_tlv_size != info.it_tlv_tot) {
|
||||||
|
rc = BOOT_EBADIMAGE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flash_area_read(fa_p, off + info.it_tlv_tot, &info, sizeof(info))) {
|
||||||
|
rc = BOOT_EFLASH;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
} else if (protect_tlv_size != 0) {
|
||||||
|
rc = BOOT_EBADIMAGE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
|
||||||
|
rc = BOOT_EBADIMAGE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = off + protect_tlv_size + info.it_tlv_tot;
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads, decrypts in RAM & write back the decrypted image in the same region
|
||||||
|
* This function is NOT power failsafe since the image is decrypted in the RAM
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* @param flash_area The ID of the source flash area.
|
||||||
|
* @param off_src The offset within the flash area to
|
||||||
|
* copy from.
|
||||||
|
* @param sz The number of bytes to copy. should match erase sector
|
||||||
|
*
|
||||||
|
* @return 0 on success; nonzero on failure.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
decrypt_region_inplace(struct boot_loader_state *state,
|
||||||
|
const struct flash_area *fap,
|
||||||
|
struct image_header *hdr,
|
||||||
|
uint32_t off, uint32_t sz)
|
||||||
|
{
|
||||||
|
uint32_t bytes_copied;
|
||||||
|
int chunk_sz;
|
||||||
|
int rc;
|
||||||
|
uint32_t tlv_off;
|
||||||
|
size_t blk_off;
|
||||||
|
uint16_t idx;
|
||||||
|
uint32_t blk_sz;
|
||||||
|
uint8_t image_index;
|
||||||
|
|
||||||
|
uint8_t buf[sz] __attribute__((aligned));
|
||||||
|
assert(sz <= sizeof buf);
|
||||||
|
|
||||||
|
bytes_copied = 0;
|
||||||
|
while (bytes_copied < sz) {
|
||||||
|
if (sz - bytes_copied > sizeof buf) {
|
||||||
|
chunk_sz = sizeof buf;
|
||||||
|
} else {
|
||||||
|
chunk_sz = sz - bytes_copied;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = flash_area_read(fap, off + bytes_copied, buf, chunk_sz);
|
||||||
|
if (rc != 0) {
|
||||||
|
return BOOT_EFLASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_index = BOOT_CURR_IMG(state);
|
||||||
|
if (IS_ENCRYPTED(hdr)) {
|
||||||
|
blk_sz = chunk_sz;
|
||||||
|
idx = 0;
|
||||||
|
if (off + bytes_copied < hdr->ih_hdr_size) {
|
||||||
|
/* do not decrypt header */
|
||||||
|
if (hdr->ih_hdr_size > (off + bytes_copied + chunk_sz)) {
|
||||||
|
/* all bytes in header, skip decryption */
|
||||||
|
blk_sz = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
blk_sz = off + bytes_copied + chunk_sz - hdr->ih_hdr_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
blk_off = 0;
|
||||||
|
idx = hdr->ih_hdr_size;
|
||||||
|
} else {
|
||||||
|
blk_off = ((off + bytes_copied) - hdr->ih_hdr_size) & 0xf;
|
||||||
|
}
|
||||||
|
tlv_off = BOOT_TLV_OFF(hdr);
|
||||||
|
if (off + bytes_copied + chunk_sz > tlv_off) {
|
||||||
|
/* do not decrypt TLVs */
|
||||||
|
if (off + bytes_copied >= tlv_off) {
|
||||||
|
blk_sz = 0;
|
||||||
|
} else {
|
||||||
|
blk_sz = tlv_off - (off + bytes_copied);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boot_encrypt(BOOT_CURR_ENC(state), image_index, fap,
|
||||||
|
(off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
|
||||||
|
blk_off, &buf[idx]);
|
||||||
|
}
|
||||||
|
rc = flash_area_erase(fap, off + bytes_copied, chunk_sz);
|
||||||
|
if (rc != 0) {
|
||||||
|
return BOOT_EFLASH;
|
||||||
|
}
|
||||||
|
rc = flash_area_write(fap, off + bytes_copied, buf, chunk_sz);
|
||||||
|
if (rc != 0) {
|
||||||
|
return BOOT_EFLASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_copied += chunk_sz;
|
||||||
|
|
||||||
|
MCUBOOT_WATCHDOG_FEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a image was encrypted into the first slot, and decrypt it
|
||||||
|
* in place. this operation is not power failsafe.
|
||||||
|
*
|
||||||
|
* The operation is done by checking the last flash sector, and using it as a
|
||||||
|
* temporarely scratch partition. The
|
||||||
|
*
|
||||||
|
* @param[in] fa_p flash area pointer
|
||||||
|
* @param[in] hdr boot image header pointer
|
||||||
|
*
|
||||||
|
* @return FIH_SUCCESS on success, error code otherwise
|
||||||
|
*/
|
||||||
|
inline static fih_ret
|
||||||
|
decrypt_image_inplace(const struct flash_area *fa_p,
|
||||||
|
struct image_header *hdr)
|
||||||
|
{
|
||||||
|
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||||
|
int rc;
|
||||||
|
struct boot_loader_state boot_data;
|
||||||
|
struct boot_loader_state *state = &boot_data;
|
||||||
|
struct boot_status _bs;
|
||||||
|
struct boot_status *bs = &_bs;
|
||||||
|
size_t size;
|
||||||
|
size_t sect_size;
|
||||||
|
size_t sect_count;
|
||||||
|
size_t sect;
|
||||||
|
uint8_t image_index;
|
||||||
|
struct flash_sector sector;
|
||||||
|
|
||||||
|
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
||||||
|
memset(&_bs, 0, sizeof(struct boot_status));
|
||||||
|
|
||||||
|
/* Get size from last sector to know page/sector erase size */
|
||||||
|
rc = flash_area_get_sector(fa_p, boot_status_off(fa_p), §or);
|
||||||
|
|
||||||
|
|
||||||
|
image_index = BOOT_CURR_IMG(state);
|
||||||
|
|
||||||
|
if(IS_ENCRYPTED(hdr)) {
|
||||||
|
#if 0 //Skip this step?, the image will just not boot if it's not decrypted properly
|
||||||
|
static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
|
||||||
|
/* First check if the encrypted image is a good image before decrypting */
|
||||||
|
FIH_CALL(boot_image_validate_encrypted,fih_rc,fa_p,&_hdr,tmpbuf,BOOT_TMPBUF_SZ);
|
||||||
|
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
||||||
|
/* Load the encryption keys into cache */
|
||||||
|
rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs);
|
||||||
|
if (rc < 0) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Expected encrypted image! */
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t src_size = 0;
|
||||||
|
rc = read_image_size(fa_p,hdr, &src_size);
|
||||||
|
if (rc != 0) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: This assumes every sector has an equal size, should instead use
|
||||||
|
* flash_area_get_sectors() to get the size of each sector and iterate
|
||||||
|
* over it.
|
||||||
|
*/
|
||||||
|
sect_size = sector.fs_size;
|
||||||
|
sect_count = fa_p->fa_size / sect_size;
|
||||||
|
for (sect = 0, size = 0; size < src_size && sect < sect_count; sect++) {
|
||||||
|
rc = decrypt_region_inplace(state, fa_p,hdr, size, sect_size);
|
||||||
|
if (rc != 0) {
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
size += sect_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
fih_rc = FIH_SUCCESS;
|
||||||
|
FIH_RET(fih_rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
boot_handle_enc_fw(const struct flash_area *flash_area)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
struct image_header _hdr = { 0 };
|
||||||
|
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
||||||
|
|
||||||
|
rc = boot_image_load_header(flash_area, &_hdr);
|
||||||
|
if (rc != 0) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ENCRYPTED(&_hdr)) {
|
||||||
|
//encrypted, we need to decrypt in place
|
||||||
|
FIH_CALL(decrypt_image_inplace,fih_rc,flash_area,&_hdr);
|
||||||
|
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -43,6 +43,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <flash_map_backend/flash_map_backend.h>
|
#include <flash_map_backend/flash_map_backend.h>
|
||||||
#include <mcuboot_config/mcuboot_config.h>
|
#include <mcuboot_config/mcuboot_config.h>
|
||||||
|
#include <bootutil/image.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -294,6 +295,18 @@ boot_read_swap_state(const struct flash_area *fa,
|
||||||
int
|
int
|
||||||
boot_set_next(const struct flash_area *fa, bool active, bool confirm);
|
boot_set_next(const struct flash_area *fa, bool active, bool confirm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to load image header from flash; verifies flash header fields.
|
||||||
|
*
|
||||||
|
* @param[in] fa_p flash area pointer
|
||||||
|
* @param[out] hdr buffer for image header
|
||||||
|
*
|
||||||
|
* @return 0 on success, error code otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
boot_image_load_header(const struct flash_area *fa_p,
|
||||||
|
struct image_header *hdr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -643,3 +643,36 @@ boot_set_confirmed(void)
|
||||||
{
|
{
|
||||||
return boot_set_confirmed_multi(0);
|
return boot_set_confirmed_multi(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
boot_image_load_header(const struct flash_area *fa_p,
|
||||||
|
struct image_header *hdr)
|
||||||
|
{
|
||||||
|
uint32_t size;
|
||||||
|
int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr);
|
||||||
|
|
||||||
|
if (rc != 0) {
|
||||||
|
rc = BOOT_EFLASH;
|
||||||
|
BOOT_LOG_ERR("Failed reading image header");
|
||||||
|
return BOOT_EFLASH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr->ih_magic != IMAGE_MAGIC) {
|
||||||
|
BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic);
|
||||||
|
|
||||||
|
return BOOT_EBADIMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) {
|
||||||
|
BOOT_LOG_ERR("Image not bootable");
|
||||||
|
|
||||||
|
return BOOT_EBADIMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
|
||||||
|
size >= flash_area_get_size(fa_p)) {
|
||||||
|
return BOOT_EBADIMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ zephyr_library_sources(
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256)
|
if(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 OR CONFIG_BOOT_ENCRYPT_EC256)
|
||||||
zephyr_library_include_directories(
|
zephyr_library_include_directories(
|
||||||
${MBEDTLS_ASN1_DIR}/include
|
${MBEDTLS_ASN1_DIR}/include
|
||||||
)
|
)
|
||||||
|
@ -219,7 +219,7 @@ elseif(CONFIG_BOOT_SIGNATURE_TYPE_ED25519 OR CONFIG_BOOT_ENCRYPT_X25519)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519 OR CONFIG_BOOT_SERIAL_ENCRYPT_EC256)
|
if(CONFIG_BOOT_ENCRYPT_EC256 OR CONFIG_BOOT_ENCRYPT_X25519)
|
||||||
zephyr_library_sources(
|
zephyr_library_sources(
|
||||||
${TINYCRYPT_DIR}/source/aes_encrypt.c
|
${TINYCRYPT_DIR}/source/aes_encrypt.c
|
||||||
${TINYCRYPT_DIR}/source/aes_decrypt.c
|
${TINYCRYPT_DIR}/source/aes_decrypt.c
|
||||||
|
@ -248,6 +248,12 @@ if(CONFIG_MCUBOOT_SERIAL)
|
||||||
CONFIG_BOOT_ERASE_PROGRESSIVELY
|
CONFIG_BOOT_ERASE_PROGRESSIVELY
|
||||||
${BOOT_DIR}/bootutil/src
|
${BOOT_DIR}/bootutil/src
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(CONFIG_BOOT_ENCRYPT_IMAGE)
|
||||||
|
zephyr_library_sources(
|
||||||
|
${BOOT_DIR}/boot_serial/src/boot_serial_encryption.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
|
if(NOT CONFIG_BOOT_SIGNATURE_KEY_FILE STREQUAL "")
|
||||||
|
|
|
@ -136,15 +136,6 @@ config BOOT_MGMT_CUSTOM_IMG_LIST
|
||||||
|
|
||||||
endif # ENABLE_MGMT_PERUSER
|
endif # ENABLE_MGMT_PERUSER
|
||||||
|
|
||||||
config BOOT_SERIAL_ENCRYPT_EC256
|
|
||||||
bool "Support for encrypted upgrade images using ECIES-P256 in serial recovery upload"
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
If y, uploaded images via serial recovery can be decrypted
|
|
||||||
on the fly when upgrading to the primary slot. The
|
|
||||||
encryption mechanism used in this case is ECIES using primitives
|
|
||||||
described under "ECIES-P256 encryption" in docs/encrypted_images.md.
|
|
||||||
|
|
||||||
menu "Entrance methods"
|
menu "Entrance methods"
|
||||||
|
|
||||||
menuconfig BOOT_SERIAL_ENTRANCE_GPIO
|
menuconfig BOOT_SERIAL_ENTRANCE_GPIO
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "config-rsa.h"
|
#include "config-rsa.h"
|
||||||
#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \
|
#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) || \
|
||||||
defined(CONFIG_BOOT_ENCRYPT_EC256) || \
|
defined(CONFIG_BOOT_ENCRYPT_EC256) || \
|
||||||
defined(CONFIG_BOOT_SERIAL_ENCRYPT_EC256) || \
|
|
||||||
(defined(CONFIG_BOOT_ENCRYPT_X25519) && !defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519))
|
(defined(CONFIG_BOOT_ENCRYPT_X25519) && !defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519))
|
||||||
#include "config-asn1.h"
|
#include "config-asn1.h"
|
||||||
#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519)
|
#elif defined(CONFIG_BOOT_SIGNATURE_TYPE_ED25519)
|
||||||
|
|
|
@ -117,11 +117,6 @@
|
||||||
#define MCUBOOT_ENCRYPT_EC256
|
#define MCUBOOT_ENCRYPT_EC256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_BOOT_SERIAL_ENCRYPT_EC256
|
|
||||||
#define MCUBOOT_ENC_IMAGES
|
|
||||||
#define MCUBOOT_ENCRYPT_EC256
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_BOOT_ENCRYPT_X25519
|
#ifdef CONFIG_BOOT_ENCRYPT_X25519
|
||||||
#define MCUBOOT_ENC_IMAGES
|
#define MCUBOOT_ENC_IMAGES
|
||||||
#define MCUBOOT_ENCRYPT_X25519
|
#define MCUBOOT_ENCRYPT_X25519
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021-2021 Crodeon Technologies
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef H_SINGLE_LOADER_
|
|
||||||
#define H_SINGLE_LOADER_
|
|
||||||
#include "bootutil/fault_injection_hardening.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle an encrypted firmware in the main flash.
|
|
||||||
* This will decrypt the image inplace
|
|
||||||
*/
|
|
||||||
int boot_handle_enc_fw();
|
|
||||||
|
|
||||||
fih_ret boot_image_validate(const struct flash_area *fa_p,
|
|
||||||
struct image_header *hdr);
|
|
||||||
#endif
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "bootutil/image.h"
|
#include "bootutil/image.h"
|
||||||
#include "bootutil_priv.h"
|
#include "bootutil_priv.h"
|
||||||
#include "bootutil/bootutil_log.h"
|
#include "bootutil/bootutil_log.h"
|
||||||
|
#include "bootutil/bootutil_public.h"
|
||||||
#include "bootutil/fault_injection_hardening.h"
|
#include "bootutil/fault_injection_hardening.h"
|
||||||
|
|
||||||
#include "mcuboot_config/mcuboot_config.h"
|
#include "mcuboot_config/mcuboot_config.h"
|
||||||
|
@ -57,7 +58,6 @@ boot_image_validate(const struct flash_area *fa_p,
|
||||||
}
|
}
|
||||||
#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/
|
#endif /* MCUBOOT_VALIDATE_PRIMARY_SLOT || MCUBOOT_VALIDATE_PRIMARY_SLOT_ONCE*/
|
||||||
|
|
||||||
|
|
||||||
inline static fih_ret
|
inline static fih_ret
|
||||||
boot_image_validate_once(const struct flash_area *fa_p,
|
boot_image_validate_once(const struct flash_area *fa_p,
|
||||||
struct image_header *hdr)
|
struct image_header *hdr)
|
||||||
|
@ -89,349 +89,6 @@ boot_image_validate_once(const struct flash_area *fa_p,
|
||||||
FIH_RET(FIH_SUCCESS);
|
FIH_RET(FIH_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to load image header from flash; verifies flash header fields.
|
|
||||||
*
|
|
||||||
* @param[in] fa_p flash area pointer
|
|
||||||
* @param[out] hdr buffer for image header
|
|
||||||
*
|
|
||||||
* @return 0 on success, error code otherwise
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
boot_image_load_header(const struct flash_area *fa_p,
|
|
||||||
struct image_header *hdr)
|
|
||||||
{
|
|
||||||
uint32_t size;
|
|
||||||
int rc = flash_area_read(fa_p, 0, hdr, sizeof *hdr);
|
|
||||||
|
|
||||||
if (rc != 0) {
|
|
||||||
rc = BOOT_EFLASH;
|
|
||||||
BOOT_LOG_ERR("Failed reading image header");
|
|
||||||
return BOOT_EFLASH;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdr->ih_magic != IMAGE_MAGIC) {
|
|
||||||
BOOT_LOG_ERR("Bad image magic 0x%lx", (unsigned long)hdr->ih_magic);
|
|
||||||
|
|
||||||
return BOOT_EBADIMAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdr->ih_flags & IMAGE_F_NON_BOOTABLE) {
|
|
||||||
BOOT_LOG_ERR("Image not bootable");
|
|
||||||
|
|
||||||
return BOOT_EBADIMAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size) ||
|
|
||||||
size >= flash_area_get_size(fa_p)) {
|
|
||||||
return BOOT_EBADIMAGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MCUBOOT_ENC_IMAGES
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate hash of a primary boot image doing on the fly decryption as well
|
|
||||||
*
|
|
||||||
* @param[in] fa_p flash area pointer
|
|
||||||
* @param[in] hdr boot image header pointer
|
|
||||||
*
|
|
||||||
* @return FIH_SUCCESS on success, error code otherwise
|
|
||||||
*/
|
|
||||||
inline static fih_ret
|
|
||||||
boot_image_validate_encrypted(const struct flash_area *fa_p,
|
|
||||||
struct image_header *hdr)
|
|
||||||
{
|
|
||||||
static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
|
|
||||||
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
|
||||||
|
|
||||||
struct boot_loader_state boot_data;
|
|
||||||
struct boot_loader_state *state = &boot_data;
|
|
||||||
struct boot_status _bs;
|
|
||||||
struct boot_status *bs = &_bs;
|
|
||||||
uint8_t image_index;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
|
||||||
image_index = BOOT_CURR_IMG(state);
|
|
||||||
if (MUST_DECRYPT(fa_p, image_index, hdr)) {
|
|
||||||
rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs);
|
|
||||||
if (rc < 0) {
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) {
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FIH_CALL(bootutil_img_validate, fih_rc, BOOT_CURR_ENC(state), image_index,
|
|
||||||
hdr, fa_p, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL);
|
|
||||||
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute the total size of the given image. Includes the size of
|
|
||||||
* the TLVs.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
read_image_size(const struct flash_area *fa_p,
|
|
||||||
struct image_header *hdr,
|
|
||||||
uint32_t *size)
|
|
||||||
{
|
|
||||||
struct image_tlv_info info;
|
|
||||||
uint32_t off;
|
|
||||||
uint32_t protect_tlv_size;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
off = BOOT_TLV_OFF(hdr);
|
|
||||||
|
|
||||||
if (flash_area_read(fa_p, off, &info, sizeof(info))) {
|
|
||||||
rc = BOOT_EFLASH;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
protect_tlv_size = hdr->ih_protect_tlv_size;
|
|
||||||
if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
|
|
||||||
if (protect_tlv_size != info.it_tlv_tot) {
|
|
||||||
rc = BOOT_EBADIMAGE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flash_area_read(fa_p, off + info.it_tlv_tot, &info, sizeof(info))) {
|
|
||||||
rc = BOOT_EFLASH;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
} else if (protect_tlv_size != 0) {
|
|
||||||
rc = BOOT_EBADIMAGE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
|
|
||||||
rc = BOOT_EBADIMAGE;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
*size = off + protect_tlv_size + info.it_tlv_tot;
|
|
||||||
rc = 0;
|
|
||||||
|
|
||||||
done:
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Get the SOC's flash erase block size from the DTS, fallback to 1024. */
|
|
||||||
#define SOC_FLASH_ERASE_BLK_SZ \
|
|
||||||
DT_PROP_OR(DT_CHOSEN(zephyr_flash), erase_block_size,1024)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* reads, decrypts in RAM & write back the decrypted image in the same region
|
|
||||||
* This function is NOT power failsafe since the image is decrypted in the RAM
|
|
||||||
* buffer.
|
|
||||||
*
|
|
||||||
* @param flash_area The ID of the source flash area.
|
|
||||||
* @param off_src The offset within the flash area to
|
|
||||||
* copy from.
|
|
||||||
* @param sz The number of bytes to copy. should match erase sector
|
|
||||||
*
|
|
||||||
* @return 0 on success; nonzero on failure.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
decrypt_region_inplace(struct boot_loader_state *state,
|
|
||||||
const struct flash_area *fap,
|
|
||||||
struct image_header *hdr,
|
|
||||||
uint32_t off, uint32_t sz)
|
|
||||||
{
|
|
||||||
uint32_t bytes_copied;
|
|
||||||
int chunk_sz;
|
|
||||||
int rc;
|
|
||||||
uint32_t tlv_off;
|
|
||||||
size_t blk_off;
|
|
||||||
uint16_t idx;
|
|
||||||
uint32_t blk_sz;
|
|
||||||
uint8_t image_index;
|
|
||||||
|
|
||||||
static uint8_t buf[SOC_FLASH_ERASE_BLK_SZ] __attribute__((aligned));
|
|
||||||
assert(sz <= sizeof buf);
|
|
||||||
|
|
||||||
bytes_copied = 0;
|
|
||||||
while (bytes_copied < sz) {
|
|
||||||
if (sz - bytes_copied > sizeof buf) {
|
|
||||||
chunk_sz = sizeof buf;
|
|
||||||
} else {
|
|
||||||
chunk_sz = sz - bytes_copied;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = flash_area_read(fap, off + bytes_copied, buf, chunk_sz);
|
|
||||||
if (rc != 0) {
|
|
||||||
return BOOT_EFLASH;
|
|
||||||
}
|
|
||||||
|
|
||||||
image_index = BOOT_CURR_IMG(state);
|
|
||||||
if (IS_ENCRYPTED(hdr)) {
|
|
||||||
blk_sz = chunk_sz;
|
|
||||||
idx = 0;
|
|
||||||
if (off + bytes_copied < hdr->ih_hdr_size) {
|
|
||||||
/* do not decrypt header */
|
|
||||||
if (hdr->ih_hdr_size > (off + bytes_copied + chunk_sz)) {
|
|
||||||
/* all bytes in header, skip decryption */
|
|
||||||
blk_sz = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
blk_sz = off + bytes_copied + chunk_sz - hdr->ih_hdr_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
blk_off = 0;
|
|
||||||
idx = hdr->ih_hdr_size;
|
|
||||||
} else {
|
|
||||||
blk_off = ((off + bytes_copied) - hdr->ih_hdr_size) & 0xf;
|
|
||||||
}
|
|
||||||
tlv_off = BOOT_TLV_OFF(hdr);
|
|
||||||
if (off + bytes_copied + chunk_sz > tlv_off) {
|
|
||||||
/* do not decrypt TLVs */
|
|
||||||
if (off + bytes_copied >= tlv_off) {
|
|
||||||
blk_sz = 0;
|
|
||||||
} else {
|
|
||||||
blk_sz = tlv_off - (off + bytes_copied);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boot_encrypt(BOOT_CURR_ENC(state), image_index, fap,
|
|
||||||
(off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
|
|
||||||
blk_off, &buf[idx]);
|
|
||||||
}
|
|
||||||
rc = flash_area_erase(fap, off + bytes_copied, chunk_sz);
|
|
||||||
if (rc != 0) {
|
|
||||||
return BOOT_EFLASH;
|
|
||||||
}
|
|
||||||
rc = flash_area_write(fap, off + bytes_copied, buf, chunk_sz);
|
|
||||||
if (rc != 0) {
|
|
||||||
return BOOT_EFLASH;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes_copied += chunk_sz;
|
|
||||||
|
|
||||||
MCUBOOT_WATCHDOG_FEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a image was encrypted into the first slot, and decrypt it
|
|
||||||
* in place. this operation is not power failsafe.
|
|
||||||
*
|
|
||||||
* The operation is done by checking the last flash sector, and using it as a
|
|
||||||
* temporarely scratch partition. The
|
|
||||||
*
|
|
||||||
* @param[in] fa_p flash area pointer
|
|
||||||
* @param[in] hdr boot image header pointer
|
|
||||||
*
|
|
||||||
* @return FIH_SUCCESS on success, error code otherwise
|
|
||||||
*/
|
|
||||||
inline static fih_ret
|
|
||||||
decrypt_image_inplace(const struct flash_area *fa_p,
|
|
||||||
struct image_header *hdr)
|
|
||||||
{
|
|
||||||
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
|
||||||
int rc;
|
|
||||||
struct boot_loader_state boot_data;
|
|
||||||
struct boot_loader_state *state = &boot_data;
|
|
||||||
struct boot_status _bs;
|
|
||||||
struct boot_status *bs = &_bs;
|
|
||||||
size_t size;
|
|
||||||
size_t sect_size;
|
|
||||||
size_t sect_count;
|
|
||||||
size_t sect;
|
|
||||||
uint8_t image_index;
|
|
||||||
struct flash_sector sector;
|
|
||||||
|
|
||||||
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
|
||||||
memset(&_bs, 0, sizeof(struct boot_status));
|
|
||||||
|
|
||||||
/* Get size from last sector to know page/sector erase size */
|
|
||||||
rc = flash_area_get_sector(fa_p, boot_status_off(fa_p), §or);
|
|
||||||
|
|
||||||
|
|
||||||
image_index = BOOT_CURR_IMG(state);
|
|
||||||
|
|
||||||
if (MUST_DECRYPT(fa_p, image_index, hdr)) {
|
|
||||||
#if 0 //Skip this step?, the image will just not boot if it's not decrypted properly
|
|
||||||
/* First check if the encrypted image is a good image before decrypting */
|
|
||||||
FIH_CALL(boot_image_validate_encrypted,fih_rc,_fa_p,&_hdr);
|
|
||||||
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
memset(&boot_data, 0, sizeof(struct boot_loader_state));
|
|
||||||
/* Load the encryption keys into cache */
|
|
||||||
rc = boot_enc_load(BOOT_CURR_ENC(state), image_index, hdr, fa_p, bs);
|
|
||||||
if (rc < 0) {
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
if (rc == 0 && boot_enc_set_key(BOOT_CURR_ENC(state), 0, bs)) {
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Expected encrypted image! */
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t src_size = 0;
|
|
||||||
rc = read_image_size(fa_p,hdr, &src_size);
|
|
||||||
if (rc != 0) {
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
sect_size = sector.fs_size;
|
|
||||||
sect_count = fa_p->fa_size / sect_size;
|
|
||||||
for (sect = 0, size = 0; size < src_size && sect < sect_count; sect++) {
|
|
||||||
rc = decrypt_region_inplace(state, fa_p,hdr, size, sect_size);
|
|
||||||
if (rc != 0) {
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
size += sect_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
fih_rc = FIH_SUCCESS;
|
|
||||||
FIH_RET(fih_rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
boot_handle_enc_fw()
|
|
||||||
{
|
|
||||||
int rc = -1;
|
|
||||||
FIH_DECLARE(fih_rc, FIH_FAILURE);
|
|
||||||
|
|
||||||
rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &_fa_p);
|
|
||||||
assert(rc == 0);
|
|
||||||
|
|
||||||
rc = boot_image_load_header(_fa_p, &_hdr);
|
|
||||||
if (rc != 0) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IS_ENCRYPTED(&_hdr)) {
|
|
||||||
//encrypted, we need to decrypt in place
|
|
||||||
FIH_CALL(decrypt_image_inplace,fih_rc,_fa_p,&_hdr);
|
|
||||||
if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) {
|
|
||||||
rc = -1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
flash_area_close(_fa_p);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gather information on image and prepare for booting.
|
* Gather information on image and prepare for booting.
|
||||||
*
|
*
|
||||||
|
|
|
@ -251,12 +251,6 @@ Use the ``CONFIG_ENABLE_MGMT_PERUSER=y`` Kconfig option to enable the following
|
||||||
* Storage erase - This command allows erasing the storage partition (enable with ``CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y``).
|
* Storage erase - This command allows erasing the storage partition (enable with ``CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y``).
|
||||||
* Custom image list - This command allows fetching version and installation status (custom properties) for all images (enable with ``CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST=y``).
|
* Custom image list - This command allows fetching version and installation status (custom properties) for all images (enable with ``CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST=y``).
|
||||||
|
|
||||||
### In-place image decryption
|
|
||||||
|
|
||||||
Images uploaded by the serial recovery can be decrypted on the fly by using ECIES primitives described in the [ECIES encryption](encrypted_images.md#ecies-encryption) section.
|
|
||||||
|
|
||||||
Enable support for this feature by using ``CONFIG_BOOT_SERIAL_ENCRYPT_EC256=y``.
|
|
||||||
|
|
||||||
### More configuration
|
### More configuration
|
||||||
|
|
||||||
For details on other available configuration options for the serial recovery protocol, check the Kconfig options (for example by using ``menuconfig``).
|
For details on other available configuration options for the serial recovery protocol, check the Kconfig options (for example by using ``menuconfig``).
|
||||||
|
|
Loading…
Reference in New Issue