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@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: