[PATCH v3 1/2] bloblist: add api to get blob with size

bloblist_find function only returns the pointer of blob data, which is fine for those self-describing data like FDT. But as a common scenario, an interface is needed to retrieve both the pointer and the size of the blob data.
Add a few ut test cases for the new api.
Signed-off-by: Raymond Mao raymond.mao@linaro.org Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Ilias Apalodimas ilias.apalodimas@linaro.org --- Changes in v2 - Rename function argument. - Add ut tests. Changes in v3 - None.
common/bloblist.c | 17 +++++++++++++++-- include/bloblist.h | 18 ++++++++++++++++++ test/common/bloblist.c | 4 ++++ 3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/common/bloblist.c b/common/bloblist.c index 110bb9dc44..ab48a3cdb9 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -222,14 +222,27 @@ static int bloblist_ensurerec(uint tag, struct bloblist_rec **recp, int size, }
void *bloblist_find(uint tag, int size) +{ + void *blob = NULL; + int blob_size; + + blob = bloblist_get_blob(tag, &blob_size); + + if (size && size != blob_size) + return NULL; + + return blob; +} + +void *bloblist_get_blob(uint tag, int *sizep) { struct bloblist_rec *rec;
rec = bloblist_findrec(tag); if (!rec) return NULL; - if (size && size != rec->size) - return NULL; + + *sizep = rec->size;
return (void *)rec + rec_hdr_size(rec); } diff --git a/include/bloblist.h b/include/bloblist.h index f999391f74..52ba0ddcf8 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -250,6 +250,24 @@ static inline void *bloblist_check_magic(ulong addr) return ptr; }
+#if CONFIG_IS_ENABLED(BLOBLIST) +/** + * bloblist_get_blob() - Find a blob and get the size of it + * + * Searches the bloblist and returns the blob with the matching tag + * + * @tag: Tag to search for (enum bloblist_tag_t) + * @sizep: Size of the blob found + * Return: pointer to bloblist if found, or NULL if not found + */ +void *bloblist_get_blob(uint tag, int *sizep); +#else +static inline void *bloblist_get_blob(uint tag, int *sizep) +{ + return NULL; +} +#endif + /** * bloblist_find() - Find a blob * diff --git a/test/common/bloblist.c b/test/common/bloblist.c index 4bca62110a..324127596f 100644 --- a/test/common/bloblist.c +++ b/test/common/bloblist.c @@ -98,10 +98,12 @@ static int bloblist_test_blob(struct unit_test_state *uts) struct bloblist_hdr *hdr; struct bloblist_rec *rec, *rec2; char *data; + int size = 0;
/* At the start there should be no records */ hdr = clear_bloblist(); ut_assertnull(bloblist_find(TEST_TAG, TEST_BLOBLIST_SIZE)); + ut_assertnull(bloblist_get_blob(TEST_TAG, &size)); ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0, 0)); ut_asserteq(sizeof(struct bloblist_hdr), bloblist_get_size()); ut_asserteq(TEST_BLOBLIST_SIZE, bloblist_get_total_size()); @@ -114,6 +116,8 @@ static int bloblist_test_blob(struct unit_test_state *uts) ut_asserteq_addr(rec + 1, data); data = bloblist_find(TEST_TAG, TEST_SIZE); ut_asserteq_addr(rec + 1, data); + ut_asserteq_addr(bloblist_get_blob(TEST_TAG, &size), data); + ut_asserteq(size, TEST_SIZE);
/* Check the data is zeroed */ ut_assertok(check_zero(data, TEST_SIZE));

Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc an 8KB buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org --- Changes in v2 - Remove patch dependency. - Remove the fallback to FDT when BLOBLIST is selected. Changes in v3 - Malloc an 8KB buffer when user eventlog buffer does not exist.
include/tpm_tcg2.h | 2 ++ lib/tpm_tcg2.c | 55 ++++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/include/tpm_tcg2.h b/include/tpm_tcg2.h index 6519004cc4..6ea316888b 100644 --- a/include/tpm_tcg2.h +++ b/include/tpm_tcg2.h @@ -65,6 +65,8 @@ #define EFI_DTB_EVENT_STRING \ "DTB DATA"
+#define EVENT_LOG_DEF_BUF_SIZE 0x2000 + /** * struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information * diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 7f868cc883..d880b14888 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -5,6 +5,7 @@
#include <dm.h> #include <dm/of_access.h> +#include <malloc.h> #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> @@ -19,6 +20,7 @@ #include <linux/unaligned/generic.h> #include <linux/unaligned/le_byteshift.h> #include "tpm-utils.h" +#include <bloblist.h>
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, u32 *pcr_banks) @@ -607,15 +609,24 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, elog->found = log.found; }
+ if (elog->found) + return 0; + /* - * 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 - * memory region is found. + * Initialize the log buffer if no log was discovered. + * User can pass in their own buffer as a fallback if no memory region + * is found, else malloc a buffer if it does not exist. */ - if (!elog->found && elog->log_size) - rc = tcg2_log_init(dev, elog); + if (!elog->log_size) { + elog->log = malloc(EVENT_LOG_DEF_BUF_SIZE); + if (!elog->log) + return -ENOMEM; + + memset(elog->log, 0, EVENT_LOG_DEF_BUF_SIZE); + elog->log_size = EVENT_LOG_DEF_BUF_SIZE; + }
- return rc; + return tcg2_log_init(dev, elog); }
int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, @@ -668,10 +679,19 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) const __be32 *size_prop; int asize; int ssize; + struct ofnode_phandle_args args; + phys_addr_t a; + fdt_size_t s;
*addr = NULL; *size = 0;
+ *addr = bloblist_get_blob(BLOBLISTT_TPM_EVLOG, size); + if (*addr && *size) + return 0; + else if (CONFIG_IS_ENABLED(BLOBLIST)) + return -ENODEV; + addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); if (!addr_prop) addr_prop = dev_read_prop(dev, "linux,sml-base", &asize); @@ -686,22 +706,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; }

