diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile | 4 | ||||
-rw-r--r-- | lib/efi_loader/Kconfig | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_image_loader.c | 2 | ||||
-rw-r--r-- | lib/efi_loader/efi_runtime.c | 44 | ||||
-rw-r--r-- | lib/fdtdec.c | 1 | ||||
-rw-r--r-- | lib/tpm-common.c | 197 | ||||
-rw-r--r-- | lib/tpm-utils.h | 101 | ||||
-rw-r--r-- | lib/tpm-v1.c (renamed from lib/tpm.c) | 602 | ||||
-rw-r--r-- | lib/tpm-v2.c | 419 |
9 files changed, 936 insertions, 436 deletions
diff --git a/lib/Makefile b/lib/Makefile index d531ea54b3..e6cb4afc23 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -39,7 +39,9 @@ obj-$(CONFIG_PHYSMEM) += physmem.o obj-y += qsort.o obj-y += rc4.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o -obj-$(CONFIG_TPM) += tpm.o +obj-$(CONFIG_TPM) += tpm-common.o +obj-$(CONFIG_TPM_V1) += tpm-v1.o +obj-$(CONFIG_TPM_V2) += tpm-v2.o obj-$(CONFIG_RBTREE) += rbtree.o obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index d38780b604..2909e76960 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -1,6 +1,6 @@ config EFI_LOADER bool "Support running EFI Applications in U-Boot" - depends on (ARM || X86) && OF_LIBFDT + depends on (ARM || X86 || RISCV) && OF_LIBFDT # We do not support bootefi booting ARMv7 in non-secure mode depends on !ARMV7_NONSEC # We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index e832cde901..b45f09591a 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -287,7 +287,7 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) /* Flush cache */ flush_cache((ulong)efi_reloc, - ALIGN(virt_size, CONFIG_SYS_CACHELINE_SIZE)); + ALIGN(virt_size, EFI_CACHELINE_SIZE)); invalidate_icache_all(); /* Populate the loaded image interface bits */ diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c index 52f1301d75..241090f6b4 100644 --- a/lib/efi_loader/efi_runtime.c +++ b/lib/efi_loader/efi_runtime.c @@ -29,13 +29,6 @@ static efi_status_t __efi_runtime EFIAPI efi_unimplemented(void); static efi_status_t __efi_runtime EFIAPI efi_device_error(void); static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void); -#ifdef CONFIG_SYS_CACHELINE_SIZE -#define EFI_CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE -#else -/* Just use the greatest cache flush alignment requirement I'm aware of */ -#define EFI_CACHELINE_SIZE 128 -#endif - #if defined(CONFIG_ARM64) #define R_RELATIVE 1027 #define R_MASK 0xffffffffULL @@ -47,6 +40,25 @@ static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void); #include <asm/elf.h> #define R_RELATIVE R_386_RELATIVE #define R_MASK 0xffULL +#elif defined(CONFIG_RISCV) +#include <elf.h> +#define R_RELATIVE R_RISCV_RELATIVE +#define R_MASK 0xffULL +#define IS_RELA 1 + +struct dyn_sym { + ulong foo1; + ulong addr; + u32 foo2; + u32 foo3; +}; +#ifdef CONFIG_CPU_RISCV_32 +#define R_ABSOLUTE R_RISCV_32 +#define SYM_INDEX 8 +#else +#define R_ABSOLUTE R_RISCV_64 +#define SYM_INDEX 32 +#endif #else #error Need to add relocation awareness #endif @@ -253,15 +265,27 @@ void efi_runtime_relocate(ulong offset, struct efi_mem_desc *map) p = (void*)((ulong)rel->offset - base) + gd->relocaddr; - if ((rel->info & R_MASK) != R_RELATIVE) { - continue; - } + debug("%s: rel->info=%#lx *p=%#lx rel->offset=%p\n", __func__, rel->info, *p, rel->offset); + switch (rel->info & R_MASK) { + case R_RELATIVE: #ifdef IS_RELA newaddr = rel->addend + offset - CONFIG_SYS_TEXT_BASE; #else newaddr = *p - lastoff + offset; #endif + break; +#ifdef R_ABSOLUTE + case R_ABSOLUTE: { + ulong symidx = rel->info >> SYM_INDEX; + extern struct dyn_sym __dyn_sym_start[]; + newaddr = __dyn_sym_start[symidx].addr + offset; + break; + } +#endif + default: + continue; + } /* Check if the relocation is inside bounds */ if (map && ((newaddr < map->virtual_start) || diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 69bf12623e..f4e8dbf699 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -72,6 +72,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(ALTERA_SOCFPGA_F2SDR2, "altr,socfpga-fpga2sdram2-bridge"), COMPAT(ALTERA_SOCFPGA_FPGA0, "altr,socfpga-a10-fpga-mgr"), COMPAT(ALTERA_SOCFPGA_NOC, "altr,socfpga-a10-noc"), + COMPAT(ALTERA_SOCFPGA_CLK_INIT, "altr,socfpga-a10-clk-init") }; const char *fdtdec_get_compatible(enum fdt_compat_id id) diff --git a/lib/tpm-common.c b/lib/tpm-common.c new file mode 100644 index 0000000000..43b530865a --- /dev/null +++ b/lib/tpm-common.c @@ -0,0 +1,197 @@ +// 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; + int i; + + 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 err; + + if (size_ptr) + *size_ptr = response_length; + + ret = tpm_return_code(response); + + log(LOGC_NONE, LOGL_DEBUG, "TPM response [ret:%d]: ", ret); + for (i = 0; i < response_length; i++) + log(LOGC_NONE, LOGL_DEBUG, "%02x ", ((u8 *)response)[i]); + log(LOGC_NONE, LOGL_DEBUG, "\n"); + + return ret; +} + +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..a9cb7dc7ee --- /dev/null +++ b/lib/tpm-utils.h @@ -0,0 +1,101 @@ +/* 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) + +/* To make strings of commands more easily */ +#define __MSB(x) ((x) >> 8) +#define __LSB(x) ((x) & 0xFF) +#define tpm_u16(x) __MSB(x), __LSB(x) +#define tpm_u32(x) tpm_u16((x) >> 16), tpm_u16((x) & 0xFFFF) + +/** + * 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 bc9652d8e4..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 ((uint32_t)~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 @@ -35,277 +20,50 @@ enum { struct session_data { int valid; - uint32_t handle; - uint8_t nonce_even[DIGEST_LENGTH]; - uint8_t nonce_odd[DIGEST_LENGTH]; + u32 handle; + u8 nonce_even[DIGEST_LENGTH]; + u8 nonce_odd[DIGEST_LENGTH]; }; 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(uint8_t *str, size_t size, const char *format, ...) -{ - va_list args; - size_t offset = 0, length = 0; - uint8_t *data = NULL; - uint32_t 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, uint32_t); - length = 4; - break; - case 's': - offset = va_arg(args, size_t); - data = va_arg(args, uint8_t *); - length = va_arg(args, uint32_t); - 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 uint8_t *str, size_t size, const char *format, ...) -{ - va_list args; - size_t offset = 0, length = 0; - uint8_t *ptr8 = NULL; - uint16_t *ptr16 = NULL; - uint32_t *ptr32 = NULL; - - va_start(args, format); - for (; *format; format++) { - switch (*format) { - case 'b': - offset = va_arg(args, size_t); - ptr8 = va_arg(args, uint8_t *); - length = 1; - break; - case 'w': - offset = va_arg(args, size_t); - ptr16 = va_arg(args, uint16_t *); - length = 2; - break; - case 'd': - offset = va_arg(args, size_t); - ptr32 = va_arg(args, uint32_t *); - length = 4; - break; - case 's': - offset = va_arg(args, size_t); - ptr8 = va_arg(args, uint8_t *); - length = va_arg(args, uint32_t); - 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 uint32_t tpm_command_size(const void *command) +u32 tpm_startup(enum tpm_startup_type mode) { - 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 uint32_t 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 uint32_t tpm_sendrecv_command(const void *command, - void *response, size_t *size_ptr) -{ - struct udevice *dev; - int err, ret; - uint8_t 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); -} - -uint32_t tpm_startup(enum tpm_startup_type mode) -{ - const uint8_t command[12] = { + const u8 command[12] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0, }; const size_t mode_offset = 10; - uint8_t buf[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE]; if (pack_byte_string(buf, sizeof(buf), "sw", - 0, command, sizeof(command), - mode_offset, mode)) + 0, command, sizeof(command), + mode_offset, mode)) return TPM_LIB_ERROR; return tpm_sendrecv_command(buf, NULL, NULL); } -uint32_t tpm_self_test_full(void) +u32 tpm_self_test_full(void) { - const uint8_t command[10] = { + const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, }; return tpm_sendrecv_command(command, NULL, NULL); } -uint32_t tpm_continue_self_test(void) +u32 tpm_continue_self_test(void) { - const uint8_t command[10] = { + const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53, }; return tpm_sendrecv_command(command, NULL, NULL); } -uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size) +u32 tpm_nv_define_space(u32 index, u32 perm, u32 size) { - const uint8_t command[101] = { + const u8 command[101] = { 0x0, 0xc1, /* TPM_TAG */ 0x0, 0x0, 0x0, 0x65, /* parameter size */ 0x0, 0x0, 0x0, 0xcc, /* TPM_COMMAND_CODE */ @@ -334,55 +92,55 @@ uint32_t tpm_nv_define_space(uint32_t index, uint32_t perm, uint32_t size) const size_t index_offset = 12; const size_t perm_offset = 70; const size_t size_offset = 77; - uint8_t buf[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE]; if (pack_byte_string(buf, sizeof(buf), "sddd", - 0, command, sizeof(command), - index_offset, index, - perm_offset, perm, - size_offset, size)) + 0, command, sizeof(command), + index_offset, index, + perm_offset, perm, + size_offset, size)) return TPM_LIB_ERROR; return tpm_sendrecv_command(buf, NULL, NULL); } -uint32_t tpm_nv_read_value(uint32_t index, void *data, uint32_t count) +u32 tpm_nv_read_value(u32 index, void *data, u32 count) { - const uint8_t command[22] = { + const u8 command[22] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf, }; const size_t index_offset = 10; const size_t length_offset = 18; const size_t data_size_offset = 10; const size_t data_offset = 14; - uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t data_size; - uint32_t err; + u32 data_size; + u32 err; if (pack_byte_string(buf, sizeof(buf), "sdd", - 0, command, sizeof(command), - index_offset, index, - length_offset, count)) + 0, command, sizeof(command), + index_offset, index, + length_offset, count)) return TPM_LIB_ERROR; err = tpm_sendrecv_command(buf, response, &response_length); if (err) return err; if (unpack_byte_string(response, response_length, "d", - data_size_offset, &data_size)) + data_size_offset, &data_size)) return TPM_LIB_ERROR; if (data_size > count) return TPM_LIB_ERROR; if (unpack_byte_string(response, response_length, "s", - data_offset, data, data_size)) + data_offset, data, data_size)) return TPM_LIB_ERROR; return 0; } -uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length) +u32 tpm_nv_write_value(u32 index, const void *data, u32 length) { - const uint8_t command[256] = { + const u8 command[256] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, }; const size_t command_size_offset = 2; @@ -390,18 +148,18 @@ uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length) const size_t length_offset = 18; const size_t data_offset = 22; const size_t write_info_size = 12; - const uint32_t total_length = + const u32 total_length = TPM_REQUEST_HEADER_LENGTH + write_info_size + length; - uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (pack_byte_string(buf, sizeof(buf), "sddds", - 0, command, sizeof(command), - command_size_offset, total_length, - index_offset, index, - length_offset, length, - data_offset, data, length)) + 0, command, sizeof(command), + command_size_offset, total_length, + index_offset, index, + length_offset, length, + data_offset, data, length)) return TPM_LIB_ERROR; err = tpm_sendrecv_command(buf, response, &response_length); if (err) @@ -410,99 +168,99 @@ uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length) return 0; } -uint32_t tpm_extend(uint32_t index, const void *in_digest, void *out_digest) +u32 tpm_extend(u32 index, const void *in_digest, void *out_digest) { - const uint8_t command[34] = { + const u8 command[34] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14, }; const size_t index_offset = 10; const size_t in_digest_offset = 14; const size_t out_digest_offset = 10; - uint8_t buf[COMMAND_BUFFER_SIZE]; - uint8_t response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH]; + u8 buf[COMMAND_BUFFER_SIZE]; + u8 response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (pack_byte_string(buf, sizeof(buf), "sds", - 0, command, sizeof(command), - index_offset, index, - in_digest_offset, in_digest, - PCR_DIGEST_LENGTH)) + 0, command, sizeof(command), + index_offset, index, + in_digest_offset, in_digest, + PCR_DIGEST_LENGTH)) return TPM_LIB_ERROR; err = tpm_sendrecv_command(buf, response, &response_length); if (err) return err; if (unpack_byte_string(response, response_length, "s", - out_digest_offset, out_digest, - PCR_DIGEST_LENGTH)) + out_digest_offset, out_digest, + PCR_DIGEST_LENGTH)) return TPM_LIB_ERROR; return 0; } -uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count) +u32 tpm_pcr_read(u32 index, void *data, size_t count) { - const uint8_t command[14] = { + const u8 command[14] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15, }; const size_t index_offset = 10; const size_t out_digest_offset = 10; - uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (count < PCR_DIGEST_LENGTH) return TPM_LIB_ERROR; if (pack_byte_string(buf, sizeof(buf), "sd", - 0, command, sizeof(command), - index_offset, index)) + 0, command, sizeof(command), + index_offset, index)) return TPM_LIB_ERROR; err = tpm_sendrecv_command(buf, response, &response_length); if (err) return err; if (unpack_byte_string(response, response_length, "s", - out_digest_offset, data, PCR_DIGEST_LENGTH)) + out_digest_offset, data, PCR_DIGEST_LENGTH)) return TPM_LIB_ERROR; return 0; } -uint32_t tpm_tsc_physical_presence(uint16_t presence) +u32 tpm_tsc_physical_presence(u16 presence) { - const uint8_t command[12] = { + const u8 command[12] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0, }; const size_t presence_offset = 10; - uint8_t buf[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE]; if (pack_byte_string(buf, sizeof(buf), "sw", - 0, command, sizeof(command), - presence_offset, presence)) + 0, command, sizeof(command), + presence_offset, presence)) return TPM_LIB_ERROR; return tpm_sendrecv_command(buf, NULL, NULL); } -uint32_t tpm_read_pubek(void *data, size_t count) +u32 tpm_read_pubek(void *data, size_t count) { - const uint8_t command[30] = { + const u8 command[30] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c, }; const size_t response_size_offset = 2; const size_t data_offset = 10; const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20; - uint8_t response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE]; + u8 response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE]; size_t response_length = sizeof(response); - uint32_t data_size; - uint32_t err; + u32 data_size; + u32 err; err = tpm_sendrecv_command(command, response, &response_length); if (err) return err; if (unpack_byte_string(response, response_length, "d", - response_size_offset, &data_size)) + response_size_offset, &data_size)) return TPM_LIB_ERROR; if (data_size < header_and_checksum_size) return TPM_LIB_ERROR; @@ -510,59 +268,58 @@ uint32_t tpm_read_pubek(void *data, size_t count) if (data_size > count) return TPM_LIB_ERROR; if (unpack_byte_string(response, response_length, "s", - data_offset, data, data_size)) + data_offset, data, data_size)) return TPM_LIB_ERROR; return 0; } -uint32_t tpm_force_clear(void) +u32 tpm_force_clear(void) { - const uint8_t command[10] = { + const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d, }; return tpm_sendrecv_command(command, NULL, NULL); } -uint32_t tpm_physical_enable(void) +u32 tpm_physical_enable(void) { - const uint8_t command[10] = { + const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f, }; return tpm_sendrecv_command(command, NULL, NULL); } -uint32_t tpm_physical_disable(void) +u32 tpm_physical_disable(void) { - const uint8_t command[10] = { + const u8 command[10] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70, }; return tpm_sendrecv_command(command, NULL, NULL); } -uint32_t tpm_physical_set_deactivated(uint8_t state) +u32 tpm_physical_set_deactivated(u8 state) { - const uint8_t command[11] = { + const u8 command[11] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, }; const size_t state_offset = 10; - uint8_t buf[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE]; if (pack_byte_string(buf, sizeof(buf), "sb", - 0, command, sizeof(command), - state_offset, state)) + 0, command, sizeof(command), + state_offset, state)) return TPM_LIB_ERROR; return tpm_sendrecv_command(buf, NULL, NULL); } -uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap, - void *cap, size_t count) +u32 tpm_get_capability(u32 cap_area, u32 sub_cap, void *cap, size_t count) { - const uint8_t command[22] = { + const u8 command[22] = { 0x0, 0xc1, /* TPM_TAG */ 0x0, 0x0, 0x0, 0x16, /* parameter size */ 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */ @@ -574,34 +331,34 @@ uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap, const size_t sub_cap_offset = 18; const size_t cap_offset = 14; const size_t cap_size_offset = 10; - uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t cap_size; - uint32_t err; + u32 cap_size; + u32 err; if (pack_byte_string(buf, sizeof(buf), "sdd", - 0, command, sizeof(command), - cap_area_offset, cap_area, - sub_cap_offset, sub_cap)) + 0, command, sizeof(command), + cap_area_offset, cap_area, + sub_cap_offset, sub_cap)) return TPM_LIB_ERROR; err = tpm_sendrecv_command(buf, response, &response_length); if (err) return err; if (unpack_byte_string(response, response_length, "d", - cap_size_offset, &cap_size)) + cap_size_offset, &cap_size)) return TPM_LIB_ERROR; if (cap_size > response_length || cap_size > count) return TPM_LIB_ERROR; if (unpack_byte_string(response, response_length, "s", - cap_offset, cap, cap_size)) + cap_offset, cap, cap_size)) return TPM_LIB_ERROR; return 0; } -uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags) +u32 tpm_get_permanent_flags(struct tpm_permanent_flags *pflags) { - const uint8_t command[22] = { + const u8 command[22] = { 0x0, 0xc1, /* TPM_TAG */ 0x0, 0x0, 0x0, 0x16, /* parameter size */ 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */ @@ -610,11 +367,11 @@ uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags) 0x0, 0x0, 0x1, 0x8, /* subcap value */ }; const size_t data_size_offset = TPM_HEADER_SIZE; - const size_t data_offset = TPM_HEADER_SIZE + sizeof (uint32_t); - uint8_t response[COMMAND_BUFFER_SIZE]; + const size_t data_offset = TPM_HEADER_SIZE + sizeof(u32); + u8 response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t err; - uint32_t data_size; + u32 err; + u32 data_size; err = tpm_sendrecv_command(command, response, &response_length); if (err) @@ -631,9 +388,9 @@ uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags) return 0; } -uint32_t tpm_get_permissions(uint32_t index, uint32_t *perm) +u32 tpm_get_permissions(u32 index, u32 *perm) { - const uint8_t command[22] = { + const u8 command[22] = { 0x0, 0xc1, /* TPM_TAG */ 0x0, 0x0, 0x0, 0x16, /* parameter size */ 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */ @@ -642,9 +399,9 @@ uint32_t tpm_get_permissions(uint32_t index, uint32_t *perm) }; const size_t index_offset = 18; const size_t perm_offset = 60; - uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command), index_offset, index)) @@ -660,9 +417,9 @@ uint32_t tpm_get_permissions(uint32_t index, uint32_t *perm) } #ifdef CONFIG_TPM_FLUSH_RESOURCES -uint32_t tpm_flush_specific(uint32_t key_handle, uint32_t resource_type) +u32 tpm_flush_specific(u32 key_handle, u32 resource_type) { - const uint8_t command[18] = { + const u8 command[18] = { 0x00, 0xc1, /* TPM_TAG */ 0x00, 0x00, 0x00, 0x12, /* parameter size */ 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */ @@ -671,9 +428,9 @@ uint32_t tpm_flush_specific(uint32_t key_handle, uint32_t resource_type) }; const size_t key_handle_offset = 10; const size_t resource_type_offset = 14; - uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (pack_byte_string(buf, sizeof(buf), "sdd", 0, command, sizeof(command), @@ -702,12 +459,12 @@ uint32_t tpm_flush_specific(uint32_t key_handle, uint32_t resource_type) * @param request_auth pointer to the auth block of the request to be filled * @param auth authentication data (HMAC key) */ -static uint32_t create_request_auth(const void *request, size_t request_len0, - size_t handles_len, - struct session_data *auth_session, - void *request_auth, const void *auth) +static u32 create_request_auth(const void *request, size_t request_len0, + size_t handles_len, + struct session_data *auth_session, + void *request_auth, const void *auth) { - uint8_t hmac_data[DIGEST_LENGTH * 3 + 1]; + u8 hmac_data[DIGEST_LENGTH * 3 + 1]; sha1_context hash_ctx; const size_t command_code_offset = 6; const size_t auth_nonce_odd_offset = 4; @@ -765,19 +522,18 @@ static uint32_t create_request_auth(const void *request, size_t request_len0, * @param response_auth pointer to the auth block of the response to be verified * @param auth authentication data (HMAC key) */ -static uint32_t verify_response_auth(uint32_t command_code, - const void *response, size_t response_len0, - size_t handles_len, - struct session_data *auth_session, - const void *response_auth, const void *auth) +static u32 verify_response_auth(u32 command_code, const void *response, + size_t response_len0, size_t handles_len, + struct session_data *auth_session, + const void *response_auth, const void *auth) { - uint8_t hmac_data[DIGEST_LENGTH * 3 + 1]; - uint8_t computed_auth[DIGEST_LENGTH]; + u8 hmac_data[DIGEST_LENGTH * 3 + 1]; + u8 computed_auth[DIGEST_LENGTH]; sha1_context hash_ctx; const size_t return_code_offset = 6; const size_t auth_continue_offset = 20; const size_t auth_auth_offset = 21; - uint8_t auth_continue; + u8 auth_continue; if (!auth_session || !auth_session->valid) return TPM_AUTHFAIL; @@ -798,7 +554,7 @@ static uint32_t verify_response_auth(uint32_t command_code, sha1_finish(&hash_ctx, hmac_data); memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH); - auth_continue = ((uint8_t *)response_auth)[auth_continue_offset]; + auth_continue = ((u8 *)response_auth)[auth_continue_offset]; if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb", DIGEST_LENGTH, response_auth, @@ -820,18 +576,17 @@ static uint32_t verify_response_auth(uint32_t command_code, return TPM_SUCCESS; } - -uint32_t tpm_terminate_auth_session(uint32_t auth_handle) +u32 tpm_terminate_auth_session(u32 auth_handle) { - const uint8_t command[18] = { + const u8 command[18] = { 0x00, 0xc1, /* TPM_TAG */ 0x00, 0x00, 0x00, 0x00, /* parameter size */ 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */ 0x00, 0x00, 0x00, 0x00, /* TPM_HANDLE */ - 0x00, 0x00, 0x00, 0x02, /* TPM_RESSOURCE_TYPE */ + 0x00, 0x00, 0x00, 0x02, /* TPM_RESOURCE_TYPE */ }; const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH; - uint8_t request[COMMAND_BUFFER_SIZE]; + u8 request[COMMAND_BUFFER_SIZE]; if (pack_byte_string(request, sizeof(request), "sd", 0, command, sizeof(command), @@ -843,26 +598,27 @@ uint32_t tpm_terminate_auth_session(uint32_t auth_handle) return tpm_sendrecv_command(request, NULL, NULL); } -uint32_t tpm_end_oiap(void) +u32 tpm_end_oiap(void) { - uint32_t err = TPM_SUCCESS; + u32 err = TPM_SUCCESS; + if (oiap_session.valid) err = tpm_terminate_auth_session(oiap_session.handle); return err; } -uint32_t tpm_oiap(uint32_t *auth_handle) +u32 tpm_oiap(u32 *auth_handle) { - const uint8_t command[10] = { + const u8 command[10] = { 0x00, 0xc1, /* TPM_TAG */ 0x00, 0x00, 0x00, 0x0a, /* parameter size */ 0x00, 0x00, 0x00, 0x0a, /* TPM_COMMAND_CODE */ }; const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH; const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4; - uint8_t response[COMMAND_BUFFER_SIZE]; + u8 response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (oiap_session.valid) tpm_terminate_auth_session(oiap_session.handle); @@ -873,7 +629,7 @@ uint32_t tpm_oiap(uint32_t *auth_handle) if (unpack_byte_string(response, response_length, "ds", res_auth_handle_offset, &oiap_session.handle, res_nonce_even_offset, &oiap_session.nonce_even, - (uint32_t)DIGEST_LENGTH)) + (u32)DIGEST_LENGTH)) return TPM_LIB_ERROR; oiap_session.valid = 1; if (auth_handle) @@ -881,12 +637,10 @@ uint32_t tpm_oiap(uint32_t *auth_handle) return 0; } -uint32_t tpm_load_key2_oiap(uint32_t parent_handle, - const void *key, size_t key_length, - const void *parent_key_usage_auth, - uint32_t *key_handle) +u32 tpm_load_key2_oiap(u32 parent_handle, const void *key, size_t key_length, + const void *parent_key_usage_auth, u32 *key_handle) { - const uint8_t command[14] = { + const u8 command[14] = { 0x00, 0xc2, /* TPM_TAG */ 0x00, 0x00, 0x00, 0x00, /* parameter size */ 0x00, 0x00, 0x00, 0x41, /* TPM_COMMAND_CODE */ @@ -896,11 +650,11 @@ uint32_t tpm_load_key2_oiap(uint32_t parent_handle, const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH; const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4; const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH; - uint8_t request[sizeof(command) + TPM_KEY12_MAX_LENGTH - + TPM_REQUEST_AUTH_LENGTH]; - uint8_t response[COMMAND_BUFFER_SIZE]; + u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH + + TPM_REQUEST_AUTH_LENGTH]; + u8 response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (!oiap_session.valid) { err = tpm_oiap(NULL); @@ -918,9 +672,9 @@ uint32_t tpm_load_key2_oiap(uint32_t parent_handle, return TPM_LIB_ERROR; err = create_request_auth(request, sizeof(command) + key_length, 4, - &oiap_session, - request + sizeof(command) + key_length, - parent_key_usage_auth); + &oiap_session, + request + sizeof(command) + key_length, + parent_key_usage_auth); if (err) return err; err = tpm_sendrecv_command(request, response, &response_length); @@ -931,10 +685,11 @@ uint32_t tpm_load_key2_oiap(uint32_t parent_handle, } err = verify_response_auth(0x00000041, response, - response_length - TPM_RESPONSE_AUTH_LENGTH, - 4, &oiap_session, - response + response_length - TPM_RESPONSE_AUTH_LENGTH, - parent_key_usage_auth); + response_length - TPM_RESPONSE_AUTH_LENGTH, + 4, &oiap_session, + response + response_length - + TPM_RESPONSE_AUTH_LENGTH, + parent_key_usage_auth); if (err) return err; @@ -947,10 +702,10 @@ uint32_t tpm_load_key2_oiap(uint32_t parent_handle, return 0; } -uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth, - void *pubkey, size_t *pubkey_len) +u32 tpm_get_pub_key_oiap(u32 key_handle, const void *usage_auth, void *pubkey, + size_t *pubkey_len) { - const uint8_t command[14] = { + const u8 command[14] = { 0x00, 0xc2, /* TPM_TAG */ 0x00, 0x00, 0x00, 0x00, /* parameter size */ 0x00, 0x00, 0x00, 0x21, /* TPM_COMMAND_CODE */ @@ -959,11 +714,11 @@ uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth, const size_t req_size_offset = 2; const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH; const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH; - uint8_t request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH]; - uint8_t response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH - + TPM_RESPONSE_AUTH_LENGTH]; + u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH]; + u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH + + TPM_RESPONSE_AUTH_LENGTH]; size_t response_length = sizeof(response); - uint32_t err; + u32 err; if (!oiap_session.valid) { err = tpm_oiap(NULL); @@ -973,13 +728,13 @@ uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth, if (pack_byte_string(request, sizeof(request), "sdd", 0, command, sizeof(command), req_size_offset, - (uint32_t)(sizeof(command) + (u32)(sizeof(command) + TPM_REQUEST_AUTH_LENGTH), req_key_handle_offset, key_handle )) return TPM_LIB_ERROR; err = create_request_auth(request, sizeof(command), 4, &oiap_session, - request + sizeof(command), usage_auth); + request + sizeof(command), usage_auth); if (err) return err; err = tpm_sendrecv_command(request, response, &response_length); @@ -989,16 +744,17 @@ uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth, return err; } err = verify_response_auth(0x00000021, response, - response_length - TPM_RESPONSE_AUTH_LENGTH, - 0, &oiap_session, - response + response_length - TPM_RESPONSE_AUTH_LENGTH, - usage_auth); + response_length - TPM_RESPONSE_AUTH_LENGTH, + 0, &oiap_session, + response + response_length - + TPM_RESPONSE_AUTH_LENGTH, + usage_auth); if (err) return err; if (pubkey) { if ((response_length - TPM_RESPONSE_HEADER_LENGTH - - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len) + - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len) return TPM_LIB_ERROR; *pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH - TPM_RESPONSE_AUTH_LENGTH; @@ -1011,15 +767,15 @@ uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth, } #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1 -uint32_t tpm_find_key_sha1(const uint8_t auth[20], const uint8_t - pubkey_digest[20], uint32_t *handle) -{ - uint16_t key_count; - uint32_t key_handles[10]; - uint8_t buf[288]; - uint8_t *ptr; - uint32_t err; - uint8_t digest[20]; +u32 tpm_find_key_sha1(const u8 auth[20], const u8 pubkey_digest[20], + u32 *handle) +{ + u16 key_count; + u32 key_handles[10]; + u8 buf[288]; + u8 *ptr; + u32 err; + u8 digest[20]; size_t buf_len; unsigned int i; @@ -1052,9 +808,9 @@ uint32_t tpm_find_key_sha1(const uint8_t auth[20], const uint8_t #endif /* CONFIG_TPM_AUTH_SESSIONS */ -uint32_t tpm_get_random(void *data, uint32_t count) +u32 tpm_get_random(void *data, u32 count) { - const uint8_t command[14] = { + const u8 command[14] = { 0x0, 0xc1, /* TPM_TAG */ 0x0, 0x0, 0x0, 0xe, /* parameter size */ 0x0, 0x0, 0x0, 0x46, /* TPM_COMMAND_CODE */ @@ -1062,15 +818,15 @@ uint32_t tpm_get_random(void *data, uint32_t count) const size_t length_offset = 10; const size_t data_size_offset = 10; const size_t data_offset = 14; - uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; size_t response_length = sizeof(response); - uint32_t data_size; - uint8_t *out = data; + u32 data_size; + u8 *out = data; while (count > 0) { - uint32_t this_bytes = min((size_t)count, - sizeof (response) - data_offset); - uint32_t err; + u32 this_bytes = min((size_t)count, + sizeof(response) - data_offset); + u32 err; if (pack_byte_string(buf, sizeof(buf), "sd", 0, command, sizeof(command), diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c new file mode 100644 index 0000000000..f1bbca8e7a --- /dev/null +++ b/lib/tpm-v2.c @@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2018 Bootlin + * Author: Miquel Raynal <miquel.raynal@bootlin.com> + */ + +#include <common.h> +#include <dm.h> +#include <tpm-common.h> +#include <tpm-v2.h> +#include "tpm-utils.h" + +u32 tpm2_startup(enum tpm2_startup_types mode) +{ + const u8 command_v2[12] = { + tpm_u16(TPM2_ST_NO_SESSIONS), + tpm_u32(12), + tpm_u32(TPM2_CC_STARTUP), + tpm_u16(mode), + }; + int ret; + + /* + * Note TPM2_Startup command will return RC_SUCCESS the first time, + * but will return RC_INITIALIZE otherwise. + */ + ret = tpm_sendrecv_command(command_v2, NULL, NULL); + if (ret && ret != TPM2_RC_INITIALIZE) + return ret; + + return 0; +} + +u32 tpm2_self_test(enum tpm2_yes_no full_test) +{ + const u8 command_v2[12] = { + tpm_u16(TPM2_ST_NO_SESSIONS), + tpm_u32(11), + tpm_u32(TPM2_CC_SELF_TEST), + full_test, + }; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +u32 tpm2_clear(u32 handle, const char *pw, const ssize_t pw_sz) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(27 + pw_sz), /* Length */ + tpm_u32(TPM2_CC_CLEAR), /* Command code */ + + /* HANDLE */ + tpm_u32(handle), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* Session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz), /* Size of <hmac/password> */ + /* STRING(pw) <hmac/password> (if any) */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "s", + offset, pw, pw_sz); + offset += pw_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +u32 tpm2_pcr_extend(u32 index, const uint8_t *digest) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(33 + TPM2_DIGEST_LEN), /* Length */ + tpm_u32(TPM2_CC_PCR_EXTEND), /* Command code */ + + /* HANDLE */ + tpm_u32(index), /* Handle (PCR Index) */ + + /* AUTH_SESSION */ + tpm_u32(9), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* Session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(0), /* Size of <hmac/password> */ + /* <hmac/password> (if any) */ + tpm_u32(1), /* Count (number of hashes) */ + tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ + /* STRING(digest) Digest */ + }; + unsigned int offset = 33; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the digest + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "s", + offset, digest, TPM2_DIGEST_LEN); + offset += TPM2_DIGEST_LEN; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +u32 tpm2_pcr_read(u32 idx, unsigned int idx_min_sz, void *data, + unsigned int *updates) +{ + u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ + tpm_u32(17 + idx_array_sz), /* Length */ + tpm_u32(TPM2_CC_PCR_READ), /* Command code */ + + /* TPML_PCR_SELECTION */ + tpm_u32(1), /* Number of selections */ + tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ + idx_array_sz, /* Array size for selection */ + /* bitmap(idx) Selected PCR bitmap */ + }; + size_t response_len = COMMAND_BUFFER_SIZE; + u8 response[COMMAND_BUFFER_SIZE]; + unsigned int pcr_sel_idx = idx / 8; + u8 pcr_sel_bit = BIT(idx % 8); + unsigned int counter = 0; + int ret; + + if (pack_byte_string(command_v2, COMMAND_BUFFER_SIZE, "b", + 17 + pcr_sel_idx, pcr_sel_bit)) + return TPM_LIB_ERROR; + + ret = tpm_sendrecv_command(command_v2, response, &response_len); + if (ret) + return ret; + + if (unpack_byte_string(response, response_len, "ds", + 10, &counter, + response_len - TPM2_DIGEST_LEN, data, + TPM2_DIGEST_LEN)) + return TPM_LIB_ERROR; + + if (updates) + *updates = counter; + + return 0; +} + +u32 tpm2_get_capability(u32 capability, u32 property, void *buf, + size_t prop_count) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ + tpm_u32(22), /* Length */ + tpm_u32(TPM2_CC_GET_CAPABILITY), /* Command code */ + + tpm_u32(capability), /* Capability */ + tpm_u32(property), /* Property */ + tpm_u32(prop_count), /* Property count */ + }; + u8 response[COMMAND_BUFFER_SIZE]; + size_t response_len = COMMAND_BUFFER_SIZE; + unsigned int properties_off; + int ret; + + ret = tpm_sendrecv_command(command_v2, response, &response_len); + if (ret) + return ret; + + /* + * In the response buffer, the properties are located after the: + * tag (u16), response size (u32), response code (u32), + * YES/NO flag (u8), TPM_CAP (u32) and TPMU_CAPABILITIES (u32). + */ + properties_off = sizeof(u16) + sizeof(u32) + sizeof(u32) + + sizeof(u8) + sizeof(u32) + sizeof(u32); + memcpy(buf, &response[properties_off], response_len - properties_off); + + return 0; +} + +u32 tpm2_dam_reset(const char *pw, const ssize_t pw_sz) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(27 + pw_sz), /* Length */ + tpm_u32(TPM2_CC_DAM_RESET), /* Command code */ + + /* HANDLE */ + tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* Session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz), /* Size of <hmac/password> */ + /* STRING(pw) <hmac/password> (if any) */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "s", + offset, pw, pw_sz); + offset += pw_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, + unsigned int max_tries, unsigned int recovery_time, + unsigned int lockout_recovery) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(27 + pw_sz + 12), /* Length */ + tpm_u32(TPM2_CC_DAM_PARAMETERS), /* Command code */ + + /* HANDLE */ + tpm_u32(TPM2_RH_LOCKOUT), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* Session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz), /* Size of <hmac/password> */ + /* STRING(pw) <hmac/password> (if any) */ + + /* LOCKOUT PARAMETERS */ + /* tpm_u32(max_tries) Max tries (0, always lock) */ + /* tpm_u32(recovery_time) Recovery time (0, no lock) */ + /* tpm_u32(lockout_recovery) Lockout recovery */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + * - max tries + * - recovery time + * - lockout recovery + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "sddd", + offset, pw, pw_sz, + offset + pw_sz, max_tries, + offset + pw_sz + 4, recovery_time, + offset + pw_sz + 8, lockout_recovery); + offset += pw_sz + 12; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, + const char *oldpw, const ssize_t oldpw_sz) +{ + unsigned int offset = 27; + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(offset + oldpw_sz + 2 + newpw_sz), /* Length */ + tpm_u32(TPM2_CC_HIERCHANGEAUTH), /* Command code */ + + /* HANDLE */ + tpm_u32(handle), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + oldpw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* Session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(oldpw_sz) /* Size of <hmac/password> */ + /* STRING(oldpw) <hmac/password> (if any) */ + + /* TPM2B_AUTH (TPM2B_DIGEST) */ + /* tpm_u16(newpw_sz) Digest size, new pw length */ + /* STRING(newpw) Digest buffer, new pw */ + }; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the old password (if any) + * - size of the new password + * - new password + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", + offset, oldpw, oldpw_sz, + offset + oldpw_sz, newpw_sz, + offset + oldpw_sz + 2, newpw, newpw_sz); + offset += oldpw_sz + 2 + newpw_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +u32 tpm2_pcr_setauthpolicy(const char *pw, const ssize_t pw_sz, u32 index, + const char *key) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(35 + pw_sz + TPM2_DIGEST_LEN), /* Length */ + tpm_u32(TPM2_CC_PCR_SETAUTHPOL), /* Command code */ + + /* HANDLE */ + tpm_u32(TPM2_RH_PLATFORM), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz) /* Size of <hmac/password> */ + /* STRING(pw) <hmac/password> (if any) */ + + /* TPM2B_AUTH (TPM2B_DIGEST) */ + /* tpm_u16(TPM2_DIGEST_LEN) Digest size length */ + /* STRING(key) Digest buffer (PCR key) */ + + /* TPMI_ALG_HASH */ + /* tpm_u16(TPM2_ALG_SHA256) Algorithm of the hash */ + + /* TPMI_DH_PCR */ + /* tpm_u32(index), PCR Index */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + * - the PCR key length + * - the PCR key + * - the hash algorithm + * - the PCR index + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "swswd", + offset, pw, pw_sz, + offset + pw_sz, TPM2_DIGEST_LEN, + offset + pw_sz + 2, key, TPM2_DIGEST_LEN, + offset + pw_sz + 2 + TPM2_DIGEST_LEN, + TPM2_ALG_SHA256, + offset + pw_sz + 4 + TPM2_DIGEST_LEN, index); + offset += pw_sz + 2 + TPM2_DIGEST_LEN + 2 + 4; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +u32 tpm2_pcr_setauthvalue(const char *pw, const ssize_t pw_sz, u32 index, + const char *key, const ssize_t key_sz) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(33 + pw_sz + TPM2_DIGEST_LEN), /* Length */ + tpm_u32(TPM2_CC_PCR_SETAUTHVAL), /* Command code */ + + /* HANDLE */ + tpm_u32(index), /* Handle (PCR Index) */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* session handle */ + tpm_u16(0), /* Size of <nonce> */ + /* <nonce> (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz), /* Size of <hmac/password> */ + /* STRING(pw) <hmac/password> (if any) */ + + /* TPM2B_DIGEST */ + /* tpm_u16(key_sz) Key length */ + /* STRING(key) Key */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + * - the number of digests, 1 in our case + * - the algorithm, sha256 in our case + * - the digest (64 bytes) + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", + offset, pw, pw_sz, + offset + pw_sz, key_sz, + offset + pw_sz + 2, key, key_sz); + offset += pw_sz + 2 + key_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} |