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