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

Stefan Berger stefanb at linux.vnet.ibm.com
Fri Aug 5 17:07:13 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 | 115 ++++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/src/std/tcg.h b/src/std/tcg.h
index 8d71226..eff0890 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 acf75c7..b468867 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -55,6 +55,13 @@ static const u8 TPM2_SelfTest_YES[] =  { TPM2_YES }; /* full test */
 typedef u8 tpm_ppi_code;
 
 /****************************************************************
+ * prototypes
+ ****************************************************************/
+
+static int tpm20_get_pcrbanks();
+static int tpm20_get_hash_buffersize(u16 hashAlg);
+
+/****************************************************************
  * ACPI TCPA table interface
  ****************************************************************/
 
@@ -187,38 +194,104 @@ tpm_log_event(struct tcg_pcr_event2_sha1 *entry, const void *event
     return 0;
 }
 
-/*
- * Initialize the log; a TPM2 log needs a special TPM 1.2 log entry
- * as the first entry serving identification purposes
- */
-static void
-tpm_log_init(void)
+int
+tpm20_write_EfiSpecIdEventStruct(char *dest, size_t destlen)
 {
-    struct TCG_EfiSpecIdEventStruct event = {
+    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,
-        .numberOfAlgorithms = 1,
-        .digestSizes[0] = {
-             .algorithmId = TPM2_ALG_SHA1,
-             .digestSize = SHA1_BUFSIZE,
+        .algs = {
+            .numberOfAlgorithms = 0, /* fill below */
         },
-        .vendorInfoSize = 0,
-    };
-    struct tcg_pcr_event2_sha1 entry = {
-        .eventtype = EV_NO_ACTION,
-        .eventdatasize = sizeof(event),
-    };
+    }, *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 (offset > destlen)
+        printf("buffer for log event is too small (%d < %d)\n",
+               destlen, offset);
+
+    return offset;
+}
+
+/*
+ * Initialize the log; a TPM2 log needs a special TPM 1.2 log entry
+ * as the first entry serving identification purposes
+ */
+static void
+tpm_log_init(void)
+{
     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);
     }
 }
 
@@ -897,10 +970,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