From: seanedmond@linux.microsoft.com
To: u-boot@lists.denx.de
Cc: sjg@chromium.org, stcarlso@linux.microsoft.com,
ilias.apalodimas@linaro.org
Subject: [PATCH 2/8] drivers: rollback: Add TPM2 implementation of rollback devices
Date: Tue, 12 Sep 2023 02:47:25 -0700 [thread overview]
Message-ID: <20230912094731.51413-3-seanedmond@linux.microsoft.com> (raw)
In-Reply-To: <20230912094731.51413-1-seanedmond@linux.microsoft.com>
From: Stephen Carlson <stcarlso@linux.microsoft.com>
This implementation of the rollback uclass driver allows existing TPM2
devices declared in the device tree to be referenced for storing the OS
anti-rollback counter, using the TPM2 non-volatile storage API. The
rollback device must be a child of the TPM device. For example:
tpm2 {
compatible = "sandbox,tpm2";
rollback@1 {
compatible = "tpm,rollback";
rollback-nv-index = <0x1001007>;
};
};
Signed-off-by: Stephen Carlson <stcarlso@linux.microsoft.com>
Signed-off-by: Sean Edmond <seanedmond@microsoft.com>
---
MAINTAINERS | 1 +
drivers/rollback/Makefile | 1 +
drivers/rollback/rollback-tpm.c | 117 ++++++++++++++++++++++++++++++++
include/tpm-v2.h | 17 +++++
lib/tpm-v2.c | 48 +++++++++++++
5 files changed, 184 insertions(+)
create mode 100644 drivers/rollback/rollback-tpm.c
diff --git a/MAINTAINERS b/MAINTAINERS
index de14724c27..e5ac889db4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1446,6 +1446,7 @@ F: drivers/rollback/Kconfig
F: drivers/rollback/Makefile
F: drivers/rollback/rollback-sandbox.c
F: drivers/rollback/rollback-uclass.c
+F: drivers/security/rollback-tpm.c
SEMIHOSTING
R: Sean Anderson <sean.anderson@seco.com>
diff --git a/drivers/rollback/Makefile b/drivers/rollback/Makefile
index 4e7fa46041..63c08863ca 100644
--- a/drivers/rollback/Makefile
+++ b/drivers/rollback/Makefile
@@ -4,3 +4,4 @@
obj-$(CONFIG_DM_ROLLBACK) += rollback-uclass.o
obj-$(CONFIG_ROLLBACK_SANDBOX) += rollback-sandbox.o
+obj-$(CONFIG_ROLLBACK_TPM) += rollback-tpm.o
\ No newline at end of file
diff --git a/drivers/rollback/rollback-tpm.c b/drivers/rollback/rollback-tpm.c
new file mode 100644
index 0000000000..3bb6214042
--- /dev/null
+++ b/drivers/rollback/rollback-tpm.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Microsoft, Inc
+ * Written by Stephen Carlson <stcarlso@microsoft.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <rollback.h>
+#include <tpm_api.h>
+
+struct rollback_state {
+ u32 nv_index;
+ struct udevice *tpm_dev;
+};
+
+static int tpm_rollback_idx_get(struct udevice *dev, u64 *rollback_idx)
+{
+ struct rollback_state *priv = dev_get_priv(dev);
+ int ret;
+
+ if (!rollback_idx)
+ return -EINVAL;
+
+ ret = tpm2_nv_read_value(priv->tpm_dev, priv->nv_index, rollback_idx, sizeof(u64));
+ if (ret) {
+ log(UCLASS_ROLLBACK, LOGL_ERR,
+ "Unable to read rollback number from TPM (ret=%d)\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int tpm_rollback_idx_set(struct udevice *dev, u64 rollback_idx)
+{
+ int ret;
+ struct rollback_state *priv = dev_get_priv(dev);
+
+ ret = tpm2_nv_write_value(priv->tpm_dev, priv->nv_index, &rollback_idx, sizeof(u64));
+ if (ret) {
+ log(UCLASS_ROLLBACK, LOGL_ERR,
+ "Unable to write anti-rollback version to TPM (ret=%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct rollback_ops tpm_rollback_ops = {
+ .rollback_idx_get = tpm_rollback_idx_get,
+ .rollback_idx_set = tpm_rollback_idx_set,
+};
+
+static int tpm_rollback_probe(struct udevice *dev)
+{
+ struct rollback_state *priv = dev_get_priv(dev);
+ int ret;
+
+ /* initialize the TPM rollback counter NV index
+ * and initial to 0. Note, this driver provides
+ * a NULL policy.
+ */
+ ret = tpm_rollback_counter_init(priv->tpm_dev, priv->nv_index,
+ NULL, 0);
+ if (ret) {
+ log(UCLASS_ROLLBACK, LOGL_ERR,
+ "TPM rollback init failed (ret=%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int tpm_rollback_remove(struct udevice *dev)
+{
+ struct rollback_state *priv = dev_get_priv(dev);
+
+ return tpm_close(priv->tpm_dev);
+}
+
+static int tpm_rollback_ofdata_to_platdata(struct udevice *dev)
+{
+ struct udevice *parent_dev;
+ struct rollback_state *priv = dev_get_priv(dev);
+
+ priv->nv_index = (u32)dev_read_u32_default(dev, "rollback-nv-index", 0);
+
+ parent_dev = dev_get_parent(dev);
+
+ if (parent_dev->driver->id == UCLASS_TPM) {
+ priv->tpm_dev = parent_dev;
+ } else {
+ log(UCLASS_ROLLBACK, LOGL_ERR,
+ "TPM rollback must be a child node of a TPM\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id tpm_rollback_ids[] = {
+ { .compatible = "tpm,rollback" },
+ { }
+};
+
+U_BOOT_DRIVER(rollback_tpm) = {
+ .name = "rollback_tpm",
+ .id = UCLASS_ROLLBACK,
+ .priv_auto = sizeof(struct rollback_state),
+ .of_match = tpm_rollback_ids,
+ .of_to_plat = tpm_rollback_ofdata_to_platdata,
+ .probe = tpm_rollback_probe,
+ .remove = tpm_rollback_remove,
+ .ops = &tpm_rollback_ops,
+};
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 2b6980e441..8c441066a0 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -321,6 +321,7 @@ enum tpm2_return_codes {
TPM2_RC_COMMAND_CODE = TPM2_RC_VER1 + 0x0043,
TPM2_RC_AUTHSIZE = TPM2_RC_VER1 + 0x0044,
TPM2_RC_AUTH_CONTEXT = TPM2_RC_VER1 + 0x0045,
+ TPM2_RC_NV_UNINITIALIZED = TPM2_RC_VER1 + 0x04a,
TPM2_RC_NV_DEFINED = TPM2_RC_VER1 + 0x004c,
TPM2_RC_NEEDS_TEST = TPM2_RC_VER1 + 0x0053,
TPM2_RC_WARN = 0x0900,
@@ -706,4 +707,20 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
*/
u32 tpm2_auto_start(struct udevice *dev);
+/**
+ * tpm_rollback_counter_init() - Initialize a TPM rollback counter
+ * (used by the TPM-backed rollback device)
+ *
+ * Will define the non-volitile index and initialize to 0 if it hasn't
+ * been created previously.
+ *
+ * @dev: TPM device
+ * @nv_index: NV index to initialize
+ * @nv_policy: NV index policy (pass NULL for no policy)
+ * @nv_policy_size: NV index policy size (pass 0 for no policy)
+ * Return: result of the operation
+ */
+int tpm_rollback_counter_init(struct udevice *dev, u32 nv_index,
+ const u8 *nv_policy, size_t nv_policy_size);
+
#endif /* __TPM_V2_H */
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 9ab5b46df1..c3c469eb35 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -742,3 +742,51 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
return 0;
}
+
+int tpm_rollback_counter_init(struct udevice *dev, u32 nv_index,
+ const u8 *nv_policy, size_t nv_policy_size)
+{
+ int ret;
+ u64 data;
+ u64 data0 = 0;
+
+ ret = tpm_open(dev);
+ if (ret == -EBUSY) {
+ log(UCLASS_ROLLBACK, LOGL_DEBUG,
+ "Existing TPM session found, reusing\n");
+ } else {
+ if (ret) {
+ log(UCLASS_ROLLBACK, LOGL_ERR,
+ "TPM initialization failed (ret=%d)\n", ret);
+ return ret;
+ }
+
+ ret = tpm2_auto_start(dev);
+ if (ret) {
+ log(UCLASS_ROLLBACK, LOGL_ERR,
+ "TPM startup failed (ret=%d)\n", ret);
+ return ret;
+ }
+ }
+
+ if (ret) {
+ log_err("TPM startup failed\n");
+ return ret;
+ }
+
+ /* test reading NV index from TPM */
+ ret = tpm2_nv_read_value(dev, nv_index, &data, sizeof(u64));
+
+ if (ret) {
+ /*read failed. Assume the NV index hasn't been defined yet */
+ ret = tpm2_nv_define_space(dev, nv_index, sizeof(u64), TPMA_NV_PPREAD |
+ TPMA_NV_PPWRITE | TPMA_NV_PLATFORMCREATE,
+ nv_policy, nv_policy_size);
+
+ /* initialize the rollback counter to 0 */
+ if (ret == TPM2_RC_NV_DEFINED || !ret)
+ ret = tpm2_nv_write_value(dev, nv_index, &data0, sizeof(u64));
+ }
+
+ return ret;
+}
--
2.40.0
next prev parent reply other threads:[~2023-09-12 9:48 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-12 9:47 [PATCH 0/5] Add anti-rollback validation feature seanedmond
2023-09-12 9:47 ` [PATCH 1/8] drivers: rollback: Add rollback devices to driver model seanedmond
2023-12-01 14:16 ` Ilias Apalodimas
2023-12-01 18:32 ` Simon Glass
2023-09-12 9:47 ` seanedmond [this message]
2023-12-01 14:52 ` [PATCH 2/8] drivers: rollback: Add TPM2 implementation of rollback devices Ilias Apalodimas
2023-12-01 18:32 ` Simon Glass
2023-09-12 9:47 ` [PATCH 3/8] common: Add OS anti-rollback validation using " seanedmond
2023-09-12 9:47 ` [PATCH 4/8] common: Add OS anti-rollback grace version seanedmond
2023-09-12 9:47 ` [PATCH 5/8] dm: test: Add a test for rollback driver seanedmond
2023-09-12 9:47 ` [PATCH 6/8] tpm: Fix issues relating to NV Indexes seanedmond
2023-09-12 9:47 ` [PATCH 7/8] sandbox: tpm: Fix TPM2_CC_NV_DEFINE_SPACE command seanedmond
2023-09-12 9:47 ` [PATCH 8/8] doc: rollback: anti-rollback verification seanedmond
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230912094731.51413-3-seanedmond@linux.microsoft.com \
--to=seanedmond@linux.microsoft.com \
--cc=ilias.apalodimas@linaro.org \
--cc=sjg@chromium.org \
--cc=stcarlso@linux.microsoft.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.