mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 18:14:24 +00:00
Merge changes from topic "paulliu-imx8m-eventlog" into integration
* changes: docs(imx8m): update for measured boot for imx8mm feat(plat/imx/imx8m/imx8mm): add support for measured boot
This commit is contained in:
commit
1776d4091b
6 changed files with 329 additions and 1 deletions
|
@ -60,3 +60,11 @@ BL2 will be in the FIT image and SPL will verify it.
|
|||
All of the BL3x will be put in the FIP image. BL2 will verify them.
|
||||
In U-boot we turn on the UEFI secure boot features so it can verify
|
||||
grub. And we use grub to verify linux kernel.
|
||||
|
||||
Measured Boot
|
||||
-------------
|
||||
|
||||
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.
|
||||
|
|
200
plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
Normal file
200
plat/imx/imx8m/imx8m_dyn_cfg_helpers.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright (c) 2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2022, Linaro.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#if MEASURED_BOOT
|
||||
#include <common/desc_image_load.h>
|
||||
#endif
|
||||
#include <common/fdt_wrappers.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#define DTB_PROP_HW_LOG_ADDR "tpm_event_log_addr"
|
||||
#define DTB_PROP_HW_LOG_SIZE "tpm_event_log_size"
|
||||
|
||||
#if MEASURED_BOOT
|
||||
|
||||
static int imx8m_event_log_fdt_init_overlay(uintptr_t dt_base, int dt_size)
|
||||
{
|
||||
int ret;
|
||||
int offset;
|
||||
void *dtb = (void *)dt_base;
|
||||
|
||||
ret = fdt_create_empty_tree(dtb, dt_size);
|
||||
if (ret < 0) {
|
||||
ERROR("cannot create empty dtb tree: %s\n",
|
||||
fdt_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
offset = fdt_path_offset(dtb, "/");
|
||||
if (offset < 0) {
|
||||
ERROR("cannot find root of the tree: %s\n",
|
||||
fdt_strerror(offset));
|
||||
return offset;
|
||||
}
|
||||
|
||||
offset = fdt_add_subnode(dtb, offset, "fragment@0");
|
||||
if (offset < 0) {
|
||||
ERROR("cannot add fragment node: %s\n",
|
||||
fdt_strerror(offset));
|
||||
return offset;
|
||||
}
|
||||
|
||||
ret = fdt_setprop_string(dtb, offset, "target-path", "/");
|
||||
if (ret < 0) {
|
||||
ERROR("cannot set target-path property: %s\n",
|
||||
fdt_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
offset = fdt_add_subnode(dtb, offset, "__overlay__");
|
||||
if (offset < 0) {
|
||||
ERROR("cannot add __overlay__ node: %s\n",
|
||||
fdt_strerror(offset));
|
||||
return ret;
|
||||
}
|
||||
|
||||
offset = fdt_add_subnode(dtb, offset, "tpm_event_log");
|
||||
if (offset < 0) {
|
||||
ERROR("cannot add tpm_event_log node: %s\n",
|
||||
fdt_strerror(offset));
|
||||
return offset;
|
||||
}
|
||||
|
||||
ret = fdt_setprop_string(dtb, offset, "compatible",
|
||||
"arm,tpm_event_log");
|
||||
if (ret < 0) {
|
||||
ERROR("cannot set compatible property: %s\n",
|
||||
fdt_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fdt_setprop_u64(dtb, offset, "tpm_event_log_addr", 0);
|
||||
if (ret < 0) {
|
||||
ERROR("cannot set tpm_event_log_addr property: %s\n",
|
||||
fdt_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fdt_setprop_u32(dtb, offset, "tpm_event_log_size", 0);
|
||||
if (ret < 0) {
|
||||
ERROR("cannot set tpm_event_log_size property: %s\n",
|
||||
fdt_strerror(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the Event Log address and its size in the DTB.
|
||||
*
|
||||
* This function is supposed to be called only by BL2.
|
||||
*
|
||||
* Returns:
|
||||
* 0 = success
|
||||
* < 0 = error
|
||||
*/
|
||||
static int imx8m_set_event_log_info(uintptr_t config_base,
|
||||
uintptr_t log_addr, size_t log_size)
|
||||
{
|
||||
/* As libfdt uses void *, we can't avoid this cast */
|
||||
void *dtb = (void *)config_base;
|
||||
const char *compatible_tpm = "arm,tpm_event_log";
|
||||
uint64_t base = cpu_to_fdt64(log_addr);
|
||||
uint32_t sz = cpu_to_fdt32(log_size);
|
||||
int err, node;
|
||||
|
||||
err = fdt_open_into(dtb, dtb, PLAT_IMX8M_DTO_MAX_SIZE);
|
||||
if (err < 0) {
|
||||
ERROR("Invalid Device Tree at %p: error %d\n", dtb, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that the DTB is valid, before attempting to write to it,
|
||||
* and get the DTB root node.
|
||||
*/
|
||||
|
||||
/* Check if the pointer to DT is correct */
|
||||
err = fdt_check_header(dtb);
|
||||
if (err < 0) {
|
||||
WARN("Invalid DTB file passed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the TPM node in device tree.
|
||||
*/
|
||||
node = fdt_node_offset_by_compatible(dtb, -1, compatible_tpm);
|
||||
if (node < 0) {
|
||||
ERROR("The compatible property '%s' not%s", compatible_tpm,
|
||||
" found in the config\n");
|
||||
return node;
|
||||
}
|
||||
|
||||
err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_ADDR, &base, 8);
|
||||
if (err < 0) {
|
||||
ERROR("Failed to add log addr err %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = fdt_setprop(dtb, node, DTB_PROP_HW_LOG_SIZE, &sz, 4);
|
||||
if (err < 0) {
|
||||
ERROR("Failed to add log addr err %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = fdt_pack(dtb);
|
||||
if (err < 0) {
|
||||
ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that the info written to the DTB is visible
|
||||
* to other images.
|
||||
*/
|
||||
flush_dcache_range(config_base, fdt_totalsize(dtb));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function writes the Event Log address and its size
|
||||
* in the QEMU DTB.
|
||||
*
|
||||
* This function is supposed to be called only by BL2.
|
||||
*
|
||||
* Returns:
|
||||
* 0 = success
|
||||
* < 0 = error
|
||||
*/
|
||||
int imx8m_set_nt_fw_info(size_t log_size, uintptr_t *ns_log_addr)
|
||||
{
|
||||
uintptr_t ns_addr;
|
||||
int err;
|
||||
|
||||
assert(ns_log_addr != NULL);
|
||||
|
||||
ns_addr = PLAT_IMX8M_DTO_BASE + PLAT_IMX8M_DTO_MAX_SIZE;
|
||||
|
||||
imx8m_event_log_fdt_init_overlay(PLAT_IMX8M_DTO_BASE,
|
||||
PLAT_IMX8M_DTO_MAX_SIZE);
|
||||
|
||||
/* Write the Event Log address and its size in the DTB */
|
||||
err = imx8m_set_event_log_info(PLAT_IMX8M_DTO_BASE,
|
||||
ns_addr, log_size);
|
||||
|
||||
/* Return Event Log address in Non-secure memory */
|
||||
*ns_log_addr = (err < 0) ? 0UL : ns_addr;
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* MEASURED_BOOT */
|
85
plat/imx/imx8m/imx8m_measured_boot.c
Normal file
85
plat/imx/imx8m/imx8m_measured_boot.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2022, Linaro.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "./include/imx8m_measured_boot.h"
|
||||
#include <drivers/measured_boot/event_log/event_log.h>
|
||||
#include <plat/arm/common/plat_arm.h>
|
||||
|
||||
/* Event Log data */
|
||||
static uint8_t event_log[PLAT_IMX_EVENT_LOG_MAX_SIZE];
|
||||
|
||||
/* FVP table with platform specific image IDs, names and PCRs */
|
||||
static const event_log_metadata_t imx8m_event_log_metadata[] = {
|
||||
{ BL31_IMAGE_ID, EVLOG_BL31_STRING, PCR_0 },
|
||||
{ BL32_IMAGE_ID, EVLOG_BL32_STRING, PCR_0 },
|
||||
{ BL32_EXTRA1_IMAGE_ID, EVLOG_BL32_EXTRA1_STRING, PCR_0 },
|
||||
{ BL32_EXTRA2_IMAGE_ID, EVLOG_BL32_EXTRA2_STRING, PCR_0 },
|
||||
{ BL33_IMAGE_ID, EVLOG_BL33_STRING, PCR_0 },
|
||||
{ EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */
|
||||
};
|
||||
|
||||
const event_log_metadata_t *plat_event_log_get_metadata(void)
|
||||
{
|
||||
return imx8m_event_log_metadata;
|
||||
}
|
||||
|
||||
int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data)
|
||||
{
|
||||
/* Calculate image hash and record data in Event Log */
|
||||
int err = event_log_measure_and_record(image_data->image_base,
|
||||
image_data->image_size,
|
||||
image_id);
|
||||
if (err != 0) {
|
||||
ERROR("%s%s image id %u (%i)\n",
|
||||
"Failed to ", "record", image_id, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bl2_plat_mboot_init(void)
|
||||
{
|
||||
event_log_init(event_log, event_log + sizeof(event_log));
|
||||
event_log_write_header();
|
||||
}
|
||||
|
||||
void bl2_plat_mboot_finish(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
/* Event Log address in Non-Secure memory */
|
||||
uintptr_t ns_log_addr;
|
||||
|
||||
/* Event Log filled size */
|
||||
size_t event_log_cur_size;
|
||||
|
||||
event_log_cur_size = event_log_get_cur_size(event_log);
|
||||
|
||||
rc = imx8m_set_nt_fw_info(event_log_cur_size, &ns_log_addr);
|
||||
if (rc != 0) {
|
||||
ERROR("%s(): Unable to update %s_FW_CONFIG\n",
|
||||
__func__, "NT");
|
||||
/*
|
||||
* It is a fatal error because on i.MX U-boot assumes that
|
||||
* a valid event log exists and will use it to record the
|
||||
* measurements into the fTPM.
|
||||
*/
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Copy Event Log to Non-secure memory */
|
||||
(void)memcpy((void *)ns_log_addr, (const void *)event_log,
|
||||
event_log_cur_size);
|
||||
|
||||
/* Ensure that the Event Log is visible in Non-secure memory */
|
||||
flush_dcache_range(ns_log_addr, event_log_cur_size);
|
||||
|
||||
dump_event_log((uint8_t *)event_log, event_log_cur_size);
|
||||
}
|
|
@ -152,3 +152,7 @@
|
|||
#define MAX_IO_HANDLES 3U
|
||||
#define MAX_IO_DEVICES 2U
|
||||
#define MAX_IO_BLOCK_DEVICES 1U
|
||||
|
||||
#define PLAT_IMX8M_DTO_BASE 0x53000000
|
||||
#define PLAT_IMX8M_DTO_MAX_SIZE 0x1000
|
||||
#define PLAT_IMX_EVENT_LOG_MAX_SIZE UL(0x400)
|
||||
|
|
|
@ -8,11 +8,14 @@ PLAT_INCLUDES := -Iplat/imx/common/include \
|
|||
-Iplat/imx/imx8m/include \
|
||||
-Iplat/imx/imx8m/imx8mm/include \
|
||||
-Idrivers/imx/usdhc \
|
||||
-Iinclude/common/tbbr
|
||||
-Iinclude/common/tbbr \
|
||||
-Iinclude/lib/libfdt
|
||||
|
||||
# Include GICv3 driver files
|
||||
include drivers/arm/gic/v3/gicv3.mk
|
||||
|
||||
include lib/libfdt/libfdt.mk
|
||||
|
||||
IMX_GIC_SOURCES := ${GICV3_SOURCES} \
|
||||
plat/common/plat_gicv3.c \
|
||||
plat/common/plat_psci_common.c \
|
||||
|
@ -43,6 +46,7 @@ BL31_SOURCES += plat/imx/common/imx8_helpers.S \
|
|||
|
||||
ifeq (${NEED_BL2},yes)
|
||||
BL2_SOURCES += common/desc_image_load.c \
|
||||
common/fdt_wrappers.c \
|
||||
plat/imx/common/imx8_helpers.S \
|
||||
plat/imx/common/imx_uart_console.S \
|
||||
plat/imx/imx8m/imx8mm/imx8mm_bl2_el3_setup.c \
|
||||
|
@ -148,3 +152,14 @@ $(eval $(call add_define,IMX_BOOT_UART_BASE))
|
|||
|
||||
EL3_EXCEPTION_HANDLING := 1
|
||||
SDEI_SUPPORT := 1
|
||||
|
||||
ifeq (${MEASURED_BOOT},1)
|
||||
MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk
|
||||
$(info Including ${MEASURED_BOOT_MK})
|
||||
include ${MEASURED_BOOT_MK}
|
||||
|
||||
BL2_SOURCES += plat/imx/imx8m/imx8m_measured_boot.c \
|
||||
plat/imx/imx8m/imx8m_dyn_cfg_helpers.c \
|
||||
${EVENT_LOG_SOURCES}
|
||||
|
||||
endif
|
||||
|
|
16
plat/imx/imx8m/include/imx8m_measured_boot.h
Normal file
16
plat/imx/imx8m/include/imx8m_measured_boot.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Linaro
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef IMX8M_MEASURED_BOOT_H
|
||||
#define IMX8M_MEASURED_BOOT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
|
||||
int imx8m_set_nt_fw_info(size_t log_size, uintptr_t *ns_log_addr);
|
||||
|
||||
#endif /* IMX8M_MEASURED_BOOT_H */
|
Loading…
Add table
Reference in a new issue