From 40814266d53b7154daf5d212de481b397db43823 Mon Sep 17 00:00:00 2001 From: Manish V Badarkhe Date: Fri, 17 Jun 2022 11:42:17 +0100 Subject: [PATCH] feat(drtm): add Event Log driver support for DRTM Added Event Log driver support for DRTM. This driver is responsible for the doing the hash measurement of various DRTM components as per [1], and putting these measurements in the Event Log buffer. [1]: https://developer.arm.com/documentation/den0113/a, section 3.16 Change-Id: I9892c313cf6640b82e261738116fe00f7975ee12 Signed-off-by: Manish V Badarkhe --- bl31/bl31.mk | 1 + plat/arm/common/arm_common.mk | 12 +- services/std_svc/drtm/drtm_main.h | 4 + services/std_svc/drtm/drtm_measurements.c | 214 ++++++++++++++++++++++ services/std_svc/drtm/drtm_measurements.h | 40 ++++ 5 files changed, 268 insertions(+), 3 deletions(-) create mode 100644 services/std_svc/drtm/drtm_measurements.c create mode 100644 services/std_svc/drtm/drtm_measurements.h diff --git a/bl31/bl31.mk b/bl31/bl31.mk index f435815ce..9f7d96e86 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -151,6 +151,7 @@ ifeq (${DRTM_SUPPORT},1) BL31_SOURCES += services/std_svc/drtm/drtm_main.c \ services/std_svc/drtm/drtm_dma_prot.c \ services/std_svc/drtm/drtm_res_address_map.c \ + services/std_svc/drtm/drtm_measurements.c \ ${MBEDTLS_SOURCES} endif diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 5dda4853b..ccf2b4597 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -406,7 +406,7 @@ endif # Include Measured Boot makefile before any Crypto library makefile. # Crypto library makefile may need default definitions of Measured Boot build # flags present in Measured Boot makefile. -ifeq (${MEASURED_BOOT},1) +ifneq ($(filter 1,${MEASURED_BOOT} ${DRTM_SUPPORT}),) MEASURED_BOOT_MK := drivers/measured_boot/event_log/event_log.mk $(info Including ${MEASURED_BOOT_MK}) include ${MEASURED_BOOT_MK} @@ -415,8 +415,14 @@ ifeq (${MEASURED_BOOT},1) $(eval $(call add_define,TF_MBEDTLS_MBOOT_USE_SHA512)) endif - BL1_SOURCES += ${EVENT_LOG_SOURCES} - BL2_SOURCES += ${EVENT_LOG_SOURCES} + ifeq (${MEASURED_BOOT},1) + BL1_SOURCES += ${EVENT_LOG_SOURCES} + BL2_SOURCES += ${EVENT_LOG_SOURCES} + endif + + ifeq (${DRTM_SUPPORT},1) + BL31_SOURCES += ${EVENT_LOG_SOURCES} + endif endif ifneq ($(filter 1,${MEASURED_BOOT} ${TRUSTED_BOARD_BOOT} ${DRTM_SUPPORT}),) diff --git a/services/std_svc/drtm/drtm_main.h b/services/std_svc/drtm/drtm_main.h index 59e56080a..cccc14f96 100644 --- a/services/std_svc/drtm/drtm_main.h +++ b/services/std_svc/drtm/drtm_main.h @@ -31,6 +31,10 @@ #define DRTM_PAGE_SIZE (4 * (1 << 10)) #define DRTM_PAGE_SIZE_STR "4-KiB" +#define DL_ARGS_GET_PCR_SCHEMA(a) (((a)->features >> 1) & 0x3U) +#define DL_ARGS_GET_DLME_ENTRY_POINT(a) \ + (((a)->dlme_paddr + (a)->dlme_img_off + (a)->dlme_img_ep_off)) + enum drtm_retc { SUCCESS = SMC_OK, NOT_SUPPORTED = SMC_UNK, diff --git a/services/std_svc/drtm/drtm_measurements.c b/services/std_svc/drtm/drtm_measurements.c new file mode 100644 index 000000000..a8f2b3267 --- /dev/null +++ b/services/std_svc/drtm/drtm_measurements.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * DRTM measurements into TPM PCRs. + * + * Authors: + * Lucian Paul-Trifu + * + */ +#include + +#include +#include +#include +#include "drtm_main.h" +#include "drtm_measurements.h" +#include + +/* Event Log buffer */ +static uint8_t drtm_event_log[PLAT_DRTM_EVENT_LOG_MAX_SIZE]; + +/* + * Calculate and write hash of various payloads as per DRTM specification + * to Event Log. + * + * @param[in] data_base Address of data + * @param[in] data_size Size of data + * @param[in] event_type Type of Event + * @param[in] event_name Name of the Event + * @return: + * 0 = success + * < 0 = error + */ +static int drtm_event_log_measure_and_record(uintptr_t data_base, + uint32_t data_size, + uint32_t event_type, + const char *event_name, + unsigned int pcr) +{ + int rc; + unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; + event_log_metadata_t metadata = {0}; + + metadata.name = event_name; + metadata.pcr = pcr; + + /* + * Measure the payloads requested by D-CRTM and DCE commponents + * Hash algorithm decided by the Event Log driver at build-time + */ + rc = event_log_measure(data_base, data_size, hash_data); + if (rc != 0) { + return rc; + } + + /* Record the mesasurement in the EventLog buffer */ + event_log_record(hash_data, event_type, &metadata); + + return 0; +} + +/* + * Initialise Event Log global variables, used during the recording + * of various payload measurements into the Event Log buffer + * + * @param[in] event_log_start Base address of Event Log buffer + * @param[in] event_log_finish End address of Event Log buffer, + * it is a first byte past end of the + * buffer + */ +static void drtm_event_log_init(uint8_t *event_log_start, + uint8_t *event_log_finish) +{ + event_log_buf_init(event_log_start, event_log_finish); + event_log_write_specid_event(); +} + +enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a) +{ + int rc; + uintptr_t dlme_img_mapping; + uint64_t dlme_img_ep; + size_t dlme_img_mapping_bytes; + uint8_t drtm_null_data = 0U; + uint8_t pcr_schema = DL_ARGS_GET_PCR_SCHEMA(a); + const char *drtm_event_arm_sep_data = "ARM_DRTM"; + + /* Initialise the EventLog driver */ + drtm_event_log_init(drtm_event_log, drtm_event_log + + sizeof(drtm_event_log)); + + /** + * Measurements extended into PCR-17. + * + * PCR-17: Measure the DCE image. Extend digest of (char)0 into PCR-17 + * since the D-CRTM and the DCE are not separate. + */ + rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data, + sizeof(drtm_null_data), + DRTM_EVENT_ARM_DCE, NULL, + PCR_17); + CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE)); + + /* PCR-17: Measure the PCR schema DRTM launch argument. */ + rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema, + sizeof(pcr_schema), + DRTM_EVENT_ARM_PCR_SCHEMA, + NULL, PCR_17); + CHECK_RC(rc, + drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA)); + + /* PCR-17: Measure the enable state of external-debug, and trace. */ + /* + * TODO: Measure the enable state of external-debug and trace. This should + * be returned through a platform-specific hook. + */ + + /* PCR-17: Measure the security lifecycle state. */ + /* + * TODO: Measure the security lifecycle state. This is an implementation- + * defined value, retrieved through an implementation-defined mechanisms. + */ + + /* + * PCR-17: Optionally measure the NWd DCE. + * It is expected that such subsequent DCE stages are signed and verified. + * Whether they are measured in addition to signing is implementation + * -defined. + * Here the choice is to not measure any NWd DCE, in favour of PCR value + * resilience to any NWd DCE updates. + */ + + /* PCR-17: End of DCE measurements. */ + rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data, + strlen(drtm_event_arm_sep_data), + DRTM_EVENT_ARM_SEPARATOR, NULL, + PCR_17); + CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR)); + + /** + * Measurements extended into PCR-18. + * + * PCR-18: Measure the PCR schema DRTM launch argument. + */ + rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema, + sizeof(pcr_schema), + DRTM_EVENT_ARM_PCR_SCHEMA, + NULL, PCR_18); + CHECK_RC(rc, + drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA)); + + /* + * PCR-18: Measure the public key used to verify DCE image(s) signatures. + * Extend digest of (char)0, since we do not expect the NWd DCE to be + * present. + */ + assert(a->dce_nwd_size == 0); + rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data, + sizeof(drtm_null_data), + DRTM_EVENT_ARM_DCE_PUBKEY, + NULL, PCR_18); + CHECK_RC(rc, + drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE_PUBKEY)); + + /* PCR-18: Measure the DLME image. */ + dlme_img_mapping_bytes = page_align(a->dlme_img_size, UP); + rc = mmap_add_dynamic_region_alloc_va(a->dlme_paddr + a->dlme_img_off, + &dlme_img_mapping, + dlme_img_mapping_bytes, MT_RO_DATA | MT_NS); + if (rc) { + WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n", + __func__, rc); + return INTERNAL_ERROR; + } + + rc = drtm_event_log_measure_and_record(dlme_img_mapping, a->dlme_img_size, + DRTM_EVENT_ARM_DLME, NULL, + PCR_18); + CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME)); + + rc = mmap_remove_dynamic_region(dlme_img_mapping, dlme_img_mapping_bytes); + CHECK_RC(rc, mmap_remove_dynamic_region); + + /* PCR-18: Measure the DLME image entry point. */ + dlme_img_ep = DL_ARGS_GET_DLME_ENTRY_POINT(a); + drtm_event_log_measure_and_record((uintptr_t)&dlme_img_ep, + sizeof(dlme_img_ep), + DRTM_EVENT_ARM_DLME_EP, NULL, + PCR_18); + CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME_EP)); + + /* PCR-18: End of DCE measurements. */ + rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data, + strlen(drtm_event_arm_sep_data), + DRTM_EVENT_ARM_SEPARATOR, NULL, + PCR_18); + CHECK_RC(rc, + drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR)); + /* + * If the DCE is unable to log a measurement because there is no available + * space in the event log region, the DCE must extend a hash of the value + * 0xFF (1 byte in size) into PCR[17] and PCR[18] and enter remediation. + */ + + return SUCCESS; +} + +void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out) +{ + *event_log_size_out = event_log_get_cur_size(drtm_event_log); + memcpy(dst, drtm_event_log, *event_log_size_out); +} diff --git a/services/std_svc/drtm/drtm_measurements.h b/services/std_svc/drtm/drtm_measurements.h new file mode 100644 index 000000000..6d7a84e93 --- /dev/null +++ b/services/std_svc/drtm/drtm_measurements.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + */ +#ifndef DRTM_MEASUREMENTS_H +#define DRTM_MEASUREMENTS_H + +#include + +#include "drtm_main.h" +#include + +#define DRTM_EVENT_ARM_BASE 0x9000U +#define DRTM_EVENT_TYPE(n) (DRTM_EVENT_ARM_BASE + (unsigned int)(n)) + +#define DRTM_EVENT_ARM_PCR_SCHEMA DRTM_EVENT_TYPE(1) +#define DRTM_EVENT_ARM_DCE DRTM_EVENT_TYPE(2) +#define DRTM_EVENT_ARM_DCE_PUBKEY DRTM_EVENT_TYPE(3) +#define DRTM_EVENT_ARM_DLME DRTM_EVENT_TYPE(4) +#define DRTM_EVENT_ARM_DLME_EP DRTM_EVENT_TYPE(5) +#define DRTM_EVENT_ARM_DEBUG_CONFIG DRTM_EVENT_TYPE(6) +#define DRTM_EVENT_ARM_NONSECURE_CONFIG DRTM_EVENT_TYPE(7) +#define DRTM_EVENT_ARM_DCE_SECONDARY DRTM_EVENT_TYPE(8) +#define DRTM_EVENT_ARM_TZFW DRTM_EVENT_TYPE(9) +#define DRTM_EVENT_ARM_SEPARATOR DRTM_EVENT_TYPE(10) + +#define CHECK_RC(rc, func_call) { \ + if (rc != 0) { \ + ERROR("%s(): " #func_call "failed unexpectedly rc=%d\n", \ + __func__, rc); \ + panic(); \ + } \ +} + +enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a); +void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out); + +#endif /* DRTM_MEASUREMENTS_H */