]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
tpm: disociate TPMv1.x specific and generic code
authorMiquel Raynal <miquel.raynal@bootlin.com>
Tue, 15 May 2018 09:57:06 +0000 (11:57 +0200)
committerTom Rini <trini@konsulko.com>
Sat, 26 May 2018 00:12:55 +0000 (20:12 -0400)
There are no changes in this commit but a new organization of the code
as follow.

* cmd/ directory:
        > move existing code from cmd/tpm.c in cmd/tpm-common.c
> move specific code in cmd/tpm-v1.c
> create a specific header file with generic definitions for
  commands only called cmd/tpm-user-utils.h

* lib/ directory:
        > move existing code from lib/tpm.c in lib/tpm-common.c
> move specific code in lib/tpm-v1.c
> create a specific header file with generic definitions for
  the library itself called lib/tpm-utils.h

* include/ directory:
        > move existing code from include/tpm.h in include/tpm-common.h
> move specific code in include/tpm-v1.h

Code designated as 'common' is compiled if TPM are used. Code designated
as 'specific' is compiled only if the right specification has been
selected.

All files include tpm-common.h.
Files in cmd/ include tpm-user-utils.h.
Files in lib/ include tpm-utils.h.
Depending on the specification, files may include either (not both)
tpm-v1.h or tpm-v2.h.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
[trini: Fix a few more cases of tpm.h -> tpm-v1.h, some Kconfig logic]
Signed-off-by: Tom Rini <trini@konsulko.com>
23 files changed:
board/gdsys/a38x/controlcenterdc.c
board/gdsys/a38x/hre.c
board/gdsys/a38x/keyprogram.c
board/gdsys/p1022/controlcenterd-id.c
cmd/Makefile
cmd/tpm-common.c [new file with mode: 0644]
cmd/tpm-user-utils.h [new file with mode: 0644]
cmd/tpm-v1.c [moved from cmd/tpm.c with 76% similarity]
cmd/tpm_test.c
drivers/tpm/Kconfig
drivers/tpm/tpm-uclass.c
drivers/tpm/tpm_atmel_twi.c
drivers/tpm/tpm_tis_infineon.c
drivers/tpm/tpm_tis_lpc.c
drivers/tpm/tpm_tis_sandbox.c
drivers/tpm/tpm_tis_st33zp24_i2c.c
drivers/tpm/tpm_tis_st33zp24_spi.c
include/tpm-common.h [new file with mode: 0644]
include/tpm-v1.h [moved from include/tpm.h with 70% similarity]
lib/Makefile
lib/tpm-common.c [new file with mode: 0644]
lib/tpm-utils.h [new file with mode: 0644]
lib/tpm-v1.c [moved from lib/tpm.c with 81% similarity]

index 320bc100c9dafba0f9db4267117e6a25e90f363d..824a08f12af83ca64b8e44dafa99488725a50c10 100644 (file)
@@ -7,7 +7,7 @@
 #include <common.h>
 #include <dm.h>
 #include <miiphy.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm-generic/gpio.h>
index 961316cab7849f7e30613d7120afa2a3c93dd6e7..34c4df71b259aaad44c049f2789c0353792a4f27 100644 (file)
@@ -9,7 +9,7 @@
 #include <fs.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <u-boot/sha1.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
index f6a2747fb25ec9855711d6260775a409f4dc98ec..1fb5306b50f6f402842cc502bf354748dd56e5dc 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #include <common.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <malloc.h>
 #include <linux/ctype.h>
 #include <asm/unaligned.h>
index 87edf92f43a8144757e579dd6368bb57995103fb..7e082dff0527865213c2a70e0560c495a500ef32 100644 (file)
@@ -15,7 +15,7 @@
 #include <fs.h>
 #include <i2c.h>
 #include <mmc.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <u-boot/sha1.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
index ca6ead8e8e8a6341c0d6eee0a03ad97d4f5d9211..6164f6e611f8dff6096c64736a86e7db24a698e8 100644 (file)
@@ -120,7 +120,8 @@ obj-$(CONFIG_CMD_TERMINAL) += terminal.o
 obj-$(CONFIG_CMD_TIME) += time.o
 obj-$(CONFIG_CMD_TRACE) += trace.o
 obj-$(CONFIG_HUSH_PARSER) += test.o
-obj-$(CONFIG_CMD_TPM_V1) += tpm.o
+obj-$(CONFIG_CMD_TPM) += tpm-common.o
+obj-$(CONFIG_CMD_TPM_V1) += tpm-v1.o
 obj-$(CONFIG_CMD_TPM_TEST) += tpm_test.o
 obj-$(CONFIG_CMD_CROS_EC) += cros_ec.o
 obj-$(CONFIG_CMD_TSI148) += tsi148.o
