[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