summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commonlib/include/commonlib/tpm_log_serialized.h3
-rw-r--r--src/security/tpm/tspi.h27
-rw-r--r--src/security/tpm/tspi/crtm.c78
-rw-r--r--src/security/tpm/tspi/log.c94
4 files changed, 132 insertions, 70 deletions
diff --git a/src/commonlib/include/commonlib/tpm_log_serialized.h b/src/commonlib/include/commonlib/tpm_log_serialized.h
index dc58dc09c3..8372f94dab 100644
--- a/src/commonlib/include/commonlib/tpm_log_serialized.h
+++ b/src/commonlib/include/commonlib/tpm_log_serialized.h
@@ -6,12 +6,9 @@
#include <commonlib/bsd/helpers.h>
#include <stdint.h>
-#define MAX_TPM_LOG_ENTRIES 50
#define TPM_CB_LOG_DIGEST_MAX_LENGTH 64
#define TPM_CB_LOG_PCR_HASH_NAME 50
#define TPM_CB_LOG_PCR_HASH_LEN 10
-/* Assumption of 2K TCPA log size reserved for CAR/SRAM */
-#define MAX_PRERAM_TPM_LOG_ENTRIES 15
struct tpm_cb_log_entry {
uint32_t pcr;
diff --git a/src/security/tpm/tspi.h b/src/security/tpm/tspi.h
index aee38aa902..b081439c44 100644
--- a/src/security/tpm/tspi.h
+++ b/src/security/tpm/tspi.h
@@ -10,12 +10,21 @@
#define TPM_PCR_MAX_LEN 64
#define HASH_DATA_CHUNK_SIZE 1024
+#define MAX_TPM_LOG_ENTRIES 50
+/* Assumption of 2K TCPA log size reserved for CAR/SRAM */
+#define MAX_PRERAM_TPM_LOG_ENTRIES 15
/**
* Get the pointer to the single instance of global
* TPM log data, and initialize it when necessary
*/
-struct tpm_cb_log_table *tpm_log_init(void);
+void *tpm_log_init(void);
+
+/**
+ * Get the pointer to the single CBMEM instance of global
+ * TPM log data, and initialize it when necessary
+ */
+void *tpm_log_cbmem_init(void);
/**
* Clears the pre-RAM TPM log data and initializes
@@ -24,6 +33,22 @@ struct tpm_cb_log_table *tpm_log_init(void);
void tpm_preram_log_clear(void);
/**
+ * Retrieves number of entries currently stored in the log.
+ */
+uint16_t tpm_log_get_size(const void *log_table);
+
+/**
+ * Copies data from pre-RAM TPM log to CBMEM (RAM) log
+ */
+void tpm_log_copy_entries(const void *from, void *to);
+
+/**
+ * Retrieves an entry from a log. Returns non-zero on invalid index or error.
+ */
+int tpm_log_get(int entry_idx, int *pcr, const uint8_t **digest_data,
+ enum vb2_hash_algorithm *digest_algo, const char **event_name);
+
+/**
* Add table entry for cbmem TPM log.
* @param name Name of the hashed data
* @param pcr PCR used to extend hashed data
diff --git a/src/security/tpm/tspi/crtm.c b/src/security/tpm/tspi/crtm.c
index 6e4fadad2b..a7efcf2145 100644
--- a/src/security/tpm/tspi/crtm.c
+++ b/src/security/tpm/tspi/crtm.c
@@ -2,7 +2,9 @@
#include <console/console.h>
#include <fmap.h>
+#include <bootstate.h>
#include <cbfs.h>
+#include <symbols.h>
#include "crtm.h"
#include <string.h>
@@ -148,39 +150,79 @@ uint32_t tspi_cbfs_measurement(const char *name, uint32_t type, const struct vb2
tpm_log_metadata);
}
+void *tpm_log_init(void)
+{
+ static void *tclt;
+
+ /* We are dealing here with pre CBMEM environment.
+ * If cbmem isn't available use CAR or SRAM */
+ if (!cbmem_possibly_online() &&
+ !CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
+ return _tpm_log;
+ else if (ENV_CREATES_CBMEM
+ && !CONFIG(VBOOT_RETURN_FROM_VERSTAGE)) {
+ tclt = tpm_log_cbmem_init();
+ if (!tclt)
+ return _tpm_log;
+ } else {
+ tclt = tpm_log_cbmem_init();
+ }
+
+ return tclt;
+}
+
int tspi_measure_cache_to_pcr(void)
{
int i;
- struct tpm_cb_log_table *tclt = tpm_log_init();
+ int pcr;
+ const char *event_name;
+ const uint8_t *digest_data;
+ enum vb2_hash_algorithm digest_algo;
/* This means the table is empty. */
if (!tpm_log_available())
return VB2_SUCCESS;
- if (!tclt) {
+ if (tpm_log_init() == NULL) {
printk(BIOS_WARNING, "TPM LOG: log non-existent!\n");
return VB2_ERROR_UNKNOWN;
}
printk(BIOS_DEBUG, "TPM: Write digests cached in TPM log to PCR\n");
- for (i = 0; i < tclt->num_entries; i++) {
- struct tpm_cb_log_entry *tce = &tclt->entries[i];
- if (tce) {
- printk(BIOS_DEBUG, "TPM: Write digest for"
- " %s into PCR %d\n",
- tce->name, tce->pcr);
- int result = tlcl_extend(tce->pcr,
- tce->digest,
- TPM_MEASURE_ALGO);
- if (result != TPM_SUCCESS) {
- printk(BIOS_ERR, "TPM: Writing digest"
- " of %s into PCR failed with error"
- " %d\n",
- tce->name, result);
- return VB2_ERROR_UNKNOWN;
- }
+ i = 0;
+ while (!tpm_log_get(i++, &pcr, &digest_data, &digest_algo, &event_name)) {
+ printk(BIOS_DEBUG, "TPM: Write digest for %s into PCR %d\n", event_name, pcr);
+ int result = tlcl_extend(pcr, digest_data, digest_algo);
+ if (result != TPM_SUCCESS) {
+ printk(BIOS_ERR,
+ "TPM: Writing digest of %s into PCR failed with error %d\n",
+ event_name, result);
+ return VB2_ERROR_UNKNOWN;
}
}
return VB2_SUCCESS;
}
+
+#if !CONFIG(VBOOT_RETURN_FROM_VERSTAGE)
+static void recover_tpm_log(int is_recovery)
+{
+ const void *preram_log = _tpm_log;
+ void *ram_log = tpm_log_cbmem_init();
+
+ if (tpm_log_get_size(preram_log) > MAX_PRERAM_TPM_LOG_ENTRIES) {
+ printk(BIOS_WARNING, "TPM LOG: pre-RAM log is too full, possible corruption\n");
+ return;
+ }
+
+ if (ram_log == NULL) {
+ printk(BIOS_WARNING, "TPM LOG: CBMEM not available, something went wrong\n");
+ return;
+ }
+
+ tpm_log_copy_entries(_tpm_log, ram_log);
+}
+CBMEM_CREATION_HOOK(recover_tpm_log);
+#endif
+
+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, tpm_log_dump, NULL);
diff --git a/src/security/tpm/tspi/log.c b/src/security/tpm/tspi/log.c
index fa95b80e81..96c3087f95 100644
--- a/src/security/tpm/tspi/log.c
+++ b/src/security/tpm/tspi/log.c
@@ -6,10 +6,9 @@
#include <string.h>
#include <symbols.h>
#include <cbmem.h>
-#include <bootstate.h>
#include <vb2_sha.h>
-static struct tpm_cb_log_table *tpm_log_cbmem_init(void)
+void *tpm_log_cbmem_init(void)
{
static struct tpm_cb_log_table *tclt;
if (tclt)
@@ -30,27 +29,6 @@ static struct tpm_cb_log_table *tpm_log_cbmem_init(void)
return tclt;
}
-struct tpm_cb_log_table *tpm_log_init(void)
-{
- static struct tpm_cb_log_table *tclt;
-
- /* We are dealing here with pre CBMEM environment.
- * If cbmem isn't available use CAR or SRAM */
- if (!cbmem_possibly_online() &&
- !CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
- return (struct tpm_cb_log_table *)_tpm_log;
- else if (ENV_CREATES_CBMEM
- && !CONFIG(VBOOT_RETURN_FROM_VERSTAGE)) {
- tclt = tpm_log_cbmem_init();
- if (!tclt)
- return (struct tpm_cb_log_table *)_tpm_log;
- } else {
- tclt = tpm_log_cbmem_init();
- }
-
- return tclt;
-}
-
void tpm_log_dump(void *unused)
{
int i, j;
@@ -121,42 +99,62 @@ void tpm_preram_log_clear(void)
tclt->num_entries = 0;
}
-#if !CONFIG(VBOOT_RETURN_FROM_VERSTAGE)
-static void recover_tpm_log(int is_recovery)
+int tpm_log_get(int entry_idx, int *pcr, const uint8_t **digest_data,
+ enum vb2_hash_algorithm *digest_algo, const char **event_name)
{
- struct tpm_cb_log_table *preram_log = (struct tpm_cb_log_table *)_tpm_log;
- struct tpm_cb_log_table *ram_log = NULL;
- int i;
+ struct tpm_cb_log_table *tclt;
+ struct tpm_cb_log_entry *tce;
+ enum vb2_hash_algorithm algo;
- if (preram_log->num_entries > MAX_PRERAM_TPM_LOG_ENTRIES) {
- printk(BIOS_WARNING, "TPM LOG: pre-RAM log is too full, possible corruption\n");
- return;
- }
+ tclt = tpm_log_init();
+ if (!tclt)
+ return 1;
- ram_log = tpm_log_cbmem_init();
- if (!ram_log) {
- printk(BIOS_WARNING, "TPM LOG: CBMEM not available something went wrong\n");
- return;
+ if (entry_idx < 0 || entry_idx >= tclt->num_entries)
+ return 1;
+
+ tce = &tclt->entries[entry_idx];
+
+ *pcr = tce->pcr;
+ *digest_data = tce->digest;
+ *event_name = tce->name;
+
+ *digest_algo = VB2_HASH_INVALID;
+ for (algo = VB2_HASH_INVALID; algo != VB2_HASH_ALG_COUNT; ++algo) {
+ if (strcmp(tce->digest_type, vb2_hash_names[algo]) == 0) {
+ *digest_algo = algo;
+ break;
+ }
}
+ return 0;
+}
- for (i = 0; i < preram_log->num_entries; i++) {
- struct tpm_cb_log_entry *tce = &ram_log->entries[ram_log->num_entries++];
- strncpy(tce->name, preram_log->entries[i].name, TPM_CB_LOG_PCR_HASH_NAME - 1);
- tce->pcr = preram_log->entries[i].pcr;
+uint16_t tpm_log_get_size(const void *log_table)
+{
+ const struct tpm_cb_log_table *tclt = log_table;
+ return tclt->num_entries;
+}
+
+void tpm_log_copy_entries(const void *from, void *to)
+{
+ const struct tpm_cb_log_table *from_log = from;
+ struct tpm_cb_log_table *to_log = to;
+ int i;
+
+ for (i = 0; i < from_log->num_entries; i++) {
+ struct tpm_cb_log_entry *tce = &to_log->entries[to_log->num_entries++];
+ strncpy(tce->name, from_log->entries[i].name, TPM_CB_LOG_PCR_HASH_NAME - 1);
+ tce->pcr = from_log->entries[i].pcr;
- if (preram_log->entries[i].digest_length > TPM_CB_LOG_DIGEST_MAX_LENGTH) {
+ if (from_log->entries[i].digest_length > TPM_CB_LOG_DIGEST_MAX_LENGTH) {
printk(BIOS_WARNING, "TPM LOG: PCR digest too long for log entry\n");
return;
}
- strncpy(tce->digest_type, preram_log->entries[i].digest_type,
+ strncpy(tce->digest_type, from_log->entries[i].digest_type,
TPM_CB_LOG_PCR_HASH_LEN - 1);
- tce->digest_length = MIN(preram_log->entries[i].digest_length,
+ tce->digest_length = MIN(from_log->entries[i].digest_length,
TPM_CB_LOG_DIGEST_MAX_LENGTH);
- memcpy(tce->digest, preram_log->entries[i].digest, tce->digest_length);
+ memcpy(tce->digest, from_log->entries[i].digest, tce->digest_length);
}
}
-CBMEM_CREATION_HOOK(recover_tpm_log);
-#endif
-
-BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, tpm_log_dump, NULL);