Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: firmware/lib/tpm_lite/tlcl.c

Issue 3078028: Pay attention to TPM communication errors (Closed) Base URL: ssh://gitrw.chromium.org/vboot_reference.git
Patch Set: Fix whitespace Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « firmware/lib/tpm_lite/include/tss_constants.h ('k') | firmware/stub/tpm_lite_stub.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 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 27 matching lines...) Expand all
38 uint32_t code; 38 uint32_t code;
39 FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code); 39 FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
40 return code; 40 return code;
41 } 41 }
42 42
43 /* Gets the return code field of a TPM result. */ 43 /* Gets the return code field of a TPM result. */
44 static INLINE int TpmReturnCode(const uint8_t* buffer) { 44 static INLINE int TpmReturnCode(const uint8_t* buffer) {
45 return TpmCommandCode(buffer); 45 return TpmCommandCode(buffer);
46 } 46 }
47 47
48 /* Checks for errors in a TPM response. */ 48 /* Sends a TPM command and gets a response. Returns 0 if success or the TPM
49 static void CheckResult(uint8_t* request, uint8_t* response, int warn_only) { 49 * error code if error. */
50 int command = TpmCommandCode(request); 50 static uint32_t TlclSendReceive(uint8_t* request, uint8_t* response,
51 int result = TpmReturnCode(response); 51 int max_length) {
52 if (result != TPM_SUCCESS) {
53 if (warn_only)
54 VBDEBUG(("TPM: command 0x%x failed: 0x%x\n", command, result));
55 else
56 error("TPM: command 0x%x failed: 0x%x\n", command, result);
57 }
58 }
59 52
60 /* Sends a TPM command and gets a response. */ 53 uint32_t result;
61 static void TlclSendReceive(uint8_t* request, uint8_t* response,
62 int max_length) {
63 54
64 #ifdef EXTRA_LOGGING 55 #ifdef EXTRA_LOGGING
65 VBDEBUG(("TPM: command: %x%x %x%x%x%x %x%x%x%x\n", 56 VBDEBUG(("TPM: command: %x%x %x%x%x%x %x%x%x%x\n",
66 request[0], request[1], 57 request[0], request[1],
67 request[2], request[3], request[4], request[5], 58 request[2], request[3], request[4], request[5],
68 request[6], request[7], request[8], request[9])); 59 request[6], request[7], request[8], request[9]));
69 #endif 60 #endif
70 61
71 TlclStubSendReceive(request, TpmCommandSize(request), 62 result = TlclStubSendReceive(request, TpmCommandSize(request),
72 response, max_length); 63 response, max_length);
64 if (0 != result) {
65 /* Communication with TPM failed, so response is garbage */
66 VBDEBUG(("TPM: command 0x%x send/receive failed: 0x%x\n",
67 TpmCommandCode(request), result));
68 return TPM_E_COMMUNICATION_ERROR;
69 }
70 /* Otherwise, use the result code from the response */
71 result = TpmReturnCode(response);
73 72
74 #ifdef EXTRA_LOGGING 73 #ifdef EXTRA_LOGGING
75 VBDEBUG(("TPM: response: %x%x %x%x%x%x %x%x%x%x\n", 74 VBDEBUG(("TPM: response: %x%x %x%x%x%x %x%x%x%x\n",
76 response[0], response[1], 75 response[0], response[1],
77 response[2], response[3], response[4], response[5], 76 response[2], response[3], response[4], response[5],
78 response[6], response[7], response[8], response[9])); 77 response[6], response[7], response[8], response[9]));
79 #endif 78 #endif
80 79
81 #ifdef VBOOT_DEBUG 80 VBDEBUG(("TPM: command 0x%x returned 0x%x\n",
82 { 81 TpmCommandCode(request), result));
83 int command = TpmCommandCode(request); 82
84 int result = TpmReturnCode(response); 83 return result;
85 VBDEBUG(("TPM: command 0x%x returned 0x%x\n", command, result));
86 }
87 #endif
88 } 84 }
89 85
90 86
91 /* Sends a command and returns the error code. */ 87 /* Sends a command and returns the error code. */
92 static uint32_t Send(uint8_t* command) { 88 static uint32_t Send(uint8_t* command) {
93 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 89 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
94 TlclSendReceive(command, response, sizeof(response)); 90 return TlclSendReceive(command, response, sizeof(response));
95 return TpmReturnCode(response);
96 } 91 }
97 92
98 /* Exported functions. */ 93 /* Exported functions. */
99 94
100 void TlclLibInit(void) { 95 void TlclLibInit(void) {
101 TlclStubInit(); 96 TlclStubInit();
102 } 97 }
103 98
104 uint32_t TlclStartup(void) { 99 uint32_t TlclStartup(void) {
105 VBDEBUG(("TPM: Startup\n")); 100 VBDEBUG(("TPM: Startup\n"));
(...skipping 28 matching lines...) Expand all
134 129
135 VBDEBUG(("TPM: TlclWrite(0x%x, %d)\n", index, length)); 130 VBDEBUG(("TPM: TlclWrite(0x%x, %d)\n", index, length));
136 Memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd)); 131 Memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd));
137 assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE); 132 assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
138 SetTpmCommandSize(cmd.buffer, total_length); 133 SetTpmCommandSize(cmd.buffer, total_length);
139 134
140 ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.index, index); 135 ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.index, index);
141 ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.length, length); 136 ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.length, length);
142 Memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length); 137 Memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length);
143 138
144 TlclSendReceive(cmd.buffer, response, sizeof(response)); 139 return TlclSendReceive(cmd.buffer, response, sizeof(response));
145 CheckResult(cmd.buffer, response, 1);
146
147 return TpmReturnCode(response);
148 } 140 }
149 141
150 uint32_t TlclRead(uint32_t index, uint8_t* data, uint32_t length) { 142 uint32_t TlclRead(uint32_t index, uint8_t* data, uint32_t length) {
151 struct s_tpm_nv_read_cmd cmd; 143 struct s_tpm_nv_read_cmd cmd;
152 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 144 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
153 uint32_t result_length; 145 uint32_t result_length;
154 uint32_t result; 146 uint32_t result;
155 147
156 VBDEBUG(("TPM: TlclRead(0x%x, %d)\n", index, length)); 148 VBDEBUG(("TPM: TlclRead(0x%x, %d)\n", index, length));
157 Memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd)); 149 Memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd));
158 ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.index, index); 150 ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.index, index);
159 ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.length, length); 151 ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.length, length);
160 152
161 TlclSendReceive(cmd.buffer, response, sizeof(response)); 153 result = TlclSendReceive(cmd.buffer, response, sizeof(response));
162 result = TpmReturnCode(response);
163 if (result == TPM_SUCCESS && length > 0) { 154 if (result == TPM_SUCCESS && length > 0) {
164 uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength; 155 uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
165 FromTpmUint32(nv_read_cursor, &result_length); 156 FromTpmUint32(nv_read_cursor, &result_length);
166 nv_read_cursor += sizeof(uint32_t); 157 nv_read_cursor += sizeof(uint32_t);
167 Memcpy(data, nv_read_cursor, result_length); 158 Memcpy(data, nv_read_cursor, result_length);
168 } 159 }
169 160
170 return result; 161 return result;
171 } 162 }
172 163
173 uint32_t TlclWriteLock(uint32_t index) { 164 uint32_t TlclWriteLock(uint32_t index) {
174 VBDEBUG(("TPM: Write lock 0x%x\n", index)); 165 VBDEBUG(("TPM: Write lock 0x%x\n", index));
175 return TlclWrite(index, NULL, 0); 166 return TlclWrite(index, NULL, 0);
176 } 167 }
177 168
178 uint32_t TlclReadLock(uint32_t index) { 169 uint32_t TlclReadLock(uint32_t index) {
179 VBDEBUG(("TPM: Read lock 0x%x\n", index)); 170 VBDEBUG(("TPM: Read lock 0x%x\n", index));
180 return TlclRead(index, NULL, 0); 171 return TlclRead(index, NULL, 0);
181 } 172 }
182 173
183 uint32_t TlclAssertPhysicalPresence(void) { 174 uint32_t TlclAssertPhysicalPresence(void) {
184 VBDEBUG(("TPM: Asserting physical presence\n")); 175 VBDEBUG(("TPM: Asserting physical presence\n"));
185 return Send(tpm_ppassert_cmd.buffer); 176 return Send(tpm_ppassert_cmd.buffer);
186 } 177 }
187 178
188 uint32_t TlclAssertPhysicalPresenceResult(void) { 179 uint32_t TlclAssertPhysicalPresenceResult(void) {
189 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 180 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
190 TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response)); 181 return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response));
191 return TpmReturnCode(response);
192 } 182 }
193 183
194 uint32_t TlclLockPhysicalPresence(void) { 184 uint32_t TlclLockPhysicalPresence(void) {
195 VBDEBUG(("TPM: Lock physical presence\n")); 185 VBDEBUG(("TPM: Lock physical presence\n"));
196 return Send(tpm_pplock_cmd.buffer); 186 return Send(tpm_pplock_cmd.buffer);
197 } 187 }
198 188
199 uint32_t TlclSetNvLocked(void) { 189 uint32_t TlclSetNvLocked(void) {
200 VBDEBUG(("TPM: Set NV locked\n")); 190 VBDEBUG(("TPM: Set NV locked\n"));
201 return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0); 191 return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0);
202 } 192 }
203 193
204 int TlclIsOwned(void) { 194 int TlclIsOwned(void) {
205 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE]; 195 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE];
206 uint32_t result; 196 uint32_t result;
207 TlclSendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response)); 197 result = TlclSendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response)) ;
208 result = TpmReturnCode(response);
209 return (result != TPM_SUCCESS); 198 return (result != TPM_SUCCESS);
210 } 199 }
211 200
212 uint32_t TlclForceClear(void) { 201 uint32_t TlclForceClear(void) {
213 VBDEBUG(("TPM: Force clear\n")); 202 VBDEBUG(("TPM: Force clear\n"));
214 return Send(tpm_forceclear_cmd.buffer); 203 return Send(tpm_forceclear_cmd.buffer);
215 } 204 }
216 205
217 uint32_t TlclSetEnable(void) { 206 uint32_t TlclSetEnable(void) {
218 VBDEBUG(("TPM: Enabling TPM\n")); 207 VBDEBUG(("TPM: Enabling TPM\n"));
(...skipping 13 matching lines...) Expand all
232 return Send(cmd.buffer); 221 return Send(cmd.buffer);
233 } 222 }
234 223
235 uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated, uint8_t *nvlocked) { 224 uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated, uint8_t *nvlocked) {
236 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 225 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
237 TPM_PERMANENT_FLAGS* pflags; 226 TPM_PERMANENT_FLAGS* pflags;
238 uint32_t result; 227 uint32_t result;
239 uint32_t size; 228 uint32_t size;
240 VBDEBUG(("TPM: Get flags\n")); 229 VBDEBUG(("TPM: Get flags\n"));
241 230
242 TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response)); 231 result = TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response));
243 result = TpmReturnCode(response); 232 if (result != TPM_SUCCESS)
244 if (result != TPM_SUCCESS) {
245 return result; 233 return result;
246 } 234
247 FromTpmUint32(response + kTpmResponseHeaderLength, &size); 235 FromTpmUint32(response + kTpmResponseHeaderLength, &size);
248 assert(size == sizeof(TPM_PERMANENT_FLAGS)); 236 assert(size == sizeof(TPM_PERMANENT_FLAGS));
249 pflags = 237 pflags =
250 (TPM_PERMANENT_FLAGS*) (response + kTpmResponseHeaderLength + sizeof(size)); 238 (TPM_PERMANENT_FLAGS*) (response + kTpmResponseHeaderLength + sizeof(size));
251 VBDEBUG(("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n", 239 VBDEBUG(("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n",
252 pflags->disable, pflags->deactivated, pflags->nvLocked)); 240 pflags->disable, pflags->deactivated, pflags->nvLocked));
253 if (disable) 241 if (disable)
254 *disable = pflags->disable; 242 *disable = pflags->disable;
255 if (deactivated) 243 if (deactivated)
256 *deactivated = pflags->deactivated; 244 *deactivated = pflags->deactivated;
257 if (nvlocked) 245 if (nvlocked)
258 *nvlocked = pflags->nvLocked; 246 *nvlocked = pflags->nvLocked;
259 return result; 247 return result;
260 } 248 }
261 249
262 uint32_t TlclSetGlobalLock(void) { 250 uint32_t TlclSetGlobalLock(void) {
263 uint32_t x; 251 uint32_t x;
264 VBDEBUG(("TPM: Set Set global lock\n")); 252 VBDEBUG(("TPM: Set global lock\n"));
265 return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); 253 return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0);
266 } 254 }
267 255
268 uint32_t TlclExtend(int pcr_num, uint8_t* in_digest, uint8_t* out_digest) { 256 uint32_t TlclExtend(int pcr_num, uint8_t* in_digest, uint8_t* out_digest) {
269 struct s_tpm_extend_cmd cmd; 257 struct s_tpm_extend_cmd cmd;
270 uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength]; 258 uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength];
259 uint32_t result;
271 260
272 Memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd)); 261 Memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd));
273 ToTpmUint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num); 262 ToTpmUint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num);
274 Memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength); 263 Memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength);
275 TlclSendReceive(cmd.buffer, response, sizeof(response)); 264
265 result = TlclSendReceive(cmd.buffer, response, sizeof(response));
266 if (result != TPM_SUCCESS)
267 return result;
268
276 Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength); 269 Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength);
277 return TpmReturnCode(response); 270 return result;
278 } 271 }
279 272
280 uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) { 273 uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) {
281 struct s_tpm_getpermissions_cmd cmd; 274 struct s_tpm_getpermissions_cmd cmd;
282 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 275 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
283 uint8_t* nvdata; 276 uint8_t* nvdata;
284 uint32_t result; 277 uint32_t result;
285 uint32_t size; 278 uint32_t size;
286 279
287 Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); 280 Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd));
288 ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index); 281 ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index);
289 TlclSendReceive(cmd.buffer, response, sizeof(response)); 282 result = TlclSendReceive(cmd.buffer, response, sizeof(response));
290 result = TpmReturnCode(response); 283 if (result != TPM_SUCCESS)
291 if (result != TPM_SUCCESS) {
292 return result; 284 return result;
293 } 285
294 nvdata = response + kTpmResponseHeaderLength + sizeof(size); 286 nvdata = response + kTpmResponseHeaderLength + sizeof(size);
295 FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions); 287 FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions);
296 return result; 288 return result;
297 } 289 }
OLDNEW
« no previous file with comments | « firmware/lib/tpm_lite/include/tss_constants.h ('k') | firmware/stub/tpm_lite_stub.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698