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 37347151e4bSgaurav rana switch (error) { 37447151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_BARKER: 37547151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE: 37647151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_LEN: 37747151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SIG_LEN: 37847151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN: 37947151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1: 38047151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2: 38147151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD: 38247151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP: 38347151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD: 38447151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 38547151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED: 38647151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY: 38747151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM: 38847151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN: 38947151e4bSgaurav rana #endif 39047151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 39147151e4bSgaurav rana /*@fallthrough@*/ 39247151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED: 39347151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY: 39447151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM: 39547151e4bSgaurav rana case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN: 39647151e4bSgaurav rana case ERROR_IE_TABLE_NOT_FOUND: 39747151e4bSgaurav rana #endif 39847151e4bSgaurav rana fsl_secboot_header_verification_failure(); 39947151e4bSgaurav rana break; 40047151e4bSgaurav rana case ERROR_ESBC_SEC_RESET: 40147151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ: 40247151e4bSgaurav rana case ERROR_ESBC_SEC_ENQ: 40347151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ_TO: 40447151e4bSgaurav rana case ERROR_ESBC_SEC_JOBQ_STATUS: 40547151e4bSgaurav rana case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY: 40647151e4bSgaurav rana case ERROR_ESBC_CLIENT_HASH_COMPARE_EM: 40747151e4bSgaurav rana fsl_secboot_image_verification_failure(); 40847151e4bSgaurav rana break; 40947151e4bSgaurav rana case ERROR_ESBC_MISSING_BOOTM: 41047151e4bSgaurav rana fsl_secboot_bootscript_parse_failure(); 41147151e4bSgaurav rana break; 41247151e4bSgaurav rana case ERROR_ESBC_WRONG_CMD: 41347151e4bSgaurav rana default: 41447151e4bSgaurav rana branch_to_self(); 41547151e4bSgaurav rana break; 41647151e4bSgaurav rana } 41747151e4bSgaurav rana } 41847151e4bSgaurav rana 41947151e4bSgaurav rana static void fsl_secblk_handle_error(int error) 42047151e4bSgaurav rana { 42147151e4bSgaurav rana switch (error) { 42247151e4bSgaurav rana case ERROR_ESBC_SEC_ENQ: 42347151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ); 42447151e4bSgaurav rana break; 42547151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ: 42647151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ); 42747151e4bSgaurav rana break; 42847151e4bSgaurav rana case ERROR_ESBC_SEC_DEQ_TO: 42947151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO); 43047151e4bSgaurav rana break; 43147151e4bSgaurav rana default: 43247151e4bSgaurav rana printf("Job Queue Output status %x\n", error); 43347151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS); 43447151e4bSgaurav rana break; 43547151e4bSgaurav rana } 43647151e4bSgaurav rana } 43747151e4bSgaurav rana 43847151e4bSgaurav rana /* 43947151e4bSgaurav rana * Calculate hash of key obtained via offset present in ESBC uboot 44047151e4bSgaurav rana * client hdr. This function calculates the hash of key which is obtained 44147151e4bSgaurav rana * through offset present in ESBC uboot client header. 44247151e4bSgaurav rana */ 44347151e4bSgaurav rana static int calc_img_key_hash(struct fsl_secboot_img_priv *img) 44447151e4bSgaurav rana { 44547151e4bSgaurav rana struct hash_algo *algo; 44647151e4bSgaurav rana void *ctx; 44747151e4bSgaurav rana int i, srk = 0; 44847151e4bSgaurav rana int ret = 0; 44947151e4bSgaurav rana const char *algo_name = "sha256"; 45047151e4bSgaurav rana 45147151e4bSgaurav rana /* Calculate hash of the esbc key */ 45247151e4bSgaurav rana ret = hash_progressive_lookup_algo(algo_name, &algo); 45347151e4bSgaurav rana if (ret) 45447151e4bSgaurav rana return ret; 45547151e4bSgaurav rana 45647151e4bSgaurav rana ret = algo->hash_init(algo, &ctx); 45747151e4bSgaurav rana if (ret) 45847151e4bSgaurav rana return ret; 45947151e4bSgaurav rana 46047151e4bSgaurav rana /* Update hash for ESBC key */ 46147151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 46247151e4bSgaurav rana if (check_srk(img)) { 46347151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 4649711f528SAneesh Bansal (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), 46547151e4bSgaurav rana img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1); 46647151e4bSgaurav rana srk = 1; 46747151e4bSgaurav rana } 46847151e4bSgaurav rana #endif 46947151e4bSgaurav rana if (!srk) 47047151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 47147151e4bSgaurav rana img->img_key, img->key_len, 1); 47247151e4bSgaurav rana if (ret) 47347151e4bSgaurav rana return ret; 47447151e4bSgaurav rana 47547151e4bSgaurav rana /* Copy hash at destination buffer */ 47647151e4bSgaurav rana ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); 47747151e4bSgaurav rana if (ret) 47847151e4bSgaurav rana return ret; 47947151e4bSgaurav rana 48047151e4bSgaurav rana for (i = 0; i < SHA256_BYTES; i++) 48147151e4bSgaurav rana img->img_key_hash[i] = hash_val[i]; 48247151e4bSgaurav rana 48347151e4bSgaurav rana return 0; 48447151e4bSgaurav rana } 48547151e4bSgaurav rana 48647151e4bSgaurav rana /* 48747151e4bSgaurav rana * Calculate hash of ESBC hdr and ESBC. This function calculates the 48847151e4bSgaurav rana * single hash of ESBC header and ESBC image. If SG flag is on, all 48947151e4bSgaurav rana * SG entries are also hashed alongwith the complete SG table. 49047151e4bSgaurav rana */ 49147151e4bSgaurav rana static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) 49247151e4bSgaurav rana { 49347151e4bSgaurav rana struct hash_algo *algo; 49447151e4bSgaurav rana void *ctx; 49547151e4bSgaurav rana int ret = 0; 49647151e4bSgaurav rana int key_hash = 0; 49747151e4bSgaurav rana const char *algo_name = "sha256"; 49847151e4bSgaurav rana 49947151e4bSgaurav rana /* Calculate the hash of the ESBC */ 50047151e4bSgaurav rana ret = hash_progressive_lookup_algo(algo_name, &algo); 50147151e4bSgaurav rana if (ret) 50247151e4bSgaurav rana return ret; 50347151e4bSgaurav rana 50447151e4bSgaurav rana ret = algo->hash_init(algo, &ctx); 50547151e4bSgaurav rana /* Copy hash at destination buffer */ 50647151e4bSgaurav rana if (ret) 50747151e4bSgaurav rana return ret; 50847151e4bSgaurav rana 50947151e4bSgaurav rana /* Update hash for CSF Header */ 51047151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 51147151e4bSgaurav rana (u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0); 51247151e4bSgaurav rana if (ret) 51347151e4bSgaurav rana return ret; 51447151e4bSgaurav rana 51547151e4bSgaurav rana /* Update the hash with that of srk table if srk flag is 1 51647151e4bSgaurav rana * If IE Table is selected, key is not added in the hash 51747151e4bSgaurav rana * If neither srk table nor IE key table available, add key 51847151e4bSgaurav rana * from header in the hash calculation 51947151e4bSgaurav rana */ 52047151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 52147151e4bSgaurav rana if (check_srk(img)) { 52247151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 5239711f528SAneesh Bansal (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off), 52447151e4bSgaurav rana img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0); 52547151e4bSgaurav rana key_hash = 1; 52647151e4bSgaurav rana } 52747151e4bSgaurav rana #endif 52847151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 52947151e4bSgaurav rana if (!key_hash && check_ie(img)) 53047151e4bSgaurav rana key_hash = 1; 53147151e4bSgaurav rana #endif 53247151e4bSgaurav rana if (!key_hash) 53347151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 53447151e4bSgaurav rana img->img_key, img->hdr.key_len, 0); 53547151e4bSgaurav rana if (ret) 53647151e4bSgaurav rana return ret; 53747151e4bSgaurav rana 53847151e4bSgaurav rana /* Update hash for actual Image */ 5399711f528SAneesh Bansal #ifdef CONFIG_ESBC_ADDR_64BIT 54047151e4bSgaurav rana ret = algo->hash_update(algo, ctx, 5419711f528SAneesh Bansal (u8 *)(uintptr_t)img->hdr.pimg64, img->hdr.img_size, 1); 5429711f528SAneesh Bansal #else 5439711f528SAneesh Bansal ret = algo->hash_update(algo, ctx, 5449711f528SAneesh Bansal (u8 *)(uintptr_t)img->hdr.pimg, img->hdr.img_size, 1); 5459711f528SAneesh Bansal #endif 54647151e4bSgaurav rana if (ret) 54747151e4bSgaurav rana return ret; 54847151e4bSgaurav rana 54947151e4bSgaurav rana /* Copy hash at destination buffer */ 55047151e4bSgaurav rana ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); 55147151e4bSgaurav rana if (ret) 55247151e4bSgaurav rana return ret; 55347151e4bSgaurav rana 55447151e4bSgaurav rana return 0; 55547151e4bSgaurav rana } 55647151e4bSgaurav rana 55747151e4bSgaurav rana /* 55847151e4bSgaurav rana * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the 55947151e4bSgaurav rana * pointers for padding, DER value and hash. And finally, constructs EM' 56047151e4bSgaurav rana * which includes hash of complete CSF header and ESBC image. If SG flag 56147151e4bSgaurav rana * is on, hash of SG table and entries is also included. 56247151e4bSgaurav rana */ 56347151e4bSgaurav rana static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img) 56447151e4bSgaurav rana { 56547151e4bSgaurav rana /* 56647151e4bSgaurav rana * RSA PKCSv1.5 encoding format for encoded message is below 56747151e4bSgaurav rana * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash 56847151e4bSgaurav rana * PS is Padding String 56947151e4bSgaurav rana * DER is DER value for SHA-256 57047151e4bSgaurav rana * Hash is SHA-256 hash 57147151e4bSgaurav rana * ********************************************************* 57247151e4bSgaurav rana * representative points to first byte of EM initially and is 57347151e4bSgaurav rana * filled with 0x0 57447151e4bSgaurav rana * representative is incremented by 1 and second byte is filled 57547151e4bSgaurav rana * with 0x1 57647151e4bSgaurav rana * padding points to third byte of EM 57747151e4bSgaurav rana * digest points to full length of EM - 32 bytes 57847151e4bSgaurav rana * hash_id (DER value) points to 19 bytes before pDigest 57947151e4bSgaurav rana * separator is one byte which separates padding and DER 58047151e4bSgaurav rana */ 58147151e4bSgaurav rana 58247151e4bSgaurav rana size_t len; 58347151e4bSgaurav rana u8 *representative; 58447151e4bSgaurav rana u8 *padding, *digest; 58547151e4bSgaurav rana u8 *hash_id, *separator; 58647151e4bSgaurav rana int i; 58747151e4bSgaurav rana 58847151e4bSgaurav rana len = (get_key_len(img) / 2) - 1; 58947151e4bSgaurav rana representative = img->img_encoded_hash_second; 59047151e4bSgaurav rana representative[0] = 0; 59147151e4bSgaurav rana representative[1] = 1; /* block type 1 */ 59247151e4bSgaurav rana 59347151e4bSgaurav rana padding = &representative[2]; 59447151e4bSgaurav rana digest = &representative[1] + len - 32; 59547151e4bSgaurav rana hash_id = digest - sizeof(hash_identifier); 59647151e4bSgaurav rana separator = hash_id - 1; 59747151e4bSgaurav rana 59847151e4bSgaurav rana /* fill padding area pointed by padding with 0xff */ 59947151e4bSgaurav rana memset(padding, 0xff, separator - padding); 60047151e4bSgaurav rana 60147151e4bSgaurav rana /* fill byte pointed by separator */ 60247151e4bSgaurav rana *separator = 0; 60347151e4bSgaurav rana 60447151e4bSgaurav rana /* fill SHA-256 DER value pointed by HashId */ 60547151e4bSgaurav rana memcpy(hash_id, hash_identifier, sizeof(hash_identifier)); 60647151e4bSgaurav rana 60747151e4bSgaurav rana /* fill hash pointed by Digest */ 60847151e4bSgaurav rana for (i = 0; i < SHA256_BYTES; i++) 60947151e4bSgaurav rana digest[i] = hash_val[i]; 61047151e4bSgaurav rana } 61147151e4bSgaurav rana 61247151e4bSgaurav rana /* 61347151e4bSgaurav rana * Reads and validates the ESBC client header. 61447151e4bSgaurav rana * This function reads key and signature from the ESBC client header. 61547151e4bSgaurav rana * If Scatter/Gather flag is on, lengths and offsets of images 61647151e4bSgaurav rana * present as SG entries are also read. This function also checks 61747151e4bSgaurav rana * whether the header is valid or not. 61847151e4bSgaurav rana */ 61947151e4bSgaurav rana static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) 62047151e4bSgaurav rana { 62147151e4bSgaurav rana char buf[20]; 62247151e4bSgaurav rana struct fsl_secboot_img_hdr *hdr = &img->hdr; 6239711f528SAneesh Bansal void *esbc = (u8 *)(uintptr_t)img->ehdrloc; 62447151e4bSgaurav rana u8 *k, *s; 62594ba5e41SAneesh Bansal u32 ret = 0; 62694ba5e41SAneesh Bansal 62747151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 62847151e4bSgaurav rana #endif 62947151e4bSgaurav rana int key_found = 0; 63047151e4bSgaurav rana 63147151e4bSgaurav rana /* check barker code */ 63247151e4bSgaurav rana if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN)) 63347151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_BARKER; 63447151e4bSgaurav rana 6359711f528SAneesh Bansal #ifdef CONFIG_ESBC_ADDR_64BIT 6369711f528SAneesh Bansal sprintf(buf, "%llx", hdr->pimg64); 6379711f528SAneesh Bansal #else 6387bcb0eb2SAneesh Bansal sprintf(buf, "%x", hdr->pimg); 6399711f528SAneesh Bansal #endif 64047151e4bSgaurav rana setenv("img_addr", buf); 64147151e4bSgaurav rana 64247151e4bSgaurav rana if (!hdr->img_size) 64347151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE; 64447151e4bSgaurav rana 64547151e4bSgaurav rana /* Key checking*/ 64647151e4bSgaurav rana #ifdef CONFIG_KEY_REVOCATION 64747151e4bSgaurav rana if (check_srk(img)) { 64894ba5e41SAneesh Bansal ret = read_validate_srk_tbl(img); 64947151e4bSgaurav rana if (ret != 0) 65047151e4bSgaurav rana return ret; 65147151e4bSgaurav rana key_found = 1; 65247151e4bSgaurav rana } 65347151e4bSgaurav rana #endif 65447151e4bSgaurav rana 65547151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 65647151e4bSgaurav rana if (!key_found && check_ie(img)) { 65794ba5e41SAneesh Bansal ret = read_validate_ie_tbl(img); 65894ba5e41SAneesh Bansal if (ret != 0) 65994ba5e41SAneesh Bansal return ret; 66047151e4bSgaurav rana key_found = 1; 66147151e4bSgaurav rana } 66247151e4bSgaurav rana #endif 66347151e4bSgaurav rana 66447151e4bSgaurav rana if (key_found == 0) { 66594ba5e41SAneesh Bansal ret = read_validate_single_key(img); 66694ba5e41SAneesh Bansal if (ret != 0) 66794ba5e41SAneesh Bansal return ret; 66847151e4bSgaurav rana key_found = 1; 66947151e4bSgaurav rana } 67047151e4bSgaurav rana 67147151e4bSgaurav rana /* check signaure */ 67247151e4bSgaurav rana if (get_key_len(img) == 2 * hdr->sign_len) { 67347151e4bSgaurav rana /* check signature length */ 67447151e4bSgaurav rana if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) || 67547151e4bSgaurav rana (hdr->sign_len == KEY_SIZE_BYTES / 2) || 67647151e4bSgaurav rana (hdr->sign_len == KEY_SIZE_BYTES))) 67747151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_SIG_LEN; 67847151e4bSgaurav rana } else { 67947151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN; 68047151e4bSgaurav rana } 68147151e4bSgaurav rana 68247151e4bSgaurav rana memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len); 68347151e4bSgaurav rana 68447151e4bSgaurav rana /* No SG support */ 68547151e4bSgaurav rana if (hdr->sg_flag) 68647151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_SG; 68747151e4bSgaurav rana 68847151e4bSgaurav rana /* modulus most significant bit should be set */ 68947151e4bSgaurav rana k = (u8 *)&img->img_key; 69047151e4bSgaurav rana 69147151e4bSgaurav rana if ((k[0] & 0x80) == 0) 69247151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1; 69347151e4bSgaurav rana 69447151e4bSgaurav rana /* modulus value should be odd */ 69547151e4bSgaurav rana if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0) 69647151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2; 69747151e4bSgaurav rana 69847151e4bSgaurav rana /* Check signature value < modulus value */ 69947151e4bSgaurav rana s = (u8 *)&img->img_sign; 70047151e4bSgaurav rana 70147151e4bSgaurav rana if (!(memcmp(s, k, hdr->sign_len) < 0)) 70247151e4bSgaurav rana return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD; 70347151e4bSgaurav rana 70447151e4bSgaurav rana return ESBC_VALID_HDR; 70547151e4bSgaurav rana } 70647151e4bSgaurav rana 70747151e4bSgaurav rana static inline int str2longbe(const char *p, ulong *num) 70847151e4bSgaurav rana { 70947151e4bSgaurav rana char *endptr; 71047151e4bSgaurav rana ulong tmp; 71147151e4bSgaurav rana 71247151e4bSgaurav rana if (!p) { 71347151e4bSgaurav rana return 0; 71447151e4bSgaurav rana } else { 71547151e4bSgaurav rana tmp = simple_strtoul(p, &endptr, 16); 71647151e4bSgaurav rana if (sizeof(ulong) == 4) 71747151e4bSgaurav rana *num = cpu_to_be32(tmp); 71847151e4bSgaurav rana else 71947151e4bSgaurav rana *num = cpu_to_be64(tmp); 72047151e4bSgaurav rana } 72147151e4bSgaurav rana 72247151e4bSgaurav rana return *p != '\0' && *endptr == '\0'; 72347151e4bSgaurav rana } 724*6629261dSAneesh Bansal /* Function to calculate the ESBC Image Hash 725*6629261dSAneesh Bansal * and hash from Digital signature. 726*6629261dSAneesh Bansal * The Two hash's are compared to yield the 727*6629261dSAneesh Bansal * result of signature validation. 728*6629261dSAneesh Bansal */ 729*6629261dSAneesh Bansal static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img) 730*6629261dSAneesh Bansal { 731*6629261dSAneesh Bansal int ret; 732*6629261dSAneesh Bansal uint32_t key_len; 733*6629261dSAneesh Bansal struct key_prop prop; 734*6629261dSAneesh Bansal #if !defined(USE_HOSTCC) 735*6629261dSAneesh Bansal struct udevice *mod_exp_dev; 736*6629261dSAneesh Bansal #endif 737*6629261dSAneesh Bansal ret = calc_esbchdr_esbc_hash(img); 738*6629261dSAneesh Bansal if (ret) 739*6629261dSAneesh Bansal return ret; 740*6629261dSAneesh Bansal 741*6629261dSAneesh Bansal /* Construct encoded hash EM' wrt PKCSv1.5 */ 742*6629261dSAneesh Bansal construct_img_encoded_hash_second(img); 743*6629261dSAneesh Bansal 744*6629261dSAneesh Bansal /* Fill prop structure for public key */ 745*6629261dSAneesh Bansal memset(&prop, 0, sizeof(struct key_prop)); 746*6629261dSAneesh Bansal key_len = get_key_len(img) / 2; 747*6629261dSAneesh Bansal prop.modulus = img->img_key; 748*6629261dSAneesh Bansal prop.public_exponent = img->img_key + key_len; 749*6629261dSAneesh Bansal prop.num_bits = key_len * 8; 750*6629261dSAneesh Bansal prop.exp_len = key_len; 751*6629261dSAneesh Bansal 752*6629261dSAneesh Bansal ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); 753*6629261dSAneesh Bansal if (ret) { 754*6629261dSAneesh Bansal printf("RSA: Can't find Modular Exp implementation\n"); 755*6629261dSAneesh Bansal return -EINVAL; 756*6629261dSAneesh Bansal } 757*6629261dSAneesh Bansal 758*6629261dSAneesh Bansal ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len, 759*6629261dSAneesh Bansal &prop, img->img_encoded_hash); 760*6629261dSAneesh Bansal if (ret) 761*6629261dSAneesh Bansal return ret; 762*6629261dSAneesh Bansal 763*6629261dSAneesh Bansal /* 764*6629261dSAneesh Bansal * compare the encoded messages EM' and EM wrt RSA PKCSv1.5 765*6629261dSAneesh Bansal * memcmp returns zero on success 766*6629261dSAneesh Bansal * memcmp returns non-zero on failure 767*6629261dSAneesh Bansal */ 768*6629261dSAneesh Bansal ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash, 769*6629261dSAneesh Bansal img->hdr.sign_len); 770*6629261dSAneesh Bansal 771*6629261dSAneesh Bansal if (ret) 772*6629261dSAneesh Bansal return ERROR_ESBC_CLIENT_HASH_COMPARE_EM; 773*6629261dSAneesh Bansal 774*6629261dSAneesh Bansal return 0; 775*6629261dSAneesh Bansal } 77647151e4bSgaurav rana 777bc71f926SAneesh Bansal int fsl_secboot_validate(ulong haddr, char *arg_hash_str) 77847151e4bSgaurav rana { 77947151e4bSgaurav rana struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); 78047151e4bSgaurav rana ulong hash[SHA256_BYTES/sizeof(ulong)]; 78147151e4bSgaurav rana char hash_str[NUM_HEX_CHARS + 1]; 78247151e4bSgaurav rana struct fsl_secboot_img_priv *img; 78347151e4bSgaurav rana struct fsl_secboot_img_hdr *hdr; 78447151e4bSgaurav rana void *esbc; 78547151e4bSgaurav rana int ret, i, hash_cmd = 0; 78647151e4bSgaurav rana u32 srk_hash[8]; 78747151e4bSgaurav rana 788bc71f926SAneesh Bansal if (arg_hash_str != NULL) { 789bc71f926SAneesh Bansal const char *cp = arg_hash_str; 79047151e4bSgaurav rana int i = 0; 79147151e4bSgaurav rana 79247151e4bSgaurav rana if (*cp == '0' && *(cp + 1) == 'x') 79347151e4bSgaurav rana cp += 2; 79447151e4bSgaurav rana 79547151e4bSgaurav rana /* The input string expected is in hex, where 79647151e4bSgaurav rana * each 4 bits would be represented by a hex 79747151e4bSgaurav rana * sha256 hash is 256 bits long, which would mean 79847151e4bSgaurav rana * num of characters = 256 / 4 79947151e4bSgaurav rana */ 80047151e4bSgaurav rana if (strlen(cp) != SHA256_NIBBLES) { 80147151e4bSgaurav rana printf("%s is not a 256 bits hex string as expected\n", 802bc71f926SAneesh Bansal arg_hash_str); 80347151e4bSgaurav rana return -1; 80447151e4bSgaurav rana } 80547151e4bSgaurav rana 80647151e4bSgaurav rana for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) { 80747151e4bSgaurav rana strncpy(hash_str, cp + (i * NUM_HEX_CHARS), 80847151e4bSgaurav rana NUM_HEX_CHARS); 80947151e4bSgaurav rana hash_str[NUM_HEX_CHARS] = '\0'; 81047151e4bSgaurav rana if (!str2longbe(hash_str, &hash[i])) { 81147151e4bSgaurav rana printf("%s is not a 256 bits hex string ", 812bc71f926SAneesh Bansal arg_hash_str); 81347151e4bSgaurav rana return -1; 81447151e4bSgaurav rana } 81547151e4bSgaurav rana } 81647151e4bSgaurav rana 81747151e4bSgaurav rana hash_cmd = 1; 81847151e4bSgaurav rana } 81947151e4bSgaurav rana 82047151e4bSgaurav rana img = malloc(sizeof(struct fsl_secboot_img_priv)); 82147151e4bSgaurav rana 82247151e4bSgaurav rana if (!img) 82347151e4bSgaurav rana return -1; 82447151e4bSgaurav rana 82547151e4bSgaurav rana memset(img, 0, sizeof(struct fsl_secboot_img_priv)); 82647151e4bSgaurav rana 82747151e4bSgaurav rana hdr = &img->hdr; 828bc71f926SAneesh Bansal img->ehdrloc = haddr; 8299711f528SAneesh Bansal esbc = (u8 *)(uintptr_t)img->ehdrloc; 83047151e4bSgaurav rana 83147151e4bSgaurav rana memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); 83247151e4bSgaurav rana 83347151e4bSgaurav rana /* read and validate esbc header */ 83447151e4bSgaurav rana ret = read_validate_esbc_client_header(img); 83547151e4bSgaurav rana 83647151e4bSgaurav rana if (ret != ESBC_VALID_HDR) { 83747151e4bSgaurav rana fsl_secboot_handle_error(ret); 83847151e4bSgaurav rana goto exit; 83947151e4bSgaurav rana } 84047151e4bSgaurav rana 84147151e4bSgaurav rana /* SRKH present in SFP */ 84247151e4bSgaurav rana for (i = 0; i < NUM_SRKH_REGS; i++) 84347151e4bSgaurav rana srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]); 84447151e4bSgaurav rana 84547151e4bSgaurav rana /* 84647151e4bSgaurav rana * Calculate hash of key obtained via offset present in 84747151e4bSgaurav rana * ESBC uboot client hdr 84847151e4bSgaurav rana */ 84947151e4bSgaurav rana ret = calc_img_key_hash(img); 85047151e4bSgaurav rana if (ret) { 85147151e4bSgaurav rana fsl_secblk_handle_error(ret); 85247151e4bSgaurav rana goto exit; 85347151e4bSgaurav rana } 85447151e4bSgaurav rana 85547151e4bSgaurav rana /* Compare hash obtained above with SRK hash present in SFP */ 85647151e4bSgaurav rana if (hash_cmd) 85747151e4bSgaurav rana ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES); 85847151e4bSgaurav rana else 85947151e4bSgaurav rana ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES); 86047151e4bSgaurav rana 86147151e4bSgaurav rana #if defined(CONFIG_FSL_ISBC_KEY_EXT) 86247151e4bSgaurav rana if (!hash_cmd && check_ie(img)) 86347151e4bSgaurav rana ret = 0; 86447151e4bSgaurav rana #endif 86547151e4bSgaurav rana 86647151e4bSgaurav rana if (ret != 0) { 86747151e4bSgaurav rana fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY); 86847151e4bSgaurav rana goto exit; 86947151e4bSgaurav rana } 87047151e4bSgaurav rana 871*6629261dSAneesh Bansal ret = calculate_cmp_img_sig(img); 87247151e4bSgaurav rana if (ret) { 873*6629261dSAneesh Bansal fsl_secboot_handle_error(ret); 87447151e4bSgaurav rana goto exit; 87547151e4bSgaurav rana } 87647151e4bSgaurav rana 87747151e4bSgaurav rana exit: 878bc71f926SAneesh Bansal return ret; 87947151e4bSgaurav rana } 880