123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- /*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * DRTM measurements into TPM PCRs.
- *
- * Authors:
- * Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
- *
- */
- #include <assert.h>
- #include <common/debug.h>
- #include <drivers/auth/crypto_mod.h>
- #include <drivers/measured_boot/event_log/event_log.h>
- #include "drtm_main.h"
- #include "drtm_measurements.h"
- #include <lib/xlat_tables/xlat_tables_v2.h>
- /* 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 components
- * 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);
- }
|