@@ -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
@@ -27,6 +27,8 @@
#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))
+/* Global data structure */
+static struct fsl_secboot_glb *glb;
/* This array contains DER value for SHA-256 */
static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
@@ -60,7 +62,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 +121,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 +150,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 +168,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 +260,61 @@ 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;
+ ret = fsl_secboot_validate(IE_TABLE_HDR_ADR, NULL,
+ 0);
+ 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.
+ */
+ char *s = getenv("img_addr");
+
+ uintptr_t ie_tbl_addr =
+ (uintptr_t)simple_strtoull(s, NULL, 16);
+
+ install_ie_tbl(ie_tbl_addr, img);
+ /* Again overide the "img_addr" env variable to
+ * point to addr of image being verified
+ */
+ char buf[20];
+ sprintf(buf, "%lx", img->img_addr);
+ setenv("img_addr", buf);
+ }
+#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;
@@ -815,6 +869,34 @@ 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)
+{
+ /* Init global data only once */
+ if (!glb) {
+ glb = malloc(sizeof(struct fsl_secboot_glb));
+ memset(glb, 0, sizeof(struct fsl_secboot_glb));
+
+ if (!glb)
+ return -ENOMEM;
+ }
+
+ *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;
+}
+
int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
uintptr_t img_addr)
{
@@ -859,12 +941,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)
+ return ret;
/* Update the information in Private Struct */
hdr = &img->hdr;
@@ -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;