]> git.sur5r.net Git - u-boot/blobdiff - lib/tpm.c
tpm: align arguments with open parenthesis
[u-boot] / lib / tpm.c
index 967c8e65150a354a098db3c8196db6e4cc129f5c..931b45301d6e9ffde82b29beb4eba7e223a60ca5 100644 (file)
--- a/lib/tpm.c
+++ b/lib/tpm.c
@@ -1,23 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (c) 2013 The Chromium OS Authors.
  * Coypright (c) 2013 Guntermann & Drunck GmbH
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-#include <stdarg.h>
-#include <sha1.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)
+#define TPM_LIB_ERROR  ((u32)~0u)
 
 /* Useful constants */
 enum {
        COMMAND_BUFFER_SIZE             = 256,
-       TPM_PUBEK_SIZE                  = 256,
        TPM_REQUEST_HEADER_LENGTH       = 10,
        TPM_RESPONSE_HEADER_LENGTH      = 10,
        PCR_DIGEST_LENGTH               = 20,
@@ -37,9 +35,9 @@ 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, };
@@ -61,12 +59,12 @@ static struct session_data oiap_session = {0, };
  * @param ...          data points
  * @return 0 on success, non-0 on error
  */
-int pack_byte_string(uint8_t *str, size_t size, const char *format, ...)
+int pack_byte_string(u8 *str, size_t size, const char *format, ...)
 {
        va_list args;
        size_t offset = 0, length = 0;
-       uint8_t *data = NULL;
-       uint32_t value = 0;
+       u8 *data = NULL;
+       u32 value = 0;
 
        va_start(args, format);
        for (; *format; format++) {
@@ -83,21 +81,24 @@ int pack_byte_string(uint8_t *str, size_t size, const char *format, ...)
                        break;
                case 'd':
                        offset = va_arg(args, size_t);
-                       value = va_arg(args, uint32_t);
+                       value = va_arg(args, u32);
                        length = 4;
                        break;
                case 's':
                        offset = va_arg(args, size_t);
-                       data = va_arg(args, uint8_t *);
-                       length = va_arg(args, uint32_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)
+               if (offset + length > size) {
+                       va_end(args);
                        return -1;
+               }
 
                switch (*format) {
                case 'b':
@@ -132,44 +133,47 @@ int pack_byte_string(uint8_t *str, size_t size, const char *format, ...)
  * @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, ...)
+int unpack_byte_string(const u8 *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;
+       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, uint8_t *);
+                       ptr8 = va_arg(args, u8 *);
                        length = 1;
                        break;
                case 'w':
                        offset = va_arg(args, size_t);
-                       ptr16 = va_arg(args, uint16_t *);
+                       ptr16 = va_arg(args, u16 *);
                        length = 2;
                        break;
                case 'd':
                        offset = va_arg(args, size_t);
-                       ptr32 = va_arg(args, uint32_t *);
+                       ptr32 = va_arg(args, u32 *);
                        length = 4;
                        break;
                case 's':
                        offset = va_arg(args, size_t);
-                       ptr8 = va_arg(args, uint8_t *);
-                       length = va_arg(args, uint32_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)
+               if (offset + length > size) {
+                       va_end(args);
                        return -1;
+               }
 
                switch (*format) {
                case 'b':
@@ -197,7 +201,7 @@ int unpack_byte_string(const uint8_t *str, size_t size, const char *format, ...)
  * @param command      byte string of TPM command
  * @return command size of the TPM command
  */
-static uint32_t tpm_command_size(const void *command)
+static u32 tpm_command_size(const void *command)
 {
        const size_t command_size_offset = 2;
        return get_unaligned_be32(command + command_size_offset);
@@ -209,7 +213,7 @@ static uint32_t tpm_command_size(const void *command)
  * @param response     byte string of TPM response
  * @return return code of the TPM response
  */
-static uint32_t tpm_return_code(const void *response)
+static u32 tpm_return_code(const void *response)
 {
        const size_t return_code_offset = 6;
        return get_unaligned_be32(response + return_code_offset);
@@ -227,12 +231,13 @@ static uint32_t tpm_return_code(const void *response)
  *                     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)
+static u32 tpm_sendrecv_command(const void *command, void *response,
+                               size_t *size_ptr)
 {
-       uint8_t response_buffer[COMMAND_BUFFER_SIZE];
+       struct udevice *dev;
+       int err, ret;
+       u8 response_buffer[COMMAND_BUFFER_SIZE];
        size_t response_length;
-       uint32_t err;
 
        if (response) {
                response_length = *size_ptr;
@@ -240,9 +245,14 @@ static uint32_t tpm_sendrecv_command(const void *command,
                response = response_buffer;
                response_length = sizeof(response_buffer);
        }
-       err = tis_sendrecv(command, tpm_command_size(command),
-                       response, &response_length);
-       if (err)
+
+       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;
@@ -250,52 +260,52 @@ static uint32_t tpm_sendrecv_command(const void *command,
        return tpm_return_code(response);
 }
 
-uint32_t tpm_init(void)
+int tpm_init(void)
 {
-       uint32_t err;
+       int err;
+       struct udevice *dev;
 
-       err = tis_init();
+       err = uclass_first_device_err(UCLASS_TPM, &dev);
        if (err)
                return err;
-
-       return tis_open();
+       return tpm_open(dev);
 }
 
-uint32_t tpm_startup(enum tpm_startup_type mode)
+u32 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 */
@@ -324,55 +334,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;
@@ -380,18 +390,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)
@@ -400,99 +410,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;
@@ -500,59 +510,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 */
@@ -564,31 +573,120 @@ 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;
+}
+
+u32 tpm_get_permanent_flags(struct tpm_permanent_flags *pflags)
+{
+       const u8 command[22] = {
+               0x0, 0xc1,              /* TPM_TAG */
+               0x0, 0x0, 0x0, 0x16,    /* parameter size */
+               0x0, 0x0, 0x0, 0x65,    /* TPM_COMMAND_CODE */
+               0x0, 0x0, 0x0, 0x4,     /* TPM_CAP_FLAG_PERM */
+               0x0, 0x0, 0x0, 0x4,     /* subcap size */
+               0x0, 0x0, 0x1, 0x8,     /* subcap value */
+       };
+       const size_t data_size_offset = TPM_HEADER_SIZE;
+       const size_t data_offset = TPM_HEADER_SIZE + sizeof(u32);
+       u8 response[COMMAND_BUFFER_SIZE];
+       size_t response_length = sizeof(response);
+       u32 err;
+       u32 data_size;
+
+       err = tpm_sendrecv_command(command, response, &response_length);
+       if (err)
+               return err;
+       if (unpack_byte_string(response, response_length, "d",
+                              data_size_offset, &data_size))
+               return TPM_LIB_ERROR;
+       if (data_size < sizeof(*pflags))
+               return TPM_LIB_ERROR;
+       if (unpack_byte_string(response, response_length, "s",
+                              data_offset, pflags, sizeof(*pflags)))
+               return TPM_LIB_ERROR;
+
+       return 0;
+}
+
+u32 tpm_get_permissions(u32 index, u32 *perm)
+{
+       const u8 command[22] = {
+               0x0, 0xc1,              /* TPM_TAG */
+               0x0, 0x0, 0x0, 0x16,    /* parameter size */
+               0x0, 0x0, 0x0, 0x65,    /* TPM_COMMAND_CODE */
+               0x0, 0x0, 0x0, 0x11,
+               0x0, 0x0, 0x0, 0x4,
+       };
+       const size_t index_offset = 18;
+       const size_t perm_offset = 60;
+       u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+       size_t response_length = sizeof(response);
+       u32 err;
+
+       if (pack_byte_string(buf, sizeof(buf), "d", 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, "d",
+                              perm_offset, perm))
                return TPM_LIB_ERROR;
 
        return 0;
 }
 
+#ifdef CONFIG_TPM_FLUSH_RESOURCES
+u32 tpm_flush_specific(u32 key_handle, u32 resource_type)
+{
+       const u8 command[18] = {
+               0x00, 0xc1,             /* TPM_TAG */
+               0x00, 0x00, 0x00, 0x12, /* parameter size */
+               0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
+               0x00, 0x00, 0x00, 0x00, /* key handle */
+               0x00, 0x00, 0x00, 0x00, /* resource type */
+       };
+       const size_t key_handle_offset = 10;
+       const size_t resource_type_offset = 14;
+       u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+       size_t response_length = sizeof(response);
+       u32 err;
+
+       if (pack_byte_string(buf, sizeof(buf), "sdd",
+                            0, command, sizeof(command),
+                            key_handle_offset, key_handle,
+                            resource_type_offset, resource_type))
+               return TPM_LIB_ERROR;
+
+       err = tpm_sendrecv_command(buf, response, &response_length);
+       if (err)
+               return err;
+       return 0;
+}
+#endif /* CONFIG_TPM_FLUSH_RESOURCES */
+
 #ifdef CONFIG_TPM_AUTH_SESSIONS
 
 /**
@@ -603,12 +701,12 @@ uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
  * @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;
@@ -666,19 +764,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)
-{
-       uint8_t hmac_data[DIGEST_LENGTH * 3 + 1];
-       uint8_t computed_auth[DIGEST_LENGTH];
+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)
+{
+       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;
@@ -699,7 +796,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,
@@ -721,10 +818,9 @@ 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 */
@@ -732,7 +828,7 @@ uint32_t tpm_terminate_auth_session(uint32_t auth_handle)
                0x00, 0x00, 0x00, 0x02, /* TPM_RESSOURCE_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),
@@ -744,26 +840,26 @@ 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);
@@ -774,7 +870,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)
@@ -782,12 +878,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 */
@@ -797,11 +891,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);
@@ -819,9 +913,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);
@@ -832,10 +926,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;
 
@@ -848,10 +943,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 */
@@ -860,11 +955,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);
@@ -874,13 +969,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);
@@ -890,16 +985,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;
@@ -911,4 +1007,87 @@ uint32_t tpm_get_pub_key_oiap(uint32_t key_handle, const void *usage_auth,
        return 0;
 }
 
