diff options
-rw-r--r-- | firmware/include/tlcl.h | 7 | ||||
-rw-r--r-- | firmware/include/tss_constants.h | 3 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/include/tlcl_structures.h | 6 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/tlcl.c | 33 | ||||
-rw-r--r-- | utility/tlcl_generator.c | 11 | ||||
-rw-r--r-- | utility/tpmc.c | 33 |
6 files changed, 88 insertions, 5 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h index 6f0db1b6..c8632e43 100644 --- a/firmware/include/tlcl.h +++ b/firmware/include/tlcl.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -150,4 +150,9 @@ uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS* pflags); */ uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS* pflags); +/* Requests [length] bytes from TPM RNG to be stored in [data]. Actual + * number of bytes read is stored in [size]. The TPM error code is returned. + */ +uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t* size); + #endif /* TPM_LITE_TLCL_H_ */ diff --git a/firmware/include/tss_constants.h b/firmware/include/tss_constants.h index 68a9c6ff..b28c3c60 100644 --- a/firmware/include/tss_constants.h +++ b/firmware/include/tss_constants.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -36,6 +36,7 @@ #define TPM_E_MUST_REBOOT ((uint32_t)0x00005002) /* vboot local */ #define TPM_E_CORRUPTED_STATE ((uint32_t)0x00005003) /* vboot local */ #define TPM_E_COMMUNICATION_ERROR ((uint32_t)0x00005004) /* vboot local */ +#define TPM_E_RESPONSE_TOO_LARGE ((uint32_t)0x00005005) /* vboot local */ #define TPM_NV_INDEX0 ((uint32_t)0x00000000) #define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff) diff --git a/firmware/lib/tpm_lite/include/tlcl_structures.h b/firmware/lib/tpm_lite/include/tlcl_structures.h index e0a7a46b..c4d80ba3 100644 --- a/firmware/lib/tpm_lite/include/tlcl_structures.h +++ b/firmware/lib/tpm_lite/include/tlcl_structures.h @@ -7,6 +7,12 @@ const struct s_tpm_extend_cmd{ } tpm_extend_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14, }, 10, 14, }; +const struct s_tpm_get_random_cmd{ + uint8_t buffer[14]; + uint16_t bytesRequested; +} tpm_get_random_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x46, }, +10, }; + const struct s_tpm_getpermissions_cmd{ uint8_t buffer[22]; uint16_t index; diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c index 338e2f67..9e9ece84 100644 --- a/firmware/lib/tpm_lite/tlcl.c +++ b/firmware/lib/tpm_lite/tlcl.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -396,3 +396,34 @@ uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) { FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions); return result; } + +uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size) { + struct s_tpm_get_random_cmd cmd; + uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; + uint32_t result; + + VBDEBUG(("TPM: TlclGetRandom(%d)\n", length)); + Memcpy(&cmd, &tpm_get_random_cmd, sizeof(cmd)); + ToTpmUint32(cmd.buffer + tpm_get_random_cmd.bytesRequested, length); + /* There must be room in the response buffer for the bytes. */ + if (length > TPM_LARGE_ENOUGH_COMMAND_SIZE - kTpmResponseHeaderLength + - sizeof(uint32_t)) { + return TPM_E_IOERROR; + } + + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result == TPM_SUCCESS) { + uint8_t* get_random_cursor; + FromTpmUint32(response + kTpmResponseHeaderLength, size); + + /* There must be room in the target buffer for the bytes. */ + if (*size > length) { + return TPM_E_RESPONSE_TOO_LARGE; + } + get_random_cursor = response + kTpmResponseHeaderLength + + sizeof(uint32_t); + Memcpy(data, get_random_cursor, *size); + } + + return result; +} diff --git a/utility/tlcl_generator.c b/utility/tlcl_generator.c index f905784f..bbc379c1 100644 --- a/utility/tlcl_generator.c +++ b/utility/tlcl_generator.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -362,6 +362,14 @@ Command* BuildGetPermissionsCommand(void) { return cmd; } +Command* BuildGetRandomCommand(void) { + int size = kTpmRequestHeaderLength + sizeof(uint32_t); + Command* cmd = newCommand(TPM_ORD_GetRandom, size); + cmd->name = "tpm_get_random_cmd"; + AddVisibleField(cmd, "bytesRequested", kTpmRequestHeaderLength); + return cmd; +} + /* Output the fields of a structure. */ void OutputFields(Field* fld) { @@ -480,6 +488,7 @@ Command* (*builders[])(void) = { BuildGetFlagsCommand, BuildGetSTClearFlagsCommand, BuildGetPermissionsCommand, + BuildGetRandomCommand, BuildExtendCommand, }; diff --git a/utility/tpmc.c b/utility/tpmc.c index d8fb07a5..68ce6d3f 100644 --- a/utility/tpmc.c +++ b/utility/tpmc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -228,6 +228,35 @@ static uint32_t HandlerGetPermissions(void) { return result; } +static uint32_t HandlerGetRandom(void) { + uint32_t length, size; + uint8_t* bytes; + uint32_t result; + int i; + if (nargs != 3) { + fprintf(stderr, "usage: tpmc getrandom <size>\n"); + exit(OTHER_ERROR); + } + if (HexStringToUint32(args[2], &length) != 0) { + fprintf(stderr, "<size> must be 32-bit hex (0x[0-9a-f]+)\n"); + exit(OTHER_ERROR); + } + bytes = calloc(1, length); + if (bytes == NULL) { + perror("calloc"); + exit(OTHER_ERROR); + } + result = TlclGetRandom(bytes, length, &size); + if (result == 0 && size > 0) { + for (i = 0; i < size; i++) { + printf("%02x", bytes[i]); + } + printf("\n"); + } + free(bytes); + return result; +} + static uint32_t HandlerGetPermanentFlags(void) { TPM_PERMANENT_FLAGS pflags; uint32_t result = TlclGetPermanentFlags(&pflags); @@ -312,6 +341,8 @@ command_record command_table[] = { HandlerGetPermissions }, { "getpermanentflags", "getpf", "print all permanent flags", HandlerGetPermanentFlags }, + { "getrandom", "rand", "read bytes from RNG (rand <size>)", + HandlerGetRandom }, { "getstclearflags", "getvf", "print all volatile (ST_CLEAR) flags", HandlerGetSTClearFlags }, { "resume", "res", "execute TPM_Startup(ST_STATE)", TlclResume }, |