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
11 #include <asm/unaligned.h>
12 #include <tpm-common.h>
13 #include "tpm-utils.h"
15 enum tpm_version tpm_get_version(struct udevice *dev)
17 struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);
22 int pack_byte_string(u8 *str, size_t size, const char *format, ...)
25 size_t offset = 0, length = 0;
29 va_start(args, format);
30 for (; *format; format++) {
33 offset = va_arg(args, size_t);
34 value = va_arg(args, int);
38 offset = va_arg(args, size_t);
39 value = va_arg(args, int);
43 offset = va_arg(args, size_t);
44 value = va_arg(args, u32);
48 offset = va_arg(args, size_t);
49 data = va_arg(args, u8 *);
50 length = va_arg(args, u32);
53 debug("Couldn't recognize format string\n");
58 if (offset + length > size) {
68 put_unaligned_be16(value, str + offset);
71 put_unaligned_be32(value, str + offset);
74 memcpy(str + offset, data, length);
83 int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
86 size_t offset = 0, length = 0;
91 va_start(args, format);
92 for (; *format; format++) {
95 offset = va_arg(args, size_t);
96 ptr8 = va_arg(args, u8 *);
100 offset = va_arg(args, size_t);
101 ptr16 = va_arg(args, u16 *);
105 offset = va_arg(args, size_t);
106 ptr32 = va_arg(args, u32 *);
110 offset = va_arg(args, size_t);
111 ptr8 = va_arg(args, u8 *);
112 length = va_arg(args, u32);
116 debug("Couldn't recognize format string\n");
120 if (offset + length > size) {
122 log_err("Failed to read: size=%zd, offset=%zx, len=%zx\n",
123 size, offset, length);
132 *ptr16 = get_unaligned_be16(str + offset);
135 *ptr32 = get_unaligned_be32(str + offset);
138 memcpy(ptr8, str + offset, length);
147 u32 tpm_command_size(const void *command)
149 const size_t command_size_offset = 2;
151 return get_unaligned_be32(command + command_size_offset);
154 u32 tpm_return_code(const void *response)
156 const size_t return_code_offset = 6;
158 return get_unaligned_be32(response + return_code_offset);
161 u32 tpm_sendrecv_command(struct udevice *dev, const void *command,
162 void *response, size_t *size_ptr)
165 u8 response_buffer[COMMAND_BUFFER_SIZE];
166 size_t response_length;
171 response_length = *size_ptr;
173 response = response_buffer;
174 response_length = sizeof(response_buffer);
177 size = tpm_command_size(command);
179 /* sanity check, which also helps coverity */
180 if (size > COMMAND_BUFFER_SIZE)
181 return log_msg_ret("size", -E2BIG);
183 log_debug("TPM request [size:%d]: ", size);
184 for (i = 0; i < size; i++)
185 log_debug("%02x ", ((u8 *)command)[i]);
188 err = tpm_xfer(dev, command, size, response, &response_length);
194 *size_ptr = response_length;
196 ret = tpm_return_code(response);
198 log_debug("TPM response [ret:%d]: ", ret);
199 for (i = 0; i < response_length; i++)
200 log_debug("%02x ", ((u8 *)response)[i]);
206 int tpm_init(struct udevice *dev)
208 return tpm_open(dev);