1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2013 The Chromium OS Authors.
4 * Coypright (c) 2013 Guntermann & Drunck GmbH
9 #include <asm/unaligned.h>
10 #include <tpm-common.h>
11 #include "tpm-utils.h"
13 int pack_byte_string(u8 *str, size_t size, const char *format, ...)
16 size_t offset = 0, length = 0;
20 va_start(args, format);
21 for (; *format; format++) {
24 offset = va_arg(args, size_t);
25 value = va_arg(args, int);
29 offset = va_arg(args, size_t);
30 value = va_arg(args, int);
34 offset = va_arg(args, size_t);
35 value = va_arg(args, u32);
39 offset = va_arg(args, size_t);
40 data = va_arg(args, u8 *);
41 length = va_arg(args, u32);
44 debug("Couldn't recognize format string\n");
49 if (offset + length > size) {
59 put_unaligned_be16(value, str + offset);
62 put_unaligned_be32(value, str + offset);
65 memcpy(str + offset, data, length);
74 int unpack_byte_string(const u8 *str, size_t size, const char *format, ...)
77 size_t offset = 0, length = 0;
82 va_start(args, format);
83 for (; *format; format++) {
86 offset = va_arg(args, size_t);
87 ptr8 = va_arg(args, u8 *);
91 offset = va_arg(args, size_t);
92 ptr16 = va_arg(args, u16 *);
96 offset = va_arg(args, size_t);
97 ptr32 = va_arg(args, u32 *);
101 offset = va_arg(args, size_t);
102 ptr8 = va_arg(args, u8 *);
103 length = va_arg(args, u32);
107 debug("Couldn't recognize format string\n");
111 if (offset + length > size) {
121 *ptr16 = get_unaligned_be16(str + offset);
124 *ptr32 = get_unaligned_be32(str + offset);
127 memcpy(ptr8, str + offset, length);
136 u32 tpm_command_size(const void *command)
138 const size_t command_size_offset = 2;
140 return get_unaligned_be32(command + command_size_offset);
143 u32 tpm_return_code(const void *response)
145 const size_t return_code_offset = 6;
147 return get_unaligned_be32(response + return_code_offset);
150 u32 tpm_sendrecv_command(const void *command, void *response, size_t *size_ptr)
154 u8 response_buffer[COMMAND_BUFFER_SIZE];
155 size_t response_length;
159 response_length = *size_ptr;
161 response = response_buffer;
162 response_length = sizeof(response_buffer);
165 ret = uclass_first_device_err(UCLASS_TPM, &dev);
168 err = tpm_xfer(dev, command, tpm_command_size(command),
169 response, &response_length);
175 *size_ptr = response_length;
177 ret = tpm_return_code(response);
179 log(LOGC_NONE, LOGL_DEBUG, "TPM response [ret:%d]: ", ret);
180 for (i = 0; i < response_length; i++)
181 log(LOGC_NONE, LOGL_DEBUG, "%02x ", ((u8 *)response)[i]);
182 log(LOGC_NONE, LOGL_DEBUG, "\n");
192 err = uclass_first_device_err(UCLASS_TPM, &dev);
196 return tpm_open(dev);