@@ -194,7 +194,7 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si
194
194
* load_options_size = load_option_unpacked .optional_data_size ;
195
195
}
196
196
197
- enum efistub_event {
197
+ enum efistub_event_type {
198
198
EFISTUB_EVT_INITRD ,
199
199
EFISTUB_EVT_LOAD_OPTIONS ,
200
200
EFISTUB_EVT_COUNT ,
@@ -220,55 +220,95 @@ static const struct {
220
220
},
221
221
};
222
222
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
+
223
230
struct efistub_measured_event {
224
- efi_tcg2_event_t event_data ;
231
+ union efistub_event event_data ;
225
232
TCG_PCClientTaggedEvent tagged_event __packed ;
226
233
};
227
234
228
235
static efi_status_t efi_measure_tagged_event (unsigned long load_addr ,
229
236
unsigned long load_size ,
230
- enum efistub_event event )
237
+ enum efistub_event_type event )
231
238
{
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 ;
232
245
struct efistub_measured_event * evt ;
233
246
int size = struct_size (evt , tagged_event .tagged_event_data ,
234
247
events [event ].event_data_len );
235
248
efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID ;
236
249
efi_tcg2_protocol_t * tcg2 = NULL ;
250
+ union efistub_event ev ;
237
251
efi_status_t status ;
252
+ void * protocol ;
238
253
239
254
efi_bs_call (locate_protocol , & tcg2_guid , NULL , (void * * )& tcg2 );
240
255
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 ){
247
257
.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 ),
249
259
.event_header .header_version = EFI_TCG2_EVENT_HEADER_VERSION ,
250
260
.event_header .pcr_index = events [event ].pcr_index ,
251
261
.event_header .event_type = EV_EVENT_TAG ,
252
262
};
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 ;
253
269
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 ;
261
273
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
+ };
265
280
281
+ status = efi_call_proto (cc , map_pcr_to_mr_index ,
282
+ events [event ].pcr_index ,
283
+ & ev .cc_data .event_header .mr_index );
266
284
if (status != EFI_SUCCESS )
267
285
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 );
269
290
}
270
291
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
+
272
312
fail :
273
313
efi_warn ("Failed to measure data for event %d: 0x%lx\n" , event , status );
274
314
return status ;
0 commit comments