xref: /rk3399_rockchip-uboot/board/freescale/common/fsl_validate.c (revision b259732d36ccdc911e5b3ed83bd55aae90a43532)
147151e4bSgaurav rana /*
247151e4bSgaurav rana  * Copyright 2015 Freescale Semiconductor, Inc.
347151e4bSgaurav rana  *
447151e4bSgaurav rana  * SPDX-License-Identifier:	GPL-2.0+
547151e4bSgaurav rana  */
647151e4bSgaurav rana 
747151e4bSgaurav rana #include <common.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 <dm/uclass.h>
1547151e4bSgaurav rana #include <u-boot/rsa-mod-exp.h>
1647151e4bSgaurav rana #include <hash.h>
1747151e4bSgaurav rana #include <fsl_secboot_err.h>
189711f528SAneesh Bansal #ifdef CONFIG_LS102XA
1947151e4bSgaurav rana #include <asm/arch/immap_ls102xa.h>
2047151e4bSgaurav rana #endif
2147151e4bSgaurav rana 
2247151e4bSgaurav rana #define SHA256_BITS	256
2347151e4bSgaurav rana #define SHA256_BYTES	(256/8)
2447151e4bSgaurav rana #define SHA256_NIBBLES	(256/4)
2547151e4bSgaurav rana #define NUM_HEX_CHARS	(sizeof(ulong) * 2)
2647151e4bSgaurav rana 
2794ba5e41SAneesh Bansal #define CHECK_KEY_LEN(key_len)	(((key_len) == 2 * KEY_SIZE_BYTES / 4) || \
2894ba5e41SAneesh Bansal 				 ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
2994ba5e41SAneesh Bansal 				 ((key_len) == 2 * KEY_SIZE_BYTES))
3094ba5e41SAneesh Bansal 
3147151e4bSgaurav rana /* This array contains DER value for SHA-256 */
3247151e4bSgaurav rana static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
3347151e4bSgaurav rana 		0x86, 0x48, 0x01, 0x65,	0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
3447151e4bSgaurav rana 		0x04, 0x20
3547151e4bSgaurav rana 		};
3647151e4bSgaurav rana 
3747151e4bSgaurav rana static u8 hash_val[SHA256_BYTES];
38fd6dbc98SSaksham Jain 
39fd6dbc98SSaksham Jain #ifdef CONFIG_ESBC_HDR_LS
40fd6dbc98SSaksham Jain /* New Barker Code for LS ESBC Header */
41fd6dbc98SSaksham Jain static const u8 barker_code[ESBC_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 };
42fd6dbc98SSaksham Jain #else
4347151e4bSgaurav rana static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
44fd6dbc98SSaksham Jain #endif
4547151e4bSgaurav rana 
4647151e4bSgaurav rana void branch_to_self(void) __attribute__ ((noreturn));
4747151e4bSgaurav rana 
4847151e4bSgaurav rana /*
4947151e4bSgaurav rana  * This function will put core in infinite loop.
5047151e4bSgaurav rana  * This will be called when the ESBC can not proceed further due
5147151e4bSgaurav rana  * to some unknown errors.
5247151e4bSgaurav rana  */
5347151e4bSgaurav rana void branch_to_self(void)
5447151e4bSgaurav rana {
5547151e4bSgaurav rana 	printf("Core is in infinite loop due to errors.\n");
5647151e4bSgaurav rana self:
5747151e4bSgaurav rana 	goto self;
5847151e4bSgaurav rana }
5947151e4bSgaurav rana 
6047151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
6147151e4bSgaurav rana static u32 check_ie(struct fsl_secboot_img_priv *img)
6247151e4bSgaurav rana {
6347151e4bSgaurav rana 	if (img->hdr.ie_flag)
6447151e4bSgaurav rana 		return 1;
6547151e4bSgaurav rana 
6647151e4bSgaurav rana 	return 0;
6747151e4bSgaurav rana }
6847151e4bSgaurav rana 
6947151e4bSgaurav rana /* This function returns the CSF Header Address of uboot
7047151e4bSgaurav rana  * For MPC85xx based platforms, the LAW mapping for NOR
7147151e4bSgaurav rana  * flash changes in uboot code. Hence the offset needs
7247151e4bSgaurav rana  * to be calculated and added to the new NOR flash base
7347151e4bSgaurav rana  * address
7447151e4bSgaurav rana  */
7547151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
767bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
7747151e4bSgaurav rana {
7847151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
7947151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
8047151e4bSgaurav rana 	u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
817bcb0eb2SAneesh Bansal 	u32 flash_addr, addr;
8247151e4bSgaurav rana 	int found = 0;
8347151e4bSgaurav rana 	int i = 0;
8447151e4bSgaurav rana 
8547151e4bSgaurav rana 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
8647151e4bSgaurav rana 		flash_addr = flash_info[i].start[0];
8747151e4bSgaurav rana 		addr = flash_info[i].start[0] + csf_flash_offset;
8847151e4bSgaurav rana 		if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
897bcb0eb2SAneesh Bansal 			debug("Barker found on addr %x\n", addr);
9047151e4bSgaurav rana 			found = 1;
9147151e4bSgaurav rana 			break;
9247151e4bSgaurav rana 		}
9347151e4bSgaurav rana 	}
9447151e4bSgaurav rana 
9547151e4bSgaurav rana 	if (!found)
9647151e4bSgaurav rana 		return -1;
9747151e4bSgaurav rana 
9847151e4bSgaurav rana 	*csf_addr = addr;
9947151e4bSgaurav rana 	*flash_base_addr = flash_addr;
10047151e4bSgaurav rana 
10147151e4bSgaurav rana 	return 0;
10247151e4bSgaurav rana }
10347151e4bSgaurav rana #else
10447151e4bSgaurav rana /* For platforms like LS1020, correct flash address is present in
10547151e4bSgaurav rana  * the header. So the function reqturns flash base address as 0
10647151e4bSgaurav rana  */
1077bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
10847151e4bSgaurav rana {
10947151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
11047151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
11147151e4bSgaurav rana 
1129711f528SAneesh Bansal 	if (memcmp((u8 *)(uintptr_t)csf_hdr_addr,
1139711f528SAneesh Bansal 		   barker_code, ESBC_BARKER_LEN))
11447151e4bSgaurav rana 		return -1;
11547151e4bSgaurav rana 
11647151e4bSgaurav rana 	*csf_addr = csf_hdr_addr;
11747151e4bSgaurav rana 	*flash_base_addr = 0;
11847151e4bSgaurav rana 	return 0;
11947151e4bSgaurav rana }
12047151e4bSgaurav rana #endif
12147151e4bSgaurav rana 
1227bcb0eb2SAneesh Bansal static int get_ie_info_addr(u32 *ie_addr)
12347151e4bSgaurav rana {
12447151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
12547151e4bSgaurav rana 	struct fsl_secboot_sg_table *sg_tbl;
1267bcb0eb2SAneesh Bansal 	u32 flash_base_addr, csf_addr;
12747151e4bSgaurav rana 
12847151e4bSgaurav rana 	if (get_csf_base_addr(&csf_addr, &flash_base_addr))
12947151e4bSgaurav rana 		return -1;
13047151e4bSgaurav rana 
1319711f528SAneesh Bansal 	hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr;
13247151e4bSgaurav rana 
13347151e4bSgaurav rana 	/* For SoC's with Trust Architecture v1 with corenet bus
13447151e4bSgaurav rana 	 * the sg table field in CSF header has absolute address
13547151e4bSgaurav rana 	 * for sg table in memory. In other Trust Architecture,
13647151e4bSgaurav rana 	 * this field specifies the offset of sg table from the
13747151e4bSgaurav rana 	 * base address of CSF Header
13847151e4bSgaurav rana 	 */
13947151e4bSgaurav rana #if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
14047151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)
1417bcb0eb2SAneesh Bansal 		 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
14247151e4bSgaurav rana 		  flash_base_addr);
14347151e4bSgaurav rana #else
1449711f528SAneesh Bansal 	sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
1457bcb0eb2SAneesh Bansal 						 (u32)hdr->psgtable);
14647151e4bSgaurav rana #endif
14747151e4bSgaurav rana 
14847151e4bSgaurav rana 	/* IE Key Table is the first entry in the SG Table */
14947151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
15047151e4bSgaurav rana 	*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
15147151e4bSgaurav rana 		   flash_base_addr;
15247151e4bSgaurav rana #else
15347151e4bSgaurav rana 	*ie_addr = sg_tbl->src_addr;
15447151e4bSgaurav rana #endif
15547151e4bSgaurav rana 
1567bcb0eb2SAneesh Bansal 	debug("IE Table address is %x\n", *ie_addr);
15747151e4bSgaurav rana 	return 0;
15847151e4bSgaurav rana }
15947151e4bSgaurav rana 
16047151e4bSgaurav rana #endif
16147151e4bSgaurav rana 
16247151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
16347151e4bSgaurav rana /* This function checks srk_table_flag in header and set/reset srk_flag.*/
16447151e4bSgaurav rana static u32 check_srk(struct fsl_secboot_img_priv *img)
16547151e4bSgaurav rana {
166fd6dbc98SSaksham Jain #ifdef CONFIG_ESBC_HDR_LS
167fd6dbc98SSaksham Jain 	/* In LS, No SRK Flag as SRK is always present*/
168fd6dbc98SSaksham Jain 	return 1;
169fd6dbc98SSaksham Jain #else
17047151e4bSgaurav rana 	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
17147151e4bSgaurav rana 		return 1;
17247151e4bSgaurav rana 
17347151e4bSgaurav rana 	return 0;
174fd6dbc98SSaksham Jain #endif
17547151e4bSgaurav rana }
17647151e4bSgaurav rana 
17747151e4bSgaurav rana /* This function returns ospr's key_revoc values.*/
17847151e4bSgaurav rana static u32 get_key_revoc(void)
17947151e4bSgaurav rana {
18047151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
18147151e4bSgaurav rana 	return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
18247151e4bSgaurav rana 		OSPR_KEY_REVOC_SHIFT;
18347151e4bSgaurav rana }
18447151e4bSgaurav rana 
18547151e4bSgaurav rana /* This function checks if selected key is revoked or not.*/
18647151e4bSgaurav rana static u32 is_key_revoked(u32 keynum, u32 rev_flag)
18747151e4bSgaurav rana {
18847151e4bSgaurav rana 	if (keynum == UNREVOCABLE_KEY)
18947151e4bSgaurav rana 		return 0;
19047151e4bSgaurav rana 
19147151e4bSgaurav rana 	if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
19247151e4bSgaurav rana 		return 1;
19347151e4bSgaurav rana 
19447151e4bSgaurav rana 	return 0;
19547151e4bSgaurav rana }
19647151e4bSgaurav rana 
19794ba5e41SAneesh Bansal /* It read validates srk_table key lengths.*/
19894ba5e41SAneesh Bansal static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
19947151e4bSgaurav rana {
20047151e4bSgaurav rana 	int i = 0;
20194ba5e41SAneesh Bansal 	u32 ret, key_num, key_revoc_flag, size;
20294ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
20394ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
20494ba5e41SAneesh Bansal 
20594ba5e41SAneesh Bansal 	if ((hdr->len_kr.num_srk == 0) ||
20694ba5e41SAneesh Bansal 	    (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
20794ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
20894ba5e41SAneesh Bansal 
20994ba5e41SAneesh Bansal 	key_num = hdr->len_kr.srk_sel;
21094ba5e41SAneesh Bansal 	if (key_num == 0 || key_num > hdr->len_kr.num_srk)
21194ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
21294ba5e41SAneesh Bansal 
21394ba5e41SAneesh Bansal 	/* Get revoc key from sfp */
21494ba5e41SAneesh Bansal 	key_revoc_flag = get_key_revoc();
21594ba5e41SAneesh Bansal 	ret = is_key_revoked(key_num, key_revoc_flag);
21694ba5e41SAneesh Bansal 	if (ret)
21794ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
21894ba5e41SAneesh Bansal 
21994ba5e41SAneesh Bansal 	size = hdr->len_kr.num_srk * sizeof(struct srk_table);
22094ba5e41SAneesh Bansal 
22194ba5e41SAneesh Bansal 	memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
22294ba5e41SAneesh Bansal 
22394ba5e41SAneesh Bansal 	for (i = 0; i < hdr->len_kr.num_srk; i++) {
22494ba5e41SAneesh Bansal 		if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
22547151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
22647151e4bSgaurav rana 	}
22794ba5e41SAneesh Bansal 
22894ba5e41SAneesh Bansal 	img->key_len = img->srk_tbl[key_num - 1].key_len;
22994ba5e41SAneesh Bansal 
23094ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
23194ba5e41SAneesh Bansal 	       img->key_len);
23294ba5e41SAneesh Bansal 
23347151e4bSgaurav rana 	return 0;
23447151e4bSgaurav rana }
23547151e4bSgaurav rana #endif
23647151e4bSgaurav rana 
237fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
23894ba5e41SAneesh Bansal static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
23994ba5e41SAneesh Bansal {
24094ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
24194ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
24294ba5e41SAneesh Bansal 
24394ba5e41SAneesh Bansal 	/* check key length */
24494ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(hdr->key_len))
24594ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
24694ba5e41SAneesh Bansal 
24794ba5e41SAneesh Bansal 	memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
24894ba5e41SAneesh Bansal 
24994ba5e41SAneesh Bansal 	img->key_len = hdr->key_len;
25094ba5e41SAneesh Bansal 
25194ba5e41SAneesh Bansal 	return 0;
25294ba5e41SAneesh Bansal }
253fd6dbc98SSaksham Jain #endif /* CONFIG_ESBC_HDR_LS */
25494ba5e41SAneesh Bansal 
25594ba5e41SAneesh Bansal #if defined(CONFIG_FSL_ISBC_KEY_EXT)
25694ba5e41SAneesh Bansal static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
25794ba5e41SAneesh Bansal {
25894ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
25994ba5e41SAneesh Bansal 	u32 ie_key_len, ie_revoc_flag, ie_num;
26094ba5e41SAneesh Bansal 	struct ie_key_info *ie_info;
26194ba5e41SAneesh Bansal 
26294ba5e41SAneesh Bansal 	if (get_ie_info_addr(&img->ie_addr))
26394ba5e41SAneesh Bansal 		return ERROR_IE_TABLE_NOT_FOUND;
26494ba5e41SAneesh Bansal 	ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
26594ba5e41SAneesh Bansal 	if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
26694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
26794ba5e41SAneesh Bansal 
26894ba5e41SAneesh Bansal 	ie_num = hdr->ie_key_sel;
26994ba5e41SAneesh Bansal 	if (ie_num == 0 || ie_num > ie_info->num_keys)
27094ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
27194ba5e41SAneesh Bansal 
27294ba5e41SAneesh Bansal 	ie_revoc_flag = ie_info->key_revok;
27394ba5e41SAneesh Bansal 	if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
27494ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
27594ba5e41SAneesh Bansal 
27694ba5e41SAneesh Bansal 	ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
27794ba5e41SAneesh Bansal 
27894ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(ie_key_len))
27994ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
28094ba5e41SAneesh Bansal 
28194ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
28294ba5e41SAneesh Bansal 	       ie_key_len);
28394ba5e41SAneesh Bansal 
28494ba5e41SAneesh Bansal 	img->key_len = ie_key_len;
28594ba5e41SAneesh Bansal 	return 0;
28694ba5e41SAneesh Bansal }
28794ba5e41SAneesh Bansal #endif
28894ba5e41SAneesh Bansal 
28994ba5e41SAneesh Bansal 
29047151e4bSgaurav rana /* This function return length of public key.*/
29147151e4bSgaurav rana static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
29247151e4bSgaurav rana {
29347151e4bSgaurav rana 	return img->key_len;
29447151e4bSgaurav rana }
29547151e4bSgaurav rana 
29647151e4bSgaurav rana /*
29747151e4bSgaurav rana  * Handles the ESBC uboot client header verification failure.
29847151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
29947151e4bSgaurav rana  * parsing and checking of ESBC uboot client header. It will also
30047151e4bSgaurav rana  * set the error bits in the SEC_MON.
30147151e4bSgaurav rana  */
30247151e4bSgaurav rana static void fsl_secboot_header_verification_failure(void)
30347151e4bSgaurav rana {
30447151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
30547151e4bSgaurav rana 
30647151e4bSgaurav rana 	/* 29th bit of OSPR is ITS */
30747151e4bSgaurav rana 	u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
30847151e4bSgaurav rana 
30947151e4bSgaurav rana 	if (its == 1)
310*b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
31147151e4bSgaurav rana 	else
312*b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
31347151e4bSgaurav rana 
31447151e4bSgaurav rana 	printf("Generating reset request\n");
31547151e4bSgaurav rana 	do_reset(NULL, 0, 0, NULL);
316c4666cf6SSaksham Jain 	/* If reset doesn't coocur, halt execution */
317c4666cf6SSaksham Jain 	do_esbc_halt(NULL, 0, 0, NULL);
31847151e4bSgaurav rana }
31947151e4bSgaurav rana 
32047151e4bSgaurav rana /*
32147151e4bSgaurav rana  * Handles the ESBC uboot client image verification failure.
32247151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
32347151e4bSgaurav rana  * public key hash comparison and signature verification of
32447151e4bSgaurav rana  * ESBC uboot client image. It will also
32547151e4bSgaurav rana  * set the error bits in the SEC_MON.
32647151e4bSgaurav rana  */
32747151e4bSgaurav rana static void fsl_secboot_image_verification_failure(void)
32847151e4bSgaurav rana {
32947151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
33047151e4bSgaurav rana 
3316ec9aef2SAneesh Bansal 	u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
33247151e4bSgaurav rana 
33347151e4bSgaurav rana 	if (its == 1) {
334*b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
33547151e4bSgaurav rana 
33647151e4bSgaurav rana 		printf("Generating reset request\n");
33747151e4bSgaurav rana 		do_reset(NULL, 0, 0, NULL);
338c4666cf6SSaksham Jain 		/* If reset doesn't coocur, halt execution */
339c4666cf6SSaksham Jain 		do_esbc_halt(NULL, 0, 0, NULL);
340c4666cf6SSaksham Jain 
34147151e4bSgaurav rana 	} else {
342*b259732dSSumit Garg 		set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
34347151e4bSgaurav rana 	}
34447151e4bSgaurav rana }
34547151e4bSgaurav rana 
34647151e4bSgaurav rana static void fsl_secboot_bootscript_parse_failure(void)
34747151e4bSgaurav rana {
34847151e4bSgaurav rana 	fsl_secboot_header_verification_failure();
34947151e4bSgaurav rana }
35047151e4bSgaurav rana 
35147151e4bSgaurav rana /*
35247151e4bSgaurav rana  * Handles the errors in esbc boot.
35347151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
35447151e4bSgaurav rana  * esbc boot phase. It will call the appropriate api to log the
35547151e4bSgaurav rana  * errors and set the error bits in the SEC_MON.
35647151e4bSgaurav rana  */
35747151e4bSgaurav rana void fsl_secboot_handle_error(int error)
35847151e4bSgaurav rana {
35947151e4bSgaurav rana 	const struct fsl_secboot_errcode *e;
36047151e4bSgaurav rana 
36147151e4bSgaurav rana 	for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
36247151e4bSgaurav rana 		e++) {
36347151e4bSgaurav rana 		if (e->errcode == error)
36447151e4bSgaurav rana 			printf("ERROR :: %x :: %s\n", error, e->name);
36547151e4bSgaurav rana 	}
36647151e4bSgaurav rana 
367856b2846SAneesh Bansal 	/* If Boot Mode is secure, transition the SNVS state and issue
368856b2846SAneesh Bansal 	 * reset based on type of failure and ITS setting.
369856b2846SAneesh Bansal 	 * If Boot mode is non-secure, return from this function.
370856b2846SAneesh Bansal 	 */
371856b2846SAneesh Bansal 	if (fsl_check_boot_mode_secure() == 0)
372856b2846SAneesh Bansal 		return;
373856b2846SAneesh Bansal 
37447151e4bSgaurav rana 	switch (error) {
37547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_BARKER:
37647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
37747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
37847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
37947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
38047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
38147151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
38247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
38347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
38447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
385fd6dbc98SSaksham Jain 	case ERROR_KEY_TABLE_NOT_FOUND:
38647151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
38747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
38847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
38947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
39047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
39147151e4bSgaurav rana #endif
39247151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
39347151e4bSgaurav rana 	/*@fallthrough@*/
39447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
39547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
39647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
39747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
39847151e4bSgaurav rana 	case ERROR_IE_TABLE_NOT_FOUND:
39947151e4bSgaurav rana #endif
40047151e4bSgaurav rana 		fsl_secboot_header_verification_failure();
40147151e4bSgaurav rana 		break;
40247151e4bSgaurav rana 	case ERROR_ESBC_SEC_RESET:
40347151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
40447151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
40547151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
40647151e4bSgaurav rana 	case ERROR_ESBC_SEC_JOBQ_STATUS:
40747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
40847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
40947151e4bSgaurav rana 		fsl_secboot_image_verification_failure();
41047151e4bSgaurav rana 		break;
41147151e4bSgaurav rana 	case ERROR_ESBC_MISSING_BOOTM:
41247151e4bSgaurav rana 		fsl_secboot_bootscript_parse_failure();
41347151e4bSgaurav rana 		break;
41447151e4bSgaurav rana 	case ERROR_ESBC_WRONG_CMD:
41547151e4bSgaurav rana 	default:
41647151e4bSgaurav rana 		branch_to_self();
41747151e4bSgaurav rana 		break;
41847151e4bSgaurav rana 	}
41947151e4bSgaurav rana }
42047151e4bSgaurav rana 
42147151e4bSgaurav rana static void fsl_secblk_handle_error(int error)
42247151e4bSgaurav rana {
42347151e4bSgaurav rana 	switch (error) {
42447151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
42547151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
42647151e4bSgaurav rana 		break;
42747151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
42847151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
42947151e4bSgaurav rana 		break;
43047151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
43147151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
43247151e4bSgaurav rana 		break;
43347151e4bSgaurav rana 	default:
43447151e4bSgaurav rana 		printf("Job Queue Output status %x\n", error);
43547151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
43647151e4bSgaurav rana 		break;
43747151e4bSgaurav rana 	}
43847151e4bSgaurav rana }
43947151e4bSgaurav rana 
44047151e4bSgaurav rana /*
44147151e4bSgaurav rana  * Calculate hash of key obtained via offset present in ESBC uboot
44247151e4bSgaurav rana  * client hdr. This function calculates the hash of key which is obtained
44347151e4bSgaurav rana  * through offset present in ESBC uboot client header.
44447151e4bSgaurav rana  */
44547151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
44647151e4bSgaurav rana {
44747151e4bSgaurav rana 	struct hash_algo *algo;
44847151e4bSgaurav rana 	void *ctx;
44947151e4bSgaurav rana 	int i, srk = 0;
45047151e4bSgaurav rana 	int ret = 0;
45147151e4bSgaurav rana 	const char *algo_name = "sha256";
45247151e4bSgaurav rana 
45347151e4bSgaurav rana 	/* Calculate hash of the esbc key */
45447151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
45547151e4bSgaurav rana 	if (ret)
45647151e4bSgaurav rana 		return ret;
45747151e4bSgaurav rana 
45847151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
45947151e4bSgaurav rana 	if (ret)
46047151e4bSgaurav rana 		return ret;
46147151e4bSgaurav rana 
46247151e4bSgaurav rana 	/* Update hash for ESBC key */
46347151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
46447151e4bSgaurav rana 	if (check_srk(img)) {
46547151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
4669711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
46747151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
46847151e4bSgaurav rana 		srk = 1;
46947151e4bSgaurav rana 	}
47047151e4bSgaurav rana #endif
47147151e4bSgaurav rana 	if (!srk)
47247151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
47347151e4bSgaurav rana 			img->img_key, img->key_len, 1);
47447151e4bSgaurav rana 	if (ret)
47547151e4bSgaurav rana 		return ret;
47647151e4bSgaurav rana 
47747151e4bSgaurav rana 	/* Copy hash at destination buffer */
47847151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
47947151e4bSgaurav rana 	if (ret)
48047151e4bSgaurav rana 		return ret;
48147151e4bSgaurav rana 
48247151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
48347151e4bSgaurav rana 		img->img_key_hash[i] = hash_val[i];
48447151e4bSgaurav rana 
48547151e4bSgaurav rana 	return 0;
48647151e4bSgaurav rana }
48747151e4bSgaurav rana 
48847151e4bSgaurav rana /*
48947151e4bSgaurav rana  * Calculate hash of ESBC hdr and ESBC. This function calculates the
49047151e4bSgaurav rana  * single hash of ESBC header and ESBC image. If SG flag is on, all
49147151e4bSgaurav rana  * SG entries are also hashed alongwith the complete SG table.
49247151e4bSgaurav rana  */
49347151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
49447151e4bSgaurav rana {
49547151e4bSgaurav rana 	struct hash_algo *algo;
49647151e4bSgaurav rana 	void *ctx;
49747151e4bSgaurav rana 	int ret = 0;
49847151e4bSgaurav rana 	int key_hash = 0;
49947151e4bSgaurav rana 	const char *algo_name = "sha256";
50047151e4bSgaurav rana 
50147151e4bSgaurav rana 	/* Calculate the hash of the ESBC */
50247151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
50347151e4bSgaurav rana 	if (ret)
50447151e4bSgaurav rana 		return ret;
50547151e4bSgaurav rana 
50647151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
50747151e4bSgaurav rana 	/* Copy hash at destination buffer */
50847151e4bSgaurav rana 	if (ret)
50947151e4bSgaurav rana 		return ret;
51047151e4bSgaurav rana 
51147151e4bSgaurav rana 	/* Update hash for CSF Header */
51247151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
51347151e4bSgaurav rana 		(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
51447151e4bSgaurav rana 	if (ret)
51547151e4bSgaurav rana 		return ret;
51647151e4bSgaurav rana 
51747151e4bSgaurav rana 	/* Update the hash with that of srk table if srk flag is 1
51847151e4bSgaurav rana 	 * If IE Table is selected, key is not added in the hash
51947151e4bSgaurav rana 	 * If neither srk table nor IE key table available, add key
52047151e4bSgaurav rana 	 * from header in the hash calculation
52147151e4bSgaurav rana 	 */
52247151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
52347151e4bSgaurav rana 	if (check_srk(img)) {
52447151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
5259711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
52647151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
52747151e4bSgaurav rana 		key_hash = 1;
52847151e4bSgaurav rana 	}
52947151e4bSgaurav rana #endif
53047151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
53147151e4bSgaurav rana 	if (!key_hash && check_ie(img))
53247151e4bSgaurav rana 		key_hash = 1;
53347151e4bSgaurav rana #endif
534fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
535fd6dbc98SSaksham Jain /* No single key support in LS ESBC header */
536fd6dbc98SSaksham Jain 	if (!key_hash) {
53747151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
53847151e4bSgaurav rana 			img->img_key, img->hdr.key_len, 0);
539fd6dbc98SSaksham Jain 		key_hash = 1;
540fd6dbc98SSaksham Jain 	}
541fd6dbc98SSaksham Jain #endif
54247151e4bSgaurav rana 	if (ret)
54347151e4bSgaurav rana 		return ret;
544fd6dbc98SSaksham Jain 	if (!key_hash)
545fd6dbc98SSaksham Jain 		return ERROR_KEY_TABLE_NOT_FOUND;
54647151e4bSgaurav rana 
54747151e4bSgaurav rana 	/* Update hash for actual Image */
54847151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
54985bb3896SSaksham Jain 		(u8 *)(*(img->img_addr_ptr)), img->img_size, 1);
55047151e4bSgaurav rana 	if (ret)
55147151e4bSgaurav rana 		return ret;
55247151e4bSgaurav rana 
55347151e4bSgaurav rana 	/* Copy hash at destination buffer */
55447151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
55547151e4bSgaurav rana 	if (ret)
55647151e4bSgaurav rana 		return ret;
55747151e4bSgaurav rana 
55847151e4bSgaurav rana 	return 0;
55947151e4bSgaurav rana }
56047151e4bSgaurav rana 
56147151e4bSgaurav rana /*
56247151e4bSgaurav rana  * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
56347151e4bSgaurav rana  * pointers for padding, DER value and hash. And finally, constructs EM'
56447151e4bSgaurav rana  * which includes hash of complete CSF header and ESBC image. If SG flag
56547151e4bSgaurav rana  * is on, hash of SG table and entries is also included.
56647151e4bSgaurav rana  */
56747151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
56847151e4bSgaurav rana {
56947151e4bSgaurav rana 	/*
57047151e4bSgaurav rana 	 * RSA PKCSv1.5 encoding format for encoded message is below
57147151e4bSgaurav rana 	 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
57247151e4bSgaurav rana 	 * PS is Padding String
57347151e4bSgaurav rana 	 * DER is DER value for SHA-256
57447151e4bSgaurav rana 	 * Hash is SHA-256 hash
57547151e4bSgaurav rana 	 * *********************************************************
57647151e4bSgaurav rana 	 * representative points to first byte of EM initially and is
57747151e4bSgaurav rana 	 * filled with 0x0
57847151e4bSgaurav rana 	 * representative is incremented by 1 and second byte is filled
57947151e4bSgaurav rana 	 * with 0x1
58047151e4bSgaurav rana 	 * padding points to third byte of EM
58147151e4bSgaurav rana 	 * digest points to full length of EM - 32 bytes
58247151e4bSgaurav rana 	 * hash_id (DER value) points to 19 bytes before pDigest
58347151e4bSgaurav rana 	 * separator is one byte which separates padding and DER
58447151e4bSgaurav rana 	 */
58547151e4bSgaurav rana 
58647151e4bSgaurav rana 	size_t len;
58747151e4bSgaurav rana 	u8 *representative;
58847151e4bSgaurav rana 	u8 *padding, *digest;
58947151e4bSgaurav rana 	u8 *hash_id, *separator;
59047151e4bSgaurav rana 	int i;
59147151e4bSgaurav rana 
59247151e4bSgaurav rana 	len = (get_key_len(img) / 2) - 1;
59347151e4bSgaurav rana 	representative = img->img_encoded_hash_second;
59447151e4bSgaurav rana 	representative[0] = 0;
59547151e4bSgaurav rana 	representative[1] = 1;  /* block type 1 */
59647151e4bSgaurav rana 
59747151e4bSgaurav rana 	padding = &representative[2];
59847151e4bSgaurav rana 	digest = &representative[1] + len - 32;
59947151e4bSgaurav rana 	hash_id = digest - sizeof(hash_identifier);
60047151e4bSgaurav rana 	separator = hash_id - 1;
60147151e4bSgaurav rana 
60247151e4bSgaurav rana 	/* fill padding area pointed by padding with 0xff */
60347151e4bSgaurav rana 	memset(padding, 0xff, separator - padding);
60447151e4bSgaurav rana 
60547151e4bSgaurav rana 	/* fill byte pointed by separator */
60647151e4bSgaurav rana 	*separator = 0;
60747151e4bSgaurav rana 
60847151e4bSgaurav rana 	/* fill SHA-256 DER value  pointed by HashId */
60947151e4bSgaurav rana 	memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
61047151e4bSgaurav rana 
61147151e4bSgaurav rana 	/* fill hash pointed by Digest */
61247151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
61347151e4bSgaurav rana 		digest[i] = hash_val[i];
61447151e4bSgaurav rana }
61547151e4bSgaurav rana 
61647151e4bSgaurav rana /*
61747151e4bSgaurav rana  * Reads and validates the ESBC client header.
61847151e4bSgaurav rana  * This function reads key and signature from the ESBC client header.
61947151e4bSgaurav rana  * If Scatter/Gather flag is on, lengths and offsets of images
62047151e4bSgaurav rana  * present as SG entries are also read. This function also checks
62147151e4bSgaurav rana  * whether the header is valid or not.
62247151e4bSgaurav rana  */
62347151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
62447151e4bSgaurav rana {
62547151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
6269711f528SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
62747151e4bSgaurav rana 	u8 *k, *s;
62894ba5e41SAneesh Bansal 	u32 ret = 0;
62994ba5e41SAneesh Bansal 
63047151e4bSgaurav rana 	int  key_found = 0;
63147151e4bSgaurav rana 
63247151e4bSgaurav rana 	/* check barker code */
63347151e4bSgaurav rana 	if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
63447151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_BARKER;
63547151e4bSgaurav rana 
636b055a0fdSAneesh Bansal 	/* If Image Address is not passed as argument to function,
637b055a0fdSAneesh Bansal 	 * then Address and Size must be read from the Header.
638b055a0fdSAneesh Bansal 	 */
63985bb3896SSaksham Jain 	if (*(img->img_addr_ptr) == 0) {
6409711f528SAneesh Bansal 	#ifdef CONFIG_ESBC_ADDR_64BIT
64185bb3896SSaksham Jain 		*(img->img_addr_ptr) = hdr->pimg64;
6429711f528SAneesh Bansal 	#else
64385bb3896SSaksham Jain 		*(img->img_addr_ptr) = hdr->pimg;
6449711f528SAneesh Bansal 	#endif
645b055a0fdSAneesh Bansal 	}
646b055a0fdSAneesh Bansal 
64747151e4bSgaurav rana 	if (!hdr->img_size)
64847151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
64947151e4bSgaurav rana 
650b055a0fdSAneesh Bansal 	img->img_size = hdr->img_size;
651b055a0fdSAneesh Bansal 
65247151e4bSgaurav rana 	/* Key checking*/
65347151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
65447151e4bSgaurav rana 	if (check_srk(img)) {
65594ba5e41SAneesh Bansal 		ret = read_validate_srk_tbl(img);
65647151e4bSgaurav rana 		if (ret != 0)
65747151e4bSgaurav rana 			return ret;
65847151e4bSgaurav rana 		key_found = 1;
65947151e4bSgaurav rana 	}
66047151e4bSgaurav rana #endif
66147151e4bSgaurav rana 
66247151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
66347151e4bSgaurav rana 	if (!key_found && check_ie(img)) {
66494ba5e41SAneesh Bansal 		ret = read_validate_ie_tbl(img);
66594ba5e41SAneesh Bansal 		if (ret != 0)
66694ba5e41SAneesh Bansal 			return ret;
66747151e4bSgaurav rana 		key_found = 1;
66847151e4bSgaurav rana 	}
66947151e4bSgaurav rana #endif
670fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
671fd6dbc98SSaksham Jain /* Single Key Feature not available in LS ESBC Header */
67247151e4bSgaurav rana 	if (key_found == 0) {
67394ba5e41SAneesh Bansal 		ret = read_validate_single_key(img);
67494ba5e41SAneesh Bansal 		if (ret != 0)
67594ba5e41SAneesh Bansal 			return ret;
67647151e4bSgaurav rana 		key_found = 1;
67747151e4bSgaurav rana 	}
678fd6dbc98SSaksham Jain #endif
679fd6dbc98SSaksham Jain 	if (!key_found)
680fd6dbc98SSaksham Jain 		return ERROR_KEY_TABLE_NOT_FOUND;
68147151e4bSgaurav rana 
68247151e4bSgaurav rana 	/* check signaure */
68347151e4bSgaurav rana 	if (get_key_len(img) == 2 * hdr->sign_len) {
68447151e4bSgaurav rana 		/* check signature length */
68547151e4bSgaurav rana 		if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
68647151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
68747151e4bSgaurav rana 		      (hdr->sign_len == KEY_SIZE_BYTES)))
68847151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
68947151e4bSgaurav rana 	} else {
69047151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
69147151e4bSgaurav rana 	}
69247151e4bSgaurav rana 
69347151e4bSgaurav rana 	memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
694fd6dbc98SSaksham Jain /* No SG support in LS-CH3 */
695fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS
69647151e4bSgaurav rana 	/* No SG support */
69747151e4bSgaurav rana 	if (hdr->sg_flag)
69847151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SG;
699fd6dbc98SSaksham Jain #endif
70047151e4bSgaurav rana 
70147151e4bSgaurav rana 	/* modulus most significant bit should be set */
70247151e4bSgaurav rana 	k = (u8 *)&img->img_key;
70347151e4bSgaurav rana 
70447151e4bSgaurav rana 	if ((k[0] & 0x80) == 0)
70547151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
70647151e4bSgaurav rana 
70747151e4bSgaurav rana 	/* modulus value should be odd */
70847151e4bSgaurav rana 	if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
70947151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
71047151e4bSgaurav rana 
71147151e4bSgaurav rana 	/* Check signature value < modulus value */
71247151e4bSgaurav rana 	s = (u8 *)&img->img_sign;
71347151e4bSgaurav rana 
71447151e4bSgaurav rana 	if (!(memcmp(s, k, hdr->sign_len) < 0))
71547151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
71647151e4bSgaurav rana 
71747151e4bSgaurav rana 	return ESBC_VALID_HDR;
71847151e4bSgaurav rana }
71947151e4bSgaurav rana 
72047151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num)
72147151e4bSgaurav rana {
72247151e4bSgaurav rana 	char *endptr;
72347151e4bSgaurav rana 	ulong tmp;
72447151e4bSgaurav rana 
72547151e4bSgaurav rana 	if (!p) {
72647151e4bSgaurav rana 		return 0;
72747151e4bSgaurav rana 	} else {
72847151e4bSgaurav rana 		tmp = simple_strtoul(p, &endptr, 16);
72947151e4bSgaurav rana 		if (sizeof(ulong) == 4)
73047151e4bSgaurav rana 			*num = cpu_to_be32(tmp);
73147151e4bSgaurav rana 		else
73247151e4bSgaurav rana 			*num = cpu_to_be64(tmp);
73347151e4bSgaurav rana 	}
73447151e4bSgaurav rana 
73547151e4bSgaurav rana 	return *p != '\0' && *endptr == '\0';
73647151e4bSgaurav rana }
7376629261dSAneesh Bansal /* Function to calculate the ESBC Image Hash
7386629261dSAneesh Bansal  * and hash from Digital signature.
7396629261dSAneesh Bansal  * The Two hash's are compared to yield the
7406629261dSAneesh Bansal  * result of signature validation.
7416629261dSAneesh Bansal  */
7426629261dSAneesh Bansal static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
7436629261dSAneesh Bansal {
7446629261dSAneesh Bansal 	int ret;
7456629261dSAneesh Bansal 	uint32_t key_len;
7466629261dSAneesh Bansal 	struct key_prop prop;
7476629261dSAneesh Bansal #if !defined(USE_HOSTCC)
7486629261dSAneesh Bansal 	struct udevice *mod_exp_dev;
7496629261dSAneesh Bansal #endif
7506629261dSAneesh Bansal 	ret = calc_esbchdr_esbc_hash(img);
7516629261dSAneesh Bansal 	if (ret)
7526629261dSAneesh Bansal 		return ret;
7536629261dSAneesh Bansal 
7546629261dSAneesh Bansal 	/* Construct encoded hash EM' wrt PKCSv1.5 */
7556629261dSAneesh Bansal 	construct_img_encoded_hash_second(img);
7566629261dSAneesh Bansal 
7576629261dSAneesh Bansal 	/* Fill prop structure for public key */
7586629261dSAneesh Bansal 	memset(&prop, 0, sizeof(struct key_prop));
7596629261dSAneesh Bansal 	key_len = get_key_len(img) / 2;
7606629261dSAneesh Bansal 	prop.modulus = img->img_key;
7616629261dSAneesh Bansal 	prop.public_exponent = img->img_key + key_len;
7626629261dSAneesh Bansal 	prop.num_bits = key_len * 8;
7636629261dSAneesh Bansal 	prop.exp_len = key_len;
7646629261dSAneesh Bansal 
7656629261dSAneesh Bansal 	ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
7666629261dSAneesh Bansal 	if (ret) {
7676629261dSAneesh Bansal 		printf("RSA: Can't find Modular Exp implementation\n");
7686629261dSAneesh Bansal 		return -EINVAL;
7696629261dSAneesh Bansal 	}
7706629261dSAneesh Bansal 
7716629261dSAneesh Bansal 	ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
7726629261dSAneesh Bansal 			  &prop, img->img_encoded_hash);
7736629261dSAneesh Bansal 	if (ret)
7746629261dSAneesh Bansal 		return ret;
7756629261dSAneesh Bansal 
7766629261dSAneesh Bansal 	/*
7776629261dSAneesh Bansal 	 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
7786629261dSAneesh Bansal 	 * memcmp returns zero on success
7796629261dSAneesh Bansal 	 * memcmp returns non-zero on failure
7806629261dSAneesh Bansal 	 */
7816629261dSAneesh Bansal 	ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
7826629261dSAneesh Bansal 		img->hdr.sign_len);
7836629261dSAneesh Bansal 
7846629261dSAneesh Bansal 	if (ret)
7856629261dSAneesh Bansal 		return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;
7866629261dSAneesh Bansal 
7876629261dSAneesh Bansal 	return 0;
7886629261dSAneesh Bansal }
78985bb3896SSaksham Jain /* haddr - Address of the header of image to be validated.
79085bb3896SSaksham Jain  * arg_hash_str - Option hash string. If provided, this
7911cc0a9f4SRobert P. J. Day  * overrides the key hash in the SFP fuses.
79285bb3896SSaksham Jain  * img_addr_ptr - Optional pointer to address of image to be validated.
7931cc0a9f4SRobert P. J. Day  * If non zero addr, this overrides the addr of image in header,
79485bb3896SSaksham Jain  * otherwise updated to image addr in header.
79585bb3896SSaksham Jain  * Acts as both input and output of function.
79685bb3896SSaksham Jain  * This pointer shouldn't be NULL.
79785bb3896SSaksham Jain  */
798b055a0fdSAneesh Bansal int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
79985bb3896SSaksham Jain 			uintptr_t *img_addr_ptr)
80047151e4bSgaurav rana {
80147151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
80247151e4bSgaurav rana 	ulong hash[SHA256_BYTES/sizeof(ulong)];
80347151e4bSgaurav rana 	char hash_str[NUM_HEX_CHARS + 1];
80447151e4bSgaurav rana 	struct fsl_secboot_img_priv *img;
80547151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
80647151e4bSgaurav rana 	void *esbc;
80747151e4bSgaurav rana 	int ret, i, hash_cmd = 0;
80847151e4bSgaurav rana 	u32 srk_hash[8];
80947151e4bSgaurav rana 
810bc71f926SAneesh Bansal 	if (arg_hash_str != NULL) {
811bc71f926SAneesh Bansal 		const char *cp = arg_hash_str;
81247151e4bSgaurav rana 		int i = 0;
81347151e4bSgaurav rana 
81447151e4bSgaurav rana 		if (*cp == '0' && *(cp + 1) == 'x')
81547151e4bSgaurav rana 			cp += 2;
81647151e4bSgaurav rana 
81747151e4bSgaurav rana 		/* The input string expected is in hex, where
81847151e4bSgaurav rana 		 * each 4 bits would be represented by a hex
81947151e4bSgaurav rana 		 * sha256 hash is 256 bits long, which would mean
82047151e4bSgaurav rana 		 * num of characters = 256 / 4
82147151e4bSgaurav rana 		 */
82247151e4bSgaurav rana 		if (strlen(cp) != SHA256_NIBBLES) {
82347151e4bSgaurav rana 			printf("%s is not a 256 bits hex string as expected\n",
824bc71f926SAneesh Bansal 			       arg_hash_str);
82547151e4bSgaurav rana 			return -1;
82647151e4bSgaurav rana 		}
82747151e4bSgaurav rana 
82847151e4bSgaurav rana 		for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
82947151e4bSgaurav rana 			strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
83047151e4bSgaurav rana 				NUM_HEX_CHARS);
83147151e4bSgaurav rana 			hash_str[NUM_HEX_CHARS] = '\0';
83247151e4bSgaurav rana 			if (!str2longbe(hash_str, &hash[i])) {
83347151e4bSgaurav rana 				printf("%s is not a 256 bits hex string ",
834bc71f926SAneesh Bansal 				       arg_hash_str);
83547151e4bSgaurav rana 				return -1;
83647151e4bSgaurav rana 			}
83747151e4bSgaurav rana 		}
83847151e4bSgaurav rana 
83947151e4bSgaurav rana 		hash_cmd = 1;
84047151e4bSgaurav rana 	}
84147151e4bSgaurav rana 
84247151e4bSgaurav rana 	img = malloc(sizeof(struct fsl_secboot_img_priv));
84347151e4bSgaurav rana 
84447151e4bSgaurav rana 	if (!img)
84547151e4bSgaurav rana 		return -1;
84647151e4bSgaurav rana 
84747151e4bSgaurav rana 	memset(img, 0, sizeof(struct fsl_secboot_img_priv));
84847151e4bSgaurav rana 
849b055a0fdSAneesh Bansal 	/* Update the information in Private Struct */
85047151e4bSgaurav rana 	hdr = &img->hdr;
851bc71f926SAneesh Bansal 	img->ehdrloc = haddr;
85285bb3896SSaksham Jain 	img->img_addr_ptr = img_addr_ptr;
853b055a0fdSAneesh Bansal 	esbc = (u8 *)img->ehdrloc;
85447151e4bSgaurav rana 
85547151e4bSgaurav rana 	memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
85647151e4bSgaurav rana 
85747151e4bSgaurav rana 	/* read and validate esbc header */
85847151e4bSgaurav rana 	ret = read_validate_esbc_client_header(img);
85947151e4bSgaurav rana 
86047151e4bSgaurav rana 	if (ret != ESBC_VALID_HDR) {
86147151e4bSgaurav rana 		fsl_secboot_handle_error(ret);
86247151e4bSgaurav rana 		goto exit;
86347151e4bSgaurav rana 	}
86447151e4bSgaurav rana 
86547151e4bSgaurav rana 	/* SRKH present in SFP */
86647151e4bSgaurav rana 	for (i = 0; i < NUM_SRKH_REGS; i++)
86747151e4bSgaurav rana 		srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
86847151e4bSgaurav rana 
86947151e4bSgaurav rana 	/*
87047151e4bSgaurav rana 	 * Calculate hash of key obtained via offset present in
87147151e4bSgaurav rana 	 * ESBC uboot client hdr
87247151e4bSgaurav rana 	 */
87347151e4bSgaurav rana 	ret = calc_img_key_hash(img);
87447151e4bSgaurav rana 	if (ret) {
87547151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
87647151e4bSgaurav rana 		goto exit;
87747151e4bSgaurav rana 	}
87847151e4bSgaurav rana 
87947151e4bSgaurav rana 	/* Compare hash obtained above with SRK hash present in SFP */
88047151e4bSgaurav rana 	if (hash_cmd)
88147151e4bSgaurav rana 		ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
88247151e4bSgaurav rana 	else
88347151e4bSgaurav rana 		ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
88447151e4bSgaurav rana 
88547151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
88647151e4bSgaurav rana 	if (!hash_cmd && check_ie(img))
88747151e4bSgaurav rana 		ret = 0;
88847151e4bSgaurav rana #endif
88947151e4bSgaurav rana 
89047151e4bSgaurav rana 	if (ret != 0) {
89147151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
89247151e4bSgaurav rana 		goto exit;
89347151e4bSgaurav rana 	}
89447151e4bSgaurav rana 
8956629261dSAneesh Bansal 	ret = calculate_cmp_img_sig(img);
89647151e4bSgaurav rana 	if (ret) {
8976629261dSAneesh Bansal 		fsl_secboot_handle_error(ret);
89847151e4bSgaurav rana 		goto exit;
89947151e4bSgaurav rana 	}
90047151e4bSgaurav rana 
90147151e4bSgaurav rana exit:
902bc71f926SAneesh Bansal 	return ret;
90347151e4bSgaurav rana }
904