[SeaBIOS] [PATCH 2/2] tpm: Write logs in TPM 2 format

Kevin O'Connor kevin at koconnor.net
Mon Feb 8 17:36:40 CET 2016


On Mon, Feb 08, 2016 at 07:25:35AM -0500, Stefan Berger wrote:
> On 02/06/2016 01:35 PM, Kevin O'Connor wrote:
> >Add support for the TPM 2 format of log messages.
> >
> >Write the logs in the format that is appropriate for the version of
> >the host's TPM. For TPM 1.2 write it in the 'pcpes' structure's
> >format, for TPM 2 in the new TPM 2 format.
> >
> >By using this method we can keep the API interface on systems with a
> >TPM 2 even though applications pass in the 'pcpes' structures
> >directly. The log will still be written in the appropriate format.
> >
> >The TPM 2 log contains a TPM 1.2 type of entry of event type
> >EV_NO_ACTION and entry of type TCG_EfiSpeIdEventStruct as the first
> >entry. This is described in the EFI specification (section 5.3):
> >
> >Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
> >---
> >  src/std/tcg.h | 35 +++++++++++++++++++++++++++
> >  src/tcgbios.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
> >  2 files changed, 101 insertions(+), 10 deletions(-)
> >
> >diff --git a/src/std/tcg.h b/src/std/tcg.h
> >index dbb3a60..c59f671 100644
> >--- a/src/std/tcg.h
> >+++ b/src/std/tcg.h
> >@@ -91,6 +91,7 @@ enum irq_ids {
> >
> >  /* event types: 10.4.1 / table 11 */
> >  #define EV_POST_CODE             1
> >+#define EV_NO_ACTION             3
> >  #define EV_SEPARATOR             4
> >  #define EV_ACTION                5
> >  #define EV_EVENT_TAG             6
> >@@ -474,4 +475,38 @@ struct tpm2_req_hierarchycontrol {
> >      u8 state;
> >  } PACKED;
> >
> >+/* TPM 2 log entry */
> >+
> >+struct tpml_digest_values_sha1 {
> >+    u16 hashtype;
> >+    u8 sha1[SHA1_BUFSIZE];
> >+};
> >+
> >+struct tcg_pcr_event2_sha1 {
> >+    u32 pcrindex;
> >+    u32 eventtype;
> >+    u32 count; /* number of digests */
> >+    struct tpml_digest_values_sha1 digests[1];
> >+    u32 eventdatasize;
> >+    u8 event[0];
> >+} PACKED;
> >+
> >+struct TCG_EfiSpecIdEventStruct {
> >+    u8 signature[16];
> >+    u32 platformClass;
> >+    u8 specVersionMinor;
> >+    u8 specVersionMajor;
> >+    u8 specErrata;
> >+    u8 uintnSize;
> >+    u32 numberOfAlgorithms;
> >+    struct TCG_EfiSpecIdEventAlgorithmSize {
> >+        u16 algorithmId;
> >+        u16 digestSize;
> >+    } digestSizes[1];
> >+    u8 vendorInfoSize;
> >+    u8 vendorInfo[0];
> >+};
> >+
> >+#define TPM_TCPA_ACPI_CLASS_CLIENT 0
> >+
> >  #endif // tcg.h
> >diff --git a/src/tcgbios.c b/src/tcgbios.c
> >index cddc99b..f0ab188 100644
> >--- a/src/tcgbios.c
> >+++ b/src/tcgbios.c
> >@@ -141,7 +141,7 @@ tpm_tcpa_probe(void)
> >   *  Returns an error code in case of faiure, 0 in case of success
> >   */
> >  static int
> >-tpm_log_event(struct pcpes *pcpes, const void *event)
> >+tpm_log_event(struct tcg_pcr_event2_sha1 *entry, const void *event)
> >  {
> >      dprintf(DEBUG_tcg, "TCGBIOS: LASA = %p, next entry = %p\n",
> >              tpm_state.log_area_start_address, tpm_state.log_area_next_entry);
> >@@ -149,7 +149,7 @@ tpm_log_event(struct pcpes *pcpes, const void *event)
> >      if (tpm_state.log_area_next_entry == NULL)
> >          return -1;
> >
> >-    u32 size = sizeof(*pcpes) + pcpes->eventdatasize;
> >+    u32 size = sizeof(*entry) + entry->eventdatasize;
> 
> This is only the correct size for TPM 2. I think there should be a case
> statement here.

I didn't think it would matter to overestimate a v1 record size by 6
bytes.  That is, the acpi log shouldn't overflow, and if it gets that
close to overflowing then one could just call it overflowed?

> >
> >      if ((tpm_state.log_area_next_entry + size - tpm_state.log_area_start_address) >
> >           tpm_state.log_area_minimum_length) {
> >@@ -157,9 +157,19 @@ tpm_log_event(struct pcpes *pcpes, const void *event)
> >          return -1;
> >      }
> >
> >-    memcpy(tpm_state.log_area_next_entry, pcpes, sizeof(*pcpes));
> >-    memcpy(tpm_state.log_area_next_entry + sizeof(*pcpes),
> >-           event, pcpes->eventdatasize);
> >+    if (TPM_version == TPM_VERSION_1_2 || entry->eventtype == EV_NO_ACTION) {
> 
> This only works if TPM 2 entries don't have a EV_NO_ACTION (= 3). I think
> the cleaner solution would be to differentiate by version only.

Okay.

> The main difference here between parts of my code and yours is that you are
> inlining it.

Yes.  Avoiding 'struct log_entry' was the main thing though.

Thanks,
-Kevin



More information about the SeaBIOS mailing list