* [PATCH] WIP: TPM additions
@ 2023-02-20 14:51 Simon Glass
2023-02-20 16:48 ` Ilias Apalodimas
0 siblings, 1 reply; 3+ messages in thread
From: Simon Glass @ 2023-02-20 14:51 UTC (permalink / raw)
To: U-Boot Mailing List
Cc: Ilias Apalodimas, Simon Glass, Dzmitry Sankouski,
Etienne Carriere, Marek Behún, Nikhil M Jain,
Patrick Delaunay, Ramon Fried, Sean Anderson, Sughosh Ganu
Signed-off-by: Simon Glass <sjg@chromium.org>
---
arch/sandbox/dts/test.dts | 4 ++
include/tpm-v1.h | 11 ++++
lib/tpm-v1.c | 11 ++++
lib/tpm-v2.c | 8 ---
lib/tpm_api.c | 19 +++++--
test/dm/tpm.c | 105 ++++++++++++++++++++++++++++++++++----
6 files changed, 138 insertions(+), 20 deletions(-)
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 05e09128a38..d72d7a567a7 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -1367,6 +1367,10 @@
compatible = "sandbox,tpm2";
};
+ tpm {
+ compatible = "google,sandbox-tpm";
+ };
+
uart0: serial {
compatible = "sandbox,serial";
bootph-all;
diff --git a/include/tpm-v1.h b/include/tpm-v1.h
index 33d53fb695e..60b71e2a4b6 100644
--- a/include/tpm-v1.h
+++ b/include/tpm-v1.h
@@ -591,4 +591,15 @@ u32 tpm_set_global_lock(struct udevice *dev);
*/
u32 tpm1_resume(struct udevice *dev);
+/**
+ * tpm1_auto_start() - start up the TPM
+ *
+ * This does not do a self test.
+ *
+ * @dev TPM device
+ * Return: TPM2_RC_SUCCESS, on success, or when the TPM returns
+ * TPM_INVALID_POSTINIT; TPM_FAILEDSELFTEST, if the TPM is in failure state
+ */
+u32 tpm1_auto_start(struct udevice *dev);
+
#endif /* __TPM_V1_H */
diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
index d0e3ab1b21d..884b8ddbac9 100644
--- a/lib/tpm-v1.c
+++ b/lib/tpm-v1.c
@@ -69,6 +69,17 @@ u32 tpm1_continue_self_test(struct udevice *dev)
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
+u32 tpm1_auto_start(struct udevice *dev)
+{
+ u32 rc;
+
+ rc = tpm1_startup(dev, TPM_ST_CLEAR);
+ if (rc == TPM_INVALID_POSTINIT)
+ rc = 0;
+
+ return rc;
+}
+
u32 tpm1_clear_and_reenable(struct udevice *dev)
{
u32 ret;
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 895b093bcb1..9ab5b46df17 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -48,14 +48,6 @@ u32 tpm2_auto_start(struct udevice *dev)
{
u32 rc;
- /*
- * the tpm_init() will return -EBUSY if the init has already happened
- * The selftest and startup code can run multiple times with no side
- * effects
- */
- rc = tpm_init(dev);
- if (rc && rc != -EBUSY)
- return rc;
rc = tpm2_self_test(dev, TPMI_YES);
if (rc == TPM2_RC_INITIALIZE) {
diff --git a/lib/tpm_api.c b/lib/tpm_api.c
index 5b2c11a277c..3ef5e811794 100644
--- a/lib/tpm_api.c
+++ b/lib/tpm_api.c
@@ -37,10 +37,23 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
u32 tpm_auto_start(struct udevice *dev)
{
- if (tpm_is_v2(dev))
- return tpm2_auto_start(dev);
+ u32 rc;
- return -ENOSYS;
+ /*
+ * the tpm_init() will return -EBUSY if the init has already happened
+ * The selftest and startup code can run multiple times with no side
+ * effects
+ */
+ rc = tpm_init(dev);
+ if (rc && rc != -EBUSY)
+ return rc;
+
+ if (tpm_is_v1(dev))
+ return tpm1_auto_start(dev);
+ else if (tpm_is_v2(dev))
+ return tpm2_auto_start(dev);
+ else
+ return -ENOSYS;
}
u32 tpm_resume(struct udevice *dev)
diff --git a/test/dm/tpm.c b/test/dm/tpm.c
index dca540bb561..14e675962c2 100644
--- a/test/dm/tpm.c
+++ b/test/dm/tpm.c
@@ -11,24 +11,111 @@
#include <test/test.h>
#include <test/ut.h>
-/* Basic test of the TPM uclass */
+/*
+ * get_tpm_version() - Get a TPM of the given version
+ *
+ * @version: Version to get
+ * @devp: Returns the TPM device
+ * Returns: 0 if OK, -ENODEV if not found
+ */
+static int get_tpm_version(enum tpm_version version, struct udevice **devp)
+{
+ struct udevice *dev;
+
+ /*
+ * For now we have to probe each TPM, since the version is set up in
+ * of_to_plat(). We could require TPMs to declare their version when
+ * probed, to avoid this
+ */
+ uclass_foreach_dev_probe(UCLASS_TPM, dev) {
+ if (tpm_get_version(dev) == version) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+/* Basic test of initing a TPM */
+static int test_tpm_init(struct unit_test_state *uts, enum tpm_version version)
+{
+ struct udevice *dev;
+
+ /* check probe success */
+ ut_assertok(get_tpm_version(version, &dev));
+
+ ut_assertok(tpm_init(dev));
+
+ return 0;
+}
+
static int dm_test_tpm(struct unit_test_state *uts)
+{
+ ut_assertok(test_tpm_init(uts, TPM_V1));
+ ut_assertok(test_tpm_init(uts, TPM_V2));
+
+ return 0;
+}
+DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT);
+
+/**
+ * test_tpm_autostart() - check the tpm_auto_start() call
+ *
+ * @uts: Unit test state
+ * @version: TPM version to use
+ * @reinit: true to call tpm_init() first
+ * Returns 0 if OK, non-zero on failure
+ */
+static int test_tpm_autostart(struct unit_test_state *uts,
+ enum tpm_version version, bool reinit)
+{
+ struct udevice *dev;
+
+ /* check probe success */
+ ut_assertok(get_tpm_version(version, &dev));
+
+ if (reinit)
+ ut_assertok(tpm_init(dev));
+ /*
+ * tpm_auto_start will rerun tpm_init() if reinit, but handles the
+ * -EBUSY return code internally.
+ */
+ ut_assertok(tpm_auto_start(dev));
+
+ return 0;
+}
+
+static int dm_test_tpm_autostart(struct unit_test_state *uts)
+{
+ ut_assertok(test_tpm_autostart(uts, TPM_V1, false));
+ ut_assertok(test_tpm_autostart(uts, TPM_V2, false));
+
+ return 0;
+}
+DM_TEST(dm_test_tpm_autostart, UT_TESTF_SCAN_FDT);
+
+static int dm_test_tpm_autostart_reinit(struct unit_test_state *uts)
+{
+ ut_assertok(test_tpm_autostart(uts, TPM_V1, true));
+ ut_assertok(test_tpm_autostart(uts, TPM_V2, true));
+
+ return 0;
+}
+DM_TEST(dm_test_tpm_autostart_reinit, UT_TESTF_SCAN_FDT);
+
+/* Test report_state */
+static int dm_test_tpm_report_state(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_assertok(get_tpm_version(TPM_V2, &dev));
ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
ut_asserteq_str("init_done=0", buf);
- ut_assertok(tpm_init(dev));
- /*
- * tpm_auto_start will rerun tpm_init, but handles the
- * -EBUSY return code internally.
- */
ut_assertok(tpm_auto_start(dev));
ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
@@ -36,4 +123,4 @@ static int dm_test_tpm(struct unit_test_state *uts)
return 0;
}
-DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT);
+DM_TEST(dm_test_tpm_report_state, UT_TESTF_SCAN_FDT);
--
2.39.2.637.g21b0678d19-goog
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] WIP: TPM additions
2023-02-20 14:51 [PATCH] WIP: TPM additions Simon Glass
@ 2023-02-20 16:48 ` Ilias Apalodimas
2023-02-20 16:50 ` Simon Glass
0 siblings, 1 reply; 3+ messages in thread
From: Ilias Apalodimas @ 2023-02-20 16:48 UTC (permalink / raw)
To: Simon Glass
Cc: U-Boot Mailing List, Dzmitry Sankouski, Etienne Carriere,
Marek Behún, Nikhil M Jain, Patrick Delaunay, Ramon Fried,
Sean Anderson, Sughosh Ganu
Hi Simon,
> + * @dev TPM device
> + * Return: TPM2_RC_SUCCESS, on success, or when the TPM returns
> + * TPM_INVALID_POSTINIT; TPM_FAILEDSELFTEST, if the TPM is in failure state
> + */
> +u32 tpm1_auto_start(struct udevice *dev);
> +
> #endif /* __TPM_V1_H */
> diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
> index d0e3ab1b21d..884b8ddbac9 100644
> --- a/lib/tpm-v1.c
> +++ b/lib/tpm-v1.c
> @@ -69,6 +69,17 @@ u32 tpm1_continue_self_test(struct udevice *dev)
> return tpm_sendrecv_command(dev, command, NULL, NULL);
> }
>
> +u32 tpm1_auto_start(struct udevice *dev)
> +{
> + u32 rc;
> +
> + rc = tpm1_startup(dev, TPM_ST_CLEAR);
> + if (rc == TPM_INVALID_POSTINIT)
> + rc = 0;
I am not an expert in 1.2 devices by any means, but don't you need to start
auto tests here as well similarly to what 2.0 does?
Looking at the kernel code it does something along the lines of
rc= tpm1_self_test_full(dev);
if (rc == TPM_FAILEDSELFTEST) {
.....
}
> +
> + return rc;
> - * -EBUSY return code internally.
[...]
> - */
> ut_assertok(tpm_auto_start(dev));
>
> ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
> @@ -36,4 +123,4 @@ static int dm_test_tpm(struct unit_test_state *uts)
>
> return 0;
> }
> -DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT);
> +DM_TEST(dm_test_tpm_report_state, UT_TESTF_SCAN_FDT);
> --
> 2.39.2.637.g21b0678d19-goog
>
Other than that, this looks ok to me
Cheers
/Ilias
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] WIP: TPM additions
2023-02-20 16:48 ` Ilias Apalodimas
@ 2023-02-20 16:50 ` Simon Glass
0 siblings, 0 replies; 3+ messages in thread
From: Simon Glass @ 2023-02-20 16:50 UTC (permalink / raw)
To: Ilias Apalodimas
Cc: U-Boot Mailing List, Dzmitry Sankouski, Etienne Carriere,
Marek Behún, Nikhil M Jain, Patrick Delaunay, Ramon Fried,
Sean Anderson, Sughosh Ganu
Hi Ilias,
On Mon, 20 Feb 2023 at 09:48, Ilias Apalodimas
<ilias.apalodimas@linaro.org> wrote:
>
> Hi Simon,
>
> > + * @dev TPM device
> > + * Return: TPM2_RC_SUCCESS, on success, or when the TPM returns
> > + * TPM_INVALID_POSTINIT; TPM_FAILEDSELFTEST, if the TPM is in failure state
> > + */
> > +u32 tpm1_auto_start(struct udevice *dev);
> > +
> > #endif /* __TPM_V1_H */
> > diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
> > index d0e3ab1b21d..884b8ddbac9 100644
> > --- a/lib/tpm-v1.c
> > +++ b/lib/tpm-v1.c
> > @@ -69,6 +69,17 @@ u32 tpm1_continue_self_test(struct udevice *dev)
> > return tpm_sendrecv_command(dev, command, NULL, NULL);
> > }
> >
> > +u32 tpm1_auto_start(struct udevice *dev)
> > +{
> > + u32 rc;
> > +
> > + rc = tpm1_startup(dev, TPM_ST_CLEAR);
> > + if (rc == TPM_INVALID_POSTINIT)
> > + rc = 0;
>
> I am not an expert in 1.2 devices by any means, but don't you need to start
> auto tests here as well similarly to what 2.0 does?
> Looking at the kernel code it does something along the lines of
>
> rc= tpm1_self_test_full(dev);
> if (rc == TPM_FAILEDSELFTEST) {
> .....
> }
>
Yes, if it has never been done before, e.g. in the factory. I didn't
understand that you were trying to do that. I will update it. Note
that this will add time.
>
> > +
> > + return rc;
> > - * -EBUSY return code internally.
>
> [...]
>
> > - */
> > ut_assertok(tpm_auto_start(dev));
> >
> > ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
> > @@ -36,4 +123,4 @@ static int dm_test_tpm(struct unit_test_state *uts)
> >
> > return 0;
> > }
> > -DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT);
> > +DM_TEST(dm_test_tpm_report_state, UT_TESTF_SCAN_FDT);
> > --
> > 2.39.2.637.g21b0678d19-goog
> >
>
>
>
> Other than that, this looks ok to me
OK I will clean it up and send.
Regards,
Simon
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-02-20 16:50 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-20 14:51 [PATCH] WIP: TPM additions Simon Glass
2023-02-20 16:48 ` Ilias Apalodimas
2023-02-20 16:50 ` Simon Glass
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.