[PATCH v4 2/6] tpm: print all PCRs from pcr_read

Ilias Apalodimas ilias.apalodimas at linaro.org
Wed Jul 1 13:05:39 CEST 2026


On Mon, 29 Jun 2026 at 11:02, Ludwig Nussel <ludwig.nussel at siemens.com> wrote:
>
> 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>
>
> ---

Acked-by: Ilias Apalodimas <ilias.apalodimas at linaro.org>

>
> (no changes since v3)
>
> Changes in v3:
> - fix test failure
>
> Changes in v2:
> - fix return value handling
>
>  cmd/tpm-v2.c               | 69 +++++++++++++++++++++++++++-----------
>  test/py/tests/test_tpm2.py |  9 ++---
>  2 files changed, 53 insertions(+), 25 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"
> diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py
> index 9be85999d46..1baf86dd065 100644
> --- a/test/py/tests/test_tpm2.py
> +++ b/test/py/tests/test_tpm2.py
> @@ -198,8 +198,7 @@ def test_tpm2_pcr_read(ubman):
>      updates = int(re.findall(r'\d+', str)[0])
>
>      # Check the output value
> -    assert 'PCR #10 sha256 32 byte content' in read_pcr
> -    assert '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' in read_pcr
> +    assert 'sha256:\r\r\n    10: 0x0000000000000000000000000000000000000000000000000000000000000000' in read_pcr
>
>  @pytest.mark.buildconfigspec('cmd_tpm_v2')
>  @pytest.mark.notbuildconfigspec('target_chromebook_coral')
> @@ -230,8 +229,7 @@ def test_tpm2_pcr_extend(ubman):
>      read_pcr = ubman.run_command('tpm2 pcr_read 10 0x%x' % (ram + 0x20))
>      output = ubman.run_command('echo $?')
>      assert output.endswith('0')
> -    assert 'f5 a5 fd 42 d1 6a 20 30 27 98 ef 6e d3 09 97 9b' in read_pcr
> -    assert '43 00 3d 23 20 d9 f0 e8 ea 98 31 a9 27 59 fb 4b' in read_pcr
> +    assert 'sha256:\r\r\n    10: 0xF5A5FD42D16A20302798EF6ED309979B43003D2320D9F0E8EA9831A92759FB4B' in read_pcr
>
>      str = re.findall(r'\d+ known updates', read_pcr)[0]
>      new_updates = int(re.findall(r'\d+', str)[0])
> @@ -244,8 +242,7 @@ def test_tpm2_pcr_extend(ubman):
>      read_pcr = ubman.run_command('tpm2 pcr_read 10 0x%x' % (ram + 0x20))
>      output = ubman.run_command('echo $?')
>      assert output.endswith('0')
> -    assert '7a 05 01 f5 95 7b df 9c b3 a8 ff 49 66 f0 22 65' in read_pcr
> -    assert 'f9 68 65 8b 7a 9c 62 64 2c ba 11 65 e8 66 42 f5' in read_pcr
> +    assert '10: 0x7A0501F5957BDF9CB3A8FF4966F02265F968658B7A9C62642CBA1165E86642F5' in read_pcr
>
>      str = re.findall(r'\d+ known updates', read_pcr)[0]
>      new_updates = int(re.findall(r'\d+', str)[0])
> --
> 2.43.0
>


More information about the U-Boot mailing list