[SLOF] [PATCH v3 08/17] Implement measurements of the master boot record

Stefan Berger stefanb at us.ibm.com
Tue Dec 1 09:01:51 AEDT 2015


From: Stefan Berger <stefanb at linux.vnet.ibm.com>

This patch adds support for measuring the boot block of the MBR and logging the
measurement. It also puts an 'event' separator into the log that can then be
seen in Linux's /sys/kernel/security/tpm0/ascii_bios_measurements. More
low-level C functions are added for measuring and logging of disk related data,
along with their FORTH-level counterparts.

Logging follows the specifications found on the following page:

http://www.trustedcomputinggroup.org/resources/pc_client_work_group_specific_implementation_specification_for_conventional_bios

Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
 board-qemu/slof/vtpm-sml.fs    |  23 +++++++++
 lib/libtpm/tcgbios.c           | 108 +++++++++++++++++++++++++++++++++++++++++
 lib/libtpm/tcgbios.h           |   6 +++
 lib/libtpm/tpm.code            |  23 +++++++++
 lib/libtpm/tpm.in              |   2 +
 slof/fs/packages/disk-label.fs |  10 +++-
 6 files changed, 171 insertions(+), 1 deletion(-)

diff --git a/board-qemu/slof/vtpm-sml.fs b/board-qemu/slof/vtpm-sml.fs
index f0b73ab..193b567 100644
--- a/board-qemu/slof/vtpm-sml.fs
+++ b/board-qemu/slof/vtpm-sml.fs
@@ -88,6 +88,29 @@ log-base LOG-SIZE tpm-set-log-parameters
 \ internal API calls
 \
 
+: separator-event ( start-pcr end-pcr -- )
+    tpm-add-event-separators                          ( -- errcode )
+    dup 0<> IF
+        ." VTPM: Error code from tpm-add-event-separators: " . cr
+    ELSE
+        drop
+    THEN
+;
+
+80 CONSTANT BCV_DEVICE_HDD
+
+: measure-hdd-mbr ( addr -- )
+    4 5 separator-event
+    200 BCV_DEVICE_HDD                         ( addr length bootdrv -- )
+    -rot                                       ( bootdrv addr length -- )
+    tpm-measure-bcv-mbr                        ( -- errcode )
+    dup 0<> IF
+        ." VTPM: Error code from tpm-measure-hdd: " . cr
+    ELSE
+        drop
+    THEN
+;
+
 : unassert-physical-presence ( -- )
     tpm-unassert-physical-presence                    ( -- errcode )
     dup 0<> IF
diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index 09fd962..814e02c 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -69,6 +69,8 @@ static const uint8_t get_capability_durations[] = {
 	0x00, 0x00, 0x01, 0x20
 };
 
+static uint8_t evt_separator[] = {0xff,0xff,0xff,0xff};
+
 struct tpm_state {
 	unsigned tpm_probed:1;
 	unsigned tpm_found:1;
@@ -518,3 +520,109 @@ uint32_t tpm_hash_log_extend_event(struct pcpes *pcpes)
 				     pcpes, event, event_length,
 				     pcpes->pcrindex);
 }
+
+/*
+ * Add a measurement to the log;
+ *
+ * Input parameters:
+ *  @pcrindex : PCR to extend
+ *  @event_type : type of event
+ *  @info : pointer to info (i.e., string) to be added to the log as-is
+ *  @info_length: length of the info
+ *  @data : pointer to data to be hashed
+ *  @data_length: length of the data
+ *
+ */
+static uint32_t tpm_add_measurement_to_log(uint32_t pcrindex,
+					   uint32_t eventtype,
+					   const char *info,
+					   uint32_t infolen,
+					   const uint8_t *data,
+					   uint32_t datalen)
+{
+	struct pcpes pcpes;
+
+	pcpes.pcrindex	= pcrindex;
+	pcpes.eventtype = eventtype;
+	memset(&pcpes.digest, 0, sizeof(pcpes.digest));
+
+	return hash_log_extend_event(data, datalen, &pcpes,
+				     info, infolen, pcrindex);
+}
+
+/*
+ * Add an EV_ACTION measurement to the list of measurements
+ */
+static uint32_t tpm_add_action(uint32_t pcrindex, const char *string)
+{
+	uint32_t len = strlen(string);
+
+	return tpm_add_measurement_to_log(pcrindex, EV_ACTION,
+					  string, len, (uint8_t *)string, len);
+}
+
+/*
+ * Add event separators for a range of PCRs
+ */
+uint32_t tpm_add_event_separators(uint32_t start_pcr, uint32_t end_pcr)
+{
+	uint32_t rc = 0;
+	uint32_t pcrindex;
+
+	if (!has_working_tpm())
+		return TCGBIOS_GENERAL_ERROR;
+
+	if (start_pcr >= 24 || start_pcr > end_pcr)
+		return TCGBIOS_INVALID_INPUT_PARA;
+
+	/* event separators need to be extended and logged for PCRs 0-7 */
+	for (pcrindex = start_pcr; pcrindex <= end_pcr; pcrindex++) {
+		rc = tpm_add_measurement_to_log(pcrindex, EV_SEPARATOR,
+						NULL, 0,
+						(uint8_t *)evt_separator,
+						sizeof(evt_separator));
+		if (rc)
+			break;
+	}
+
+	return rc;
+}
+
+uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
+			     uint32_t length)
+{
+	uint32_t rc;
+	const char *string;
+
+	if (!has_working_tpm())
+		return TCGBIOS_GENERAL_ERROR;
+
+	if (length < 0x200)
+		return TCGBIOS_INVALID_INPUT_PARA;
+
+	string = "Booting BCV device 00h (Floppy)";
+	if (bootdrv == BCV_DEVICE_HDD)
+		string = "Booting BCV device 80h (HDD)";
+
+	rc = tpm_add_action(4, string);
+	if (rc)
+		return rc;
+
+	/*
+	 * equivalent to: dd if=/dev/hda ibs=1 count=440 | sha1sum
+	 */
+	string = "MBR";
+	rc = tpm_add_measurement_to_log(4, EV_IPL,
+					string, strlen(string),
+					addr, 0x1b8);
+	if (rc)
+		return rc;
+
+	/*
+	 * equivalent to: dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum
+	 */
+	string = "MBR PARTITION TABLE";
+	return tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA,
+					  string, strlen(string),
+					  addr + 0x1b8, 0x48);
+}
diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
index 592ae6d..3ccfca5 100644
--- a/lib/libtpm/tcgbios.h
+++ b/lib/libtpm/tcgbios.h
@@ -16,6 +16,9 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#define BCV_DEVICE_FLOPPY  0x0
+#define BCV_DEVICE_HDD     0x80
+
 struct pcpes;
 
 uint32_t tpm_start(void);
