Commit 0187c985 authored by Stefano Babic's avatar Stefano Babic

tools: add support for setting the CSF into imximage

Add support for setting the CSF (Command Sequence File) pointer
which is used for HAB (High Assurance Boot) in the imximage by
adding e.g.

CSF 0x2000

in the imximage.cfg file.

This will set the CSF pointer accordingly just after the padded
data image area. The boot_data.length is adjusted with the
value from the imximage.cfg config file.

The resulting u-boot.imx can be signed with the FSL HAB tooling.
The generated CSF block needs to be appended to the u-boot.imx.
Signed-off-by: default avatarStefano Babic <sbabic@denx.de>
parent 01390aff
......@@ -15,9 +15,6 @@ Booting from NOR flash does not require to use this image type.
For more details refer Chapter 2 - System Boot and section 2.14
(flash header description) of the processor's manual.
This implementation does not use at the moment the secure boot feature
of the processor. The image is generated disabling all security fields.
Command syntax:
--------------
./tools/mkimage -l <mx u-boot_file>
......@@ -86,6 +83,33 @@ Configuration command line syntax:
Example:
BOOT_FROM spi
CSF value
Total size of CSF (Command Sequence File)
used for Secure Boot/ High Assurance Boot
(HAB).
Using this command will populate the IVT
(Initial Vector Table) CSF pointer and adjust
the length fields only. The CSF itself needs
to be generated with Freescale tools and
'manually' appended to the u-boot.imx file.
The CSF is then simply concatenated
to the u-boot image, making a signed bootloader,
that the processor can verify
if the fuses for the keys are burned.
Further infos how to configure the SOC to verify
the bootloader can be found in the "High
Assurance Boot Version Application Programming
Interface Reference Manual" as part of the
Freescale Code Signing Tool, available on the
manufacturer's website.
Example:
CSF 0x2000
DATA type address value
type: word=4, halfword=2, byte=1
......
High Assurance Boot (HAB) for i.MX6 CPUs
To authenticate U-Boot only by the CPU there is no code required in
U-Boot itself. However, the U-Boot image to be programmed into the
boot media needs to be properly constructed, i.e. it must contain a
proper Command Sequence File (CSF).
The Initial Vector Table contains a pointer to the CSF. Please see
doc/README.imximage for how to prepare u-boot.imx.
The CSF itself is being generated by Freescale HAB tools.
mkimage will output additional information about "HAB Blocks"
which can be used in the Freescale tooling to authenticate U-Boot
(entries in the CSF file).
Image Type: Freescale IMX Boot Image
Image Ver: 2 (i.MX53/6 compatible)
Data Size: 327680 Bytes = 320.00 kB = 0.31 MB
Load Address: 177ff420
Entry Point: 17800000
HAB Blocks: 177ff400 00000000 0004dc00
^^^^^^^^ ^^^^^^^^ ^^^^^^^^
| | |
| | -------- (1)
| |
| ------------------- (2)
|
--------------------------- (3)
(1) Size of area in file u-boot.imx to sign
This area should include the IVT, the Boot Data the DCD
and U-Boot itself.
(2) Start of area in u-boot.imx to sign
(3) Start of area in RAM to authenticate
CONFIG_SECURE_BOOT currently enables only an additional command
'hab_status' in U-Boot to retrieve the HAB status and events. This
can be useful while developing and testing HAB.
Commands to generate a signed U-Boot using Freescale HAB tools:
cst --o U-Boot_CSF.bin < U-Boot.CSF
objcopy -I binary -O binary --pad-to 0x2000 --gap-fill=0x00 \
U-Boot_CSF.bin U-Boot_CSF_pad.bin
cat u-boot.imx U-Boot_CSF_pad.bin > u-boot-signed.imx
NOTE: U-Boot_CSF.bin needs to be padded to the value specified in
the imximage.cfg file.
......@@ -16,6 +16,8 @@
#include <image.h>
#include "imximage.h"
#define UNDEFINED 0xFFFFFFFF
/*
* Supported commands for configuration file
*/
......@@ -23,6 +25,7 @@ static table_entry_t imximage_cmds[] = {
{CMD_BOOT_FROM, "BOOT_FROM", "boot command", },
{CMD_BOOT_OFFSET, "BOOT_OFFSET", "Boot offset", },
{CMD_DATA, "DATA", "Reg Write Data", },
{CMD_CSF, "CSF", "Command Sequence File", },
{CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", },
{-1, "", "", },
};
......@@ -66,8 +69,13 @@ static table_entry_t imximage_versions[] = {
static struct imx_header imximage_header;
static uint32_t imximage_version;
/* Image Vector Table Offset */
static uint32_t imximage_ivt_offset;
/*
* Image Vector Table Offset
* Initialized to a wrong not 4-bytes aligned address to
* check if it is was set by the cfg file.
*/
static uint32_t imximage_ivt_offset = UNDEFINED;
static uint32_t imximage_csf_size = UNDEFINED;
/* Initial Load Region Size */
static uint32_t imximage_init_loadsize;
......@@ -76,6 +84,7 @@ static set_dcd_rst_t set_dcd_rst;
static set_imx_hdr_t set_imx_hdr;
static uint32_t max_dcd_entries;
static uint32_t *header_size_ptr;
static uint32_t *csf_ptr;
static uint32_t get_cfg_value(char *token, char *name, int linenr)
{
......@@ -247,9 +256,10 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+ offsetof(imx_header_v2_t, boot_data);
hdr_v2->boot_data.start = entry_point - imximage_init_loadsize;
/* Security feature are not supported */
fhdr_v2->csf = 0;
header_size_ptr = &hdr_v2->boot_data.size;
csf_ptr = &fhdr_v2->csf;
}
static void set_hdr_func(struct imx_header *imxhdr)
......@@ -326,6 +336,13 @@ static void print_hdr_v2(struct imx_header *imx_hdr)
genimg_print_size(hdr_v2->boot_data.size);
printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry);
if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) &&
(imximage_csf_size != UNDEFINED)) {
printf("HAB Blocks: %08x %08x %08x\n",
(uint32_t)fhdr_v2->self, 0,
hdr_v2->boot_data.size - imximage_ivt_offset -
imximage_csf_size);
}
}
static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
......@@ -386,6 +403,17 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
if (unlikely(cmd_ver_first != 1))
cmd_ver_first = 0;
break;
case CMD_CSF:
if (imximage_version != 2) {
fprintf(stderr,
"Error: %s[%d] - CSF only supported for VERSION 2(%s)\n",
name, lineno, token);
exit(EXIT_FAILURE);
}
imximage_csf_size = get_cfg_value(token, name, lineno);
if (unlikely(cmd_ver_first != 1))
cmd_ver_first = 0;
break;
}
}
......@@ -537,6 +565,7 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
imximage_version = IMXIMAGE_V1;
/* Be able to detect if the cfg file has no BOOT_FROM tag */
imximage_ivt_offset = FLASH_OFFSET_UNDEFINED;
imximage_csf_size = 0;
set_hdr_func(imxhdr);
/* Parse dcd configuration file */
......@@ -555,6 +584,12 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
* The remaining fraction of a block bytes would not be loaded!
*/
*header_size_ptr = ROUND(sbuf->st_size, 4096);
if (csf_ptr && imximage_csf_size) {
*csf_ptr = params->ep - imximage_init_loadsize +
*header_size_ptr;
*header_size_ptr += imximage_csf_size;
}
}
int imximage_check_params(struct mkimage_params *params)
......
......@@ -52,7 +52,8 @@ enum imximage_cmd {
CMD_IMAGE_VERSION,
CMD_BOOT_FROM,
CMD_BOOT_OFFSET,
CMD_DATA
CMD_DATA,
CMD_CSF,
};
enum imximage_fld_types {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment