hvm: TCGBIOS fixes
authorKeir Fraser <keir@xensource.com>
Wed, 17 Oct 2007 09:00:27 +0000 (10:00 +0100)
committerKeir Fraser <keir@xensource.com>
Wed, 17 Oct 2007 09:00:27 +0000 (10:00 +0100)
Fix IPL measurement of El Torito CD boot and some eventlog formats.

The TCG BIOS extensions are described here:
https://www.trustedcomputinggroup.org/specs/PCClient/TCG_PCClientImplementationforBIOS_1-20_1-00.pdf

- fix cdrom (El Torito) boot (8.2.5.6 El Torito, p63)
   tcpa_ipl() is modified to support various boot devices.
   move some measurement code into cdrom_boot() function.
- fix EV_IPL (0Dh) event (10.4.1 Event Types, p76)
   eventfield size should be zero
- fix EV_SEPARATOR event (3.2.2 Integrity Collection and Reporting,
   p32)
   change eventfield to -1 (0xFFFFFFFF)  from  "---------------"
- add "Returned INT 19h" event (8.2.3 Logging of Boot Events, p59)
   actually, tcgbios does not call int19h, but we extend this
   tentatively

Signed-off-by: Seiji Munetoh <seiji.munetoh@gmail.com>
tools/firmware/rombios/32bit/tcgbios/tcgbios.c
tools/firmware/rombios/32bitprotos.h
tools/firmware/rombios/rombios.c
tools/firmware/rombios/tcgbios.c

index c9b10f8327b4767b874639bc6a034e13910eb1b1..5e548bd2c2726c6f3bea4844e965d480058b316b 100644 (file)
@@ -533,7 +533,8 @@ uint16_t tcpa_add_measurement_to_log_simple(uint32_t pcrIndex,
        memset(&pcpes, 0x0, sizeof(pcpes));
        pcpes.pcrindex = pcrIndex;
        pcpes.eventtype = event_type;
-       pcpes.eventdatasize = length;
+       /* specs: 10.4.1, EV_IPL eventfield should not contain the code.*/
+       pcpes.eventdatasize = 0;
 
        hleei.ipblength = 0x18;
        hleei.reserved  = 0x0;
@@ -570,11 +571,9 @@ static const char ev_action[][23] = {
            "Start Option ROM Scan"
 };
 
-
-static char evt_separator[] = "---------------";
+static char evt_separator[] = {0xff,0xff,0xff,0xff}; 
 static char wake_event_1[]    = "Wake Event 1";
 
-
 /*
  * Add a measurement to the list of measurements
  * pcrIndex   : PCR to be extended
@@ -590,11 +589,10 @@ void tcpa_add_measurement(uint32_t pcrIndex,
 
        switch (event_type) {
        case EV_SEPARATOR:
-               tcpa_add_measurement_to_log(pcrIndex,
+               tcpa_add_measurement_to_log_simple(pcrIndex,
                                            event_type,
-                                           0,
                                            evt_separator,
-                                           strlen(evt_separator));
+                                           4);
        break;
        case EV_ACTION:
                string = ev_action[data /* event_id */];
@@ -723,22 +721,44 @@ void tcpa_option_rom(uint32_t seg)
  * Creates two log entries
  *
  * Input parameter:
+ *  bootcd : 0: MBR of hdd, 1: boot image, 2: boot catalog of El Torito
  *  seg    : segment where the IPL data are located
+ *  off    : offset where the IPL data are located
+ *  count  : length in bytes
  */
-void tcpa_ipl(Bit32u seg)
+void tcpa_ipl(Bit32u bootcd,Bit32u seg,Bit32u off,Bit32u count)
 {
-       /* specs: 8.2.5.3 */
-       uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,0);
-       /* equivalent to: dd if=/dev/hda ibs=1 count=440 | sha1sum */
-       tcpa_add_measurement_to_log_simple(4,
-                                          EV_IPL,
-                                          addr,
-                                          0x1b8);
-       /* equivalent to: dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum */
-       tcpa_add_measurement_to_log_simple(5,
-                                          EV_IPL_PARTITION_DATA,
-                                          addr + 0x1b8,
-                                          0x48);
+       uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,off);
+       if (bootcd == 1) {
+               /* specs: 8.2.5.6 El Torito */
+               tcpa_add_measurement_to_log_simple(4,
+                                                  EV_IPL,
+                                                  addr,
+                                                  count);
+       }
+       else if (bootcd == 2) { /* Boot Catalog */
+
+               /* specs: 8.2.5.6 El Torito */
+               tcpa_add_measurement_to_log_simple(5,
+                                                  EV_IPL_PARTITION_DATA,
+                                                  addr,
+                                                  count);
+       }
+       else {
+               /* specs: 8.2.5.3 */
+               /* equivalent to: dd if=/dev/hda ibs=1 count=440 | sha1sum */
+               tcpa_add_measurement_to_log_simple(4,
+                                                  EV_IPL,
+                                                  addr,
+                                                  0x1b8);
+
+
+               /* equivalent to: dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum */
+               tcpa_add_measurement_to_log_simple(5,
+                                                  EV_IPL_PARTITION_DATA,
+                                                  addr + 0x1b8,
+                                                  0x48);
+       }
 }
 
 void tcpa_measure_post(Bit32u from, Bit32u to)
