2828#include <linux-bootparams.h>
2929#include <event_log.h>
3030#include <multiboot2.h>
31- #include <tags .h>
31+ #include <slrt .h>
3232#include <string.h>
3333#include <printk.h>
3434#include <dev.h>
@@ -276,181 +276,12 @@ typedef struct {
276276 void * dlme_arg ; /* %edx */
277277} asm_return_t ;
278278
279- static asm_return_t skl_linux (struct tpm * tpm , struct skl_tag_boot_linux * skl_tag )
280- {
281- struct boot_params * bp ;
282- struct kernel_info * ki ;
283- struct mle_header * mle_header ;
284- void * dlme_entry ;
285-
286- /* The Zero Page with the boot_params and legacy header */
287- bp = _p (skl_tag -> zero_page );
288-
289- print ("\ncode32_start " );
290- print_p (_p (bp -> code32_start ));
291-
292- if ( bp -> version < 0x020f
293- || (ki = get_kernel_info (bp )) == NULL
294- || ki -> header != KERNEL_INFO_HEADER
295- || (mle_header = get_mle_hdr (bp , ki )) == NULL
296- || mle_header -> uuid [0 ] != MLE_UUID0
297- || mle_header -> uuid [1 ] != MLE_UUID1
298- || mle_header -> uuid [2 ] != MLE_UUID2
299- || mle_header -> uuid [3 ] != MLE_UUID3 )
300- {
301- print ("\nKernel is too old or MLE header not present.\n" );
302- reboot ();
303- }
304-
305- print ("\nmle_header\n" );
306- hexdump (mle_header , sizeof (struct mle_header ));
307-
308- dlme_entry = get_kernel_entry (bp , mle_header );
309-
310- if ( dlme_entry == NULL )
311- {
312- print ("\nBad kernel entry in MLE header.\n" );
313- reboot ();
314- }
315-
316- /* extend TB Loader code segment into PCR17 */
317- extend_pcr (tpm , _p (bp -> code32_start ), bp -> syssize << 4 , 17 ,
318- "Measured Kernel into PCR17" );
319-
320- tpm_relinquish_locality (tpm );
321- free_tpm (tpm );
322-
323- /* End of the line, off to the protected mode entry into the kernel */
324- print ("dlme_entry:\n" );
325- hexdump (dlme_entry , 0x100 );
326- print ("dlme_arg:\n" );
327- hexdump (bp , 0x280 );
328- print ("skl_base:\n" );
329- hexdump (_start , 0x100 );
330- print ("device_table:\n" );
331- hexdump (device_table , 0x100 );
332- print ("command_buf:\n" );
333- hexdump (command_buf , 0x1000 );
334- print ("event_log:\n" );
335- hexdump (event_log , 0x1000 );
336-
337- print ("skl_main() is about to exit\n" );
338-
339- return (asm_return_t ){ dlme_entry , bp };
340- }
341-
342- static asm_return_t skl_multiboot2 (struct tpm * tpm , struct skl_tag_boot_mb2 * skl_tag )
343- {
344- void * kernel_entry ;
345- u32 kernel_size , mbi_len ;
346- struct multiboot_tag * tag ;
347- int i ;
348-
349- /* This is MBI header, not a tag, but their structures are similar enough.
350- * Note that 'size' offsets are reversed in those two! */
351- tag = _p (skl_tag -> mbi );
352-
353- /* skl_tag->kernel_size is either passed size of kernel from bootloader
354- * or 0 */
355- kernel_size = skl_tag -> kernel_size ;
356- kernel_entry = _p (skl_tag -> kernel_entry );
357-
358- /* Extend PCR18 with MBI structure's hash; this includes all cmdlines.
359- * Use 'type' and not 'size', as their offsets are swapped in the header! */
360- mbi_len = tag -> type ;
361- extend_pcr (tpm , & tag , mbi_len , 18 , "Measured MBI into PCR18" );
362-
363- tag ++ ;
364-
365- while ( tag -> type )
366- {
367- if ( kernel_entry && kernel_size )
368- break ;
369-
370- /* If the entry point wasn't passed by a bootloader, we can only assume
371- * that it starts at the kernel base address (true at least for Xen) */
372- if ( !kernel_entry && tag -> type == MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR )
373- {
374- struct multiboot_tag_load_base_addr * ba = (void * )tag ;
375- kernel_entry = _p (ba -> load_base_addr );
376- print ("kernel_entry " );
377- print_p (kernel_entry );
378- print ("\n" );
379- }
380-
381- /* This assumes that ELF has only one PROGBITS section, and that section
382- * is the first one (i.e. it is loaded at load_base_addr). It is true
383- * for Xen, but may not always the case.
384- *
385- * Also, GRUB2 creates this tag after all module tags, so separate loop
386- * is needed for consistent order of PCR extension operations. */
387- if ( !kernel_size && tag -> type == MULTIBOOT_TAG_TYPE_ELF_SECTIONS )
388- {
389- struct multiboot_tag_elf_sections * es_tag = (void * )tag ;
390- for ( i = 0 ; i < es_tag -> num ; i ++ )
391- {
392- Elf32_Shdr * sh = (void * )& es_tag -> sections [es_tag -> entsize * i ];
393- if ( sh -> sh_type == SHT_PROGBITS )
394- {
395- kernel_size = sh -> sh_size ;
396- print ("kernel_size " );
397- print_p (_p (kernel_size ));
398- print ("\n" );
399- break ;
400- }
401- }
402- }
403-
404- tag = multiboot_next_tag (tag );
405- }
406-
407- extend_pcr (tpm , kernel_entry , kernel_size , 17 ,
408- "Measured Kernel into PCR17" );
409-
410- tag = _p (skl_tag -> mbi );
411- tag ++ ;
412-
413- while ( tag -> type )
414- {
415- if ( tag -> type == MULTIBOOT_TAG_TYPE_MODULE )
416- {
417- struct multiboot_tag_module * mod = (void * )tag ;
418- print ("Module '" );
419- print (mod -> cmdline );
420- print ("' [" );
421- print_p (_p (mod -> mod_start ));
422- print_p (_p (mod -> mod_end ));
423- print ("]\n" );
424- extend_pcr (tpm , _p (mod -> mod_start ), mod -> mod_end - mod -> mod_start ,
425- 17 , mod -> cmdline );
426- }
427-
428- tag = multiboot_next_tag (tag );
429- }
430-
431- /* Safety checks */
432- if ( tag -> size != 8
433- || _p (multiboot_next_tag (tag )) > _p (skl_tag -> mbi ) + mbi_len )
434- {
435- print ("MBI safety checks failed\n" );
436- reboot ();
437- }
438-
439- return (asm_return_t ){ kernel_entry , _p (skl_tag -> mbi ) };
440- }
441-
442- static asm_return_t skl_simple_payload (struct tpm * tpm , struct skl_tag_boot_simple_payload * skl_tag )
443- {
444- extend_pcr (tpm , _p (skl_tag -> base ), skl_tag -> size , 17 , "Measured payload into PCR17" );
445-
446- return (asm_return_t ){ _p (skl_tag -> entry ), _p (skl_tag -> arg ) };
447- }
448-
449279asm_return_t skl_main (void )
450280{
451- asm_return_t ret ;
452281 struct tpm * tpm ;
453- struct skl_tag_hdr * t = (struct skl_tag_hdr * ) & bootloader_data ;
282+ struct slr_entry_dl_info * dl_info ;
283+ asm_return_t ret ;
284+ u32 entry_offset ;
454285
455286 /*
456287 * Now in 64b mode, paging is setup. This is the launching point. We can
@@ -464,16 +295,6 @@ asm_return_t skl_main(void)
464295 /* Disable memory protection and setup IOMMU */
465296 iommu_setup ();
466297
467- if ( t -> type != SKL_TAG_TAGS_SIZE
468- || t -> len != sizeof (struct skl_tag_tags_size )
469- || end_of_tags () > _p (_start + SLB_SIZE )
470- || (t = next_of_type (t , SKL_TAG_END )) == NULL
471- || _p (t ) + t -> len != end_of_tags ())
472- {
473- print ("Bad bootloader data format\n" );
474- reboot ();
475- }
476-
477298 /*
478299 * TODO Note these functions can fail but there is no clear way to
479300 * report the error unless SKINIT has some resource to do this. For
@@ -483,36 +304,39 @@ asm_return_t skl_main(void)
483304 tpm_request_locality (tpm , 2 );
484305 event_log_init (tpm );
485306
486- /* Now that we have TPM and event log, measure bootloader data */
487- extend_pcr (tpm , & bootloader_data , bootloader_data .size , 18 ,
488- "Measured bootloader data into PCR18" );
489-
490- t = next_of_class (& bootloader_data , SKL_TAG_BOOT_CLASS );
491- if ( t == NULL || next_of_class (t , SKL_TAG_BOOT_CLASS ) != NULL )
307+ /*
308+ * Now that we have TPM and event log, we can begin measuring. For parity
309+ * with what TXT does, we leave most of measuring for the DLME. Here, we
310+ * only have to measure DLME itself, as well as entry point offset - only
311+ * both of those measurements together tell that the proper code has been
312+ * started. Entry point offset may come from MLE header included in DLME,
313+ * but we can't trust that the bootloader passed it without modification.
314+ */
315+ dl_info = next_entry_with_tag (NULL , SLR_ENTRY_DL_INFO );
316+
317+ if ( dl_info == NULL
318+ || dl_info -> hdr .size != sizeof (* dl_info )
319+ || end_of_slrt () < _p (& dl_info [1 ])
320+ || dl_info -> dlme_base >= 0x100000000ULL
321+ || dl_info -> dlme_base + dl_info -> dlme_size >= 0x100000000ULL
322+ || dl_info -> dlme_entry >= dl_info -> dlme_size
323+ || dl_info -> bl_context .bootloader != SLR_BOOTLOADER_GRUB )
492324 {
493- print ("No boot tag or multiple boot tags \n" );
325+ print ("Bad bootloader data format \n" );
494326 reboot ();
495327 }
496328
497- switch ( t -> type )
498- {
499- case SKL_TAG_BOOT_LINUX :
500- ret = skl_linux (tpm , (struct skl_tag_boot_linux * )t );
501- break ;
502- case SKL_TAG_BOOT_MB2 :
503- ret = skl_multiboot2 (tpm , (struct skl_tag_boot_mb2 * )t );
504- break ;
505- case SKL_TAG_BOOT_SIMPLE :
506- ret = skl_simple_payload (tpm , (struct skl_tag_boot_simple_payload * )t );
507- break ;
508- default :
509- print ("Unknown kernel boot protocol\n" );
510- reboot ();
511- }
329+ entry_offset = dl_info -> dlme_entry ;
330+ extend_pcr (tpm , & entry_offset , sizeof (entry_offset ), 17 ,
331+ "DLME entry offset" );
332+ extend_pcr (tpm , _p (dl_info -> dlme_base ), dl_info -> dlme_size , 17 , "DLME" );
512333
513334 tpm_relinquish_locality (tpm );
514335 free_tpm (tpm );
515336
337+ ret .dlme_entry = _p (dl_info -> dlme_base + dl_info -> dlme_entry );
338+ ret .dlme_arg = _p (dl_info -> bl_context .context );
339+
516340 /* End of the line, off to the protected mode entry into the kernel */
517341 print ("dlme_entry:\n" );
518342 hexdump (ret .dlme_entry , 0x100 );
@@ -523,14 +347,6 @@ asm_return_t skl_main(void)
523347 print ("bootloader_data:\n" );
524348 hexdump (& bootloader_data , bootloader_data .size );
525349
526- t = next_of_type (& bootloader_data , SKL_TAG_EVENT_LOG );
527- if ( t != NULL )
528- {
529- print ("TPM event log:\n" );
530- hexdump (_p (((struct skl_tag_evtlog * )t )-> address ),
531- ((struct skl_tag_evtlog * )t )-> size );
532- }
533-
534350 print ("skl_main() is about to exit\n" );
535351
536352 return ret ;
0 commit comments