Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* Copyright (c) 2010-2011 The Chromium OS Authors. All rights reserved. | 1 /* Copyright (c) 2010-2011 The Chromium OS Authors. All rights reserved. |
| 2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 */ | 4 */ |
| 5 | 5 |
| 6 /* A lightweight TPM command library. | 6 /* A lightweight TPM command library. |
| 7 * | 7 * |
| 8 * The general idea is that TPM commands are array of bytes whose | 8 * The general idea is that TPM commands are array of bytes whose |
| 9 * fields are mostly compile-time constant. The goal is to build much | 9 * fields are mostly compile-time constant. The goal is to build much |
| 10 * of the commands at compile time (or build time) and change some of | 10 * of the commands at compile time (or build time) and change some of |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 uint32_t code; | 37 uint32_t code; |
| 38 FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code); | 38 FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code); |
| 39 return code; | 39 return code; |
| 40 } | 40 } |
| 41 | 41 |
| 42 /* Gets the return code field of a TPM result. */ | 42 /* Gets the return code field of a TPM result. */ |
| 43 static INLINE int TpmReturnCode(const uint8_t* buffer) { | 43 static INLINE int TpmReturnCode(const uint8_t* buffer) { |
| 44 return TpmCommandCode(buffer); | 44 return TpmCommandCode(buffer); |
| 45 } | 45 } |
| 46 | 46 |
| 47 /* Sends a TPM command and gets a response. Returns 0 if success or the TPM | 47 /* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or |
| 48 * error code if error. */ | 48 * DOING_SELFTEST errors are returned. |
| 49 static uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, | 49 */ |
| 50 int max_length) { | 50 static uint32_t TlclSendReceiveNoRetry(const uint8_t* request, |
| 51 | 51 uint8_t* response, int max_length) { |
| 52 uint32_t result; | 52 uint32_t result; |
| 53 | 53 |
| 54 #ifdef EXTRA_LOGGING | 54 #ifdef EXTRA_LOGGING |
| 55 VBDEBUG(("TPM: command: %x%x %x%x%x%x %x%x%x%x\n", | 55 VBDEBUG(("TPM: command: %x%x %x%x%x%x %x%x%x%x\n", |
| 56 request[0], request[1], | 56 request[0], request[1], |
| 57 request[2], request[3], request[4], request[5], | 57 request[2], request[3], request[4], request[5], |
| 58 request[6], request[7], request[8], request[9])); | 58 request[6], request[7], request[8], request[9])); |
| 59 #endif | 59 #endif |
| 60 | 60 |
| 61 result = TlclStubSendReceive(request, TpmCommandSize(request), | 61 result = TlclStubSendReceive(request, TpmCommandSize(request), |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 76 response[6], response[7], response[8], response[9])); | 76 response[6], response[7], response[8], response[9])); |
| 77 #endif | 77 #endif |
| 78 | 78 |
| 79 VBDEBUG(("TPM: command 0x%x returned 0x%x\n", | 79 VBDEBUG(("TPM: command 0x%x returned 0x%x\n", |
| 80 TpmCommandCode(request), result)); | 80 TpmCommandCode(request), result)); |
| 81 | 81 |
| 82 return result; | 82 return result; |
| 83 } | 83 } |
| 84 | 84 |
| 85 | 85 |
| 86 /* Sends a TPM command and gets a response. Returns 0 if success or the TPM | |
| 87 * error code if error. Waits for self test to complete if needed. */ | |
| 88 static uint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, | |
| 89 int max_length) { | |
| 90 uint32_t result = TlclSendReceiveNoRetry(request, response, max_length); | |
| 91 /* When compiling for the firmware, hide command failures due to the self | |
|
Randall Spangler
2011/03/16 23:23:43
???
When compiling for the firmware, we look at t
| |
| 92 * test not having run or completed. */ | |
| 93 #ifndef CHROMEOS_ENVIRONMENT | |
| 94 if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) { | |
| 95 result = TlclContinueSelfTest(); | |
| 96 if (result != TPM_SUCCESS) { | |
| 97 return result; | |
| 98 } | |
| 99 #if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE) | |
| 100 /* Retry only once */ | |
| 101 result = TlclSendReceiveNoRetry(request, response, max_length); | |
| 102 #else | |
| 103 /* This needs serious testing. The TPM specification says: "iii. The | |
| 104 * caller MUST wait for the actions of TPM_ContinueSelfTest to complete | |
| 105 * before reissuing the command C1." But, if ContinueSelfTest is | |
| 106 * non-blocking, how do we know that the actions have completed other than | |
| 107 * trying again? */ | |
| 108 do { | |
| 109 result = TlclSendReceiveNoRetry(request, response, max_length); | |
| 110 } while (result == TPM_E_DOING_SELFTEST); | |
| 111 #endif | |
| 112 } | |
| 113 #endif /* ! defined(CHROMEOS_ENVIRONMENT) */ | |
| 114 return result; | |
| 115 } | |
| 116 | |
| 86 /* Sends a command and returns the error code. */ | 117 /* Sends a command and returns the error code. */ |
| 87 static uint32_t Send(const uint8_t* command) { | 118 static uint32_t Send(const uint8_t* command) { |
| 88 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | 119 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; |
| 89 return TlclSendReceive(command, response, sizeof(response)); | 120 return TlclSendReceive(command, response, sizeof(response)); |
| 90 } | 121 } |
| 91 | 122 |
| 92 /* Exported functions. */ | 123 /* Exported functions. */ |
| 93 | 124 |
| 94 uint32_t TlclLibInit(void) { | 125 uint32_t TlclLibInit(void) { |
| 95 return TlclStubInit(); | 126 return TlclStubInit(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 109 VBDEBUG(("TPM: Resume\n")); | 140 VBDEBUG(("TPM: Resume\n")); |
| 110 return Send(tpm_resume_cmd.buffer); | 141 return Send(tpm_resume_cmd.buffer); |
| 111 } | 142 } |
| 112 | 143 |
| 113 uint32_t TlclSelfTestFull(void) { | 144 uint32_t TlclSelfTestFull(void) { |
| 114 VBDEBUG(("TPM: Self test full\n")); | 145 VBDEBUG(("TPM: Self test full\n")); |
| 115 return Send(tpm_selftestfull_cmd.buffer); | 146 return Send(tpm_selftestfull_cmd.buffer); |
| 116 } | 147 } |
| 117 | 148 |
| 118 uint32_t TlclContinueSelfTest(void) { | 149 uint32_t TlclContinueSelfTest(void) { |
| 150 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | |
| 119 VBDEBUG(("TPM: Continue self test\n")); | 151 VBDEBUG(("TPM: Continue self test\n")); |
| 120 return Send(tpm_continueselftest_cmd.buffer); | 152 /* Call the No Retry version of SendReceive to avoid recursion. */ |
| 153 return TlclSendReceiveNoRetry(tpm_continueselftest_cmd.buffer, | |
| 154 response, sizeof(response)); | |
| 121 } | 155 } |
| 122 | 156 |
| 123 uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { | 157 uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { |
| 124 struct s_tpm_nv_definespace_cmd cmd; | 158 struct s_tpm_nv_definespace_cmd cmd; |
| 125 VBDEBUG(("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size)); | 159 VBDEBUG(("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size)); |
| 126 Memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd)); | 160 Memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd)); |
| 127 ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.index, index); | 161 ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.index, index); |
| 128 ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm); | 162 ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm); |
| 129 ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.size, size); | 163 ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.size, size); |
| 130 return Send(cmd.buffer); | 164 return Send(cmd.buffer); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); | 358 Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); |
| 325 ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index); | 359 ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index); |
| 326 result = TlclSendReceive(cmd.buffer, response, sizeof(response)); | 360 result = TlclSendReceive(cmd.buffer, response, sizeof(response)); |
| 327 if (result != TPM_SUCCESS) | 361 if (result != TPM_SUCCESS) |
| 328 return result; | 362 return result; |
| 329 | 363 |
| 330 nvdata = response + kTpmResponseHeaderLength + sizeof(size); | 364 nvdata = response + kTpmResponseHeaderLength + sizeof(size); |
| 331 FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions); | 365 FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions); |
| 332 return result; | 366 return result; |
| 333 } | 367 } |
| OLD | NEW |