mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-17 22:49:02 +00:00
imx: hab: Simplify the mechanism
The current mechanism is unnecessarily complex. Simplify the whole mechanism such that the entire fitImage is signed, IVT is placed at the end, followed by CSF, and this entire bundle is also authenticated. This makes the signing scripting far simpler. Signed-off-by: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
6a412faea3
commit
6039e0edc8
10 changed files with 67 additions and 159 deletions
|
@ -81,7 +81,9 @@
|
|||
|
||||
fit {
|
||||
description = "Configuration to load ATF before U-Boot";
|
||||
#ifndef CONFIG_IMX_HAB
|
||||
fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
|
||||
#endif
|
||||
fit,fdt-list = "of-list";
|
||||
#address-cells = <1>;
|
||||
|
||||
|
|
|
@ -145,7 +145,9 @@
|
|||
|
||||
fit {
|
||||
description = "Configuration to load ATF before U-Boot";
|
||||
#ifndef CONFIG_IMX_HAB
|
||||
fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
|
||||
#endif
|
||||
fit,fdt-list = "of-list";
|
||||
#address-cells = <1>;
|
||||
|
||||
|
|
|
@ -103,7 +103,9 @@
|
|||
|
||||
fit {
|
||||
description = "Configuration to load ATF before U-Boot";
|
||||
#ifndef CONFIG_IMX_HAB
|
||||
fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
|
||||
#endif
|
||||
fit,fdt-list = "of-list";
|
||||
#address-cells = <1>;
|
||||
|
||||
|
|
|
@ -97,7 +97,9 @@
|
|||
|
||||
fit {
|
||||
description = "Configuration to load ATF before U-Boot";
|
||||
#ifndef CONFIG_IMX_HAB
|
||||
fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
|
||||
#endif
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <asm/mach-imx/boot_mode.h>
|
||||
#include <g_dnl.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <memalign.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -315,36 +316,49 @@ ulong board_spl_fit_size_align(ulong size)
|
|||
size = ALIGN(size, 0x1000);
|
||||
size += CONFIG_CSF_SIZE;
|
||||
|
||||
if (size > CONFIG_SYS_BOOTM_LEN)
|
||||
panic("spl: ERROR: image too big\n");
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void board_spl_fit_post_load(const void *fit)
|
||||
{
|
||||
u32 offset = ALIGN(fdt_totalsize(fit), 0x1000);
|
||||
|
||||
if (imx_hab_authenticate_image((uintptr_t)fit,
|
||||
offset + IVT_SIZE + CSF_PAD_SIZE,
|
||||
offset)) {
|
||||
panic("spl: ERROR: image authentication unsuccessful\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len)
|
||||
{
|
||||
int align_len = ARCH_DMA_MINALIGN - 1;
|
||||
|
||||
/* Some devices like SDP, NOR, NAND, SPI are using bl_len =1, so their fit address
|
||||
* is different with SD/MMC, this cause mismatch with signed address. Thus, adjust
|
||||
* the bl_len to align with SD/MMC.
|
||||
*/
|
||||
if (bl_len < 512)
|
||||
bl_len = 512;
|
||||
|
||||
return (void *)((CONFIG_TEXT_BASE - fit_size - bl_len -
|
||||
align_len) & ~align_len);
|
||||
}
|
||||
#if defined(CONFIG_SPL_LOAD_FIT_ADDRESS)
|
||||
return (void *)CONFIG_SPL_LOAD_FIT_ADDRESS;
|
||||
#else
|
||||
return (void *)(CONFIG_TEXT_BASE + CONFIG_SYS_BOOTM_LEN);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* read the address where the IVT header must sit
|
||||
* from IVT image header, loaded from SPL into
|
||||
* an malloced buffer and copy the IVT header
|
||||
* to this address
|
||||
*/
|
||||
void *spl_load_simple_fit_fix_load(const void *fit)
|
||||
{
|
||||
struct ivt *ivt;
|
||||
unsigned long offset;
|
||||
unsigned long size;
|
||||
u8 *tmp = (u8 *)fit;
|
||||
|
||||
offset = ALIGN(fdt_totalsize(fit), 0x1000);
|
||||
size = ALIGN(fdt_totalsize(fit), 4);
|
||||
size = board_spl_fit_size_align(size);
|
||||
tmp += offset;
|
||||
ivt = (struct ivt *)tmp;
|
||||
|
||||
debug("%s: ivt: %p offset: %lx size: %lx\n", __func__, ivt, offset, size);
|
||||
debug("%s: ivt self: %x\n", __func__, ivt->self);
|
||||
|
||||
if (imx_hab_authenticate_image((uintptr_t)fit, (uintptr_t)ivt, offset))
|
||||
panic("spl: ERROR: image authentication unsuccessful\n");
|
||||
|
||||
return (void *)fit;
|
||||
}
|
||||
#endif /* CONFIG_IMX_HAB */
|
||||
|
||||
#if defined(CONFIG_MX6) && defined(CONFIG_SPL_OS_BOOT)
|
||||
int dram_init_banksize(void)
|
||||
|
@ -355,36 +369,3 @@ int dram_init_banksize(void)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* read the address where the IVT header must sit
|
||||
* from IVT image header, loaded from SPL into
|
||||
* an malloced buffer and copy the IVT header
|
||||
* to this address
|
||||
*/
|
||||
void *spl_load_simple_fit_fix_load(const void *fit)
|
||||
{
|
||||
struct ivt *ivt;
|
||||
unsigned long new;
|
||||
unsigned long offset;
|
||||
unsigned long size;
|
||||
u8 *tmp = (u8 *)fit;
|
||||
|
||||
offset = ALIGN(fdt_totalsize(fit), 0x1000);
|
||||
size = ALIGN(fdt_totalsize(fit), 4);
|
||||
size = board_spl_fit_size_align(size);
|
||||
tmp += offset;
|
||||
ivt = (struct ivt *)tmp;
|
||||
if (ivt->hdr.magic != IVT_HEADER_MAGIC) {
|
||||
debug("no IVT header found\n");
|
||||
return (void *)fit;
|
||||
}
|
||||
debug("%s: ivt: %p offset: %lx size: %lx\n", __func__, ivt, offset, size);
|
||||
debug("%s: ivt self: %x\n", __func__, ivt->self);
|
||||
new = ivt->self;
|
||||
new -= offset;
|
||||
debug("%s: new %lx\n", __func__, new);
|
||||
memcpy((void *)new, fit, size);
|
||||
|
||||
return (void *)new;
|
||||
}
|
||||
|
|
|
@ -27,10 +27,6 @@ struct spl_fit_info {
|
|||
int conf_node; /* FDT offset to selected configuration node */
|
||||
};
|
||||
|
||||
__weak void board_spl_fit_post_load(const void *fit)
|
||||
{
|
||||
}
|
||||
|
||||
__weak ulong board_spl_fit_size_align(ulong size)
|
||||
{
|
||||
return size;
|
||||
|
@ -829,8 +825,5 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
|
|||
|
||||
spl_image->flags |= SPL_FIT_FOUND;
|
||||
|
||||
if (IS_ENABLED(CONFIG_IMX_HAB))
|
||||
board_spl_fit_post_load(ctx.fit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -37,29 +37,11 @@ dd if=csf_spl.bin of=flash.bin bs=1 seek=${spl_dd_offset} conv=notrunc
|
|||
|
||||
# 3) Sign u-boot.itb
|
||||
|
||||
# fitImage tree
|
||||
fit_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_TEXT_BASE=/ s@.*=@@p" .config) - $(sed -n "/CONFIG_FIT_EXTERNAL_OFFSET=/ s@.*=@@p" .config) - 0x200 - 0x40)) )
|
||||
# fitImage
|
||||
fit_block_base=$(printf "0x%x" $(sed -n "/CONFIG_SPL_LOAD_FIT_ADDRESS=/ s@.*=@@p" .config) )
|
||||
fit_block_offset=$(printf "0x%s" $(fdtget -t x u-boot.dtb /binman/imx-boot/uboot offset))
|
||||
fit_block_size=$(printf "0x%x" $(( ( ($(fdtdump u-boot.itb 2>/dev/null | sed -n "/^...totalsize:/ s@.*\(0x[0-9a-f]\+\).*@\1@p") + 0x1000 - 0x1 ) & ~(0x1000 - 0x1)) + 0x20 )) )
|
||||
sed -i "/Blocks = / s@.*@ Blocks = $fit_block_base $fit_block_offset $fit_block_size \"flash.bin\", \\\\@" csf_fit.tmp
|
||||
|
||||
# U-Boot
|
||||
uboot_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot load))
|
||||
uboot_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-position)) + ${fit_block_offset} )))
|
||||
uboot_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-size))
|
||||
sed -i "/0xuuuu/ s@.*@ $uboot_block_base $uboot_block_offset $uboot_block_size \"flash.bin\", \\\\@" csf_fit.tmp
|
||||
|
||||
# ATF
|
||||
atf_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf load))
|
||||
atf_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-position)) + ${fit_block_offset} )))
|
||||
atf_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-size))
|
||||
sed -i "/0xaaaa/ s@.*@ $atf_block_base $atf_block_offset $atf_block_size \"flash.bin\", \\\\@" csf_fit.tmp
|
||||
|
||||
# DTB
|
||||
dtb_block_base=$(printf "0x%x" $(( ${uboot_block_base} + ${uboot_block_size} )))
|
||||
dtb_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-position)) + ${fit_block_offset} )))
|
||||
dtb_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-size))
|
||||
sed -i "/0xdddd/ s@.*@ $dtb_block_base $dtb_block_offset $dtb_block_size \"flash.bin\"@" csf_fit.tmp
|
||||
fit_block_size=$(printf "0x%x" $(( ( ( $(stat -tc %s u-boot.itb) + 0x1000 - 0x1 ) & ~(0x1000 - 0x1)) + 0x20 )) )
|
||||
sed -i "/Blocks = / s@.*@ Blocks = $fit_block_base $fit_block_offset $fit_block_size \"flash.bin\"@" csf_fit.tmp
|
||||
|
||||
# IVT
|
||||
ivt_ptr_base=$(printf "%08x" ${fit_block_base} | sed "s@\(..\)\(..\)\(..\)\(..\)@0x\4\3\2\1@")
|
||||
|
@ -68,7 +50,7 @@ csf_block_base=$(printf "%08x" $(( ${fit_block_base} + ${fit_block_size} )) | se
|
|||
ivt_block_offset=$((${fit_block_offset} + ${fit_block_size} - 0x20))
|
||||
csf_block_offset=$((${ivt_block_offset} + 0x20))
|
||||
|
||||
echo "0xd1002041 ${ivt_ptr_base} 0x00000000 0x00000000 0x00000000 ${ivt_block_base} ${csf_block_base} 0x00000000" | xxd -r -p > ivt.bin
|
||||
echo "0xd1002041 ${ivt_block_base} 0x00000000 0x00000000 0x00000000 ${ivt_block_base} ${csf_block_base} 0x00000000" | xxd -r -p > ivt.bin
|
||||
dd if=ivt.bin of=flash.bin bs=1 seek=${ivt_block_offset} conv=notrunc
|
||||
|
||||
# Generate CSF blob
|
||||
|
|
|
@ -26,11 +26,5 @@
|
|||
[Authenticate Data]
|
||||
Verification index = 2
|
||||
# FIXME:
|
||||
# Line 1 -- fitImage tree
|
||||
# Line 2 -- U-Boot u-boot-nodtb.bin blob
|
||||
# Line 3 -- ATF BL31 blob
|
||||
# Line 4 -- DT blob
|
||||
Blocks = 0x401fcdc0 0x57c00 0xffff "flash.bin", \
|
||||
0x40200000 0x62c00 0xuuuu "flash.bin", \
|
||||
0x920000 0x00000 0xaaaa "flash.bin", \
|
||||
0x40200000 0x00000 0xdddd "flash.bin"
|
||||
# Line 1 -- fitImage
|
||||
Blocks = 0x401fcdc0 0x57c00 0xffff "flash.bin"
|
||||
|
|
|
@ -79,18 +79,16 @@ code within it:
|
|||
|
||||
The diagram below illustrate a signed U-Boot binary, DT blob and external
|
||||
ATF BL31 blob combined to form fitImage part of flash.bin container layout.
|
||||
The *load_address is derived from CONFIG_TEXT_BASE such that the U-Boot
|
||||
binary *start is placed exactly at CONFIG_SPL_TEXT_BASE in DRAM, however the
|
||||
SPL moves the fitImage tree further to location:
|
||||
*load_address = CONFIG_SPL_TEXT_BASE - CONFIG_FIT_EXTERNAL_OFFSET (=12kiB) -
|
||||
512 Byte sector - sizeof(mkimage header)
|
||||
The *load_address is CONFIG_SPL_LOAD_FIT_ADDRESS, the fitImage is loaded
|
||||
including all of its embedded data, authenticated using IVT+CSF concatenated
|
||||
at the end of the fitImage at offset aligned to 4 kiB. The fitImage with
|
||||
external data is not supported.
|
||||
|
||||
------- +-----------------------------+ <-- *load_address
|
||||
^ | |
|
||||
| | fitImage tree |
|
||||
| | with external data at |
|
||||
| | offset 12 kiB from tree |
|
||||
| | (cca. 1 kiB) |
|
||||
| | with embedded data |
|
||||
| | (cca. 1 MiB) |
|
||||
Signed | | |
|
||||
.----- Tree | +-----------------------------+
|
||||
| Data | | Padding to next 4k aligned |
|
||||
|
@ -101,34 +99,9 @@ SPL moves the fitImage tree further to location:
|
|||
| ------- +-----------------------------+ <-- *csf
|
||||
| | Command Sequence File (CSF) |
|
||||
| | for all signed entries in |
|
||||
>--------------->| the fitImage, tree and data |
|
||||
| | (cca 6-7 kiB) |
|
||||
| +-----------------------------+
|
||||
| | Padding to 12 kiB offset |
|
||||
| | from *load_address |
|
||||
| ------- +-----------------------------+ <-- *start
|
||||
| ^ | |
|
||||
| Signed | | |
|
||||
|---- Payload | | U-Boot external data blob |
|
||||
| Data | | |
|
||||
| v | |
|
||||
| ------- +-----------------------------+
|
||||
| | Padding to 4 Bytes |
|
||||
| ------- +-----------------------------+
|
||||
| ^ | |
|
||||
| Signed | | |
|
||||
|---- Payload | | ATF external data blob |
|
||||
| Data | | |
|
||||
| v | |
|
||||
| ------- +-----------------------------+
|
||||
| | Padding to 4 Bytes |
|
||||
| ------- +-----------------------------+
|
||||
| ^ | |
|
||||
| Signed | | |
|
||||
'---- Payload | | DTB external data blob |
|
||||
Data | | |
|
||||
v | |
|
||||
------- +-----------------------------+
|
||||
'---------------->| the fitImage, tree and data |
|
||||
| (cca 6-7 kiB) |
|
||||
+-----------------------------+
|
||||
|
||||
The diagram below illustrate a combined flash.bin container layout:
|
||||
|
||||
|
@ -202,29 +175,11 @@ dd if=csf_spl.bin of=flash.bin bs=1 seek=${spl_dd_offset} conv=notrunc
|
|||
|
||||
CSF "Blocks" line for csf_fit.txt can be generated as follows:
|
||||
```
|
||||
# fitImage tree
|
||||
fit_block_base=$(printf "0x%x" $(( $(sed -n "/CONFIG_TEXT_BASE=/ s@.*=@@p" .config) - $(sed -n "/CONFIG_FIT_EXTERNAL_OFFSET=/ s@.*=@@p" .config) - 0x200 - 0x40)) )
|
||||
# fitImage
|
||||
fit_block_base=$(printf "0x%x" $(sed -n "/CONFIG_SPL_LOAD_FIT_ADDRESS=/ s@.*=@@p" .config) )
|
||||
fit_block_offset=$(printf "0x%s" $(fdtget -t x u-boot.dtb /binman/imx-boot/uboot offset))
|
||||
fit_block_size=$(printf "0x%x" $(( ( $(fdtdump u-boot.itb 2>/dev/null | sed -n "/^...totalsize:/ s@.*\(0x[0-9a-f]\+\).*@\1@p") + 0x1000 - 0x1 ) & ~(0x1000 - 0x1) + 0x20 )) )
|
||||
sed -i "/Blocks = / s@.*@ Blocks = $fit_block_base $fit_block_offset $fit_block_size \"flash.bin\", \\\\@" csf_fit.tmp
|
||||
|
||||
# U-Boot
|
||||
uboot_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot load))
|
||||
uboot_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-position)) + ${fit_block_offset} )))
|
||||
uboot_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/uboot data-size))
|
||||
sed -i "/0xuuuu/ s@.*@ $uboot_block_base $uboot_block_offset $uboot_block_size \"flash.bin\", \\\\@" csf_fit.tmp
|
||||
|
||||
# ATF
|
||||
atf_block_base=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf load))
|
||||
atf_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-position)) + ${fit_block_offset} )))
|
||||
atf_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/atf data-size))
|
||||
sed -i "/0xaaaa/ s@.*@ $atf_block_base $atf_block_offset $atf_block_size \"flash.bin\", \\\\@" csf_fit.tmp
|
||||
|
||||
# DTB
|
||||
dtb_block_base=$(printf "0x%x" $(( ${uboot_block_base} + ${uboot_block_size} )))
|
||||
dtb_block_offset=$(printf "0x%x" $(( $(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-position)) + ${fit_block_offset} )))
|
||||
dtb_block_size=$(printf "0x%s" $(fdtget -t x u-boot.itb /images/fdt-1 data-size))
|
||||
sed -i "/0xdddd/ s@.*@ $dtb_block_base $dtb_block_offset $dtb_block_size \"flash.bin\"@" csf_fit.tmp
|
||||
fit_block_size=$(printf "0x%x" $(( ( ( $(stat -tc %s u-boot.itb) + 0x1000 - 0x1 ) & ~(0x1000 - 0x1)) + 0x20 )) )
|
||||
sed -i "/Blocks = / s@.*@ Blocks = $fit_block_base $fit_block_offset $fit_block_size \"flash.bin\"@" csf_fit.tmp
|
||||
```
|
||||
|
||||
The fitImage part of flash.bin requires separate IVT. Generate the IVT and
|
||||
|
@ -237,8 +192,9 @@ csf_block_base=$(printf "%08x" $(( ${fit_block_base} + ${fit_block_size} )) | se
|
|||
ivt_block_offset=$((${fit_block_offset} + ${fit_block_size} - 0x20))
|
||||
csf_block_offset=$((${ivt_block_offset} + 0x20))
|
||||
|
||||
echo "0xd1002041 ${ivt_ptr_base} 0x00000000 0x00000000 0x00000000 ${ivt_block_base} ${csf_block_base} 0x00000000" | xxd -r -p > ivt.bin
|
||||
echo "0xd1002041 ${ivt_block_base} 0x00000000 0x00000000 0x00000000 ${ivt_block_base} ${csf_block_base} 0x00000000" | xxd -r -p > ivt.bin
|
||||
dd if=ivt.bin of=flash.bin bs=1 seek=${ivt_block_offset} conv=notrunc
|
||||
```
|
||||
|
||||
To generate CSF signature for the fitImage part of flash.bin container, use CST:
|
||||
```
|
||||
|
|
|
@ -871,12 +871,6 @@ void spl_invoke_opensbi(struct spl_image_info *spl_image);
|
|||
int board_return_to_bootrom(struct spl_image_info *spl_image,
|
||||
struct spl_boot_device *bootdev);
|
||||
|
||||
/**
|
||||
* board_spl_fit_post_load - allow process images after loading finished
|
||||
* @fit: Pointer to a valid Flattened Image Tree blob
|
||||
*/
|
||||
void board_spl_fit_post_load(const void *fit);
|
||||
|
||||
/**
|
||||
* board_spl_fit_size_align - specific size align before processing payload
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue