[SLOF] [PATCH v2 07/20] Perform some initial measurements
Stefan Berger
stefanb at us.ibm.com
Wed Nov 18 04:02:23 AEDT 2015
From: Stefan Berger <stefanb at linux.vnet.ibm.com>
This patch 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. These functions
will be called in subsequent patches.
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/OF.fs | 1 +
lib/libtpm/tcgbios.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++
lib/libtpm/tcgbios.h | 14 ++++
lib/libtpm/tpm.code | 34 ++++++++
lib/libtpm/tpm.in | 3 +
slof/fs/tpm/tpm-static.fs | 11 +++
6 files changed, 267 insertions(+)
diff --git a/board-qemu/slof/OF.fs b/board-qemu/slof/OF.fs
index 80bc011..1eeb305 100644
--- a/board-qemu/slof/OF.fs
+++ b/board-qemu/slof/OF.fs
@@ -304,6 +304,7 @@ cr
#include "copyright-oss.fs"
cr cr
+vtpm-add-event-separators
vtpm-unassert-physical-presence
\ this CATCH is to ensure the code bellow always executes: boot may ABORT!
diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index dbc77d7..6dd8077 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 {
uint8_t tpm_probed:1;
uint8_t tpm_found:1;
@@ -734,3 +736,205 @@ static uint32_t hash_log_extend_event(const void *hashdata,
return tpm_extend(pcpes->digest, 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 a measurement to the list of measurements
+ * pcrindex : PCR to be extended
+ * event_type : type of event
+ * string : string describing the event; used if event_type is EV_ACTION
+ */
+static uint32_t tpm_add_measurement(uint32_t pcrindex,
+ uint16_t event_type,
+ const char *string)
+{
+ uint32_t rc;
+ uint32_t len;
+
+ switch (event_type) {
+ case EV_SEPARATOR:
+ len = sizeof(evt_separator);
+ rc = tpm_add_measurement_to_log(pcrindex, event_type,
+ NULL, 0,
+ (uint8_t *)evt_separator, len);
+ break;
+
+ case EV_ACTION:
+ rc = tpm_add_measurement_to_log(pcrindex, event_type,
+ string, strlen(string),
+ (uint8_t *)string, strlen(string));
+ break;
+
+ default:
+ rc = TCGBIOS_INVALID_INPUT_PARA;
+ }
+
+ return rc;
+}
+
+/*
+ * Add event separators for PCRs 0 to 7
+ */
+uint32_t tpm_add_event_separators(void)
+{
+ uint32_t rc;
+ uint32_t pcrindex = 0;
+
+ if (!has_working_tpm())
+ return TCGBIOS_GENERAL_ERROR;
+
+ while (pcrindex <= 7) {
+ rc = tpm_add_measurement(pcrindex, EV_SEPARATOR, NULL);
+ if (rc)
+ break;
+ pcrindex ++;
+ }
+
+ return rc;
+}
+
+/*
+ * Add a measurement regarding the boot device (CDRom, Floppy, HDD) to
+ * the list of measurements.
+ */
+static uint32_t tpm_measure_bootdevice(uint32_t bootcd, uint32_t bootdrv)
+{
+ const char *string;
+
+ dprintf("add bootdevice: bootcd = %d, bootdrv = 0x%x\n", bootcd, bootdrv);
+
+ if (!has_working_tpm())
+ return TCGBIOS_GENERAL_ERROR;
+
+ switch (bootcd) {
+ case 0:
+ switch (bootdrv) {
+ case BCV_DEVICE_FLOPPY:
+ string = "Booting BCV device 00h (Floppy)";
+ break;
+
+ case BCV_DEVICE_HDD:
+ string = "Booting BCV device 80h (HDD)";
+ break;
+
+ default:
+ string = "Booting unknown device";
+ break;
+ }
+ break;
+
+ default:
+ string = "Booting from CD ROM device";
+ }
+
+ return tpm_add_measurement_to_log(4, EV_ACTION,
+ string, strlen(string),
+ (uint8_t *)string, strlen(string));
+}
+
+/*
+ * Add a measurement to the log. This function creates two log entries
+ * of the Initial Program Load (IPL).
+ *
+ * Input parameter:
+ * bootcd : 0: MBR of hdd, 1: boot image, 2: boot catalog of El Torito
+ * addr : address where the IP data are located
+ * length : IP data length in bytes
+ */
+uint32_t tpm_measure_ipl(enum ipltype bootcd, const uint8_t *addr,
+ uint32_t length)
+{
+ uint32_t rc;
+ const char *string;
+
+ dprintf("tpm_ipl: bootcd = %d, addr = %p, length = 0x%x\n",
+ bootcd, addr, length);
+
+ if (!has_working_tpm())
+ return TCGBIOS_GENERAL_ERROR;
+
+ switch (bootcd) {
+ case IPL_EL_TORITO_1:
+ /* specs: see section 'El Torito' */
+ string = "EL TORITO IPL";
+ rc = tpm_add_measurement_to_log(4, EV_IPL,
+ string, strlen(string),
+ addr, length);
+ break;
+
+ case IPL_EL_TORITO_2:
+ /* specs: see section 'El Torito' */
+ string = "BOOT CATALOG";
+ rc = tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA,
+ string, strlen(string),
+ addr, length);
+ break;
+
+ default:
+ /*
+ * 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)
+ break;
+
+ /*
+ * equivalent to:
+ * dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum
+ */
+ string = "MBR PARTITION TABLE";
+ rc = tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA,
+ string, strlen(string),
+ addr + 0x1b8, 0x48);
+ }
+
+ return rc;
+}
+
+uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
+ uint32_t length)
+{
+ uint32_t rc;
+
+ if (!has_working_tpm())
+ return TCGBIOS_GENERAL_ERROR;
+
+ rc = tpm_measure_bootdevice(0, bootdrv);
+ if (rc)
+ return rc;
+
+ return tpm_measure_ipl(IPL_BCV, addr, length);
+}
diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
index 4e92b16..2e2d1af 100644
--- a/lib/libtpm/tcgbios.h
+++ b/lib/libtpm/tcgbios.h
@@ -15,9 +15,23 @@
#include <stdint.h>
+enum ipltype {
+ IPL_BCV = 0,
+ IPL_EL_TORITO_1,
+ IPL_EL_TORITO_2
+};
+
+#define BCV_DEVICE_FLOPPY 0x0
+#define BCV_DEVICE_HDD 0x80
+
uint32_t tpm_start(void);
uint32_t tpm_unassert_physical_presence(void);
void tpm_set_log_parameters(void *address, unsigned int size);
uint32_t tpm_get_logsize(void);
+uint32_t tpm_measure_ipl(enum ipltype bootcd, const uint8_t *addr,
+ uint32_t length);
+uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
+ uint32_t length);
+uint32_t tpm_add_event_separators(void);
#endif /* TCGBIOS_H */
diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
index 83e175d..69a4b69 100644
--- a/lib/libtpm/tpm.code
+++ b/lib/libtpm/tpm.code
@@ -56,3 +56,37 @@ PRIM(tpm_X2d_get_X2d_logsize)
PUSH;
TOS.n = tpm_get_logsize();
MIRP
+
+/****************************************************/
+/* Measure and log event separators */
+/* SLOF: tpm-add-event-separators ( -- errcode) */
+/* LIBTPM: tpm_add_event_separators(void) */
+/****************************************************/
+PRIM(tpm_X2d_add_X2d_event_X2d_separators)
+ PUSH;
+ TOS.n = tpm_add_event_separators();
+MIRP
+
+/***************************************************************/
+/* Measure and log Initial Program Load (IPL) */
+/* SLOF: tpm-measure-ipl ( ipltype addr length -- errcode) */
+/* LIBTPM: tpm_measure_ipl(void) */
+/***************************************************************/
+PRIM(tpm_X2d_measure_X2d_ipl)
+ int length = TOS.u; POP;
+ void *addr = TOS.a; POP;
+ int bootcd = TOS.u;
+ TOS.n = tpm_measure_ipl(bootcd, addr, length);
+MIRP
+
+/*************************************************************************/
+/* Measure and log boot connect vector (bcv) device's master boot record */
+/* SLOF: tpm-measure-bcv-mbr ( bootdrv addr length -- errcode ) */
+/* LIBTPM: 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 60bdf45..676073a 100644
--- a/lib/libtpm/tpm.in
+++ b/lib/libtpm/tpm.in
@@ -17,3 +17,6 @@ cod(tpm-start)
cod(tpm-unassert-physical-presence)
cod(tpm-set-log-parameters)
cod(tpm-get-logsize)
+cod(tpm-add-event-separators)
+cod(tpm-measure-ipl)
+cod(tpm-measure-bcv-mbr)
diff --git a/slof/fs/tpm/tpm-static.fs b/slof/fs/tpm/tpm-static.fs
index 504c345..ea8b125 100644
--- a/slof/fs/tpm/tpm-static.fs
+++ b/slof/fs/tpm/tpm-static.fs
@@ -22,6 +22,17 @@ false VALUE vtpm-debug?
THEN
;
+: vtpm-add-event-separators
+ vtpm-available? IF
+ tpm-add-event-separators ( -- errcode )
+ dup 0<> IF
+ ." VTPM: Error code from tpm-add-event-separators: " . cr
+ ELSE
+ drop
+ THEN
+ THEN
+;
+
: vtpm-unassert-physical-presence
vtpm-available? IF
tpm-unassert-physical-presence ( -- errcode )
--
2.4.3
More information about the SLOF
mailing list