From d487c3283c83d1314f9736bdfc69391dbc347154 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Mon, 27 Jan 2025 06:58:49 -0800 Subject: tpm: add PCR allocate into the eventlog handling Get eventlog bank mask when parsing the eventlog from previous boot stage and invoke PCR allocate function based on it. PCR allocate will be proceeded if any dismatches observed among the active, supportted and eventlog bank masks to re-configurate the TPM with the proper algorithms and reboot the system. Signed-off-by: Raymond Mao Reviewed-by: Ilias Apalodimas Signed-off-by: Ilias Apalodimas --- lib/tpm_tcg2.c | 52 +++++++++++++++++----------------------------------- 1 file changed, 17 insertions(+), 35 deletions(-) (limited to 'lib/tpm_tcg2.c') diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 4134d93a358..1175d08abc5 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -358,12 +358,12 @@ static int tcg2_replay_eventlog(struct tcg2_event_log *elog, return 0; } -static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) +static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog, + u32 *log_active) { struct tpml_digest_values digest_list; struct tcg_efi_spec_id_event *event; struct tcg_pcr_event *log; - u32 log_active; u32 calc_size; u32 active; u32 count; @@ -374,6 +374,8 @@ static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) int rc; u32 i; + *log_active = 0; + if (elog->log_size <= offsetof(struct tcg_pcr_event, event)) return 0; @@ -419,7 +421,6 @@ static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) * algorithms, so just check the EvenLog against the TPM active ones. */ digest_list.count = 0; - log_active = 0; for (i = 0; i < count; ++i) { algo = get_unaligned_le16(&event->digest_sizes[i].algorithm_id); mask = tcg2_algorithm_to_mask(algo); @@ -445,17 +446,15 @@ static int tcg2_log_parse(struct udevice *dev, struct tcg2_event_log *elog) algo); return -1; } - log_active |= mask; + *log_active |= mask; } rc = tcg2_get_active_pcr_banks(dev, &active); if (rc) return rc; /* If the EventLog and active algorithms don't match exit */ - if (log_active != active) { - log_err("EventLog doesn't contain all active PCR banks\n"); - return -1; - } + if (*log_active != active) + return -ERESTARTSYS; /* Read PCR0 to check if previous firmware extended the PCRs or not. */ rc = tcg2_pcr_read(dev, 0, &digest_list); @@ -552,43 +551,21 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, bool ignore_existing_log) { struct tcg2_event_log log; - int rc, i; + int rc; + u32 log_active = 0; elog->log_position = 0; elog->found = false; - /* - * Make sure U-Boot is compiled with all the active PCRs - * since we are about to create an EventLog and we won't - * measure anything if the PCR banks don't match - */ - if (!tpm2_check_active_banks(dev)) { - log_err("Cannot create EventLog\n"); - log_err("Mismatch between U-Boot and TPM hash algos\n"); - log_info("TPM:\n"); - tpm2_print_active_banks(dev); - log_info("U-Boot:\n"); - for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) { - const struct digest_info *algo = &hash_algo_list[i]; - const char *str; - - if (!algo->supported) - continue; - - str = tpm2_algorithm_name(algo->hash_alg); - if (str) - log_info("%s\n", str); - } - return -EINVAL; - } - rc = tcg2_platform_get_log(dev, (void **)&log.log, &log.log_size); if (!rc) { log.log_position = 0; log.found = false; if (!ignore_existing_log) { - rc = tcg2_log_parse(dev, &log); + rc = tcg2_log_parse(dev, &log, &log_active); + if (rc == -ERESTARTSYS && log_active) + goto pcr_allocate; if (rc) return rc; } @@ -615,6 +592,11 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, elog->found = log.found; } +pcr_allocate: + rc = tpm2_activate_banks(dev, log_active); + if (rc) + return rc; + /* * Initialize the log buffer if no log was discovered and the buffer is * valid. User's can pass in their own buffer as a fallback if no -- cgit v1.2.3 From 8895ff8ae2186b53b4a073966ef16b09c12a69b8 Mon Sep 17 00:00:00 2001 From: Raymond Mao Date: Mon, 27 Jan 2025 06:49:36 -0800 Subject: tpm: get tpm event log from bloblist Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage. Signed-off-by: Raymond Mao Reviewed-by: Ilias Apalodimas Signed-off-by: Ilias Apalodimas --- lib/tpm_tcg2.c | 59 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 20 deletions(-) (limited to 'lib/tpm_tcg2.c') diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 1175d08abc5..c314b401d0b 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -19,6 +19,7 @@ #include #include #include "tpm-utils.h" +#include int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_bank, u32 *active_bank, u32 *bank_num) @@ -654,21 +655,42 @@ void tcg2_measurement_term(struct udevice *dev, struct tcg2_event_log *elog, __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) { - const __be32 *addr_prop; - const __be32 *size_prop; + const __be32 *addr_prop = NULL; + const __be32 *size_prop = NULL; int asize; int ssize; + struct ofnode_phandle_args args; + phys_addr_t a; + fdt_size_t s; *addr = NULL; *size = 0; - addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); - if (!addr_prop) - addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); + *addr = bloblist_get_blob(BLOBLISTT_TPM_EVLOG, size); + if (*addr && *size) { + *addr = map_physmem((uintptr_t)(*addr), *size, MAP_NOCACHE); + return 0; + } - size_prop = dev_read_prop(dev, "tpm_event_log_size", &ssize); - if (!size_prop) + /* + * TODO: + * Replace BLOBLIST with a new kconfig for handoff all components + * (fdt, tpm event log, etc...) from previous boot stage via bloblist + * mandatorily following Firmware Handoff spec. + */ + if (!CONFIG_IS_ENABLED(BLOBLIST)) { + addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); + size_prop = dev_read_prop(dev, "tpm_event_log_size", &ssize); + } + + /* + * If no eventlog was observed, a sml buffer is required for the kernel + * to discover the eventlog. + */ + if (!addr_prop || !size_prop) { + addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); size_prop = dev_read_prop(dev, "linux,sml-size", &ssize); + } if (addr_prop && size_prop) { u64 a = of_read_number(addr_prop, asize / sizeof(__be32)); @@ -676,22 +698,19 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) *addr = map_physmem(a, s, MAP_NOCACHE); *size = (u32)s; - } else { - struct ofnode_phandle_args args; - phys_addr_t a; - fdt_size_t s; - if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, - 0, &args)) - return -ENODEV; + return 0; + } - a = ofnode_get_addr_size(args.node, "reg", &s); - if (a == FDT_ADDR_T_NONE) - return -ENOMEM; + if (dev_read_phandle_with_args(dev, "memory-region", NULL, 0, 0, &args)) + return -ENODEV; - *addr = map_physmem(a, s, MAP_NOCACHE); - *size = (u32)s; - } + a = ofnode_get_addr_size(args.node, "reg", &s); + if (a == FDT_ADDR_T_NONE) + return -ENOMEM; + + *addr = map_physmem(a, s, MAP_NOCACHE); + *size = (u32)s; return 0; } -- cgit v1.2.3