aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board-qemu/slof/vtpm-sml.fs8
-rw-r--r--lib/libtpm/tcgbios.c88
-rw-r--r--lib/libtpm/tcgbios.h3
-rw-r--r--lib/libtpm/tcgbios_int.h40
-rw-r--r--lib/libtpm/tpm.code32
-rw-r--r--lib/libtpm/tpm.in3
-rw-r--r--slof/fs/packages/disk-label.fs22
7 files changed, 196 insertions, 0 deletions
diff --git a/board-qemu/slof/vtpm-sml.fs b/board-qemu/slof/vtpm-sml.fs
index fd888fb..865db06 100644
--- a/board-qemu/slof/vtpm-sml.fs
+++ b/board-qemu/slof/vtpm-sml.fs
@@ -42,6 +42,14 @@ s" ibm,vtpm" 2dup device-name device-type
THEN
;
+: measure-gpt ( )
+ 0 7 separator-event
+ tpm-measure-gpt
+ ?dup IF
+ ." VTPM: Error code from tpm-measure-gpt: " . cr
+ THEN
+;
+
: leave-firmware ( -- )
tpm-leave-firmware ( errcode )
?dup IF
diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index c5f8ccf..be6c3d1 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -69,6 +69,11 @@ static struct {
#define TPM2_ALG_SHA512_FLAG (1 << 3)
#define TPM2_ALG_SM3_256_FLAG (1 << 4)
+static const uint8_t ZeroGuid[16] = { 0 };
+
+static UEFI_GPT_DATA *uefi_gpt_data;
+static size_t uefi_gpt_data_size;
+
/*
* TPM 2 logs are written in little endian format.
*/
@@ -925,6 +930,89 @@ uint32_t tpm_measure_bcv_mbr(uint32_t bootdrv, const uint8_t *addr,
addr + 0x1b8, 0x48);
}
+/*
+ * This is the first function to call when measuring a GPT table.
+ * It allocates memory for the data to log which are 'measured' later on.
+ */
+void tpm_gpt_set_lba1(const uint8_t *addr, uint32_t length)
+{
+ if (!tpm_is_working())
+ return;
+
+ SLOF_free_mem(uefi_gpt_data, uefi_gpt_data_size);
+
+ uefi_gpt_data_size = sizeof(UEFI_GPT_DATA);
+ uefi_gpt_data = SLOF_alloc_mem(uefi_gpt_data_size);
+ if (!uefi_gpt_data)
+ return;
+
+ memcpy(&uefi_gpt_data->EfiPartitionHeader,
+ addr, sizeof(uefi_gpt_data->EfiPartitionHeader));
+ uefi_gpt_data->NumberOfPartitions = 0;
+}
+
+/*
+ * This function adds a GPT entry to the data to measure. It must
+ * be called after tpm_gpt_set_lba1.
+ */
+void tpm_gpt_add_entry(const uint8_t *addr, uint32_t length)
+{
+ size_t sz;
+ UEFI_PARTITION_ENTRY *upe = (void *)addr;
+ void *tmp;
+
+ if (!tpm_is_working() ||
+ !uefi_gpt_data ||
+ length < sizeof(*upe) ||
+ !memcmp(upe->partTypeGuid, ZeroGuid, sizeof(ZeroGuid)))
+ return;
+
+ sz = offset_of(UEFI_GPT_DATA, Partitions) +
+ (uefi_gpt_data->NumberOfPartitions + 1)
+ * sizeof(UEFI_PARTITION_ENTRY);
+ if (sz > uefi_gpt_data_size) {
+ tmp = SLOF_alloc_mem(sz);
+ if (!tmp)
+ goto err_no_mem;
+
+ memcpy(tmp, uefi_gpt_data, uefi_gpt_data_size);
+ SLOF_free_mem(uefi_gpt_data, uefi_gpt_data_size);
+ uefi_gpt_data = tmp;
+ uefi_gpt_data_size = sz;
+ }
+
+ memcpy(&uefi_gpt_data->Partitions[uefi_gpt_data->NumberOfPartitions],
+ addr,
+ sizeof(UEFI_PARTITION_ENTRY));
+ uefi_gpt_data->NumberOfPartitions++;
+
+ return;
+
+err_no_mem:
+ SLOF_free_mem(uefi_gpt_data, uefi_gpt_data_size);
+ uefi_gpt_data_size = 0;
+ uefi_gpt_data = NULL;
+}
+
+/*
+ * tpm_measure_gpt finally measures the GPT table and adds an entry
+ * to the log.
+ */
+uint32_t tpm_measure_gpt(void)
+{
+ size_t sz;
+
+ if (!tpm_is_working())
+ return TCGBIOS_GENERAL_ERROR;
+
+ sz = offset_of(UEFI_GPT_DATA, Partitions) +
+ uefi_gpt_data->NumberOfPartitions * sizeof(UEFI_PARTITION_ENTRY);
+
+ return tpm_add_measurement_to_log(5, EV_EFI_GPT_EVENT,
+ (const char *)uefi_gpt_data, sz,
+ (const uint8_t *)uefi_gpt_data, sz);
+}
+
uint32_t tpm_measure_scrtm(void)
{
uint32_t rc;
diff --git a/lib/libtpm/tcgbios.h b/lib/libtpm/tcgbios.h
index c4a2e71..8174d86 100644
--- a/lib/libtpm/tcgbios.h
+++ b/lib/libtpm/tcgbios.h
@@ -29,5 +29,8 @@ uint32_t tpm_driver_get_failure_reason(void);
void tpm_driver_set_failure_reason(uint32_t errcode);
bool tpm_is_working(void);
void tpm20_menu(void);
+void tpm_gpt_set_lba1(const uint8_t *addr, uint32_t length);
+void tpm_gpt_add_entry(const uint8_t *addr, uint32_t length);
+uint32_t tpm_measure_gpt(void);
#endif /* TCGBIOS_H */
diff --git a/lib/libtpm/tcgbios_int.h b/lib/libtpm/tcgbios_int.h
index 6892e6f..1a88402 100644
--- a/lib/libtpm/tcgbios_int.h
+++ b/lib/libtpm/tcgbios_int.h
@@ -39,6 +39,8 @@
#define EV_S_CRTM_VERSION 8
#define EV_IPL 13
#define EV_IPL_PARTITION_DATA 14
+#define EV_EFI_EVENT_BASE 0x80000000
+#define EV_EFI_GPT_EVENT (EV_EFI_EVENT_BASE + 0x6)
#define BCV_DEVICE_HDD 0x80
@@ -91,6 +93,44 @@ struct TCG_EfiSpecIdEventStruct {
*/
} __attribute__((packed));
+/* EFI related data structures for logging */
+typedef struct {
+ uint64_t signature;
+ uint32_t revision;
+ uint32_t size;
+ uint32_t crc32;
+ uint8_t reserved[4];
+} __attribute__((packed)) UEFI_TABLE_HEADER;
+
+typedef struct {
+ UEFI_TABLE_HEADER header;
+ uint64_t currentLba;
+ uint64_t backupLba;
+ uint64_t firstLba;
+ uint64_t lastLba;
+ uint8_t diskGuid[16];
+ uint64_t partEntryLba;
+ uint32_t numPartEntry;
+ uint32_t partEntrySize;
+ uint32_t partArrayCrc32;
+ uint8_t reserved[420];
+} __attribute__((packed)) UEFI_PARTITION_TABLE_HEADER;
+
+typedef struct {
+ uint8_t partTypeGuid[16];
+ uint8_t partGuid[16];
+ uint64_t firstLba;
+ uint64_t lastLba;
+ uint64_t attribute;
+ uint8_t partName[72];
+} __attribute__((packed)) UEFI_PARTITION_ENTRY;
+
+typedef struct {
+ UEFI_PARTITION_TABLE_HEADER EfiPartitionHeader;
+ uint64_t NumberOfPartitions;
+ UEFI_PARTITION_ENTRY Partitions[0];
+} __attribute__((packed)) UEFI_GPT_DATA;
+
/* Input and Output headers for all TPM commands */
struct tpm_req_header {
uint16_t tag;
diff --git a/lib/libtpm/tpm.code b/lib/libtpm/tpm.code
index b8f5669..205c608 100644
--- a/lib/libtpm/tpm.code
+++ b/lib/libtpm/tpm.code
@@ -137,3 +137,35 @@ MIRP
PRIM(tpm20_X2d_menu)
tpm20_menu();
MIRP
+
+/*************************************************************************/
+/* Set the LBA1 of the GPT */
+/* SLOF: tpm-gpt-set-lba1 ( addr length -- ) */
+/* LIBTPM: tpm_gpt_set_lba1(addr, length) */
+/*************************************************************************/
+PRIM(tpm_X2d_gpt_X2d_set_X2d_lba1)
+ int length = TOS.u; POP;
+ void *addr = TOS.a; POP;
+ tpm_gpt_set_lba1(addr, length);
+MIRP
+
+/*************************************************************************/
+/* Add a GPT table entry */
+/* SLOF: tpm-gpt-add-entry ( addr length -- ) */
+/* LIBTPM: tpm_gpt_add_entry(addr, length) */
+/*************************************************************************/
+PRIM(tpm_X2d_gpt_X2d_add_X2d_entry)
+ int length = TOS.u; POP;
+ void *addr = TOS.a; POP;
+ tpm_gpt_add_entry(addr, length);
+MIRP
+
+/*************************************************************************/
+/* Measure and log GPT EVENT */
+/* SLOF: tpm-measure-gpt ( -- errcode ) */
+/* LIBTPM: errcode = tpm_measure_gpt() */
+/*************************************************************************/
+PRIM(tpm_X2d_measure_X2d_gpt)
+ PUSH;
+ TOS.n = tpm_measure_gpt();
+MIRP
diff --git a/lib/libtpm/tpm.in b/lib/libtpm/tpm.in
index 590fee1..bdbc47d 100644
--- a/lib/libtpm/tpm.in
+++ b/lib/libtpm/tpm.in
@@ -25,3 +25,6 @@ cod(tpm-measure-scrtm)
cod(tpm-driver-get-failure-reason)
cod(tpm-driver-set-failure-reason)
cod(tpm20-menu)
+cod(tpm-gpt-set-lba1)
+cod(tpm-gpt-add-entry)
+cod(tpm-measure-gpt)
diff --git a/slof/fs/packages/disk-label.fs b/slof/fs/packages/disk-label.fs
index 969eb00..bb64022 100644
--- a/slof/fs/packages/disk-label.fs
+++ b/slof/fs/packages/disk-label.fs
@@ -431,6 +431,27 @@ CREATE GPT-LINUX-PARTITION 10 allot
block gpt>signature x@ GPT-SIGNATURE =
;
+\ Measure the GPT partition table by collecting its LBA1
+\ and GPT Entries and then measuring them.
+\ This function modifies 'block' and 'seek-pos'
+
+: measure-gpt-partition ( -- )
+ s" /ibm,vtpm" find-node ?dup IF
+ get-gpt-partition 0= if drop EXIT THEN
+
+ block block-size tpm-gpt-set-lba1
+
+ block gpt>num-part-entry l@-le
+ 1+ 1 ?DO
+ seek-pos 0 seek drop
+ block gpt-part-size read drop
+ block gpt-part-size tpm-gpt-add-entry
+ seek-pos gpt-part-size + to seek-pos
+ LOOP
+ s" measure-gpt" rot $call-static
+ THEN
+;
+
: load-from-gpt-prep-partition ( addr -- size )
get-gpt-partition 0= IF false EXIT THEN
block gpt>num-part-entry l@-le dup 0= IF false exit THEN
@@ -465,6 +486,7 @@ CREATE GPT-LINUX-PARTITION 10 allot
;
: try-gpt-dos-partition ( -- true|false )
+ measure-gpt-partition
get-gpt-partition 0= IF false EXIT THEN
block gpt>num-part-entry l@-le dup 0= IF false EXIT THEN
1+ 1 ?DO