@@ -26,5 +29,8 @@ uint32_t tpm_get_logsize(void);
 uint32_t tpm_hash_log_extend_event(struct pcpes *pcpes);
 bool tpm_log_event(struct pcpes *pcpes);
 uint32_t tpm_hash_all(const void *data, uint32_t datalen, void *hashptr);
+uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
+                             uint32_t length);
+uint32_t tpm_add_event_separators(uint32_t start_pcr, uint32_t end_pcr);
 
 #endif /* TCGBIOS_H */
diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
index eed9fbf..4d532de 100644
--- a/lib/libtpm/tpm.code
+++ b/lib/libtpm/tpm.code
@@ -97,3 +97,26 @@ PRIM(tpm_X2d_get_X2d_logsize)
 	PUSH;
 	TOS.n = tpm_get_logsize();
 MIRP
+
+/**********************************************************************/
+/* Measure and log event separators                                   */
+/* SLOF:   tpm-add-event-separators  ( start-pcr end-pcr -- errcode)  */
+/* LIBTPM: errcode = tpm_add_event_separators(start_pcr, end_pcr)     */
+/**********************************************************************/
+PRIM(tpm_X2d_add_X2d_event_X2d_separators)
+	int end_pcr = TOS.u; POP;
+	int start_pcr = TOS.u;
+	TOS.n = tpm_add_event_separators(start_pcr, end_pcr);
+MIRP
+
+/*************************************************************************/
+/* Measure and log boot connect vector (bcv) device's master boot record */
+/* SLOF:   tpm-measure-bcv-mbr  ( bootdrv addr length -- errcode )       */
+/* LIBTPM: errcode = tpm_measure_bcv_mbr(void)                           */
+/*************************************************************************/
+PRIM(tpm_X2d_measure_X2d_bcv_X2d_mbr)
+	int length = TOS.u; POP;
+	void *addr = TOS.a; POP;
+	int bootdrv = TOS.u;
+	TOS.n = tpm_measure_bcv_mbr(bootdrv, addr, length);
+MIRP
diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
index 1e8ffc1..2d3d75e 100644
--- a/lib/libtpm/tpm.in
+++ b/lib/libtpm/tpm.in
@@ -21,3 +21,5 @@ cod(tpm-get-logsize)
 cod(tpm-log-event)
 cod(tpm-hash-log-extend-event)
 cod(tpm-hash-all)
+cod(tpm-add-event-separators)
+cod(tpm-measure-bcv-mbr)
diff --git a/slof/fs/packages/disk-label.fs b/slof/fs/packages/disk-label.fs
index e034d64..8172654 100644
--- a/slof/fs/packages/disk-label.fs
+++ b/slof/fs/packages/disk-label.fs
@@ -545,7 +545,15 @@ B9E5                CONSTANT GPT-BASIC-DATA-PARTITION-2
 \ load from a bootable partition
 : load-from-boot-partition ( addr -- size )
    debug-disk-label? IF ." Trying DOS boot " .s cr THEN
-   dup load-from-dos-boot-partition ?dup 0 <> IF nip EXIT THEN
+   dup load-from-dos-boot-partition ?dup 0 <> IF
+      nip
+      block s" /ibm,vtpm" find-node dup IF
+         s" measure-hdd-mbr" rot $call-static
+      ELSE
+         2drop
+      THEN
+      EXIT
+   THEN
 
    debug-disk-label? IF ." Trying CHRP boot " .s cr THEN
    1 disk-chrp-boot !
-- 
2.4.3



More information about the SLOF mailing list