Commit 3c6050277b54f536e7effbe850dcc970a27387ab

Authored by André Draszik
Committed by Simon Glass
1 parent e8155dfe33

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>

Showing 2 changed files with 55 additions and 0 deletions Side-by-side Diff

... ... @@ -651,5 +651,17 @@
651 651 uint32_t tpm_find_key_sha1(const uint8_t auth[20], const uint8_t
652 652 pubkey_digest[20], uint32_t *handle);
653 653 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
  654 +
  655 +/**
  656 + * Read random bytes from the TPM RNG. The implementation deals with the fact
  657 + * that the TPM may legally return fewer bytes than requested by retrying
  658 + * until @p count bytes have been received.
  659 + *
  660 + * @param data output buffer for the random bytes
  661 + * @param count size of output buffer
  662 + * @return return code of the operation
  663 + */
  664 +uint32_t tpm_get_random(void *data, uint32_t count);
  665 +
654 666 #endif /* __TPM_H */
... ... @@ -1049,4 +1049,47 @@
1049 1049 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
1050 1050  
1051 1051 #endif /* CONFIG_TPM_AUTH_SESSIONS */
  1052 +
  1053 +uint32_t tpm_get_random(void *data, uint32_t count)
  1054 +{
  1055 + const uint8_t command[14] = {
  1056 + 0x0, 0xc1, /* TPM_TAG */
  1057 + 0x0, 0x0, 0x0, 0xe, /* parameter size */
  1058 + 0x0, 0x0, 0x0, 0x46, /* TPM_COMMAND_CODE */
  1059 + };
  1060 + const size_t length_offset = 10;
  1061 + const size_t data_size_offset = 10;
  1062 + const size_t data_offset = 14;
  1063 + uint8_t buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
  1064 + size_t response_length = sizeof(response);
  1065 + uint32_t data_size;
  1066 + uint8_t *out = data;
  1067 +
  1068 + while (count > 0) {
  1069 + uint32_t this_bytes = min((size_t)count,
  1070 + sizeof (response) - data_offset);
  1071 + uint32_t err;
  1072 +
  1073 + if (pack_byte_string(buf, sizeof(buf), "sd",
  1074 + 0, command, sizeof(command),
  1075 + length_offset, this_bytes))
  1076 + return TPM_LIB_ERROR;
  1077 + err = tpm_sendrecv_command(buf, response, &response_length);
  1078 + if (err)
  1079 + return err;
  1080 + if (unpack_byte_string(response, response_length, "d",
  1081 + data_size_offset, &data_size))
  1082 + return TPM_LIB_ERROR;
  1083 + if (data_size > count)
  1084 + return TPM_LIB_ERROR;
  1085 + if (unpack_byte_string(response, response_length, "s",
  1086 + data_offset, out, data_size))
  1087 + return TPM_LIB_ERROR;
  1088 +
  1089 + count -= data_size;
  1090 + out += data_size;
  1091 + }
  1092 +
  1093 + return 0;
  1094 +}