diff --git a/cmd/tpm-common.c b/cmd/tpm-common.c
new file mode 100644 (file)
index 0000000..6cf9fcc
--- /dev/null
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <asm/unaligned.h>
+#include <linux/string.h>
+#include <tpm-common.h>
+#include "tpm-user-utils.h"
+
+/**
+ * Print a byte string in hexdecimal format, 16-bytes per line.
+ *
+ * @param data         byte string to be printed
+ * @param count                number of bytes to be printed
+ */
+void print_byte_string(u8 *data, size_t count)
+{
+       int i, print_newline = 0;
+
+       for (i = 0; i < count; i++) {
+               printf(" %02x", data[i]);
+               print_newline = (i % 16 == 15);
+               if (print_newline)
+                       putc('\n');
+       }
+       /* Avoid duplicated newline at the end */
+       if (!print_newline)
+               putc('\n');
+}
+
+/**
+ * Convert a text string of hexdecimal values into a byte string.
+ *
+ * @param bytes                text string of hexdecimal values with no space
+ *                     between them
+ * @param data         output buffer for byte string.  The caller has to make
+ *                     sure it is large enough for storing the output.  If
+ *                     NULL is passed, a large enough buffer will be allocated,
+ *                     and the caller must free it.
+ * @param count_ptr    output variable for the length of byte string
+ * @return pointer to output buffer
+ */
+void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr)
+{
+       char byte[3];
+       size_t count, length;
+       int i;
+
+       if (!bytes)
+               return NULL;
+       length = strlen(bytes);
+       count = length / 2;
+
+       if (!data)
+               data = malloc(count);
+       if (!data)
+               return NULL;
+
+       byte[2] = '\0';
+       for (i = 0; i < length; i += 2) {
+               byte[0] = bytes[i];
+               byte[1] = bytes[i + 1];
+               data[i / 2] = (u8)simple_strtoul(byte, NULL, 16);
+       }
+
+       if (count_ptr)
+               *count_ptr = count;
+
+       return data;
+}
+
+/**
+ * report_return_code() - Report any error and return failure or success
+ *
+ * @param return_code  TPM command return code
+ * @return value of enum command_ret_t
+ */
+int report_return_code(int return_code)
+{
+       if (return_code) {
+               printf("Error: %d\n", return_code);
+               return CMD_RET_FAILURE;
+       } else {
+               return CMD_RET_SUCCESS;
+       }
+}
+
+/**
+ * Return number of values defined by a type string.
+ *
+ * @param type_str     type string
+ * @return number of values of type string
+ */
+int type_string_get_num_values(const char *type_str)
+{
+       return strlen(type_str);
+}
+
+/**
+ * Return total size of values defined by a type string.
+ *
+ * @param type_str     type string
+ * @return total size of values of type string, or 0 if type string
+ *  contains illegal type character.
+ */
+size_t type_string_get_space_size(const char *type_str)
+{
+       size_t size;
+
+       for (size = 0; *type_str; type_str++) {
+               switch (*type_str) {
+               case 'b':
+                       size += 1;
+                       break;
+               case 'w':
+                       size += 2;
+                       break;
+               case 'd':
+                       size += 4;
+                       break;
+               default:
+                       return 0;
+               }
+       }
+
+       return size;
+}
+
+/**
+ * Allocate a buffer large enough to hold values defined by a type
+ * string.  The caller has to free the buffer.
+ *
+ * @param type_str     type string
+ * @param count                pointer for storing size of buffer
+ * @return pointer to buffer or NULL on error
+ */
+void *type_string_alloc(const char *type_str, u32 *count)
+{
+       void *data;
+       size_t size;
+
+       size = type_string_get_space_size(type_str);
+       if (!size)
+               return NULL;
+       data = malloc(size);
+       if (data)
+               *count = size;
+
+       return data;
+}
+
+/**
+ * Pack values defined by a type string into a buffer.  The buffer must have
+ * large enough space.
+ *
+ * @param type_str     type string
+ * @param values       text strings of values to be packed
+ * @param data         output buffer of values
+ * @return 0 on success, non-0 on error
+ */
+int type_string_pack(const char *type_str, char * const values[],
+                    u8 *data)
+{
+       size_t offset;
+       u32 value;
+
+       for (offset = 0; *type_str; type_str++, values++) {
+               value = simple_strtoul(values[0], NULL, 0);
+               switch (*type_str) {
+               case 'b':
+                       data[offset] = value;
+                       offset += 1;
+                       break;
+               case 'w':
+                       put_unaligned_be16(value, data + offset);
+                       offset += 2;
+                       break;
+               case 'd':
+                       put_unaligned_be32(value, data + offset);
+                       offset += 4;
+                       break;
+               default:
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * Read values defined by a type string from a buffer, and write these values
+ * to environment variables.
+ *
+ * @param type_str     type string
+ * @param data         input buffer of values
+ * @param vars         names of environment variables
+ * @return 0 on success, non-0 on error
+ */
+int type_string_write_vars(const char *type_str, u8 *data,
+                          char * const vars[])
+{
+       size_t offset;
+       u32 value;
+
+       for (offset = 0; *type_str; type_str++, vars++) {
+               switch (*type_str) {
+               case 'b':
+                       value = data[offset];
+                       offset += 1;
+                       break;
+               case 'w':
+                       value = get_unaligned_be16(data + offset);
+                       offset += 2;
+                       break;
+               case 'd':
+                       value = get_unaligned_be32(data + offset);
+                       offset += 4;
+                       break;
+               default:
+                       return -1;
+               }
+               if (env_set_ulong(*vars, value))
+                       return -1;
+       }
+
+       return 0;
+}
+
+int get_tpm(struct udevice **devp)
+{
+       int rc;
+
+       rc = uclass_first_device_err(UCLASS_TPM, devp);
+       if (rc) {
+               printf("Could not find TPM (ret=%d)\n", rc);
+               return CMD_RET_FAILURE;
+       }
+
+       return 0;
+}
+
+int do_tpm_info(cmd_tbl_t *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_get_desc(dev, buf, sizeof(buf));
+       if (rc < 0) {
+               printf("Couldn't get TPM info (%d)\n", rc);
+               return CMD_RET_FAILURE;
+       }
+       printf("%s\n", buf);
+
+       return 0;
+}
+
+int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       if (argc != 1)
+               return CMD_RET_USAGE;
+
+       return report_return_code(tpm_init());
+}
+
+int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       cmd_tbl_t *tpm_commands, *cmd;
+       unsigned int size;
+
+       if (argc < 2)
+               return CMD_RET_USAGE;
+
+       tpm_commands = get_tpm_commands(&size);
+
+       cmd = find_cmd_tbl(argv[1], tpm_commands, size);
+       if (!cmd)
+               return CMD_RET_USAGE;
+
+       return cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
+}
diff --git a/cmd/tpm-user-utils.h b/cmd/tpm-user-utils.h
new file mode 100644 (file)
index 0000000..8ce9861
--- /dev/null
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_USER_UTILS_H
+#define __TPM_USER_UTILS_H
+
+void print_byte_string(u8 *data, size_t count);
+void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr);
+int report_return_code(int return_code);
+int type_string_get_num_values(const char *type_str);
+size_t type_string_get_space_size(const char *type_str);
+void *type_string_alloc(const char *type_str, u32 *count);
+int type_string_pack(const char *type_str, char * const values[], u8 *data);
+int type_string_write_vars(const char *type_str, u8 *data, char * const vars[]);
+int get_tpm(struct udevice **devp);
+
+int do_tpm_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+#endif /* __TPM_USER_UTILS_H */
similarity index 76%
rename from cmd/tpm.c
rename to cmd/tpm-v1.c
index e0cd8410f5367a9501608892e7bf4377e3c0b92d..0874c4d7baff044e5d802e27b398fe6201740103 100644 (file)
--- a/cmd/tpm.c
  */
 
 #include <common.h>
-#include <command.h>
-#include <dm.h>
 #include <malloc.h>
-#include <tpm.h>
 #include <asm/unaligned.h>
