diff options
author | André Draszik <adraszik@tycoint.com> | 2017-10-03 16:55:52 +0100 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2017-11-17 07:15:40 -0700 |
commit | 3c6050277b54f536e7effbe850dcc970a27387ab (patch) | |
tree | 0060f5315a771e64bff35445700b4db84d3a72f5 /lib/tpm.c | |
parent | e8155dfe33eb2b3e538e8717d6578c1d08651454 (diff) | |
download | u-boot-3c6050277b54f536e7effbe850dcc970a27387ab.tar.gz |
tpm: add tpm_get_random()
Add a function to obtain random data from the TPM.
Signed-off-by: André Draszik <adraszik@tycoint.com>
Added commit message, add cast to min()
Signed-off-by: Simon Glass <sjg@chromium.org>
Acked-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib/tpm.c')
-rw-r--r-- | lib/tpm.c | 43 |
1 files changed, 43 insertions, 0 deletions
@@ -1049,3 +1049,46 @@ uint32_t tpm_find_key_sha1(const uint8_t auth[20], const uint8_t #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */ #endif /* CONFIG_TPM_AUTH_SESSIONS */ + +uint32_t tpm_get_random(void *data, uint32_t count) +{ + const uint8_t 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; + uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE]; + size_t response_length = sizeof(response); + uint32_t data_size; + uint8_t *out = data; + + while (count > 0) { + uint32_t this_bytes = min((size_t)count, + sizeof (response) - data_offset); + uint32_t 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; +} |