diff options
author | Miquel Raynal | 2018-05-15 11:57:06 +0200 |
---|---|---|
committer | Tom Rini | 2018-05-25 20:12:55 -0400 |
commit | d677bfe2f7914367d1caa6146b34e86d0df1c75d (patch) | |
tree | a9fd34e6cceac25b6d232ab2d07460648cb53022 /lib/tpm-common.c | |
parent | 9f9ce3c369b7fbcc47496331ff28fad80302a42c (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/tpm-common.c')
-rw-r--r-- | lib/tpm-common.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/lib/tpm-common.c b/lib/tpm-common.c new file mode 100644 index 00000000000..4c2b9393c4b --- /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); +} |