summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2018-05-15 11:57:06 +0200
committerTom Rini <trini@konsulko.com>2018-05-25 20:12:55 -0400
commitd677bfe2f7914367d1caa6146b34e86d0df1c75d (patch)
treea9fd34e6cceac25b6d232ab2d07460648cb53022 /lib
parent9f9ce3c369b7fbcc47496331ff28fad80302a42c (diff)
tpm: disociate TPMv1.x specific and generic code
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile3
-rw-r--r--lib/tpm-common.c188
-rw-r--r--lib/tpm-utils.h95
-rw-r--r--lib/tpm-v1.c (renamed from lib/tpm.c)250
4 files changed, 288 insertions, 248 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 2a56b3b1c6..72504e7654 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -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
index 0000000000..4c2b9393c4
--- /dev/null
+++ b/lib/tpm-common.c
@@ -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
index 0000000000..bc98d1ef8f
--- /dev/null
+++ b/lib/tpm-utils.h
@@ -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 */
diff --git a/lib/tpm.c b/lib/tpm-v1.c
index 899528e178..7aecb24f92 100644
--- a/lib/tpm.c
+++ b/lib/tpm-v1.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] = {