]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
fsl: Secure Boot: Enable IE (Key extention) Feature
authorUdit Agarwal <udit.agarwal@nxp.com>
Thu, 9 Feb 2017 16:06:11 +0000 (21:36 +0530)
committerYork Sun <york.sun@nxp.com>
Tue, 28 Mar 2017 16:03:04 +0000 (09:03 -0700)
For validating images from uboot (Such as Kernel Image), either keys
from SoC fuses can be used or keys from a verified table of public
keys can be used. The latter feature is called IE Key Extension
Feature.

For Layerscape Chasis 3 based platforms, IE table is validated by
Bootrom and address of this table is written in scratch registers 13
and 14 via PBI commands.

Following are the steps describing usage of this feature:

1) Verify IE Table in ISBC phase using keys stored in fuses.
2) Install IE table. (To be used across verification of multiple
   images stored in a static global structure.)
3) Use keys from IE table, to verify further images.

Signed-off-by: Aneesh Bansal <aneesh.bansal@nxp.com>
Signed-off-by: Saksham Jain <saksham.jain@nxp.com>
Signed-off-by: Udit Agarwal <udit.agarwal@nxp.com>
Reviewed-by: York Sun <york.sun@nxp.com>
arch/arm/include/asm/fsl_secure_boot.h
board/freescale/common/fsl_validate.c
include/fsl_validate.h

index 8ef866d740aac9370ce0562ea44bbf7269130e2e..d98a1e8f89d7eb2f537fc6a2d6620f80c473c7ba 100644 (file)
  * 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
 
index 2b723a4b9cb995af5f4398412010aa9dde8387d1..7396aa2f698aa0022317460becc230f9b7ad1b81 100644 (file)
 #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,21 @@ 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 ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+       /* For LS-CH3, the address of IE Table is
+        * stated in Scratch13 and scratch14 of DCFG.
+        * Bootrom validates this table while validating uboot.
+        * DCFG is LE*/
+       *ie_addr = in_le32(&gur->scratchrw[SCRATCH_IE_HIGH_ADR - 1]);
+       *ie_addr = *ie_addr << 32;
+       *ie_addr |= in_le32(&gur->scratchrw[SCRATCH_IE_LOW_ADR - 1]);
+       return 0;
+}
+#else /* 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 +165,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 +183,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 +275,29 @@ static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
 #endif /* CONFIG_ESBC_HDR_LS */
 
 #if defined(CONFIG_FSL_ISBC_KEY_EXT)
+
+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;
+}
+
 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;
+       if (!img->ie_addr) {
+               if (get_ie_info_addr(&img->ie_addr))
+                       return ERROR_IE_TABLE_NOT_FOUND;
+               else
+                       install_ie_tbl(img->ie_addr, img);
+               }
+
        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;
@@ -786,6 +823,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
  * overrides the key hash in the SFP fuses.
@@ -839,12 +896,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;
@@ -899,5 +953,7 @@ int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
        }
 
 exit:
+       /* Free Img as it was malloc'ed*/
+       free(img);
        return ret;
 }
index c350938d1ffc92142f7dfeba5616b7dbf694e55b..452c6df83f25587b9d4eea82d42165d9adaaebc6 100644 (file)
@@ -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,11 @@ struct fsl_secboot_img_hdr {
 #define MAX_KEY_ENTRIES 8
 #endif
 
+#if defined(CONFIG_FSL_ISBC_KEY_EXT)
+#define IE_FLAG_MASK 0x1
+#define SCRATCH_IE_LOW_ADR 13
+#define SCRATCH_IE_HIGH_ADR 14
+#endif
 
 #else /* CONFIG_ESBC_HDR_LS */
 
@@ -150,6 +155,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 +211,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 +233,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;