xref: /rk3399_rockchip-uboot/board/freescale/common/fsl_validate.c (revision 856b284617eea5688ccf5f4655f8d70ac5ae5fbb)
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];
3847151e4bSgaurav rana static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
3947151e4bSgaurav rana 
4047151e4bSgaurav rana void branch_to_self(void) __attribute__ ((noreturn));
4147151e4bSgaurav rana 
4247151e4bSgaurav rana /*
4347151e4bSgaurav rana  * This function will put core in infinite loop.
4447151e4bSgaurav rana  * This will be called when the ESBC can not proceed further due
4547151e4bSgaurav rana  * to some unknown errors.
4647151e4bSgaurav rana  */
4747151e4bSgaurav rana void branch_to_self(void)
4847151e4bSgaurav rana {
4947151e4bSgaurav rana 	printf("Core is in infinite loop due to errors.\n");
5047151e4bSgaurav rana self:
5147151e4bSgaurav rana 	goto self;
5247151e4bSgaurav rana }
5347151e4bSgaurav rana 
5447151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
5547151e4bSgaurav rana static u32 check_ie(struct fsl_secboot_img_priv *img)
5647151e4bSgaurav rana {
5747151e4bSgaurav rana 	if (img->hdr.ie_flag)
5847151e4bSgaurav rana 		return 1;
5947151e4bSgaurav rana 
6047151e4bSgaurav rana 	return 0;
6147151e4bSgaurav rana }
6247151e4bSgaurav rana 
6347151e4bSgaurav rana /* This function returns the CSF Header Address of uboot
6447151e4bSgaurav rana  * For MPC85xx based platforms, the LAW mapping for NOR
6547151e4bSgaurav rana  * flash changes in uboot code. Hence the offset needs
6647151e4bSgaurav rana  * to be calculated and added to the new NOR flash base
6747151e4bSgaurav rana  * address
6847151e4bSgaurav rana  */
6947151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
707bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
7147151e4bSgaurav rana {
7247151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
7347151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
7447151e4bSgaurav rana 	u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
757bcb0eb2SAneesh Bansal 	u32 flash_addr, addr;
7647151e4bSgaurav rana 	int found = 0;
7747151e4bSgaurav rana 	int i = 0;
7847151e4bSgaurav rana 
7947151e4bSgaurav rana 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
8047151e4bSgaurav rana 		flash_addr = flash_info[i].start[0];
8147151e4bSgaurav rana 		addr = flash_info[i].start[0] + csf_flash_offset;
8247151e4bSgaurav rana 		if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
837bcb0eb2SAneesh Bansal 			debug("Barker found on addr %x\n", addr);
8447151e4bSgaurav rana 			found = 1;
8547151e4bSgaurav rana 			break;
8647151e4bSgaurav rana 		}
8747151e4bSgaurav rana 	}
8847151e4bSgaurav rana 
8947151e4bSgaurav rana 	if (!found)
9047151e4bSgaurav rana 		return -1;
9147151e4bSgaurav rana 
9247151e4bSgaurav rana 	*csf_addr = addr;
9347151e4bSgaurav rana 	*flash_base_addr = flash_addr;
9447151e4bSgaurav rana 
9547151e4bSgaurav rana 	return 0;
9647151e4bSgaurav rana }
9747151e4bSgaurav rana #else
9847151e4bSgaurav rana /* For platforms like LS1020, correct flash address is present in
9947151e4bSgaurav rana  * the header. So the function reqturns flash base address as 0
10047151e4bSgaurav rana  */
1017bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
10247151e4bSgaurav rana {
10347151e4bSgaurav rana 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
10447151e4bSgaurav rana 	u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
10547151e4bSgaurav rana 
1069711f528SAneesh Bansal 	if (memcmp((u8 *)(uintptr_t)csf_hdr_addr,
1079711f528SAneesh Bansal 		   barker_code, ESBC_BARKER_LEN))
10847151e4bSgaurav rana 		return -1;
10947151e4bSgaurav rana 
11047151e4bSgaurav rana 	*csf_addr = csf_hdr_addr;
11147151e4bSgaurav rana 	*flash_base_addr = 0;
11247151e4bSgaurav rana 	return 0;
11347151e4bSgaurav rana }
11447151e4bSgaurav rana #endif
11547151e4bSgaurav rana 
1167bcb0eb2SAneesh Bansal static int get_ie_info_addr(u32 *ie_addr)
11747151e4bSgaurav rana {
11847151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
11947151e4bSgaurav rana 	struct fsl_secboot_sg_table *sg_tbl;
1207bcb0eb2SAneesh Bansal 	u32 flash_base_addr, csf_addr;
12147151e4bSgaurav rana 
12247151e4bSgaurav rana 	if (get_csf_base_addr(&csf_addr, &flash_base_addr))
12347151e4bSgaurav rana 		return -1;
12447151e4bSgaurav rana 
1259711f528SAneesh Bansal 	hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr;
12647151e4bSgaurav rana 
12747151e4bSgaurav rana 	/* For SoC's with Trust Architecture v1 with corenet bus
12847151e4bSgaurav rana 	 * the sg table field in CSF header has absolute address
12947151e4bSgaurav rana 	 * for sg table in memory. In other Trust Architecture,
13047151e4bSgaurav rana 	 * this field specifies the offset of sg table from the
13147151e4bSgaurav rana 	 * base address of CSF Header
13247151e4bSgaurav rana 	 */
13347151e4bSgaurav rana #if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
13447151e4bSgaurav rana 	sg_tbl = (struct fsl_secboot_sg_table *)
1357bcb0eb2SAneesh Bansal 		 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
13647151e4bSgaurav rana 		  flash_base_addr);
13747151e4bSgaurav rana #else
1389711f528SAneesh Bansal 	sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
1397bcb0eb2SAneesh Bansal 						 (u32)hdr->psgtable);
14047151e4bSgaurav rana #endif
14147151e4bSgaurav rana 
14247151e4bSgaurav rana 	/* IE Key Table is the first entry in the SG Table */
14347151e4bSgaurav rana #if defined(CONFIG_MPC85xx)
14447151e4bSgaurav rana 	*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
14547151e4bSgaurav rana 		   flash_base_addr;
14647151e4bSgaurav rana #else
14747151e4bSgaurav rana 	*ie_addr = sg_tbl->src_addr;
14847151e4bSgaurav rana #endif
14947151e4bSgaurav rana 
1507bcb0eb2SAneesh Bansal 	debug("IE Table address is %x\n", *ie_addr);
15147151e4bSgaurav rana 	return 0;
15247151e4bSgaurav rana }
15347151e4bSgaurav rana 
15447151e4bSgaurav rana #endif
15547151e4bSgaurav rana 
15647151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
15747151e4bSgaurav rana /* This function checks srk_table_flag in header and set/reset srk_flag.*/
15847151e4bSgaurav rana static u32 check_srk(struct fsl_secboot_img_priv *img)
15947151e4bSgaurav rana {
16047151e4bSgaurav rana 	if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
16147151e4bSgaurav rana 		return 1;
16247151e4bSgaurav rana 
16347151e4bSgaurav rana 	return 0;
16447151e4bSgaurav rana }
16547151e4bSgaurav rana 
16647151e4bSgaurav rana /* This function returns ospr's key_revoc values.*/
16747151e4bSgaurav rana static u32 get_key_revoc(void)
16847151e4bSgaurav rana {
16947151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
17047151e4bSgaurav rana 	return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
17147151e4bSgaurav rana 		OSPR_KEY_REVOC_SHIFT;
17247151e4bSgaurav rana }
17347151e4bSgaurav rana 
17447151e4bSgaurav rana /* This function checks if selected key is revoked or not.*/
17547151e4bSgaurav rana static u32 is_key_revoked(u32 keynum, u32 rev_flag)
17647151e4bSgaurav rana {
17747151e4bSgaurav rana 	if (keynum == UNREVOCABLE_KEY)
17847151e4bSgaurav rana 		return 0;
17947151e4bSgaurav rana 
18047151e4bSgaurav rana 	if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
18147151e4bSgaurav rana 		return 1;
18247151e4bSgaurav rana 
18347151e4bSgaurav rana 	return 0;
18447151e4bSgaurav rana }
18547151e4bSgaurav rana 
18694ba5e41SAneesh Bansal /* It read validates srk_table key lengths.*/
18794ba5e41SAneesh Bansal static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
18847151e4bSgaurav rana {
18947151e4bSgaurav rana 	int i = 0;
19094ba5e41SAneesh Bansal 	u32 ret, key_num, key_revoc_flag, size;
19194ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
19294ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
19394ba5e41SAneesh Bansal 
19494ba5e41SAneesh Bansal 	if ((hdr->len_kr.num_srk == 0) ||
19594ba5e41SAneesh Bansal 	    (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
19694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
19794ba5e41SAneesh Bansal 
19894ba5e41SAneesh Bansal 	key_num = hdr->len_kr.srk_sel;
19994ba5e41SAneesh Bansal 	if (key_num == 0 || key_num > hdr->len_kr.num_srk)
20094ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
20194ba5e41SAneesh Bansal 
20294ba5e41SAneesh Bansal 	/* Get revoc key from sfp */
20394ba5e41SAneesh Bansal 	key_revoc_flag = get_key_revoc();
20494ba5e41SAneesh Bansal 	ret = is_key_revoked(key_num, key_revoc_flag);
20594ba5e41SAneesh Bansal 	if (ret)
20694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
20794ba5e41SAneesh Bansal 
20894ba5e41SAneesh Bansal 	size = hdr->len_kr.num_srk * sizeof(struct srk_table);
20994ba5e41SAneesh Bansal 
21094ba5e41SAneesh Bansal 	memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
21194ba5e41SAneesh Bansal 
21294ba5e41SAneesh Bansal 	for (i = 0; i < hdr->len_kr.num_srk; i++) {
21394ba5e41SAneesh Bansal 		if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
21447151e4bSgaurav rana 			return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
21547151e4bSgaurav rana 	}
21694ba5e41SAneesh Bansal 
21794ba5e41SAneesh Bansal 	img->key_len = img->srk_tbl[key_num - 1].key_len;
21894ba5e41SAneesh Bansal 
21994ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
22094ba5e41SAneesh Bansal 	       img->key_len);
22194ba5e41SAneesh Bansal 
22247151e4bSgaurav rana 	return 0;
22347151e4bSgaurav rana }
22447151e4bSgaurav rana #endif
22547151e4bSgaurav rana 
22694ba5e41SAneesh Bansal static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
22794ba5e41SAneesh Bansal {
22894ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
22994ba5e41SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
23094ba5e41SAneesh Bansal 
23194ba5e41SAneesh Bansal 	/* check key length */
23294ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(hdr->key_len))
23394ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
23494ba5e41SAneesh Bansal 
23594ba5e41SAneesh Bansal 	memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
23694ba5e41SAneesh Bansal 
23794ba5e41SAneesh Bansal 	img->key_len = hdr->key_len;
23894ba5e41SAneesh Bansal 
23994ba5e41SAneesh Bansal 	return 0;
24094ba5e41SAneesh Bansal }
24194ba5e41SAneesh Bansal 
24294ba5e41SAneesh Bansal #if defined(CONFIG_FSL_ISBC_KEY_EXT)
24394ba5e41SAneesh Bansal static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
24494ba5e41SAneesh Bansal {
24594ba5e41SAneesh Bansal 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
24694ba5e41SAneesh Bansal 	u32 ie_key_len, ie_revoc_flag, ie_num;
24794ba5e41SAneesh Bansal 	struct ie_key_info *ie_info;
24894ba5e41SAneesh Bansal 
24994ba5e41SAneesh Bansal 	if (get_ie_info_addr(&img->ie_addr))
25094ba5e41SAneesh Bansal 		return ERROR_IE_TABLE_NOT_FOUND;
25194ba5e41SAneesh Bansal 	ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
25294ba5e41SAneesh Bansal 	if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
25394ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
25494ba5e41SAneesh Bansal 
25594ba5e41SAneesh Bansal 	ie_num = hdr->ie_key_sel;
25694ba5e41SAneesh Bansal 	if (ie_num == 0 || ie_num > ie_info->num_keys)
25794ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
25894ba5e41SAneesh Bansal 
25994ba5e41SAneesh Bansal 	ie_revoc_flag = ie_info->key_revok;
26094ba5e41SAneesh Bansal 	if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
26194ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
26294ba5e41SAneesh Bansal 
26394ba5e41SAneesh Bansal 	ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
26494ba5e41SAneesh Bansal 
26594ba5e41SAneesh Bansal 	if (!CHECK_KEY_LEN(ie_key_len))
26694ba5e41SAneesh Bansal 		return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
26794ba5e41SAneesh Bansal 
26894ba5e41SAneesh Bansal 	memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
26994ba5e41SAneesh Bansal 	       ie_key_len);
27094ba5e41SAneesh Bansal 
27194ba5e41SAneesh Bansal 	img->key_len = ie_key_len;
27294ba5e41SAneesh Bansal 	return 0;
27394ba5e41SAneesh Bansal }
27494ba5e41SAneesh Bansal #endif
27594ba5e41SAneesh Bansal 
27694ba5e41SAneesh Bansal 
27747151e4bSgaurav rana /* This function return length of public key.*/
27847151e4bSgaurav rana static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
27947151e4bSgaurav rana {
28047151e4bSgaurav rana 	return img->key_len;
28147151e4bSgaurav rana }
28247151e4bSgaurav rana 
28347151e4bSgaurav rana /*
28447151e4bSgaurav rana  * Handles the ESBC uboot client header verification failure.
28547151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
28647151e4bSgaurav rana  * parsing and checking of ESBC uboot client header. It will also
28747151e4bSgaurav rana  * set the error bits in the SEC_MON.
28847151e4bSgaurav rana  */
28947151e4bSgaurav rana static void fsl_secboot_header_verification_failure(void)
29047151e4bSgaurav rana {
29147151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
29247151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
29347151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
29447151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
29547151e4bSgaurav rana 
29647151e4bSgaurav rana 	/* 29th bit of OSPR is ITS */
29747151e4bSgaurav rana 	u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
29847151e4bSgaurav rana 
29947151e4bSgaurav rana 	/*
30047151e4bSgaurav rana 	 * Read the SEC_MON status register
30147151e4bSgaurav rana 	 * Read SSM_ST field
30247151e4bSgaurav rana 	 */
30347151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
30447151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
30547151e4bSgaurav rana 		if (its == 1)
30647151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
30747151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
30847151e4bSgaurav rana 		else
30947151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
31047151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
31147151e4bSgaurav rana 	}
31247151e4bSgaurav rana 
31347151e4bSgaurav rana 	printf("Generating reset request\n");
31447151e4bSgaurav rana 	do_reset(NULL, 0, 0, NULL);
31547151e4bSgaurav rana }
31647151e4bSgaurav rana 
31747151e4bSgaurav rana /*
31847151e4bSgaurav rana  * Handles the ESBC uboot client image verification failure.
31947151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
32047151e4bSgaurav rana  * public key hash comparison and signature verification of
32147151e4bSgaurav rana  * ESBC uboot client image. It will also
32247151e4bSgaurav rana  * set the error bits in the SEC_MON.
32347151e4bSgaurav rana  */
32447151e4bSgaurav rana static void fsl_secboot_image_verification_failure(void)
32547151e4bSgaurav rana {
32647151e4bSgaurav rana 	struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
32747151e4bSgaurav rana 						(CONFIG_SYS_SEC_MON_ADDR);
32847151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
32947151e4bSgaurav rana 	u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
33047151e4bSgaurav rana 
3316ec9aef2SAneesh Bansal 	u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
33247151e4bSgaurav rana 
33347151e4bSgaurav rana 	/*
33447151e4bSgaurav rana 	 * Read the SEC_MON status register
33547151e4bSgaurav rana 	 * Read SSM_ST field
33647151e4bSgaurav rana 	 */
33747151e4bSgaurav rana 	sts = sec_mon_in32(&sec_mon_regs->hp_stat);
33847151e4bSgaurav rana 	if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
33947151e4bSgaurav rana 		if (its == 1) {
34047151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
34147151e4bSgaurav rana 					     HPSR_SSM_ST_SOFT_FAIL);
34247151e4bSgaurav rana 
34347151e4bSgaurav rana 			printf("Generating reset request\n");
34447151e4bSgaurav rana 			do_reset(NULL, 0, 0, NULL);
34547151e4bSgaurav rana 		} else {
34647151e4bSgaurav rana 			change_sec_mon_state(HPSR_SSM_ST_TRUST,
34747151e4bSgaurav rana 					     HPSR_SSM_ST_NON_SECURE);
34847151e4bSgaurav rana 		}
34947151e4bSgaurav rana 	}
35047151e4bSgaurav rana }
35147151e4bSgaurav rana 
35247151e4bSgaurav rana static void fsl_secboot_bootscript_parse_failure(void)
35347151e4bSgaurav rana {
35447151e4bSgaurav rana 	fsl_secboot_header_verification_failure();
35547151e4bSgaurav rana }
35647151e4bSgaurav rana 
35747151e4bSgaurav rana /*
35847151e4bSgaurav rana  * Handles the errors in esbc boot.
35947151e4bSgaurav rana  * This  function  handles all the errors which might occur in the
36047151e4bSgaurav rana  * esbc boot phase. It will call the appropriate api to log the
36147151e4bSgaurav rana  * errors and set the error bits in the SEC_MON.
36247151e4bSgaurav rana  */
36347151e4bSgaurav rana void fsl_secboot_handle_error(int error)
36447151e4bSgaurav rana {
36547151e4bSgaurav rana 	const struct fsl_secboot_errcode *e;
36647151e4bSgaurav rana 
36747151e4bSgaurav rana 	for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
36847151e4bSgaurav rana 		e++) {
36947151e4bSgaurav rana 		if (e->errcode == error)
37047151e4bSgaurav rana 			printf("ERROR :: %x :: %s\n", error, e->name);
37147151e4bSgaurav rana 	}
37247151e4bSgaurav rana 
373*856b2846SAneesh Bansal 	/* If Boot Mode is secure, transition the SNVS state and issue
374*856b2846SAneesh Bansal 	 * reset based on type of failure and ITS setting.
375*856b2846SAneesh Bansal 	 * If Boot mode is non-secure, return from this function.
376*856b2846SAneesh Bansal 	 */
377*856b2846SAneesh Bansal 	if (fsl_check_boot_mode_secure() == 0)
378*856b2846SAneesh Bansal 		return;
379*856b2846SAneesh Bansal 
38047151e4bSgaurav rana 	switch (error) {
38147151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_BARKER:
38247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
38347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
38447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
38547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
38647151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
38747151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
38847151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
38947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
39047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
39147151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
39247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
39347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
39447151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
39547151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
39647151e4bSgaurav rana #endif
39747151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
39847151e4bSgaurav rana 	/*@fallthrough@*/
39947151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
40047151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
40147151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
40247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
40347151e4bSgaurav rana 	case ERROR_IE_TABLE_NOT_FOUND:
40447151e4bSgaurav rana #endif
40547151e4bSgaurav rana 		fsl_secboot_header_verification_failure();
40647151e4bSgaurav rana 		break;
40747151e4bSgaurav rana 	case ERROR_ESBC_SEC_RESET:
40847151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
40947151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
41047151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
41147151e4bSgaurav rana 	case ERROR_ESBC_SEC_JOBQ_STATUS:
41247151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
41347151e4bSgaurav rana 	case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
41447151e4bSgaurav rana 		fsl_secboot_image_verification_failure();
41547151e4bSgaurav rana 		break;
41647151e4bSgaurav rana 	case ERROR_ESBC_MISSING_BOOTM:
41747151e4bSgaurav rana 		fsl_secboot_bootscript_parse_failure();
41847151e4bSgaurav rana 		break;
41947151e4bSgaurav rana 	case ERROR_ESBC_WRONG_CMD:
42047151e4bSgaurav rana 	default:
42147151e4bSgaurav rana 		branch_to_self();
42247151e4bSgaurav rana 		break;
42347151e4bSgaurav rana 	}
42447151e4bSgaurav rana }
42547151e4bSgaurav rana 
42647151e4bSgaurav rana static void fsl_secblk_handle_error(int error)
42747151e4bSgaurav rana {
42847151e4bSgaurav rana 	switch (error) {
42947151e4bSgaurav rana 	case ERROR_ESBC_SEC_ENQ:
43047151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
43147151e4bSgaurav rana 		break;
43247151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ:
43347151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
43447151e4bSgaurav rana 		break;
43547151e4bSgaurav rana 	case ERROR_ESBC_SEC_DEQ_TO:
43647151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
43747151e4bSgaurav rana 		break;
43847151e4bSgaurav rana 	default:
43947151e4bSgaurav rana 		printf("Job Queue Output status %x\n", error);
44047151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
44147151e4bSgaurav rana 		break;
44247151e4bSgaurav rana 	}
44347151e4bSgaurav rana }
44447151e4bSgaurav rana 
44547151e4bSgaurav rana /*
44647151e4bSgaurav rana  * Calculate hash of key obtained via offset present in ESBC uboot
44747151e4bSgaurav rana  * client hdr. This function calculates the hash of key which is obtained
44847151e4bSgaurav rana  * through offset present in ESBC uboot client header.
44947151e4bSgaurav rana  */
45047151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
45147151e4bSgaurav rana {
45247151e4bSgaurav rana 	struct hash_algo *algo;
45347151e4bSgaurav rana 	void *ctx;
45447151e4bSgaurav rana 	int i, srk = 0;
45547151e4bSgaurav rana 	int ret = 0;
45647151e4bSgaurav rana 	const char *algo_name = "sha256";
45747151e4bSgaurav rana 
45847151e4bSgaurav rana 	/* Calculate hash of the esbc key */
45947151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
46047151e4bSgaurav rana 	if (ret)
46147151e4bSgaurav rana 		return ret;
46247151e4bSgaurav rana 
46347151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
46447151e4bSgaurav rana 	if (ret)
46547151e4bSgaurav rana 		return ret;
46647151e4bSgaurav rana 
46747151e4bSgaurav rana 	/* Update hash for ESBC key */
46847151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
46947151e4bSgaurav rana 	if (check_srk(img)) {
47047151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
4719711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
47247151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
47347151e4bSgaurav rana 		srk = 1;
47447151e4bSgaurav rana 	}
47547151e4bSgaurav rana #endif
47647151e4bSgaurav rana 	if (!srk)
47747151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
47847151e4bSgaurav rana 			img->img_key, img->key_len, 1);
47947151e4bSgaurav rana 	if (ret)
48047151e4bSgaurav rana 		return ret;
48147151e4bSgaurav rana 
48247151e4bSgaurav rana 	/* Copy hash at destination buffer */
48347151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
48447151e4bSgaurav rana 	if (ret)
48547151e4bSgaurav rana 		return ret;
48647151e4bSgaurav rana 
48747151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
48847151e4bSgaurav rana 		img->img_key_hash[i] = hash_val[i];
48947151e4bSgaurav rana 
49047151e4bSgaurav rana 	return 0;
49147151e4bSgaurav rana }
49247151e4bSgaurav rana 
49347151e4bSgaurav rana /*
49447151e4bSgaurav rana  * Calculate hash of ESBC hdr and ESBC. This function calculates the
49547151e4bSgaurav rana  * single hash of ESBC header and ESBC image. If SG flag is on, all
49647151e4bSgaurav rana  * SG entries are also hashed alongwith the complete SG table.
49747151e4bSgaurav rana  */
49847151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
49947151e4bSgaurav rana {
50047151e4bSgaurav rana 	struct hash_algo *algo;
50147151e4bSgaurav rana 	void *ctx;
50247151e4bSgaurav rana 	int ret = 0;
50347151e4bSgaurav rana 	int key_hash = 0;
50447151e4bSgaurav rana 	const char *algo_name = "sha256";
50547151e4bSgaurav rana 
50647151e4bSgaurav rana 	/* Calculate the hash of the ESBC */
50747151e4bSgaurav rana 	ret = hash_progressive_lookup_algo(algo_name, &algo);
50847151e4bSgaurav rana 	if (ret)
50947151e4bSgaurav rana 		return ret;
51047151e4bSgaurav rana 
51147151e4bSgaurav rana 	ret = algo->hash_init(algo, &ctx);
51247151e4bSgaurav rana 	/* Copy hash at destination buffer */
51347151e4bSgaurav rana 	if (ret)
51447151e4bSgaurav rana 		return ret;
51547151e4bSgaurav rana 
51647151e4bSgaurav rana 	/* Update hash for CSF Header */
51747151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
51847151e4bSgaurav rana 		(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
51947151e4bSgaurav rana 	if (ret)
52047151e4bSgaurav rana 		return ret;
52147151e4bSgaurav rana 
52247151e4bSgaurav rana 	/* Update the hash with that of srk table if srk flag is 1
52347151e4bSgaurav rana 	 * If IE Table is selected, key is not added in the hash
52447151e4bSgaurav rana 	 * If neither srk table nor IE key table available, add key
52547151e4bSgaurav rana 	 * from header in the hash calculation
52647151e4bSgaurav rana 	 */
52747151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
52847151e4bSgaurav rana 	if (check_srk(img)) {
52947151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
5309711f528SAneesh Bansal 		      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
53147151e4bSgaurav rana 		      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
53247151e4bSgaurav rana 		key_hash = 1;
53347151e4bSgaurav rana 	}
53447151e4bSgaurav rana #endif
53547151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
53647151e4bSgaurav rana 	if (!key_hash && check_ie(img))
53747151e4bSgaurav rana 		key_hash = 1;
53847151e4bSgaurav rana #endif
53947151e4bSgaurav rana 	if (!key_hash)
54047151e4bSgaurav rana 		ret = algo->hash_update(algo, ctx,
54147151e4bSgaurav rana 			img->img_key, img->hdr.key_len, 0);
54247151e4bSgaurav rana 	if (ret)
54347151e4bSgaurav rana 		return ret;
54447151e4bSgaurav rana 
54547151e4bSgaurav rana 	/* Update hash for actual Image */
54647151e4bSgaurav rana 	ret = algo->hash_update(algo, ctx,
547b055a0fdSAneesh Bansal 		(u8 *)img->img_addr, img->img_size, 1);
54847151e4bSgaurav rana 	if (ret)
54947151e4bSgaurav rana 		return ret;
55047151e4bSgaurav rana 
55147151e4bSgaurav rana 	/* Copy hash at destination buffer */
55247151e4bSgaurav rana 	ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
55347151e4bSgaurav rana 	if (ret)
55447151e4bSgaurav rana 		return ret;
55547151e4bSgaurav rana 
55647151e4bSgaurav rana 	return 0;
55747151e4bSgaurav rana }
55847151e4bSgaurav rana 
55947151e4bSgaurav rana /*
56047151e4bSgaurav rana  * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
56147151e4bSgaurav rana  * pointers for padding, DER value and hash. And finally, constructs EM'
56247151e4bSgaurav rana  * which includes hash of complete CSF header and ESBC image. If SG flag
56347151e4bSgaurav rana  * is on, hash of SG table and entries is also included.
56447151e4bSgaurav rana  */
56547151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
56647151e4bSgaurav rana {
56747151e4bSgaurav rana 	/*
56847151e4bSgaurav rana 	 * RSA PKCSv1.5 encoding format for encoded message is below
56947151e4bSgaurav rana 	 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
57047151e4bSgaurav rana 	 * PS is Padding String
57147151e4bSgaurav rana 	 * DER is DER value for SHA-256
57247151e4bSgaurav rana 	 * Hash is SHA-256 hash
57347151e4bSgaurav rana 	 * *********************************************************
57447151e4bSgaurav rana 	 * representative points to first byte of EM initially and is
57547151e4bSgaurav rana 	 * filled with 0x0
57647151e4bSgaurav rana 	 * representative is incremented by 1 and second byte is filled
57747151e4bSgaurav rana 	 * with 0x1
57847151e4bSgaurav rana 	 * padding points to third byte of EM
57947151e4bSgaurav rana 	 * digest points to full length of EM - 32 bytes
58047151e4bSgaurav rana 	 * hash_id (DER value) points to 19 bytes before pDigest
58147151e4bSgaurav rana 	 * separator is one byte which separates padding and DER
58247151e4bSgaurav rana 	 */
58347151e4bSgaurav rana 
58447151e4bSgaurav rana 	size_t len;
58547151e4bSgaurav rana 	u8 *representative;
58647151e4bSgaurav rana 	u8 *padding, *digest;
58747151e4bSgaurav rana 	u8 *hash_id, *separator;
58847151e4bSgaurav rana 	int i;
58947151e4bSgaurav rana 
59047151e4bSgaurav rana 	len = (get_key_len(img) / 2) - 1;
59147151e4bSgaurav rana 	representative = img->img_encoded_hash_second;
59247151e4bSgaurav rana 	representative[0] = 0;
59347151e4bSgaurav rana 	representative[1] = 1;  /* block type 1 */
59447151e4bSgaurav rana 
59547151e4bSgaurav rana 	padding = &representative[2];
59647151e4bSgaurav rana 	digest = &representative[1] + len - 32;
59747151e4bSgaurav rana 	hash_id = digest - sizeof(hash_identifier);
59847151e4bSgaurav rana 	separator = hash_id - 1;
59947151e4bSgaurav rana 
60047151e4bSgaurav rana 	/* fill padding area pointed by padding with 0xff */
60147151e4bSgaurav rana 	memset(padding, 0xff, separator - padding);
60247151e4bSgaurav rana 
60347151e4bSgaurav rana 	/* fill byte pointed by separator */
60447151e4bSgaurav rana 	*separator = 0;
60547151e4bSgaurav rana 
60647151e4bSgaurav rana 	/* fill SHA-256 DER value  pointed by HashId */
60747151e4bSgaurav rana 	memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
60847151e4bSgaurav rana 
60947151e4bSgaurav rana 	/* fill hash pointed by Digest */
61047151e4bSgaurav rana 	for (i = 0; i < SHA256_BYTES; i++)
61147151e4bSgaurav rana 		digest[i] = hash_val[i];
61247151e4bSgaurav rana }
61347151e4bSgaurav rana 
61447151e4bSgaurav rana /*
61547151e4bSgaurav rana  * Reads and validates the ESBC client header.
61647151e4bSgaurav rana  * This function reads key and signature from the ESBC client header.
61747151e4bSgaurav rana  * If Scatter/Gather flag is on, lengths and offsets of images
61847151e4bSgaurav rana  * present as SG entries are also read. This function also checks
61947151e4bSgaurav rana  * whether the header is valid or not.
62047151e4bSgaurav rana  */
62147151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
62247151e4bSgaurav rana {
62347151e4bSgaurav rana 	char buf[20];
62447151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr = &img->hdr;
6259711f528SAneesh Bansal 	void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
62647151e4bSgaurav rana 	u8 *k, *s;
62794ba5e41SAneesh Bansal 	u32 ret = 0;
62894ba5e41SAneesh Bansal 
62947151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
63047151e4bSgaurav rana #endif
63147151e4bSgaurav rana 	int  key_found = 0;
63247151e4bSgaurav rana 
63347151e4bSgaurav rana 	/* check barker code */
63447151e4bSgaurav rana 	if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
63547151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_BARKER;
63647151e4bSgaurav rana 
637b055a0fdSAneesh Bansal 	/* If Image Address is not passed as argument to function,
638b055a0fdSAneesh Bansal 	 * then Address and Size must be read from the Header.
639b055a0fdSAneesh Bansal 	 */
640b055a0fdSAneesh Bansal 	if (img->img_addr == 0) {
6419711f528SAneesh Bansal 	#ifdef CONFIG_ESBC_ADDR_64BIT
642b055a0fdSAneesh Bansal 		img->img_addr = hdr->pimg64;
6439711f528SAneesh Bansal 	#else
644b055a0fdSAneesh Bansal 		img->img_addr = hdr->pimg;
6459711f528SAneesh Bansal 	#endif
646b055a0fdSAneesh Bansal 	}
647b055a0fdSAneesh Bansal 
648b055a0fdSAneesh Bansal 	sprintf(buf, "%lx", img->img_addr);
64947151e4bSgaurav rana 	setenv("img_addr", buf);
65047151e4bSgaurav rana 
65147151e4bSgaurav rana 	if (!hdr->img_size)
65247151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
65347151e4bSgaurav rana 
654b055a0fdSAneesh Bansal 	img->img_size = hdr->img_size;
655b055a0fdSAneesh Bansal 
65647151e4bSgaurav rana 	/* Key checking*/
65747151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION
65847151e4bSgaurav rana 	if (check_srk(img)) {
65994ba5e41SAneesh Bansal 		ret = read_validate_srk_tbl(img);
66047151e4bSgaurav rana 		if (ret != 0)
66147151e4bSgaurav rana 			return ret;
66247151e4bSgaurav rana 		key_found = 1;
66347151e4bSgaurav rana 	}
66447151e4bSgaurav rana #endif
66547151e4bSgaurav rana 
66647151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
66747151e4bSgaurav rana 	if (!key_found && check_ie(img)) {
66894ba5e41SAneesh Bansal 		ret = read_validate_ie_tbl(img);
66994ba5e41SAneesh Bansal 		if (ret != 0)
67094ba5e41SAneesh Bansal 			return ret;
67147151e4bSgaurav rana 		key_found = 1;
67247151e4bSgaurav rana 	}
67347151e4bSgaurav rana #endif
67447151e4bSgaurav rana 
67547151e4bSgaurav rana 	if (key_found == 0) {
67694ba5e41SAneesh Bansal 		ret = read_validate_single_key(img);
67794ba5e41SAneesh Bansal 		if (ret != 0)
67894ba5e41SAneesh Bansal 			return ret;
67947151e4bSgaurav rana 		key_found = 1;
68047151e4bSgaurav rana 	}
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);
69447151e4bSgaurav rana 
69547151e4bSgaurav rana 	/* No SG support */
69647151e4bSgaurav rana 	if (hdr->sg_flag)
69747151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SG;
69847151e4bSgaurav rana 
69947151e4bSgaurav rana 	/* modulus most significant bit should be set */
70047151e4bSgaurav rana 	k = (u8 *)&img->img_key;
70147151e4bSgaurav rana 
70247151e4bSgaurav rana 	if ((k[0] & 0x80) == 0)
70347151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
70447151e4bSgaurav rana 
70547151e4bSgaurav rana 	/* modulus value should be odd */
70647151e4bSgaurav rana 	if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
70747151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
70847151e4bSgaurav rana 
70947151e4bSgaurav rana 	/* Check signature value < modulus value */
71047151e4bSgaurav rana 	s = (u8 *)&img->img_sign;
71147151e4bSgaurav rana 
71247151e4bSgaurav rana 	if (!(memcmp(s, k, hdr->sign_len) < 0))
71347151e4bSgaurav rana 		return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
71447151e4bSgaurav rana 
71547151e4bSgaurav rana 	return ESBC_VALID_HDR;
71647151e4bSgaurav rana }
71747151e4bSgaurav rana 
71847151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num)
71947151e4bSgaurav rana {
72047151e4bSgaurav rana 	char *endptr;
72147151e4bSgaurav rana 	ulong tmp;
72247151e4bSgaurav rana 
72347151e4bSgaurav rana 	if (!p) {
72447151e4bSgaurav rana 		return 0;
72547151e4bSgaurav rana 	} else {
72647151e4bSgaurav rana 		tmp = simple_strtoul(p, &endptr, 16);
72747151e4bSgaurav rana 		if (sizeof(ulong) == 4)
72847151e4bSgaurav rana 			*num = cpu_to_be32(tmp);
72947151e4bSgaurav rana 		else
73047151e4bSgaurav rana 			*num = cpu_to_be64(tmp);
73147151e4bSgaurav rana 	}
73247151e4bSgaurav rana 
73347151e4bSgaurav rana 	return *p != '\0' && *endptr == '\0';
73447151e4bSgaurav rana }
7356629261dSAneesh Bansal /* Function to calculate the ESBC Image Hash
7366629261dSAneesh Bansal  * and hash from Digital signature.
7376629261dSAneesh Bansal  * The Two hash's are compared to yield the
7386629261dSAneesh Bansal  * result of signature validation.
7396629261dSAneesh Bansal  */
7406629261dSAneesh Bansal static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
7416629261dSAneesh Bansal {
7426629261dSAneesh Bansal 	int ret;
7436629261dSAneesh Bansal 	uint32_t key_len;
7446629261dSAneesh Bansal 	struct key_prop prop;
7456629261dSAneesh Bansal #if !defined(USE_HOSTCC)
7466629261dSAneesh Bansal 	struct udevice *mod_exp_dev;
7476629261dSAneesh Bansal #endif
7486629261dSAneesh Bansal 	ret = calc_esbchdr_esbc_hash(img);
7496629261dSAneesh Bansal 	if (ret)
7506629261dSAneesh Bansal 		return ret;
7516629261dSAneesh Bansal 
7526629261dSAneesh Bansal 	/* Construct encoded hash EM' wrt PKCSv1.5 */
7536629261dSAneesh Bansal 	construct_img_encoded_hash_second(img);
7546629261dSAneesh Bansal 
7556629261dSAneesh Bansal 	/* Fill prop structure for public key */
7566629261dSAneesh Bansal 	memset(&prop, 0, sizeof(struct key_prop));
7576629261dSAneesh Bansal 	key_len = get_key_len(img) / 2;
7586629261dSAneesh Bansal 	prop.modulus = img->img_key;
7596629261dSAneesh Bansal 	prop.public_exponent = img->img_key + key_len;
7606629261dSAneesh Bansal 	prop.num_bits = key_len * 8;
7616629261dSAneesh Bansal 	prop.exp_len = key_len;
7626629261dSAneesh Bansal 
7636629261dSAneesh Bansal 	ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
7646629261dSAneesh Bansal 	if (ret) {
7656629261dSAneesh Bansal 		printf("RSA: Can't find Modular Exp implementation\n");
7666629261dSAneesh Bansal 		return -EINVAL;
7676629261dSAneesh Bansal 	}
7686629261dSAneesh Bansal 
7696629261dSAneesh Bansal 	ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
7706629261dSAneesh Bansal 			  &prop, img->img_encoded_hash);
7716629261dSAneesh Bansal 	if (ret)
7726629261dSAneesh Bansal 		return ret;
7736629261dSAneesh Bansal 
7746629261dSAneesh Bansal 	/*
7756629261dSAneesh Bansal 	 * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
7766629261dSAneesh Bansal 	 * memcmp returns zero on success
7776629261dSAneesh Bansal 	 * memcmp returns non-zero on failure
7786629261dSAneesh Bansal 	 */
7796629261dSAneesh Bansal 	ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
7806629261dSAneesh Bansal 		img->hdr.sign_len);
7816629261dSAneesh Bansal 
7826629261dSAneesh Bansal 	if (ret)
7836629261dSAneesh Bansal 		return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;
7846629261dSAneesh Bansal 
7856629261dSAneesh Bansal 	return 0;
7866629261dSAneesh Bansal }
78747151e4bSgaurav rana 
788b055a0fdSAneesh Bansal int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
789b055a0fdSAneesh Bansal 			uintptr_t img_addr)
79047151e4bSgaurav rana {
79147151e4bSgaurav rana 	struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
79247151e4bSgaurav rana 	ulong hash[SHA256_BYTES/sizeof(ulong)];
79347151e4bSgaurav rana 	char hash_str[NUM_HEX_CHARS + 1];
79447151e4bSgaurav rana 	struct fsl_secboot_img_priv *img;
79547151e4bSgaurav rana 	struct fsl_secboot_img_hdr *hdr;
79647151e4bSgaurav rana 	void *esbc;
79747151e4bSgaurav rana 	int ret, i, hash_cmd = 0;
79847151e4bSgaurav rana 	u32 srk_hash[8];
79947151e4bSgaurav rana 
800bc71f926SAneesh Bansal 	if (arg_hash_str != NULL) {
801bc71f926SAneesh Bansal 		const char *cp = arg_hash_str;
80247151e4bSgaurav rana 		int i = 0;
80347151e4bSgaurav rana 
80447151e4bSgaurav rana 		if (*cp == '0' && *(cp + 1) == 'x')
80547151e4bSgaurav rana 			cp += 2;
80647151e4bSgaurav rana 
80747151e4bSgaurav rana 		/* The input string expected is in hex, where
80847151e4bSgaurav rana 		 * each 4 bits would be represented by a hex
80947151e4bSgaurav rana 		 * sha256 hash is 256 bits long, which would mean
81047151e4bSgaurav rana 		 * num of characters = 256 / 4
81147151e4bSgaurav rana 		 */
81247151e4bSgaurav rana 		if (strlen(cp) != SHA256_NIBBLES) {
81347151e4bSgaurav rana 			printf("%s is not a 256 bits hex string as expected\n",
814bc71f926SAneesh Bansal 			       arg_hash_str);
81547151e4bSgaurav rana 			return -1;
81647151e4bSgaurav rana 		}
81747151e4bSgaurav rana 
81847151e4bSgaurav rana 		for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
81947151e4bSgaurav rana 			strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
82047151e4bSgaurav rana 				NUM_HEX_CHARS);
82147151e4bSgaurav rana 			hash_str[NUM_HEX_CHARS] = '\0';
82247151e4bSgaurav rana 			if (!str2longbe(hash_str, &hash[i])) {
82347151e4bSgaurav rana 				printf("%s is not a 256 bits hex string ",
824bc71f926SAneesh Bansal 				       arg_hash_str);
82547151e4bSgaurav rana 				return -1;
82647151e4bSgaurav rana 			}
82747151e4bSgaurav rana 		}
82847151e4bSgaurav rana 
82947151e4bSgaurav rana 		hash_cmd = 1;
83047151e4bSgaurav rana 	}
83147151e4bSgaurav rana 
83247151e4bSgaurav rana 	img = malloc(sizeof(struct fsl_secboot_img_priv));
83347151e4bSgaurav rana 
83447151e4bSgaurav rana 	if (!img)
83547151e4bSgaurav rana 		return -1;
83647151e4bSgaurav rana 
83747151e4bSgaurav rana 	memset(img, 0, sizeof(struct fsl_secboot_img_priv));
83847151e4bSgaurav rana 
839b055a0fdSAneesh Bansal 	/* Update the information in Private Struct */
84047151e4bSgaurav rana 	hdr = &img->hdr;
841bc71f926SAneesh Bansal 	img->ehdrloc = haddr;
842b055a0fdSAneesh Bansal 	img->img_addr = img_addr;
843b055a0fdSAneesh Bansal 	esbc = (u8 *)img->ehdrloc;
84447151e4bSgaurav rana 
84547151e4bSgaurav rana 	memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
84647151e4bSgaurav rana 
84747151e4bSgaurav rana 	/* read and validate esbc header */
84847151e4bSgaurav rana 	ret = read_validate_esbc_client_header(img);
84947151e4bSgaurav rana 
85047151e4bSgaurav rana 	if (ret != ESBC_VALID_HDR) {
85147151e4bSgaurav rana 		fsl_secboot_handle_error(ret);
85247151e4bSgaurav rana 		goto exit;
85347151e4bSgaurav rana 	}
85447151e4bSgaurav rana 
85547151e4bSgaurav rana 	/* SRKH present in SFP */
85647151e4bSgaurav rana 	for (i = 0; i < NUM_SRKH_REGS; i++)
85747151e4bSgaurav rana 		srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
85847151e4bSgaurav rana 
85947151e4bSgaurav rana 	/*
86047151e4bSgaurav rana 	 * Calculate hash of key obtained via offset present in
86147151e4bSgaurav rana 	 * ESBC uboot client hdr
86247151e4bSgaurav rana 	 */
86347151e4bSgaurav rana 	ret = calc_img_key_hash(img);
86447151e4bSgaurav rana 	if (ret) {
86547151e4bSgaurav rana 		fsl_secblk_handle_error(ret);
86647151e4bSgaurav rana 		goto exit;
86747151e4bSgaurav rana 	}
86847151e4bSgaurav rana 
86947151e4bSgaurav rana 	/* Compare hash obtained above with SRK hash present in SFP */
87047151e4bSgaurav rana 	if (hash_cmd)
87147151e4bSgaurav rana 		ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
87247151e4bSgaurav rana 	else
87347151e4bSgaurav rana 		ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
87447151e4bSgaurav rana 
87547151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT)
87647151e4bSgaurav rana 	if (!hash_cmd && check_ie(img))
87747151e4bSgaurav rana 		ret = 0;
87847151e4bSgaurav rana #endif
87947151e4bSgaurav rana 
88047151e4bSgaurav rana 	if (ret != 0) {
88147151e4bSgaurav rana 		fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
88247151e4bSgaurav rana 		goto exit;
88347151e4bSgaurav rana 	}
88447151e4bSgaurav rana 
8856629261dSAneesh Bansal 	ret = calculate_cmp_img_sig(img);
88647151e4bSgaurav rana 	if (ret) {
8876629261dSAneesh Bansal 		fsl_secboot_handle_error(ret);
88847151e4bSgaurav rana 		goto exit;
88947151e4bSgaurav rana 	}
89047151e4bSgaurav rana 
89147151e4bSgaurav rana exit:
892bc71f926SAneesh Bansal 	return ret;
89347151e4bSgaurav rana }
894