+#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
+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;
+
+       /* fetch list of already loaded keys in the TPM */
+       err = tpm_get_capability(TPM_CAP_HANDLE, TPM_RT_KEY, buf, sizeof(buf));
+       if (err)
+               return -1;
+       key_count = get_unaligned_be16(buf);
+       ptr = buf + 2;
+       for (i = 0; i < key_count; ++i, ptr += 4)
+               key_handles[i] = get_unaligned_be32(ptr);
+
+       /* now search a(/ the) key which we can access with the given auth */
+       for (i = 0; i < key_count; ++i) {
+               buf_len = sizeof(buf);
+               err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
+               if (err && err != TPM_AUTHFAIL)
+                       return -1;
+               if (err)
+                       continue;
+               sha1_csum(buf, buf_len, digest);
+               if (!memcmp(digest, pubkey_digest, 20)) {
+                       *handle = key_handles[i];
+                       return 0;
+               }
+       }
+       return 1;
+}
+#endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
+
 #endif /* CONFIG_TPM_AUTH_SESSIONS */
+
+u32 tpm_get_random(void *data, u32 count)
+{
+       const u8 command[14] = {
+               0x0, 0xc1,              /* TPM_TAG */
+               0x0, 0x0, 0x0, 0xe,     /* parameter size */
+               0x0, 0x0, 0x0, 0x46,    /* TPM_COMMAND_CODE */
+       };
+       const size_t length_offset = 10;
+       const size_t data_size_offset = 10;
+       const size_t data_offset = 14;
+       u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
+       size_t response_length = sizeof(response);
+       u32 data_size;
+       u8 *out = data;
+
+       while (count > 0) {
+               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),
+                                    length_offset, this_bytes))
+                       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))
+                       return TPM_LIB_ERROR;
+               if (data_size > count)
+                       return TPM_LIB_ERROR;
+               if (unpack_byte_string(response, response_length, "s",
+                                      data_offset, out, data_size))
+                       return TPM_LIB_ERROR;
+
+               count -= data_size;
+               out += data_size;
+       }
+
+       return 0;
+}