Merge changes from topic "imx8m-hab-support" into integration

* changes:
  docs(imx8m): update for high assurance boot
  feat(imx8m): add support for high assurance boot
  feat(imx8mp): add hab and map required memory blocks
  feat(imx8mn): add hab and map required memory blocks
  feat(imx8mm): add hab and map required memory blocks
This commit is contained in:
Sandrine Bailleux 2022-10-21 09:35:32 +02:00 committed by TrustedFirmware Code Review
commit 4e5d262345
13 changed files with 252 additions and 4 deletions

View file

@ -68,3 +68,46 @@ When setting MEASURED_BOOT=1 on imx8mm we can let TF-A generate event logs
with a DTB overlay. The overlay will be put at PLAT_IMX8M_DTO_BASE with
maximum size PLAT_IMX8M_DTO_MAX_SIZE. Then in U-boot we can apply the DTB
overlay and let U-boot to parse the event log and update the PCRs.
High Assurance Boot (HABv4)
---------------------------
All actively maintained platforms have a support for High Assurance
Boot (HABv4), which is implemented via ROM Vector Table (RVT) API to
extend the Root-of-Trust beyond the SPL. Those calls are done via SMC
and are executed in EL3, with results returned back to original caller.
Note on DRAM Memory Mapping
~~~~~~~~~~~~~~~~~~~~~~~~~~~
There is a special case of mapping the DRAM: entire DRAM available on the
platform is mapped into the EL3 with MT_RW attributes.
Mapping the entire DRAM allows the usage of 2MB block mapping in Level-2
Translation Table entries, which use less Page Table Entries (PTEs). If
Level-3 PTE mapping is used instead then additional PTEs would be required,
which leads to the increase of translation table size.
Due to the fact that the size of SRAM is limited on some platforms in the
family it should rather be avoided creating additional Level-3 mapping and
introduce more PTEs, hence the implementation uses Level-2 mapping which
maps entire DRAM space.
The reason for the MT_RW attribute mapping scheme is the fact that the SMC
API to get the status and events is called from NS world passing destination
pointers which are located in DRAM. Mapping DRAM without MT_RW permissions
causes those locations not to be filled, which in turn causing EL1&0 software
not to receive replies.
Therefore, DRAM mapping is done with MT_RW attributes, as it is required for
data exchange between EL3 and EL1&0 software.
Reference Documentation
~~~~~~~~~~~~~~~~~~~~~~~
Details on HABv4 usage and implementation could be found in following documents:
- AN4581: "i.MX Secure Boot on HABv4 Supported Devices", Rev. 4 - June 2020
- AN12263: "HABv4 RVT Guidelines and Recommendations", Rev. 1 - 06/2020
- "HABv4 API Reference Manual". This document in the part of NXP Code Signing Tool (CST) distribution.

View file

@ -59,6 +59,11 @@ static uintptr_t imx_sip_handler(unsigned int smc_fid,
case IMX_SIP_SRC:
SMC_RET1(handle, imx_src_handler(smc_fid, x1, x2, x3, handle));
break;
#endif
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
case IMX_SIP_HAB:
SMC_RET1(handle, imx_hab_handler(smc_fid, x1, x2, x3, x4));
break;
#endif
case IMX_SIP_BUILDINFO:
SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));

View file

@ -27,6 +27,17 @@
#define IMX_SIP_GET_SOC_INFO 0xC2000006
#define IMX_SIP_HAB 0xC2000007
#define IMX_SIP_HAB_AUTH_IMG 0x00
#define IMX_SIP_HAB_ENTRY 0x01
#define IMX_SIP_HAB_EXIT 0x02
#define IMX_SIP_HAB_REPORT_EVENT 0x03
#define IMX_SIP_HAB_REPORT_STATUS 0x04
#define IMX_SIP_HAB_FAILSAFE 0x05
#define IMX_SIP_HAB_CHECK_TARGET 0x06
#define IMX_SIP_HAB_GET_VERSION 0x07
#define IMX_SIP_HAB_AUTH_IMG_NO_DCD 0x08
#define IMX_SIP_WAKEUP_SRC 0xC2000009
#define IMX_SIP_WAKEUP_SRC_SCU 0x1
#define IMX_SIP_WAKEUP_SRC_IRQSTEER 0x2
@ -58,6 +69,11 @@ int imx_src_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3, void *handle);
#endif
#if defined(PLAT_imx8mm) || defined(PLAT_imx8mn) || defined(PLAT_imx8mp)
int imx_hab_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3, u_register_t x4);
#endif
#if (defined(PLAT_imx8qm) || defined(PLAT_imx8qx))
int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3);

View file