index b7127698d7b216b4a38f1813fec1c790efb124d3..69ec87dc34c029675a0538b770fdd4f14463f99e 100644 (file)
@@ -38,7 +38,7 @@ void tcpa_wake_event( PARMS(void) );
 void tcpa_add_bootdevice( PARMS(Bit32u bootcd, Bit32u bootdrv) );
 void tcpa_start_option_rom_scan( PARMS(void) );
 void tcpa_option_rom( PARMS(Bit32u seg) );
-void tcpa_ipl( PARMS(Bit32u seg) );
+void tcpa_ipl( PARMS(Bit32u bootcd,Bit32u seg,Bit32u off,Bit32u count) );
 void tcpa_measure_post( PARMS(Bit32u from, Bit32u to) );
 Bit32u tcpa_initialize_tpm( PARMS(Bit32u physpres) );
 
index fcdf3fb7ff6435e81ff55cfea45c73a79da24f37..23ec3aa265dc39cbe80efd42ff8214a932a20b31 100644 (file)
@@ -3378,6 +3378,13 @@ cdrom_boot()
   // Initial/Default Entry
   if(buffer[0x20]!=0x88)return 11; // Bootable
 
+#if BX_TCGBIOS
+  /* specs: 8.2.3 step 5 and 8.2.5.6, measure El Torito boot catalog */
+  /* measure 2048 bytes (one sector) */
+  tcpa_add_bootdevice((Bit32u)1L, (Bit32u)0L); /* bootcd = 1 */
+  tcpa_ipl((Bit32u)2L,(Bit32u)get_SS(),(Bit32u)buffer,(Bit32u)2048L);
+#endif
+
   write_byte(ebda_seg,&EbdaData->cdemu.media,buffer[0x21]);
   if(buffer[0x21]==0){
     // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0. 
@@ -3416,6 +3423,13 @@ cdrom_boot()
   if((error = ata_cmd_packet(device, 12, get_SS(), atacmd, 0, nbsectors*512L, ATA_DATA_IN, boot_segment,0)) != 0)
     return 12;
 
+#if BX_TCGBIOS
+  /* specs: 8.2.3 step 4 and 8.2.5.6, measure El Torito boot image */
+  /* measure 1st 512 bytes  */
+  tcpa_ipl((Bit32u)1L,(Bit32u)boot_segment,(Bit32u)0L,(Bit32u)512L);
+#endif
+
+
   // Remember the media type
   switch(read_byte(ebda_seg,&EbdaData->cdemu.media)) {
     case 0x01:  // 1.2M floppy
@@ -7686,6 +7700,7 @@ ASM_END
 
 #if BX_TCGBIOS
     tcpa_add_bootdevice((Bit32u)0L, (Bit32u)bootdrv);
+    tcpa_ipl((Bit32u)0L,(Bit32u)bootseg,(Bit32u)0L,(Bit32u)512L); /* specs: 8.2.3 steps 4 and 5 */
 #endif
 
     /* Canonicalize bootseg:bootip */
@@ -7706,9 +7721,6 @@ ASM_END
 
     bootdrv = (Bit8u)(status>>8);
     bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
-#if BX_TCGBIOS
-    tcpa_add_bootdevice((Bit32u)1L, (Bit32u)0L);
-#endif
 
     /* Canonicalize bootseg:bootip */
     bootip = (bootseg & 0x0fff) << 4;
@@ -7724,9 +7736,6 @@ ASM_END
   default: return;
   }
 
-#if BX_TCGBIOS
-  tcpa_ipl((Bit32u)bootseg);               /* specs: 8.2.3 steps 4 and 5 */
-#endif
   
   /* Jump to the boot vector */
 ASM_START
@@ -9795,16 +9804,14 @@ post_default_ints:
 #if BX_TCGBIOS
   call _tcpa_calling_int19h          /* specs: 8.2.3 step 1 */
   call _tcpa_add_event_separators    /* specs: 8.2.3 step 2 */
+  /* we do not call int 19h handler but keep following eventlog */
+  call _tcpa_returned_int19h         /* specs: 8.2.3 step 3/7 */
 #endif
 
   ;; Start the boot sequence.   See the comments in int19_relocated 
   ;; for why we use INT 18h instead of INT 19h here.
   int  #0x18
 
-#if BX_TCGBIOS
-  call _tcpa_returned_int19h         /* specs: 8.2.3 step 3/7 */
-#endif
-
 .org 0xe2c3 ; NMI Handler Entry Point
 nmi:
   ;; FIXME the NMI handler should not panic
index de2066fd1de2b10c03bc52fc580ac2675816254d..9adba404fc78cf4664eabfa22c64f55819c8f8c3 100644 (file)
@@ -150,8 +150,11 @@ void
  *  seg    : segment where the IPL data are located
  */
  void
-tcpa_ipl(seg)
+ tcpa_ipl(bootcd,seg,off,count)
+    Bit32u bootcd;
     Bit32u seg;
+    Bit32u off;
+    Bit32u count;
 {
        ASM_START
        DoUpcall(IDX_TCPA_IPL)