imx: hab: Check if CSF is valid before authenticating image
For proper authentication the HAB code must check if the CSF is valid. Users must call the csf_is_valid() function to parse the CSF prior to authenticating any additional images. The function will return a failure if any of the following invalid conditions are met: - CSF pointer is NULL - CSF Header does not exist - CSF does not lie within the image bounds - CSF command length zero Signed-off-by: Utkarsh Gupta <utkarsh.gupta@nxp.com> Signed-off-by: Breno Lima <breno.lima@nxp.com> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
This commit is contained in:
parent
8c4037a09a
commit
ed286bc80e
@ -38,6 +38,12 @@ struct ivt {
|
|||||||
uint32_t reserved2; /* Reserved should be zero */
|
uint32_t reserved2; /* Reserved should be zero */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct __packed hab_hdr {
|
||||||
|
u8 tag; /* Tag field */
|
||||||
|
u8 len[2]; /* Length field in bytes (big-endian) */
|
||||||
|
u8 par; /* Parameters field */
|
||||||
|
};
|
||||||
|
|
||||||
/* -------- start of HAB API updates ------------*/
|
/* -------- start of HAB API updates ------------*/
|
||||||
/* The following are taken from HAB4 SIS */
|
/* The following are taken from HAB4 SIS */
|
||||||
|
|
||||||
@ -182,6 +188,8 @@ typedef void hapi_clock_init_t(void);
|
|||||||
#define HAB_CID_ROM 0 /**< ROM Caller ID */
|
#define HAB_CID_ROM 0 /**< ROM Caller ID */
|
||||||
#define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
|
#define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
|
||||||
|
|
||||||
|
#define HAB_CMD_HDR 0xD4 /* CSF Header */
|
||||||
|
|
||||||
#define IVT_SIZE 0x20
|
#define IVT_SIZE 0x20
|
||||||
#define CSF_PAD_SIZE 0x2000
|
#define CSF_PAD_SIZE 0x2000
|
||||||
|
|
||||||
|
@ -453,6 +453,83 @@ U_BOOT_CMD(
|
|||||||
|
|
||||||
#endif /* !defined(CONFIG_SPL_BUILD) */
|
#endif /* !defined(CONFIG_SPL_BUILD) */
|
||||||
|
|
||||||
|
/* Get CSF Header length */
|
||||||
|
static int get_hab_hdr_len(struct hab_hdr *hdr)
|
||||||
|
{
|
||||||
|
return (size_t)((hdr->len[0] << 8) + (hdr->len[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether addr lies between start and
|
||||||
|
* end and is within the length of the image
|
||||||
|
*/
|
||||||
|
static int chk_bounds(u8 *addr, size_t bytes, u8 *start, u8 *end)
|
||||||
|
{
|
||||||
|
size_t csf_size = (size_t)((end + 1) - addr);
|
||||||
|
|
||||||
|
return (addr && (addr >= start) && (addr <= end) &&
|
||||||
|
(csf_size >= bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get Length of each command in CSF */
|
||||||
|
static int get_csf_cmd_hdr_len(u8 *csf_hdr)
|
||||||
|
{
|
||||||
|
if (*csf_hdr == HAB_CMD_HDR)
|
||||||
|
return sizeof(struct hab_hdr);
|
||||||
|
|
||||||
|
return get_hab_hdr_len((struct hab_hdr *)csf_hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if CSF is valid */
|
||||||
|
static bool csf_is_valid(struct ivt *ivt, ulong start_addr, size_t bytes)
|
||||||
|
{
|
||||||
|
u8 *start = (u8 *)start_addr;
|
||||||
|
u8 *csf_hdr;
|
||||||
|
u8 *end;
|
||||||
|
|
||||||
|
size_t csf_hdr_len;
|
||||||
|
size_t cmd_hdr_len;
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
|
if (bytes != 0)
|
||||||
|
end = start + bytes - 1;
|
||||||
|
else
|
||||||
|
end = start;
|
||||||
|
|
||||||
|
/* Verify if CSF pointer content is zero */
|
||||||
|
if (!ivt->csf) {
|
||||||
|
puts("Error: CSF pointer is NULL\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
csf_hdr = (u8 *)ivt->csf;
|
||||||
|
|
||||||
|
/* Verify if CSF Header exist */
|
||||||
|
if (*csf_hdr != HAB_CMD_HDR) {
|
||||||
|
puts("Error: CSF header command not found\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
csf_hdr_len = get_hab_hdr_len((struct hab_hdr *)csf_hdr);
|
||||||
|
|
||||||
|
/* Check if the CSF lies within the image bounds */
|
||||||
|
if (!chk_bounds(csf_hdr, csf_hdr_len, start, end)) {
|
||||||
|
puts("Error: CSF lies outside the image bounds\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
cmd_hdr_len = get_csf_cmd_hdr_len(&csf_hdr[offset]);
|
||||||
|
if (!cmd_hdr_len) {
|
||||||
|
puts("Error: Invalid command length\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
offset += cmd_hdr_len;
|
||||||
|
|
||||||
|
} while (offset < csf_hdr_len);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool imx_hab_is_enabled(void)
|
bool imx_hab_is_enabled(void)
|
||||||
{
|
{
|
||||||
struct imx_sec_config_fuse_t *fuse =
|
struct imx_sec_config_fuse_t *fuse =
|
||||||
@ -525,6 +602,10 @@ int imx_hab_authenticate_image(uint32_t ddr_start, uint32_t image_size,
|
|||||||
start = ddr_start;
|
start = ddr_start;
|
||||||
bytes = image_size;
|
bytes = image_size;
|
||||||
|
|
||||||
|
/* Verify CSF */
|
||||||
|
if (!csf_is_valid(ivt, start, bytes))
|
||||||
|
goto hab_authentication_exit;
|
||||||
|
|
||||||
if (hab_rvt_entry() != HAB_SUCCESS) {
|
if (hab_rvt_entry() != HAB_SUCCESS) {
|
||||||
puts("hab entry function fail\n");
|
puts("hab entry function fail\n");
|
||||||
goto hab_exit_failure_print_status;
|
goto hab_exit_failure_print_status;
|
||||||
|
Loading…
Reference in New Issue
Block a user