From 205190d4ae8080298d9d1b580dd95c885f2af42c Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Thu, 5 Aug 2010 15:55:06 -0700 Subject: Pay attention to TPM communication errors BUG=none TEST=make && make runtests Review URL: http://codereview.chromium.org/3078028 --- firmware/lib/tpm_lite/include/tlcl.h | 9 +-- firmware/lib/tpm_lite/include/tss_constants.h | 1 + firmware/lib/tpm_lite/tlcl.c | 84 ++++++++++++--------------- 3 files changed, 44 insertions(+), 50 deletions(-) (limited to 'firmware/lib/tpm_lite') diff --git a/firmware/lib/tpm_lite/include/tlcl.h b/firmware/lib/tpm_lite/include/tlcl.h index 6875619e..2812a5b1 100644 --- a/firmware/lib/tpm_lite/include/tlcl.h +++ b/firmware/lib/tpm_lite/include/tlcl.h @@ -26,8 +26,10 @@ void TlclStubInit(void); void TlclCloseDevice(void); void TlclOpenDevice(void); -void TlclStubSendReceive(uint8_t* request, int request_length, - uint8_t* response, int max_length); +/* Send data to the TPM and receive a response. Returns 0 if success, + * nonzero if error. */ +uint32_t TlclStubSendReceive(uint8_t* request, int request_length, + uint8_t* response, int max_length); /*****************************************************************************/ /* Functions implemented in tlcl.c */ @@ -36,7 +38,6 @@ void TlclStubSendReceive(uint8_t* request, int request_length, */ void TlclLibInit(void); - /* Logs to stdout. Arguments like printf. */ void TlclLog(char* format, ...); @@ -116,7 +117,7 @@ uint32_t TlclClearEnable(void); uint32_t TlclSetDeactivated(uint8_t flag); /* Gets flags of interest. Pointers for flags you aren't interested in may - * be NULL. The TPM error code is returned. + * be NULL. The TPM error code is returned. */ uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated, uint8_t* nvlocked); diff --git a/firmware/lib/tpm_lite/include/tss_constants.h b/firmware/lib/tpm_lite/include/tss_constants.h index aaeacbea..cf2062ba 100644 --- a/firmware/lib/tpm_lite/include/tss_constants.h +++ b/firmware/lib/tpm_lite/include/tss_constants.h @@ -23,6 +23,7 @@ #define TPM_E_INTERNAL_INCONSISTENCY ((uint32_t)0x00005001) /* vboot local */ #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_NV_INDEX0 ((uint32_t)0x00000000) #define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff) diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c index 21966457..94a28286 100644 --- a/firmware/lib/tpm_lite/tlcl.c +++ b/firmware/lib/tpm_lite/tlcl.c @@ -45,21 +45,12 @@ static INLINE int TpmReturnCode(const uint8_t* buffer) { return TpmCommandCode(buffer); } -/* Checks for errors in a TPM response. */ -static void CheckResult(uint8_t* request, uint8_t* response, int warn_only) { - int command = TpmCommandCode(request); - int result = TpmReturnCode(response); - if (result != TPM_SUCCESS) { - if (warn_only) - VBDEBUG(("TPM: command 0x%x failed: 0x%x\n", command, result)); - else - error("TPM: command 0x%x failed: 0x%x\n", command, result); - } -} +/* Sends a TPM command and gets a response. Returns 0 if success or the TPM + * error code if error. */ +static uint32_t TlclSendReceive(uint8_t* request, uint8_t* response, + int max_length) { -/* Sends a TPM command and gets a response. */ -static void TlclSendReceive(uint8_t* request, uint8_t* response, - int max_length) { + uint32_t result; #ifdef EXTRA_LOGGING VBDEBUG(("TPM: command: %x%x %x%x%x%x %x%x%x%x\n", @@ -68,8 +59,16 @@ static void TlclSendReceive(uint8_t* request, uint8_t* response, request[6], request[7], request[8], request[9])); #endif - TlclStubSendReceive(request, TpmCommandSize(request), - response, max_length); + result = TlclStubSendReceive(request, TpmCommandSize(request), + response, max_length); + if (0 != result) { + /* Communication with TPM failed, so response is garbage */ + VBDEBUG(("TPM: command 0x%x send/receive failed: 0x%x\n", + TpmCommandCode(request), result)); + return TPM_E_COMMUNICATION_ERROR; + } + /* Otherwise, use the result code from the response */ + result = TpmReturnCode(response); #ifdef EXTRA_LOGGING VBDEBUG(("TPM: response: %x%x %x%x%x%x %x%x%x%x\n", @@ -78,21 +77,17 @@ static void TlclSendReceive(uint8_t* request, uint8_t* response, response[6], response[7], response[8], response[9])); #endif -#ifdef VBOOT_DEBUG - { - int command = TpmCommandCode(request); - int result = TpmReturnCode(response); - VBDEBUG(("TPM: command 0x%x returned 0x%x\n", command, result)); - } -#endif + VBDEBUG(("TPM: command 0x%x returned 0x%x\n", + TpmCommandCode(request), result)); + + return result; } /* Sends a command and returns the error code. */ static uint32_t Send(uint8_t* command) { uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; - TlclSendReceive(command, response, sizeof(response)); - return TpmReturnCode(response); + return TlclSendReceive(command, response, sizeof(response)); } /* Exported functions. */ @@ -141,10 +136,7 @@ uint32_t TlclWrite(uint32_t index, uint8_t* data, uint32_t length) { ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.length, length); Memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length); - TlclSendReceive(cmd.buffer, response, sizeof(response)); - CheckResult(cmd.buffer, response, 1); - - return TpmReturnCode(response); + return TlclSendReceive(cmd.buffer, response, sizeof(response)); } uint32_t TlclRead(uint32_t index, uint8_t* data, uint32_t length) { @@ -158,8 +150,7 @@ uint32_t TlclRead(uint32_t index, uint8_t* data, uint32_t length) { ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.index, index); ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.length, length); - TlclSendReceive(cmd.buffer, response, sizeof(response)); - result = TpmReturnCode(response); + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); if (result == TPM_SUCCESS && length > 0) { uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength; FromTpmUint32(nv_read_cursor, &result_length); @@ -187,8 +178,7 @@ uint32_t TlclAssertPhysicalPresence(void) { uint32_t TlclAssertPhysicalPresenceResult(void) { uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; - TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response)); - return TpmReturnCode(response); + return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response)); } uint32_t TlclLockPhysicalPresence(void) { @@ -204,8 +194,7 @@ uint32_t TlclSetNvLocked(void) { int TlclIsOwned(void) { uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE]; uint32_t result; - TlclSendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response)); - result = TpmReturnCode(response); + result = TlclSendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response)); return (result != TPM_SUCCESS); } @@ -239,11 +228,10 @@ uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated, uint8_t *nvlocked) uint32_t size; VBDEBUG(("TPM: Get flags\n")); - TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response)); - result = TpmReturnCode(response); - if (result != TPM_SUCCESS) { + result = TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) return result; - } + FromTpmUint32(response + kTpmResponseHeaderLength, &size); assert(size == sizeof(TPM_PERMANENT_FLAGS)); pflags = @@ -261,20 +249,25 @@ uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated, uint8_t *nvlocked) uint32_t TlclSetGlobalLock(void) { uint32_t x; - VBDEBUG(("TPM: Set Set global lock\n")); + VBDEBUG(("TPM: Set global lock\n")); return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); } uint32_t TlclExtend(int pcr_num, uint8_t* in_digest, uint8_t* out_digest) { struct s_tpm_extend_cmd cmd; uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength]; + uint32_t result; Memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd)); ToTpmUint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num); Memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength); - TlclSendReceive(cmd.buffer, response, sizeof(response)); + + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) + return result; + Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength); - return TpmReturnCode(response); + return result; } uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) { @@ -286,11 +279,10 @@ uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) { Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index); - TlclSendReceive(cmd.buffer, response, sizeof(response)); - result = TpmReturnCode(response); - if (result != TPM_SUCCESS) { + result = TlclSendReceive(cmd.buffer, response, sizeof(response)); + if (result != TPM_SUCCESS) return result; - } + nvdata = response + kTpmResponseHeaderLength + sizeof(size); FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions); return result; -- cgit v1.2.1