[U-Boot] [PATCH v3 15/15] SECURE_BOOT: Enable IE (Key extention) Feature in Ls2085a & LS2088a
Aneesh Bansal
aneesh.bansal at nxp.com
Wed Feb 3 08:04:26 CET 2016
> -----Original Message-----
> From: Saksham Jain [mailto:saksham.jain at nxp.com]
> Sent: Monday, February 01, 2016 5:14 PM
> To: u-boot at lists.denx.de
> Cc: york sun <york.sun at nxp.com>; Ruchika Gupta <ruchika.gupta at nxp.com>;
> Prabhakar Kushwaha <prabhakar.kushwaha at nxp.com>; Saksham Jain
> <saksham.jain at nxp.com>; Aneesh Bansal <aneesh.bansal at nxp.com>
> Subject: [PATCH v3 15/15] SECURE_BOOT: Enable IE (Key extention) Feature in
> Ls2085a & LS2088a
>
> For validating images from uboot (Such as Kernel Image), either keys from SoC fuses
> can be used or keys from a veriied table of public keys can be used. The latter feature
> is called IE Key Extension Feature.
>
> For earlier SoCs, BootROM used to verify IE Key Table and then write the address of
> this table in a secure register (SCRATCHREG). But in LS2088 and LS2085, no such
> secure registers are available. Hence IE Table is left to be verified by Uboot.
>
> The new procedure is to first verify IE table using Keys stored in fuses, and then use
> the keys in this table to verify further images. So the steps
> are:
>
> 1) Verify IE Table (If "IE Table Flag" set in any image i.e. Verify IE Table only when
> any image needs IE Table's Key to be verified)
> 2) Install IE table. (To be used across verification of multiple images.
> Stored in a static global structure.)
> 3) If IE flag enabled in header of any image, Use keys from IE table, otherwise use
> keys tied up with SoC's fuses (SRK).
>
> The address of IE Table HDR is fixed for NOR. In case of boot from other devices, IE
> Table and it's Header needs to be copied to an XIP Memory.
>
> Signed-off-by: Aneesh Bansal <aneesh.bansal at nxp.com>
> Signed-off-by: Saksham Jain <saksham.jain at nxp.com>
> ---
> Changes for v2:
> - No changes
> Changes for v3:
> -changes to remove compliation warning for various platforms
>
> arch/arm/include/asm/fsl_secure_boot.h | 6 +--
> board/freescale/common/fsl_validate.c | 97 ++++++++++++++++++++++++++++------
> include/fsl_validate.h | 23 +++++++-
> 3 files changed, 105 insertions(+), 21 deletions(-)
>
> diff --git a/arch/arm/include/asm/fsl_secure_boot.h
> b/arch/arm/include/asm/fsl_secure_boot.h
> index eafdc0b..061c9f5 100644
> --- a/arch/arm/include/asm/fsl_secure_boot.h
> +++ b/arch/arm/include/asm/fsl_secure_boot.h
> @@ -41,11 +41,11 @@
> * in boot ROM of the SoC.
> * The feature is only applicable in case of NOR boot and is
> * not applicable in case of RAMBOOT (NAND, SD, SPI).
> + * For LS, this feature is available for all device if IE Table
> + * is copied to XIP memory
> + * Also, for LS, ISBC doesn't verify this table.
> */
> -#ifndef CONFIG_ESBC_HDR_LS
> -/* Current Key EXT feature not available in LS ESBC Header */ #define
> CONFIG_FSL_ISBC_KEY_EXT -#endif
>
> #endif
>
> diff --git a/board/freescale/common/fsl_validate.c
> b/board/freescale/common/fsl_validate.c
> index 64e4e30..248a759 100644
> --- a/board/freescale/common/fsl_validate.c
> +++ b/board/freescale/common/fsl_validate.c
> @@ -27,6 +27,10 @@
> #define CHECK_KEY_LEN(key_len) (((key_len) == 2 * KEY_SIZE_BYTES /
> 4) || \
> ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
> ((key_len) == 2 * KEY_SIZE_BYTES))
> +#if defined(CONFIG_FSL_ISBC_KEY_EXT)
> +/* Global data structure */
> +static struct fsl_secboot_glb glb;
> +#endif
>
> /* This array contains DER value for SHA-256 */ static const u8 hash_identifier[] = {
> 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, @@ -60,7 +64,7 @@ self:
> #if defined(CONFIG_FSL_ISBC_KEY_EXT)
> static u32 check_ie(struct fsl_secboot_img_priv *img) {
> - if (img->hdr.ie_flag)
> + if (img->hdr.ie_flag & IE_FLAG_MASK)
> return 1;
>
> return 0;
> @@ -119,7 +123,8 @@ int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
> } #endif
>
> -static int get_ie_info_addr(u32 *ie_addr)
> +#if !defined(CONFIG_ESBC_HDR_LS)
> +static int get_ie_info_addr(uintptr_t *ie_addr)
> {
> struct fsl_secboot_img_hdr *hdr;
> struct fsl_secboot_sg_table *sg_tbl;
> @@ -147,16 +152,17 @@ static int get_ie_info_addr(u32 *ie_addr)
>
> /* IE Key Table is the first entry in the SG Table */ #if
> defined(CONFIG_MPC85xx)
> - *ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
> - flash_base_addr;
> + *ie_addr = (uintptr_t)((sg_tbl->src_addr &
> + ~(CONFIG_SYS_PBI_FLASH_BASE)) +
> + flash_base_addr);
> #else
> - *ie_addr = sg_tbl->src_addr;
> + *ie_addr = (uintptr_t)sg_tbl->src_addr;
> #endif
>
> - debug("IE Table address is %x\n", *ie_addr);
> + debug("IE Table address is %lx\n", *ie_addr);
> return 0;
> }
> -
> +#endif /* CONFIG_ESBC_HDR_LS */
> #endif
>
> #ifdef CONFIG_KEY_REVOCATION
> @@ -164,7 +170,10 @@ static int get_ie_info_addr(u32 *ie_addr) static u32
> check_srk(struct fsl_secboot_img_priv *img) { #ifdef CONFIG_ESBC_HDR_LS
> - /* In LS, No SRK Flag as SRK is always present*/
> + /* In LS, No SRK Flag as SRK is always present if IE not present*/ #if
> +defined(CONFIG_FSL_ISBC_KEY_EXT)
> + return !check_ie(img);
> +#endif
> return 1;
> #else
> if (img->hdr.len_kr.srk_table_flag & SRK_FLAG) @@ -253,14 +262,51 @@
> static u32 read_validate_single_key(struct fsl_secboot_img_priv *img) #endif /*
> CONFIG_ESBC_HDR_LS */
>
> #if defined(CONFIG_FSL_ISBC_KEY_EXT)
> +
> +#if defined(CONFIG_ESBC_HDR_LS)
> +static void install_ie_tbl(uintptr_t ie_tbl_addr,
> + struct fsl_secboot_img_priv *img)
> +{
> + /* Copy IE tbl to Global Data */
> + memcpy(&glb.ie_tbl, (u8 *)ie_tbl_addr, sizeof(struct ie_key_info));
> + img->ie_addr = (uintptr_t)&glb.ie_tbl;
> + glb.ie_addr = img->ie_addr;
> +}
> +#endif
> +
> static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img) {
> struct fsl_secboot_img_hdr *hdr = &img->hdr;
> u32 ie_key_len, ie_revoc_flag, ie_num;
> struct ie_key_info *ie_info;
>
> - if (get_ie_info_addr(&img->ie_addr))
> - return ERROR_IE_TABLE_NOT_FOUND;
> +/* For LS, IE Table is installed as a separate image.
> + * It is not verified by ISBC.
> + */
> + if (!img->ie_addr)
> +#if defined(CONFIG_ESBC_HDR_LS)
> + /* Verify and Install IE Table */
> + debug("Verifying IE Table\n");
> +
> + int ret;
> + uintptr_t ie_tbl_addr = 0;
> + ret = fsl_secboot_validate(IE_TABLE_HDR_ADR, NULL,
> + &ie_tbl_addr);
> + if (ret) {
> + printf("IE Table Verification Failed\n");
> + return ret;
> + } else {
> + printf("IE Table Verified Successfully\n");
> + /* If the image is IE Table,
> + * then install that IE Table for
> + * future verification process.
> + */
> + install_ie_tbl(ie_tbl_addr, img);
> + }
> +#else
> + if (get_ie_info_addr(&img->ie_addr))
> + return ERROR_IE_TABLE_NOT_FOUND;
> +#endif
> ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
> if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
> return
> ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
> @@ -810,6 +856,26 @@ static int calculate_cmp_img_sig(struct
> fsl_secboot_img_priv *img)
>
> return 0;
> }
> +/* Function to initialize img priv and global data structure */ static
> +int secboot_init(struct fsl_secboot_img_priv **img_ptr) {
> + *img_ptr = malloc(sizeof(struct fsl_secboot_img_priv));
> +
> + struct fsl_secboot_img_priv *img = *img_ptr;
> +
> + if (!img)
> + return -ENOMEM;
> + memset(img, 0, sizeof(struct fsl_secboot_img_priv));
> +
> +#if defined(CONFIG_FSL_ISBC_KEY_EXT)
> + if (glb.ie_addr)
> + img->ie_addr = glb.ie_addr;
> +#endif
> + return 0;
> +}
> +
> +
> /* haddr - Address of the header of image to be validated.
> * arg_hash_str - Option hash string. If provided, this
> * overides the key hash in the SFP fuses.
> @@ -863,12 +929,9 @@ int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
> hash_cmd = 1;
> }
>
> - img = malloc(sizeof(struct fsl_secboot_img_priv));
> -
> - if (!img)
> - return -1;
> -
> - memset(img, 0, sizeof(struct fsl_secboot_img_priv));
> + ret = secboot_init(&img);
> + if (ret)
> + goto exit;
>
> /* Update the information in Private Struct */
> hdr = &img->hdr;
> @@ -923,5 +986,7 @@ int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
> }
>
> exit:
> + /* Free Img as it was malloc'ed*/
> + free(img);
> return ret;
> }
> diff --git a/include/fsl_validate.h b/include/fsl_validate.h index a71e1ce..7aae5c9
> 100644
> --- a/include/fsl_validate.h
> +++ b/include/fsl_validate.h
> @@ -40,8 +40,8 @@ struct fsl_secboot_img_hdr {
> u8 num_srk;
> u8 srk_sel;
> u8 reserve;
> - u8 ie_flag;
> } len_kr;
> + u8 ie_flag;
>
> u32 uid_flag;
>
> @@ -69,6 +69,10 @@ struct fsl_secboot_img_hdr { #define MAX_KEY_ENTRIES
> 8 #endif
>
> +#if defined(CONFIG_FSL_ISBC_KEY_EXT)
> +#define IE_FLAG_MASK 0x1
> +#define IE_TABLE_HDR_ADR 0x5839c0000
> +#endif
>
> #else /* CONFIG_ESBC_HDR_LS */
>
> @@ -150,6 +154,10 @@ struct fsl_secboot_img_hdr { #define
> MAX_KEY_ENTRIES 4 #endif
>
> +#if defined(CONFIG_FSL_ISBC_KEY_EXT)
> +#define IE_FLAG_MASK 0xFFFFFFFF
> +#endif
> +
> #endif /* CONFIG_ESBC_HDR_LS */
>
>
> @@ -202,6 +210,17 @@ struct fsl_secboot_sg_table { }; #endif
>
> +/* ESBC global structure.
> + * Data to be used across verification of different images.
> + * Stores follwoing Data:
> + * IE Table
> + */
> +struct fsl_secboot_glb {
> +#if defined(CONFIG_FSL_ISBC_KEY_EXT)
> + uintptr_t ie_addr;
> + struct ie_key_info ie_tbl;
> +#endif
> +};
> /*
> * ESBC private structure.
> * Private structure used by ESBC to store following fields @@ -213,7 +232,7 @@
> struct fsl_secboot_sg_table {
> */
> struct fsl_secboot_img_priv {
> uint32_t hdr_location;
> - u32 ie_addr;
> + uintptr_t ie_addr;
> u32 key_len;
> struct fsl_secboot_img_hdr hdr;
>
> --
> 1.8.1.4
IE Table must be verified my ISBC only and not by ESBC.
This should be done in similar way as legacy QorIQ PBL based platforms. The address of a verified IE Table must
be read from a SCRATCH Register and that should be used.
More information about the U-Boot
mailing list