diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index 92ff39fdd..24af13e76 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1195,7 +1195,7 @@ Function : plat_mboot_measure_image() :: Argument : unsigned int, image_info_t * - Return : void + Return : int When the MEASURED_BOOT flag is enabled: @@ -1204,7 +1204,25 @@ When the MEASURED_BOOT flag is enabled: - On the Arm FVP port, this function measures the given image using its passed id and information and then records that measurement in the Event Log buffer. -- This function must return 0 on success, a negative error code otherwise. +- This function must return 0 on success, a signed integer error code + otherwise. + +When the MEASURED_BOOT flag is disabled, this function doesn't do anything. + +Function : plat_mboot_measure_critical_data() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : unsigned int, const void *, size_t + Return : int + +When the MEASURED_BOOT flag is enabled: + +- This function measures the given critical data structure and records its + measurement using the measured boot backend driver. +- This function must return 0 on success, a signed integer error code + otherwise. When the MEASURED_BOOT flag is disabled, this function doesn't do anything. diff --git a/include/drivers/measured_boot/event_log/event_log.h b/include/drivers/measured_boot/event_log/event_log.h index 78712af65..a687d41f0 100644 --- a/include/drivers/measured_boot/event_log/event_log.h +++ b/include/drivers/measured_boot/event_log/event_log.h @@ -38,7 +38,7 @@ /* Number of hashing algorithms supported */ #define HASH_ALG_COUNT 1U -#define EVLOG_INVALID_ID MAX_NUMBER_IDS +#define EVLOG_INVALID_ID UINT32_MAX #define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h index 14ae603b9..632f1229c 100644 --- a/include/plat/common/common_def.h +++ b/include/plat/common/common_def.h @@ -85,4 +85,12 @@ #endif /* BL2_IN_XIP_MEM */ #endif /* SEPARATE_CODE_AND_RODATA */ +#if MEASURED_BOOT +/* + * Start critical data Ids from 2^32/2 reserving Ids from 0 to (2^32/2 - 1) + * for Images, It is a critical data Id base for all platforms. + */ +#define CRITICAL_DATA_ID_BASE U(0x80000000) +#endif /* MEASURED_BOOT */ + #endif /* COMMON_DEF_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 3fa63f555..9a61b502c 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -124,12 +124,22 @@ int plat_try_next_boot_source(void); #if MEASURED_BOOT int plat_mboot_measure_image(unsigned int image_id, image_info_t *image_data); +int plat_mboot_measure_critical_data(unsigned int critical_data_id, + const void *base, + size_t size); #else static inline int plat_mboot_measure_image(unsigned int image_id __unused, image_info_t *image_data __unused) { return 0; } +static inline int plat_mboot_measure_critical_data( + unsigned int critical_data_id __unused, + const void *base __unused, + size_t size __unused) +{ + return 0; +} #endif /* MEASURED_BOOT */ /******************************************************************************* diff --git a/plat/arm/board/fvp/fvp_bl2_measured_boot.c b/plat/arm/board/fvp/fvp_bl2_measured_boot.c index decf13d92..4943e58c5 100644 --- a/plat/arm/board/fvp/fvp_bl2_measured_boot.c +++ b/plat/arm/board/fvp/fvp_bl2_measured_boot.c @@ -7,7 +7,11 @@ #include #include +#include +#include + #include +#include /* Event Log data */ static uint64_t event_log_base; @@ -25,6 +29,8 @@ const event_log_metadata_t fvp_event_log_metadata[] = { { SOC_FW_CONFIG_ID, EVLOG_SOC_FW_CONFIG_STRING, PCR_0 }, { TOS_FW_CONFIG_ID, EVLOG_TOS_FW_CONFIG_STRING, PCR_0 }, + { CRITICAL_DATA_ID, EVLOG_CRITICAL_DATA_STRING, PCR_1 }, + { EVLOG_INVALID_ID, NULL, (unsigned int)(-1) } /* Terminator */ }; @@ -59,6 +65,60 @@ void bl2_plat_mboot_init(void) event_log_init((uint8_t *)event_log_start, event_log_finish); } +int plat_mboot_measure_critical_data(unsigned int critical_data_id, + const void *base, size_t size) +{ + /* + * It is very unlikely that the critical data size would be + * bigger than 2^32 bytes + */ + assert(size < UINT32_MAX); + assert(base != NULL); + + /* Calculate image hash and record data in Event Log */ + int err = event_log_measure_and_record((uintptr_t)base, (uint32_t)size, + critical_data_id); + if (err != 0) { + ERROR("%s%s critical data (%i)\n", + "Failed to ", "record", err); + return err; + } + + return 0; +} + +static int fvp_populate_critical_data(struct fvp_critical_data *critical_data) +{ + char *nv_ctr_oids[MAX_NV_CTR_IDS] = { + [TRUSTED_NV_CTR_ID] = TRUSTED_FW_NVCOUNTER_OID, + [NON_TRUSTED_NV_CTR_ID] = NON_TRUSTED_FW_NVCOUNTER_OID, + }; + + for (int i = 0; i < MAX_NV_CTR_IDS; i++) { + int rc = plat_get_nv_ctr(nv_ctr_oids[i], + &critical_data->nv_ctr[i]); + if (rc != 0) { + return rc; + } + } + + return 0; +} + +static int fvp_populate_and_measure_critical_data(void) +{ + struct fvp_critical_data populate_critical_data; + + int rc = fvp_populate_critical_data(&populate_critical_data); + if (rc == 0) { + rc = plat_mboot_measure_critical_data(CRITICAL_DATA_ID, + &populate_critical_data, + sizeof(populate_critical_data)); + } + + return rc; +} + void bl2_plat_mboot_finish(void) { int rc; @@ -69,6 +129,11 @@ void bl2_plat_mboot_finish(void) /* Event Log filled size */ size_t event_log_cur_size; + rc = fvp_populate_and_measure_critical_data(); + if (rc != 0) { + panic(); + } + event_log_cur_size = event_log_get_cur_size((uint8_t *)event_log_base); rc = arm_set_nt_fw_info( diff --git a/plat/arm/board/fvp/include/fvp_critical_data.h b/plat/arm/board/fvp/include/fvp_critical_data.h new file mode 100644 index 000000000..3010d2180 --- /dev/null +++ b/plat/arm/board/fvp/include/fvp_critical_data.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#define EVLOG_CRITICAL_DATA_STRING "CRITICAL DATA" + +#define CRITICAL_DATA_ID CRITICAL_DATA_ID_BASE + +struct fvp_critical_data { + + /* platform NV counters */ + unsigned int nv_ctr[MAX_NV_CTR_IDS]; +};