Philipp Deppenwiese (zaolin.daisuki@googlemail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/14137
-gerrit
commit 8814e83f336ce9bc0b1e6d5829cfeb1bfc85df6b Author: Philipp Deppenwiese zaolin@das-labor.org Date: Fri Mar 18 04:22:20 2016 +0100
TPM: WIP - Add TCPA Log support
Change-Id: Ia36817c9840b9ebe59265d641691276edc9c9e06 Signed-off-by: Philipp Deppenwiese zaolin@das-labor.org --- src/include/tpm/tss_constants.h | 15 ++++++++ src/lib/tpm/tspi.c | 76 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 3 deletions(-)
diff --git a/src/include/tpm/tss_constants.h b/src/include/tpm/tss_constants.h index afd2593..3f2092d 100644 --- a/src/include/tpm/tss_constants.h +++ b/src/include/tpm/tss_constants.h @@ -15,6 +15,7 @@ #define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */ #define TPM_PUBEK_SIZE 256 #define TPM_PCR_DIGEST 20 +#define TPM_EVENT_DATA_SIZE 25
#define TPM_E_NON_FATAL 0x800
@@ -60,6 +61,8 @@
typedef uint8_t TSS_BOOL; typedef uint16_t TPM_STRUCTURE_TAG; +typedef uint32_t TSS_EVENTTYPE; +typedef uint32_t TSS_PCRINDEX;
typedef struct tdTPM_PERMANENT_FLAGS { TPM_STRUCTURE_TAG tag; @@ -94,4 +97,16 @@ typedef struct tdTPM_STCLEAR_FLAGS { TSS_BOOL bGlobalLock; } TPM_STCLEAR_FLAGS;
+typedef struct tdTPM_DIGEST { + uint8_t digest[TPM_PCR_DIGEST]; +} TPM_DIGEST; + +typedef struct tdTPM_PCR_EVENT { + TSS_PCRINDEX PCRIndex; //PCRIndex event extended to + TSS_EVENTTYPE EventType; //See Table 7-1, below + TPM_DIGEST Digest; //Value extended into PCRIndex + uint32_t EventSize; //Size of the event data + uint8_t Event[TPM_EVENT_DATA_SIZE]; //The event data +} TPM_PCR_EVENT; + #endif /* TPM_TSS_CONSTANTS_H */ diff --git a/src/lib/tpm/tspi.c b/src/lib/tpm/tspi.c index bd3025b..3edf0e8 100644 --- a/src/lib/tpm/tspi.c +++ b/src/lib/tpm/tspi.c @@ -17,10 +17,15 @@ #include <console/cbmem_console.h> #include <console/console.h> #include <reset.h> +#include <string.h>
#include <tpm/tss.h> #include <tpm/tspi.h>
+#include <cbmem.h> + +#define MAX_EVENT_STRUCT_SIZE 100 + static inline void _debug_init_pcrs(void) { uint32_t result; @@ -125,11 +130,72 @@ void init_tpm(int s3resume) } }
+static inline int tcpa_log(uint32_t pcr, const unsigned char *digest, const char *log_message) { + const struct cbmem_entry *ce; + TPM_PCR_EVENT tcpa_event; + TPM_DIGEST pcr_digest; + size_t size; + void *lasa; + uint8_t lasa_old[MAX_EVENT_STRUCT_SIZE]; + size_t log_message_len; + + if(log_message == NULL) { + return -1; + } else { + log_message_len = strlen(log_message); + + if(log_message_len >= TPM_EVENT_DATA_SIZE) { + return -2; + } + } + + memcpy(pcr_digest.digest, digest, TPM_PCR_DIGEST); + + tcpa_event.PCRIndex = pcr; + tcpa_event.EventType = 5; // ACTION type for linux kernel. + tcpa_event.Digest = pcr_digest; + tcpa_event.EventSize = TPM_EVENT_DATA_SIZE; + + memset(tcpa_event.Event, 0, TPM_EVENT_DATA_SIZE); + memcpy(tcpa_event.Event, log_message, log_message_len); + + ce = cbmem_entry_find(CBMEM_ID_TCPA_LOG); + if (ce) { + lasa = cbmem_entry_start(ce); + size = cbmem_entry_size(ce); + + memcpy(lasa_old, lasa, size); + + if(cbmem_entry_remove(ce) != 0) { + return -3; + } + + lasa = cbmem_add(CBMEM_ID_TCPA_LOG, sizeof(TPM_PCR_EVENT) + size); + if (!lasa) { + printk(BIOS_ERR, "TCPA log creation failed\n"); + return -4; + } + + memcpy(lasa, lasa_old, size); + lasa += size; + } else { + lasa = cbmem_add(CBMEM_ID_TCPA_LOG, sizeof(TPM_PCR_EVENT)); + if (!lasa) { + printk(BIOS_ERR, "TCPA log creation failed\n"); + return -4; + } + } + + memcpy(lasa, &tcpa_event, sizeof(TPM_PCR_EVENT)); + + return 0; +} + void measure_thing(const uint8_t * data, size_t size, int pcr, const char *thing_name) { uint8_t digest[SHA1_DIGEST_LENGTH]; - + sha1(data, size, digest);
printk(BIOS_DEBUG, "TPM: Digest for "%s": ", @@ -143,13 +209,17 @@ void measure_thing(const uint8_t * data, size_t size, int pcr,
if (tlcl_extend(pcr, digest, digest) == TPM_SUCCESS) { printk(BIOS_DEBUG, "TPM: PCR[%i] after extension: ", pcr); - + for(size = 0; size < SHA1_DIGEST_LENGTH; ++size) { printk(BIOS_SPEW, "%02x%c", digest[size], size < SHA1_DIGEST_LENGTH - 1 ? ':' : '\n'); } + + if(tcpa_log(pcr, digest, thing_name) < 0) { + printk(BIOS_SPEW, "TCPA logging failed!"); + } } }
@@ -160,7 +230,7 @@ void measure_prog(struct prog *program, int pcr, const char *prog_name) { start = prog_start(program); size = prog_size(program);
- printk(BIOS_DEBUG, "TPM: Measuring program "%s" at %p (%lx bytes)\n", + printk(BIOS_DEBUG, "TPM: Measuring program "%s" at %p (%u bytes)\n", prog_name, start, size);
return measure_thing(start, size, pcr, prog_name);