140814266SManish V Badarkhe /*
22ec44880SManish V Badarkhe * Copyright (c) 2022-2025 Arm Limited. All rights reserved.
340814266SManish V Badarkhe *
440814266SManish V Badarkhe * SPDX-License-Identifier: BSD-3-Clause
540814266SManish V Badarkhe *
640814266SManish V Badarkhe * DRTM measurements into TPM PCRs.
740814266SManish V Badarkhe *
840814266SManish V Badarkhe * Authors:
940814266SManish V Badarkhe * Lucian Paul-Trifu <lucian.paultrifu@gmail.com>
1040814266SManish V Badarkhe *
1140814266SManish V Badarkhe */
1240814266SManish V Badarkhe #include <assert.h>
1340814266SManish V Badarkhe
1440814266SManish V Badarkhe #include <common/debug.h>
1540814266SManish V Badarkhe #include <drivers/auth/crypto_mod.h>
16*b67e9846SHarrison Mutai #include <event_measure.h>
17*b67e9846SHarrison Mutai #include <event_print.h>
18*b67e9846SHarrison Mutai #include <lib/xlat_tables/xlat_tables_v2.h>
19*b67e9846SHarrison Mutai
2040814266SManish V Badarkhe #include "drtm_main.h"
2140814266SManish V Badarkhe #include "drtm_measurements.h"
2240814266SManish V Badarkhe
2340814266SManish V Badarkhe /* Event Log buffer */
2440814266SManish V Badarkhe static uint8_t drtm_event_log[PLAT_DRTM_EVENT_LOG_MAX_SIZE];
25*b67e9846SHarrison Mutai static const struct event_log_hash_info crypto_hash_info = {
26*b67e9846SHarrison Mutai .func = crypto_mod_calc_hash,
27*b67e9846SHarrison Mutai .ids = (const uint32_t[]){ CRYPTO_MD_ID },
28*b67e9846SHarrison Mutai .count = 1U,
29*b67e9846SHarrison Mutai };
3040814266SManish V Badarkhe
3140814266SManish V Badarkhe /*
3240814266SManish V Badarkhe * Calculate and write hash of various payloads as per DRTM specification
3340814266SManish V Badarkhe * to Event Log.
3440814266SManish V Badarkhe *
3540814266SManish V Badarkhe * @param[in] data_base Address of data
3640814266SManish V Badarkhe * @param[in] data_size Size of data
3740814266SManish V Badarkhe * @param[in] event_type Type of Event
3840814266SManish V Badarkhe * @param[in] event_name Name of the Event
3940814266SManish V Badarkhe * @return:
4040814266SManish V Badarkhe * 0 = success
4140814266SManish V Badarkhe * < 0 = error
4240814266SManish V Badarkhe */
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)4340814266SManish V Badarkhe static int drtm_event_log_measure_and_record(uintptr_t data_base,
4440814266SManish V Badarkhe uint32_t data_size,
4540814266SManish V Badarkhe uint32_t event_type,
4640814266SManish V Badarkhe const char *event_name,
4740814266SManish V Badarkhe unsigned int pcr)
4840814266SManish V Badarkhe {
4940814266SManish V Badarkhe int rc;
5040814266SManish V Badarkhe unsigned char hash_data[CRYPTO_MD_MAX_SIZE];
5140814266SManish V Badarkhe event_log_metadata_t metadata = {0};
5240814266SManish V Badarkhe
5340814266SManish V Badarkhe metadata.name = event_name;
5440814266SManish V Badarkhe metadata.pcr = pcr;
5540814266SManish V Badarkhe
5640814266SManish V Badarkhe /*
571b491eeaSElyes Haouas * Measure the payloads requested by D-CRTM and DCE components
5840814266SManish V Badarkhe * Hash algorithm decided by the Event Log driver at build-time
5940814266SManish V Badarkhe */
6040814266SManish V Badarkhe rc = event_log_measure(data_base, data_size, hash_data);
6140814266SManish V Badarkhe if (rc != 0) {
6240814266SManish V Badarkhe return rc;
6340814266SManish V Badarkhe }
6440814266SManish V Badarkhe
6540814266SManish V Badarkhe /* Record the mesasurement in the EventLog buffer */
66cb03020eSHarrison Mutai rc = event_log_record(hash_data, event_type, &metadata);
67cb03020eSHarrison Mutai if (rc != 0) {
68cb03020eSHarrison Mutai return rc;
69cb03020eSHarrison Mutai }
7040814266SManish V Badarkhe
7140814266SManish V Badarkhe return 0;
7240814266SManish V Badarkhe }
7340814266SManish V Badarkhe
7440814266SManish V Badarkhe /*
7540814266SManish V Badarkhe * Initialise Event Log global variables, used during the recording
7640814266SManish V Badarkhe * of various payload measurements into the Event Log buffer
7740814266SManish V Badarkhe *
7840814266SManish V Badarkhe * @param[in] event_log_start Base address of Event Log buffer
7940814266SManish V Badarkhe * @param[in] event_log_finish End address of Event Log buffer,
8040814266SManish V Badarkhe * it is a first byte past end of the
8140814266SManish V Badarkhe * buffer
8240814266SManish V Badarkhe */
drtm_event_log_init(uint8_t * event_log_start,uint8_t * event_log_finish)8340814266SManish V Badarkhe static void drtm_event_log_init(uint8_t *event_log_start,
8440814266SManish V Badarkhe uint8_t *event_log_finish)
8540814266SManish V Badarkhe {
86*b67e9846SHarrison Mutai int rc = event_log_init_and_reg(event_log_start, event_log_finish,
87*b67e9846SHarrison Mutai &crypto_hash_info);
88*b67e9846SHarrison Mutai if (rc < 0) {
89*b67e9846SHarrison Mutai ERROR("Failed to initialize event log (%d).\n", rc);
90*b67e9846SHarrison Mutai panic();
91*b67e9846SHarrison Mutai }
92*b67e9846SHarrison Mutai
93*b67e9846SHarrison Mutai rc = event_log_write_specid_event();
94*b67e9846SHarrison Mutai if (rc < 0) {
95*b67e9846SHarrison Mutai ERROR("Failed to write Specification ID Event (%d).\n", rc);
96*b67e9846SHarrison Mutai panic();
97*b67e9846SHarrison Mutai }
9840814266SManish V Badarkhe }
9940814266SManish V Badarkhe
drtm_take_measurements(const struct_drtm_dl_args * a)10040814266SManish V Badarkhe enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a)
10140814266SManish V Badarkhe {
10240814266SManish V Badarkhe int rc;
10340814266SManish V Badarkhe uintptr_t dlme_img_mapping;
10440814266SManish V Badarkhe uint64_t dlme_img_ep;
10540814266SManish V Badarkhe size_t dlme_img_mapping_bytes;
10640814266SManish V Badarkhe uint8_t drtm_null_data = 0U;
10740814266SManish V Badarkhe uint8_t pcr_schema = DL_ARGS_GET_PCR_SCHEMA(a);
10840814266SManish V Badarkhe const char *drtm_event_arm_sep_data = "ARM_DRTM";
10940814266SManish V Badarkhe
11040814266SManish V Badarkhe /* Initialise the EventLog driver */
11140814266SManish V Badarkhe drtm_event_log_init(drtm_event_log, drtm_event_log +
11240814266SManish V Badarkhe sizeof(drtm_event_log));
11340814266SManish V Badarkhe
11440814266SManish V Badarkhe /**
11540814266SManish V Badarkhe * Measurements extended into PCR-17.
11640814266SManish V Badarkhe *
11740814266SManish V Badarkhe * PCR-17: Measure the DCE image. Extend digest of (char)0 into PCR-17
11840814266SManish V Badarkhe * since the D-CRTM and the DCE are not separate.
11940814266SManish V Badarkhe */
12040814266SManish V Badarkhe rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
12140814266SManish V Badarkhe sizeof(drtm_null_data),
12240814266SManish V Badarkhe DRTM_EVENT_ARM_DCE, NULL,
12340814266SManish V Badarkhe PCR_17);
12440814266SManish V Badarkhe CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE));
12540814266SManish V Badarkhe
12640814266SManish V Badarkhe /* PCR-17: Measure the PCR schema DRTM launch argument. */
12740814266SManish V Badarkhe rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
12840814266SManish V Badarkhe sizeof(pcr_schema),
12940814266SManish V Badarkhe DRTM_EVENT_ARM_PCR_SCHEMA,
13040814266SManish V Badarkhe NULL, PCR_17);
13140814266SManish V Badarkhe CHECK_RC(rc,
13240814266SManish V Badarkhe drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
13340814266SManish V Badarkhe
13440814266SManish V Badarkhe /* PCR-17: Measure the enable state of external-debug, and trace. */
13540814266SManish V Badarkhe /*
13640814266SManish V Badarkhe * TODO: Measure the enable state of external-debug and trace. This should
13740814266SManish V Badarkhe * be returned through a platform-specific hook.
13840814266SManish V Badarkhe */
13940814266SManish V Badarkhe
14040814266SManish V Badarkhe /* PCR-17: Measure the security lifecycle state. */
14140814266SManish V Badarkhe /*
14240814266SManish V Badarkhe * TODO: Measure the security lifecycle state. This is an implementation-
14340814266SManish V Badarkhe * defined value, retrieved through an implementation-defined mechanisms.
14440814266SManish V Badarkhe */
14540814266SManish V Badarkhe
14640814266SManish V Badarkhe /*
14740814266SManish V Badarkhe * PCR-17: Optionally measure the NWd DCE.
14840814266SManish V Badarkhe * It is expected that such subsequent DCE stages are signed and verified.
14940814266SManish V Badarkhe * Whether they are measured in addition to signing is implementation
15040814266SManish V Badarkhe * -defined.
15140814266SManish V Badarkhe * Here the choice is to not measure any NWd DCE, in favour of PCR value
15240814266SManish V Badarkhe * resilience to any NWd DCE updates.
15340814266SManish V Badarkhe */
15440814266SManish V Badarkhe
15540814266SManish V Badarkhe /* PCR-17: End of DCE measurements. */
15640814266SManish V Badarkhe rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
15740814266SManish V Badarkhe strlen(drtm_event_arm_sep_data),
15894aa3d27SManish V Badarkhe DRTM_EVENT_ARM_SEPARATOR,
15994aa3d27SManish V Badarkhe drtm_event_arm_sep_data,
16040814266SManish V Badarkhe PCR_17);
16140814266SManish V Badarkhe CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
16240814266SManish V Badarkhe
16340814266SManish V Badarkhe /**
16440814266SManish V Badarkhe * Measurements extended into PCR-18.
16540814266SManish V Badarkhe *
16640814266SManish V Badarkhe * PCR-18: Measure the PCR schema DRTM launch argument.
16740814266SManish V Badarkhe */
16840814266SManish V Badarkhe rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
16940814266SManish V Badarkhe sizeof(pcr_schema),
17040814266SManish V Badarkhe DRTM_EVENT_ARM_PCR_SCHEMA,
17140814266SManish V Badarkhe NULL, PCR_18);
17240814266SManish V Badarkhe CHECK_RC(rc,
17340814266SManish V Badarkhe drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
17440814266SManish V Badarkhe
17540814266SManish V Badarkhe /*
17640814266SManish V Badarkhe * PCR-18: Measure the public key used to verify DCE image(s) signatures.
17740814266SManish V Badarkhe * Extend digest of (char)0, since we do not expect the NWd DCE to be
17840814266SManish V Badarkhe * present.
17940814266SManish V Badarkhe */
18040814266SManish V Badarkhe assert(a->dce_nwd_size == 0);
18140814266SManish V Badarkhe rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
18240814266SManish V Badarkhe sizeof(drtm_null_data),
18340814266SManish V Badarkhe DRTM_EVENT_ARM_DCE_PUBKEY,
18440814266SManish V Badarkhe NULL, PCR_18);
18540814266SManish V Badarkhe CHECK_RC(rc,
18640814266SManish V Badarkhe drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE_PUBKEY));
18740814266SManish V Badarkhe
18840814266SManish V Badarkhe /* PCR-18: Measure the DLME image. */
18940814266SManish V Badarkhe dlme_img_mapping_bytes = page_align(a->dlme_img_size, UP);
19040814266SManish V Badarkhe rc = mmap_add_dynamic_region_alloc_va(a->dlme_paddr + a->dlme_img_off,
19140814266SManish V Badarkhe &dlme_img_mapping,
19240814266SManish V Badarkhe dlme_img_mapping_bytes, MT_RO_DATA | MT_NS);
19340814266SManish V Badarkhe if (rc) {
19440814266SManish V Badarkhe WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n",
19540814266SManish V Badarkhe __func__, rc);
19640814266SManish V Badarkhe return INTERNAL_ERROR;
19740814266SManish V Badarkhe }
19840814266SManish V Badarkhe
19940814266SManish V Badarkhe rc = drtm_event_log_measure_and_record(dlme_img_mapping, a->dlme_img_size,
20040814266SManish V Badarkhe DRTM_EVENT_ARM_DLME, NULL,
20140814266SManish V Badarkhe PCR_18);
20240814266SManish V Badarkhe CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME));
20340814266SManish V Badarkhe
20440814266SManish V Badarkhe rc = mmap_remove_dynamic_region(dlme_img_mapping, dlme_img_mapping_bytes);
20540814266SManish V Badarkhe CHECK_RC(rc, mmap_remove_dynamic_region);
20640814266SManish V Badarkhe
20740814266SManish V Badarkhe /* PCR-18: Measure the DLME image entry point. */
20840814266SManish V Badarkhe dlme_img_ep = DL_ARGS_GET_DLME_ENTRY_POINT(a);
209f3fec61fSManish V Badarkhe drtm_event_log_measure_and_record((uintptr_t)&(a->dlme_img_ep_off),
21040814266SManish V Badarkhe sizeof(dlme_img_ep),
21140814266SManish V Badarkhe DRTM_EVENT_ARM_DLME_EP, NULL,
21240814266SManish V Badarkhe PCR_18);
21340814266SManish V Badarkhe CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME_EP));
21440814266SManish V Badarkhe
21540814266SManish V Badarkhe /* PCR-18: End of DCE measurements. */
21640814266SManish V Badarkhe rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
21740814266SManish V Badarkhe strlen(drtm_event_arm_sep_data),
21894aa3d27SManish V Badarkhe DRTM_EVENT_ARM_SEPARATOR,
21994aa3d27SManish V Badarkhe drtm_event_arm_sep_data,
22040814266SManish V Badarkhe PCR_18);
22140814266SManish V Badarkhe CHECK_RC(rc,
22240814266SManish V Badarkhe drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
2232ec44880SManish V Badarkhe
2242ec44880SManish V Badarkhe /* Measure no Action event but not extend it in PCR */
2252ec44880SManish V Badarkhe CHECK_RC(rc,
2262ec44880SManish V Badarkhe drtm_event_log_measure_and_record(DRTM_EVENT_ARM_NO_ACTION));
22740814266SManish V Badarkhe /*
22840814266SManish V Badarkhe * If the DCE is unable to log a measurement because there is no available
22940814266SManish V Badarkhe * space in the event log region, the DCE must extend a hash of the value
23040814266SManish V Badarkhe * 0xFF (1 byte in size) into PCR[17] and PCR[18] and enter remediation.
23140814266SManish V Badarkhe */
23240814266SManish V Badarkhe
23340814266SManish V Badarkhe return SUCCESS;
23440814266SManish V Badarkhe }
23540814266SManish V Badarkhe
drtm_serialise_event_log(uint8_t * dst,size_t * event_log_size_out)23640814266SManish V Badarkhe void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out)
23740814266SManish V Badarkhe {
23840814266SManish V Badarkhe *event_log_size_out = event_log_get_cur_size(drtm_event_log);
23940814266SManish V Badarkhe memcpy(dst, drtm_event_log, *event_log_size_out);
24040814266SManish V Badarkhe }
241