Browse Source
* changes: docs(imx8m): update for measured boot for imx8mm feat(plat/imx/imx8m/imx8mm): add support for measured bootpull/1985/head
Madhukar Pappireddy
3 years ago
committed by
TrustedFirmware Code Review
6 changed files with 329 additions and 1 deletions
@ -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 */ |
@ -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); |
|||
} |
@ -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…
Reference in new issue