Thanks for the patch, it was validated and merged…
Br.
-Ning
From: Sahil Rihan [mailto:sri...@fb.com]
Sent: Monday, May 14, 2018 3:37 PM
To: tboot-devel@lists.sourceforge.net
Subject: [tboot-devel] Add support for TPM2 TCG log format
Tboot didn’t have support for appending to a TPM2 TCG style event log. As a
result it would crash with a “generic fatal error” when it ran with an SINIT
that supports the TCG log format.
This change addresses that by adding code to handle the new log format.
Testing done: Verify tboot crashes on Skylake system without patch, and
successfully boots kernel with the patch.
Signed-off-by: Sahil Rihan <sri...@fb.com<mailto:sri...@fb.com>>
diff -r 57c7d147daec -r 8bcaa41a5769 tboot/txt/txt.c
--- a/tboot/txt/txt.c Fri May 04 17:10:58 2018 -0700
+++ b/tboot/txt/txt.c Mon May 14 15:26:18 2018 -0700
@@ -69,6 +69,12 @@
/* counter timeout for waiting for all APs to enter wait-for-sipi */
#define AP_WFS_TIMEOUT 0x10000000
+/* TPM event log types */
+#define EVTLOG_UNKNOWN 0
+#define EVTLOG_TPM12 1
+#define EVTLOG_TPM2_LEGACY 2
+#define EVTLOG_TPM2_TCG 3
+
__data struct acpi_rsdp g_rsdp;
extern char _start[]; /* start of module */
extern char _end[]; /* end of module */
@@ -87,6 +93,7 @@
extern void cpu_wakeup(uint32_t cpuid, uint32_t sipi_vec);
extern void print_event(const tpm12_pcr_event_t *evt);
extern void print_event_2(void *evt, uint16_t alg);
+extern uint32_t print_event_2_1(void *evt);
/*
@@ -282,6 +289,26 @@
}
}
+int get_evtlog_type(void)
+{
+ struct tpm_if *tpm = get_tpm();
+
+ if (tpm->major == TPM12_VER_MAJOR) {
+ return EVTLOG_TPM12;
+ } else if (tpm->major == TPM20_VER_MAJOR) {
+ if (g_sinit) {
+ txt_caps_t sinit_caps = get_sinit_capabilities(g_sinit);
+ return sinit_caps.tcg_event_log_format ? EVTLOG_TPM2_TCG :
EVTLOG_TPM2_LEGACY;
+ } else {
+ printk(TBOOT_ERR"SINIT not found\n");
+ }
+ } else {
+ printk(TBOOT_ERR"Unknown TPM major version: %d\n", tpm->major);
+ }
+ printk(TBOOT_ERR"Unable to determine log type\n");
+ return EVTLOG_UNKNOWN;
+}
+
static void init_os_sinit_ext_data(heap_ext_data_element_t* elts)
{
heap_ext_data_element_t* elt = elts;
@@ -391,7 +418,7 @@
}
}
-bool evtlog_append_tpm20(uint8_t pcr, uint16_t alg, tb_hash_t *hash, uint32_t
type)
+bool evtlog_append_tpm2_legacy(uint8_t pcr, uint16_t alg, tb_hash_t *hash,
uint32_t type)
{
heap_event_log_descr_t *cur_desc = NULL;
uint32_t hash_size;
@@ -428,21 +455,79 @@
return true;
}
+bool evtlog_append_tpm2_tcg(uint8_t pcr, uint32_t type, hash_list_t *hl)
+{
+ uint32_t i, event_size;
+ unsigned int hash_size;
+ tcg_pcr_event2 *event;
+ uint8_t *hash_entry;
+ tcg_pcr_event2 dummy;
+
+ /*
+ * Dont't use sizeof(tcg_pcr_event2) since that has
TPML_DIGESTV_VALUES_1.digests
+ * set to 5. Compute the static size as pcr_index + event_type +
+ * digest.count + event_size. Then add the space taken up by the hashes.
+ */
+ event_size = sizeof(dummy.pcr_index) + sizeof(dummy.event_type) +
+ sizeof(dummy.digest.count) + sizeof(dummy.event_size);
+
+ for (i = 0; i < hl->count; i++) {
+ hash_size = get_hash_size(hl->entries[i].alg);
+ if (hash_size == 0) {
+ return false;
+ }
+ event_size += sizeof(uint16_t); // hash_alg field
+ event_size += hash_size;
+ }
+
+ // Check if event will fit in buffer.
+ if (event_size + g_elog_2_1->next_record_offset >
+ g_elog_2_1->allcoated_event_container_size) {
+ return false;
+ }
+
+ event = (tcg_pcr_event2*)(void *)(unsigned long)g_elog_2_1->phys_addr +
+ g_elog_2_1->next_record_offset;
+ event->pcr_index = pcr;
+ event->event_type = type;
+ event->event_size = 0; // No event data passed by tboot.
+ event->digest.count = hl->count;
+
+ hash_entry = (uint8_t *)&event->digest.digests[0];
+ for (i = 0; i < hl->count; i++) {
+ // Populate individual TPMT_HA_1 structs.
+ *((uint16_t *)hash_entry) = hl->entries[i].alg; // TPMT_HA_1.hash_alg
+ hash_entry += sizeof(uint16_t);
+ hash_size = get_hash_size(hl->entries[i].alg); // already checked
above
+ memcpy(hash_entry, &(hl->entries[i].hash), hash_size);
+ hash_entry += hash_size;
+ }
+
+ g_elog_2_1->next_record_offset += event_size;
+ print_event_2_1(event);
+ return true;
+}
+
+
bool evtlog_append(uint8_t pcr, hash_list_t *hl, uint32_t type)
{
- struct tpm_if *tpm = get_tpm();
- switch (tpm->major) {
- case TPM12_VER_MAJOR:
+ int log_type = get_evtlog_type();
+ switch (log_type) {
+ case EVTLOG_TPM12:
if ( !evtlog_append_tpm12(pcr, &hl->entries[0].hash, type) )
return false;
break;
- case TPM20_VER_MAJOR:
+ case EVTLOG_TPM2_LEGACY:
for (unsigned int i=0; i<hl->count; i++) {
- if ( !evtlog_append_tpm20(pcr, hl->entries[i].alg,
+ if ( !evtlog_append_tpm2_legacy(pcr, hl->entries[i].alg,
&hl->entries[i].hash, type))
return false;
}
break;
+ case EVTLOG_TPM2_TCG:
+ if ( !evtlog_append_tpm2_tcg(pcr, type, hl) )
+ return false;
+ break;
default:
return false;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
tboot-devel mailing list
tboot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tboot-devel