diff options
-rw-r--r-- | doc/README.imximage | 30 | ||||
-rw-r--r-- | doc/README.mxc_hab | 48 | ||||
-rw-r--r-- | tools/imximage.c | 41 | ||||
-rw-r--r-- | tools/imximage.h | 3 |
4 files changed, 115 insertions, 7 deletions
diff --git a/doc/README.imximage b/doc/README.imximage index 802eb90..dcda200 100644 --- a/doc/README.imximage +++ b/doc/README.imximage @@ -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 diff --git a/doc/README.mxc_hab b/doc/README.mxc_hab new file mode 100644 index 0000000..97f8b7d --- /dev/null +++ b/doc/README.mxc_hab @@ -0,0 +1,48 @@ +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. diff --git a/tools/imximage.c b/tools/imximage.c index 26460bf..3f2dc68 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -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) diff --git a/tools/imximage.h b/tools/imximage.h index bb04a43..efe6a88 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -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 { |