xref: /openbmc/u-boot/board/freescale/common/fsl_validate.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
247151e4bSgaurav rana /*
347151e4bSgaurav rana  * Copyright 2015 Freescale Semiconductor, Inc.
447151e4bSgaurav rana  */
547151e4bSgaurav rana 
647151e4bSgaurav rana #include <common.h>
79d922450SSimon Glass #include <dm.h>
847151e4bSgaurav rana #include <fsl_validate.h>
947151e4bSgaurav rana #include <fsl_secboot_err.h>
1047151e4bSgaurav rana #include <fsl_sfp.h>
1147151e4bSgaurav rana #include <fsl_sec.h>
1247151e4bSgaurav rana #include <command.h>
1347151e4bSgaurav rana #include <malloc.h>
1447151e4bSgaurav rana #include <u-boot/rsa-mod-exp.h>
1547151e4bSgaurav rana #include <hash.h>
1647151e4bSgaurav rana #include <fsl_secboot_err.h>
1773fb5838SYork Sun #ifdef CONFIG_ARCH_LS1021A
1847151e4bSgaurav rana #include <asm/arch/immap_ls102xa.h>
1947151e4bSgaurav rana #endif
2047151e4bSgaurav rana 
2147151e4bSgaurav rana #define SHA256_BITS	256
2247151e4bSgaurav rana #define SHA256_BYTES	(256/8)
2347151e4bSgaurav rana #define SHA256_NIBBLES	(256/4)
2447151e4bSgaurav rana #define NUM_HEX_CHARS	(sizeof(ulong) * 2)
2547151e4bSgaurav rana 
2694ba5e41SAneesh Bansal #define CHECK_KEY_LEN(key_len)	(((key_len) == 2 * KEY_SIZE_BYTES / 4) || \
2794ba5e41SAneesh Bansal 				 ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
2894ba5e41SAneesh Bansal 				 ((key_len) == 2 * KEY_SIZE_BYTES))
29ac55dadbSUdit Agarwal #if defined(CONFIG_FSL_ISBC_KEY_EXT)
30ac55dadbSUdit Agarwal /* Global data structure */
31ac55dadbSUdit Agarwal static struct fsl_secboot_glb glb;
32ac55dadbSUdit Agarwal #endif
3394ba5e41SAneesh Bansal 
3447151e4bSgaurav rana /* This array contains DER value for SHA-256 */
3547151e4bSgaurav rana static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
3647151e4bSgaurav rana 		0x86, 0x48, 0x01, 0x65,	0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
3747151e4bSgaurav rana 		0x04, 0x20
3847151e4bSgaurav rana 		};
3947151e4bSgaurav rana 
4047151e4bSgaurav rana static u8 hash_val[SHA256_BYTES];
41fd6dbc98SSaksham Jain 
42fd6dbc98SSaksham Jain #ifdef CONFIG_ESBC_HDR_LS
43fd6dbc98SSaksham Jain /* New Barker Code for LS ESBC Header */
44fd6dbc98SSaksham Jain static const u8 barker_code[ESBC_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 };
45fd6dbc98SSaksham Jain #else
4647151e4bSgaurav rana static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
47fd6dbc98SSaksham Jain #endif
4847151e4bSgaurav rana 
4947151e4bSgaurav rana void branch_to_self(void) __attribute__ ((noreturn));
5047151e4bSgaurav rana 
5147151e4bSgaurav rana /*
5247151e4bSgaurav rana  * This function will put core in infinite loop.
5347151e4bSgaurav rana  * This will be called when the ESBC can not proceed further due
5447151e4bSgaurav rana  * to some unknown errors.
5547151e4bSgaurav rana  */
branch_to_self(void)5647151e4bSgaurav rana void branch_to_self(void)
5747151e4bSgaurav rana {
5847151e4bSgaurav rana 	printf("Core is in infinite loop due to errors.\n");
5947151e4bSgaurav rana self:
6047151e4bSgaurav rana 	goto self;
6147151e4bSgaurav rana }
6247151e4bSgaurav rana 
6347151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
check_ie(struct fsl_secboot_img_priv * img)6447151e4bSgaurav rana static u32 check_ie(struct fsl_secboot_img_priv *img)
6547151e4bSgaurav rana {
66ac55dadbSUdit Agarwal 	if (img->hdr.ie_flag & IE_FLAG_MASK)
6747151e4bSgaurav rana 		return 1;
6847151e4bSgaurav rana 
6947151e4bSgaurav rana 	return 0;
7047151e4bSgaurav rana }
7147151e4bSgaurav rana 
7247151e4bSgaurav rana /* This function returns the CSF Header Address of uboot
7347151e4bSgaurav rana  * For MPC85xx based platforms, the LAW mapping for NOR
7447151e4bSgaurav rana  * flash changes in uboot code. Hence the offset needs
7547151e4bSgaurav rana  * to be calculated and added to the new NOR flash base
7647151e4bSgaurav rana  * address
7747151e4bSgaurav rana  */
7847151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
get_csf_base_addr(u32 * csf_addr,u32 * flash_base_addr)797bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
8047151e4bSgaurav rana {
8147151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
8247151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
8347151e4bSgaurav rana 	u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
847bcb0eb2SAneesh Bansal 	u32 flash_addr, addr;
8547151e4bSgaurav rana 	int found = 0;
8647151e4bSgaurav rana 	int i = 0;
8747151e4bSgaurav rana 
8847151e4bSgaurav rana 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
8947151e4bSgaurav rana 		flash_addr = flash_info[i].start[0];
9047151e4bSgaurav rana 		addr = flash_info[i].start[0] + csf_flash_offset;
9147151e4bSgaurav rana 		if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
927bcb0eb2SAneesh Bansal 			debug("Barker found on addr %x\n", addr);
9347151e4bSgaurav rana 			found = 1;
9447151e4bSgaurav rana 			break;
9547151e4bSgaurav rana 		}
9647151e4bSgaurav rana 	}
9747151e4bSgaurav rana 
9847151e4bSgaurav rana 	if (!found)
9947151e4bSgaurav rana 		return -1;
10047151e4bSgaurav rana 
10147151e4bSgaurav rana 	*csf_addr = addr;
10247151e4bSgaurav rana 	*flash_base_addr = flash_addr;
10347151e4bSgaurav rana 
10447151e4bSgaurav rana 	return 0;
10547151e4bSgaurav rana }
10647151e4bSgaurav rana #else
10747151e4bSgaurav rana /* For platforms like LS1020, correct flash address is present in
10847151e4bSgaurav rana  * the header. So the function reqturns flash base address as 0
10947151e4bSgaurav rana  */
get_csf_base_addr(u32 * csf_addr,u32 * flash_base_addr)1107bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
11147151e4bSgaurav rana {
11247151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
11347151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
11447151e4bSgaurav rana 
1159711f528SAneesh Bansal 	if (memcmp((u8 *)(uintptr_t)csf_hdr_addr,
1169711f528SAneesh Bansal 		   barker_code, ESBC_BARKER_LEN))
11747151e4bSgaurav rana 		return -1;
11847151e4bSgaurav rana 
11947151e4bSgaurav rana 	*csf_addr = csf_hdr_addr;
12047151e4bSgaurav rana 	*flash_base_addr = 0;
12147151e4bSgaurav rana 	return 0;
12247151e4bSgaurav rana }
12347151e4bSgaurav rana #endif
12447151e4bSgaurav rana 
125ac55dadbSUdit Agarwal #if defined(CONFIG_ESBC_HDR_LS)
get_ie_info_addr(uintptr_t * ie_addr)126ac55dadbSUdit Agarwal static int get_ie_info_addr(uintptr_t *ie_addr)
127ac55dadbSUdit Agarwal {
128ac55dadbSUdit Agarwal 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
129ac55dadbSUdit Agarwal 	/* For LS-CH3, the address of IE Table is
130ac55dadbSUdit Agarwal 	 * stated in Scratch13 and scratch14 of DCFG.
131ac55dadbSUdit Agarwal 	 * Bootrom validates this table while validating uboot.
132ac55dadbSUdit Agarwal 	 * DCFG is LE*/
133ac55dadbSUdit Agarwal 	*ie_addr = in_le32(&gur->scratchrw[SCRATCH_IE_HIGH_ADR - 1]);
134ac55dadbSUdit Agarwal 	*ie_addr = *ie_addr << 32;
135ac55dadbSUdit Agarwal 	*ie_addr |= in_le32(&gur->scratchrw[SCRATCH_IE_LOW_ADR - 1]);
136ac55dadbSUdit Agarwal 	return 0;
137ac55dadbSUdit Agarwal }
138ac55dadbSUdit Agarwal #else /* CONFIG_ESBC_HDR_LS */
get_ie_info_addr(uintptr_t * ie_addr)139ac55dadbSUdit Agarwal static int get_ie_info_addr(uintptr_t *ie_addr)
14047151e4bSgaurav rana {
14147151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
14247151e4bSgaurav rana 	struct fsl_secboot_sg_table *sg_tbl;
1437bcb0eb2SAneesh Bansal 	u32 flash_base_addr, csf_addr;
14447151e4bSgaurav rana 
14547151e4bSgaurav rana 	if (get_csf_base_addr(&csf_addr, &flash_base_addr))
14647151e4bSgaurav rana 		return -1;
14747151e4bSgaurav rana 
1489711f528SAneesh Bansal 	hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr;
14947151e4bSgaurav rana 
15047151e4bSgaurav rana 	/* For SoC's with Trust Architecture v1 with corenet bus
15147151e4bSgaurav rana 	 * the sg table field in CSF header has absolute address
15247151e4bSgaurav rana 	 * for sg table in memory. In other Trust Architecture,
15347151e4bSgaurav rana 	 * this field specifies the offset of sg table from the
15447151e4bSgaurav rana 	 * base address of CSF Header
15547151e4bSgaurav rana 	 */
15647151e4bSgaurav rana #if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
15747151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)
1587bcb0eb2SAneesh Bansal 		 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
15947151e4bSgaurav rana 		  flash_base_addr);
16047151e4bSgaurav rana #else
1619711f528SAneesh Bansal 	sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
1627bcb0eb2SAneesh Bansal 						 (u32)hdr->psgtable);
16347151e4bSgaurav rana #endif
16447151e4bSgaurav rana 
16547151e4bSgaurav rana 	/* IE Key Table is the first entry in the SG Table */
16647151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
167ac55dadbSUdit Agarwal 	*ie_addr = (uintptr_t)((sg_tbl->src_addr &
168ac55dadbSUdit Agarwal 			~(CONFIG_SYS_PBI_FLASH_BASE)) +
169ac55dadbSUdit Agarwal 			flash_base_addr);
17047151e4bSgaurav rana #else
171ac55dadbSUdit Agarwal 	*ie_addr = (uintptr_t)sg_tbl->src_addr;
17247151e4bSgaurav rana #endif
17347151e4bSgaurav rana 
174ac55dadbSUdit Agarwal 	debug("IE Table address is %lx\n", *ie_addr);
17547151e4bSgaurav rana 	return 0;
17647151e4bSgaurav rana }
177ac55dadbSUdit Agarwal #endif /* CONFIG_ESBC_HDR_LS */
17847151e4bSgaurav rana #endif
17947151e4bSgaurav rana 
18047151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
18147151e4bSgaurav rana /* This function checks srk_table_flag in header and set/reset srk_flag.*/
check_srk(struct fsl_secboot_img_priv * img)18247151e4bSgaurav rana static u32 check_srk(struct fsl_secboot_img_priv *img)
18347151e4bSgaurav rana {
184fd6dbc98SSaksham Jain #ifdef CONFIG_ESBC_HDR_LS
185ac55dadbSUdit Agarwal 	/* In LS, No SRK Flag as SRK is always present if IE not present*/
186ac55dadbSUdit Agarwal #if defined(CONFIG_FSL_ISBC_KEY_EXT)
187ac55dadbSUdit Agarwal 	return !check_ie(img);
188ac55dadbSUdit Agarwal #endif
189fd6dbc98SSaksham Jain 	return 1;
190fd6dbc98SSaksham Jain #else
19147151e4bSgaurav rana 	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
19247151e4bSgaurav rana 		return 1;
19347151e4bSgaurav rana 
19447151e4bSgaurav rana 	return 0;
195fd6dbc98SSaksham Jain #endif
19647151e4bSgaurav rana }
19747151e4bSgaurav rana 
19847151e4bSgaurav rana /* This function returns ospr's key_revoc values.*/
get_key_revoc(void)19947151e4bSgaurav rana static u32 get_key_revoc(void)
20047151e4bSgaurav rana {
20147151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
20247151e4bSgaurav rana 	return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
20347151e4bSgaurav rana 		OSPR_KEY_REVOC_SHIFT;
20447151e4bSgaurav rana }
20547151e4bSgaurav rana 
20647151e4bSgaurav rana /* This function checks if selected key is revoked or not.*/
is_key_revoked(u32 keynum,u32 rev_flag)20747151e4bSgaurav rana static u32 is_key_revoked(u32 keynum, u32 rev_flag)
20847151e4bSgaurav rana {
20947151e4bSgaurav rana 	if (keynum == UNREVOCABLE_KEY)
21047151e4bSgaurav rana 		return 0;
21147151e4bSgaurav rana 
21247151e4bSgaurav rana 	if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
21347151e4bSgaurav rana 		return 1;
21447151e4bSgaurav rana 
21547151e4bSgaurav rana 	return 0;
21647151e4bSgaurav rana }
21747151e4bSgaurav rana 
21894ba5e41SAneesh Bansal /* It read validates srk_table key lengths.*/
read_validate_srk_tbl(struct fsl_secboot_img_priv * img)21994ba5e41SAneesh Bansal static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
22047151e4bSgaurav rana {
22147151e4bSgaurav rana 	int i = 0;
22294ba5e41SAneesh Bansal 	u32 ret, key_num, key_revoc_flag, size;
22394ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
22494ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
22594ba5e41SAneesh Bansal 
22694ba5e41SAneesh Bansal 	if ((hdr->len_kr.num_srk == 0) ||
22794ba5e41SAneesh Bansal 	    (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
22894ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
22994ba5e41SAneesh Bansal 
23094ba5e41SAneesh Bansal 	key_num = hdr->len_kr.srk_sel;
23194ba5e41SAneesh Bansal 	if (key_num == 0 || key_num > hdr->len_kr.num_srk)
23294ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
23394ba5e41SAneesh Bansal 
23494ba5e41SAneesh Bansal 	/* Get revoc key from sfp */
23594ba5e41SAneesh Bansal 	key_revoc_flag = get_key_revoc();
23694ba5e41SAneesh Bansal 	ret = is_key_revoked(key_num, key_revoc_flag);
23794ba5e41SAneesh Bansal 	if (ret)
23894ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
23994ba5e41SAneesh Bansal 
24094ba5e41SAneesh Bansal 	size = hdr->len_kr.num_srk * sizeof(struct srk_table);
24194ba5e41SAneesh Bansal 
24294ba5e41SAneesh Bansal 	memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
24394ba5e41SAneesh Bansal 
24494ba5e41SAneesh Bansal 	for (i = 0; i < hdr->len_kr.num_srk; i++) {
24594ba5e41SAneesh Bansal 		if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
24647151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
24747151e4bSgaurav rana 	}
24894ba5e41SAneesh Bansal 
24994ba5e41SAneesh Bansal 	img->key_len = img->srk_tbl[key_num - 1].key_len;
25094ba5e41SAneesh Bansal 
25194ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
25294ba5e41SAneesh Bansal 	       img->key_len);
25394ba5e41SAneesh Bansal 
25447151e4bSgaurav rana 	return 0;
25547151e4bSgaurav rana }
25647151e4bSgaurav rana #endif
25747151e4bSgaurav rana 
258fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
read_validate_single_key(struct fsl_secboot_img_priv * img)25994ba5e41SAneesh Bansal static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
26094ba5e41SAneesh Bansal {
26194ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
26294ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
26394ba5e41SAneesh Bansal 
26494ba5e41SAneesh Bansal 	/* check key length */
26594ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(hdr->key_len))
26694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
26794ba5e41SAneesh Bansal 
26894ba5e41SAneesh Bansal 	memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
26994ba5e41SAneesh Bansal 
27094ba5e41SAneesh Bansal 	img->key_len = hdr->key_len;
27194ba5e41SAneesh Bansal 
27294ba5e41SAneesh Bansal 	return 0;
27394ba5e41SAneesh Bansal }
274fd6dbc98SSaksham Jain #endif /* CONFIG_ESBC_HDR_LS */
27594ba5e41SAneesh Bansal 
27694ba5e41SAneesh Bansal #if defined(CONFIG_FSL_ISBC_KEY_EXT)
277ac55dadbSUdit Agarwal 
install_ie_tbl(uintptr_t ie_tbl_addr,struct fsl_secboot_img_priv * img)278ac55dadbSUdit Agarwal static void install_ie_tbl(uintptr_t ie_tbl_addr,
279ac55dadbSUdit Agarwal 		struct fsl_secboot_img_priv *img)
280ac55dadbSUdit Agarwal {
281ac55dadbSUdit Agarwal 	/* Copy IE tbl to Global Data */
282ac55dadbSUdit Agarwal 	memcpy(&glb.ie_tbl, (u8 *)ie_tbl_addr, sizeof(struct ie_key_info));
283ac55dadbSUdit Agarwal 	img->ie_addr = (uintptr_t)&glb.ie_tbl;
284ac55dadbSUdit Agarwal 	glb.ie_addr = img->ie_addr;
285ac55dadbSUdit Agarwal }
286ac55dadbSUdit Agarwal 
read_validate_ie_tbl(struct fsl_secboot_img_priv * img)28794ba5e41SAneesh Bansal static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
28894ba5e41SAneesh Bansal {
28994ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
29094ba5e41SAneesh Bansal 	u32 ie_key_len, ie_revoc_flag, ie_num;
29194ba5e41SAneesh Bansal 	struct ie_key_info *ie_info;
29294ba5e41SAneesh Bansal 
293ac55dadbSUdit Agarwal 	if (!img->ie_addr) {
29494ba5e41SAneesh Bansal 		if (get_ie_info_addr(&img->ie_addr))
29594ba5e41SAneesh Bansal 			return ERROR_IE_TABLE_NOT_FOUND;
296ac55dadbSUdit Agarwal 		else
297ac55dadbSUdit Agarwal 			install_ie_tbl(img->ie_addr, img);
298ac55dadbSUdit Agarwal 		}
299ac55dadbSUdit Agarwal 
30094ba5e41SAneesh Bansal 	ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
30194ba5e41SAneesh Bansal 	if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
30294ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
30394ba5e41SAneesh Bansal 
30494ba5e41SAneesh Bansal 	ie_num = hdr->ie_key_sel;
30594ba5e41SAneesh Bansal 	if (ie_num == 0 || ie_num > ie_info->num_keys)
30694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
30794ba5e41SAneesh Bansal 
30894ba5e41SAneesh Bansal 	ie_revoc_flag = ie_info->key_revok;
30994ba5e41SAneesh Bansal 	if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
31094ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
31194ba5e41SAneesh Bansal 
31294ba5e41SAneesh Bansal 	ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
31394ba5e41SAneesh Bansal 
31494ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(ie_key_len))
31594ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
31694ba5e41SAneesh Bansal 
31794ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
31894ba5e41SAneesh Bansal 	       ie_key_len);
31994ba5e41SAneesh Bansal 
32094ba5e41SAneesh Bansal 	img->key_len = ie_key_len;
32194ba5e41SAneesh Bansal 	return 0;
32294ba5e41SAneesh Bansal }
32394ba5e41SAneesh Bansal #endif
32494ba5e41SAneesh Bansal 
32594ba5e41SAneesh Bansal 
32647151e4bSgaurav rana /* This function return length of public key.*/
get_key_len(struct fsl_secboot_img_priv * img)32747151e4bSgaurav rana static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
32847151e4bSgaurav rana {
32947151e4bSgaurav rana 	return img->key_len;
33047151e4bSgaurav rana }
33147151e4bSgaurav rana 
33247151e4bSgaurav rana /*
33347151e4bSgaurav rana  * Handles the ESBC uboot client header verification failure.
33447151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
33547151e4bSgaurav rana  * parsing and checking of ESBC uboot client header. It will also
33647151e4bSgaurav rana  * set the error bits in the SEC_MON.
33747151e4bSgaurav rana  */
fsl_secboot_header_verification_failure(void)33847151e4bSgaurav rana static void fsl_secboot_header_verification_failure(void)
33947151e4bSgaurav rana {
34047151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
34147151e4bSgaurav rana 
34247151e4bSgaurav rana 	/* 29th bit of OSPR is ITS */
34347151e4bSgaurav rana 	u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
34447151e4bSgaurav rana 
34547151e4bSgaurav rana 	if (its == 1)
346b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
34747151e4bSgaurav rana 	else
348b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
34947151e4bSgaurav rana 
35047151e4bSgaurav rana 	printf("Generating reset request\n");
35147151e4bSgaurav rana 	do_reset(NULL, 0, 0, NULL);
352c4666cf6SSaksham Jain 	/* If reset doesn't coocur, halt execution */
353c4666cf6SSaksham Jain 	do_esbc_halt(NULL, 0, 0, NULL);
35447151e4bSgaurav rana }
35547151e4bSgaurav rana 
35647151e4bSgaurav rana /*
35747151e4bSgaurav rana  * Handles the ESBC uboot client image verification failure.
35847151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
35947151e4bSgaurav rana  * public key hash comparison and signature verification of
36047151e4bSgaurav rana  * ESBC uboot client image. It will also
36147151e4bSgaurav rana  * set the error bits in the SEC_MON.
36247151e4bSgaurav rana  */
fsl_secboot_image_verification_failure(void)36347151e4bSgaurav rana static void fsl_secboot_image_verification_failure(void)
36447151e4bSgaurav rana {
36547151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
36647151e4bSgaurav rana 
3676ec9aef2SAneesh Bansal 	u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
36847151e4bSgaurav rana 
36947151e4bSgaurav rana 	if (its == 1) {
370b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
37147151e4bSgaurav rana 
37247151e4bSgaurav rana 		printf("Generating reset request\n");
37347151e4bSgaurav rana 		do_reset(NULL, 0, 0, NULL);
374c4666cf6SSaksham Jain 		/* If reset doesn't coocur, halt execution */
375c4666cf6SSaksham Jain 		do_esbc_halt(NULL, 0, 0, NULL);
376c4666cf6SSaksham Jain 
37747151e4bSgaurav rana 	} else {
378b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
37947151e4bSgaurav rana 	}
38047151e4bSgaurav rana }
38147151e4bSgaurav rana 
fsl_secboot_bootscript_parse_failure(void)38247151e4bSgaurav rana static void fsl_secboot_bootscript_parse_failure(void)
38347151e4bSgaurav rana {
38447151e4bSgaurav rana 	fsl_secboot_header_verification_failure();
38547151e4bSgaurav rana }
38647151e4bSgaurav rana 
38747151e4bSgaurav rana /*
38847151e4bSgaurav rana  * Handles the errors in esbc boot.
38947151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
39047151e4bSgaurav rana  * esbc boot phase. It will call the appropriate api to log the
39147151e4bSgaurav rana  * errors and set the error bits in the SEC_MON.
39247151e4bSgaurav rana  */
fsl_secboot_handle_error(int error)39347151e4bSgaurav rana void fsl_secboot_handle_error(int error)
39447151e4bSgaurav rana {
39570f9661cSRuchika Gupta #ifndef CONFIG_SPL_BUILD
39647151e4bSgaurav rana 	const struct fsl_secboot_errcode *e;
39747151e4bSgaurav rana 
39847151e4bSgaurav rana 	for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
39947151e4bSgaurav rana 		e++) {
40047151e4bSgaurav rana 		if (e->errcode == error)
40147151e4bSgaurav rana 			printf("ERROR :: %x :: %s\n", error, e->name);
40247151e4bSgaurav rana 	}
40370f9661cSRuchika Gupta #else
40470f9661cSRuchika Gupta 	printf("ERROR :: %x\n", error);
40570f9661cSRuchika Gupta #endif
40647151e4bSgaurav rana 
407856b2846SAneesh Bansal 	/* If Boot Mode is secure, transition the SNVS state and issue
408856b2846SAneesh Bansal 	 * reset based on type of failure and ITS setting.
409856b2846SAneesh Bansal 	 * If Boot mode is non-secure, return from this function.
410856b2846SAneesh Bansal 	 */
411856b2846SAneesh Bansal 	if (fsl_check_boot_mode_secure() == 0)
412856b2846SAneesh Bansal 		return;
413856b2846SAneesh Bansal 
41447151e4bSgaurav rana 	switch (error) {
41547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_BARKER:
41647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
41747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
41847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
41947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
42047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
42147151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
42247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
42347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
42447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
425fd6dbc98SSaksham Jain 	case ERROR_KEY_TABLE_NOT_FOUND:
42647151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
42747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
42847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
42947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
43047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
43147151e4bSgaurav rana #endif
43247151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
43347151e4bSgaurav rana 	/*@fallthrough@*/
43447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
43547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
43647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
43747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
43847151e4bSgaurav rana 	case ERROR_IE_TABLE_NOT_FOUND:
43947151e4bSgaurav rana #endif
44047151e4bSgaurav rana 		fsl_secboot_header_verification_failure();
44147151e4bSgaurav rana 		break;
44247151e4bSgaurav rana 	case ERROR_ESBC_SEC_RESET:
44347151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
44447151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
44547151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
44647151e4bSgaurav rana 	case ERROR_ESBC_SEC_JOBQ_STATUS:
44747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
44847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
44947151e4bSgaurav rana 		fsl_secboot_image_verification_failure();
45047151e4bSgaurav rana 		break;
45147151e4bSgaurav rana 	case ERROR_ESBC_MISSING_BOOTM:
45247151e4bSgaurav rana 		fsl_secboot_bootscript_parse_failure();
45347151e4bSgaurav rana 		break;
45447151e4bSgaurav rana 	case ERROR_ESBC_WRONG_CMD:
45547151e4bSgaurav rana 	default:
45647151e4bSgaurav rana 		branch_to_self();
45747151e4bSgaurav rana 		break;
45847151e4bSgaurav rana 	}
45947151e4bSgaurav rana }
46047151e4bSgaurav rana 
fsl_secblk_handle_error(int error)46147151e4bSgaurav rana static void fsl_secblk_handle_error(int error)
46247151e4bSgaurav rana {
46347151e4bSgaurav rana 	switch (error) {
46447151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
46547151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
46647151e4bSgaurav rana 		break;
46747151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
46847151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
46947151e4bSgaurav rana 		break;
47047151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
47147151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
47247151e4bSgaurav rana 		break;
47347151e4bSgaurav rana 	default:
47447151e4bSgaurav rana 		printf("Job Queue Output status %x\n", error);
47547151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
47647151e4bSgaurav rana 		break;
47747151e4bSgaurav rana 	}
47847151e4bSgaurav rana }
47947151e4bSgaurav rana 
48047151e4bSgaurav rana /*
48147151e4bSgaurav rana  * Calculate hash of key obtained via offset present in ESBC uboot
48247151e4bSgaurav rana  * client hdr. This function calculates the hash of key which is obtained
48347151e4bSgaurav rana  * through offset present in ESBC uboot client header.
48447151e4bSgaurav rana  */
calc_img_key_hash(struct fsl_secboot_img_priv * img)48547151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
48647151e4bSgaurav rana {
48747151e4bSgaurav rana 	struct hash_algo *algo;
48847151e4bSgaurav rana 	void *ctx;
48947151e4bSgaurav rana 	int i, srk = 0;
49047151e4bSgaurav rana 	int ret = 0;
49147151e4bSgaurav rana 	const char *algo_name = "sha256";
49247151e4bSgaurav rana 
49347151e4bSgaurav rana 	/* Calculate hash of the esbc key */
49447151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
49547151e4bSgaurav rana 	if (ret)
49647151e4bSgaurav rana 		return ret;
49747151e4bSgaurav rana 
49847151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
49947151e4bSgaurav rana 	if (ret)
50047151e4bSgaurav rana 		return ret;
50147151e4bSgaurav rana 
50247151e4bSgaurav rana 	/* Update hash for ESBC key */
50347151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
50447151e4bSgaurav rana 	if (check_srk(img)) {
50547151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
5069711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
50747151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
50847151e4bSgaurav rana 		srk = 1;
50947151e4bSgaurav rana 	}
51047151e4bSgaurav rana #endif
51147151e4bSgaurav rana 	if (!srk)
51247151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
51347151e4bSgaurav rana 			img->img_key, img->key_len, 1);
51447151e4bSgaurav rana 	if (ret)
51547151e4bSgaurav rana 		return ret;
51647151e4bSgaurav rana 
51747151e4bSgaurav rana 	/* Copy hash at destination buffer */
51847151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
51947151e4bSgaurav rana 	if (ret)
52047151e4bSgaurav rana 		return ret;
52147151e4bSgaurav rana 
52247151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
52347151e4bSgaurav rana 		img->img_key_hash[i] = hash_val[i];
52447151e4bSgaurav rana 
52547151e4bSgaurav rana 	return 0;
52647151e4bSgaurav rana }
52747151e4bSgaurav rana 
52847151e4bSgaurav rana /*
52947151e4bSgaurav rana  * Calculate hash of ESBC hdr and ESBC. This function calculates the
53047151e4bSgaurav rana  * single hash of ESBC header and ESBC image. If SG flag is on, all
53147151e4bSgaurav rana  * SG entries are also hashed alongwith the complete SG table.
53247151e4bSgaurav rana  */
calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv * img)53347151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
53447151e4bSgaurav rana {
53547151e4bSgaurav rana 	struct hash_algo *algo;
53647151e4bSgaurav rana 	void *ctx;
53747151e4bSgaurav rana 	int ret = 0;
53847151e4bSgaurav rana 	int key_hash = 0;
53947151e4bSgaurav rana 	const char *algo_name = "sha256";
54047151e4bSgaurav rana 
54147151e4bSgaurav rana 	/* Calculate the hash of the ESBC */
54247151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
54347151e4bSgaurav rana 	if (ret)
54447151e4bSgaurav rana 		return ret;
54547151e4bSgaurav rana 
54647151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
54747151e4bSgaurav rana 	/* Copy hash at destination buffer */
54847151e4bSgaurav rana 	if (ret)
54947151e4bSgaurav rana 		return ret;
55047151e4bSgaurav rana 
55147151e4bSgaurav rana 	/* Update hash for CSF Header */
55247151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
55347151e4bSgaurav rana 		(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
55447151e4bSgaurav rana 	if (ret)
55547151e4bSgaurav rana 		return ret;
55647151e4bSgaurav rana 
55747151e4bSgaurav rana 	/* Update the hash with that of srk table if srk flag is 1
55847151e4bSgaurav rana 	 * If IE Table is selected, key is not added in the hash
55947151e4bSgaurav rana 	 * If neither srk table nor IE key table available, add key
56047151e4bSgaurav rana 	 * from header in the hash calculation
56147151e4bSgaurav rana 	 */
56247151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
56347151e4bSgaurav rana 	if (check_srk(img)) {
56447151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
5659711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
56647151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
56747151e4bSgaurav rana 		key_hash = 1;
56847151e4bSgaurav rana 	}
56947151e4bSgaurav rana #endif
57047151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
57147151e4bSgaurav rana 	if (!key_hash && check_ie(img))
57247151e4bSgaurav rana 		key_hash = 1;
57347151e4bSgaurav rana #endif
574fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
575fd6dbc98SSaksham Jain /* No single key support in LS ESBC header */
576fd6dbc98SSaksham Jain 	if (!key_hash) {
57747151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
57847151e4bSgaurav rana 			img->img_key, img->hdr.key_len, 0);
579fd6dbc98SSaksham Jain 		key_hash = 1;
580fd6dbc98SSaksham Jain 	}
581fd6dbc98SSaksham Jain #endif
58247151e4bSgaurav rana 	if (ret)
58347151e4bSgaurav rana 		return ret;
584fd6dbc98SSaksham Jain 	if (!key_hash)
585fd6dbc98SSaksham Jain 		return ERROR_KEY_TABLE_NOT_FOUND;
58647151e4bSgaurav rana 
58747151e4bSgaurav rana 	/* Update hash for actual Image */
58847151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
58985bb3896SSaksham Jain 		(u8 *)(*(img->img_addr_ptr)), img->img_size, 1);
59047151e4bSgaurav rana 	if (ret)
59147151e4bSgaurav rana 		return ret;
59247151e4bSgaurav rana 
59347151e4bSgaurav rana 	/* Copy hash at destination buffer */
59447151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
59547151e4bSgaurav rana 	if (ret)
59647151e4bSgaurav rana 		return ret;
59747151e4bSgaurav rana 
59847151e4bSgaurav rana 	return 0;
59947151e4bSgaurav rana }
60047151e4bSgaurav rana 
60147151e4bSgaurav rana /*
60247151e4bSgaurav rana  * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
60347151e4bSgaurav rana  * pointers for padding, DER value and hash. And finally, constructs EM'
60447151e4bSgaurav rana  * which includes hash of complete CSF header and ESBC image. If SG flag
60547151e4bSgaurav rana  * is on, hash of SG table and entries is also included.
60647151e4bSgaurav rana  */
construct_img_encoded_hash_second(struct fsl_secboot_img_priv * img)60747151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
60847151e4bSgaurav rana {
60947151e4bSgaurav rana 	/*
61047151e4bSgaurav rana 	 * RSA PKCSv1.5 encoding format for encoded message is below
61147151e4bSgaurav rana 	 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
61247151e4bSgaurav rana 	 * PS is Padding String
61347151e4bSgaurav rana 	 * DER is DER value for SHA-256
61447151e4bSgaurav rana 	 * Hash is SHA-256 hash
61547151e4bSgaurav rana 	 * *********************************************************
61647151e4bSgaurav rana 	 * representative points to first byte of EM initially and is
61747151e4bSgaurav rana 	 * filled with 0x0
61847151e4bSgaurav rana 	 * representative is incremented by 1 and second byte is filled
61947151e4bSgaurav rana 	 * with 0x1
62047151e4bSgaurav rana 	 * padding points to third byte of EM
62147151e4bSgaurav rana 	 * digest points to full length of EM - 32 bytes
62247151e4bSgaurav rana 	 * hash_id (DER value) points to 19 bytes before pDigest
62347151e4bSgaurav rana 	 * separator is one byte which separates padding and DER
62447151e4bSgaurav rana 	 */
62547151e4bSgaurav rana 
62647151e4bSgaurav rana 	size_t len;
62747151e4bSgaurav rana 	u8 *representative;
62847151e4bSgaurav rana 	u8 *padding, *digest;
62947151e4bSgaurav rana 	u8 *hash_id, *separator;
63047151e4bSgaurav rana 	int i;
63147151e4bSgaurav rana 
63247151e4bSgaurav rana 	len = (get_key_len(img) / 2) - 1;
63347151e4bSgaurav rana 	representative = img->img_encoded_hash_second;
63447151e4bSgaurav rana 	representative[0] = 0;
63547151e4bSgaurav rana 	representative[1] = 1;  /* block type 1 */
63647151e4bSgaurav rana 
63747151e4bSgaurav rana 	padding = &representative[2];
63847151e4bSgaurav rana 	digest = &representative[1] + len - 32;
63947151e4bSgaurav rana 	hash_id = digest - sizeof(hash_identifier);
64047151e4bSgaurav rana 	separator = hash_id - 1;
64147151e4bSgaurav rana 
64247151e4bSgaurav rana 	/* fill padding area pointed by padding with 0xff */
64347151e4bSgaurav rana 	memset(padding, 0xff, separator - padding);
64447151e4bSgaurav rana 
64547151e4bSgaurav rana 	/* fill byte pointed by separator */
64647151e4bSgaurav rana 	*separator = 0;
64747151e4bSgaurav rana 
64847151e4bSgaurav rana 	/* fill SHA-256 DER value  pointed by HashId */
64947151e4bSgaurav rana 	memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
65047151e4bSgaurav rana 
65147151e4bSgaurav rana 	/* fill hash pointed by Digest */
65247151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
65347151e4bSgaurav rana 		digest[i] = hash_val[i];
65447151e4bSgaurav rana }
65547151e4bSgaurav rana 
65647151e4bSgaurav rana /*
65747151e4bSgaurav rana  * Reads and validates the ESBC client header.
65847151e4bSgaurav rana  * This function reads key and signature from the ESBC client header.
65947151e4bSgaurav rana  * If Scatter/Gather flag is on, lengths and offsets of images
66047151e4bSgaurav rana  * present as SG entries are also read. This function also checks
66147151e4bSgaurav rana  * whether the header is valid or not.
66247151e4bSgaurav rana  */
read_validate_esbc_client_header(struct fsl_secboot_img_priv * img)66347151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
66447151e4bSgaurav rana {
66547151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
6669711f528SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
66747151e4bSgaurav rana 	u8 *k, *s;
66894ba5e41SAneesh Bansal 	u32 ret = 0;
66994ba5e41SAneesh Bansal 
67047151e4bSgaurav rana 	int  key_found = 0;
67147151e4bSgaurav rana 
67247151e4bSgaurav rana 	/* check barker code */
67347151e4bSgaurav rana 	if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
67447151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_BARKER;
67547151e4bSgaurav rana 
676b055a0fdSAneesh Bansal 	/* If Image Address is not passed as argument to function,
677b055a0fdSAneesh Bansal 	 * then Address and Size must be read from the Header.
678b055a0fdSAneesh Bansal 	 */
67985bb3896SSaksham Jain 	if (*(img->img_addr_ptr) == 0) {
6809711f528SAneesh Bansal 	#ifdef CONFIG_ESBC_ADDR_64BIT
68185bb3896SSaksham Jain 		*(img->img_addr_ptr) = hdr->pimg64;
6829711f528SAneesh Bansal 	#else
68385bb3896SSaksham Jain 		*(img->img_addr_ptr) = hdr->pimg;
6849711f528SAneesh Bansal 	#endif
685b055a0fdSAneesh Bansal 	}
686b055a0fdSAneesh Bansal 
68747151e4bSgaurav rana 	if (!hdr->img_size)
68847151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
68947151e4bSgaurav rana 
690b055a0fdSAneesh Bansal 	img->img_size = hdr->img_size;
691b055a0fdSAneesh Bansal 
69247151e4bSgaurav rana 	/* Key checking*/
69347151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
69447151e4bSgaurav rana 	if (check_srk(img)) {
69594ba5e41SAneesh Bansal 		ret = read_validate_srk_tbl(img);
69647151e4bSgaurav rana 		if (ret != 0)
69747151e4bSgaurav rana 			return ret;
69847151e4bSgaurav rana 		key_found = 1;
69947151e4bSgaurav rana 	}
70047151e4bSgaurav rana #endif
70147151e4bSgaurav rana 
70247151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
70347151e4bSgaurav rana 	if (!key_found && check_ie(img)) {
70494ba5e41SAneesh Bansal 		ret = read_validate_ie_tbl(img);
70594ba5e41SAneesh Bansal 		if (ret != 0)
70694ba5e41SAneesh Bansal 			return ret;
70747151e4bSgaurav rana 		key_found = 1;
70847151e4bSgaurav rana 	}
70947151e4bSgaurav rana #endif
710fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
711fd6dbc98SSaksham Jain /* Single Key Feature not available in LS ESBC Header */
71247151e4bSgaurav rana 	if (key_found == 0) {
71394ba5e41SAneesh Bansal 		ret = read_validate_single_key(img);
71494ba5e41SAneesh Bansal 		if (ret != 0)
71594ba5e41SAneesh Bansal 			return ret;
71647151e4bSgaurav rana 		key_found = 1;
71747151e4bSgaurav rana 	}
718fd6dbc98SSaksham Jain #endif
719fd6dbc98SSaksham Jain 	if (!key_found)
720fd6dbc98SSaksham Jain 		return ERROR_KEY_TABLE_NOT_FOUND;
72147151e4bSgaurav rana 
72247151e4bSgaurav rana 	/* check signaure */
72347151e4bSgaurav rana 	if (get_key_len(img) == 2 * hdr->sign_len) {
72447151e4bSgaurav rana 		/* check signature length */
72547151e4bSgaurav rana 		if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
72647151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
72747151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES)))
72847151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
72947151e4bSgaurav rana 	} else {
73047151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
73147151e4bSgaurav rana 	}
73247151e4bSgaurav rana 
73347151e4bSgaurav rana 	memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
734fd6dbc98SSaksham Jain /* No SG support in LS-CH3 */
735fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
73647151e4bSgaurav rana 	/* No SG support */
73747151e4bSgaurav rana 	if (hdr->sg_flag)
73847151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SG;
739fd6dbc98SSaksham Jain #endif
74047151e4bSgaurav rana 
74147151e4bSgaurav rana 	/* modulus most significant bit should be set */
74247151e4bSgaurav rana 	k = (u8 *)&img->img_key;
74347151e4bSgaurav rana 
74447151e4bSgaurav rana 	if ((k[0] & 0x80) == 0)
74547151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
74647151e4bSgaurav rana 
74747151e4bSgaurav rana 	/* modulus value should be odd */
74847151e4bSgaurav rana 	if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
74947151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
75047151e4bSgaurav rana 
75147151e4bSgaurav rana 	/* Check signature value < modulus value */
75247151e4bSgaurav rana 	s = (u8 *)&img->img_sign;
75347151e4bSgaurav rana 
75447151e4bSgaurav rana 	if (!(memcmp(s, k, hdr->sign_len) < 0))
75547151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
75647151e4bSgaurav rana 
75747151e4bSgaurav rana 	return ESBC_VALID_HDR;
75847151e4bSgaurav rana }
75947151e4bSgaurav rana 
str2longbe(const char * p,ulong * num)76047151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num)
76147151e4bSgaurav rana {
76247151e4bSgaurav rana 	char *endptr;
76347151e4bSgaurav rana 	ulong tmp;
76447151e4bSgaurav rana 
76547151e4bSgaurav rana 	if (!p) {
76647151e4bSgaurav rana 		return 0;
76747151e4bSgaurav rana 	} else {
76847151e4bSgaurav rana 		tmp = simple_strtoul(p, &endptr, 16);
76947151e4bSgaurav rana 		if (sizeof(ulong) == 4)
77047151e4bSgaurav rana 			*num = cpu_to_be32(tmp);
77147151e4bSgaurav rana 		else
77247151e4bSgaurav rana 			*num = cpu_to_be64(tmp);
77347151e4bSgaurav rana 	}
77447151e4bSgaurav rana 
77547151e4bSgaurav rana 	return *p != '\0' && *endptr == '\0';
77647151e4bSgaurav rana }
7776629261dSAneesh Bansal /* Function to calculate the ESBC Image Hash
7786629261dSAneesh Bansal  * and hash from Digital signature.
7796629261dSAneesh Bansal  * The Two hash's are compared to yield the
7806629261dSAneesh Bansal  * result of signature validation.
7816629261dSAneesh Bansal  */
calculate_cmp_img_sig(struct fsl_secboot_img_priv * img)7826629261dSAneesh Bansal static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
7836629261dSAneesh Bansal {
7846629261dSAneesh Bansal 	int ret;
7856629261dSAneesh Bansal 	uint32_t key_len;
7866629261dSAneesh Bansal 	struct key_prop prop;
7876629261dSAneesh Bansal #if !defined(USE_HOSTCC)
7886629261dSAneesh Bansal 	struct udevice *mod_exp_dev;
7896629261dSAneesh Bansal #endif
7906629261dSAneesh Bansal 	ret = calc_esbchdr_esbc_hash(img);
7916629261dSAneesh Bansal 	if (ret)
7926629261dSAneesh Bansal 		return ret;
7936629261dSAneesh Bansal 
7946629261dSAneesh Bansal 	/* Construct encoded hash EM' wrt PKCSv1.5 */
7956629261dSAneesh Bansal 	construct_img_encoded_hash_second(img);
7966629261dSAneesh Bansal 
7976629261dSAneesh Bansal 	/* Fill prop structure for public key */
7986629261dSAneesh Bansal 	memset(&prop, 0, sizeof(struct key_prop));
7996629261dSAneesh Bansal 	key_len = get_key_len(img) / 2;
8006629261dSAneesh Bansal 	prop.modulus = img->img_key;
8016629261dSAneesh Bansal 	prop.public_exponent = img->img_key + key_len;
8026629261dSAneesh Bansal 	prop.num_bits = key_len * 8;
8036629261dSAneesh Bansal 	prop.exp_len = key_len;
8046629261dSAneesh Bansal 
8056629261dSAneesh Bansal 	ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
8066629261dSAneesh Bansal 	if (ret) {
8076629261dSAneesh Bansal 		printf("RSA: Can't find Modular Exp implementation\n");
8086629261dSAneesh Bansal 		return -EINVAL;
8096629261dSAneesh Bansal 	}
8106629261dSAneesh Bansal 
8116629261dSAneesh Bansal 	ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
8126629261dSAneesh Bansal 			  &prop, img->img_encoded_hash);
8136629261dSAneesh Bansal 	if (ret)
8146629261dSAneesh Bansal 		return ret;
8156629261dSAneesh Bansal 
8166629261dSAneesh Bansal 	/*
8176629261dSAneesh Bansal 	 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
8186629261dSAneesh Bansal 	 * memcmp returns zero on success
8196629261dSAneesh Bansal 	 * memcmp returns non-zero on failure
8206629261dSAneesh Bansal 	 */
8216629261dSAneesh Bansal 	ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
8226629261dSAneesh Bansal 		img->hdr.sign_len);
8236629261dSAneesh Bansal 
8246629261dSAneesh Bansal 	if (ret)
8256629261dSAneesh Bansal 		return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;
8266629261dSAneesh Bansal 
8276629261dSAneesh Bansal 	return 0;
8286629261dSAneesh Bansal }
829ac55dadbSUdit Agarwal /* Function to initialize img priv and global data structure
830ac55dadbSUdit Agarwal  */
secboot_init(struct fsl_secboot_img_priv ** img_ptr)831ac55dadbSUdit Agarwal static int secboot_init(struct fsl_secboot_img_priv **img_ptr)
832ac55dadbSUdit Agarwal {
833ac55dadbSUdit Agarwal 	*img_ptr = malloc(sizeof(struct fsl_secboot_img_priv));
834ac55dadbSUdit Agarwal 
835ac55dadbSUdit Agarwal 	struct fsl_secboot_img_priv *img = *img_ptr;
836ac55dadbSUdit Agarwal 
837ac55dadbSUdit Agarwal 	if (!img)
838ac55dadbSUdit Agarwal 		return -ENOMEM;
839ac55dadbSUdit Agarwal 	memset(img, 0, sizeof(struct fsl_secboot_img_priv));
840ac55dadbSUdit Agarwal 
841ac55dadbSUdit Agarwal #if defined(CONFIG_FSL_ISBC_KEY_EXT)
842ac55dadbSUdit Agarwal 	if (glb.ie_addr)
843ac55dadbSUdit Agarwal 		img->ie_addr = glb.ie_addr;
844ac55dadbSUdit Agarwal #endif
845ac55dadbSUdit Agarwal 	return 0;
846ac55dadbSUdit Agarwal }
847ac55dadbSUdit Agarwal 
848ac55dadbSUdit Agarwal 
84985bb3896SSaksham Jain /* haddr - Address of the header of image to be validated.
85085bb3896SSaksham Jain  * arg_hash_str - Option hash string. If provided, this
8511cc0a9f4SRobert P. J. Day  * overrides the key hash in the SFP fuses.
85285bb3896SSaksham Jain  * img_addr_ptr - Optional pointer to address of image to be validated.
8531cc0a9f4SRobert P. J. Day  * If non zero addr, this overrides the addr of image in header,
85485bb3896SSaksham Jain  * otherwise updated to image addr in header.
85585bb3896SSaksham Jain  * Acts as both input and output of function.
85685bb3896SSaksham Jain  * This pointer shouldn't be NULL.
85785bb3896SSaksham Jain  */
fsl_secboot_validate(uintptr_t haddr,char * arg_hash_str,uintptr_t * img_addr_ptr)858b055a0fdSAneesh Bansal int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
85985bb3896SSaksham Jain 			uintptr_t *img_addr_ptr)
86047151e4bSgaurav rana {
86147151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
86247151e4bSgaurav rana 	ulong hash[SHA256_BYTES/sizeof(ulong)];
86347151e4bSgaurav rana 	char hash_str[NUM_HEX_CHARS + 1];
86447151e4bSgaurav rana 	struct fsl_secboot_img_priv *img;
86547151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
86647151e4bSgaurav rana 	void *esbc;
86747151e4bSgaurav rana 	int ret, i, hash_cmd = 0;
86847151e4bSgaurav rana 	u32 srk_hash[8];
86947151e4bSgaurav rana 
870bc71f926SAneesh Bansal 	if (arg_hash_str != NULL) {
871bc71f926SAneesh Bansal 		const char *cp = arg_hash_str;
87247151e4bSgaurav rana 		int i = 0;
87347151e4bSgaurav rana 
87447151e4bSgaurav rana 		if (*cp == '0' && *(cp + 1) == 'x')
87547151e4bSgaurav rana 			cp += 2;
87647151e4bSgaurav rana 
87747151e4bSgaurav rana 		/* The input string expected is in hex, where
87847151e4bSgaurav rana 		 * each 4 bits would be represented by a hex
87947151e4bSgaurav rana 		 * sha256 hash is 256 bits long, which would mean
88047151e4bSgaurav rana 		 * num of characters = 256 / 4
88147151e4bSgaurav rana 		 */
88247151e4bSgaurav rana 		if (strlen(cp) != SHA256_NIBBLES) {
88347151e4bSgaurav rana 			printf("%s is not a 256 bits hex string as expected\n",
884bc71f926SAneesh Bansal 			       arg_hash_str);
88547151e4bSgaurav rana 			return -1;
88647151e4bSgaurav rana 		}
88747151e4bSgaurav rana 
88847151e4bSgaurav rana 		for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
88947151e4bSgaurav rana 			strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
89047151e4bSgaurav rana 				NUM_HEX_CHARS);
89147151e4bSgaurav rana 			hash_str[NUM_HEX_CHARS] = '\0';
89247151e4bSgaurav rana 			if (!str2longbe(hash_str, &hash[i])) {
89347151e4bSgaurav rana 				printf("%s is not a 256 bits hex string ",
894bc71f926SAneesh Bansal 				       arg_hash_str);
89547151e4bSgaurav rana 				return -1;
89647151e4bSgaurav rana 			}
89747151e4bSgaurav rana 		}
89847151e4bSgaurav rana 
89947151e4bSgaurav rana 		hash_cmd = 1;
90047151e4bSgaurav rana 	}
90147151e4bSgaurav rana 
902ac55dadbSUdit Agarwal 	ret = secboot_init(&img);
903ac55dadbSUdit Agarwal 	if (ret)
904ac55dadbSUdit Agarwal 		goto exit;
90547151e4bSgaurav rana 
906b055a0fdSAneesh Bansal 	/* Update the information in Private Struct */
90747151e4bSgaurav rana 	hdr = &img->hdr;
908bc71f926SAneesh Bansal 	img->ehdrloc = haddr;
90985bb3896SSaksham Jain 	img->img_addr_ptr = img_addr_ptr;
910b055a0fdSAneesh Bansal 	esbc = (u8 *)img->ehdrloc;
91147151e4bSgaurav rana 
91247151e4bSgaurav rana 	memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
91347151e4bSgaurav rana 
91447151e4bSgaurav rana 	/* read and validate esbc header */
91547151e4bSgaurav rana 	ret = read_validate_esbc_client_header(img);
91647151e4bSgaurav rana 
91747151e4bSgaurav rana 	if (ret != ESBC_VALID_HDR) {
91847151e4bSgaurav rana 		fsl_secboot_handle_error(ret);
91947151e4bSgaurav rana 		goto exit;
92047151e4bSgaurav rana 	}
92147151e4bSgaurav rana 
92247151e4bSgaurav rana 	/* SRKH present in SFP */
92347151e4bSgaurav rana 	for (i = 0; i < NUM_SRKH_REGS; i++)
92447151e4bSgaurav rana 		srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
92547151e4bSgaurav rana 
92647151e4bSgaurav rana 	/*
92747151e4bSgaurav rana 	 * Calculate hash of key obtained via offset present in
92847151e4bSgaurav rana 	 * ESBC uboot client hdr
92947151e4bSgaurav rana 	 */
93047151e4bSgaurav rana 	ret = calc_img_key_hash(img);
93147151e4bSgaurav rana 	if (ret) {
93247151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
93347151e4bSgaurav rana 		goto exit;
93447151e4bSgaurav rana 	}
93547151e4bSgaurav rana 
93647151e4bSgaurav rana 	/* Compare hash obtained above with SRK hash present in SFP */
93747151e4bSgaurav rana 	if (hash_cmd)
93847151e4bSgaurav rana 		ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
93947151e4bSgaurav rana 	else
94047151e4bSgaurav rana 		ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
94147151e4bSgaurav rana 
94247151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
94347151e4bSgaurav rana 	if (!hash_cmd && check_ie(img))
94447151e4bSgaurav rana 		ret = 0;
94547151e4bSgaurav rana #endif
94647151e4bSgaurav rana 
94747151e4bSgaurav rana 	if (ret != 0) {
94847151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
94947151e4bSgaurav rana 		goto exit;
95047151e4bSgaurav rana 	}
95147151e4bSgaurav rana 
9526629261dSAneesh Bansal 	ret = calculate_cmp_img_sig(img);
95347151e4bSgaurav rana 	if (ret) {
9546629261dSAneesh Bansal 		fsl_secboot_handle_error(ret);
95547151e4bSgaurav rana 		goto exit;
95647151e4bSgaurav rana 	}
95747151e4bSgaurav rana 
95847151e4bSgaurav rana exit:
959ac55dadbSUdit Agarwal 	/* Free Img as it was malloc'ed*/
960ac55dadbSUdit Agarwal 	free(img);
961bc71f926SAneesh Bansal 	return ret;
96247151e4bSgaurav rana }
963