1 /*
2 * Copyright (c) 2022 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 */
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)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 commponents
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 event_log_record(hash_data, event_type, &metadata);
60
61 return 0;
62 }
63
64 /*
65 * Initialise Event Log global variables, used during the recording
66 * of various payload measurements into the Event Log buffer
67 *
68 * @param[in] event_log_start Base address of Event Log buffer
69 * @param[in] event_log_finish End address of Event Log buffer,
70 * it is a first byte past end of the
71 * buffer
72 */
drtm_event_log_init(uint8_t * event_log_start,uint8_t * event_log_finish)73 static void drtm_event_log_init(uint8_t *event_log_start,
74 uint8_t *event_log_finish)
75 {
76 event_log_buf_init(event_log_start, event_log_finish);
77 event_log_write_specid_event();
78 }
79
drtm_take_measurements(const struct_drtm_dl_args * a)80 enum drtm_retc drtm_take_measurements(const struct_drtm_dl_args *a)
81 {
82 int rc;
83 uintptr_t dlme_img_mapping;
84 uint64_t dlme_img_ep;
85 size_t dlme_img_mapping_bytes;
86 uint8_t drtm_null_data = 0U;
87 uint8_t pcr_schema = DL_ARGS_GET_PCR_SCHEMA(a);
88 const char *drtm_event_arm_sep_data = "ARM_DRTM";
89
90 /* Initialise the EventLog driver */
91 drtm_event_log_init(drtm_event_log, drtm_event_log +
92 sizeof(drtm_event_log));
93
94 /**
95 * Measurements extended into PCR-17.
96 *
97 * PCR-17: Measure the DCE image. Extend digest of (char)0 into PCR-17
98 * since the D-CRTM and the DCE are not separate.
99 */
100 rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
101 sizeof(drtm_null_data),
102 DRTM_EVENT_ARM_DCE, NULL,
103 PCR_17);
104 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE));
105
106 /* PCR-17: Measure the PCR schema DRTM launch argument. */
107 rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
108 sizeof(pcr_schema),
109 DRTM_EVENT_ARM_PCR_SCHEMA,
110 NULL, PCR_17);
111 CHECK_RC(rc,
112 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
113
114 /* PCR-17: Measure the enable state of external-debug, and trace. */
115 /*
116 * TODO: Measure the enable state of external-debug and trace. This should
117 * be returned through a platform-specific hook.
118 */
119
120 /* PCR-17: Measure the security lifecycle state. */
121 /*
122 * TODO: Measure the security lifecycle state. This is an implementation-
123 * defined value, retrieved through an implementation-defined mechanisms.
124 */
125
126 /*
127 * PCR-17: Optionally measure the NWd DCE.
128 * It is expected that such subsequent DCE stages are signed and verified.
129 * Whether they are measured in addition to signing is implementation
130 * -defined.
131 * Here the choice is to not measure any NWd DCE, in favour of PCR value
132 * resilience to any NWd DCE updates.
133 */
134
135 /* PCR-17: End of DCE measurements. */
136 rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
137 strlen(drtm_event_arm_sep_data),
138 DRTM_EVENT_ARM_SEPARATOR, NULL,
139 PCR_17);
140 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
141
142 /**
143 * Measurements extended into PCR-18.
144 *
145 * PCR-18: Measure the PCR schema DRTM launch argument.
146 */
147 rc = drtm_event_log_measure_and_record((uintptr_t)&pcr_schema,
148 sizeof(pcr_schema),
149 DRTM_EVENT_ARM_PCR_SCHEMA,
150 NULL, PCR_18);
151 CHECK_RC(rc,
152 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_PCR_SCHEMA));
153
154 /*
155 * PCR-18: Measure the public key used to verify DCE image(s) signatures.
156 * Extend digest of (char)0, since we do not expect the NWd DCE to be
157 * present.
158 */
159 assert(a->dce_nwd_size == 0);
160 rc = drtm_event_log_measure_and_record((uintptr_t)&drtm_null_data,
161 sizeof(drtm_null_data),
162 DRTM_EVENT_ARM_DCE_PUBKEY,
163 NULL, PCR_18);
164 CHECK_RC(rc,
165 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DCE_PUBKEY));
166
167 /* PCR-18: Measure the DLME image. */
168 dlme_img_mapping_bytes = page_align(a->dlme_img_size, UP);
169 rc = mmap_add_dynamic_region_alloc_va(a->dlme_paddr + a->dlme_img_off,
170 &dlme_img_mapping,
171 dlme_img_mapping_bytes, MT_RO_DATA | MT_NS);
172 if (rc) {
173 WARN("DRTM: %s: mmap_add_dynamic_region() failed rc=%d\n",
174 __func__, rc);
175 return INTERNAL_ERROR;
176 }
177
178 rc = drtm_event_log_measure_and_record(dlme_img_mapping, a->dlme_img_size,
179 DRTM_EVENT_ARM_DLME, NULL,
180 PCR_18);
181 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME));
182
183 rc = mmap_remove_dynamic_region(dlme_img_mapping, dlme_img_mapping_bytes);
184 CHECK_RC(rc, mmap_remove_dynamic_region);
185
186 /* PCR-18: Measure the DLME image entry point. */
187 dlme_img_ep = DL_ARGS_GET_DLME_ENTRY_POINT(a);
188 drtm_event_log_measure_and_record((uintptr_t)&dlme_img_ep,
189 sizeof(dlme_img_ep),
190 DRTM_EVENT_ARM_DLME_EP, NULL,
191 PCR_18);
192 CHECK_RC(rc, drtm_event_log_measure_and_record(DRTM_EVENT_ARM_DLME_EP));
193
194 /* PCR-18: End of DCE measurements. */
195 rc = drtm_event_log_measure_and_record((uintptr_t)drtm_event_arm_sep_data,
196 strlen(drtm_event_arm_sep_data),
197 DRTM_EVENT_ARM_SEPARATOR, NULL,
198 PCR_18);
199 CHECK_RC(rc,
200 drtm_event_log_measure_and_record(DRTM_EVENT_ARM_SEPARATOR));
201 /*
202 * If the DCE is unable to log a measurement because there is no available
203 * space in the event log region, the DCE must extend a hash of the value
204 * 0xFF (1 byte in size) into PCR[17] and PCR[18] and enter remediation.
205 */
206
207 return SUCCESS;
208 }
209
drtm_serialise_event_log(uint8_t * dst,size_t * event_log_size_out)210 void drtm_serialise_event_log(uint8_t *dst, size_t *event_log_size_out)
211 {
212 *event_log_size_out = event_log_get_cur_size(drtm_event_log);
213 memcpy(dst, drtm_event_log, *event_log_size_out);
214 }
215