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> 18*73fb5838SYork Sun #ifdef CONFIG_ARCH_LS1021A 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)) 30ac55dadbSUdit Agarwal #if defined(CONFIG_FSL_ISBC_KEY_EXT) 31ac55dadbSUdit Agarwal /* Global data structure */ 32ac55dadbSUdit Agarwal static struct fsl_secboot_glb glb; 33ac55dadbSUdit Agarwal #endif 3494ba5e41SAneesh Bansal 3547151e4bSgaurav rana /* This array contains DER value for SHA-256 */ 3647151e4bSgaurav rana static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 3747151e4bSgaurav rana 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 3847151e4bSgaurav rana 0x04, 0x20 3947151e4bSgaurav rana }; 4047151e4bSgaurav rana 4147151e4bSgaurav rana static u8 hash_val[SHA256_BYTES]; 42fd6dbc98SSaksham Jain 43fd6dbc98SSaksham Jain #ifdef CONFIG_ESBC_HDR_LS 44fd6dbc98SSaksham Jain /* New Barker Code for LS ESBC Header */ 45fd6dbc98SSaksham Jain static const u8 barker_code[ESBC_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 }; 46fd6dbc98SSaksham Jain #else 4747151e4bSgaurav rana static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 }; 48fd6dbc98SSaksham Jain #endif 4947151e4bSgaurav rana 5047151e4bSgaurav rana void branch_to_self(void) __attribute__ ((noreturn)); 5147151e4bSgaurav rana 5247151e4bSgaurav rana /* 5347151e4bSgaurav rana * This function will put core in infinite loop. 5447151e4bSgaurav rana * This will be called when the ESBC can not proceed further due 5547151e4bSgaurav rana * to some unknown errors. 5647151e4bSgaurav rana */ 5747151e4bSgaurav rana void branch_to_self(void) 5847151e4bSgaurav rana { 5947151e4bSgaurav rana printf("Core is in infinite loop due to errors.\n"); 6047151e4bSgaurav rana self: 6147151e4bSgaurav rana goto self; 6247151e4bSgaurav rana } 6347151e4bSgaurav rana 6447151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 6547151e4bSgaurav rana static u32 check_ie(struct fsl_secboot_img_priv *img) 6647151e4bSgaurav rana { 67ac55dadbSUdit Agarwal if (img->hdr.ie_flag & IE_FLAG_MASK) 6847151e4bSgaurav rana return 1; 6947151e4bSgaurav rana 7047151e4bSgaurav rana return 0; 7147151e4bSgaurav rana } 7247151e4bSgaurav rana 7347151e4bSgaurav rana /* This function returns the CSF Header Address of uboot 7447151e4bSgaurav rana * For MPC85xx based platforms, the LAW mapping for NOR 7547151e4bSgaurav rana * flash changes in uboot code. Hence the offset needs 7647151e4bSgaurav rana * to be calculated and added to the new NOR flash base 7747151e4bSgaurav rana * address 7847151e4bSgaurav rana */ 7947151e4bSgaurav rana #if defined(CONFIG_MPC85xx) 807bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr) 8147151e4bSgaurav rana { 8247151e4bSgaurav rana struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 8347151e4bSgaurav rana u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); 8447151e4bSgaurav rana u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE); 857bcb0eb2SAneesh Bansal u32 flash_addr, addr; 8647151e4bSgaurav rana int found = 0; 8747151e4bSgaurav rana int i = 0; 8847151e4bSgaurav rana 8947151e4bSgaurav rana for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { 9047151e4bSgaurav rana flash_addr = flash_info[i].start[0]; 9147151e4bSgaurav rana addr = flash_info[i].start[0] + csf_flash_offset; 9247151e4bSgaurav rana if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) { 937bcb0eb2SAneesh Bansal debug("Barker found on addr %x\n", addr); 9447151e4bSgaurav rana found = 1; 9547151e4bSgaurav rana break; 9647151e4bSgaurav rana } 9747151e4bSgaurav rana } 9847151e4bSgaurav rana 9947151e4bSgaurav rana if (!found) 10047151e4bSgaurav rana return -1; 10147151e4bSgaurav rana 10247151e4bSgaurav rana *csf_addr = addr; 10347151e4bSgaurav rana *flash_base_addr = flash_addr; 10447151e4bSgaurav rana 10547151e4bSgaurav rana return 0; 10647151e4bSgaurav rana } 10747151e4bSgaurav rana #else 10847151e4bSgaurav rana /* For platforms like LS1020, correct flash address is present in 10947151e4bSgaurav rana * the header. So the function reqturns flash base address as 0 11047151e4bSgaurav rana */ 1117bcb0eb2SAneesh Bansal int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr) 11247151e4bSgaurav rana { 11347151e4bSgaurav rana struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 11447151e4bSgaurav rana u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); 11547151e4bSgaurav rana 1169711f528SAneesh Bansal if (memcmp((u8 *)(uintptr_t)csf_hdr_addr, 1179711f528SAneesh Bansal barker_code, ESBC_BARKER_LEN)) 11847151e4bSgaurav rana return -1; 11947151e4bSgaurav rana 12047151e4bSgaurav rana *csf_addr = csf_hdr_addr; 12147151e4bSgaurav rana *flash_base_addr = 0; 12247151e4bSgaurav rana return 0; 12347151e4bSgaurav rana } 12447151e4bSgaurav rana #endif 12547151e4bSgaurav rana 126ac55dadbSUdit Agarwal #if defined(CONFIG_ESBC_HDR_LS) 127ac55dadbSUdit Agarwal static int get_ie_info_addr(uintptr_t *ie_addr) 128ac55dadbSUdit Agarwal { 129ac55dadbSUdit Agarwal struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); 130ac55dadbSUdit Agarwal /* For LS-CH3, the address of IE Table is 131ac55dadbSUdit Agarwal * stated in Scratch13 and scratch14 of DCFG. 132ac55dadbSUdit Agarwal * Bootrom validates this table while validating uboot. 133ac55dadbSUdit Agarwal * DCFG is LE*/ 134ac55dadbSUdit Agarwal *ie_addr = in_le32(&gur->scratchrw[SCRATCH_IE_HIGH_ADR - 1]); 135ac55dadbSUdit Agarwal *ie_addr = *ie_addr << 32; 136ac55dadbSUdit Agarwal *ie_addr |= in_le32(&gur->scratchrw[SCRATCH_IE_LOW_ADR - 1]); 137ac55dadbSUdit Agarwal return 0; 138ac55dadbSUdit Agarwal } 139ac55dadbSUdit Agarwal #else /* CONFIG_ESBC_HDR_LS */ 140ac55dadbSUdit Agarwal static int get_ie_info_addr(uintptr_t *ie_addr) 14147151e4bSgaurav rana { 14247151e4bSgaurav rana struct fsl_secboot_img_hdr *hdr; 14347151e4bSgaurav rana struct fsl_secboot_sg_table *sg_tbl; 1447bcb0eb2SAneesh Bansal u32 flash_base_addr, csf_addr; 14547151e4bSgaurav rana 14647151e4bSgaurav rana if (get_csf_base_addr(&csf_addr, &flash_base_addr)) 14747151e4bSgaurav rana return -1; 14847151e4bSgaurav rana 1499711f528SAneesh Bansal hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr; 15047151e4bSgaurav rana 15147151e4bSgaurav rana /* For SoC's with Trust Architecture v1 with corenet bus 15247151e4bSgaurav rana * the sg table field in CSF header has absolute address 15347151e4bSgaurav rana * for sg table in memory. In other Trust Architecture, 15447151e4bSgaurav rana * this field specifies the offset of sg table from the 15547151e4bSgaurav rana * base address of CSF Header 15647151e4bSgaurav rana */ 15747151e4bSgaurav rana #if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET) 15847151e4bSgaurav rana sg_tbl = (struct fsl_secboot_sg_table *) 1597bcb0eb2SAneesh Bansal (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) + 16047151e4bSgaurav rana flash_base_addr); 16147151e4bSgaurav rana #else 1629711f528SAneesh Bansal sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr + 1637bcb0eb2SAneesh Bansal (u32)hdr->psgtable); 16447151e4bSgaurav rana #endif 16547151e4bSgaurav rana 16647151e4bSgaurav rana /* IE Key Table is the first entry in the SG Table */ 16747151e4bSgaurav rana #if defined(CONFIG_MPC85xx) 168ac55dadbSUdit Agarwal *ie_addr = (uintptr_t)((sg_tbl->src_addr & 169ac55dadbSUdit Agarwal ~(CONFIG_SYS_PBI_FLASH_BASE)) + 170ac55dadbSUdit Agarwal flash_base_addr); 17147151e4bSgaurav rana #else 172ac55dadbSUdit Agarwal *ie_addr = (uintptr_t)sg_tbl->src_addr; 17347151e4bSgaurav rana #endif 17447151e4bSgaurav rana 175ac55dadbSUdit Agarwal debug("IE Table address is %lx\n", *ie_addr); 17647151e4bSgaurav rana return 0; 17747151e4bSgaurav rana } 178ac55dadbSUdit Agarwal #endif /* CONFIG_ESBC_HDR_LS */ 17947151e4bSgaurav rana #endif 18047151e4bSgaurav rana 18147151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 18247151e4bSgaurav rana /* This function checks srk_table_flag in header and set/reset srk_flag.*/ 18347151e4bSgaurav rana static u32 check_srk(struct fsl_secboot_img_priv *img) 18447151e4bSgaurav rana { 185fd6dbc98SSaksham Jain #ifdef CONFIG_ESBC_HDR_LS 186ac55dadbSUdit Agarwal /* In LS, No SRK Flag as SRK is always present if IE not present*/ 187ac55dadbSUdit Agarwal #if defined(CONFIG_FSL_ISBC_KEY_EXT) 188ac55dadbSUdit Agarwal return !check_ie(img); 189ac55dadbSUdit Agarwal #endif 190fd6dbc98SSaksham Jain return 1; 191fd6dbc98SSaksham Jain #else 19247151e4bSgaurav rana if (img->hdr.len_kr.srk_table_flag & SRK_FLAG) 19347151e4bSgaurav rana return 1; 19447151e4bSgaurav rana 19547151e4bSgaurav rana return 0; 196fd6dbc98SSaksham Jain #endif 19747151e4bSgaurav rana } 19847151e4bSgaurav rana 19947151e4bSgaurav rana /* This function returns ospr's key_revoc values.*/ 20047151e4bSgaurav rana static u32 get_key_revoc(void) 20147151e4bSgaurav rana { 20247151e4bSgaurav rana struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); 20347151e4bSgaurav rana return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >> 20447151e4bSgaurav rana OSPR_KEY_REVOC_SHIFT; 20547151e4bSgaurav rana } 20647151e4bSgaurav rana 20747151e4bSgaurav rana /* This function checks if selected key is revoked or not.*/ 20847151e4bSgaurav rana static u32 is_key_revoked(u32 keynum, u32 rev_flag) 20947151e4bSgaurav rana { 21047151e4bSgaurav rana if (keynum == UNREVOCABLE_KEY) 21147151e4bSgaurav rana return 0; 21247151e4bSgaurav rana 21347151e4bSgaurav rana if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag) 21447151e4bSgaurav rana return 1; 21547151e4bSgaurav rana 21647151e4bSgaurav rana return 0; 21747151e4bSgaurav rana } 21847151e4bSgaurav rana 21994ba5e41SAneesh Bansal /* It read validates srk_table key lengths.*/ 22094ba5e41SAneesh Bansal static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img) 22147151e4bSgaurav rana { 22247151e4bSgaurav rana int i = 0; 22394ba5e41SAneesh Bansal u32 ret, key_num, key_revoc_flag, size; 22494ba5e41SAneesh Bansal struct fsl_secboot_img_hdr *hdr = &img->hdr; 22594ba5e41SAneesh Bansal void *esbc = (u8 *)(uintptr_t)img->ehdrloc; 22694ba5e41SAneesh Bansal 22794ba5e41SAneesh Bansal if ((hdr->len_kr.num_srk == 0) || 22894ba5e41SAneesh Bansal (hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) 22994ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY; 23094ba5e41SAneesh Bansal 23194ba5e41SAneesh Bansal key_num = hdr->len_kr.srk_sel; 23294ba5e41SAneesh Bansal if (key_num == 0 || key_num > hdr->len_kr.num_srk) 23394ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM; 23494ba5e41SAneesh Bansal 23594ba5e41SAneesh Bansal /* Get revoc key from sfp */ 23694ba5e41SAneesh Bansal key_revoc_flag = get_key_revoc(); 23794ba5e41SAneesh Bansal ret = is_key_revoked(key_num, key_revoc_flag); 23894ba5e41SAneesh Bansal if (ret) 23994ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED; 24094ba5e41SAneesh Bansal 24194ba5e41SAneesh Bansal size = hdr->len_kr.num_srk * sizeof(struct srk_table); 24294ba5e41SAneesh Bansal 24394ba5e41SAneesh Bansal memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size); 24494ba5e41SAneesh Bansal 24594ba5e41SAneesh Bansal for (i = 0; i < hdr->len_kr.num_srk; i++) { 24694ba5e41SAneesh Bansal if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len)) 24747151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN; 24847151e4bSgaurav rana } 24994ba5e41SAneesh Bansal 25094ba5e41SAneesh Bansal img->key_len = img->srk_tbl[key_num - 1].key_len; 25194ba5e41SAneesh Bansal 25294ba5e41SAneesh Bansal memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey), 25394ba5e41SAneesh Bansal img->key_len); 25494ba5e41SAneesh Bansal 25547151e4bSgaurav rana return 0; 25647151e4bSgaurav rana } 25747151e4bSgaurav rana #endif 25847151e4bSgaurav rana 259fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS 26094ba5e41SAneesh Bansal static u32 read_validate_single_key(struct fsl_secboot_img_priv *img) 26194ba5e41SAneesh Bansal { 26294ba5e41SAneesh Bansal struct fsl_secboot_img_hdr *hdr = &img->hdr; 26394ba5e41SAneesh Bansal void *esbc = (u8 *)(uintptr_t)img->ehdrloc; 26494ba5e41SAneesh Bansal 26594ba5e41SAneesh Bansal /* check key length */ 26694ba5e41SAneesh Bansal if (!CHECK_KEY_LEN(hdr->key_len)) 26794ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_KEY_LEN; 26894ba5e41SAneesh Bansal 26994ba5e41SAneesh Bansal memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len); 27094ba5e41SAneesh Bansal 27194ba5e41SAneesh Bansal img->key_len = hdr->key_len; 27294ba5e41SAneesh Bansal 27394ba5e41SAneesh Bansal return 0; 27494ba5e41SAneesh Bansal } 275fd6dbc98SSaksham Jain #endif /* CONFIG_ESBC_HDR_LS */ 27694ba5e41SAneesh Bansal 27794ba5e41SAneesh Bansal #if defined(CONFIG_FSL_ISBC_KEY_EXT) 278ac55dadbSUdit Agarwal 279ac55dadbSUdit Agarwal static void install_ie_tbl(uintptr_t ie_tbl_addr, 280ac55dadbSUdit Agarwal struct fsl_secboot_img_priv *img) 281ac55dadbSUdit Agarwal { 282ac55dadbSUdit Agarwal /* Copy IE tbl to Global Data */ 283ac55dadbSUdit Agarwal memcpy(&glb.ie_tbl, (u8 *)ie_tbl_addr, sizeof(struct ie_key_info)); 284ac55dadbSUdit Agarwal img->ie_addr = (uintptr_t)&glb.ie_tbl; 285ac55dadbSUdit Agarwal glb.ie_addr = img->ie_addr; 286ac55dadbSUdit Agarwal } 287ac55dadbSUdit Agarwal 28894ba5e41SAneesh Bansal static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img) 28994ba5e41SAneesh Bansal { 29094ba5e41SAneesh Bansal struct fsl_secboot_img_hdr *hdr = &img->hdr; 29194ba5e41SAneesh Bansal u32 ie_key_len, ie_revoc_flag, ie_num; 29294ba5e41SAneesh Bansal struct ie_key_info *ie_info; 29394ba5e41SAneesh Bansal 294ac55dadbSUdit Agarwal if (!img->ie_addr) { 29594ba5e41SAneesh Bansal if (get_ie_info_addr(&img->ie_addr)) 29694ba5e41SAneesh Bansal return ERROR_IE_TABLE_NOT_FOUND; 297ac55dadbSUdit Agarwal else 298ac55dadbSUdit Agarwal install_ie_tbl(img->ie_addr, img); 299ac55dadbSUdit Agarwal } 300ac55dadbSUdit Agarwal 30194ba5e41SAneesh Bansal ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr; 30294ba5e41SAneesh Bansal if (ie_info->num_keys == 0 || ie_info->num_keys > 32) 30394ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY; 30494ba5e41SAneesh Bansal 30594ba5e41SAneesh Bansal ie_num = hdr->ie_key_sel; 30694ba5e41SAneesh Bansal if (ie_num == 0 || ie_num > ie_info->num_keys) 30794ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM; 30894ba5e41SAneesh Bansal 30994ba5e41SAneesh Bansal ie_revoc_flag = ie_info->key_revok; 31094ba5e41SAneesh Bansal if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag) 31194ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED; 31294ba5e41SAneesh Bansal 31394ba5e41SAneesh Bansal ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len; 31494ba5e41SAneesh Bansal 31594ba5e41SAneesh Bansal if (!CHECK_KEY_LEN(ie_key_len)) 31694ba5e41SAneesh Bansal return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN; 31794ba5e41SAneesh Bansal 31894ba5e41SAneesh Bansal memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey), 31994ba5e41SAneesh Bansal ie_key_len); 32094ba5e41SAneesh Bansal 32194ba5e41SAneesh Bansal img->key_len = ie_key_len; 32294ba5e41SAneesh Bansal return 0; 32394ba5e41SAneesh Bansal } 32494ba5e41SAneesh Bansal #endif 32594ba5e41SAneesh Bansal 32694ba5e41SAneesh Bansal 32747151e4bSgaurav rana /* This function return length of public key.*/ 32847151e4bSgaurav rana static inline u32 get_key_len(struct fsl_secboot_img_priv *img) 32947151e4bSgaurav rana { 33047151e4bSgaurav rana return img->key_len; 33147151e4bSgaurav rana } 33247151e4bSgaurav rana 33347151e4bSgaurav rana /* 33447151e4bSgaurav rana * Handles the ESBC uboot client header verification failure. 33547151e4bSgaurav rana * This function handles all the errors which might occur in the 33647151e4bSgaurav rana * parsing and checking of ESBC uboot client header. It will also 33747151e4bSgaurav rana * set the error bits in the SEC_MON. 33847151e4bSgaurav rana */ 33947151e4bSgaurav rana static void fsl_secboot_header_verification_failure(void) 34047151e4bSgaurav rana { 34147151e4bSgaurav rana struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); 34247151e4bSgaurav rana 34347151e4bSgaurav rana /* 29th bit of OSPR is ITS */ 34447151e4bSgaurav rana u32 its = sfp_in32(&sfp_regs->ospr) >> 2; 34547151e4bSgaurav rana 34647151e4bSgaurav rana if (its == 1) 347b259732dSSumit Garg set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL); 34847151e4bSgaurav rana else 349b259732dSSumit Garg set_sec_mon_state(HPSR_SSM_ST_NON_SECURE); 35047151e4bSgaurav rana 35147151e4bSgaurav rana printf("Generating reset request\n"); 35247151e4bSgaurav rana do_reset(NULL, 0, 0, NULL); 353c4666cf6SSaksham Jain /* If reset doesn't coocur, halt execution */ 354c4666cf6SSaksham Jain do_esbc_halt(NULL, 0, 0, NULL); 35547151e4bSgaurav rana } 35647151e4bSgaurav rana 35747151e4bSgaurav rana /* 35847151e4bSgaurav rana * Handles the ESBC uboot client image verification failure. 35947151e4bSgaurav rana * This function handles all the errors which might occur in the 36047151e4bSgaurav rana * public key hash comparison and signature verification of 36147151e4bSgaurav rana * ESBC uboot client image. It will also 36247151e4bSgaurav rana * set the error bits in the SEC_MON. 36347151e4bSgaurav rana */ 36447151e4bSgaurav rana static void fsl_secboot_image_verification_failure(void) 36547151e4bSgaurav rana { 36647151e4bSgaurav rana struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); 36747151e4bSgaurav rana 3686ec9aef2SAneesh Bansal u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT; 36947151e4bSgaurav rana 37047151e4bSgaurav rana if (its == 1) { 371b259732dSSumit Garg set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL); 37247151e4bSgaurav rana 37347151e4bSgaurav rana printf("Generating reset request\n"); 37447151e4bSgaurav rana do_reset(NULL, 0, 0, NULL); 375c4666cf6SSaksham Jain /* If reset doesn't coocur, halt execution */ 376c4666cf6SSaksham Jain do_esbc_halt(NULL, 0, 0, NULL); 377c4666cf6SSaksham Jain 37847151e4bSgaurav rana } else { 379b259732dSSumit Garg set_sec_mon_state(HPSR_SSM_ST_NON_SECURE); 38047151e4bSgaurav rana } 38147151e4bSgaurav rana } 38247151e4bSgaurav rana 38347151e4bSgaurav rana static void fsl_secboot_bootscript_parse_failure(void) 38447151e4bSgaurav rana { 38547151e4bSgaurav rana fsl_secboot_header_verification_failure(); 38647151e4bSgaurav rana } 38747151e4bSgaurav rana 38847151e4bSgaurav rana /* 38947151e4bSgaurav rana * Handles the errors in esbc boot. 39047151e4bSgaurav rana * This function handles all the errors which might occur in the 39147151e4bSgaurav rana * esbc boot phase. It will call the appropriate api to log the 39247151e4bSgaurav rana * errors and set the error bits in the SEC_MON. 39347151e4bSgaurav rana */ 39447151e4bSgaurav rana void fsl_secboot_handle_error(int error) 39547151e4bSgaurav rana { 39670f9661cSRuchika Gupta #ifndef CONFIG_SPL_BUILD 39747151e4bSgaurav rana const struct fsl_secboot_errcode *e; 39847151e4bSgaurav rana 39947151e4bSgaurav rana for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX; 40047151e4bSgaurav rana e++) { 40147151e4bSgaurav rana if (e->errcode == error) 40247151e4bSgaurav rana printf("ERROR :: %x :: %s\n", error, e->name); 40347151e4bSgaurav rana } 40470f9661cSRuchika Gupta #else 40570f9661cSRuchika Gupta printf("ERROR :: %x\n", error); 40670f9661cSRuchika Gupta #endif 40747151e4bSgaurav rana 408856b2846SAneesh Bansal /* If Boot Mode is secure, transition the SNVS state and issue 409856b2846SAneesh Bansal * reset based on type of failure and ITS setting. 410856b2846SAneesh Bansal * If Boot mode is non-secure, return from this function. 411856b2846SAneesh Bansal */ 412856b2846SAneesh Bansal if (fsl_check_boot_mode_secure() == 0) 413856b2846SAneesh Bansal return; 414856b2846SAneesh Bansal 41547151e4bSgaurav rana switch (error) { 41647151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_BARKER: 41747151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE: 41847151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_LEN: 41947151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SIG_LEN: 42047151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN: 42147151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1: 42247151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2: 42347151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD: 42447151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP: 42547151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD: 426fd6dbc98SSaksham Jain case ERROR_KEY_TABLE_NOT_FOUND: 42747151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 42847151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED: 42947151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY: 43047151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM: 43147151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN: 43247151e4bSgaurav rana #endif 43347151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 43447151e4bSgaurav rana /*@fallthrough@*/ 43547151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED: 43647151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY: 43747151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM: 43847151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN: 43947151e4bSgaurav rana case ERROR_IE_TABLE_NOT_FOUND: 44047151e4bSgaurav rana #endif 44147151e4bSgaurav rana fsl_secboot_header_verification_failure(); 44247151e4bSgaurav rana break; 44347151e4bSgaurav rana case ERROR_ESBC_SEC_RESET: 44447151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ: 44547151e4bSgaurav rana case ERROR_ESBC_SEC_ENQ: 44647151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ_TO: 44747151e4bSgaurav rana case ERROR_ESBC_SEC_JOBQ_STATUS: 44847151e4bSgaurav rana case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY: 44947151e4bSgaurav rana case ERROR_ESBC_CLIENT_HASH_COMPARE_EM: 45047151e4bSgaurav rana fsl_secboot_image_verification_failure(); 45147151e4bSgaurav rana break; 45247151e4bSgaurav rana case ERROR_ESBC_MISSING_BOOTM: 45347151e4bSgaurav rana fsl_secboot_bootscript_parse_failure(); 45447151e4bSgaurav rana break; 45547151e4bSgaurav rana case ERROR_ESBC_WRONG_CMD: 45647151e4bSgaurav rana default: 45747151e4bSgaurav rana branch_to_self(); 45847151e4bSgaurav rana break; 45947151e4bSgaurav rana } 46047151e4bSgaurav rana } 46147151e4bSgaurav rana 46247151e4bSgaurav rana static void fsl_secblk_handle_error(int error) 46347151e4bSgaurav rana { 46447151e4bSgaurav rana switch (error) { 46547151e4bSgaurav rana case ERROR_ESBC_SEC_ENQ: 46647151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ); 46747151e4bSgaurav rana break; 46847151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ: 46947151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ); 47047151e4bSgaurav rana break; 47147151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ_TO: 47247151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO); 47347151e4bSgaurav rana break; 47447151e4bSgaurav rana default: 47547151e4bSgaurav rana printf("Job Queue Output status %x\n", error); 47647151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS); 47747151e4bSgaurav rana break; 47847151e4bSgaurav rana } 47947151e4bSgaurav rana } 48047151e4bSgaurav rana 48147151e4bSgaurav rana /* 48247151e4bSgaurav rana * Calculate hash of key obtained via offset present in ESBC uboot 48347151e4bSgaurav rana * client hdr. This function calculates the hash of key which is obtained 48447151e4bSgaurav rana * through offset present in ESBC uboot client header. 48547151e4bSgaurav rana */ 48647151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img) 48747151e4bSgaurav rana { 48847151e4bSgaurav rana struct hash_algo *algo; 48947151e4bSgaurav rana void *ctx; 49047151e4bSgaurav rana int i, srk = 0; 49147151e4bSgaurav rana int ret = 0; 49247151e4bSgaurav rana const char *algo_name = "sha256"; 49347151e4bSgaurav rana 49447151e4bSgaurav rana /* Calculate hash of the esbc key */ 49547151e4bSgaurav rana ret = hash_progressive_lookup_algo(algo_name, &algo); 49647151e4bSgaurav rana if (ret) 49747151e4bSgaurav rana return ret; 49847151e4bSgaurav rana 49947151e4bSgaurav rana ret = algo->hash_init(algo, &ctx); 50047151e4bSgaurav rana if (ret) 50147151e4bSgaurav rana return ret; 50247151e4bSgaurav rana 50347151e4bSgaurav rana /* Update hash for ESBC key */ 50447151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 50547151e4bSgaurav rana if (check_srk(img)) { 50647151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 5079711f528SAneesh Bansal (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), 50847151e4bSgaurav rana img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1); 50947151e4bSgaurav rana srk = 1; 51047151e4bSgaurav rana } 51147151e4bSgaurav rana #endif 51247151e4bSgaurav rana if (!srk) 51347151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 51447151e4bSgaurav rana img->img_key, img->key_len, 1); 51547151e4bSgaurav rana if (ret) 51647151e4bSgaurav rana return ret; 51747151e4bSgaurav rana 51847151e4bSgaurav rana /* Copy hash at destination buffer */ 51947151e4bSgaurav rana ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); 52047151e4bSgaurav rana if (ret) 52147151e4bSgaurav rana return ret; 52247151e4bSgaurav rana 52347151e4bSgaurav rana for (i = 0; i < SHA256_BYTES; i++) 52447151e4bSgaurav rana img->img_key_hash[i] = hash_val[i]; 52547151e4bSgaurav rana 52647151e4bSgaurav rana return 0; 52747151e4bSgaurav rana } 52847151e4bSgaurav rana 52947151e4bSgaurav rana /* 53047151e4bSgaurav rana * Calculate hash of ESBC hdr and ESBC. This function calculates the 53147151e4bSgaurav rana * single hash of ESBC header and ESBC image. If SG flag is on, all 53247151e4bSgaurav rana * SG entries are also hashed alongwith the complete SG table. 53347151e4bSgaurav rana */ 53447151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) 53547151e4bSgaurav rana { 53647151e4bSgaurav rana struct hash_algo *algo; 53747151e4bSgaurav rana void *ctx; 53847151e4bSgaurav rana int ret = 0; 53947151e4bSgaurav rana int key_hash = 0; 54047151e4bSgaurav rana const char *algo_name = "sha256"; 54147151e4bSgaurav rana 54247151e4bSgaurav rana /* Calculate the hash of the ESBC */ 54347151e4bSgaurav rana ret = hash_progressive_lookup_algo(algo_name, &algo); 54447151e4bSgaurav rana if (ret) 54547151e4bSgaurav rana return ret; 54647151e4bSgaurav rana 54747151e4bSgaurav rana ret = algo->hash_init(algo, &ctx); 54847151e4bSgaurav rana /* Copy hash at destination buffer */ 54947151e4bSgaurav rana if (ret) 55047151e4bSgaurav rana return ret; 55147151e4bSgaurav rana 55247151e4bSgaurav rana /* Update hash for CSF Header */ 55347151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 55447151e4bSgaurav rana (u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0); 55547151e4bSgaurav rana if (ret) 55647151e4bSgaurav rana return ret; 55747151e4bSgaurav rana 55847151e4bSgaurav rana /* Update the hash with that of srk table if srk flag is 1 55947151e4bSgaurav rana * If IE Table is selected, key is not added in the hash 56047151e4bSgaurav rana * If neither srk table nor IE key table available, add key 56147151e4bSgaurav rana * from header in the hash calculation 56247151e4bSgaurav rana */ 56347151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 56447151e4bSgaurav rana if (check_srk(img)) { 56547151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 5669711f528SAneesh Bansal (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), 56747151e4bSgaurav rana img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0); 56847151e4bSgaurav rana key_hash = 1; 56947151e4bSgaurav rana } 57047151e4bSgaurav rana #endif 57147151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 57247151e4bSgaurav rana if (!key_hash && check_ie(img)) 57347151e4bSgaurav rana key_hash = 1; 57447151e4bSgaurav rana #endif 575fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS 576fd6dbc98SSaksham Jain /* No single key support in LS ESBC header */ 577fd6dbc98SSaksham Jain if (!key_hash) { 57847151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 57947151e4bSgaurav rana img->img_key, img->hdr.key_len, 0); 580fd6dbc98SSaksham Jain key_hash = 1; 581fd6dbc98SSaksham Jain } 582fd6dbc98SSaksham Jain #endif 58347151e4bSgaurav rana if (ret) 58447151e4bSgaurav rana return ret; 585fd6dbc98SSaksham Jain if (!key_hash) 586fd6dbc98SSaksham Jain return ERROR_KEY_TABLE_NOT_FOUND; 58747151e4bSgaurav rana 58847151e4bSgaurav rana /* Update hash for actual Image */ 58947151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 59085bb3896SSaksham Jain (u8 *)(*(img->img_addr_ptr)), img->img_size, 1); 59147151e4bSgaurav rana if (ret) 59247151e4bSgaurav rana return ret; 59347151e4bSgaurav rana 59447151e4bSgaurav rana /* Copy hash at destination buffer */ 59547151e4bSgaurav rana ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); 59647151e4bSgaurav rana if (ret) 59747151e4bSgaurav rana return ret; 59847151e4bSgaurav rana 59947151e4bSgaurav rana return 0; 60047151e4bSgaurav rana } 60147151e4bSgaurav rana 60247151e4bSgaurav rana /* 60347151e4bSgaurav rana * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the 60447151e4bSgaurav rana * pointers for padding, DER value and hash. And finally, constructs EM' 60547151e4bSgaurav rana * which includes hash of complete CSF header and ESBC image. If SG flag 60647151e4bSgaurav rana * is on, hash of SG table and entries is also included. 60747151e4bSgaurav rana */ 60847151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img) 60947151e4bSgaurav rana { 61047151e4bSgaurav rana /* 61147151e4bSgaurav rana * RSA PKCSv1.5 encoding format for encoded message is below 61247151e4bSgaurav rana * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash 61347151e4bSgaurav rana * PS is Padding String 61447151e4bSgaurav rana * DER is DER value for SHA-256 61547151e4bSgaurav rana * Hash is SHA-256 hash 61647151e4bSgaurav rana * ********************************************************* 61747151e4bSgaurav rana * representative points to first byte of EM initially and is 61847151e4bSgaurav rana * filled with 0x0 61947151e4bSgaurav rana * representative is incremented by 1 and second byte is filled 62047151e4bSgaurav rana * with 0x1 62147151e4bSgaurav rana * padding points to third byte of EM 62247151e4bSgaurav rana * digest points to full length of EM - 32 bytes 62347151e4bSgaurav rana * hash_id (DER value) points to 19 bytes before pDigest 62447151e4bSgaurav rana * separator is one byte which separates padding and DER 62547151e4bSgaurav rana */ 62647151e4bSgaurav rana 62747151e4bSgaurav rana size_t len; 62847151e4bSgaurav rana u8 *representative; 62947151e4bSgaurav rana u8 *padding, *digest; 63047151e4bSgaurav rana u8 *hash_id, *separator; 63147151e4bSgaurav rana int i; 63247151e4bSgaurav rana 63347151e4bSgaurav rana len = (get_key_len(img) / 2) - 1; 63447151e4bSgaurav rana representative = img->img_encoded_hash_second; 63547151e4bSgaurav rana representative[0] = 0; 63647151e4bSgaurav rana representative[1] = 1; /* block type 1 */ 63747151e4bSgaurav rana 63847151e4bSgaurav rana padding = &representative[2]; 63947151e4bSgaurav rana digest = &representative[1] + len - 32; 64047151e4bSgaurav rana hash_id = digest - sizeof(hash_identifier); 64147151e4bSgaurav rana separator = hash_id - 1; 64247151e4bSgaurav rana 64347151e4bSgaurav rana /* fill padding area pointed by padding with 0xff */ 64447151e4bSgaurav rana memset(padding, 0xff, separator - padding); 64547151e4bSgaurav rana 64647151e4bSgaurav rana /* fill byte pointed by separator */ 64747151e4bSgaurav rana *separator = 0; 64847151e4bSgaurav rana 64947151e4bSgaurav rana /* fill SHA-256 DER value pointed by HashId */ 65047151e4bSgaurav rana memcpy(hash_id, hash_identifier, sizeof(hash_identifier)); 65147151e4bSgaurav rana 65247151e4bSgaurav rana /* fill hash pointed by Digest */ 65347151e4bSgaurav rana for (i = 0; i < SHA256_BYTES; i++) 65447151e4bSgaurav rana digest[i] = hash_val[i]; 65547151e4bSgaurav rana } 65647151e4bSgaurav rana 65747151e4bSgaurav rana /* 65847151e4bSgaurav rana * Reads and validates the ESBC client header. 65947151e4bSgaurav rana * This function reads key and signature from the ESBC client header. 66047151e4bSgaurav rana * If Scatter/Gather flag is on, lengths and offsets of images 66147151e4bSgaurav rana * present as SG entries are also read. This function also checks 66247151e4bSgaurav rana * whether the header is valid or not. 66347151e4bSgaurav rana */ 66447151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) 66547151e4bSgaurav rana { 66647151e4bSgaurav rana struct fsl_secboot_img_hdr *hdr = &img->hdr; 6679711f528SAneesh Bansal void *esbc = (u8 *)(uintptr_t)img->ehdrloc; 66847151e4bSgaurav rana u8 *k, *s; 66994ba5e41SAneesh Bansal u32 ret = 0; 67094ba5e41SAneesh Bansal 67147151e4bSgaurav rana int key_found = 0; 67247151e4bSgaurav rana 67347151e4bSgaurav rana /* check barker code */ 67447151e4bSgaurav rana if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN)) 67547151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_BARKER; 67647151e4bSgaurav rana 677b055a0fdSAneesh Bansal /* If Image Address is not passed as argument to function, 678b055a0fdSAneesh Bansal * then Address and Size must be read from the Header. 679b055a0fdSAneesh Bansal */ 68085bb3896SSaksham Jain if (*(img->img_addr_ptr) == 0) { 6819711f528SAneesh Bansal #ifdef CONFIG_ESBC_ADDR_64BIT 68285bb3896SSaksham Jain *(img->img_addr_ptr) = hdr->pimg64; 6839711f528SAneesh Bansal #else 68485bb3896SSaksham Jain *(img->img_addr_ptr) = hdr->pimg; 6859711f528SAneesh Bansal #endif 686b055a0fdSAneesh Bansal } 687b055a0fdSAneesh Bansal 68847151e4bSgaurav rana if (!hdr->img_size) 68947151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE; 69047151e4bSgaurav rana 691b055a0fdSAneesh Bansal img->img_size = hdr->img_size; 692b055a0fdSAneesh Bansal 69347151e4bSgaurav rana /* Key checking*/ 69447151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 69547151e4bSgaurav rana if (check_srk(img)) { 69694ba5e41SAneesh Bansal ret = read_validate_srk_tbl(img); 69747151e4bSgaurav rana if (ret != 0) 69847151e4bSgaurav rana return ret; 69947151e4bSgaurav rana key_found = 1; 70047151e4bSgaurav rana } 70147151e4bSgaurav rana #endif 70247151e4bSgaurav rana 70347151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 70447151e4bSgaurav rana if (!key_found && check_ie(img)) { 70594ba5e41SAneesh Bansal ret = read_validate_ie_tbl(img); 70694ba5e41SAneesh Bansal if (ret != 0) 70794ba5e41SAneesh Bansal return ret; 70847151e4bSgaurav rana key_found = 1; 70947151e4bSgaurav rana } 71047151e4bSgaurav rana #endif 711fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS 712fd6dbc98SSaksham Jain /* Single Key Feature not available in LS ESBC Header */ 71347151e4bSgaurav rana if (key_found == 0) { 71494ba5e41SAneesh Bansal ret = read_validate_single_key(img); 71594ba5e41SAneesh Bansal if (ret != 0) 71694ba5e41SAneesh Bansal return ret; 71747151e4bSgaurav rana key_found = 1; 71847151e4bSgaurav rana } 719fd6dbc98SSaksham Jain #endif 720fd6dbc98SSaksham Jain if (!key_found) 721fd6dbc98SSaksham Jain return ERROR_KEY_TABLE_NOT_FOUND; 72247151e4bSgaurav rana 72347151e4bSgaurav rana /* check signaure */ 72447151e4bSgaurav rana if (get_key_len(img) == 2 * hdr->sign_len) { 72547151e4bSgaurav rana /* check signature length */ 72647151e4bSgaurav rana if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) || 72747151e4bSgaurav rana (hdr->sign_len == KEY_SIZE_BYTES / 2) || 72847151e4bSgaurav rana (hdr->sign_len == KEY_SIZE_BYTES))) 72947151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_SIG_LEN; 73047151e4bSgaurav rana } else { 73147151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN; 73247151e4bSgaurav rana } 73347151e4bSgaurav rana 73447151e4bSgaurav rana memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len); 735fd6dbc98SSaksham Jain /* No SG support in LS-CH3 */ 736fd6dbc98SSaksham Jain #ifndef CONFIG_ESBC_HDR_LS 73747151e4bSgaurav rana /* No SG support */ 73847151e4bSgaurav rana if (hdr->sg_flag) 73947151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_SG; 740fd6dbc98SSaksham Jain #endif 74147151e4bSgaurav rana 74247151e4bSgaurav rana /* modulus most significant bit should be set */ 74347151e4bSgaurav rana k = (u8 *)&img->img_key; 74447151e4bSgaurav rana 74547151e4bSgaurav rana if ((k[0] & 0x80) == 0) 74647151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1; 74747151e4bSgaurav rana 74847151e4bSgaurav rana /* modulus value should be odd */ 74947151e4bSgaurav rana if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0) 75047151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2; 75147151e4bSgaurav rana 75247151e4bSgaurav rana /* Check signature value < modulus value */ 75347151e4bSgaurav rana s = (u8 *)&img->img_sign; 75447151e4bSgaurav rana 75547151e4bSgaurav rana if (!(memcmp(s, k, hdr->sign_len) < 0)) 75647151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD; 75747151e4bSgaurav rana 75847151e4bSgaurav rana return ESBC_VALID_HDR; 75947151e4bSgaurav rana } 76047151e4bSgaurav rana 76147151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num) 76247151e4bSgaurav rana { 76347151e4bSgaurav rana char *endptr; 76447151e4bSgaurav rana ulong tmp; 76547151e4bSgaurav rana 76647151e4bSgaurav rana if (!p) { 76747151e4bSgaurav rana return 0; 76847151e4bSgaurav rana } else { 76947151e4bSgaurav rana tmp = simple_strtoul(p, &endptr, 16); 77047151e4bSgaurav rana if (sizeof(ulong) == 4) 77147151e4bSgaurav rana *num = cpu_to_be32(tmp); 77247151e4bSgaurav rana else 77347151e4bSgaurav rana *num = cpu_to_be64(tmp); 77447151e4bSgaurav rana } 77547151e4bSgaurav rana 77647151e4bSgaurav rana return *p != '\0' && *endptr == '\0'; 77747151e4bSgaurav rana } 7786629261dSAneesh Bansal /* Function to calculate the ESBC Image Hash 7796629261dSAneesh Bansal * and hash from Digital signature. 7806629261dSAneesh Bansal * The Two hash's are compared to yield the 7816629261dSAneesh Bansal * result of signature validation. 7826629261dSAneesh Bansal */ 7836629261dSAneesh Bansal static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img) 7846629261dSAneesh Bansal { 7856629261dSAneesh Bansal int ret; 7866629261dSAneesh Bansal uint32_t key_len; 7876629261dSAneesh Bansal struct key_prop prop; 7886629261dSAneesh Bansal #if !defined(USE_HOSTCC) 7896629261dSAneesh Bansal struct udevice *mod_exp_dev; 7906629261dSAneesh Bansal #endif 7916629261dSAneesh Bansal ret = calc_esbchdr_esbc_hash(img); 7926629261dSAneesh Bansal if (ret) 7936629261dSAneesh Bansal return ret; 7946629261dSAneesh Bansal 7956629261dSAneesh Bansal /* Construct encoded hash EM' wrt PKCSv1.5 */ 7966629261dSAneesh Bansal construct_img_encoded_hash_second(img); 7976629261dSAneesh Bansal 7986629261dSAneesh Bansal /* Fill prop structure for public key */ 7996629261dSAneesh Bansal memset(&prop, 0, sizeof(struct key_prop)); 8006629261dSAneesh Bansal key_len = get_key_len(img) / 2; 8016629261dSAneesh Bansal prop.modulus = img->img_key; 8026629261dSAneesh Bansal prop.public_exponent = img->img_key + key_len; 8036629261dSAneesh Bansal prop.num_bits = key_len * 8; 8046629261dSAneesh Bansal prop.exp_len = key_len; 8056629261dSAneesh Bansal 8066629261dSAneesh Bansal ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); 8076629261dSAneesh Bansal if (ret) { 8086629261dSAneesh Bansal printf("RSA: Can't find Modular Exp implementation\n"); 8096629261dSAneesh Bansal return -EINVAL; 8106629261dSAneesh Bansal } 8116629261dSAneesh Bansal 8126629261dSAneesh Bansal ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len, 8136629261dSAneesh Bansal &prop, img->img_encoded_hash); 8146629261dSAneesh Bansal if (ret) 8156629261dSAneesh Bansal return ret; 8166629261dSAneesh Bansal 8176629261dSAneesh Bansal /* 8186629261dSAneesh Bansal * compare the encoded messages EM' and EM wrt RSA PKCSv1.5 8196629261dSAneesh Bansal * memcmp returns zero on success 8206629261dSAneesh Bansal * memcmp returns non-zero on failure 8216629261dSAneesh Bansal */ 8226629261dSAneesh Bansal ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash, 8236629261dSAneesh Bansal img->hdr.sign_len); 8246629261dSAneesh Bansal 8256629261dSAneesh Bansal if (ret) 8266629261dSAneesh Bansal return ERROR_ESBC_CLIENT_HASH_COMPARE_EM; 8276629261dSAneesh Bansal 8286629261dSAneesh Bansal return 0; 8296629261dSAneesh Bansal } 830ac55dadbSUdit Agarwal /* Function to initialize img priv and global data structure 831ac55dadbSUdit Agarwal */ 832ac55dadbSUdit Agarwal static int secboot_init(struct fsl_secboot_img_priv **img_ptr) 833ac55dadbSUdit Agarwal { 834ac55dadbSUdit Agarwal *img_ptr = malloc(sizeof(struct fsl_secboot_img_priv)); 835ac55dadbSUdit Agarwal 836ac55dadbSUdit Agarwal struct fsl_secboot_img_priv *img = *img_ptr; 837ac55dadbSUdit Agarwal 838ac55dadbSUdit Agarwal if (!img) 839ac55dadbSUdit Agarwal return -ENOMEM; 840ac55dadbSUdit Agarwal memset(img, 0, sizeof(struct fsl_secboot_img_priv)); 841ac55dadbSUdit Agarwal 842ac55dadbSUdit Agarwal #if defined(CONFIG_FSL_ISBC_KEY_EXT) 843ac55dadbSUdit Agarwal if (glb.ie_addr) 844ac55dadbSUdit Agarwal img->ie_addr = glb.ie_addr; 845ac55dadbSUdit Agarwal #endif 846ac55dadbSUdit Agarwal return 0; 847ac55dadbSUdit Agarwal } 848ac55dadbSUdit Agarwal 849ac55dadbSUdit Agarwal 85085bb3896SSaksham Jain /* haddr - Address of the header of image to be validated. 85185bb3896SSaksham Jain * arg_hash_str - Option hash string. If provided, this 8521cc0a9f4SRobert P. J. Day * overrides the key hash in the SFP fuses. 85385bb3896SSaksham Jain * img_addr_ptr - Optional pointer to address of image to be validated. 8541cc0a9f4SRobert P. J. Day * If non zero addr, this overrides the addr of image in header, 85585bb3896SSaksham Jain * otherwise updated to image addr in header. 85685bb3896SSaksham Jain * Acts as both input and output of function. 85785bb3896SSaksham Jain * This pointer shouldn't be NULL. 85885bb3896SSaksham Jain */ 859b055a0fdSAneesh Bansal int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str, 86085bb3896SSaksham Jain uintptr_t *img_addr_ptr) 86147151e4bSgaurav rana { 86247151e4bSgaurav rana struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); 86347151e4bSgaurav rana ulong hash[SHA256_BYTES/sizeof(ulong)]; 86447151e4bSgaurav rana char hash_str[NUM_HEX_CHARS + 1]; 86547151e4bSgaurav rana struct fsl_secboot_img_priv *img; 86647151e4bSgaurav rana struct fsl_secboot_img_hdr *hdr; 86747151e4bSgaurav rana void *esbc; 86847151e4bSgaurav rana int ret, i, hash_cmd = 0; 86947151e4bSgaurav rana u32 srk_hash[8]; 87047151e4bSgaurav rana 871bc71f926SAneesh Bansal if (arg_hash_str != NULL) { 872bc71f926SAneesh Bansal const char *cp = arg_hash_str; 87347151e4bSgaurav rana int i = 0; 87447151e4bSgaurav rana 87547151e4bSgaurav rana if (*cp == '0' && *(cp + 1) == 'x') 87647151e4bSgaurav rana cp += 2; 87747151e4bSgaurav rana 87847151e4bSgaurav rana /* The input string expected is in hex, where 87947151e4bSgaurav rana * each 4 bits would be represented by a hex 88047151e4bSgaurav rana * sha256 hash is 256 bits long, which would mean 88147151e4bSgaurav rana * num of characters = 256 / 4 88247151e4bSgaurav rana */ 88347151e4bSgaurav rana if (strlen(cp) != SHA256_NIBBLES) { 88447151e4bSgaurav rana printf("%s is not a 256 bits hex string as expected\n", 885bc71f926SAneesh Bansal arg_hash_str); 88647151e4bSgaurav rana return -1; 88747151e4bSgaurav rana } 88847151e4bSgaurav rana 88947151e4bSgaurav rana for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) { 89047151e4bSgaurav rana strncpy(hash_str, cp + (i * NUM_HEX_CHARS), 89147151e4bSgaurav rana NUM_HEX_CHARS); 89247151e4bSgaurav rana hash_str[NUM_HEX_CHARS] = '\0'; 89347151e4bSgaurav rana if (!str2longbe(hash_str, &hash[i])) { 89447151e4bSgaurav rana printf("%s is not a 256 bits hex string ", 895bc71f926SAneesh Bansal arg_hash_str); 89647151e4bSgaurav rana return -1; 89747151e4bSgaurav rana } 89847151e4bSgaurav rana } 89947151e4bSgaurav rana 90047151e4bSgaurav rana hash_cmd = 1; 90147151e4bSgaurav rana } 90247151e4bSgaurav rana 903ac55dadbSUdit Agarwal ret = secboot_init(&img); 904ac55dadbSUdit Agarwal if (ret) 905ac55dadbSUdit Agarwal goto exit; 90647151e4bSgaurav rana 907b055a0fdSAneesh Bansal /* Update the information in Private Struct */ 90847151e4bSgaurav rana hdr = &img->hdr; 909bc71f926SAneesh Bansal img->ehdrloc = haddr; 91085bb3896SSaksham Jain img->img_addr_ptr = img_addr_ptr; 911b055a0fdSAneesh Bansal esbc = (u8 *)img->ehdrloc; 91247151e4bSgaurav rana 91347151e4bSgaurav rana memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); 91447151e4bSgaurav rana 91547151e4bSgaurav rana /* read and validate esbc header */ 91647151e4bSgaurav rana ret = read_validate_esbc_client_header(img); 91747151e4bSgaurav rana 91847151e4bSgaurav rana if (ret != ESBC_VALID_HDR) { 91947151e4bSgaurav rana fsl_secboot_handle_error(ret); 92047151e4bSgaurav rana goto exit; 92147151e4bSgaurav rana } 92247151e4bSgaurav rana 92347151e4bSgaurav rana /* SRKH present in SFP */ 92447151e4bSgaurav rana for (i = 0; i < NUM_SRKH_REGS; i++) 92547151e4bSgaurav rana srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]); 92647151e4bSgaurav rana 92747151e4bSgaurav rana /* 92847151e4bSgaurav rana * Calculate hash of key obtained via offset present in 92947151e4bSgaurav rana * ESBC uboot client hdr 93047151e4bSgaurav rana */ 93147151e4bSgaurav rana ret = calc_img_key_hash(img); 93247151e4bSgaurav rana if (ret) { 93347151e4bSgaurav rana fsl_secblk_handle_error(ret); 93447151e4bSgaurav rana goto exit; 93547151e4bSgaurav rana } 93647151e4bSgaurav rana 93747151e4bSgaurav rana /* Compare hash obtained above with SRK hash present in SFP */ 93847151e4bSgaurav rana if (hash_cmd) 93947151e4bSgaurav rana ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES); 94047151e4bSgaurav rana else 94147151e4bSgaurav rana ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES); 94247151e4bSgaurav rana 94347151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 94447151e4bSgaurav rana if (!hash_cmd && check_ie(img)) 94547151e4bSgaurav rana ret = 0; 94647151e4bSgaurav rana #endif 94747151e4bSgaurav rana 94847151e4bSgaurav rana if (ret != 0) { 94947151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY); 95047151e4bSgaurav rana goto exit; 95147151e4bSgaurav rana } 95247151e4bSgaurav rana 9536629261dSAneesh Bansal ret = calculate_cmp_img_sig(img); 95447151e4bSgaurav rana if (ret) { 9556629261dSAneesh Bansal fsl_secboot_handle_error(ret); 95647151e4bSgaurav rana goto exit; 95747151e4bSgaurav rana } 95847151e4bSgaurav rana 95947151e4bSgaurav rana exit: 960ac55dadbSUdit Agarwal /* Free Img as it was malloc'ed*/ 961ac55dadbSUdit Agarwal free(img); 962bc71f926SAneesh Bansal return ret; 96347151e4bSgaurav rana } 964