[PATCH v4 5/7] tpm: Allow reporting the internal state

Ilias Apalodimas ilias.apalodimas at linaro.org
Fri Aug 26 08:37:02 CEST 2022


On Tue, 23 Aug 2022 at 20:13, Simon Glass <sjg at chromium.org> wrote:
>
> It is useful to read information about the current TPM state, where
> supported, e.g. for debugging purposes when verified boot fails.
>
> Add support for this to the TPM interface as well as Cr50. Add a simple
> sandbox test.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> (no changes since v1)
>
>  cmd/tpm-common.c               | 20 ++++++++++++++++++++
>  cmd/tpm-user-utils.h           |  2 ++
>  cmd/tpm-v2.c                   |  3 +++
>  drivers/tpm/tpm-uclass.c       | 10 ++++++++++
>  drivers/tpm/tpm2_tis_sandbox.c | 11 +++++++++++
>  include/tpm-common.h           | 20 ++++++++++++++++++++
>  test/dm/Makefile               |  1 +
>  test/dm/tpm.c                  | 34 ++++++++++++++++++++++++++++++++++
>  8 files changed, 101 insertions(+)
>  create mode 100644 test/dm/tpm.c
>
> diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
> index 47adaffd184..d0c63cadf41 100644
> --- a/cmd/tpm-common.c
> +++ b/cmd/tpm-common.c
> @@ -333,6 +333,26 @@ int do_tpm_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>         return 0;
>  }
>
> +int do_tpm_report_state(struct cmd_tbl *cmdtp, int flag, int argc,
> +                       char *const argv[])
> +{
> +       struct udevice *dev;
> +       char buf[80];
> +       int rc;
> +
> +       rc = get_tpm(&dev);
> +       if (rc)
> +               return rc;
> +       rc = tpm_report_state(dev, buf, sizeof(buf));
> +       if (rc < 0) {
> +               printf("Couldn't get TPM state (%d)\n", rc);
> +               return CMD_RET_FAILURE;
> +       }
> +       printf("%s\n", buf);
> +
> +       return 0;
> +}
> +
>  int do_tpm_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
>  {
>         struct udevice *dev;
> diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
> index 358ddff5761..de4a934aab6 100644
> --- a/cmd/tpm-user-utils.h
> +++ b/cmd/tpm-user-utils.h
> @@ -21,6 +21,8 @@ int do_tpm_device(struct cmd_tbl *cmdtp, int flag, int argc,
>                   char *const argv[]);
>  int do_tpm_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>  int do_tpm_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
> +int do_tpm_report_state(struct cmd_tbl *cmdtp, int flag, int argc,
> +                       char *const argv[]);
>  int do_tpm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
>
>  #endif /* __TPM_USER_UTILS_H */
> diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
> index 4ea5f9f094f..d93b83ada93 100644
> --- a/cmd/tpm-v2.c
> +++ b/cmd/tpm-v2.c
> @@ -359,6 +359,7 @@ static int do_tpm_pcr_setauthvalue(struct cmd_tbl *cmdtp, int flag,
>  static struct cmd_tbl tpm2_commands[] = {
>         U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
>         U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
> +       U_BOOT_CMD_MKENT(state, 0, 1, do_tpm_report_state, "", ""),
>         U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
>         U_BOOT_CMD_MKENT(startup, 0, 1, do_tpm2_startup, "", ""),
>         U_BOOT_CMD_MKENT(self_test, 0, 1, do_tpm2_self_test, "", ""),
> @@ -389,6 +390,8 @@ U_BOOT_CMD(tpm2, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command",
>  "    Show all devices or set the specified device\n"
>  "info\n"
>  "    Show information about the TPM.\n"
> +"state\n"
> +"    Show internal state from the TPM (if available)\n"
>  "init\n"
>  "    Initialize the software stack. Always the first command to issue.\n"
>  "startup <mode>\n"
> diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
> index 0eb35f50c4e..5ff0cd3958c 100644
> --- a/drivers/tpm/tpm-uclass.c
> +++ b/drivers/tpm/tpm-uclass.c
> @@ -49,6 +49,16 @@ int tpm_get_desc(struct udevice *dev, char *buf, int size)
>         return ops->get_desc(dev, buf, size);
>  }
>
> +int tpm_report_state(struct udevice *dev, char *buf, int size)
> +{
> +       struct tpm_ops *ops = tpm_get_ops(dev);
> +
> +       if (!ops->report_state)
> +               return -ENOSYS;
> +
> +       return ops->report_state(dev, buf, size);
> +}
> +
>  /* Returns max number of milliseconds to wait */
>  static ulong tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip_priv *priv,
>                                                u32 ordinal)
> diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
> index c26f5d35abf..dd94bdc31fb 100644
> --- a/drivers/tpm/tpm2_tis_sandbox.c
> +++ b/drivers/tpm/tpm2_tis_sandbox.c
> @@ -795,6 +795,16 @@ static int sandbox_tpm2_get_desc(struct udevice *dev, char *buf, int size)
>         return snprintf(buf, size, "Sandbox TPM2.x");
>  }
>
> +static int sandbox_tpm2_report_state(struct udevice *dev, char *buf, int size)
> +{
> +       struct sandbox_tpm2 *priv = dev_get_priv(dev);
> +
> +       if (size < 40)
> +               return -ENOSPC;
> +
> +       return snprintf(buf, size, "init_done=%d", priv->init_done);
> +}
> +
>  static int sandbox_tpm2_open(struct udevice *dev)
>  {
>         struct sandbox_tpm2 *tpm = dev_get_priv(dev);
> @@ -834,6 +844,7 @@ static const struct tpm_ops sandbox_tpm2_ops = {
>         .open           = sandbox_tpm2_open,
>         .close          = sandbox_tpm2_close,
>         .get_desc       = sandbox_tpm2_get_desc,
> +       .report_state   = sandbox_tpm2_report_state,
>         .xfer           = sandbox_tpm2_xfer,
>  };
>
> diff --git a/include/tpm-common.h b/include/tpm-common.h
> index a28629e7013..b2c5404430f 100644
> --- a/include/tpm-common.h
> +++ b/include/tpm-common.h
> @@ -119,6 +119,16 @@ struct tpm_ops {
>          */
>         int (*get_desc)(struct udevice *dev, char *buf, int size);
>
> +       /**
> +        * report_state() - Collect information about the current TPM state
> +        *
> +        * @dev:        Device to check
> +        * @buf:        Buffer to put the string
> +        * @size:       Maximum size of buffer
> +        * Return: return code of the operation (0 = success)
> +        */
> +       int (*report_state)(struct udevice *dev, char *buf, int size);
> +
>         /**
>          * send() - send data to the TPM
>          *
> @@ -234,6 +244,16 @@ u32 tpm_clear_and_reenable(struct udevice *dev);
>   */
>  int tpm_get_desc(struct udevice *dev, char *buf, int size);
>
> +/**
> + * tpm_report_state() - Collect information about the current TPM state
> + *
> + * @dev:       Device to check
> + * @buf:       Buffer to put the string
> + * @size:      Maximum size of buffer
> + * Return: return code of the operation (0 = success)
> + */
> +int tpm_report_state(struct udevice *dev, char *buf, int size);
> +
>  /**
>   * tpm_xfer() - send data to the TPM and get response
>   *
> diff --git a/test/dm/Makefile b/test/dm/Makefile
> index 52fe178a828..7543df8823c 100644
> --- a/test/dm/Makefile
> +++ b/test/dm/Makefile
> @@ -107,6 +107,7 @@ obj-$(CONFIG_SYSINFO_GPIO) += sysinfo-gpio.o
>  obj-$(CONFIG_UT_DM) += tag.o
>  obj-$(CONFIG_TEE) += tee.o
>  obj-$(CONFIG_TIMER) += timer.o
> +obj-$(CONFIG_TPM_V2) += tpm.o
>  obj-$(CONFIG_DM_USB) += usb.o
>  obj-$(CONFIG_DM_VIDEO) += video.o
>  ifeq ($(CONFIG_VIRTIO_SANDBOX),y)
> diff --git a/test/dm/tpm.c b/test/dm/tpm.c
> new file mode 100644
> index 00000000000..0b46f799591
> --- /dev/null
> +++ b/test/dm/tpm.c
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2022 Google LLC
> + * Written by Simon Glass <sjg at chromium.org>
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <tpm_api.h>
> +#include <dm/test.h>
> +#include <test/test.h>
> +#include <test/ut.h>
> +
> +/* Basic test of the TPM uclass */
> +static int dm_test_tpm(struct unit_test_state *uts)
> +{
> +       struct udevice *dev;
> +       char buf[50];
> +
> +       /* check probe success */
> +       ut_assertok(uclass_first_device_err(UCLASS_TPM, &dev));
> +       ut_assert(tpm_is_v2(dev));
> +
> +       ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
> +       ut_asserteq_str("init_done=0", buf);
> +
> +       ut_assertok(tpm_init(dev));
> +
> +       ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
> +       ut_asserteq_str("init_done=1", buf);
> +
> +       return 0;
> +}
> +DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT);
> --
> 2.37.2.609.g9ff673ca1a-goog
>

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


More information about the U-Boot mailing list