diff options
author | Luigi Semenzato <semenzato@chromium.org> | 2013-01-11 15:50:39 -0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-01-11 18:15:14 -0800 |
commit | 3428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3 (patch) | |
tree | 3270eaffc59874e813f195f026a1147ef8acd718 | |
parent | 17f8d341099120da78a6ca71165834eefb0960ed (diff) | |
download | vboot-3428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3.tar.gz |
Make tpmc able to send and receive raw datagrams.
This is immediately needed to debug a Parrot TPM problems, but
we've had similar situation in the past and probably will again
in the future.
BUG=chromium-os:37819
TEST=manually tested with a couple of different packets, and error inputs
BRANCH=none
Change-Id: Id7f66bdbdfe5887fa49cd62af4a9b807fa3d9a89
Reviewed-on: https://gerrit.chromium.org/gerrit/41166
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Commit-Queue: Luigi Semenzato <semenzato@chromium.org>
Tested-by: Luigi Semenzato <semenzato@chromium.org>
-rw-r--r-- | firmware/include/tlcl.h | 13 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/tlcl.c | 9 | ||||
-rw-r--r-- | utility/tpmc.c | 44 |
3 files changed, 64 insertions, 2 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h index 682bc86b..cd82fdca 100644 --- a/firmware/include/tlcl.h +++ b/firmware/include/tlcl.h @@ -33,6 +33,19 @@ void TlclLog(char* format, ...); */ void TlclSetLogLevel(int level); +/* Low-level operations */ + +/* Performs a raw TPM request/response transaction. + */ +uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, + int max_length); + +/* Returns the size of a TPM request or response packet. + */ +int TlclPacketSize(const uint8_t* packet); + +/* Commands */ + /* Sends a TPM_Startup(ST_CLEAR). The TPM error code is returned (0 * for success). */ diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c index 9a0801f5..332fd019 100644 --- a/firmware/lib/tpm_lite/tlcl.c +++ b/firmware/lib/tpm_lite/tlcl.c @@ -33,6 +33,11 @@ POSSIBLY_UNUSED static INLINE int TpmCommandSize(const uint8_t* buffer) { return (int) size; } +/* Gets the size field of a TPM request or response. */ +int TlclPacketSize(const uint8_t* packet) { + return TpmCommandSize(packet); +} + /* Gets the code field of a TPM command. */ static INLINE int TpmCommandCode(const uint8_t* buffer) { uint32_t code; @@ -93,8 +98,8 @@ static uint32_t TlclSendReceiveNoRetry(const uint8_t* request, /* Sends a TPM command and gets a response. Returns 0 if success or the TPM * error code if error. In the firmware, waits for the self test to complete * if needed. In the host, reports the first error without retries. */ -static uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, - int max_length) { +uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, + int max_length) { uint32_t result = TlclSendReceiveNoRetry(request, response, max_length); /* When compiling for the firmware, hide command failures due to the self * test not having run or completed. */ diff --git a/utility/tpmc.c b/utility/tpmc.c index c1a97f4b..898e2552 100644 --- a/utility/tpmc.c +++ b/utility/tpmc.c @@ -317,6 +317,48 @@ static uint32_t HandlerGetSTClearFlags(void) { } +static uint32_t HandlerSendRaw(void) { + uint8_t request[4096]; + uint8_t response[4096]; + uint32_t result; + int size; + int i; + if (nargs == 2) { + fprintf(stderr, "usage: tpmc sendraw <hex byte 0> ... <hex byte N>\n"); + exit(OTHER_ERROR); + } + for (i = 0; i < nargs - 2 && i < sizeof(request); i++) { + if (HexStringToUint8(args[2 + i], &request[i]) != 0) { + fprintf(stderr, "bad byte value \"%s\"\n", args[2 + i]); + exit(OTHER_ERROR); + } + } + size = TlclPacketSize(request); + if (size != i) { + fprintf(stderr, "bad request: size field is %d, but packet has %d bytes\n", + size, i); + exit(OTHER_ERROR); + } + bzero(response, sizeof(response)); + result = TlclSendReceive(request, response, sizeof(response)); + if (result != 0) { + fprintf(stderr, "request failed with code %d\n", result); + } + size = TlclPacketSize(response); + if (size < 10 || size > sizeof(response)) { + fprintf(stderr, "unexpected response size %d\n", size); + exit(OTHER_ERROR); + } + for (i = 0; i < size; i++) { + printf("0x%02x ", response[i]); + if (i == size - 1 || (i + 1) % 8 == 0) { + printf("\n"); + } + } + return result; +} + + /* Table of TPM commands. */ command_record command_table[] = { @@ -363,6 +405,8 @@ command_record command_table[] = { HandlerGetSTClearFlags }, { "resume", "res", "execute TPM_Startup(ST_STATE)", TlclResume }, { "savestate", "save", "execute TPM_SaveState", TlclSaveState }, + { "sendraw", "raw", "send a raw request and print raw response", + HandlerSendRaw }, }; static int n_commands = sizeof(command_table) / sizeof(command_table[0]); |