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 802eb90f1..dcda2005a 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 000000000..97f8b7d74 --- /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 26460bfec..3f2dc68eb 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 bb04a4320..efe6a88d9 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 { |