On Thu, 9 Jan 2025 at 17:09, Raymond Mao raymond.mao@linaro.org wrote:
Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc an 8KB buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Remove patch dependency.
- Remove the fallback to FDT when BLOBLIST is selected.
Changes in v3
- Malloc an 8KB buffer when user eventlog buffer does not exist.
include/tpm_tcg2.h | 2 ++ lib/tpm_tcg2.c | 55 ++++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/include/tpm_tcg2.h b/include/tpm_tcg2.h index 6519004cc4..6ea316888b 100644 --- a/include/tpm_tcg2.h +++ b/include/tpm_tcg2.h @@ -65,6 +65,8 @@ #define EFI_DTB_EVENT_STRING \ "DTB DATA"
+#define EVENT_LOG_DEF_BUF_SIZE 0x2000
That's too small for an eventlog. We have a confog option for the TCG eventlog size (EFI_TCG2_PROTOCOL_EVENTLOG_SIZE). I'd prefer decoupling this from EFI only and using that instead.
Cheers /Ilias
/**
- struct TCG_EfiSpecIdEventAlgorithmSize - hashing algorithm information
diff --git a/lib/tpm_tcg2.c b/lib/tpm_tcg2.c index 7f868cc883..d880b14888 100644 --- a/lib/tpm_tcg2.c +++ b/lib/tpm_tcg2.c @@ -5,6 +5,7 @@
#include <dm.h> #include <dm/of_access.h> +#include <malloc.h> #include <tpm_api.h> #include <tpm-common.h> #include <tpm-v2.h> @@ -19,6 +20,7 @@ #include <linux/unaligned/generic.h> #include <linux/unaligned/le_byteshift.h> #include "tpm-utils.h" +#include <bloblist.h>
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr, u32 *pcr_banks) @@ -607,15 +609,24 @@ int tcg2_log_prepare_buffer(struct udevice *dev, struct tcg2_event_log *elog, elog->found = log.found; }
if (elog->found)
return 0;
/*
* 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
* memory region is found.
* Initialize the log buffer if no log was discovered.
* User can pass in their own buffer as a fallback if no memory region
* is found, else malloc a buffer if it does not exist. */
if (!elog->found && elog->log_size)
rc = tcg2_log_init(dev, elog);
if (!elog->log_size) {
elog->log = malloc(EVENT_LOG_DEF_BUF_SIZE);
if (!elog->log)
return -ENOMEM;
memset(elog->log, 0, EVENT_LOG_DEF_BUF_SIZE);
elog->log_size = EVENT_LOG_DEF_BUF_SIZE;
}
return rc;
return tcg2_log_init(dev, elog);
}
int tcg2_measurement_init(struct udevice **dev, struct tcg2_event_log *elog, @@ -668,10 +679,19 @@ __weak int tcg2_platform_get_log(struct udevice *dev, void **addr, u32 *size) const __be32 *size_prop; int asize; int ssize;
struct ofnode_phandle_args args;
phys_addr_t a;
fdt_size_t s; *addr = NULL; *size = 0;
*addr = bloblist_get_blob(BLOBLISTT_TPM_EVLOG, size);
if (*addr && *size)
return 0;
else if (CONFIG_IS_ENABLED(BLOBLIST))
return -ENODEV;
addr_prop = dev_read_prop(dev, "tpm_event_log_addr", &asize); if (!addr_prop) addr_prop = dev_read_prop(dev, "linux,sml-base", &asize);
@@ -686,22 +706,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;
}
2.25.1

Hi Ilias,
On Fri, 10 Jan 2025 at 08:32, Ilias Apalodimas ilias.apalodimas@linaro.org wrote:
On Thu, 9 Jan 2025 at 17:09, Raymond Mao raymond.mao@linaro.org wrote:
Get tpm event log from bloblist instead of FDT when bloblist is enabled and valid from previous boot stage.
As a fallback, when no event log from previous stage is observed and no user buffer is passed, malloc an 8KB buffer to initialize the event log.
Signed-off-by: Raymond Mao raymond.mao@linaro.org
Changes in v2
- Remove patch dependency.
- Remove the fallback to FDT when BLOBLIST is selected.
Changes in v3
- Malloc an 8KB buffer when user eventlog buffer does not exist.
include/tpm_tcg2.h | 2 ++ lib/tpm_tcg2.c | 55 ++++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 19 deletions(-)
diff --git a/include/tpm_tcg2.h b/include/tpm_tcg2.h index 6519004cc4..6ea316888b 100644 --- a/include/tpm_tcg2.h +++ b/include/tpm_tcg2.h @@ -65,6 +65,8 @@ #define EFI_DTB_EVENT_STRING \ "DTB DATA"
+#define EVENT_LOG_DEF_BUF_SIZE 0x2000
That's too small for an eventlog. We have a confog option for the TCG eventlog size (EFI_TCG2_PROTOCOL_EVENTLOG_SIZE). I'd prefer decoupling this from EFI only and using that instead.
I got this size from "reg" of "memory-region", but yes I agree with what you suggested.
[snip]
Regards, Raymond
participants (2)
-
Ilias Apalodimas
-
Raymond Mao