Skip to content

Commit ac93cbf

Browse files
committed
efi/libstub: Measure into CC protocol if TCG2 protocol is absent
To accommodate confidential compute VMs that expose the simplified CC measurement protocol instead of the full-blown TCG2 one, fall back to the former if the latter does not exist. The CC protocol was designed to be used in this manner, which is why the types and prototypes have been kept the same where possible. So reuse the existing code, and only deviate from the TCG2 code path where needed. Reviewed-by: Kuppuswamy Sathyanarayanan <[email protected]> Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 0bbe5b0 commit ac93cbf

File tree

1 file changed

+62
-22
lines changed

1 file changed

+62
-22
lines changed

drivers/firmware/efi/libstub/efi-stub-helper.c

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si
194194
*load_options_size = load_option_unpacked.optional_data_size;
195195
}
196196

197-
enum efistub_event {
197+
enum efistub_event_type {
198198
EFISTUB_EVT_INITRD,
199199
EFISTUB_EVT_LOAD_OPTIONS,
200200
EFISTUB_EVT_COUNT,
@@ -220,55 +220,95 @@ static const struct {
220220
},
221221
};
222222

223+
static_assert(sizeof(efi_tcg2_event_t) == sizeof(efi_cc_event_t));
224+
225+
union efistub_event {
226+
efi_tcg2_event_t tcg2_data;
227+
efi_cc_event_t cc_data;
228+
};
229+
223230
struct efistub_measured_event {
224-
efi_tcg2_event_t event_data;
231+
union efistub_event event_data;
225232
TCG_PCClientTaggedEvent tagged_event __packed;
226233
};
227234

228235
static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
229236
unsigned long load_size,
230-
enum efistub_event event)
237+
enum efistub_event_type event)
231238
{
239+
union {
240+
efi_status_t
241+
(__efiapi *hash_log_extend_event)(void *, u64, efi_physical_addr_t,
242+
u64, const union efistub_event *);
243+
struct { u32 hash_log_extend_event; } mixed_mode;
244+
} method;
232245
struct efistub_measured_event *evt;
233246
int size = struct_size(evt, tagged_event.tagged_event_data,
234247
events[event].event_data_len);
235248
efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
236249
efi_tcg2_protocol_t *tcg2 = NULL;
250+
union efistub_event ev;
237251
efi_status_t status;
252+
void *protocol;
238253

239254
efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
240255
if (tcg2) {
241-
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
242-
(void **)&evt);
243-
if (status != EFI_SUCCESS)
244-
goto fail;
245-
246-
evt->event_data = (struct efi_tcg2_event){
256+
ev.tcg2_data = (struct efi_tcg2_event){
247257
.event_size = size,
248-
.event_header.header_size = sizeof(evt->event_data.event_header),
258+
.event_header.header_size = sizeof(ev.tcg2_data.event_header),
249259
.event_header.header_version = EFI_TCG2_EVENT_HEADER_VERSION,
250260
.event_header.pcr_index = events[event].pcr_index,
251261
.event_header.event_type = EV_EVENT_TAG,
252262
};
263+
protocol = tcg2;
264+
method.hash_log_extend_event =
265+
(void *)efi_table_attr(tcg2, hash_log_extend_event);
266+
} else {
267+
efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
268+
efi_cc_protocol_t *cc = NULL;
253269

254-
evt->tagged_event = (TCG_PCClientTaggedEvent){
255-
.tagged_event_id = events[event].event_id,
256-
.tagged_event_data_size = events[event].event_data_len,
257-
};
258-
259-
memcpy(evt->tagged_event.tagged_event_data, events[event].event_data,
260-
events[event].event_data_len);
270+
efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc);
271+
if (!cc)
272+
return EFI_UNSUPPORTED;
261273

262-
status = efi_call_proto(tcg2, hash_log_extend_event, 0,
263-
load_addr, load_size, &evt->event_data);
264-
efi_bs_call(free_pool, evt);
274+
ev.cc_data = (struct efi_cc_event){
275+
.event_size = size,
276+
.event_header.header_size = sizeof(ev.cc_data.event_header),
277+
.event_header.header_version = EFI_CC_EVENT_HEADER_VERSION,
278+
.event_header.event_type = EV_EVENT_TAG,
279+
};
265280

281+
status = efi_call_proto(cc, map_pcr_to_mr_index,
282+
events[event].pcr_index,
283+
&ev.cc_data.event_header.mr_index);
266284
if (status != EFI_SUCCESS)
267285
goto fail;
268-
return EFI_SUCCESS;
286+
287+
protocol = cc;
288+
method.hash_log_extend_event =
289+
(void *)efi_table_attr(cc, hash_log_extend_event);
269290
}
270291

271-
return EFI_UNSUPPORTED;
292+
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, (void **)&evt);
293+
if (status != EFI_SUCCESS)
294+
goto fail;
295+
296+
*evt = (struct efistub_measured_event) {
297+
.event_data = ev,
298+
.tagged_event.tagged_event_id = events[event].event_id,
299+
.tagged_event.tagged_event_data_size = events[event].event_data_len,
300+
};
301+
302+
memcpy(evt->tagged_event.tagged_event_data, events[event].event_data,
303+
events[event].event_data_len);
304+
305+
status = efi_fn_call(&method, hash_log_extend_event, protocol, 0,
306+
load_addr, load_size, &evt->event_data);
307+
efi_bs_call(free_pool, evt);
308+
309+
if (status == EFI_SUCCESS)
310+
return EFI_SUCCESS;
311+
272312
fail:
273313
efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status);
274314
return status;

0 commit comments

Comments
 (0)