-#include <linux/string.h>
-
-/* Useful constants */
-enum {
-       DIGEST_LENGTH           = 20,
-       /* max lengths, valid for RSA keys <= 2048 bits */
-       TPM_PUBKEY_MAX_LENGTH   = 288,
-};
-
-/**
- * Print a byte string in hexdecimal format, 16-bytes per line.
- *
- * @param data         byte string to be printed
- * @param count                number of bytes to be printed
- */
-static void print_byte_string(u8 *data, size_t count)
-{
-       int i, print_newline = 0;
-
-       for (i = 0; i < count; i++) {
-               printf(" %02x", data[i]);
-               print_newline = (i % 16 == 15);
-               if (print_newline)
-                       putc('\n');
-       }
-       /* Avoid duplicated newline at the end */
-       if (!print_newline)
-               putc('\n');
-}
-
-/**
- * Convert a text string of hexdecimal values into a byte string.
- *
- * @param bytes                text string of hexdecimal values with no space
- *                     between them
- * @param data         output buffer for byte string.  The caller has to make
- *                     sure it is large enough for storing the output.  If
- *                     NULL is passed, a large enough buffer will be allocated,
- *                     and the caller must free it.
- * @param count_ptr    output variable for the length of byte string
- * @return pointer to output buffer
- */
-static void *parse_byte_string(char *bytes, u8 *data, size_t *count_ptr)
-{
-       char byte[3];
-       size_t count, length;
-       int i;
-
-       if (!bytes)
-               return NULL;
-       length = strlen(bytes);
-       count = length / 2;
-
-       if (!data)
-               data = malloc(count);
-       if (!data)
-               return NULL;
-
-       byte[2] = '\0';
-       for (i = 0; i < length; i += 2) {
-               byte[0] = bytes[i];
-               byte[1] = bytes[i + 1];
-               data[i / 2] = (u8)simple_strtoul(byte, NULL, 16);
-       }
-
-       if (count_ptr)
-               *count_ptr = count;
-
-       return data;
-}
-
-/**
- * report_return_code() - Report any error and return failure or success
- *
- * @param return_code  TPM command return code
- * @return value of enum command_ret_t
- */
-static int report_return_code(int return_code)
-{
-       if (return_code) {
-               printf("Error: %d\n", return_code);
-               return CMD_RET_FAILURE;
-       } else {
-               return CMD_RET_SUCCESS;
-       }
-}
-
-/**
- * Return number of values defined by a type string.
- *
- * @param type_str     type string
- * @return number of values of type string
- */
-static int type_string_get_num_values(const char *type_str)
-{
-       return strlen(type_str);
-}
-
-/**
- * Return total size of values defined by a type string.
- *
- * @param type_str     type string
- * @return total size of values of type string, or 0 if type string
- *  contains illegal type character.
- */
-static size_t type_string_get_space_size(const char *type_str)
-{
-       size_t size;
-
-       for (size = 0; *type_str; type_str++) {
-               switch (*type_str) {
-               case 'b':
-                       size += 1;
-                       break;
-               case 'w':
-                       size += 2;
-                       break;
-               case 'd':
-                       size += 4;
-                       break;
-               default:
-                       return 0;
-               }
-       }
-
-       return size;
-}
-
-/**
- * Allocate a buffer large enough to hold values defined by a type
- * string.  The caller has to free the buffer.
- *
- * @param type_str     type string
- * @param count                pointer for storing size of buffer
- * @return pointer to buffer or NULL on error
- */
-static void *type_string_alloc(const char *type_str, u32 *count)
-{
-       void *data;
-       size_t size;
-
-       size = type_string_get_space_size(type_str);
-       if (!size)
-               return NULL;
-       data = malloc(size);
-       if (data)
-               *count = size;
-
-       return data;
-}
-
-/**
- * Pack values defined by a type string into a buffer.  The buffer must have
- * large enough space.
- *
- * @param type_str     type string
- * @param values       text strings of values to be packed
- * @param data         output buffer of values
- * @return 0 on success, non-0 on error
- */
-static int type_string_pack(const char *type_str, char * const values[],
-                           u8 *data)
-{
-       size_t offset;
-       u32 value;
-
-       for (offset = 0; *type_str; type_str++, values++) {
-               value = simple_strtoul(values[0], NULL, 0);
-               switch (*type_str) {
-               case 'b':
-                       data[offset] = value;
-                       offset += 1;
-                       break;
-               case 'w':
-                       put_unaligned_be16(value, data + offset);
-                       offset += 2;
-                       break;
-               case 'd':
-                       put_unaligned_be32(value, data + offset);
-                       offset += 4;
-                       break;
-               default:
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * Read values defined by a type string from a buffer, and write these values
- * to environment variables.
- *
- * @param type_str     type string
- * @param data         input buffer of values
- * @param vars         names of environment variables
- * @return 0 on success, non-0 on error
- */
-static int type_string_write_vars(const char *type_str, u8 *data,
-                                 char * const vars[])
-{
-       size_t offset;
-       u32 value;
-
-       for (offset = 0; *type_str; type_str++, vars++) {
-               switch (*type_str) {
-               case 'b':
-                       value = data[offset];
-                       offset += 1;
-                       break;
-               case 'w':
-                       value = get_unaligned_be16(data + offset);
-                       offset += 2;
-                       break;
-               case 'd':
-                       value = get_unaligned_be32(data + offset);
-                       offset += 4;
-                       break;
-               default:
-                       return -1;
-               }
-               if (env_set_ulong(*vars, value))
-                       return -1;
-       }
-
-       return 0;
-}
+#include <tpm-common.h>
+#include <tpm-v1.h>
+#include "tpm-user-utils.h"
 
 static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag, int argc,
                          char * const argv[])
@@ -426,54 +199,6 @@ static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag, int argc,
        return report_return_code(rc);
 }
 
-#define TPM_COMMAND_NO_ARG(cmd)                                \
-static int do_##cmd(cmd_tbl_t *cmdtp, int flag,                \
-                   int argc, char * const argv[])      \
-{                                                      \
-       if (argc != 1)                                  \
-               return CMD_RET_USAGE;                   \
-       return report_return_code(cmd());               \
-}
-
-TPM_COMMAND_NO_ARG(tpm_init)
-TPM_COMMAND_NO_ARG(tpm_self_test_full)
-TPM_COMMAND_NO_ARG(tpm_continue_self_test)
-TPM_COMMAND_NO_ARG(tpm_force_clear)
-TPM_COMMAND_NO_ARG(tpm_physical_enable)
-TPM_COMMAND_NO_ARG(tpm_physical_disable)
-
-static int get_tpm(struct udevice **devp)
-{
-       int rc;
-
-       rc = uclass_first_device_err(UCLASS_TPM, devp);
-       if (rc) {
-               printf("Could not find TPM (ret=%d)\n", rc);
-               return CMD_RET_FAILURE;
-       }
-
-       return 0;
-}
-
-static int do_tpm_info(cmd_tbl_t *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_get_desc(dev, buf, sizeof(buf));
-       if (rc < 0) {
-               printf("Couldn't get TPM info (%d)\n", rc);
-               return CMD_RET_FAILURE;
-       }
-       printf("%s\n", buf);
-
-       return 0;
-}
-
 static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag, int argc,
                               char * const argv[])
 {
@@ -812,10 +537,13 @@ static int do_tpm_list(cmd_tbl_t *cmdtp, int flag, int argc,
 }
 #endif /* CONFIG_TPM_LIST_RESOURCES */
 
-#define MAKE_TPM_CMD_ENTRY(cmd) \
-       U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
+TPM_COMMAND_NO_ARG(tpm_self_test_full)
+TPM_COMMAND_NO_ARG(tpm_continue_self_test)
+TPM_COMMAND_NO_ARG(tpm_force_clear)
+TPM_COMMAND_NO_ARG(tpm_physical_enable)
+TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
-static cmd_tbl_t tpm_commands[] = {
+static cmd_tbl_t tpm1_commands[] = {
        U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
        U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
        U_BOOT_CMD_MKENT(startup, 0, 1,
@@ -880,21 +608,15 @@ static cmd_tbl_t tpm_commands[] = {
 #endif /* CONFIG_TPM_LIST_RESOURCES */
 };
 
-static int do_tpm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+cmd_tbl_t *get_tpm_commands(unsigned int *size)
 {
-       cmd_tbl_t *tpm_cmd;
-
-       if (argc < 2)
-               return CMD_RET_USAGE;
-       tpm_cmd = find_cmd_tbl(argv[1], tpm_commands, ARRAY_SIZE(tpm_commands));
-       if (!tpm_cmd)
-               return CMD_RET_USAGE;
+       *size = ARRAY_SIZE(tpm1_commands);
 
-       return tpm_cmd->cmd(cmdtp, flag, argc - 1, argv + 1);
+       return tpm1_commands;
 }
 
 U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
-"Issue a TPM command",
+"Issue a TPMv1.x command",
 "cmd args...\n"
 "    - Issue TPM command <cmd> with arguments <args...>.\n"
 "Admin Startup and State Commands:\n"
index 2e7d133a47e75ac805d184884f44252334be1d82..35f3c96e3de7c38d4034433cf213ea4903cca116 100644 (file)
@@ -6,7 +6,7 @@
 #include <common.h>
 #include <command.h>
 #include <environment.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 
 /* Prints error and returns on failure */
 #define TPM_CHECK(tpm_command) do { \
index 53c34612df0aa692279f2cb9982e3a084c13db45..bc11f61e91f63fa207e0df01560346e172fbac1a 100644 (file)
@@ -46,7 +46,7 @@ config TPM_TIS_INFINEON
 
 config TPM_TIS_I2C_BURST_LIMITATION
        bool "Enable I2C burst length limitation"
-       depends on TPM_V1 && TPM_TIS_INFINEON
+       depends on TPM_TIS_INFINEON
        help
          Some broken TPMs have a limitation on the number of bytes they can
          receive in one message. Enable this option to allow you to set this
@@ -62,6 +62,7 @@ config TPM_TIS_I2C_BURST_LIMITATION_LEN
 config TPM_TIS_LPC
        bool "Enable support for Infineon SLB9635/45 TPMs on LPC"
        depends on TPM_V1 && X86
+       select TPM_DRIVER_SELECTED
        help
          This driver supports Infineon TPM devices connected on the LPC bus.
          The usual tpm operations and the 'tpm' command can be used to talk
index e71545235cff29e1b1ea1930d6d8190395cc1efe..9488b091a2e823cd53680dbd1573c9859b3dc072 100644 (file)
@@ -6,8 +6,10 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
 #include <linux/unaligned/be_byteshift.h>
+#if defined(CONFIG_TPM_V1)
+#include <tpm-v1.h>
+#endif
 #include "tpm_internal.h"
 
 int tpm_open(struct udevice *dev)
index 8547580c244803c50a79ad1892d67c988018736c..2079ea913e4428d88e03a962c00e5a667aecbba5 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <i2c.h>
 #include <asm/unaligned.h>
 
index 9b2a0250e19eb64dfafe8beb159da6e9cbd6188a..b5fe43ee50f7f68b95bb4b32232b919382000589 100644 (file)
@@ -23,7 +23,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <i2c.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <linux/errno.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
index 572926382ef271b486bf74a2c4e740f012e29430..7664bb1a6057996b4d2a8c0d726fce1b370045c4 100644 (file)
@@ -15,7 +15,7 @@
 #include <common.h>
 #include <dm.h>
 #include <mapmem.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/io.h>
 
 #define PREFIX "lpc_tpm: "
index 44157542a1f4c5390f253f4d8d37cf5ea02af377..8816d55759fdf7bba66537bbf9efe2434afe6a49 100644 (file)
@@ -5,7 +5,7 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <asm/state.h>
 #include <asm/unaligned.h>
 #include <linux/crc8.h>
index 9cf302caffd0e67df63ea396edb15b367ae74338..0d380375eb33c6b108b6c1ba78499da463766599 100644 (file)
@@ -16,7 +16,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <i2c.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <errno.h>
 #include <linux/types.h>
 #include <asm/unaligned.h>
index d5fde11a83d497e0c1769225925edd67667c3f1f..f6087e7633822aad580eb33612bd0334fc17dc65 100644 (file)
@@ -16,7 +16,7 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <spi.h>
-#include <tpm.h>
+#include <tpm-v1.h>
 #include <errno.h>
 #include <linux/types.h>
 #include <asm/unaligned.h>
diff --git a/include/tpm-common.h b/include/tpm-common.h
new file mode 100644 (file)
index 0000000..1ca5d28
--- /dev/null
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_COMMON_H
+#define __TPM_COMMON_H
+
+enum tpm_duration {
+       TPM_SHORT = 0,
+       TPM_MEDIUM = 1,
+       TPM_LONG = 2,
+       TPM_UNDEFINED,
+
+       TPM_DURATION_COUNT,
+};
+
+/*
+ * Here is a partial implementation of TPM commands.  Please consult TCG Main
+ * Specification for definitions of TPM commands.
+ */
+
+#define TPM_HEADER_SIZE                10
+
+/* Max buffer size supported by our tpm */
+#define TPM_DEV_BUFSIZE                1260
+
+/**
+ * struct tpm_chip_priv - Information about a TPM, stored by the uclass
+ *
+ * These values must be set up by the device's probe() method before
+ * communcation is attempted. If the device has an xfer() method, this is
+ * not needed. There is no need to set up @buf.
+ *
+ * @duration_ms:       Length of each duration type in milliseconds
+ * @retry_time_ms:     Time to wait before retrying receive
+ */
+struct tpm_chip_priv {
+       uint duration_ms[TPM_DURATION_COUNT];
+       uint retry_time_ms;
+       u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
+};
+
+/**
+ * struct tpm_ops - low-level TPM operations
+ *
+ * These are designed to avoid loops and delays in the driver itself. These
+ * should be handled in the uclass.
+ *
+ * In gneral you should implement everything except xfer(). Where you need
+ * complete control of the transfer, then xfer() can be provided and will
+ * override the other methods.
+ *
+ * This interface is for low-level TPM access. It does not understand the
+ * concept of localities or the various TPM messages. That interface is
+ * defined in the functions later on in this file, but they all translate
+ * to bytes which are sent and received.
+ */
+struct tpm_ops {
+       /**
+        * open() - Request access to locality 0 for the caller
+        *
+        * After all commands have been completed the caller should call
+        * close().
+        *
+        * @dev:        Device to close
+        * @return 0 ok OK, -ve on error
+        */
+       int (*open)(struct udevice *dev);
+
+       /**
+        * close() - Close the current session
+        *
+        * Releasing the locked locality. Returns 0 on success, -ve 1 on
+        * failure (in case lock removal did not succeed).
+        *
+        * @dev:        Device to close
+        * @return 0 ok OK, -ve on error
+        */
+       int (*close)(struct udevice *dev);
+
+       /**
+        * get_desc() - Get a text description of the TPM
+        *
+        * @dev:        Device to check
+        * @buf:        Buffer to put the string
+        * @size:       Maximum size of buffer
+        * @return length of string, or -ENOSPC it no space
+        */
+       int (*get_desc)(struct udevice *dev, char *buf, int size);
+
+       /**
+        * send() - send data to the TPM
+        *
+        * @dev:        Device to talk to
+        * @sendbuf:    Buffer of the data to send
+        * @send_size:  Size of the data to send
+        *
+        * Returns 0 on success or -ve on failure.
+        */
+       int (*send)(struct udevice *dev, const u8 *sendbuf, size_t send_size);
+
+       /**
+        * recv() - receive a response from the TPM
+        *
+        * @dev:        Device to talk to
+        * @recvbuf:    Buffer to save the response to
+        * @max_size:   Maximum number of bytes to receive
+        *
+        * Returns number of bytes received on success, -EAGAIN if the TPM
+        * response is not ready, -EINTR if cancelled, or other -ve value on
+        * failure.
+        */
+       int (*recv)(struct udevice *dev, u8 *recvbuf, size_t max_size);
+
+       /**
+        * cleanup() - clean up after an operation in progress
+        *
+        * This is called if receiving times out. The TPM may need to abort
+        * the current transaction if it did not complete, and make itself
+        * ready for another.
+        *
+        * @dev:        Device to talk to
+        */
+       int (*cleanup)(struct udevice *dev);
+
+       /**
+        * xfer() - send data to the TPM and get response
+        *
+        * This method is optional. If it exists it is used in preference
+        * to send(), recv() and cleanup(). It should handle all aspects of
+        * TPM communication for a single transfer.
+        *
+        * @dev:        Device to talk to
+        * @sendbuf:    Buffer of the data to send
+        * @send_size:  Size of the data to send
+        * @recvbuf:    Buffer to save the response to
+        * @recv_size:  Pointer to the size of the response buffer
+        *
+        * Returns 0 on success (and places the number of response bytes at
+        * recv_size) or -ve on failure.
+        */
+       int (*xfer)(struct udevice *dev, const u8 *sendbuf, size_t send_size,
+                   u8 *recvbuf, size_t *recv_size);
+};
+
+#define tpm_get_ops(dev)        ((struct tpm_ops *)device_get_ops(dev))
+
+#define MAKE_TPM_CMD_ENTRY(cmd) \
+       U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
+
+#define TPM_COMMAND_NO_ARG(cmd)                                \
+int do_##cmd(cmd_tbl_t *cmdtp, int flag,               \
+            int argc, char * const argv[])             \
+{                                                      \
+       if (argc != 1)                                  \
+               return CMD_RET_USAGE;                   \
+       return report_return_code(cmd());               \
+}
+
+/**
+ * tpm_get_desc() - Get a text description of the TPM
+ *
+ * @dev:       Device to check
+ * @buf:       Buffer to put the string
+ * @size:      Maximum size of buffer
+ * @return length of string, or -ENOSPC it no space
+ */
+int tpm_get_desc(struct udevice *dev, char *buf, int size);
+
+/**
+ * tpm_xfer() - send data to the TPM and get response
+ *
+ * This first uses the device's send() method to send the bytes. Then it calls
+ * recv() to get the reply. If recv() returns -EAGAIN then it will delay a
+ * short time and then call recv() again.
+ *
+ * Regardless of whether recv() completes successfully, it will then call
+ * cleanup() to finish the transaction.
+ *
+ * Note that the outgoing data is inspected to determine command type
+ * (ordinal) and a timeout is used for that command type.
+ *
+ * @sendbuf - buffer of the data to send
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at
+ * recv_len) or -ve on failure.
+ */
+int tpm_xfer(struct udevice *dev, const u8 *sendbuf, size_t send_size,
+            u8 *recvbuf, size_t *recv_size);
+
+/**
+ * Initialize TPM device.  It must be called before any TPM commands.
+ *
+ * @return 0 on success, non-0 on error.
+ */
+int tpm_init(void);
+
+/**
+ * Retrieve the array containing all the commands.
+ *
+ * @return a cmd_tbl_t array.
+ */
+cmd_tbl_t *get_tpm_commands(unsigned int *size);
+
+#endif /* __TPM_COMMON_H */
similarity index 70%
rename from include/tpm.h
rename to include/tpm-v1.h
index 23d925ecaaca6079e4f7fc29d896676288375bde..6b4941ef9a2f1969f6e59854e444b71d177517b7 100644 (file)
@@ -4,23 +4,22 @@
  * Coypright (c) 2013 Guntermann & Drunck GmbH
  */
 
-#ifndef __TPM_H
-#define __TPM_H
+#ifndef __TPM_V1_H
+#define __TPM_V1_H
 
-/*
- * Here is a partial implementation of TPM commands.  Please consult TCG Main
- * Specification for definitions of TPM commands.
- */
-
-#define TPM_HEADER_SIZE                10
+#include <tpm-common.h>
 
-enum tpm_duration {
-       TPM_SHORT = 0,
-       TPM_MEDIUM = 1,
-       TPM_LONG = 2,
-       TPM_UNDEFINED,
-
-       TPM_DURATION_COUNT,
+/* Useful constants */
+enum {
+       TPM_REQUEST_HEADER_LENGTH       = 10,
+       TPM_RESPONSE_HEADER_LENGTH      = 10,
+       PCR_DIGEST_LENGTH               = 20,
+       DIGEST_LENGTH                   = 20,
+       TPM_REQUEST_AUTH_LENGTH         = 45,
+       TPM_RESPONSE_AUTH_LENGTH        = 41,
+       /* some max lengths, valid for RSA keys <= 2048 bits */
+       TPM_KEY12_MAX_LENGTH            = 618,
+       TPM_PUBKEY_MAX_LENGTH           = 288,
 };
 
 enum tpm_startup_type {
@@ -232,189 +231,6 @@ struct tpm_permanent_flags {
        u8      disable_full_da_logic_info;
 } __packed;
 
-/* Max buffer size supported by our tpm */
-#define TPM_DEV_BUFSIZE                1260
-
-/**
- * struct tpm_chip_priv - Information about a TPM, stored by the uclass
- *
- * These values must be set up by the device's probe() method before
- * communcation is attempted. If the device has an xfer() method, this is
- * not needed. There is no need to set up @buf.
- *
- * @duration_ms:       Length of each duration type in milliseconds
- * @retry_time_ms:     Time to wait before retrying receive
- */
-struct tpm_chip_priv {
-       uint duration_ms[TPM_DURATION_COUNT];
-       uint retry_time_ms;
-       u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
-};
-
-/**
- * struct tpm_ops - low-level TPM operations
- *
- * These are designed to avoid loops and delays in the driver itself. These
- * should be handled in the uclass.
- *
- * In gneral you should implement everything except xfer(). Where you need
- * complete control of the transfer, then xfer() can be provided and will
- * override the other methods.
- *
- * This interface is for low-level TPM access. It does not understand the
- * concept of localities or the various TPM messages. That interface is
- * defined in the functions later on in this file, but they all translate
- * to bytes which are sent and received.
- */
-struct tpm_ops {
-       /**
-        * open() - Request access to locality 0 for the caller
-        *
-        * After all commands have been completed the caller should call
-        * close().
-        *
-        * @dev:        Device to close
-        * @return 0 ok OK, -ve on error
-        */
-       int (*open)(struct udevice *dev);
-
-       /**
-        * close() - Close the current session
-        *
-        * Releasing the locked locality. Returns 0 on success, -ve 1 on
-        * failure (in case lock removal did not succeed).
-        *
-        * @dev:        Device to close
-        * @return 0 ok OK, -ve on error
-        */
-       int (*close)(struct udevice *dev);
-
-       /**
-        * get_desc() - Get a text description of the TPM
-        *
-        * @dev:        Device to check
-        * @buf:        Buffer to put the string
-        * @size:       Maximum size of buffer
-        * @return length of string, or -ENOSPC it no space
-        */
-       int (*get_desc)(struct udevice *dev, char *buf, int size);
-
-       /**
-        * send() - send data to the TPM
-        *
-        * @dev:        Device to talk to
-        * @sendbuf:    Buffer of the data to send
-        * @send_size:  Size of the data to send
-        *
-        * Returns 0 on success or -ve on failure.
-        */
-       int (*send)(struct udevice *dev, const u8 *sendbuf, size_t send_size);
-
-       /**
-        * recv() - receive a response from the TPM
-        *
-        * @dev:        Device to talk to
-        * @recvbuf:    Buffer to save the response to
-        * @max_size:   Maximum number of bytes to receive
-        *
-        * Returns number of bytes received on success, -EAGAIN if the TPM
-        * response is not ready, -EINTR if cancelled, or other -ve value on
-        * failure.
-        */
-       int (*recv)(struct udevice *dev, u8 *recvbuf, size_t max_size);
-
-       /**
-        * cleanup() - clean up after an operation in progress
-        *
-        * This is called if receiving times out. The TPM may need to abort
-        * the current transaction if it did not complete, and make itself
-        * ready for another.
-        *
-        * @dev:        Device to talk to
-        */
-       int (*cleanup)(struct udevice *dev);
-
-       /**
-        * xfer() - send data to the TPM and get response
-        *
-        * This method is optional. If it exists it is used in preference
-        * to send(), recv() and cleanup(). It should handle all aspects of
-        * TPM communication for a single transfer.
-        *
-        * @dev:        Device to talk to
-        * @sendbuf:    Buffer of the data to send
-        * @send_size:  Size of the data to send
-        * @recvbuf:    Buffer to save the response to
-        * @recv_size:  Pointer to the size of the response buffer
-        *
-        * Returns 0 on success (and places the number of response bytes at
-        * recv_size) or -ve on failure.
-        */
-       int (*xfer)(struct udevice *dev, const u8 *sendbuf, size_t send_size,
-                   u8 *recvbuf, size_t *recv_size);
-};
-
-#define tpm_get_ops(dev)        ((struct tpm_ops *)device_get_ops(dev))
-
-/**
- * tpm_open() - Request access to locality 0 for the caller
- *
- * After all commands have been completed the caller is supposed to
- * call tpm_close().
- *
- * Returns 0 on success, -ve on failure.
- */
-int tpm_open(struct udevice *dev);
-
-/**
- * tpm_close() - Close the current session
- *
- * Releasing the locked locality. Returns 0 on success, -ve 1 on
- * failure (in case lock removal did not succeed).
- */
-int tpm_close(struct udevice *dev);
-
-/**
- * tpm_get_desc() - Get a text description of the TPM
- *
- * @dev:       Device to check
- * @buf:       Buffer to put the string
- * @size:      Maximum size of buffer
- * @return length of string, or -ENOSPC it no space
- */
-int tpm_get_desc(struct udevice *dev, char *buf, int size);
-
-/**
- * tpm_xfer() - send data to the TPM and get response
- *
- * This first uses the device's send() method to send the bytes. Then it calls
- * recv() to get the reply. If recv() returns -EAGAIN then it will delay a
- * short time and then call recv() again.
- *
- * Regardless of whether recv() completes successfully, it will then call
- * cleanup() to finish the transaction.
- *
- * Note that the outgoing data is inspected to determine command type
- * (ordinal) and a timeout is used for that command type.
- *
- * @sendbuf - buffer of the data to send
- * @send_size size of the data to send
- * @recvbuf - memory to save the response to
- * @recv_len - pointer to the size of the response buffer
- *
- * Returns 0 on success (and places the number of response bytes at
- * recv_len) or -ve on failure.
- */
-int tpm_xfer(struct udevice *dev, const u8 *sendbuf, size_t send_size,
-            u8 *recvbuf, size_t *recv_size);
-
-/**
- * Initialize TPM device.  It must be called before any TPM commands.
- *
- * @return 0 on success, non-0 on error.
- */
-int tpm_init(void);
-
 /**
  * Issue a TPM_Startup command.
  *
@@ -661,4 +477,4 @@ u32 tpm_find_key_sha1(const u8 auth[20], const u8 pubkey_digest[20],
  */
 u32 tpm_get_random(void *data, u32 count);
 
-#endif /* __TPM_H */
+#endif /* __TPM_V1_H */
index 2a56b3b1c60dc9df8b2230be57d40a6fe08dbc81..72504e7654a89917fafbdd0e80e95f5541831924 100644 (file)
@@ -39,7 +39,8 @@ obj-$(CONFIG_PHYSMEM) += physmem.o
 obj-y += qsort.o
 obj-y += rc4.o
 obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
-obj-$(CONFIG_TPM_V1) += tpm.o
+obj-$(CONFIG_TPM) += tpm-common.o
+obj-$(CONFIG_TPM_V1) += tpm-v1.o
 obj-$(CONFIG_RBTREE)   += rbtree.o
 obj-$(CONFIG_BITREVERSE) += bitrev.o
 obj-y += list_sort.o
diff --git a/lib/tpm-common.c b/lib/tpm-common.c
new file mode 100644 (file)
index 0000000..4c2b939
--- /dev/null
@@ -0,0 +1,188 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/unaligned.h>
+#include <tpm-common.h>
+#include "tpm-utils.h"
+
+int pack_byte_string(u8 *str, size_t size, const char *format, ...)
+{
+       va_list args;
+       size_t offset = 0, length = 0;
+       u8 *data = NULL;
+       u32 value = 0;
+
+       va_start(args, format);
+       for (; *format; format++) {
+               switch (*format) {
+               case 'b':
+                       offset = va_arg(args, size_t);
+                       value = va_arg(args, int);
+                       length = 1;
+                       break;
+               case 'w':
+                       offset = va_arg(args, size_t);
+                       value = va_arg(args, int);
+                       length = 2;
+                       break;
+               case 'd':
+                       offset = va_arg(args, size_t);
+                       value = va_arg(args, u32);
+                       length = 4;
+                       break;
+               case 's':
+                       offset = va_arg(args, size_t);
+                       data = va_arg(args, u8 *);
+                       length = va_arg(args, u32);
+                       break;
+               default:
+                       debug("Couldn't recognize format string\n");
+                       va_end(args);
+                       return -1;
+               }
+
+               if (offset + length > size) {
+                       va_end(args);
+                       return -1;
+               }
+
+               switch (*format) {
+               case 'b':
+                       str[offset] = value;
+                       break;
+               case 'w':
+                       put_unaligned_be16(value, str + offset);
+                       break;
+               case 'd':
+                       put_unaligned_be32(value, str + offset);
+                       break;
+               case 's':
+                       memcpy(str + offset, data, length);
+                       break;
+               }
+       }
+       va_end(args);
+
+       return 0;
+}
+
+int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
+{
+       va_list args;
+       size_t offset = 0, length = 0;
+       u8 *ptr8 = NULL;
+       u16 *ptr16 = NULL;
+       u32 *ptr32 = NULL;
+
+       va_start(args, format);
+       for (; *format; format++) {
+               switch (*format) {
+               case 'b':
+                       offset = va_arg(args, size_t);
+                       ptr8 = va_arg(args, u8 *);
+                       length = 1;
+                       break;
+               case 'w':
+                       offset = va_arg(args, size_t);
+                       ptr16 = va_arg(args, u16 *);
+                       length = 2;
+                       break;
+               case 'd':
+                       offset = va_arg(args, size_t);
+                       ptr32 = va_arg(args, u32 *);
+                       length = 4;
+                       break;
+               case 's':
+                       offset = va_arg(args, size_t);
+                       ptr8 = va_arg(args, u8 *);
+                       length = va_arg(args, u32);
+                       break;
+               default:
+                       va_end(args);
+                       debug("Couldn't recognize format string\n");
+                       return -1;
+               }
+
+               if (offset + length > size) {
+                       va_end(args);
+                       return -1;
+               }
+
+               switch (*format) {
+               case 'b':
+                       *ptr8 = str[offset];
+                       break;
+               case 'w':
+                       *ptr16 = get_unaligned_be16(str + offset);
+                       break;
+               case 'd':
+                       *ptr32 = get_unaligned_be32(str + offset);
+                       break;
+               case 's':
+                       memcpy(ptr8, str + offset, length);
+                       break;
+               }
+       }
+       va_end(args);
+
+       return 0;
+}
+
+u32 tpm_command_size(const void *command)
+{
+       const size_t command_size_offset = 2;
+
+       return get_unaligned_be32(command + command_size_offset);
+}
+
+u32 tpm_return_code(const void *response)
+{
+       const size_t return_code_offset = 6;
+
+       return get_unaligned_be32(response + return_code_offset);
+}
+
+u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr)
+{
+       struct udevice *dev;
+       int err, ret;
+       u8 response_buffer[COMMAND_BUFFER_SIZE];
+       size_t response_length;
+
+       if (response) {
+               response_length = *size_ptr;
+       } else {
+               response = response_buffer;
+               response_length = sizeof(response_buffer);
+       }
+
+       ret = uclass_first_device_err(UCLASS_TPM, &dev);
+       if (ret)
+               return ret;
+       err = tpm_xfer(dev, command, tpm_command_size(command),
+                      response, &response_length);
+
+       if (err < 0)
+               return TPM_LIB_ERROR;
+       if (size_ptr)
+               *size_ptr = response_length;
+
+       return tpm_return_code(response);
+}
+
+int tpm_init(void)
+{
+       struct udevice *dev;
+       int err;
+
+       err = uclass_first_device_err(UCLASS_TPM, &dev);
+       if (err)
+               return err;
+
+       return tpm_open(dev);
+}
diff --git a/lib/tpm-utils.h b/lib/tpm-utils.h
new file mode 100644 (file)
index 0000000..bc98d1e
--- /dev/null
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ * Coypright (c) 2013 Guntermann & Drunck GmbH
+ */
+
+#ifndef __TPM_UTILS_H
+#define __TPM_UTILS_H
+
+#define COMMAND_BUFFER_SIZE 256
+
+/* Internal error of TPM command library */
+#define TPM_LIB_ERROR ((u32)~0u)
+
+/**
+ * tpm_open() - Request access to locality 0 for the caller
+ *
+ * After all commands have been completed the caller is supposed to
+ * call tpm_close().
+ *
+ * Returns 0 on success, -ve on failure.
+ */
+int tpm_open(struct udevice *dev);
+
+/**
+ * tpm_close() - Close the current session
+ *
+ * Releasing the locked locality. Returns 0 on success, -ve 1 on
+ * failure (in case lock removal did not succeed).
+ */
+int tpm_close(struct udevice *dev);
+
+/**
+ * Pack data into a byte string.  The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string.  The data are a
+ * series of offsets and values (for type byte string there are also
+ * lengths).  The data values are packed into the byte string
+ * sequentially, and so a latter value could over-write a former
+ * value.
+ *
+ * @param str          output string
+ * @param size         size of output string
+ * @param format       format string
+ * @param ...          data points
+ * @return 0 on success, non-0 on error
+ */
+int pack_byte_string(u8 *str, size_t size, const char *format, ...);
+
+/**
+ * Unpack data from a byte string.  The data types are specified in
+ * the format string: 'b' means unsigned byte, 'w' unsigned word,
+ * 'd' unsigned double word, and 's' byte string.  The data are a
+ * series of offsets and pointers (for type byte string there are also
+ * lengths).
+ *
+ * @param str          output string
+ * @param size         size of output string
+ * @param format       format string
+ * @param ...          data points
+ * @return 0 on success, non-0 on error
+ */
+int unpack_byte_string(const u8 *str, size_t size, const char *format, ...);
+
+/**
+ * Get TPM command size.
+ *
+ * @param command      byte string of TPM command
+ * @return command size of the TPM command
+ */
+u32 tpm_command_size(const void *command);
+
+/**
+ * Get TPM response return code, which is one of TPM_RESULT values.
+ *
+ * @param response     byte string of TPM response
+ * @return return code of the TPM response
+ */
+u32 tpm_return_code(const void *response);
+
+/**
+ * Send a TPM command and return response's return code, and optionally
+ * return response to caller.
+ *
+ * @param command      byte string of TPM command
+ * @param response     output buffer for TPM response, or NULL if the
+ *                     caller does not care about it
+ * @param size_ptr     output buffer size (input parameter) and TPM
+ *                     response length (output parameter); this parameter
+ *                     is a bidirectional
+ * @return return code of the TPM response
+ */
+u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr);
+
+#endif /* __TPM_UTILS_H */
similarity index 81%
rename from lib/tpm.c
rename to lib/tpm-v1.c
index 899528e178b156a16615ddd28d36b2963fb5507f..7aecb24f9213eddbb17feea0303f2a933c4f1148 100644 (file)
--- a/lib/tpm.c
@@ -6,26 +6,11 @@
 
 #include <common.h>
 #include <dm.h>
-#include <tpm.h>
 #include <asm/unaligned.h>
 #include <u-boot/sha1.h>
-
-/* Internal error of TPM command library */
-#define TPM_LIB_ERROR  ((u32)~0u)
-
-/* Useful constants */
-enum {
-       COMMAND_BUFFER_SIZE             = 256,
-       TPM_REQUEST_HEADER_LENGTH       = 10,
-       TPM_RESPONSE_HEADER_LENGTH      = 10,
-       PCR_DIGEST_LENGTH               = 20,
-       DIGEST_LENGTH                   = 20,
-       TPM_REQUEST_AUTH_LENGTH         = 45,
-       TPM_RESPONSE_AUTH_LENGTH        = 41,
-       /* some max lengths, valid for RSA keys <= 2048 bits */
-       TPM_KEY12_MAX_LENGTH            = 618,
-       TPM_PUBKEY_MAX_LENGTH           = 288,
-};
+#include <tpm-common.h>
+#include <tpm-v1.h>
+#include "tpm-utils.h"
 
 #ifdef CONFIG_TPM_AUTH_SESSIONS
 
@@ -44,235 +29,6 @@ static struct session_data oiap_session = {0, };
 
 #endif /* CONFIG_TPM_AUTH_SESSIONS */
 
-/**
- * Pack data into a byte string.  The data types are specified in
- * the format string: 'b' means unsigned byte, 'w' unsigned word,
- * 'd' unsigned double word, and 's' byte string.  The data are a
- * series of offsets and values (for type byte string there are also
- * lengths).  The data values are packed into the byte string
- * sequentially, and so a latter value could over-write a former
- * value.
- *
- * @param str          output string
- * @param size         size of output string
- * @param format       format string
- * @param ...          data points
- * @return 0 on success, non-0 on error
- */
-int pack_byte_string(u8 *str, size_t size, const char *format, ...)
-{
-       va_list args;
-       size_t offset = 0, length = 0;
-       u8 *data = NULL;
-       u32 value = 0;
-
-       va_start(args, format);
-       for (; *format; format++) {
-               switch (*format) {
-               case 'b':
-                       offset = va_arg(args, size_t);
-                       value = va_arg(args, int);
-                       length = 1;
-                       break;
-               case 'w':
-                       offset = va_arg(args, size_t);
-                       value = va_arg(args, int);
-                       length = 2;
-                       break;
-               case 'd':
-                       offset = va_arg(args, size_t);
-                       value = va_arg(args, u32);
-                       length = 4;
-                       break;
-               case 's':
-                       offset = va_arg(args, size_t);
-                       data = va_arg(args, u8 *);
-                       length = va_arg(args, u32);
-                       break;
-               default:
-                       debug("Couldn't recognize format string\n");
-                       va_end(args);
-                       return -1;
-               }
-
-               if (offset + length > size) {
-                       va_end(args);
-                       return -1;
-               }
-
-               switch (*format) {
-               case 'b':
-                       str[offset] = value;
-                       break;
-               case 'w':
-                       put_unaligned_be16(value, str + offset);
-                       break;
-               case 'd':
-                       put_unaligned_be32(value, str + offset);
-                       break;
-               case 's':
-                       memcpy(str + offset, data, length);
-                       break;
-               }
-       }
-       va_end(args);
-
-       return 0;
-}
-
-/**
- * Unpack data from a byte string.  The data types are specified in
- * the format string: 'b' means unsigned byte, 'w' unsigned word,
- * 'd' unsigned double word, and 's' byte string.  The data are a
- * series of offsets and pointers (for type byte string there are also
- * lengths).
- *
- * @param str          output string
- * @param size         size of output string
- * @param format       format string
- * @param ...          data points
- * @return 0 on success, non-0 on error
- */
-int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
-{
-       va_list args;
-       size_t offset = 0, length = 0;
-       u8 *ptr8 = NULL;
-       u16 *ptr16 = NULL;
-       u32 *ptr32 = NULL;
-
-       va_start(args, format);
-       for (; *format; format++) {
-               switch (*format) {
-               case 'b':
-                       offset = va_arg(args, size_t);
-                       ptr8 = va_arg(args, u8 *);
-                       length = 1;
-                       break;
-               case 'w':
-                       offset = va_arg(args, size_t);
-                       ptr16 = va_arg(args, u16 *);
-                       length = 2;
-                       break;
-               case 'd':
-                       offset = va_arg(args, size_t);
-                       ptr32 = va_arg(args, u32 *);
-                       length = 4;
-                       break;
-               case 's':
-                       offset = va_arg(args, size_t);
-                       ptr8 = va_arg(args, u8 *);
-                       length = va_arg(args, u32);
-                       break;
-               default:
-                       va_end(args);
-                       debug("Couldn't recognize format string\n");
-                       return -1;
-               }
-
-               if (offset + length > size) {
-                       va_end(args);
-                       return -1;
-               }
-
-               switch (*format) {
-               case 'b':
-                       *ptr8 = str[offset];
-                       break;
-               case 'w':
-                       *ptr16 = get_unaligned_be16(str + offset);
-                       break;
-               case 'd':
-                       *ptr32 = get_unaligned_be32(str + offset);
-                       break;
-               case 's':
-                       memcpy(ptr8, str + offset, length);
-                       break;
-               }
-       }
-       va_end(args);
-
-       return 0;
-}
-
-/**
- * Get TPM command size.
- *
- * @param command      byte string of TPM command
- * @return command size of the TPM command
- */
-static u32 tpm_command_size(const void *command)
-{
-       const size_t command_size_offset = 2;
-
-       return get_unaligned_be32(command + command_size_offset);
-}
-
-/**
- * Get TPM response return code, which is one of TPM_RESULT values.
- *
- * @param response     byte string of TPM response
- * @return return code of the TPM response
- */
-static u32 tpm_return_code(const void *response)
-{
-       const size_t return_code_offset = 6;
-
-       return get_unaligned_be32(response + return_code_offset);
-}
-
-/**
- * Send a TPM command and return response's return code, and optionally
- * return response to caller.
- *
- * @param command      byte string of TPM command
- * @param response     output buffer for TPM response, or NULL if the
- *                     caller does not care about it
- * @param size_ptr     output buffer size (input parameter) and TPM
- *                     response length (output parameter); this parameter
- *                     is a bidirectional
- * @return return code of the TPM response
- */
-static u32 tpm_sendrecv_command(const void *command, void *response,
-                               size_t *size_ptr)
-{
-       struct udevice *dev;
-       int err, ret;
-       u8 response_buffer[COMMAND_BUFFER_SIZE];
-       size_t response_length;
-
-       if (response) {
-               response_length = *size_ptr;
-       } else {
-               response = response_buffer;
-               response_length = sizeof(response_buffer);
-       }
-
-       ret = uclass_first_device_err(UCLASS_TPM, &dev);
-       if (ret)
-               return ret;
-       err = tpm_xfer(dev, command, tpm_command_size(command),
-                      response, &response_length);
-
-       if (err < 0)
-               return TPM_LIB_ERROR;
-       if (size_ptr)
-               *size_ptr = response_length;
-
-       return tpm_return_code(response);
-}
-
-int tpm_init(void)
-{
-       int err;
-       struct udevice *dev;
-
-       err = uclass_first_device_err(UCLASS_TPM, &dev);
-       if (err)
-               return err;
-       return tpm_open(dev);
-}
-
 u32 tpm_startup(enum tpm_startup_type mode)
 {
        const u8 command[12] = {