@ -32,12 +32,22 @@
#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
/*
* Note: DRAM region is mapped with entire size available and uses MT_RW
* attributes.
* See details in docs/plat/imx8m.rst "High Assurance Boot (HABv4)" section
* for explanation of this mapping scheme.
*/
static const mmap_region_t imx_mmap[] = {
MAP_REGION_FLAT(IMX_GIC_BASE, IMX_GIC_SIZE, MT_DEVICE | MT_RW),
MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW), /* AIPS map */
MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW), /* OCRAM_S */
MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW), /* DDRMIX */
MAP_REGION_FLAT(IMX_VPUMIX_BASE, IMX_VPUMIX_SIZE, MT_DEVICE | MT_RW), /* VPUMIX */
MAP_REGION_FLAT(IMX_CAAM_RAM_BASE, IMX_CAAM_RAM_SIZE, MT_MEMORY | MT_RW), /* CAMM RAM */
MAP_REGION_FLAT(IMX_NS_OCRAM_BASE, IMX_NS_OCRAM_SIZE, MT_MEMORY | MT_RW), /* NS OCRAM */
MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO), /* ROM code */
MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS), /* DRAM */
{0},
};

View file

@ -107,9 +107,16 @@
#define IMX_DDRPHY_BASE U(0x3c000000)
#define IMX_DDR_IPS_BASE U(0x3d000000)
#define IMX_DDR_IPS_SIZE U(0x1800000)
#define IMX_VPUMIX_BASE U(0x38330000)
#define IMX_VPUMIX_SIZE U(0x100000)
#define IMX_ROM_BASE U(0x0)
#define IMX_VPUMIX_BASE U(0x38330000)
#define IMX_VPUMIX_SIZE U(0x100000)
#define IMX_ROM_SIZE U(0x40000)
#define IMX_NS_OCRAM_BASE U(0x900000)
#define IMX_NS_OCRAM_SIZE U(0x20000)
#define IMX_CAAM_RAM_BASE U(0x100000)
#define IMX_CAAM_RAM_SIZE U(0x10000)
#define IMX_DRAM_BASE U(0x40000000)
#define IMX_DRAM_SIZE U(0xc0000000)
#define GPV_BASE U(0x32000000)
#define GPV_SIZE U(0x800000)

View file

@ -32,6 +32,7 @@ IMX_GIC_SOURCES := ${GICV3_SOURCES} \
BL31_SOURCES += plat/imx/common/imx8_helpers.S \
plat/imx/imx8m/gpc_common.c \
plat/imx/imx8m/imx_hab.c \
plat/imx/imx8m/imx_aipstz.c \
plat/imx/imx8m/imx_rdc.c \
plat/imx/imx8m/imx8m_csu.c \

View file

