[SeaBIOS] [PATCH v2 5/6] tpm: Adjust the TPM2 log header to show all hashes

Stefan Berger stefanb at linux.vnet.ibm.com
Tue Jul 26 17:19:52 CEST 2016


Adjust the TPM2's log header event to show all hashes that are found in
the subsequent log entries.

Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
 src/std/tcg.h |  18 ++++++----
 src/tcgbios.c | 112 +++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 99 insertions(+), 31 deletions(-)

diff --git a/src/std/tcg.h b/src/std/tcg.h
index 3500867..c3b0632 100644
--- a/src/std/tcg.h
+++ b/src/std/tcg.h
@@ -541,6 +541,14 @@ struct tcg_pcr_event2_sha1 {
     u8 event[0];
 } PACKED;
 
+struct TCG_EfiSpecIdEventAlgorithms {
+    u32 numberOfAlgorithms;
+    struct TCG_EfiSpecIDEventAlgorithmSize {
+        u16 algorithmId;
+        u16 digestSize;
+    } digestSizes[0];
+} PACKED;
+
 struct TCG_EfiSpecIdEventStruct {
     u8 signature[16];
     u32 platformClass;
@@ -548,14 +556,12 @@ struct TCG_EfiSpecIdEventStruct {
     u8 specVersionMajor;
     u8 specErrata;
     u8 uintnSize;
-    u32 numberOfAlgorithms;
-    struct TCG_EfiSpecIdEventAlgorithmSize {
-        u16 algorithmId;
-        u16 digestSize;
-    } digestSizes[1];
+    struct TCG_EfiSpecIdEventAlgorithms algs;
+    /*
     u8 vendorInfoSize;
     u8 vendorInfo[0];
-};
+    */
+} PACKED;
 
 #define TPM_TCPA_ACPI_CLASS_CLIENT 0
 
diff --git a/src/tcgbios.c b/src/tcgbios.c
index 1eaf45e..80466b5 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -183,6 +183,78 @@ tpm20_write_tpml_dig_values(u8 *dest, size_t destlen, u32 pcrindex,
     return offset;
 }
 
+int
+tpm20_write_EfiSpecIdEventStruct(char *dest, size_t destlen)
+{
+    if (!tpm20_pcr_selection)
+        return -1;
+
+    struct TCG_EfiSpecIdEventStruct temp = {
+        .signature = "Spec ID Event03",
+        .platformClass = TPM_TCPA_ACPI_CLASS_CLIENT,
+        .specVersionMinor = 0,
+        .specVersionMajor = 2,
+        .specErrata = 0,
+        .uintnSize = 2,
+        .algs = {
+            .numberOfAlgorithms = 0, /* fill below */
+        },
+    }, *event = (struct TCG_EfiSpecIdEventStruct *)dest;
+
+    int hsize;
+    struct tpms_pcr_selection *sel = tpm20_pcr_selection->selections;
+    void *nsel, *end = (void *)tpm20_pcr_selection + tpm20_pcr_selection_size;
+    struct TCG_EfiSpecIdEventAlgorithms *algs = &event->algs;
+
+    int offset = offsetof(struct TCG_EfiSpecIdEventStruct,
+                          algs.digestSizes[0]);
+    u32 count;
+
+    memcpy(event, &temp, offset);
+
+    for (count = 0;
+         count < be32_to_cpu(tpm20_pcr_selection->count);
+         count++) {
+        u8 sizeOfSelect = sel->sizeOfSelect;
+
+        nsel = (void *)sel +
+               offsetof(struct tpms_pcr_selection, pcrSelect) +
+               sizeOfSelect;
+        if (nsel > end)
+            break;
+
+        hsize = tpm20_get_hash_buffersize(be16_to_cpu(sel->hashAlg));
+        if (hsize < 0) {
+            dprintf(DEBUG_tcg, "TPM is using an unsupported hash: %d\n",
+                    be16_to_cpu(sel->hashAlg));
+            return -1;
+        }
+
+        algs->digestSizes[count].algorithmId = be16_to_cpu(sel->hashAlg);
+        algs->digestSizes[count].digestSize = hsize;
+
+        offset += sizeof(algs->digestSizes[0]);
+
+        sel = nsel;
+    }
+
+    if (sel != end) {
+        dprintf(DEBUG_tcg, "Malformed pcr selection structure fron TPM\n");
+        return -1;
+    }
+    event->algs.numberOfAlgorithms = count;
+
+    u32 *vendorInfoSize = (u32 *)&dest[offset];
+    *vendorInfoSize = 0;
+    offset += sizeof(*vendorInfoSize);
+
+    if (dest && offset > destlen)
+        panic("buffer for log event is too small (%d < %d)\n",
+              destlen, offset);
+
+    return offset;
+}
+
 static struct tcpa_descriptor_rev2 *
 find_tcpa_by_rsdp(struct rsdp_descriptor *rsdp)
 {
@@ -346,31 +418,25 @@ tpm20_get_pcrbanks(void)
 static void
 tpm_log_init(void)
 {
-    struct TCG_EfiSpecIdEventStruct event = {
-        .signature = "Spec ID Event03",
-        .platformClass = TPM_TCPA_ACPI_CLASS_CLIENT,
-        .specVersionMinor = 0,
-        .specVersionMajor = 2,
-        .specErrata = 0,
-        .uintnSize = 2,
-        .numberOfAlgorithms = 1,
-        .digestSizes[0] = {
-             .algorithmId = TPM2_ALG_SHA1,
-             .digestSize = SHA1_BUFSIZE,
-        },
-        .vendorInfoSize = 0,
-    };
-    struct tcg_pcr_event2_sha1 entry = {
-        .eventtype = EV_NO_ACTION,
-        .eventdatasize = sizeof(event),
-    };
-
     switch (TPM_version) {
     case TPM_VERSION_1_2:
         break;
-    case TPM_VERSION_2:
+    case TPM_VERSION_2: ;
+        int ret = tpm20_get_pcrbanks();
+        /* if this failed, no entry will be written */
+        if (ret)
+            return;
+
         /* write a 1.2 type of entry */
-        tpm_log_event(&entry, &event, TPM_VERSION_1_2);
+        char buf[256];
+        ret = tpm20_write_EfiSpecIdEventStruct(buf, sizeof(buf));
+        if (ret < 0)
+            return;
+        struct tcg_pcr_event2_sha1 entry = {
+            .eventtype = EV_NO_ACTION,
+            .eventdatasize = ret,
+        };
+        tpm_log_event(&entry, buf, TPM_VERSION_1_2);
     }
 }
 
@@ -866,10 +932,6 @@ tpm20_startup(void)
     if (ret)
         goto err_exit;
 
-    ret = tpm20_get_pcrbanks();
-    if (ret)
-        goto err_exit;
-
     return 0;
 
 err_exit:
-- 
2.5.5




More information about the SeaBIOS mailing list