1 /* 2 * Copyright (c) 2022-2025 Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * DRTM measurements into TPM PCRs. 7 * 8 * Authors: 9 * Lucian Paul-Trifu <lucian.paultrifu@gmail.com> 10 * 11 */ 12 #include <assert.h> 13 14 #include <common/debug.h> 15 #include <drivers/auth/crypto_mod.h> 16 #include <drivers/measured_boot/event_log/event_log.h> 17 #include "drtm_main.h" 18 #include "drtm_measurements.h" 19 #include <lib/xlat_tables/xlat_tables_v2.h> 20 21 /* Event Log buffer */ 22 static uint8_t drtm_event_log[PLAT_DRTM_EVENT_LOG_MAX_SIZE]; 23 24 /* 25 * Calculate and write hash of various payloads as per DRTM specification 26 * to Event Log. 27 * 28 * @param[in] data_base Address of data 29 * @param[in] data_size Size of data 30 * @param[in] event_type Type of Event 31 * @param[in] event_name Name of the Event 32 * @return: 33 * 0 = success 34 * < 0 = error 35 */ 36 static int drtm_event_log_measure_and_record(uintptr_t data_base, 37 uint32_t data_size, 38 uint32_t event_type, 39 const char *event_name, 40 unsigned int pcr) 41 { 42 int rc; 43 unsigned char hash_data[CRYPTO_MD_MAX_SIZE]; 44 event_log_metadata_t metadata = {0}; 45 46 metadata.name = event_name; 47 metadata.pcr = pcr; 48 49 /* 50 * Measure the payloads requested by D-CRTM and DCE components 51 * Hash algorithm decided by the Event Log driver at build-time 52 */ 53 rc = event_log_measure(data_base, data_size, hash_data); 54 if (rc != 0) { 55 return rc; 56 } 57 58 /* Record the mesasurement in the EventLog buffer */ 59 rc = event_log_record(hash_data, event_type, &metadata); 60 if (rc != 0) { 61 return rc; 62 } 63 64 return 0; 65 } 66 67 /* 68 * Initialise Event Log global variables, used during the recording 69 * of various payload measurements into the Event Log buffer 70 * 71 * @param[in] event_log_start Base address of Event Log buffer 72 * @param[in] event_log_finish End address of Event Log buffer, 73 * it is a first byte past end of the 74 * buffer 75 */ 76 static void drtm_event_log_init(uint8_t *event_log_start, 77 uint8_t *event_log_finish) 78 { 79 event_log_buf_init(event_log_start, event_log_finish); 80 event_log_write_specid_event(); 81 } 82 83 enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a) 84 { 85 int rc; 86 uintptr_t dlme_img_mapping; 87 uint64_t dlme_img_ep; 88 size_t dlme_img_mapping_bytes; 89 uint8_t drtm_null_data = 0U; 90 uint8_t pcr_schema = DL_ARGS_GET_PCR_SCHEMA(a); 91 const char *drtm_event_arm_sep_data = "ARM_DRTM"; 92 93 /* Initialise the EventLog driver */ 94 drtm_event_log_init(drtm_event_log, drtm_event_log + 95 sizeof(drtm_event_log)); 96 97 /** 98 * Measurements extended into PCR-17. 99 * 100 * PCR-17: Measure the DCE image. Extend digest of (char)0 into PCR-17 101 * since the D-CRTM and the DCE are not separate. 102 */ 103 rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data, 104 sizeof(drtm_null_data), 105 DRTM_EVENT_ARM_DCE, NULL, 106 PCR_17); 107 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE)); 108 109 /* PCR-17: Measure the PCR schema DRTM launch argument. */ 110 rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema, 111 sizeof(pcr_schema), 112 DRTM_EVENT_ARM_PCR_SCHEMA, 113 NULL, PCR_17); 114 CHECK_RC(rc, 115 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA)); 116 117 /* PCR-17: Measure the enable state of external-debug, and trace. */ 118 /* 119 * TODO: Measure the enable state of external-debug and trace. This should 120 * be returned through a platform-specific hook. 121 */ 122 123 /* PCR-17: Measure the security lifecycle state. */ 124 /* 125 * TODO: Measure the security lifecycle state. This is an implementation- 126 * defined value, retrieved through an implementation-defined mechanisms. 127 */ 128 129 /* 130 * PCR-17: Optionally measure the NWd DCE. 131 * It is expected that such subsequent DCE stages are signed and verified. 132 * Whether they are measured in addition to signing is implementation 133 * -defined. 134 * Here the choice is to not measure any NWd DCE, in favour of PCR value 135 * resilience to any NWd DCE updates. 136 */ 137 138 /* PCR-17: End of DCE measurements. */ 139 rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data, 140 strlen(drtm_event_arm_sep_data), 141 DRTM_EVENT_ARM_SEPARATOR, 142 drtm_event_arm_sep_data, 143 PCR_17); 144 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR)); 145 146 /** 147 * Measurements extended into PCR-18. 148 * 149 * PCR-18: Measure the PCR schema DRTM launch argument. 150 */ 151 rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema, 152 sizeof(pcr_schema), 153 DRTM_EVENT_ARM_PCR_SCHEMA, 154 NULL, PCR_18); 155 CHECK_RC(rc, 156 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA)); 157 158 /* 159 * PCR-18: Measure the public key used to verify DCE image(s) signatures. 160 * Extend digest of (char)0, since we do not expect the NWd DCE to be 161 * present. 162 */ 163 assert(a->dce_nwd_size == 0); 164 rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data, 165 sizeof(drtm_null_data), 166 DRTM_EVENT_ARM_DCE_PUBKEY, 167 NULL, PCR_18); 168 CHECK_RC(rc, 169 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE_PUBKEY)); 170 171 /* PCR-18: Measure the DLME image. */ 172 dlme_img_mapping_bytes = page_align(a->dlme_img_size, UP); 173 rc = mmap_add_dynamic_region_alloc_va(a->dlme_paddr + a->dlme_img_off, 174 &dlme_img_mapping, 175 dlme_img_mapping_bytes, MT_RO_DATA | MT_NS); 176 if (rc) { 177 WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n", 178 __func__, rc); 179 return INTERNAL_ERROR; 180 } 181 182 rc = drtm_event_log_measure_and_record(dlme_img_mapping, a->dlme_img_size, 183 DRTM_EVENT_ARM_DLME, NULL, 184 PCR_18); 185 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME)); 186 187 rc = mmap_remove_dynamic_region(dlme_img_mapping, dlme_img_mapping_bytes); 188 CHECK_RC(rc, mmap_remove_dynamic_region); 189 190 /* PCR-18: Measure the DLME image entry point. */ 191 dlme_img_ep = DL_ARGS_GET_DLME_ENTRY_POINT(a); 192 drtm_event_log_measure_and_record((uintptr_t)&(a->dlme_img_ep_off), 193 sizeof(dlme_img_ep), 194 DRTM_EVENT_ARM_DLME_EP, NULL, 195 PCR_18); 196 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME_EP)); 197 198 /* PCR-18: End of DCE measurements. */ 199 rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data, 200 strlen(drtm_event_arm_sep_data), 201 DRTM_EVENT_ARM_SEPARATOR, 202 drtm_event_arm_sep_data, 203 PCR_18); 204 CHECK_RC(rc, 205 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR)); 206 207 /* Measure no Action event but not extend it in PCR */ 208 CHECK_RC(rc, 209 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_NO_ACTION)); 210 /* 211 * If the DCE is unable to log a measurement because there is no available 212 * space in the event log region, the DCE must extend a hash of the value 213 * 0xFF (1 byte in size) into PCR[17] and PCR[18] and enter remediation. 214 */ 215 216 return SUCCESS; 217 } 218 219 void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out) 220 { 221 *event_log_size_out = event_log_get_cur_size(drtm_event_log); 222 memcpy(dst, drtm_event_log, *event_log_size_out); 223 } 224