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 */ 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 */ 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 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 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