Browse Source
* changes: plat/arm/board/fvp: Add support for Measured Boot TF-A: Add support for Measured Boot driver to FCONF TF-A: Add support for Measured Boot driver in BL1 and BL2 TF-A: Add Event Log for Measured Boot TF-A: Add support for Measured Boot driverpull/1979/head
joanna.farley
4 years ago
committed by
TrustedFirmware Code Review
33 changed files with 1780 additions and 75 deletions
@ -0,0 +1,35 @@ |
|||
DTB binding for Event Log properties |
|||
==================================== |
|||
|
|||
This document describes the device tree format of Event Log properties. |
|||
These properties are not related to a specific platform and can be queried |
|||
from common code. |
|||
|
|||
Dynamic configuration for Event Log |
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
Measured Boot driver expects a *tpm_event_log* node with the following field |
|||
in 'nt_fw_config' and 'tsp_fw_config' DTS files: |
|||
|
|||
- compatible [mandatory] |
|||
- value type: <string> |
|||
- Must be the string "arm,tpm_event_log". |
|||
|
|||
Then a list of properties representing Event Log configuration, which |
|||
can be used by Measured Boot driver. Each property is named according |
|||
to the information it contains: |
|||
|
|||
- tpm_event_log_sm_addr [fvp_nt_fw_config.dts with OP-TEE] |
|||
- value type: <u64> |
|||
- Event Log base address in secure memory. |
|||
|
|||
Note. Currently OP-TEE does not support reading DTBs from Secure memory |
|||
and this property should be removed when this feature is supported. |
|||
|
|||
- tpm_event_log_addr [mandatory] |
|||
- value type: <u64> |
|||
- Event Log base address in non-secure memory. |
|||
|
|||
- tpm_event_log_size [mandatory] |
|||
- value type: <u32> |
|||
- Event Log size. |
@ -0,0 +1,12 @@ |
|||
Measured Boot Driver (MBD) |
|||
========================== |
|||
|
|||
.. _measured-boot-document: |
|||
|
|||
Properties binding information |
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
|
|||
.. toctree:: |
|||
:maxdepth: 1 |
|||
|
|||
event_log |
@ -0,0 +1,406 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
#include <errno.h> |
|||
#include <string.h> |
|||
#include <arch_helpers.h> |
|||
|
|||
#include <common/bl_common.h> |
|||
#include <common/debug.h> |
|||
#include <drivers/auth/crypto_mod.h> |
|||
#include <drivers/measured_boot/event_log.h> |
|||
#include <mbedtls/md.h> |
|||
|
|||
#include <plat/common/platform.h> |
|||
|
|||
/* Event Log data */ |
|||
static uint8_t event_log[EVENT_LOG_SIZE]; |
|||
|
|||
/* End of Event Log */ |
|||
#define EVENT_LOG_END ((uintptr_t)event_log + sizeof(event_log) - 1U) |
|||
|
|||
CASSERT(sizeof(event_log) >= LOG_MIN_SIZE, assert_event_log_size); |
|||
|
|||
/* Pointer in event_log[] */ |
|||
static uint8_t *log_ptr = event_log; |
|||
|
|||
/* Pointer to measured_boot_data_t */ |
|||
const static measured_boot_data_t *plat_data_ptr; |
|||
|
|||
static uintptr_t tos_fw_config_base; |
|||
static uintptr_t nt_fw_config_base; |
|||
|
|||
/* TCG_EfiSpecIdEvent */ |
|||
static const id_event_headers_t id_event_header = { |
|||
.header = { |
|||
.pcr_index = PCR_0, |
|||
.event_type = EV_NO_ACTION, |
|||
.digest = {0}, |
|||
.event_size = (uint32_t)(sizeof(id_event_struct_t) + |
|||
(sizeof(id_event_algorithm_size_t) * |
|||
HASH_ALG_COUNT)) |
|||
}, |
|||
|
|||
.struct_header = { |
|||
.signature = TCG_ID_EVENT_SIGNATURE_03, |
|||
.platform_class = PLATFORM_CLASS_CLIENT, |
|||
.spec_version_minor = TCG_SPEC_VERSION_MINOR_TPM2, |
|||
.spec_version_major = TCG_SPEC_VERSION_MAJOR_TPM2, |
|||
.spec_errata = TCG_SPEC_ERRATA_TPM2, |
|||
.uintn_size = (uint8_t)(sizeof(unsigned int) / |
|||
sizeof(uint32_t)), |
|||
.number_of_algorithms = HASH_ALG_COUNT |
|||
} |
|||
}; |
|||
|
|||
static const event2_header_t locality_event_header = { |
|||
/*
|
|||
* All EV_NO_ACTION events SHALL set |
|||
* TCG_PCR_EVENT2.pcrIndex = 0, unless otherwise specified |
|||
*/ |
|||
.pcr_index = PCR_0, |
|||
|
|||
/*
|
|||
* All EV_NO_ACTION events SHALL set |
|||
* TCG_PCR_EVENT2.eventType = 03h |
|||
*/ |
|||
.event_type = EV_NO_ACTION, |
|||
|
|||
/*
|
|||
* All EV_NO_ACTION events SHALL set |
|||
* TCG_PCR_EVENT2.digests to all |
|||
* 0x00's for each allocated Hash algorithm |
|||
*/ |
|||
.digests = { |
|||
.count = HASH_ALG_COUNT |
|||
} |
|||
}; |
|||
|
|||
/* Platform's table with platform specific image IDs, names and PCRs */ |
|||
static const image_data_t plat_images_data[] = { |
|||
{ BL2_IMAGE_ID, BL2_STRING, PCR_0 }, /* Reserved for BL2 */ |
|||
{ INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ |
|||
}; |
|||
|
|||
static const measured_boot_data_t plat_measured_boot_data = { |
|||
plat_images_data, |
|||
NULL, /* platform_set_nt_fw_info */ |
|||
NULL /* platform_set_tos_fw_info */ |
|||
}; |
|||
|
|||
/*
|
|||
* Function retuns pointer to platform's measured_boot_data_t structure |
|||
* |
|||
* Must be overridden in the platform code |
|||
*/ |
|||
#pragma weak plat_get_measured_boot_data |
|||
|
|||
const measured_boot_data_t *plat_get_measured_boot_data(void) |
|||
{ |
|||
return &plat_measured_boot_data; |
|||
} |
|||
|
|||
/*
|
|||
* Add TCG_PCR_EVENT2 event |
|||
* |
|||
* @param[in] hash Pointer to hash data of TCG_DIGEST_SIZE bytes |
|||
* @param[in] image_ptr Pointer to image_data_t structure |
|||
* @return: |
|||
* 0 = success |
|||
* < 0 = error code |
|||
*/ |
|||
static int add_event2(const uint8_t *hash, const image_data_t *image_ptr) |
|||
{ |
|||
void *ptr = log_ptr; |
|||
uint32_t name_len; |
|||
uint32_t size_of_event; |
|||
|
|||
assert(image_ptr != NULL); |
|||
assert(image_ptr->name != NULL); |
|||
|
|||
name_len = (uint32_t)strlen(image_ptr->name) + 1U; |
|||
size_of_event = name_len + (uint32_t)EVENT2_HDR_SIZE; |
|||
|
|||
/* Check for space in Event Log buffer */ |
|||
if (((uintptr_t)ptr + size_of_event) > EVENT_LOG_END) { |
|||
ERROR("%s(): Event Log is short of memory", __func__); |
|||
return -ENOMEM; |
|||
} |
|||
|
|||
/*
|
|||
* As per TCG specifications, firmware components that are measured |
|||
* into PCR[0] must be logged in the event log using the event type |
|||
* EV_POST_CODE. |
|||
*/ |
|||
/* TCG_PCR_EVENT2.PCRIndex */ |
|||
((event2_header_t *)ptr)->pcr_index = image_ptr->pcr; |
|||
|
|||
/* TCG_PCR_EVENT2.EventType */ |
|||
((event2_header_t *)ptr)->event_type = EV_POST_CODE; |
|||
|
|||
/* TCG_PCR_EVENT2.Digests.Count */ |
|||
ptr = (uint8_t *)ptr + offsetof(event2_header_t, digests); |
|||
((tpml_digest_values *)ptr)->count = HASH_ALG_COUNT; |
|||
|
|||
/* TCG_PCR_EVENT2.Digests[] */ |
|||
ptr = (uint8_t *)ptr + offsetof(tpml_digest_values, digests); |
|||
|
|||
/* TCG_PCR_EVENT2.Digests[].AlgorithmId */ |
|||
((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; |
|||
|
|||
/* TCG_PCR_EVENT2.Digests[].Digest[] */ |
|||
ptr = (uint8_t *)ptr + offsetof(tpmt_ha, digest); |
|||
|
|||
/* Check for space in Event Log buffer */ |
|||
if (((uintptr_t)ptr + TCG_DIGEST_SIZE) > EVENT_LOG_END) { |
|||
ERROR("%s(): Event Log is short of memory", __func__); |
|||
return -ENOMEM; |
|||
} |
|||
|
|||
if (hash == NULL) { |
|||
/* Get BL2 hash from DTB */ |
|||
bl2_plat_get_hash(ptr); |
|||
} else { |
|||
/* Copy digest */ |
|||
(void)memcpy(ptr, (const void *)hash, TCG_DIGEST_SIZE); |
|||
} |
|||
|
|||
/* TCG_PCR_EVENT2.EventSize */ |
|||
ptr = (uint8_t *)ptr + TCG_DIGEST_SIZE; |
|||
((event2_data_t *)ptr)->event_size = name_len; |
|||
|
|||
/* Copy event data to TCG_PCR_EVENT2.Event */ |
|||
(void)memcpy((void *)(((event2_data_t *)ptr)->event), |
|||
(const void *)image_ptr->name, name_len); |
|||
|
|||
/* End of event data */ |
|||
log_ptr = (uint8_t *)ptr + offsetof(event2_data_t, event) + name_len; |
|||
|
|||
return 0; |
|||
} |
|||
|
|||
/*
|
|||
* Init Event Log |
|||
* |
|||
* Initialises Event Log by writing Specification ID and |
|||
* Startup Locality events. |
|||
*/ |
|||
void event_log_init(void) |
|||
{ |
|||
const char locality_signature[] = TCG_STARTUP_LOCALITY_SIGNATURE; |
|||
const uint8_t *start_ptr; |
|||
void *ptr = event_log; |
|||
|
|||
/* Get pointer to platform's measured_boot_data_t structure */ |
|||
plat_data_ptr = plat_get_measured_boot_data(); |
|||
|
|||
/*
|
|||
* Add Specification ID Event first |
|||
* |
|||
* Copy TCG_EfiSpecIDEventStruct structure header |
|||
*/ |
|||
(void)memcpy(ptr, (const void *)&id_event_header, |
|||
sizeof(id_event_header)); |
|||
ptr = (uint8_t *)ptr + sizeof(id_event_header); |
|||
|
|||
/* TCG_EfiSpecIdEventAlgorithmSize structure */ |
|||
((id_event_algorithm_size_t *)ptr)->algorithm_id = TPM_ALG_ID; |
|||
((id_event_algorithm_size_t *)ptr)->digest_size = TCG_DIGEST_SIZE; |
|||
ptr = (uint8_t *)ptr + sizeof(id_event_algorithm_size_t); |
|||
|
|||
/*
|
|||
* TCG_EfiSpecIDEventStruct.vendorInfoSize |
|||
* No vendor data |
|||
*/ |
|||
((id_event_struct_data_t *)ptr)->vendor_info_size = 0; |
|||
ptr = (uint8_t *)ptr + offsetof(id_event_struct_data_t, vendor_info); |
|||
if ((uintptr_t)ptr != ((uintptr_t)event_log + ID_EVENT_SIZE)) { |
|||
panic(); |
|||
} |
|||
|
|||
start_ptr = (uint8_t *)ptr; |
|||
|
|||
/*
|
|||
* The Startup Locality event should be placed in the log before |
|||
* any event which extends PCR[0]. |
|||
* |
|||
* Ref. TCG PC Client Platform Firmware Profile 9.4.5.3 |
|||
*/ |
|||
|
|||
/* Copy Startup Locality Event Header */ |
|||
(void)memcpy(ptr, (const void *)&locality_event_header, |
|||
sizeof(locality_event_header)); |
|||
ptr = (uint8_t *)ptr + sizeof(locality_event_header); |
|||
|
|||
/* TCG_PCR_EVENT2.Digests[].AlgorithmId */ |
|||
((tpmt_ha *)ptr)->algorithm_id = TPM_ALG_ID; |
|||
|
|||
/* TCG_PCR_EVENT2.Digests[].Digest[] */ |
|||
(void)memset(&((tpmt_ha *)ptr)->digest, 0, TPM_ALG_ID); |
|||
ptr = (uint8_t *)ptr + offsetof(tpmt_ha, digest) + TCG_DIGEST_SIZE; |
|||
|
|||
/* TCG_PCR_EVENT2.EventSize */ |
|||
((event2_data_t *)ptr)->event_size = |
|||
(uint32_t)sizeof(startup_locality_event_t); |
|||
ptr = (uint8_t *)ptr + offsetof(event2_data_t, event); |
|||
|
|||
/* TCG_EfiStartupLocalityEvent.Signature */ |
|||
(void)memcpy(ptr, (const void *)locality_signature, |
|||
sizeof(TCG_STARTUP_LOCALITY_SIGNATURE)); |
|||
|
|||
/*
|
|||
* TCG_EfiStartupLocalityEvent.StartupLocality = 0: |
|||
* the platform's boot firmware |
|||
*/ |
|||
((startup_locality_event_t *)ptr)->startup_locality = 0U; |
|||
ptr = (uint8_t *)ptr + sizeof(startup_locality_event_t); |
|||
if ((uintptr_t)ptr != ((uintptr_t)start_ptr + LOC_EVENT_SIZE)) { |
|||
panic(); |
|||
} |
|||
|
|||
log_ptr = (uint8_t *)ptr; |
|||
|
|||
/* Add BL2 event */ |
|||
if (add_event2(NULL, plat_data_ptr->images_data) != 0) { |
|||
panic(); |
|||
} |
|||
} |
|||
|
|||
/*
|
|||
* Calculate and write hash of image, configuration data, etc. |
|||
* to Event Log. |
|||
* |
|||
* @param[in] data_base Address of data |
|||
* @param[in] data_size Size of data |
|||
* @param[in] data_id Data ID |
|||
* @return: |
|||
* 0 = success |
|||
* < 0 = error |
|||
*/ |
|||
int tpm_record_measurement(uintptr_t data_base, uint32_t data_size, |
|||
uint32_t data_id) |
|||
{ |
|||
const image_data_t *data_ptr = plat_data_ptr->images_data; |
|||
unsigned char hash_data[MBEDTLS_MD_MAX_SIZE]; |
|||
int rc; |
|||
|
|||
/* Check if image_id is supported */ |
|||
while (data_ptr->id != data_id) { |
|||
if ((data_ptr++)->id == INVALID_ID) { |
|||
ERROR("%s(): image_id %u not supported\n", |
|||
__func__, data_id); |
|||
return -EINVAL; |
|||
} |
|||
} |
|||
|
|||
if (data_id == TOS_FW_CONFIG_ID) { |
|||
tos_fw_config_base = data_base; |
|||
} else if (data_id == NT_FW_CONFIG_ID) { |
|||
nt_fw_config_base = data_base; |
|||
} else { |
|||
/* No action */ |
|||
} |
|||
|
|||
/* Calculate hash */ |
|||
rc = crypto_mod_calc_hash((unsigned int)MBEDTLS_MD_ID, |
|||
(void *)data_base, data_size, hash_data); |
|||
if (rc != 0) { |
|||
return rc; |
|||
} |
|||
|
|||
return add_event2(hash_data, data_ptr); |
|||
} |
|||
|
|||
/*
|
|||
* Finalise Event Log |
|||
* |
|||
* @param[out] log_addr Pointer to return Event Log address |
|||
* @param[out] log_size Pointer to return Event Log size |
|||
* @return: |
|||
* 0 = success |
|||
* < 0 = error code |
|||
*/ |
|||
int event_log_finalise(uint8_t **log_addr, size_t *log_size) |
|||
{ |
|||
/* Event Log size */ |
|||
size_t num_bytes = (uintptr_t)log_ptr - (uintptr_t)event_log; |
|||
int rc; |
|||
|
|||
assert(log_addr != NULL); |
|||
assert(log_size != NULL); |
|||
|
|||
if (nt_fw_config_base == 0UL) { |
|||
ERROR("%s(): %s_FW_CONFIG not loaded\n", __func__, "NT"); |
|||
return -ENOENT; |
|||
} |
|||
|
|||
/*
|
|||
* Set Event Log data in NT_FW_CONFIG and |
|||
* get Event Log address in Non-Secure memory |
|||
*/ |
|||
if (plat_data_ptr->set_nt_fw_info != NULL) { |
|||
|
|||
/* Event Log address in Non-Secure memory */ |
|||
uintptr_t ns_log_addr; |
|||
|
|||
rc = plat_data_ptr->set_nt_fw_info( |
|||
nt_fw_config_base, |
|||
#ifdef SPD_opteed |
|||
(uintptr_t)event_log, |
|||
#endif |
|||
num_bytes, &ns_log_addr); |
|||
if (rc != 0) { |
|||
ERROR("%s(): Unable to update %s_FW_CONFIG\n", |
|||
__func__, "NT"); |
|||
return rc; |
|||
} |
|||
|
|||
/* Copy Event Log to Non-secure memory */ |
|||
(void)memcpy((void *)ns_log_addr, (const void *)event_log, |
|||
num_bytes); |
|||
|
|||
/* Ensure that the Event Log is visible in Non-secure memory */ |
|||
flush_dcache_range(ns_log_addr, num_bytes); |
|||
|
|||
/* Return Event Log address in Non-Secure memory */ |
|||
*log_addr = (uint8_t *)ns_log_addr; |
|||
|
|||
} else { |
|||
INFO("%s(): set_%s_fw_info not set\n", __func__, "nt"); |
|||
|
|||
/* Return Event Log address in Secure memory */ |
|||
*log_addr = event_log; |
|||
} |
|||
|
|||
if (tos_fw_config_base != 0UL) { |
|||
if (plat_data_ptr->set_tos_fw_info != NULL) { |
|||
|
|||
/* Set Event Log data in TOS_FW_CONFIG */ |
|||
rc = plat_data_ptr->set_tos_fw_info( |
|||
tos_fw_config_base, |
|||
(uintptr_t)event_log, |
|||
num_bytes); |
|||
if (rc != 0) { |
|||
ERROR("%s(): Unable to update %s_FW_CONFIG\n", |
|||
__func__, "TOS"); |
|||
return rc; |
|||
} |
|||
} else { |
|||
INFO("%s(): set_%s_fw_info not set\n", __func__, "tos"); |
|||
} |
|||
} else { |
|||
INFO("%s(): %s_FW_CONFIG not loaded\n", __func__, "TOS"); |
|||
} |
|||
|
|||
/* Ensure that the Event Log is visible in Secure memory */ |
|||
flush_dcache_range((uintptr_t)event_log, num_bytes); |
|||
|
|||
/* Return Event Log size */ |
|||
*log_size = num_bytes; |
|||
|
|||
return 0; |
|||
} |
@ -0,0 +1,264 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
#include <string.h> |
|||
|
|||
#include <common/debug.h> |
|||
#include <drivers/measured_boot/event_log.h> |
|||
|
|||
#if LOG_LEVEL >= EVENT_LOG_LEVEL |
|||
|
|||
/*
|
|||
* Print TCG_EfiSpecIDEventStruct |
|||
* |
|||
* @param[in/out] log_addr Pointer to Event Log |
|||
* @param[in/out] log_size Pointer to Event Log size |
|||
*/ |
|||
static void id_event_print(uint8_t **log_addr, size_t *log_size) |
|||
{ |
|||
unsigned int i; |
|||
uint8_t info_size, *info_size_ptr; |
|||
void *ptr = *log_addr; |
|||
id_event_headers_t *event = (id_event_headers_t *)ptr; |
|||
id_event_algorithm_size_t *alg_ptr; |
|||
uint32_t event_size, number_of_algorithms; |
|||
size_t digest_len; |
|||
#if ENABLE_ASSERTIONS |
|||
const uint8_t *end_ptr = *log_addr + *log_size; |
|||
bool valid = true; |
|||
#endif |
|||
|
|||
assert(*log_size >= sizeof(id_event_headers_t)); |
|||
|
|||
/* The fields of the event log header are defined to be PCRIndex of 0,
|
|||
* EventType of EV_NO_ACTION, Digest of 20 bytes of 0, and |
|||
* Event content defined as TCG_EfiSpecIDEventStruct. |
|||
*/ |
|||
LOG_EVENT("TCG_EfiSpecIDEvent:\n"); |
|||
LOG_EVENT(" PCRIndex : %u\n", event->header.pcr_index); |
|||
assert(event->header.pcr_index == (uint32_t)PCR_0); |
|||
|
|||
LOG_EVENT(" EventType : %u\n", event->header.event_type); |
|||
assert(event->header.event_type == EV_NO_ACTION); |
|||
|
|||
LOG_EVENT(" Digest :"); |
|||
for (i = 0U; i < sizeof(event->header.digest); ++i) { |
|||
uint8_t val = event->header.digest[i]; |
|||
|
|||
(void)printf(" %02x", val); |
|||
if ((i & U(0xF)) == 0U) { |
|||
(void)printf("\n"); |
|||
LOG_EVENT("\t\t :"); |
|||
} |
|||
#if ENABLE_ASSERTIONS |
|||
if (val != 0U) { |
|||
valid = false; |
|||
} |
|||
#endif |
|||
} |
|||
if ((i & U(0xF)) != 0U) { |
|||
(void)printf("\n"); |
|||
} |
|||
|
|||
assert(valid); |
|||
|
|||
/* EventSize */ |
|||
event_size = event->header.event_size; |
|||
LOG_EVENT(" EventSize : %u\n", event_size); |
|||
|
|||
LOG_EVENT(" Signature : %s\n", |
|||
event->struct_header.signature); |
|||
LOG_EVENT(" PlatformClass : %u\n", |
|||
event->struct_header.platform_class); |
|||
LOG_EVENT(" SpecVersion : %u.%u.%u\n", |
|||
event->struct_header.spec_version_major, |
|||
event->struct_header.spec_version_minor, |
|||
event->struct_header.spec_errata); |
|||
LOG_EVENT(" UintnSize : %u\n", |
|||
event->struct_header.uintn_size); |
|||
|
|||
/* NumberOfAlgorithms */ |
|||
number_of_algorithms = event->struct_header.number_of_algorithms; |
|||
LOG_EVENT(" NumberOfAlgorithms : %u\n", number_of_algorithms); |
|||
|
|||
/* Address of DigestSizes[] */ |
|||
alg_ptr = event->struct_header.digest_size; |
|||
|
|||
/* Size of DigestSizes[] */ |
|||
digest_len = number_of_algorithms * sizeof(id_event_algorithm_size_t); |
|||
assert(((uint8_t *)alg_ptr + digest_len) <= end_ptr); |
|||
|
|||
LOG_EVENT(" DigestSizes :\n"); |
|||
for (i = 0U; i < number_of_algorithms; ++i) { |
|||
LOG_EVENT(" #%u AlgorithmId : SHA", i); |
|||
uint16_t algorithm_id = alg_ptr[i].algorithm_id; |
|||
|
|||
switch (algorithm_id) { |
|||
case TPM_ALG_SHA256: |
|||
(void)printf("256\n"); |
|||
break; |
|||
case TPM_ALG_SHA384: |
|||
(void)printf("384\n"); |
|||
break; |
|||
case TPM_ALG_SHA512: |
|||
(void)printf("512\n"); |
|||
break; |
|||
default: |
|||
(void)printf("?\n"); |
|||
ERROR("Algorithm 0x%x not found\n", algorithm_id); |
|||
assert(false); |
|||
} |
|||
|
|||
LOG_EVENT(" DigestSize : %u\n", |
|||
alg_ptr[i].digest_size); |
|||
} |
|||
|
|||
/* Address of VendorInfoSize */ |
|||
info_size_ptr = (uint8_t *)alg_ptr + digest_len; |
|||
assert(info_size_ptr <= end_ptr); |
|||
|
|||
info_size = *info_size_ptr++; |
|||
LOG_EVENT(" VendorInfoSize : %u\n", info_size); |
|||
|
|||
/* Check VendorInfo end address */ |
|||
assert((info_size_ptr + info_size) <= end_ptr); |
|||
|
|||
/* Check EventSize */ |
|||
assert(event_size == (sizeof(id_event_struct_t) + |
|||
digest_len + info_size)); |
|||
if (info_size != 0U) { |
|||
LOG_EVENT(" VendorInfo :"); |
|||
for (i = 0U; i < info_size; ++i) { |
|||
(void)printf(" %02x", *info_size_ptr++); |
|||
} |
|||
(void)printf("\n"); |
|||
} |
|||
|
|||
*log_size -= (uintptr_t)info_size_ptr - (uintptr_t)*log_addr; |
|||
*log_addr = info_size_ptr; |
|||
} |
|||
|
|||
/*
|
|||
* Print TCG_PCR_EVENT2 |
|||
* |
|||
* @param[in/out] log_addr Pointer to Event Log |
|||
* @param[in/out] log_size Pointer to Event Log size |
|||
*/ |
|||
static void event2_print(uint8_t **log_addr, size_t *log_size) |
|||
{ |
|||
uint32_t event_size, count; |
|||
size_t sha_size, digests_size = 0U; |
|||
void *ptr = *log_addr; |
|||
#if ENABLE_ASSERTIONS |
|||
const uint8_t *end_ptr = *log_addr + *log_size; |
|||
#endif |
|||
|
|||
assert(*log_size >= sizeof(event2_header_t)); |
|||
|
|||
LOG_EVENT("PCR_Event2:\n"); |
|||
LOG_EVENT(" PCRIndex : %u\n", |
|||
((event2_header_t *)ptr)->pcr_index); |
|||
LOG_EVENT(" EventType : %u\n", |
|||
((event2_header_t *)ptr)->event_type); |
|||
|
|||
count = ((event2_header_t *)ptr)->digests.count; |
|||
LOG_EVENT(" Digests Count : %u\n", count); |
|||
|
|||
/* Address of TCG_PCR_EVENT2.Digests[] */ |
|||
ptr = (uint8_t *)ptr + sizeof(event2_header_t); |
|||
assert(((uintptr_t)ptr <= (uintptr_t)end_ptr) && (count != 0U)); |
|||
|
|||
for (unsigned int i = 0U; i < count; ++i) { |
|||
/* Check AlgorithmId address */ |
|||
assert(((uint8_t *)ptr + offsetof(tpmt_ha, digest)) <= end_ptr); |
|||
|
|||
LOG_EVENT(" #%u AlgorithmId : SHA", i); |
|||
switch (((tpmt_ha *)ptr)->algorithm_id) { |
|||
case TPM_ALG_SHA256: |
|||
sha_size = SHA256_DIGEST_SIZE; |
|||
(void)printf("256\n"); |
|||
break; |
|||
case TPM_ALG_SHA384: |
|||
sha_size = SHA384_DIGEST_SIZE; |
|||
(void)printf("384\n"); |
|||
break; |
|||
case TPM_ALG_SHA512: |
|||
sha_size = SHA512_DIGEST_SIZE; |
|||
(void)printf("512\n"); |
|||
break; |
|||
default: |
|||
(void)printf("?\n"); |
|||
ERROR("Algorithm 0x%x not found\n", |
|||
((tpmt_ha *)ptr)->algorithm_id); |
|||
panic(); |
|||
} |
|||
|
|||
/* End of Digest[] */ |
|||
ptr = (uint8_t *)ptr + offsetof(tpmt_ha, digest); |
|||
assert(((uint8_t *)ptr + sha_size) <= end_ptr); |
|||
|
|||
/* Total size of all digests */ |
|||
digests_size += sha_size; |
|||
|
|||
LOG_EVENT(" Digest :"); |
|||
for (unsigned int j = 0U; j < sha_size; ++j) { |
|||
(void)printf(" %02x", *(uint8_t *)ptr++); |
|||
if ((j & U(0xF)) == U(0xF)) { |
|||
(void)printf("\n"); |
|||
if (j < (sha_size - 1U)) { |
|||
LOG_EVENT("\t\t :"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/* TCG_PCR_EVENT2.EventSize */ |
|||
assert(((uint8_t *)ptr + offsetof(event2_data_t, event)) <= end_ptr); |
|||
|
|||
event_size = ((event2_data_t *)ptr)->event_size; |
|||
LOG_EVENT(" EventSize : %u\n", event_size); |
|||
|
|||
/* Address of TCG_PCR_EVENT2.Event[EventSize] */ |
|||
ptr = (uint8_t *)ptr + offsetof(event2_data_t, event); |
|||
|
|||
/* End of TCG_PCR_EVENT2.Event[EventSize] */ |
|||
assert(((uint8_t *)ptr + event_size) <= end_ptr); |
|||
|
|||
if ((event_size == sizeof(startup_locality_event_t)) && |
|||
(strcmp((const char *)ptr, TCG_STARTUP_LOCALITY_SIGNATURE) == 0)) { |
|||
LOG_EVENT(" Signature : %s\n", |
|||
((startup_locality_event_t *)ptr)->signature); |
|||
LOG_EVENT(" StartupLocality : %u\n", |
|||
((startup_locality_event_t *)ptr)->startup_locality); |
|||
} else { |
|||
LOG_EVENT(" Event : %s\n", (uint8_t *)ptr); |
|||
} |
|||
|
|||
*log_size -= (uintptr_t)ptr + event_size - (uintptr_t)*log_addr; |
|||
*log_addr = (uint8_t *)ptr + event_size; |
|||
} |
|||
#endif /* LOG_LEVEL >= EVENT_LOG_LEVEL */ |
|||
|
|||
/*
|
|||
* Print Event Log |
|||
* |
|||
* @param[in] log_addr Pointer to Event Log |
|||
* @param[in] log_size Event Log size |
|||
*/ |
|||
void dump_event_log(uint8_t *log_addr, size_t log_size) |
|||
{ |
|||
#if LOG_LEVEL >= EVENT_LOG_LEVEL |
|||
assert(log_addr != NULL); |
|||
|
|||
/* Print TCG_EfiSpecIDEvent */ |
|||
id_event_print(&log_addr, &log_size); |
|||
|
|||
while (log_size != 0U) { |
|||
event2_print(&log_addr, &log_size); |
|||
} |
|||
#endif |
|||
} |
@ -0,0 +1,39 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <assert.h> |
|||
|
|||
#include <common/debug.h> |
|||
#include <drivers/measured_boot/measured_boot.h> |
|||
|
|||
/*
|
|||
* Init Measured Boot driver |
|||
* |
|||
* Initialises Event Log. |
|||
*/ |
|||
void measured_boot_init(void) |
|||
{ |
|||
event_log_init(); |
|||
} |
|||
|
|||
/*
|
|||
* Finish Measured Boot driver |
|||
* |
|||
* Finalises Event Log and dumps the records to the debug console. |
|||
*/ |
|||
void measured_boot_finish(void) |
|||
{ |
|||
uint8_t *log_addr; |
|||
size_t log_size; |
|||
int rc; |
|||
|
|||
rc = event_log_finalise(&log_addr, &log_size); |
|||
if (rc != 0) { |
|||
panic(); |
|||
} |
|||
|
|||
dump_event_log(log_addr, log_size); |
|||
} |
@ -0,0 +1,45 @@ |
|||
#
|
|||
# Copyright (c) 2020, Arm Limited. All rights reserved.
|
|||
#
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
|||
#
|
|||
|
|||
# TPM hash algorithm
|
|||
TPM_HASH_ALG := sha256 |
|||
|
|||
ifeq (${TPM_HASH_ALG}, sha512) |
|||
MBEDTLS_MD_ID := MBEDTLS_MD_SHA512 |
|||
TPM_ALG_ID := TPM_ALG_SHA512 |
|||
TCG_DIGEST_SIZE := 64U |
|||
else ifeq (${TPM_HASH_ALG}, sha384) |
|||
MBEDTLS_MD_ID := MBEDTLS_MD_SHA384 |
|||
TPM_ALG_ID := TPM_ALG_SHA384 |
|||
TCG_DIGEST_SIZE := 48U |
|||
else |
|||
MBEDTLS_MD_ID := MBEDTLS_MD_SHA256 |
|||
TPM_ALG_ID := TPM_ALG_SHA256 |
|||
TCG_DIGEST_SIZE := 32U |
|||
endif |
|||
|
|||
# Event Log length in bytes
|
|||
EVENT_LOG_SIZE := 1024 |
|||
|
|||
# Set definitions for mbed TLS library and Measured Boot driver
|
|||
$(eval $(call add_define,MBEDTLS_MD_ID)) |
|||
$(eval $(call add_define,TPM_ALG_ID)) |
|||
$(eval $(call add_define,TCG_DIGEST_SIZE)) |
|||
$(eval $(call add_define,EVENT_LOG_SIZE)) |
|||
|
|||
ifeq (${HASH_ALG}, sha256) |
|||
ifneq (${TPM_HASH_ALG}, sha256) |
|||
$(eval $(call add_define,MBEDTLS_SHA512_C)) |
|||
endif |
|||
endif |
|||
|
|||
MEASURED_BOOT_SRC_DIR := drivers/measured_boot/ |
|||
|
|||
MEASURED_BOOT_SOURCES := ${MEASURED_BOOT_SRC_DIR}measured_boot.c \
|
|||
${MEASURED_BOOT_SRC_DIR}event_log.c \
|
|||
${MEASURED_BOOT_SRC_DIR}event_print.c |
|||
|
|||
BL2_SOURCES += ${MEASURED_BOOT_SOURCES} |
@ -0,0 +1,99 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef EVENT_LOG_H |
|||
#define EVENT_LOG_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#include <common/debug.h> |
|||
#include <drivers/measured_boot/tcg.h> |
|||
|
|||
/*
|
|||
* Set Event Log debug level to one of: |
|||
* |
|||
* LOG_LEVEL_ERROR |
|||
* LOG_LEVEL_INFO |
|||
* LOG_LEVEL_WARNING |
|||
* LOG_LEVEL_VERBOSE |
|||
*/ |
|||
#define EVENT_LOG_LEVEL LOG_LEVEL_INFO |
|||
|
|||
#if EVENT_LOG_LEVEL == LOG_LEVEL_ERROR |
|||
#define LOG_EVENT ERROR |
|||
#elif EVENT_LOG_LEVEL == LOG_LEVEL_NOTICE |
|||
#define LOG_EVENT NOTICE |
|||
#elif EVENT_LOG_LEVEL == LOG_LEVEL_WARNING |
|||
#define LOG_EVENT WARN |
|||
#elif EVENT_LOG_LEVEL == LOG_LEVEL_INFO |
|||
#define LOG_EVENT INFO |
|||
#elif EVENT_LOG_LEVEL == LOG_LEVEL_VERBOSE |
|||
#define LOG_EVENT VERBOSE |
|||
#else |
|||
#error "Not supported EVENT_LOG_LEVEL" |
|||
#endif |
|||
|
|||
/* Number of hashing algorithms supported */ |
|||
#define HASH_ALG_COUNT 1U |
|||
|
|||
#define INVALID_ID MAX_NUMBER_IDS |
|||
|
|||
#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) |
|||
|
|||
#define BL2_STRING "BL_2" |
|||
#define BL31_STRING "BL_31" |
|||
#define BL32_STRING "BL_32" |
|||
#define BL32_EXTRA1_IMAGE_STRING "BL32_EXTRA1_IMAGE" |
|||
#define BL32_EXTRA2_IMAGE_STRING "BL32_EXTRA2_IMAGE" |
|||
#define BL33_STRING "BL_33" |
|||
#define GPT_IMAGE_STRING "GPT" |
|||
#define HW_CONFIG_STRING "HW_CONFIG" |
|||
#define NT_FW_CONFIG_STRING "NT_FW_CONFIG" |
|||
#define SCP_BL2_IMAGE_STRING "SCP_BL2_IMAGE" |
|||
#define SOC_FW_CONFIG_STRING "SOC_FW_CONFIG" |
|||
#define STM32_IMAGE_STRING "STM32" |
|||
#define TOS_FW_CONFIG_STRING "TOS_FW_CONFIG" |
|||
|
|||
typedef struct { |
|||
unsigned int id; |
|||
const char *name; |
|||
unsigned int pcr; |
|||
} image_data_t; |
|||
|
|||
typedef struct { |
|||
const image_data_t *images_data; |
|||
int (*set_nt_fw_info)(uintptr_t config_base, |
|||
#ifdef SPD_opteed |
|||
uintptr_t log_addr, |
|||
#endif |
|||
size_t log_size, uintptr_t *ns_log_addr); |
|||
int (*set_tos_fw_info)(uintptr_t config_base, uintptr_t log_addr, |
|||
size_t log_size); |
|||
} measured_boot_data_t; |
|||
|
|||
#define ID_EVENT_SIZE (sizeof(id_event_headers_t) + \ |
|||
(sizeof(id_event_algorithm_size_t) * HASH_ALG_COUNT) + \ |
|||
sizeof(id_event_struct_data_t)) |
|||
|
|||
#define LOC_EVENT_SIZE (sizeof(event2_header_t) + \ |
|||
sizeof(tpmt_ha) + TCG_DIGEST_SIZE + \ |
|||
sizeof(event2_data_t) + \ |
|||
sizeof(startup_locality_event_t)) |
|||
|
|||
#define LOG_MIN_SIZE (ID_EVENT_SIZE + LOC_EVENT_SIZE) |
|||
|
|||
#define EVENT2_HDR_SIZE (sizeof(event2_header_t) + \ |
|||
sizeof(tpmt_ha) + TCG_DIGEST_SIZE + \ |
|||
sizeof(event2_data_t)) |
|||
|
|||
/* Functions' declarations */ |
|||
void event_log_init(void); |
|||
int event_log_finalise(uint8_t **log_addr, size_t *log_size); |
|||
void dump_event_log(uint8_t *log_addr, size_t log_size); |
|||
const measured_boot_data_t *plat_get_measured_boot_data(void); |
|||
int tpm_record_measurement(uintptr_t data_base, uint32_t data_size, |
|||
uint32_t data_id); |
|||
#endif /* EVENT_LOG_H */ |
@ -0,0 +1,21 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef MEASURED_BOOT_H |
|||
#define MEASURED_BOOT_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#include <drivers/measured_boot/event_log.h> |
|||
|
|||
/* Platform specific table of image IDs, names and PCRs */ |
|||
extern const image_data_t images_data[]; |
|||
|
|||
/* Functions' declarations */ |
|||
void measured_boot_init(void); |
|||
void measured_boot_finish(void); |
|||
|
|||
#endif /* MEASURED_BOOT_H */ |
@ -0,0 +1,304 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef TCG_H |
|||
#define TCG_H |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#define TCG_ID_EVENT_SIGNATURE_03 "Spec ID Event03" |
|||
#define TCG_STARTUP_LOCALITY_SIGNATURE "StartupLocality" |
|||
|
|||
#define TCG_SPEC_VERSION_MAJOR_TPM2 2 |
|||
#define TCG_SPEC_VERSION_MINOR_TPM2 0 |
|||
#define TCG_SPEC_ERRATA_TPM2 2 |
|||
|
|||
/*
|
|||
* Event types |
|||
* Ref. Table 9 Events |
|||
* TCG PC Client Platform Firmware Profile Specification. |
|||
*/ |
|||
#define EV_PREBOOT_CERT U(0x00000000) |
|||
#define EV_POST_CODE U(0x00000001) |
|||
#define EV_UNUSED U(0x00000002) |
|||
#define EV_NO_ACTION U(0x00000003) |
|||
#define EV_SEPARATOR U(0x00000004) |
|||
#define EV_ACTION U(0x00000005) |
|||
#define EV_EVENT_TAG U(0x00000006) |
|||
#define EV_S_CRTM_CONTENTS U(0x00000007) |
|||
#define EV_S_CRTM_VERSION U(0x00000008) |
|||
#define EV_CPU_MICROCODE U(0x00000009) |
|||
#define EV_PLATFORM_CONFIG_FLAGS U(0x0000000A) |
|||
#define EV_TABLE_OF_DEVICES U(0x0000000B) |
|||
#define EV_COMPACT_HASH U(0x0000000C) |
|||
#define EV_IPL U(0x0000000D) |
|||
#define EV_IPL_PARTITION_DATA U(0x0000000E) |
|||
#define EV_NONHOST_CODE U(0x0000000F) |
|||
#define EV_NONHOST_CONFIG U(0x00000010) |
|||
#define EV_NONHOST_INFO U(0x00000011) |
|||
#define EV_OMIT_BOOT_DEVICE_EVENTS U(0x00000012) |
|||
#define EV_EFI_EVENT_BASE U(0x80000000) |
|||
#define EV_EFI_VARIABLE_DRIVER_CONFIG U(0x80000001) |
|||
#define EV_EFI_VARIABLE_BOOT U(0x80000002) |
|||
#define EV_EFI_BOOT_SERVICES_APPLICATION U(0x80000003) |
|||
#define EV_EFI_BOOT_SERVICES_DRIVER U(0x80000004) |
|||
#define EV_EFI_RUNTIME_SERVICES_DRIVER U(0x80000005) |
|||
#define EV_EFI_GPT_EVENT U(0x80000006) |
|||
#define EV_EFI_ACTION U(0x80000007) |
|||
#define EV_EFI_PLATFORM_FIRMWARE_BLOB U(0x80000008) |
|||
#define EV_EFI_HANDOFF_TABLES U(0x80000009) |
|||
#define EV_EFI_HCRTM_EVENT U(0x80000010) |
|||
#define EV_EFI_VARIABLE_AUTHORITY U(0x800000E0) |
|||
|
|||
/*
|
|||
* TPM_ALG_ID constants. |
|||
* Ref. Table 9 - Definition of (UINT16) TPM_ALG_ID Constants |
|||
* Trusted Platform Module Library. Part 2: Structures |
|||
*/ |
|||
#define TPM_ALG_SHA256 0x000B |
|||
#define TPM_ALG_SHA384 0x000C |
|||
#define TPM_ALG_SHA512 0x000D |
|||
|
|||
/* TCG Platform Type */ |
|||
#define PLATFORM_CLASS_CLIENT 0 |
|||
#define PLATFORM_CLASS_SERVER 1 |
|||
|
|||
/* SHA digest sizes in bytes */ |
|||
#define SHA1_DIGEST_SIZE 20 |
|||
#define SHA256_DIGEST_SIZE 32 |
|||
#define SHA384_DIGEST_SIZE 48 |
|||
#define SHA512_DIGEST_SIZE 64 |
|||
|
|||
enum { |
|||
/*
|
|||
* SRTM, BIOS, Host Platform Extensions, Embedded |
|||
* Option ROMs and PI Drivers |
|||
*/ |
|||
PCR_0 = 0, |
|||
/* Host Platform Configuration */ |
|||
PCR_1, |
|||
/* UEFI driver and application Code */ |
|||
PCR_2, |
|||
/* UEFI driver and application Configuration and Data */ |
|||
PCR_3, |
|||
/* UEFI Boot Manager Code (usually the MBR) and Boot Attempts */ |
|||
PCR_4, |
|||
/*
|
|||
* Boot Manager Code Configuration and Data (for use |
|||
* by the Boot Manager Code) and GPT/Partition Table |
|||
*/ |
|||
PCR_5, |
|||
/* Host Platform Manufacturer Specific */ |
|||
PCR_6, |
|||
/* Secure Boot Policy */ |
|||
PCR_7, |
|||
/* 8-15: Defined for use by the Static OS */ |
|||
PCR_8, |
|||
/* Debug */ |
|||
PCR_16 = 16 |
|||
}; |
|||
|
|||
#pragma pack(push, 1) |
|||
|
|||
/*
|
|||
* PCR Event Header |
|||
* TCG EFI Protocol Specification |
|||
* 5.3 Event Log Header |
|||
*/ |
|||
typedef struct { |
|||
/* PCRIndex:
|
|||
* The PCR Index to which this event is extended |
|||
*/ |
|||
uint32_t pcr_index; |
|||
|
|||
/* EventType:
|
|||
* SHALL be an EV_NO_ACTION event |
|||
*/ |
|||
uint32_t event_type; |
|||
|
|||
/* SHALL be 20 Bytes of 0x00 */ |
|||
uint8_t digest[SHA1_DIGEST_SIZE]; |
|||
|
|||
/* The size of the event */ |
|||
uint32_t event_size; |
|||
|
|||
/* SHALL be a TCG_EfiSpecIdEvent */ |
|||
uint8_t event[]; /* [event_data_size] */ |
|||
} tcg_pcr_event_t; |
|||
|
|||
/*
|
|||
* Log Header Entry Data |
|||
* Ref. Table 14 TCG_EfiSpecIdEventAlgorithmSize |
|||
* TCG PC Client Platform Firmware Profile 9.4.5.1 |
|||
*/ |
|||
typedef struct { |
|||
/* Algorithm ID (hashAlg) of the Hash used by BIOS */ |
|||
uint16_t algorithm_id; |
|||
|
|||
/* The size of the digest produced by the implemented Hash algorithm */ |
|||
uint16_t digest_size; |
|||
} id_event_algorithm_size_t; |
|||
|
|||
/*
|
|||
* TCG_EfiSpecIdEvent structure |
|||
* Ref. Table 15 TCG_EfiSpecIdEvent |
|||
* TCG PC Client Platform Firmware Profile 9.4.5.1 |
|||
*/ |
|||
typedef struct { |
|||
/*
|
|||
* The NUL-terminated ASCII string "Spec ID Event03". |
|||
* SHALL be set to {0x53, 0x70, 0x65, 0x63, 0x20, 0x49, 0x44, |
|||
* 0x20, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x33, 0x00}. |
|||
*/ |
|||
uint8_t signature[16]; |
|||
|
|||
/*
|
|||
* The value for the Platform Class. |
|||
* The enumeration is defined in the TCG ACPI Specification Client |
|||
* Common Header. |
|||
*/ |
|||
uint32_t platform_class; |
|||
|
|||
/*
|
|||
* The PC Client Platform Profile Specification minor version number |
|||
* this BIOS supports. |
|||
* Any BIOS supporting this version (2.0) MUST set this value to 0x00. |
|||
*/ |
|||
uint8_t spec_version_minor; |
|||
|
|||
/*
|
|||
* The PC Client Platform Profile Specification major version number |
|||
* this BIOS supports. |
|||
* Any BIOS supporting this version (2.0) MUST set this value to 0x02. |
|||
*/ |
|||
uint8_t spec_version_major; |
|||
|
|||
/*
|
|||
* The PC Client Platform Profile Specification errata version number |
|||
* this BIOS supports. |
|||
* Any BIOS supporting this version (2.0) MUST set this value to 0x02. |
|||
*/ |
|||
uint8_t spec_errata; |
|||
|
|||
/*
|
|||
* Specifies the size of the UINTN fields used in various data |
|||
* structures used in this specification. |
|||
* 0x01 indicates UINT32 and 0x02 indicates UINT64. |
|||
*/ |
|||
uint8_t uintn_size; |
|||
|
|||
/*
|
|||
* The number of Hash algorithms in the digestSizes field. |
|||
* This field MUST be set to a value of 0x01 or greater. |
|||
*/ |
|||
uint32_t number_of_algorithms; |
|||
|
|||
/*
|
|||
* Each TCG_EfiSpecIdEventAlgorithmSize SHALL contain an algorithmId |
|||
* and digestSize for each hash algorithm used in the TCG_PCR_EVENT2 |
|||
* structure, the first of which is a Hash algorithmID and the second |
|||
* is the size of the respective digest. |
|||
*/ |
|||
id_event_algorithm_size_t digest_size[]; /* number_of_algorithms */ |
|||
} id_event_struct_header_t; |
|||
|
|||
typedef struct { |
|||
/*
|
|||
* Size in bytes of the VendorInfo field. |
|||
* Maximum value MUST be FFh bytes. |
|||
*/ |
|||
uint8_t vendor_info_size; |
|||
|
|||
/*
|
|||
* Provided for use by Platform Firmware implementer. The value might |
|||
* be used, for example, to provide more detailed information about the |
|||
* specific BIOS such as BIOS revision numbers, etc. The values within |
|||
* this field are not standardized and are implementer-specific. |
|||
* Platform-specific or -unique information MUST NOT be provided in |
|||
* this field. |
|||
* |
|||
*/ |
|||
uint8_t vendor_info[]; /* [vendorInfoSize] */ |
|||
} id_event_struct_data_t; |
|||
|
|||
typedef struct { |
|||
id_event_struct_header_t struct_header; |
|||
id_event_struct_data_t struct_data; |
|||
} id_event_struct_t; |
|||
|
|||
typedef struct { |
|||
tcg_pcr_event_t header; |
|||
id_event_struct_header_t struct_header; |
|||
} id_event_headers_t; |
|||
|
|||
/* TPMT_HA Structure */ |
|||
typedef struct { |
|||
/* Selector of the hash contained in the digest that implies
|
|||
* the size of the digest |
|||
*/ |
|||
uint16_t algorithm_id; /* AlgorithmId */ |
|||
|
|||
/* Digest, depends on AlgorithmId */ |
|||
uint8_t digest[]; /* Digest[] */ |
|||
} tpmt_ha; |
|||
|
|||
/*
|
|||
* TPML_DIGEST_VALUES Structure |
|||
*/ |
|||
typedef struct { |
|||
/* The number of digests in the list */ |
|||
uint32_t count; /* Count */ |
|||
|
|||
/* The list of tagged digests, as sent to the TPM as part of a
|
|||
* TPM2_PCR_Extend or as received from a TPM2_PCR_Event command |
|||
*/ |
|||
tpmt_ha digests[]; /* Digests[Count] */ |
|||
} tpml_digest_values; |
|||
|
|||
/*
|
|||
* TCG_PCR_EVENT2 header |
|||
*/ |
|||
typedef struct { |
|||
/* The PCR Index to which this event was extended */ |
|||
uint32_t pcr_index; /* PCRIndex */ |
|||
|
|||
/* Type of event */ |
|||
uint32_t event_type; /* EventType */ |
|||
|
|||
/* Digests:
|
|||
* A counted list of tagged digests, which contain the digest of |
|||
* the event data (or external data) for all active PCR banks |
|||
*/ |
|||
tpml_digest_values digests; /* Digests */ |
|||
} event2_header_t; |
|||
|
|||
typedef struct event2_data { |
|||
/* The size of the event data */ |
|||
uint32_t event_size; /* EventSize */ |
|||
|
|||
/* The data of the event */ |
|||
uint8_t event[]; /* Event[EventSize] */ |
|||
} event2_data_t; |
|||
|
|||
/*
|
|||
* Startup Locality Event |
|||
* Ref. TCG PC Client Platform Firmware Profile 9.4.5.3 |
|||
*/ |
|||
typedef struct { |
|||
/*
|
|||
* The NUL-terminated ASCII string "StartupLocality" SHALL be |
|||
* set to {0x53 0x74 0x61 0x72 0x74 0x75 0x70 0x4C 0x6F 0x63 |
|||
* 0x61 0x6C 0x69 0x74 0x79 0x00} |
|||
*/ |
|||
uint8_t signature[16]; |
|||
|
|||
/* The Locality Indicator which sent the TPM2_Startup command */ |
|||
uint8_t startup_locality; |
|||
} startup_locality_event_t; |
|||
|
|||
#pragma pack(pop) |
|||
|
|||
#endif /* TCG_H */ |
@ -0,0 +1,64 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <common/debug.h> |
|||
#include <common/fdt_wrappers.h> |
|||
|
|||
#include <libfdt.h> |
|||
#include <fconf_nt_config_getter.h> |
|||
|
|||
#include <plat/common/platform.h> |
|||
|
|||
struct event_log_config_t event_log_config; |
|||
|
|||
int fconf_populate_event_log_config(uintptr_t config) |
|||
{ |
|||
int err; |
|||
int node; |
|||
|
|||
/* Necessary to work with libfdt APIs */ |
|||
const void *dtb = (const void *)config; |
|||
|
|||
/*
|
|||
* Find the offset of the node containing "arm,tpm_event_log" |
|||
* compatible property |
|||
*/ |
|||
const char *compatible_str = "arm,tpm_event_log"; |
|||
|
|||
node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); |
|||
if (node < 0) { |
|||
ERROR("FCONF: Can't find '%s' compatible in dtb\n", |
|||
compatible_str); |
|||
return node; |
|||
} |
|||
|
|||
/* Retrieve Event Log details from the DTB */ |
|||
#ifdef SPD_opteed |
|||
err = fdtw_read_cells(dtb, node, "tpm_event_log_sm_addr", 2, |
|||
&event_log_config.tpm_event_log_sm_addr); |
|||
if (err < 0) { |
|||
ERROR("FCONF: Read cell failed for 'tpm_event_log_sm_addr'\n"); |
|||
return err; |
|||
} |
|||
#endif |
|||
err = fdtw_read_cells(dtb, node, |
|||
"tpm_event_log_addr", 2, &event_log_config.tpm_event_log_addr); |
|||
if (err < 0) { |
|||
ERROR("FCONF: Read cell failed for 'tpm_event_log_addr'\n"); |
|||
return err; |
|||
} |
|||
|
|||
err = fdtw_read_cells(dtb, node, |
|||
"tpm_event_log_size", 1, &event_log_config.tpm_event_log_size); |
|||
if (err < 0) { |
|||
ERROR("FCONF: Read cell failed for 'tpm_event_log_size'\n"); |
|||
} |
|||
|
|||
return err; |
|||
} |
|||
|
|||
FCONF_REGISTER_POPULATOR(NT_CONFIG, event_log_config, |
|||
fconf_populate_event_log_config); |
@ -0,0 +1,12 @@ |
|||
/* |
|||
* Copyright (c) 2020, ARM Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
/* TPM Event Log Config */ |
|||
event_log: tpm_event_log { |
|||
compatible = "arm,tpm_event_log"; |
|||
tpm_event_log_addr = <0x0 0x0>; |
|||
tpm_event_log_size = <0x0>; |
|||
}; |
@ -0,0 +1,40 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#include <drivers/measured_boot/event_log.h> |
|||
#include <plat/arm/common/plat_arm.h> |
|||
|
|||
/* FVP table with platform specific image IDs, names and PCRs */ |
|||
static const image_data_t fvp_images_data[] = { |
|||
{ BL2_IMAGE_ID, BL2_STRING, PCR_0 }, /* Reserved for BL2 */ |
|||
{ BL31_IMAGE_ID, BL31_STRING, PCR_0 }, |
|||
{ BL32_IMAGE_ID, BL32_STRING, PCR_0 }, |
|||
{ BL32_EXTRA1_IMAGE_ID, BL32_EXTRA1_IMAGE_STRING, PCR_0 }, |
|||
{ BL32_EXTRA2_IMAGE_ID, BL32_EXTRA2_IMAGE_STRING, PCR_0 }, |
|||
{ BL33_IMAGE_ID, BL33_STRING, PCR_0 }, |
|||
{ GPT_IMAGE_ID, GPT_IMAGE_STRING, PCR_0 }, |
|||
{ HW_CONFIG_ID, HW_CONFIG_STRING, PCR_0 }, |
|||
{ NT_FW_CONFIG_ID, NT_FW_CONFIG_STRING, PCR_0 }, |
|||
{ SCP_BL2_IMAGE_ID, SCP_BL2_IMAGE_STRING, PCR_0 }, |
|||
{ SOC_FW_CONFIG_ID, SOC_FW_CONFIG_STRING, PCR_0 }, |
|||
{ STM32_IMAGE_ID, STM32_IMAGE_STRING, PCR_0 }, |
|||
{ TOS_FW_CONFIG_ID, TOS_FW_CONFIG_STRING, PCR_0 }, |
|||
{ INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ |
|||
}; |
|||
|
|||
static const measured_boot_data_t fvp_measured_boot_data = { |
|||
fvp_images_data, |
|||
arm_set_nt_fw_info, |
|||
arm_set_tos_fw_info |
|||
}; |
|||
|
|||
/*
|
|||
* Function retuns pointer to FVP plat_measured_boot_data_t structure |
|||
*/ |
|||
const measured_boot_data_t *plat_get_measured_boot_data(void) |
|||
{ |
|||
return &fvp_measured_boot_data; |
|||
} |
@ -0,0 +1,27 @@ |
|||
/*
|
|||
* Copyright (c) 2020, Arm Limited. All rights reserved. |
|||
* |
|||
* SPDX-License-Identifier: BSD-3-Clause |
|||
*/ |
|||
|
|||
#ifndef FCONF_NT_CONFIG_GETTER_H |
|||
#define FCONF_NT_CONFIG_GETTER_H |
|||
|
|||
#include <lib/fconf/fconf.h> |
|||
|
|||
/* NT Firmware Config related getter */ |
|||
#define nt_config__event_log_config_getter(prop) event_log.prop |
|||
|
|||
struct event_log_config_t { |
|||
#ifdef SPD_opteed |
|||
void *tpm_event_log_sm_addr; |
|||
#endif |
|||
void *tpm_event_log_addr; |
|||
size_t tpm_event_log_size; |
|||
}; |
|||
|
|||
int fconf_populate_event_log_config(uintptr_t config); |
|||
|
|||
extern struct event_log_config_t event_log_config; |
|||
|
|||
#endif /* FCONF_NT_CONFIG_GETTER_H */ |
Loading…
Reference in new issue