@@ -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+
223230struct efistub_measured_event {
224- efi_tcg2_event_t event_data ;
231+ union efistub_event event_data ;
225232 TCG_PCClientTaggedEvent tagged_event __packed ;
226233};
227234
228235static 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+
272312fail :
273313 efi_warn ("Failed to measure data for event %d: 0x%lx\n" , event , status );
274314 return status ;
0 commit comments