@ -32,7 +32,9 @@
#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
static const mmap_region_t imx_mmap[] = {
GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP, {0},
GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP,
CAAM_RAM_MAP, NS_OCRAM_MAP, ROM_MAP, DRAM_MAP,
{0},
};
static const struct aipstz_cfg aipstz[] = {

View file

@ -94,6 +94,13 @@
#define IMX_DDR_IPS_BASE U(0x3d000000)
#define IMX_DDR_IPS_SIZE U(0x1800000)
#define IMX_ROM_BASE U(0x0)
#define IMX_ROM_SIZE U(0x40000)
#define IMX_NS_OCRAM_BASE U(0x900000)
#define IMX_NS_OCRAM_SIZE U(0x60000)
#define IMX_CAAM_RAM_BASE U(0x100000)
#define IMX_CAAM_RAM_SIZE U(0x10000)
#define IMX_DRAM_BASE U(0x40000000)
#define IMX_DRAM_SIZE U(0xc0000000)
#define IMX_GIC_BASE PLAT_GICD_BASE
#define IMX_GIC_SIZE U(0x200000)
@ -140,5 +147,16 @@
#define AIPS_MAP MAP_REGION_FLAT(IMX_AIPS_BASE, IMX_AIPS_SIZE, MT_DEVICE | MT_RW) /* AIPS map */
#define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_DEVICE | MT_RW) /* OCRAM_S */
#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */
#define CAAM_RAM_MAP MAP_REGION_FLAT(IMX_CAAM_RAM_BASE, IMX_CAAM_RAM_SIZE, MT_MEMORY | MT_RW) /* CAMM RAM */
#define NS_OCRAM_MAP MAP_REGION_FLAT(IMX_NS_OCRAM_BASE, IMX_NS_OCRAM_SIZE, MT_MEMORY | MT_RW) /* NS OCRAM */
#define ROM_MAP MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO) /* ROM code */
/*
* Note: DRAM region is mapped with entire size available and uses MT_RW
* attributes.
* See details in docs/plat/imx8m.rst "High Assurance Boot (HABv4)" section
* for explanation of this mapping scheme.
*/
#define DRAM_MAP MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS) /* DRAM */
#endif /* platform_def.h */

View file

@ -27,6 +27,7 @@ IMX_GIC_SOURCES := ${GICV3_SOURCES} \
BL31_SOURCES += plat/imx/common/imx8_helpers.S \
plat/imx/imx8m/gpc_common.c \
plat/imx/imx8m/imx_hab.c \
plat/imx/imx8m/imx_aipstz.c \
plat/imx/imx8m/imx_rdc.c \
plat/imx/imx8m/imx8m_caam.c \

View file

@ -33,7 +33,9 @@
static const mmap_region_t imx_mmap[] = {
GIC_MAP, AIPS_MAP, OCRAM_S_MAP, DDRC_MAP,
NOC_MAP, {0},
NOC_MAP, CAAM_RAM_MAP, NS_OCRAM_MAP,
ROM_MAP, DRAM_MAP,
{0},
};
static const struct aipstz_cfg aipstz[] = {

View file

@ -111,6 +111,13 @@
#define IMX_DDR_IPS_BASE U(0x3d000000)
#define IMX_DDR_IPS_SIZE U(0x1800000)
#define IMX_ROM_BASE U(0x0)
#define IMX_ROM_SIZE U(0x40000)
#define IMX_NS_OCRAM_BASE U(0x900000)
#define IMX_NS_OCRAM_SIZE U(0x60000)
#define IMX_CAAM_RAM_BASE U(0x100000)
#define IMX_CAAM_RAM_SIZE U(0x10000)
#define IMX_DRAM_BASE U(0x40000000)
#define IMX_DRAM_SIZE U(0xc0000000)
#define IMX_GIC_BASE PLAT_GICD_BASE
#define IMX_GIC_SIZE U(0x200000)
@ -178,5 +185,16 @@
#define OCRAM_S_MAP MAP_REGION_FLAT(OCRAM_S_BASE, OCRAM_S_SIZE, MT_MEMORY | MT_RW) /* OCRAM_S */
#define DDRC_MAP MAP_REGION_FLAT(IMX_DDRPHY_BASE, IMX_DDR_IPS_SIZE, MT_DEVICE | MT_RW) /* DDRMIX */
#define NOC_MAP MAP_REGION_FLAT(IMX_NOC_BASE, IMX_NOC_SIZE, MT_DEVICE | MT_RW) /* NOC QoS */
#define CAAM_RAM_MAP MAP_REGION_FLAT(IMX_CAAM_RAM_BASE, IMX_CAAM_RAM_SIZE, MT_MEMORY | MT_RW) /* CAMM RAM */
#define NS_OCRAM_MAP MAP_REGION_FLAT(IMX_NS_OCRAM_BASE, IMX_NS_OCRAM_SIZE, MT_MEMORY | MT_RW) /* NS OCRAM */
#define ROM_MAP MAP_REGION_FLAT(IMX_ROM_BASE, IMX_ROM_SIZE, MT_MEMORY | MT_RO) /* ROM code */
/*
* Note: DRAM region is mapped with entire size available and uses MT_RW
* attributes.
* See details in docs/plat/imx8m.rst "High Assurance Boot (HABv4)" section
* for explanation of this mapping scheme.
*/
#define DRAM_MAP MAP_REGION_FLAT(IMX_DRAM_BASE, IMX_DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS) /* DRAM */
#endif /* platform_def.h */

View file

@ -28,6 +28,7 @@ IMX_GIC_SOURCES := ${GICV3_SOURCES} \
BL31_SOURCES += plat/imx/common/imx8_helpers.S \
plat/imx/imx8m/gpc_common.c \
plat/imx/imx8m/imx_hab.c \
plat/imx/imx8m/imx_aipstz.c \
plat/imx/imx8m/imx_rdc.c \
plat/imx/imx8m/imx8m_caam.c \

124
plat/imx/imx8m/imx_hab.c Normal file
View file

@ -0,0 +1,124 @@
/*
* Copyright 2017-2020 NXP
* Copyright 2022 Leica Geosystems AG
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <common/runtime_svc.h>
#include <imx_sip_svc.h>
#define HAB_CID_ATF U(2) /* TF-A Caller ID */
/* HAB Status definitions */
enum hab_status {
HAB_STS_ANY = 0x00, /* Match any status in report_event() */
HAB_FAILURE = 0x33, /* Operation failed */
HAB_WARNING = 0x69, /* Operation completed with warning */
HAB_SUCCESS = 0xf0 /* Operation completed successfully */
};
/* HAB Configuration definitions */
enum hab_config {
HAB_CFG_RETURN = 0x33, /* Field Return IC */
HAB_CFG_OPEN = 0xf0, /* Non-secure IC */
HAB_CFG_CLOSED = 0xcc /* Secure IC */
};
/* HAB State definitions */
enum hab_state {
HAB_STATE_INITIAL = 0x33, /* Initializing state (transitory) */
HAB_STATE_CHECK = 0x55, /* Check state (non-secure) */
HAB_STATE_NONSECURE = 0x66, /* Non-secure state */
HAB_STATE_TRUSTED = 0x99, /* Trusted state */
HAB_STATE_SECURE = 0xaa, /* Secure state */
HAB_STATE_FAIL_SOFT = 0xcc, /* Soft fail state */
HAB_STATE_FAIL_HARD = 0xff, /* Hard fail state (terminal) */
HAB_STATE_NONE = 0xf0 /* No security state machine */
};
/* HAB Verification Target definitions */
enum hab_target {
HAB_TGT_MEMORY = 0x0f, /* Check memory allowed list */
HAB_TGT_PERIPHERAL = 0xf0, /* Check peripheral allowed list */
HAB_TGT_ANY = 0x55 /* Check memory & peripheral allowed list */
};
/* Authenticate Image Loader Callback prototype */
typedef enum hab_status hab_loader_callback_f_t(void **, size_t *, const void *);
/*
* HAB Rom VectorTable (RVT) structure.
* This table provides function pointers into the HAB library in ROM for
* use by post-ROM boot sequence components.
* Functions are ordered in the structure below based on the offsets in ROM
* image, and shall not be changed!
* Details on API allocation offsets and function description could be
* found in following documents from NXP:
* - High Assurance Boot Version 4 Application Programming Interface
* Reference Manual (available in CST package)
* - HABv4 RVT Guidelines and Recommendations (AN12263)
*/
struct hab_rvt_api {
uint64_t hdr;
enum hab_status (*entry)(void);
enum hab_status (*exit)(void);
enum hab_status (*check_target)(enum hab_target type, const void *start, size_t bytes);
void* (*authenticate_image)(uint8_t cid, long ivt_offset, void **start,
size_t *bytes, hab_loader_callback_f_t loader);
enum hab_status (*run_dcd)(const uint8_t *dcd);
enum hab_status (*run_csf)(const uint8_t *csf, uint8_t cid, uint32_t srkmask);
enum hab_status (*assert)(long type, const void *data, uint32_t count);
enum hab_status (*report_event)(enum hab_status status, uint32_t index,
uint8_t *event, size_t *bytes);
enum hab_status (*report_status)(enum hab_config *config, enum hab_state *state);
void (*failsafe)(void);
void* (*authenticate_image_no_dcd)(uint8_t cid, long ivt_offset, void **start,
size_t *bytes, hab_loader_callback_f_t loader);
uint32_t (*get_version)(void);
enum hab_status (*authenticate_container)(uint8_t cid, long ivt_offset, void **start,
size_t *bytes, hab_loader_callback_f_t loader, uint32_t srkmask, int skip_dcd);
};
struct hab_rvt_api *g_hab_rvt_api = (struct hab_rvt_api *)HAB_RVT_BASE;
/*******************************************************************************
* Handler for servicing HAB SMC calls
******************************************************************************/
int imx_hab_handler(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
u_register_t x4)
{
switch (x1) {
case IMX_SIP_HAB_ENTRY:
return g_hab_rvt_api->entry();
case IMX_SIP_HAB_EXIT:
return g_hab_rvt_api->exit();
case IMX_SIP_HAB_CHECK_TARGET:
return g_hab_rvt_api->check_target((enum hab_target)x2,
(const void *)x3, (size_t)x4);
case IMX_SIP_HAB_AUTH_IMG:
return (unsigned long)g_hab_rvt_api->authenticate_image(HAB_CID_ATF,
x2, (void **)x3, (size_t *)x4, NULL);
case IMX_SIP_HAB_REPORT_EVENT:
return g_hab_rvt_api->report_event(HAB_FAILURE,
(uint32_t)x2, (uint8_t *)x3, (size_t *)x4);
case IMX_SIP_HAB_REPORT_STATUS:
return g_hab_rvt_api->report_status((enum hab_config *)x2,
(enum hab_state *)x3);
case IMX_SIP_HAB_FAILSAFE:
g_hab_rvt_api->failsafe();
break;
case IMX_SIP_HAB_AUTH_IMG_NO_DCD:
return (unsigned long)g_hab_rvt_api->authenticate_image_no_dcd(
HAB_CID_ATF, x2, (void **)x3, (size_t *)x4, NULL);
case IMX_SIP_HAB_GET_VERSION:
return g_hab_rvt_api->get_version();
default:
return SMC_UNK;
};
return SMC_OK;
}