aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-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
5 files changed, 166 insertions, 0 deletions
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)