[U-Boot] [PATCH v2 2/2] Add a cli command to test the TPM device.

Vadim Bendebury vbendeb at chromium.org
Sat Oct 15 05:39:08 CEST 2011


The command gets an arbitrary number of arguments (up to 30), which
are interpreted as byte values and are feed into the TPM device after
proper initialization. Then the return value and data of the TPM
driver is examined.

TPM commands are described in the TCG specification.

For instance, the following sequence is the 'TPM Startup' command, it
is processed by the TPM and a response is generated:

boot > tpm 0x0 0xc1 0x0 0x0 0x0 0xc 0x0 0x0 0x0 0x99 0x0 0x1
Found TPM SLB9635 TT 1.2 by Infineon
Got TPM response:
 00 c4 00 00 00 0a 00 00 00 00

If the command is corrupted (fed one byte short), an error is reported:
boot > tpm 0x0 0xc1 0x0 0x0 0x0 0xc 0x0 0x0 0x0 0x99 0x0
generic_lpc_tpm.c:311 unexpected TPM status 0xff000888
generic_lpc_tpm.c:516 failed sending data to TPM
tpm command failed
boot >

Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
CC: Wolfgang Denk <wd at denx.de>
---
 common/Makefile  |    2 +
 common/cmd_tpm.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_tpm.c

diff --git a/common/Makefile b/common/Makefile
index 371a0d9..28c2ec5 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -153,6 +153,8 @@ COBJS-$(CONFIG_CMD_UBI) += cmd_ubi.o
 COBJS-$(CONFIG_CMD_UBIFS) += cmd_ubifs.o
 COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
 COBJS-$(CONFIG_CMD_UNZIP) += cmd_unzip.o
+COBJS-$(CONFIG_CMD_TPM) += cmd_tpm.o
+
 ifdef CONFIG_CMD_USB
 COBJS-y += cmd_usb.o
 COBJS-y += usb.o
diff --git a/common/cmd_tpm.c b/common/cmd_tpm.c
new file mode 100644
index 0000000..e008a78
--- /dev/null
+++ b/common/cmd_tpm.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+ * Released under the 2-clause BSD license.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <tpm.h>
+
+#define MAX_TRANSACTION_SIZE 30
+static void report_error(const char *msg);
+
+/*
+ * tpm_write() expects a variable number of parameters: the internal address
+ * followed by data to write, byte by byte.
+ *
+ * Returns 0 on success or ~0 on errors (wrong arguments or TPM failure).
+ */
+static int tpm_process(int argc, char * const argv[])
+{
+	u8 tpm_buffer[MAX_TRANSACTION_SIZE];
+	u32 write_size, read_size;
+	char *p;
+	int rv = ~0;
+
+	for (write_size = 0; write_size < argc; write_size++) {
+		u32 datum = simple_strtoul(argv[write_size], &p, 0);
+		if (*p || (datum > 0xff)) {
+			printf("%s: ", argv[write_size]);
+			report_error("bad data value\n");
+			return rv;
+		}
+		tpm_buffer[write_size] = (u8)datum;
+	}
+
+	read_size = sizeof(tpm_buffer);
+	if (!tis_sendrecv(tpm_buffer, write_size, tpm_buffer, &read_size)) {
+		int i;
+		puts("Got TPM response:\n");
+		for (i = 0; i < read_size; i++)
+			printf(" %2.2x", tpm_buffer[i]);
+		puts("\n");
+		rv = 0;
+	} else {
+		puts("tpm command failed\n");
+	}
+	return rv;
+}
+
+static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int rv = 0;
+
+	/*
+	 * Verify that in case it is present, the first argument, it is
+	 * exactly one character in size.
+	 */
+	if (argc < 7) {
+		puts("command should be at least six bytes in size\n");
+		return ~0;
+	}
+
+	if (tis_init()) {
+		puts("tis_init() failed!\n");
+		return ~0;
+	}
+
+	if (tis_open()) {
+		puts("tis_open() failed!\n");
+		return ~0;
+	}
+
+	rv = tpm_process(argc - 1, argv + 1);
+
+	if (!rv && tis_close()) {
+		puts("tis_close() failed!\n");
+		rv = ~0;
+	}
+
+	return rv;
+}
+
+U_BOOT_CMD(tpm, MAX_TRANSACTION_SIZE, 1, do_tpm,
+	   "tpm <data> [<data>]   - write data and read ressponse\n",
+	   "send arbitrary data to the TPM and read the response"
+);
+
+static void report_error(const char *msg)
+{
+	if (msg && *msg)
+		printf("%s\n", msg);
+	cmd_usage(&__u_boot_cmd_tpm);
+}
-- 
1.7.3.1



More information about the U-Boot mailing list