commit
1c6f6a6ef9
@ -0,0 +1,34 @@ |
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <fsl_validate.h> |
||||
|
||||
static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc, |
||||
char * const argv[]) |
||||
{ |
||||
if (argc < 2) |
||||
return cmd_usage(cmdtp); |
||||
|
||||
return fsl_secboot_validate(cmdtp, flag, argc, argv); |
||||
} |
||||
|
||||
/***************************************************/ |
||||
static char esbc_validate_help_text[] = |
||||
"esbc_validate hdr_addr <hash_val> - Validates signature using\n" |
||||
" RSA verification\n" |
||||
" $hdr_addr Address of header of the image\n" |
||||
" to be validated.\n" |
||||
" $hash_val -Optional\n" |
||||
" It provides Hash of public/srk key to be\n" |
||||
" used to verify signature.\n"; |
||||
|
||||
U_BOOT_CMD( |
||||
esbc_validate, 3, 0, do_esbc_validate, |
||||
"Validates signature on a given image using RSA verification", |
||||
esbc_validate_help_text |
||||
); |
@ -0,0 +1,840 @@ |
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <fsl_validate.h> |
||||
#include <fsl_secboot_err.h> |
||||
#include <fsl_sfp.h> |
||||
#include <fsl_sec.h> |
||||
#include <command.h> |
||||
#include <malloc.h> |
||||
#include <dm/uclass.h> |
||||
#include <u-boot/rsa-mod-exp.h> |
||||
#include <hash.h> |
||||
#include <fsl_secboot_err.h> |
||||
#ifndef CONFIG_MPC85xx |
||||
#include <asm/arch/immap_ls102xa.h> |
||||
#endif |
||||
|
||||
#define SHA256_BITS 256 |
||||
#define SHA256_BYTES (256/8) |
||||
#define SHA256_NIBBLES (256/4) |
||||
#define NUM_HEX_CHARS (sizeof(ulong) * 2) |
||||
|
||||
/* This array contains DER value for SHA-256 */ |
||||
static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, |
||||
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, |
||||
0x04, 0x20 |
||||
}; |
||||
|
||||
static u8 hash_val[SHA256_BYTES]; |
||||
static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 }; |
||||
|
||||
void branch_to_self(void) __attribute__ ((noreturn)); |
||||
|
||||
/*
|
||||
* This function will put core in infinite loop. |
||||
* This will be called when the ESBC can not proceed further due |
||||
* to some unknown errors. |
||||
*/ |
||||
void branch_to_self(void) |
||||
{ |
||||
printf("Core is in infinite loop due to errors.\n"); |
||||
self: |
||||
goto self; |
||||
} |
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT) |
||||
static u32 check_ie(struct fsl_secboot_img_priv *img) |
||||
{ |
||||
if (img->hdr.ie_flag) |
||||
return 1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/* This function returns the CSF Header Address of uboot
|
||||
* For MPC85xx based platforms, the LAW mapping for NOR |
||||
* flash changes in uboot code. Hence the offset needs |
||||
* to be calculated and added to the new NOR flash base |
||||
* address |
||||
*/ |
||||
#if defined(CONFIG_MPC85xx) |
||||
int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr) |
||||
{ |
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
||||
u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); |
||||
u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE); |
||||
ulong flash_addr, addr; |
||||
int found = 0; |
||||
int i = 0; |
||||
|
||||
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) { |
||||
flash_addr = flash_info[i].start[0]; |
||||
addr = flash_info[i].start[0] + csf_flash_offset; |
||||
if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) { |
||||
debug("Barker found on addr %lx\n", addr); |
||||
found = 1; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (!found) |
||||
return -1; |
||||
|
||||
*csf_addr = addr; |
||||
*flash_base_addr = flash_addr; |
||||
|
||||
return 0; |
||||
} |
||||
#else |
||||
/* For platforms like LS1020, correct flash address is present in
|
||||
* the header. So the function reqturns flash base address as 0 |
||||
*/ |
||||
int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr) |
||||
{ |
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); |
||||
u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]); |
||||
|
||||
if (memcmp((u8 *)csf_hdr_addr, barker_code, ESBC_BARKER_LEN)) |
||||
return -1; |
||||
|
||||
*csf_addr = csf_hdr_addr; |
||||
*flash_base_addr = 0; |
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
static int get_ie_info_addr(ulong *ie_addr) |
||||
{ |
||||
struct fsl_secboot_img_hdr *hdr; |
||||
struct fsl_secboot_sg_table *sg_tbl; |
||||
ulong flash_base_addr, csf_addr; |
||||
|
||||
if (get_csf_base_addr(&csf_addr, &flash_base_addr)) |
||||
return -1; |
||||
|
||||
hdr = (struct fsl_secboot_img_hdr *)csf_addr; |
||||
|
||||
/* For SoC's with Trust Architecture v1 with corenet bus
|
||||
* the sg table field in CSF header has absolute address |
||||
* for sg table in memory. In other Trust Architecture, |
||||
* this field specifies the offset of sg table from the |
||||
* base address of CSF Header |
||||
*/ |
||||
#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET) |
||||
sg_tbl = (struct fsl_secboot_sg_table *) |
||||
(((ulong)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) + |
||||
flash_base_addr); |
||||
#else |
||||
sg_tbl = (struct fsl_secboot_sg_table *)(csf_addr + |
||||
(ulong)hdr->psgtable); |
||||
#endif |
||||
|
||||
/* IE Key Table is the first entry in the SG Table */ |
||||
#if defined(CONFIG_MPC85xx) |
||||
*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) + |
||||
flash_base_addr; |
||||
#else |
||||
*ie_addr = sg_tbl->src_addr; |
||||
#endif |
||||
|
||||
debug("IE Table address is %lx\n", *ie_addr); |
||||
return 0; |
||||
} |
||||
|
||||
#endif |
||||
|
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
/* This function checks srk_table_flag in header and set/reset srk_flag.*/ |
||||
static u32 check_srk(struct fsl_secboot_img_priv *img) |
||||
{ |
||||
if (img->hdr.len_kr.srk_table_flag & SRK_FLAG) |
||||
return 1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/* This function returns ospr's key_revoc values.*/ |
||||
static u32 get_key_revoc(void) |
||||
{ |
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); |
||||
return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >> |
||||
OSPR_KEY_REVOC_SHIFT; |
||||
} |
||||
|
||||
/* This function checks if selected key is revoked or not.*/ |
||||
static u32 is_key_revoked(u32 keynum, u32 rev_flag) |
||||
{ |
||||
if (keynum == UNREVOCABLE_KEY) |
||||
return 0; |
||||
|
||||
if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag) |
||||
return 1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/* It validates srk_table key lengths.*/ |
||||
static u32 validate_srk_tbl(struct srk_table *tbl, u32 num_entries) |
||||
{ |
||||
int i = 0; |
||||
for (i = 0; i < num_entries; i++) { |
||||
if (!((tbl[i].key_len == 2 * KEY_SIZE_BYTES/4) || |
||||
(tbl[i].key_len == 2 * KEY_SIZE_BYTES/2) || |
||||
(tbl[i].key_len == 2 * KEY_SIZE_BYTES))) |
||||
return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN; |
||||
} |
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
/* This function return length of public key.*/ |
||||
static inline u32 get_key_len(struct fsl_secboot_img_priv *img) |
||||
{ |
||||
return img->key_len; |
||||
} |
||||
|
||||
/*
|
||||
* Handles the ESBC uboot client header verification failure. |
||||
* This function handles all the errors which might occur in the |
||||
* parsing and checking of ESBC uboot client header. It will also |
||||
* set the error bits in the SEC_MON. |
||||
*/ |
||||
static void fsl_secboot_header_verification_failure(void) |
||||
{ |
||||
struct ccsr_sec_mon_regs *sec_mon_regs = (void *) |
||||
(CONFIG_SYS_SEC_MON_ADDR); |
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); |
||||
u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat); |
||||
|
||||
/* 29th bit of OSPR is ITS */ |
||||
u32 its = sfp_in32(&sfp_regs->ospr) >> 2; |
||||
|
||||
/*
|
||||
* Read the SEC_MON status register |
||||
* Read SSM_ST field |
||||
*/ |
||||
sts = sec_mon_in32(&sec_mon_regs->hp_stat); |
||||
if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) { |
||||
if (its == 1) |
||||
change_sec_mon_state(HPSR_SSM_ST_TRUST, |
||||
HPSR_SSM_ST_SOFT_FAIL); |
||||
else |
||||
change_sec_mon_state(HPSR_SSM_ST_TRUST, |
||||
HPSR_SSM_ST_NON_SECURE); |
||||
} |
||||
|
||||
printf("Generating reset request\n"); |
||||
do_reset(NULL, 0, 0, NULL); |
||||
} |
||||
|
||||
/*
|
||||
* Handles the ESBC uboot client image verification failure. |
||||
* This function handles all the errors which might occur in the |
||||
* public key hash comparison and signature verification of |
||||
* ESBC uboot client image. It will also |
||||
* set the error bits in the SEC_MON. |
||||
*/ |
||||
static void fsl_secboot_image_verification_failure(void) |
||||
{ |
||||
struct ccsr_sec_mon_regs *sec_mon_regs = (void *) |
||||
(CONFIG_SYS_SEC_MON_ADDR); |
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); |
||||
u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat); |
||||
|
||||
u32 its = sfp_in32(&sfp_regs->ospr) & ITS_MASK >> ITS_BIT; |
||||
|
||||
/*
|
||||
* Read the SEC_MON status register |
||||
* Read SSM_ST field |
||||
*/ |
||||
sts = sec_mon_in32(&sec_mon_regs->hp_stat); |
||||
if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) { |
||||
if (its == 1) { |
||||
change_sec_mon_state(HPSR_SSM_ST_TRUST, |
||||
HPSR_SSM_ST_SOFT_FAIL); |
||||
|
||||
printf("Generating reset request\n"); |
||||
do_reset(NULL, 0, 0, NULL); |
||||
} else { |
||||
change_sec_mon_state(HPSR_SSM_ST_TRUST, |
||||
HPSR_SSM_ST_NON_SECURE); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void fsl_secboot_bootscript_parse_failure(void) |
||||
{ |
||||
fsl_secboot_header_verification_failure(); |
||||
} |
||||
|
||||
/*
|
||||
* Handles the errors in esbc boot. |
||||
* This function handles all the errors which might occur in the |
||||
* esbc boot phase. It will call the appropriate api to log the |
||||
* errors and set the error bits in the SEC_MON. |
||||
*/ |
||||
void fsl_secboot_handle_error(int error) |
||||
{ |
||||
const struct fsl_secboot_errcode *e; |
||||
|
||||
for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX; |
||||
e++) { |
||||
if (e->errcode == error) |
||||
printf("ERROR :: %x :: %s\n", error, e->name); |
||||
} |
||||
|
||||
switch (error) { |
||||
case ERROR_ESBC_CLIENT_HEADER_BARKER: |
||||
case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE: |
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_LEN: |
||||
case ERROR_ESBC_CLIENT_HEADER_SIG_LEN: |
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN: |
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1: |
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2: |
||||
case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD: |
||||
case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP: |
||||
case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD: |
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED: |
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY: |
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM: |
||||
case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN: |
||||
#endif |
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT) |
||||
/*@fallthrough@*/ |
||||
case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED: |
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY: |
||||
case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM: |
||||
case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN: |
||||
case ERROR_IE_TABLE_NOT_FOUND: |
||||
#endif |
||||
fsl_secboot_header_verification_failure(); |
||||
break; |
||||
case ERROR_ESBC_SEC_RESET: |
||||
case ERROR_ESBC_SEC_DEQ: |
||||
case ERROR_ESBC_SEC_ENQ: |
||||
case ERROR_ESBC_SEC_DEQ_TO: |
||||
case ERROR_ESBC_SEC_JOBQ_STATUS: |
||||
case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY: |
||||
case ERROR_ESBC_CLIENT_HASH_COMPARE_EM: |
||||
fsl_secboot_image_verification_failure(); |
||||
break; |
||||
case ERROR_ESBC_MISSING_BOOTM: |
||||
fsl_secboot_bootscript_parse_failure(); |
||||
break; |
||||
case ERROR_ESBC_WRONG_CMD: |
||||
default: |
||||
branch_to_self(); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
static void fsl_secblk_handle_error(int error) |
||||
{ |
||||
switch (error) { |
||||
case ERROR_ESBC_SEC_ENQ: |
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ); |
||||
break; |
||||
case ERROR_ESBC_SEC_DEQ: |
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ); |
||||
break; |
||||
case ERROR_ESBC_SEC_DEQ_TO: |
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO); |
||||
break; |
||||
default: |
||||
printf("Job Queue Output status %x\n", error); |
||||
fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* Calculate hash of key obtained via offset present in ESBC uboot |
||||
* client hdr. This function calculates the hash of key which is obtained |
||||
* through offset present in ESBC uboot client header. |
||||
*/ |
||||
static int calc_img_key_hash(struct fsl_secboot_img_priv *img) |
||||
{ |
||||
struct hash_algo *algo; |
||||
void *ctx; |
||||
int i, srk = 0; |
||||
int ret = 0; |
||||
const char *algo_name = "sha256"; |
||||
|
||||
/* Calculate hash of the esbc key */ |
||||
ret = hash_progressive_lookup_algo(algo_name, &algo); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
ret = algo->hash_init(algo, &ctx); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
/* Update hash for ESBC key */ |
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
if (check_srk(img)) { |
||||
ret = algo->hash_update(algo, ctx, |
||||
(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off), |
||||
img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1); |
||||
srk = 1; |
||||
} |
||||
#endif |
||||
if (!srk) |
||||
ret = algo->hash_update(algo, ctx, |
||||
img->img_key, img->key_len, 1); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
/* Copy hash at destination buffer */ |
||||
ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
for (i = 0; i < SHA256_BYTES; i++) |
||||
img->img_key_hash[i] = hash_val[i]; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
* Calculate hash of ESBC hdr and ESBC. This function calculates the |
||||
* single hash of ESBC header and ESBC image. If SG flag is on, all |
||||
* SG entries are also hashed alongwith the complete SG table. |
||||
*/ |
||||
static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img) |
||||
{ |
||||
struct hash_algo *algo; |
||||
void *ctx; |
||||
int ret = 0; |
||||
int key_hash = 0; |
||||
const char *algo_name = "sha256"; |
||||
|
||||
/* Calculate the hash of the ESBC */ |
||||
ret = hash_progressive_lookup_algo(algo_name, &algo); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
ret = algo->hash_init(algo, &ctx); |
||||
/* Copy hash at destination buffer */ |
||||
if (ret) |
||||
return ret; |
||||
|
||||
/* Update hash for CSF Header */ |
||||
ret = algo->hash_update(algo, ctx, |
||||
(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
/* Update the hash with that of srk table if srk flag is 1
|
||||
* If IE Table is selected, key is not added in the hash |
||||
* If neither srk table nor IE key table available, add key |
||||
* from header in the hash calculation |
||||
*/ |
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
if (check_srk(img)) { |
||||
ret = algo->hash_update(algo, ctx, |
||||
(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off), |
||||
img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0); |
||||
key_hash = 1; |
||||
} |
||||
#endif |
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT) |
||||
if (!key_hash && check_ie(img)) |
||||
key_hash = 1; |
||||
#endif |
||||
if (!key_hash) |
||||
ret = algo->hash_update(algo, ctx, |
||||
img->img_key, img->hdr.key_len, 0); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
/* Update hash for actual Image */ |
||||
ret = algo->hash_update(algo, ctx, |
||||
(u8 *)img->hdr.pimg, img->hdr.img_size, 1); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
/* Copy hash at destination buffer */ |
||||
ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size); |
||||
if (ret) |
||||
return ret; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*
|
||||
* Construct encoded hash EM' wrt PKCSv1.5. This function calculates the |
||||
* pointers for padding, DER value and hash. And finally, constructs EM' |
||||
* which includes hash of complete CSF header and ESBC image. If SG flag |
||||
* is on, hash of SG table and entries is also included. |
||||
*/ |
||||
static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img) |
||||
{ |
||||
/*
|
||||
* RSA PKCSv1.5 encoding format for encoded message is below |
||||
* EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash |
||||
* PS is Padding String |
||||
* DER is DER value for SHA-256 |
||||
* Hash is SHA-256 hash |
||||
* ********************************************************* |
||||
* representative points to first byte of EM initially and is |
||||
* filled with 0x0 |
||||
* representative is incremented by 1 and second byte is filled |
||||
* with 0x1 |
||||
* padding points to third byte of EM |
||||
* digest points to full length of EM - 32 bytes |
||||
* hash_id (DER value) points to 19 bytes before pDigest |
||||
* separator is one byte which separates padding and DER |
||||
*/ |
||||
|
||||
size_t len; |
||||
u8 *representative; |
||||
u8 *padding, *digest; |
||||
u8 *hash_id, *separator; |
||||
int i; |
||||
|
||||
len = (get_key_len(img) / 2) - 1; |
||||
representative = img->img_encoded_hash_second; |
||||
representative[0] = 0; |
||||
representative[1] = 1; /* block type 1 */ |
||||
|
||||
padding = &representative[2]; |
||||
digest = &representative[1] + len - 32; |
||||
hash_id = digest - sizeof(hash_identifier); |
||||
separator = hash_id - 1; |
||||
|
||||
/* fill padding area pointed by padding with 0xff */ |
||||
memset(padding, 0xff, separator - padding); |
||||
|
||||
/* fill byte pointed by separator */ |
||||
*separator = 0; |
||||
|
||||
/* fill SHA-256 DER value pointed by HashId */ |
||||
memcpy(hash_id, hash_identifier, sizeof(hash_identifier)); |
||||
|
||||
/* fill hash pointed by Digest */ |
||||
for (i = 0; i < SHA256_BYTES; i++) |
||||
digest[i] = hash_val[i]; |
||||
} |
||||
|
||||
/*
|
||||
* Reads and validates the ESBC client header. |
||||
* This function reads key and signature from the ESBC client header. |
||||
* If Scatter/Gather flag is on, lengths and offsets of images |
||||
* present as SG entries are also read. This function also checks |
||||
* whether the header is valid or not. |
||||
*/ |
||||
static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img) |
||||
{ |
||||
char buf[20]; |
||||
struct fsl_secboot_img_hdr *hdr = &img->hdr; |
||||
void *esbc = (u8 *)img->ehdrloc; |
||||
u8 *k, *s; |
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
u32 ret; |
||||
u32 key_num, key_revoc_flag, size; |
||||
#endif |
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT) |
||||
struct ie_key_info *ie_info; |
||||
u32 ie_num, ie_revoc_flag, ie_key_len; |
||||
#endif |
||||
int key_found = 0; |
||||
|
||||
/* check barker code */ |
||||
if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN)) |
||||
return ERROR_ESBC_CLIENT_HEADER_BARKER; |
||||
|
||||
sprintf(buf, "%p", hdr->pimg); |
||||
setenv("img_addr", buf); |
||||
|
||||
if (!hdr->img_size) |
||||
return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE; |
||||
|
||||
/* Key checking*/ |
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
if (check_srk(img)) { |
||||
if ((hdr->len_kr.num_srk == 0) || |
||||
(hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) |
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY; |
||||
|
||||
key_num = hdr->len_kr.srk_sel; |
||||
if (key_num == 0 || key_num > hdr->len_kr.num_srk) |
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM; |
||||
|
||||
/* Get revoc key from sfp */ |
||||
key_revoc_flag = get_key_revoc(); |
||||
ret = is_key_revoked(key_num, key_revoc_flag); |
||||
if (ret) |
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED; |
||||
|
||||
size = hdr->len_kr.num_srk * sizeof(struct srk_table); |
||||
|
||||
memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size); |
||||
|
||||
ret = validate_srk_tbl(img->srk_tbl, hdr->len_kr.num_srk); |
||||
|
||||
if (ret != 0) |
||||
return ret; |
||||
|
||||
img->key_len = img->srk_tbl[key_num - 1].key_len; |
||||
|
||||
memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey), |
||||
img->key_len); |
||||
|
||||
key_found = 1; |
||||
} |
||||
#endif |
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT) |
||||
if (!key_found && check_ie(img)) { |
||||
if (get_ie_info_addr(&img->ie_addr)) |
||||
return ERROR_IE_TABLE_NOT_FOUND; |
||||
ie_info = (struct ie_key_info *)img->ie_addr; |
||||
if (ie_info->num_keys == 0 || ie_info->num_keys > 32) |
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY; |
||||
|
||||
ie_num = hdr->ie_key_sel; |
||||
if (ie_num == 0 || ie_num > ie_info->num_keys) |
||||
return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM; |
||||
|
||||
ie_revoc_flag = ie_info->key_revok; |
||||
if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag) |
||||
return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED; |
||||
|
||||
ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len; |
||||
|
||||
if (!((ie_key_len == 2 * KEY_SIZE_BYTES / 4) || |
||||
(ie_key_len == 2 * KEY_SIZE_BYTES / 2) || |
||||
(ie_key_len == 2 * KEY_SIZE_BYTES))) |
||||
return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN; |
||||
|
||||
memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey), |
||||
ie_key_len); |
||||
|
||||
img->key_len = ie_key_len; |
||||
key_found = 1; |
||||
} |
||||
#endif |
||||
|
||||
if (key_found == 0) { |
||||
/* check key length */ |
||||
if (!((hdr->key_len == 2 * KEY_SIZE_BYTES / 4) || |
||||
(hdr->key_len == 2 * KEY_SIZE_BYTES / 2) || |
||||
(hdr->key_len == 2 * KEY_SIZE_BYTES))) |
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_LEN; |
||||
|
||||
memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len); |
||||
|
||||
img->key_len = hdr->key_len; |
||||
|
||||
key_found = 1; |
||||
} |
||||
|
||||
/* check signaure */ |
||||
if (get_key_len(img) == 2 * hdr->sign_len) { |
||||
/* check signature length */ |
||||
if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) || |
||||
(hdr->sign_len == KEY_SIZE_BYTES / 2) || |
||||
(hdr->sign_len == KEY_SIZE_BYTES))) |
||||
return ERROR_ESBC_CLIENT_HEADER_SIG_LEN; |
||||
} else { |
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN; |
||||
} |
||||
|
||||
memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len); |
||||
|
||||
/* No SG support */ |
||||
if (hdr->sg_flag) |
||||
return ERROR_ESBC_CLIENT_HEADER_SG; |
||||
|
||||
/* modulus most significant bit should be set */ |
||||
k = (u8 *)&img->img_key; |
||||
|
||||
if ((k[0] & 0x80) == 0) |
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1; |
||||
|
||||
/* modulus value should be odd */ |
||||
if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0) |
||||
return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2; |
||||
|
||||
/* Check signature value < modulus value */ |
||||
s = (u8 *)&img->img_sign; |
||||
|
||||
if (!(memcmp(s, k, hdr->sign_len) < 0)) |
||||
return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD; |
||||
|
||||
return ESBC_VALID_HDR; |
||||
} |
||||
|
||||
static inline int str2longbe(const char *p, ulong *num) |
||||
{ |
||||
char *endptr; |
||||
ulong tmp; |
||||
|
||||
if (!p) { |
||||
return 0; |
||||
} else { |
||||
tmp = simple_strtoul(p, &endptr, 16); |
||||
if (sizeof(ulong) == 4) |
||||
*num = cpu_to_be32(tmp); |
||||
else |
||||
*num = cpu_to_be64(tmp); |
||||
} |
||||
|
||||
return *p != '\0' && *endptr == '\0'; |
||||
} |
||||
|
||||
int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, |
||||
char * const argv[]) |
||||
{ |
||||
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR); |
||||
ulong hash[SHA256_BYTES/sizeof(ulong)]; |
||||
char hash_str[NUM_HEX_CHARS + 1]; |
||||
ulong addr = simple_strtoul(argv[1], NULL, 16); |
||||
struct fsl_secboot_img_priv *img; |
||||
struct fsl_secboot_img_hdr *hdr; |
||||
void *esbc; |
||||
int ret, i, hash_cmd = 0; |
||||
u32 srk_hash[8]; |
||||
uint32_t key_len; |
||||
struct key_prop prop; |
||||
#if !defined(USE_HOSTCC) |
||||
struct udevice *mod_exp_dev; |
||||
#endif |
||||
|
||||
if (argc == 3) { |
||||
char *cp = argv[2]; |
||||
int i = 0; |
||||
|
||||
if (*cp == '0' && *(cp + 1) == 'x') |
||||
cp += 2; |
||||
|
||||
/* The input string expected is in hex, where
|
||||
* each 4 bits would be represented by a hex |
||||
* sha256 hash is 256 bits long, which would mean |
||||
* num of characters = 256 / 4 |
||||
*/ |
||||
if (strlen(cp) != SHA256_NIBBLES) { |
||||
printf("%s is not a 256 bits hex string as expected\n", |
||||
argv[2]); |
||||
return -1; |
||||
} |
||||
|
||||
for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) { |
||||
strncpy(hash_str, cp + (i * NUM_HEX_CHARS), |
||||
NUM_HEX_CHARS); |
||||
hash_str[NUM_HEX_CHARS] = '\0'; |
||||
if (!str2longbe(hash_str, &hash[i])) { |
||||
printf("%s is not a 256 bits hex string ", |
||||
argv[2]); |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
hash_cmd = 1; |
||||
} |
||||
|
||||
img = malloc(sizeof(struct fsl_secboot_img_priv)); |
||||
|
||||
if (!img) |
||||
return -1; |
||||
|
||||
memset(img, 0, sizeof(struct fsl_secboot_img_priv)); |
||||
|
||||
hdr = &img->hdr; |
||||
img->ehdrloc = addr; |
||||
esbc = (u8 *)img->ehdrloc; |
||||
|
||||
memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr)); |
||||
|
||||
/* read and validate esbc header */ |
||||
ret = read_validate_esbc_client_header(img); |
||||
|
||||
if (ret != ESBC_VALID_HDR) { |
||||
fsl_secboot_handle_error(ret); |
||||
goto exit; |
||||
} |
||||
|
||||
/* SRKH present in SFP */ |
||||
for (i = 0; i < NUM_SRKH_REGS; i++) |
||||
srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]); |
||||
|
||||
/*
|
||||
* Calculate hash of key obtained via offset present in |
||||
* ESBC uboot client hdr |
||||
*/ |
||||
ret = calc_img_key_hash(img); |
||||
if (ret) { |
||||
fsl_secblk_handle_error(ret); |
||||
goto exit; |
||||
} |
||||
|
||||
/* Compare hash obtained above with SRK hash present in SFP */ |
||||
if (hash_cmd) |
||||
ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES); |
||||
else |
||||
ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES); |
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT) |
||||
if (!hash_cmd && check_ie(img)) |
||||
ret = 0; |
||||
#endif |
||||
|
||||
if (ret != 0) { |
||||
fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY); |
||||
goto exit; |
||||
} |
||||
|
||||
ret = calc_esbchdr_esbc_hash(img); |
||||
if (ret) { |
||||
fsl_secblk_handle_error(ret); |
||||
goto exit; |
||||
} |
||||
|
||||
/* Construct encoded hash EM' wrt PKCSv1.5 */ |
||||
construct_img_encoded_hash_second(img); |
||||
|
||||
/* Fill prop structure for public key */ |
||||
memset(&prop, 0, sizeof(struct key_prop)); |
||||
key_len = get_key_len(img) / 2; |
||||
prop.modulus = img->img_key; |
||||
prop.public_exponent = img->img_key + key_len; |
||||
prop.num_bits = key_len * 8; |
||||
prop.exp_len = key_len; |
||||
|
||||
ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev); |
||||
if (ret) { |
||||
printf("RSA: Can't find Modular Exp implementation\n"); |
||||
return -EINVAL; |
||||
} |
||||
|
||||
ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len, |
||||
&prop, img->img_encoded_hash); |
||||
if (ret) { |
||||
fsl_secblk_handle_error(ret); |
||||
goto exit; |
||||
} |
||||
|
||||
/*
|
||||
* compare the encoded messages EM' and EM wrt RSA PKCSv1.5 |
||||
* memcmp returns zero on success |
||||
* memcmp returns non-zero on failure |
||||
*/ |
||||
ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash, |
||||
img->hdr.sign_len); |
||||
|
||||
if (ret) { |
||||
fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_EM); |
||||
goto exit; |
||||
} |
||||
|
||||
printf("esbc_validate command successful\n"); |
||||
|
||||
exit: |
||||
return 0; |
||||
} |
@ -0,0 +1,105 @@ |
||||
DSP side awareness for Freescale heterogeneous multicore chips based on |
||||
StarCore and Power Architecture |
||||
=============================================================== |
||||
powerpc/mpc85xx code ve APIs and function to get the number, |
||||
configuration and frequencies of all PowerPC cores and devices |
||||
connected to them, but it didnt have the similar code ofr HEterogeneous |
||||
SC3900/DSP cores and such devices like CPRI, MAPLE, MAPLE-ULB etc. |
||||
|
||||
Code for DSP side awareness provides such functionality for Freescale |
||||
Heterogeneous SoCs which are chasis-2 compliant like B4860 and B4420 |
||||
|
||||
As part of this feature, following changes have been made: |
||||
========================================================== |
||||
|
||||
1. Changed files: |
||||
================= |
||||
- arch/powerpc/cpu/mpc85xx/cpu.c |
||||
|
||||
Code added in this file to print the DSP cores and other device's(CPRI, |
||||
MAPLE etc) frequencies |
||||
|
||||
- arch/powerpc/cpu/mpc85xx/speed.c |
||||
|
||||
Added Defines and code to extract the frequncy information for all |
||||
required cores and devices from RCW and System frequency |
||||
|
||||
- arch/powerpc/cpu/mpc8xxx/cpu.c |
||||
|
||||
Added API to get the number of SC cores in running system and Their BIT |
||||
MASK, similar to the code written for PowerPC |
||||
|
||||
- arch/powerpc/include/asm/config_mpc85xx.h |
||||
|
||||
Added top level CONFIG to identify presence of HETEROGENUOUS clusters |
||||
in the system and CONFIGS for SC3900/DSP components |
||||
|
||||
- arch/powerpc/include/asm/processor.h |
||||
- include/common.h |
||||
|
||||
Added newly added Functions Declaration |
||||
|
||||
- include/e500.h |
||||
|
||||
Global structure updated for dsp cores and other components |
||||
|
||||
2. CONFIGs ADDED |
||||
================ |
||||
|
||||
CONFIG_HETROGENOUS_CLUSTERS - Define for checking the presence of |
||||
DSP/SC3900 core clusters |
||||
|
||||
CONFIG_SYS_FSL_NUM_CC_PLLS - Define for number of PLLs |
||||
|
||||
Though there are only 4 PLLs in B4, but in sequence of PLLs from PLL1 - |
||||
PLL5, PLL3 is Reserved(as mentioned in RM), so this define contains the |
||||
value as 5 not 4, to iterate over all PLLs while coding |
||||
|
||||
CONFIG_SYS_MAPLE - Define for MAPLE Baseband Accelerator |
||||
CONFIG_SYS_CPRI - Define for CPRI Interface |
||||
CONFIG_PPC_CLUSTER_START - Start index of ppc clusters |
||||
CONFIG_DSP_CLUSTER_START - Start index of dsp clusters |
||||
|
||||
Following are the defines for PLL's index that provide the Clocking to |
||||
CPRI, ULB and ETVE components |
||||
|
||||
CONFIG_SYS_CPRI_CLK - Define PLL index for CPRI clock |
||||
CONFIG_SYS_ULB_CLK - Define PLL index for ULB clock |
||||
CONFIG_SYS_ETVPE_CLK - Define PLL index for ETVPE clock |
||||
|
||||
3. Changes in MPC85xx_SYS_INFO Global structure |
||||
=============================================== |
||||
|
||||
DSP cores and other device's components have been added in this structure. |
||||
|
||||
freq_processor_dsp[CONFIG_MAX_DSP_CPUS] - Array to contain the DSP core's frequencies |
||||
freq_cpri - To store CPRI frequency |
||||
freq_maple - To store MAPLE frequency |
||||
freq_maple_ulb - To store MAPLE-ULB frequency |
||||
freq_maple_etvpe - To store MAPLE-eTVPE frequency |
||||
|
||||
4. U-BOOT LOGS |
||||
============== |
||||
4.1 B4860QDS board |
||||
Boot from NOR flash |
||||
|
||||
U-Boot 2014.07-00222-g70587a8-dirty (Aug 07 2014 - 13:15:47) |
||||
|
||||
CPU0: B4860E, Version: 2.0, (0x86880020) |
||||
Core: e6500, Version: 2.0, (0x80400020) Clock Configuration: |
||||
CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz, |
||||
DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz, |
||||
DSP CPU4:1200 MHz, DSP CPU5:1200 MHz, |
||||
CCB:666.667 MHz, |
||||
DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz |
||||
CPRI:600 MHz |
||||
MAPLE:600 MHz, MAPLE-ULB:800 MHz, MAPLE-eTVPE:1000 MHz |
||||
FMAN1: 666.667 MHz |
||||
QMAN: 333.333 MHz |
||||
|
||||
CPUn - PowerPC core |
||||
DSP CPUn - SC3900 core |
||||
|
||||
Shaveta Leekha(shaveta@freescale.com) |
||||
Created August 7, 2014 |
||||
=========================================== |
@ -0,0 +1,41 @@ |
||||
/* |
||||
* (C) Copyright 2015 |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
esbc_validate command |
||||
======================================== |
||||
|
||||
1. esbc_validate command is meant for validating header and |
||||
signature of images (Boot Script and ESBC uboot client). |
||||
SHA-256 and RSA operations are performed using SEC block in HW. |
||||
This command works on both PBL based and Non PBL based Freescale |
||||
platforms. |
||||
Command usage: |
||||
esbc_validate img_hdr_addr [pub_key_hash] |
||||
esbc_validate hdr_addr <hash_val> |
||||
Validates signature using RSA verification. |
||||
$hdr_addr Address of header of the image to be validated. |
||||
$hash_val -Optional. It provides Hash of public/srk key to be |
||||
used to verify signature. |
||||
|
||||
2. ESBC uboot client can be linux. Additionally, rootfs and device |
||||
tree blob can also be signed. |
||||
3. In the event of header or signature failure in validation, |
||||
ITS and ITF bits determine further course of action. |
||||
4. In case of soft failure, appropriate error is dumped on console. |
||||
5. In case of hard failure, SoC is issued RESET REQUEST after |
||||
dumping error on the console. |
||||
6. KEY REVOCATION Feature: |
||||
QorIQ platforms like B4/T4 have support of srk key table and key |
||||
revocation in ISBC code in Silicon. |
||||
The srk key table allows the user to have a key table with multiple |
||||
keys and revoke any key in case of particular key gets compromised. |
||||
In case the ISBC code uses the key revocation and srk key table to |
||||
verify the u-boot code, the subsequent chain of trust should also |
||||
use the same. |
||||
6. ISBC KEY EXTENSION Feature: |
||||
This feature allows large number of keys to be used for esbc validation |
||||
of images. A set of public keys is being signed and validated by ISBC |
||||
which can be further used for esbc validation of images. |
@ -0,0 +1,146 @@ |
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <fsl_sec_mon.h> |
||||
|
||||
int change_sec_mon_state(u32 initial_state, u32 final_state) |
||||
{ |
||||
struct ccsr_sec_mon_regs *sec_mon_regs = (void *) |
||||
(CONFIG_SYS_SEC_MON_ADDR); |
||||
u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat); |
||||
int timeout = 10; |
||||
|
||||
if ((sts & HPSR_SSM_ST_MASK) != initial_state) |
||||
return -1; |
||||
|
||||
if (initial_state == HPSR_SSM_ST_TRUST) { |
||||
switch (final_state) { |
||||
case HPSR_SSM_ST_NON_SECURE: |
||||
printf("SEC_MON state transitioning to Soft Fail.\n"); |
||||
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV); |
||||
|
||||
/*
|
||||
* poll till SEC_MON is in |
||||
* Soft Fail state |
||||
*/ |
||||
while (((sts & HPSR_SSM_ST_MASK) != |
||||
HPSR_SSM_ST_SOFT_FAIL)) { |
||||
while (timeout) { |
||||
sts = sec_mon_in32 |
||||
(&sec_mon_regs->hp_stat); |
||||
|
||||
if ((sts & HPSR_SSM_ST_MASK) == |
||||
HPSR_SSM_ST_SOFT_FAIL) |
||||
break; |
||||
|
||||
udelay(10); |
||||
timeout--; |
||||
} |
||||
} |
||||
|
||||
if (timeout == 0) { |
||||
printf("SEC_MON state transition timeout.\n"); |
||||
return -1; |
||||
} |
||||
|
||||
timeout = 10; |
||||
|
||||
printf("SEC_MON state transitioning to Non Secure.\n"); |
||||
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST); |
||||
|
||||
/*
|
||||
* poll till SEC_MON is in |
||||
* Non Secure state |
||||
*/ |
||||
while (((sts & HPSR_SSM_ST_MASK) != |
||||
HPSR_SSM_ST_NON_SECURE)) { |
||||
while (timeout) { |
||||
sts = sec_mon_in32 |
||||
(&sec_mon_regs->hp_stat); |
||||
|
||||
if ((sts & HPSR_SSM_ST_MASK) == |
||||
HPSR_SSM_ST_NON_SECURE) |
||||
break; |
||||
|
||||
udelay(10); |
||||
timeout--; |
||||
} |
||||
} |
||||
|
||||
if (timeout == 0) { |
||||
printf("SEC_MON state transition timeout.\n"); |
||||
return -1; |
||||
} |
||||
break; |
||||
case HPSR_SSM_ST_SOFT_FAIL: |
||||
printf("SEC_MON state transitioning to Soft Fail.\n"); |
||||
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV); |
||||
|
||||
/*
|
||||
* polling loop till SEC_MON is in |
||||
* Soft Fail state |
||||
*/ |
||||
while (((sts & HPSR_SSM_ST_MASK) != |
||||
HPSR_SSM_ST_SOFT_FAIL)) { |
||||
while (timeout) { |
||||
sts = sec_mon_in32 |
||||
(&sec_mon_regs->hp_stat); |
||||
|
||||
if ((sts & HPSR_SSM_ST_MASK) == |
||||
HPSR_SSM_ST_SOFT_FAIL) |
||||
break; |
||||
|
||||
udelay(10); |
||||
timeout--; |
||||
} |
||||
} |
||||
|
||||
if (timeout == 0) { |
||||
printf("SEC_MON state transition timeout.\n"); |
||||
return -1; |
||||
} |
||||
break; |
||||
default: |
||||
return -1; |
||||
} |
||||
} else if (initial_state == HPSR_SSM_ST_NON_SECURE) { |
||||
switch (final_state) { |
||||
case HPSR_SSM_ST_SOFT_FAIL: |
||||
printf("SEC_MON state transitioning to Soft Fail.\n"); |
||||
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV); |
||||
|
||||
/*
|
||||
* polling loop till SEC_MON is in |
||||
* Soft Fail state |
||||
*/ |
||||
while (((sts & HPSR_SSM_ST_MASK) != |
||||
HPSR_SSM_ST_SOFT_FAIL)) { |
||||
while (timeout) { |
||||
sts = sec_mon_in32 |
||||
(&sec_mon_regs->hp_stat); |
||||
|
||||
if ((sts & HPSR_SSM_ST_MASK) == |
||||
HPSR_SSM_ST_SOFT_FAIL) |
||||
break; |
||||
|
||||
udelay(10); |
||||
timeout--; |
||||
} |
||||
} |
||||
|
||||
if (timeout == 0) { |
||||
printf("SEC_MON state transition timeout.\n"); |
||||
return -1; |
||||
} |
||||
break; |
||||
default: |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,58 @@ |
||||
/*
|
||||
* Common internal memory map for some Freescale SoCs |
||||
* |
||||
* Copyright 2015 Freescale Semiconductor, Inc. |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef __FSL_SEC_MON_H |
||||
#define __FSL_SEC_MON_H |
||||
|
||||
#include <common.h> |
||||
#include <asm/io.h> |
||||
|
||||
#ifdef CONFIG_SYS_FSL_SEC_MON_LE |
||||
#define sec_mon_in32(a) in_le32(a) |
||||
#define sec_mon_out32(a, v) out_le32(a, v) |
||||
#define sec_mon_in16(a) in_le16(a) |
||||
#define sec_mon_clrbits32 clrbits_le32 |
||||
#define sec_mon_setbits32 setbits_le32 |
||||
#elif defined(CONFIG_SYS_FSL_SEC_MON_BE) |
||||
#define sec_mon_in32(a) in_be32(a) |
||||
#define sec_mon_out32(a, v) out_be32(a, v) |
||||
#define sec_mon_in16(a) in_be16(a) |
||||
#define sec_mon_clrbits32 clrbits_be32 |
||||
#define sec_mon_setbits32 setbits_be32 |
||||
#else |
||||
#error Neither CONFIG_SYS_FSL_SEC_MON_LE nor CONFIG_SYS_FSL_SEC_MON_BE defined |
||||
#endif |
||||
|
||||
struct ccsr_sec_mon_regs { |
||||
u8 reserved0[0x04]; |
||||
u32 hp_com; /* 0x04 SEC_MON_HP Command Register */ |
||||
u8 reserved2[0x0c]; |
||||
u32 hp_stat; /* 0x08 SEC_MON_HP Status Register */ |
||||
}; |
||||
|
||||
#define HPCOMR_SW_SV 0x100 /* Security Violation bit */ |
||||
#define HPCOMR_SW_FSV 0x200 /* Fatal Security Violation bit */ |
||||
#define HPCOMR_SSM_ST 0x1 /* SSM_ST field in SEC_MON command */ |
||||
#define HPSR_SSM_ST_CHECK 0x900 /* SEC_MON is in check state */ |
||||
#define HPSR_SSM_ST_NON_SECURE 0xb00 /* SEC_MON is in non secure state */ |
||||
#define HPSR_SSM_ST_TRUST 0xd00 /* SEC_MON is in trusted state */ |
||||
#define HPSR_SSM_ST_SOFT_FAIL 0x300 /* SEC_MON is in soft fail state */ |
||||
#define HPSR_SSM_ST_MASK 0xf00 /* Mask for SSM_ST field */ |
||||
|
||||
/*
|
||||
* SEC_MON read. This specifies the possible reads |
||||
* from the SEC_MON |
||||
*/ |
||||
enum { |
||||
SEC_MON_SSM_ST, |
||||
SEC_MON_SW_FSV, |
||||
SEC_MON_SW_SV, |
||||
}; |
||||
|
||||
int change_sec_mon_state(uint32_t initial_state, uint32_t final_state); |
||||
|
||||
#endif /* __FSL_SEC_MON_H */ |
@ -0,0 +1,128 @@ |
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _FSL_SECBOOT_ERR_H |
||||
#define _FSL_SECBOOT_ERR_H |
||||
|
||||
#define ERROR_ESBC_PAMU_INIT 0x100000 |
||||
#define ERROR_ESBC_SEC_RESET 0x200000 |
||||
#define ERROR_ESBC_SEC_INIT 0x400000 |
||||
#define ERROR_ESBC_SEC_DEQ 0x800000 |
||||
#define ERROR_ESBC_SEC_DEQ_TO 0x1000000 |
||||
#define ERROR_ESBC_SEC_ENQ 0x2000000 |
||||
#define ERROR_ESBC_SEC_JOBQ_STATUS 0x4000000 |
||||
#define ERROR_ESBC_CLIENT_CPUID_NO_MATCH 0x1 |
||||
#define ERROR_ESBC_CLIENT_HDR_LOC 0x2 |
||||
#define ERROR_ESBC_CLIENT_HEADER_BARKER 0x4 |
||||
#define ERROR_ESBC_CLIENT_HEADER_KEY_LEN 0x8 |
||||
#define ERROR_ESBC_CLIENT_HEADER_SIG_LEN 0x10 |
||||
#define ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED 0x11 |
||||
#define ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY 0x12 |
||||
#define ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM 0x13 |
||||
#define ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN 0x14 |
||||
#define ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED 0x15 |
||||
#define ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY 0x16 |
||||
#define ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM 0x17 |
||||
#define ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN 0x18 |
||||
#define ERROR_IE_TABLE_NOT_FOUND 0x19 |
||||
#define ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN 0x20 |
||||
#define ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1 0x40 |
||||
#define ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2 0x80 |
||||
#define ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD 0x100 |
||||
#define ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP 0x200 |
||||
#define ERROR_ESBC_CLIENT_HASH_COMPARE_KEY 0x400 |
||||
#define ERROR_ESBC_CLIENT_HASH_COMPARE_EM 0x800 |
||||
#define ERROR_ESBC_CLIENT_SSM_TRUSTSTS 0x1000 |
||||
#define ERROR_ESBC_CLIENT_BAD_ADDRESS 0x2000 |
||||
#define ERROR_ESBC_CLIENT_MISC 0x4000 |
||||
#define ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD 0x8000 |
||||
#define ERROR_ESBC_CLIENT_HEADER_SG 0x10000 |
||||
#define ERROR_ESBC_CLIENT_HEADER_IMG_SIZE 0x20000 |
||||
#define ERROR_ESBC_WRONG_CMD 0x40000 |
||||
#define ERROR_ESBC_MISSING_BOOTM 0x80000 |
||||
#define ERROR_ESBC_CLIENT_MAX 0x0 |
||||
|
||||
struct fsl_secboot_errcode { |
||||
int errcode; |
||||
const char *name; |
||||
}; |
||||
|
||||
static const struct fsl_secboot_errcode fsl_secboot_errcodes[] = { |
||||
{ ERROR_ESBC_PAMU_INIT, |
||||
"Error in initializing PAMU"}, |
||||
{ ERROR_ESBC_SEC_RESET, |
||||
"Error in resetting Job ring of SEC"}, |
||||
{ ERROR_ESBC_SEC_INIT, |
||||
"Error in initializing SEC"}, |
||||
{ ERROR_ESBC_SEC_ENQ, |
||||
"Error in enqueue operation by SEC"}, |
||||
{ ERROR_ESBC_SEC_DEQ_TO, |
||||
"Dequeue operation by SEC is timed out"}, |
||||
{ ERROR_ESBC_SEC_DEQ, |
||||
"Error in dequeue operation by SEC"}, |
||||
{ ERROR_ESBC_SEC_JOBQ_STATUS, |
||||
"Error in status of the job submitted to SEC"}, |
||||
{ ERROR_ESBC_CLIENT_CPUID_NO_MATCH, |
||||
"Current core is not boot core i.e core0" }, |
||||
{ ERROR_ESBC_CLIENT_HDR_LOC, |
||||
"Header address not in allowed memory range" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_BARKER, |
||||
"Wrong barker code in header" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_KEY_LEN, |
||||
"Wrong public key length in header" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_SIG_LEN, |
||||
"Wrong signature length in header" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN, |
||||
"Public key length not twice of signature length" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1, |
||||
"Public key Modulus most significant bit not set" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2, |
||||
"Public key Modulus in header not odd" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD, |
||||
"Signature not less than modulus" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP, |
||||
"Entry point not in allowed space or one of the SG entries" }, |
||||
{ ERROR_ESBC_CLIENT_HASH_COMPARE_KEY, |
||||
"Public key hash comparison failed" }, |
||||
{ ERROR_ESBC_CLIENT_HASH_COMPARE_EM, |
||||
"RSA verification failed" }, |
||||
{ ERROR_ESBC_CLIENT_SSM_TRUSTSTS, |
||||
"SNVS not in TRUSTED state" }, |
||||
{ ERROR_ESBC_CLIENT_BAD_ADDRESS, |
||||
"Bad address error" }, |
||||
{ ERROR_ESBC_CLIENT_MISC, |
||||
"Miscallaneous error" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_SG, |
||||
"No SG support" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_IMG_SIZE, |
||||
"Invalid Image size" }, |
||||
{ ERROR_ESBC_WRONG_CMD, |
||||
"Unknown cmd/Wrong arguments. Core in infinite loop"}, |
||||
{ ERROR_ESBC_MISSING_BOOTM, |
||||
"Bootm command missing from bootscript" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED, |
||||
"Selected key is revoked" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY, |
||||
"Wrong key entry" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM, |
||||
"Wrong key is selected" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN, |
||||
"Wrong srk public key len in header" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED, |
||||
"Selected IE key is revoked" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY, |
||||
"Wrong key entry in IE Table" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM, |
||||
"Wrong IE key is selected" }, |
||||
{ ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN, |
||||
"Wrong IE public key len in header" }, |
||||
{ ERROR_IE_TABLE_NOT_FOUND, |
||||
"Information about IE Table missing" }, |
||||
{ ERROR_ESBC_CLIENT_MAX, "NULL" } |
||||
}; |
||||
|
||||
void fsl_secboot_handle_error(int error); |
||||
#endif |
@ -0,0 +1,85 @@ |
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _FSL_SFP_SNVS_ |
||||
#define _FSL_SFP_SNVS_ |
||||
|
||||
#include <common.h> |
||||
#include <config.h> |
||||
#include <asm/io.h> |
||||
|
||||
#ifdef CONFIG_SYS_FSL_SRK_LE |
||||
#define srk_in32(a) in_le32(a) |
||||
#else |
||||
#define srk_in32(a) in_be32(a) |
||||
#endif |
||||
|
||||
#ifdef CONFIG_SYS_FSL_SFP_LE |
||||
#define sfp_in32(a) in_le32(a) |
||||
#define sfp_out32(a, v) out_le32(a, v) |
||||
#define sfp_in16(a) in_le16(a) |
||||
#elif defined(CONFIG_SYS_FSL_SFP_BE) |
||||
#define sfp_in32(a) in_be32(a) |
||||
#define sfp_out32(a, v) out_be32(a, v) |
||||
#define sfp_in16(a) in_be16(a) |
||||
#else |
||||
#error Neither CONFIG_SYS_FSL_SFP_LE nor CONFIG_SYS_FSL_SFP_BE is defined |
||||
#endif |
||||
|
||||
/* Number of SRKH registers */ |
||||
#define NUM_SRKH_REGS 8 |
||||
|
||||
#ifdef CONFIG_SYS_FSL_SFP_VER_3_2 |
||||
struct ccsr_sfp_regs { |
||||
u32 ospr; /* 0x200 */ |
||||
u32 ospr1; /* 0x204 */ |
||||
u32 reserved1[4]; |
||||
u32 fswpr; /* 0x218 FSL Section Write Protect */ |
||||
u32 fsl_uid; /* 0x21c FSL UID 0 */ |
||||
u32 fsl_uid_1; /* 0x220 FSL UID 0 */ |
||||
u32 reserved2[12]; |
||||
u32 srk_hash[8]; /* 0x254 Super Root Key Hash */ |
||||
u32 oem_uid; /* 0x274 OEM UID 0*/ |
||||
u32 oem_uid_1; /* 0x278 OEM UID 1*/ |
||||
u32 oem_uid_2; /* 0x27c OEM UID 2*/ |
||||
u32 oem_uid_3; /* 0x280 OEM UID 3*/ |
||||
u32 oem_uid_4; /* 0x284 OEM UID 4*/ |
||||
u32 reserved3[8]; |
||||
}; |
||||
#elif defined(CONFIG_SYS_FSL_SFP_VER_3_0) |
||||
struct ccsr_sfp_regs { |
||||
u32 ospr; /* 0x200 */ |
||||
u32 reserved0[14]; |
||||
u32 srk_hash[NUM_SRKH_REGS]; /* 0x23c Super Root Key Hash */ |
||||
u32 oem_uid; /* 0x9c OEM Unique ID */ |
||||
u8 reserved2[0x04]; |
||||
u32 ovpr; /* 0xA4 Intent To Secure */ |
||||
u8 reserved4[0x08]; |
||||
u32 fsl_uid; /* 0xB0 FSL Unique ID */ |
||||
u8 reserved5[0x04]; |
||||
u32 fsl_spfr0; /* Scratch Pad Fuse Register 0 */ |
||||
u32 fsl_spfr1; /* Scratch Pad Fuse Register 1 */ |
||||
|
||||
}; |
||||
#else |
||||
struct ccsr_sfp_regs { |
||||
u8 reserved0[0x40]; |
||||
u32 ospr; /* 0x40 OEM Security Policy Register */ |
||||
u8 reserved2[0x38]; |
||||
u32 srk_hash[8]; /* 0x7c Super Root Key Hash */ |
||||
u32 oem_uid; /* 0x9c OEM Unique ID */ |
||||
u8 reserved4[0x4]; |
||||
u32 ovpr; /* 0xA4 OEM Validation Policy Register */ |
||||
u8 reserved8[0x8]; |
||||
u32 fsl_uid; /* 0xB0 FSL Unique ID */ |
||||
}; |
||||
#endif |
||||
#define ITS_MASK 0x00000004 |
||||
#define ITS_BIT 2 |
||||
#define OSPR_KEY_REVOC_SHIFT 13 |
||||
#define OSPR_KEY_REVOC_MASK 0x0000e000 |
||||
|
||||
#endif |
@ -0,0 +1,199 @@ |
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _FSL_VALIDATE_H_ |
||||
#define _FSL_VALIDATE_H_ |
||||
|
||||
#include <fsl_sec.h> |
||||
#include <fsl_sec_mon.h> |
||||
#include <command.h> |
||||
#include <linux/types.h> |
||||
|
||||
#define WORD_SIZE 4 |
||||
|
||||
/* Minimum and maximum size of RSA signature length in bits */ |
||||
#define KEY_SIZE 4096 |
||||
#define KEY_SIZE_BYTES (KEY_SIZE/8) |
||||
#define KEY_SIZE_WORDS (KEY_SIZE_BYTES/(WORD_SIZE)) |
||||
|
||||
extern struct jobring jr; |
||||
|
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
/* Srk table and key revocation check */ |
||||
#define SRK_FLAG 0x01 |
||||
#define UNREVOCABLE_KEY 4 |
||||
#define ALIGN_REVOC_KEY 3 |
||||
#define MAX_KEY_ENTRIES 4 |
||||
#endif |
||||
|
||||
/* Barker code size in bytes */ |
||||
#define ESBC_BARKER_LEN 4 /* barker code length in ESBC uboot client */ |
||||
/* header */ |
||||
|
||||
/* No-error return values */ |
||||
#define ESBC_VALID_HDR 0 /* header is valid */ |
||||
|
||||
/* Maximum number of SG entries allowed */ |
||||
#define MAX_SG_ENTRIES 8 |
||||
|
||||
/*
|
||||
* ESBC uboot client header structure. |
||||
* The struct contain the following fields |
||||
* barker code |
||||
* public key offset |
||||
* pub key length |
||||
* signature offset |
||||
* length of the signature |
||||
* ptr to SG table |
||||
* no of entries in SG table |
||||
* esbc ptr |
||||
* size of esbc |
||||
* esbc entry point |
||||
* Scatter gather flag |
||||
* UID flag |
||||
* FSL UID |
||||
* OEM UID |
||||
* Here, pub key is modulus concatenated with exponent |
||||
* of equal length |
||||
*/ |
||||
struct fsl_secboot_img_hdr { |
||||
u8 barker[ESBC_BARKER_LEN]; /* barker code */ |
||||
union { |
||||
u32 pkey; /* public key offset */ |
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
u32 srk_tbl_off; |
||||
#endif |
||||
}; |
||||
|
||||
union { |
||||
u32 key_len; /* pub key length in bytes */ |
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
struct { |
||||
u32 srk_table_flag:8; |
||||
u32 srk_sel:8; |
||||
u32 num_srk:16; |
||||
} len_kr; |
||||
#endif |
||||
}; |
||||
|
||||
u32 psign; /* signature offset */ |
||||
u32 sign_len; /* length of the signature in bytes */ |
||||
union { |
||||
struct fsl_secboot_sg_table *psgtable; /* ptr to SG table */ |
||||
u8 *pimg; /* ptr to ESBC client image */ |
||||
}; |
||||
union { |
||||
u32 sg_entries; /* no of entries in SG table */ |
||||
u32 img_size; /* ESBC client image size in bytes */ |
||||
}; |
||||
ulong img_start; /* ESBC client entry point */ |
||||
u32 sg_flag; /* Scatter gather flag */ |
||||
u32 uid_flag; |
||||
u32 fsl_uid_0; |
||||
u32 oem_uid_0; |
||||
u32 reserved1[2]; |
||||
u32 fsl_uid_1; |
||||
u32 oem_uid_1; |
||||
u32 reserved2[2]; |
||||
u32 ie_flag; |
||||
u32 ie_key_sel; |
||||
}; |
||||
|
||||
#if defined(CONFIG_FSL_ISBC_KEY_EXT) |
||||
struct ie_key_table { |
||||
u32 key_len; |
||||
u8 pkey[2 * KEY_SIZE_BYTES]; |
||||
}; |
||||
|
||||
struct ie_key_info { |
||||
uint32_t key_revok; |
||||
uint32_t num_keys; |
||||
struct ie_key_table ie_key_tbl[32]; |
||||
}; |
||||
#endif |
||||
|
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
struct srk_table { |
||||
u32 key_len; |
||||
u8 pkey[2 * KEY_SIZE_BYTES]; |
||||
}; |
||||
#endif |
||||
|
||||
/*
|
||||
* SG table. |
||||
*/ |
||||
#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET) |
||||
/*
|
||||
* This struct contains the following fields |
||||
* length of the segment |
||||
* source address |
||||
*/ |
||||
struct fsl_secboot_sg_table { |
||||
u32 len; /* length of the segment in bytes */ |
||||
ulong src_addr; /* ptr to the data segment */ |
||||
}; |
||||
#else |
||||
/*
|
||||
* This struct contains the following fields |
||||
* length of the segment |
||||
* Destination Target ID |
||||
* source address |
||||
* destination address |
||||
*/ |
||||
struct fsl_secboot_sg_table { |
||||
u32 len; |
||||
u32 trgt_id; |
||||
ulong src_addr; |
||||
ulong dst_addr; |
||||
}; |
||||
#endif |
||||
|
||||
/*
|
||||
* ESBC private structure. |
||||
* Private structure used by ESBC to store following fields |
||||
* ESBC client key |
||||
* ESBC client key hash |
||||
* ESBC client Signature |
||||
* Encoded hash recovered from signature |
||||
* Encoded hash of ESBC client header plus ESBC client image |
||||
*/ |
||||
struct fsl_secboot_img_priv { |
||||
uint32_t hdr_location; |
||||
ulong ie_addr; |
||||
u32 key_len; |
||||
struct fsl_secboot_img_hdr hdr; |
||||
|
||||
u8 img_key[2 * KEY_SIZE_BYTES]; /* ESBC client key */ |
||||
u8 img_key_hash[32]; /* ESBC client key hash */ |
||||
|
||||
#ifdef CONFIG_KEY_REVOCATION |
||||
struct srk_table srk_tbl[MAX_KEY_ENTRIES]; |
||||
#endif |
||||
u8 img_sign[KEY_SIZE_BYTES]; /* ESBC client signature */ |
||||
|
||||
u8 img_encoded_hash[KEY_SIZE_BYTES]; /* EM wrt RSA PKCSv1.5 */ |
||||
/* Includes hash recovered after
|
||||
* signature verification |
||||
*/ |
||||
|
||||
u8 img_encoded_hash_second[KEY_SIZE_BYTES];/* EM' wrt RSA PKCSv1.5 */ |
||||
/* Includes hash of
|
||||
* ESBC client header plus |
||||
* ESBC client image |
||||
*/ |
||||
|
||||
struct fsl_secboot_sg_table sgtbl[MAX_SG_ENTRIES]; /* SG table */ |
||||
u32 ehdrloc; /* ESBC client location */ |
||||
}; |
||||
|
||||
int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc, |
||||
char * const argv[]); |
||||
int fsl_secboot_blob_encap(cmd_tbl_t *cmdtp, int flag, int argc, |
||||
char * const argv[]); |
||||
int fsl_secboot_blob_decap(cmd_tbl_t *cmdtp, int flag, int argc, |
||||
char * const argv[]); |
||||
|
||||
#endif |
Loading…
Reference in new issue