1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2013 The Chromium OS Authors.
4 * Coypright (c) 2013 Guntermann & Drunck GmbH
7 #define LOG_CATEGORY UCLASS_TPM
12 #include <asm/unaligned.h>
13 #include <tpm-common.h>
14 #include "tpm-utils.h"
16 enum tpm_version tpm_get_version(struct udevice *dev)
18 struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);
23 int pack_byte_string(u8 *str, size_t size, const char *format, ...)
26 size_t offset = 0, length = 0;
30 va_start(args, format);
31 for (; *format; format++) {
34 offset = va_arg(args, size_t);
35 value = va_arg(args, int);
39 offset = va_arg(args, size_t);
40 value = va_arg(args, int);
44 offset = va_arg(args, size_t);
45 value = va_arg(args, u32);
49 offset = va_arg(args, size_t);
50 data = va_arg(args, u8 *);
51 length = va_arg(args, u32);
54 debug("Couldn't recognize format string\n");
59 if (offset + length > size) {
69 put_unaligned_be16(value, str + offset);
72 put_unaligned_be32(value, str + offset);
75 memcpy(str + offset, data, length);
84 int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
87 size_t offset = 0, length = 0;
92 va_start(args, format);
93 for (; *format; format++) {
96 offset = va_arg(args, size_t);
97 ptr8 = va_arg(args, u8 *);
101 offset = va_arg(args, size_t);
102 ptr16 = va_arg(args, u16 *);
106 offset = va_arg(args, size_t);
107 ptr32 = va_arg(args, u32 *);
111 offset = va_arg(args, size_t);
112 ptr8 = va_arg(args, u8 *);
113 length = va_arg(args, u32);
117 debug("Couldn't recognize format string\n");
121 if (offset + length > size) {
123 log_err("Failed to read: size=%zd, offset=%zx, len=%zx\n",
124 size, offset, length);
133 *ptr16 = get_unaligned_be16(str + offset);
136 *ptr32 = get_unaligned_be32(str + offset);
139 memcpy(ptr8, str + offset, length);
148 u32 tpm_command_size(const void *command)
150 const size_t command_size_offset = 2;
152 return get_unaligned_be32(command + command_size_offset);
155 u32 tpm_return_code(const void *response)
157 const size_t return_code_offset = 6;
159 return get_unaligned_be32(response + return_code_offset);
162 u32 tpm_sendrecv_command(struct udevice *dev, const void *command,
163 void *response, size_t *size_ptr)
166 u8 response_buffer[COMMAND_BUFFER_SIZE];
167 size_t response_length;
172 response_length = *size_ptr;
174 response = response_buffer;
175 response_length = sizeof(response_buffer);
178 size = tpm_command_size(command);
180 /* sanity check, which also helps coverity */
181 if (size > COMMAND_BUFFER_SIZE)
182 return log_msg_ret("size", -E2BIG);
184 log_debug("TPM request [size:%d]: ", size);
185 for (i = 0; i < size; i++)
186 log_debug("%02x ", ((u8 *)command)[i]);
189 err = tpm_xfer(dev, command, size, response, &response_length);
195 *size_ptr = response_length;
197 ret = tpm_return_code(response);
199 log_debug("TPM response [ret:%d]: ", ret);
200 for (i = 0; i < response_length; i++)
201 log_debug("%02x ", ((u8 *)response)[i]);
207 int tpm_init(struct udevice *dev)
209 return tpm_open(dev);