[PATCH v2 2/3] tpm: print all PCRs from pcr_read
Ludwig Nussel
ludwig.nussel at siemens.com
Wed Jun 10 12:52:04 CEST 2026
Output is now more similar to the Linux userspace tool "tpm2_pcrread".
The old semantics that require specifying one PCR number are
retained. In addition with no arguments the command now prints
contents of all PCR registers.
Signed-off-by: Ludwig Nussel <ludwig.nussel at siemens.com>
---
Changes in v2:
- fix return value handling
cmd/tpm-v2.c | 69 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 50 insertions(+), 19 deletions(-)
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
index 847b2691581..e9f4bc24e33 100644
--- a/cmd/tpm-v2.c
+++ b/cmd/tpm-v2.c
@@ -8,6 +8,7 @@
#include <dm.h>
#include <log.h>
#include <mapmem.h>
+#include <malloc.h>
#include <tpm-common.h>
#include <tpm-v2.h>
#include "tpm-user-utils.h"
@@ -150,10 +151,11 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
u32 index, rc;
int algo_len;
unsigned int updates;
- void *data;
+ u8 *data;
int ret;
+ u32 pcr_start, pcr_end;
- if (argc < 3 || argc > 4)
+ if (argc > 4)
return CMD_RET_USAGE;
if (argc == 4) {
algo = tpm2_name_to_algorithm(argv[3]);
@@ -168,25 +170,51 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc,
priv = dev_get_uclass_priv(dev);
if (!priv)
- return -EINVAL;
-
- index = simple_strtoul(argv[1], NULL, 0);
- if (index >= priv->pcr_count)
- return -EINVAL;
+ return CMD_RET_FAILURE;
- data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
+ if (argc >= 2) {
+ pcr_start = simple_strtoul(argv[1], NULL, 0);
+ if (pcr_start >= priv->pcr_count) {
+ log_err("Index %u out of range (max %u)\n", pcr_start, priv->pcr_count - 1);
+ return CMD_RET_FAILURE;
+ }
+ pcr_end = pcr_start + 1;
+ } else {
+ pcr_start = 0;
+ pcr_end = priv->pcr_count;
+ }
- rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, algo,
- data, algo_len, &updates);
- if (!rc) {
- printf("PCR #%u %s %d byte content (%u known updates):\n", index,
- tpm2_algorithm_name(algo), algo_len, updates);
- print_byte_string(data, algo_len);
+ if (argc >= 3) {
+ data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0);
+ } else {
+ data = malloc(algo_len);
+ if (!data) {
+ log_err("Failed to allocate %u bytes for PCR data\n", algo_len);
+ return CMD_RET_FAILURE;
+ }
}
- unmap_sysmem(data);
+ printf("%8s:\n", tpm2_algorithm_name(algo));
+ for (index = pcr_start; index < pcr_end; ++index) {
+ printf("%6u: ", index);
+ rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, algo,
+ data, algo_len, &updates);
+ if (rc == 0) {
+ printf("0x");
+ for (int i = 0; i < algo_len; ++i)
+ printf("%02X", data[i]);
+ printf(" (%u known updates)\n", updates);
+ } else {
+ log_err("PCR #%u read failed: %d\n", index, rc);
+ ret = report_return_code(rc);
+ }
+ }
+ if (argc >= 3)
+ unmap_sysmem(data);
+ else
+ free(data);
- return report_return_code(rc);
+ return ret;
}
static int do_tpm_get_capability(struct cmd_tbl *cmdtp, int flag, int argc,
@@ -548,10 +576,13 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command",
" Extend PCR #<pcr> with digest at <digest_addr> with digest_algo.\n"
" <pcr>: index of the PCR\n"
" <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
-"pcr_read <pcr> <digest_addr> [<digest_algo>]\n"
+"pcr_read [<pcr> [<digest_addr> [<digest_algo>]]]\n"
" Read PCR #<pcr> to memory address <digest_addr> with <digest_algo>.\n"
-" <pcr>: index of the PCR\n"
-" <digest_addr>: address of digest of digest_algo type (defaults to SHA256)\n"
+" With no arguments, print all PCR registers.\n"
+" If only <pcr> is specified, a buffer is allocated internally.\n"
+" <pcr>: index of the PCR (optional, defaults to all PCRs)\n"
+" <digest_addr>: address of digest of digest_algo type (optional)\n"
+" <digest_algo>: digest algorithm type (defaults to SHA256)\n"
"get_capability <capability> <property> <addr> <count>\n"
" Read and display <count> entries indexed by <capability>/<property>.\n"
" Values are 4 bytes long and are written at <addr>.\n"
--
2.43.0
More information about the U-Boot
mailing list