OLD | NEW |
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 fields are | 8 * The general idea is that TPM commands are array of bytes whose fields are |
9 * mostly compile-time constant. The goal is to build much of the commands at | 9 * mostly compile-time constant. The goal is to build much of the commands at |
10 * compile time (or build time) and change some of the fields at run time as | 10 * compile time (or build time) and change some of the fields at run time as |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
196 response_tag == TPM_TAG_RSP_COMMAND) || | 196 response_tag == TPM_TAG_RSP_COMMAND) || |
197 (tag == TPM_TAG_RQU_AUTH1_COMMAND && | 197 (tag == TPM_TAG_RQU_AUTH1_COMMAND && |
198 response_tag == TPM_TAG_RSP_AUTH1_COMMAND) || | 198 response_tag == TPM_TAG_RSP_AUTH1_COMMAND) || |
199 (tag == TPM_TAG_RQU_AUTH2_COMMAND && | 199 (tag == TPM_TAG_RQU_AUTH2_COMMAND && |
200 response_tag == TPM_TAG_RSP_AUTH2_COMMAND)); | 200 response_tag == TPM_TAG_RSP_AUTH2_COMMAND)); |
201 assert(response_length == TpmCommandSize(response)); | 201 assert(response_length == TpmCommandSize(response)); |
202 #endif /* FIRMWARE */ | 202 #endif /* FIRMWARE */ |
203 | 203 |
204 } | 204 } |
205 | 205 |
206 /* Sends a command and checks the result for errors. Note that this error | 206 /* Sends a command and returns the error code. |
207 * checking is only meaningful when running in user mode. TODO: The entire | |
208 * error recovery strategy in the firmware needs more work. | |
209 */ | 207 */ |
210 static void Send(uint8_t* command) { | 208 static uint32_t Send(uint8_t* command) { |
211 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | 209 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; |
212 SendReceive(command, response, sizeof(response)); | 210 SendReceive(command, response, sizeof(response)); |
213 CheckResult(command, response, false); | 211 return TpmReturnCode(response); |
214 } | 212 } |
215 | 213 |
216 | |
217 /* Exported functions. | 214 /* Exported functions. |
218 */ | 215 */ |
219 | 216 |
220 void TlclLog(char* format, ...) { | 217 void TlclLog(char* format, ...) { |
221 va_list ap; | 218 va_list ap; |
222 if (tlcl_log_level > 0) { | 219 if (tlcl_log_level > 0) { |
223 va_start(ap, format); | 220 va_start(ap, format); |
224 vprintf(format, ap); | 221 vprintf(format, ap); |
225 va_end(ap); | 222 va_end(ap); |
226 } | 223 } |
227 } | 224 } |
228 | 225 |
229 void TlclSetLogLevel(int level) { | 226 void TlclSetLogLevel(int level) { |
230 tlcl_log_level = level; | 227 tlcl_log_level = level; |
231 } | 228 } |
232 | 229 |
233 void TlclLibInit(void) { | 230 void TlclLibInit(void) { |
234 #if USE_TPM_EMULATOR | 231 #if USE_TPM_EMULATOR |
235 tpmemu_init(); | 232 tpmemu_init(); |
236 #else | 233 #else |
237 #if !FIRMWARE | 234 #if !FIRMWARE |
238 tpm_fd = open("/dev/tpm0", O_RDWR); | 235 tpm_fd = open("/dev/tpm0", O_RDWR); |
239 if (tpm_fd < 0) { | 236 if (tpm_fd < 0) { |
240 error("cannot open TPM device: %s\n", strerror(errno)); | 237 error("cannot open TPM device: %s\n", strerror(errno)); |
241 } | 238 } |
242 #endif /* !FIRMWARE */ | 239 #endif /* !FIRMWARE */ |
243 #endif /* USE_TPM_EMULATOR */ | 240 #endif /* USE_TPM_EMULATOR */ |
244 } | 241 } |
245 | 242 |
246 void TlclStartup(void) { | 243 uint32_t TlclStartup(void) { |
247 Send(tpm_startup_cmd.buffer); | 244 return Send(tpm_startup_cmd.buffer); |
248 } | 245 } |
249 | 246 |
250 void TlclSelftestfull(void) { | 247 uint32_t TlclSelftestfull(void) { |
251 Send(tpm_selftestfull_cmd.buffer); | 248 return Send(tpm_selftestfull_cmd.buffer); |
252 } | 249 } |
253 | 250 |
254 void TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { | 251 uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { |
255 ToTpmUint32(tpm_nv_definespace_cmd.index, index); | 252 ToTpmUint32(tpm_nv_definespace_cmd.index, index); |
256 ToTpmUint32(tpm_nv_definespace_cmd.perm, perm); | 253 ToTpmUint32(tpm_nv_definespace_cmd.perm, perm); |
257 ToTpmUint32(tpm_nv_definespace_cmd.size, size); | 254 ToTpmUint32(tpm_nv_definespace_cmd.size, size); |
258 Send(tpm_nv_definespace_cmd.buffer); | 255 return Send(tpm_nv_definespace_cmd.buffer); |
259 } | 256 } |
260 | 257 |
261 uint32_t TlclWrite(uint32_t index, uint8_t* data, uint32_t length) { | 258 uint32_t TlclWrite(uint32_t index, uint8_t* data, uint32_t length) { |
262 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | 259 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; |
263 const int total_length = | 260 const int total_length = |
264 kTpmRequestHeaderLength + kWriteInfoLength + length; | 261 kTpmRequestHeaderLength + kWriteInfoLength + length; |
265 | 262 |
266 assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE); | 263 assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE); |
267 SetTpmCommandSize(tpm_nv_write_cmd.buffer, total_length); | 264 SetTpmCommandSize(tpm_nv_write_cmd.buffer, total_length); |
268 | 265 |
(...skipping 20 matching lines...) Expand all Loading... |
289 if (result == TPM_SUCCESS && length > 0) { | 286 if (result == TPM_SUCCESS && length > 0) { |
290 uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength; | 287 uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength; |
291 FromTpmUint32(nv_read_cursor, &result_length); | 288 FromTpmUint32(nv_read_cursor, &result_length); |
292 nv_read_cursor += sizeof(uint32_t); | 289 nv_read_cursor += sizeof(uint32_t); |
293 memcpy(data, nv_read_cursor, result_length); | 290 memcpy(data, nv_read_cursor, result_length); |
294 } | 291 } |
295 | 292 |
296 return result; | 293 return result; |
297 } | 294 } |
298 | 295 |
299 void TlclWriteLock(uint32_t index) { | 296 uint32_t TlclWriteLock(uint32_t index) { |
300 if (TlclWrite(index, NULL, 0) != TPM_SUCCESS) { | 297 return TlclWrite(index, NULL, 0); |
301 error("failed to write lock space 0x%x\n", index); | |
302 } | |
303 } | 298 } |
304 | 299 |
305 void TlclReadLock(uint32_t index) { | 300 uint32_t TlclReadLock(uint32_t index) { |
306 if (TlclRead(index, NULL, 0) != TPM_SUCCESS) { | 301 return TlclRead(index, NULL, 0); |
307 error("failed to read lock space 0x%x\n", index); | |
308 } | |
309 } | 302 } |
310 | 303 |
311 void TlclAssertPhysicalPresence(void) { | 304 uint32_t TlclAssertPhysicalPresence(void) { |
312 Send(tpm_ppassert_cmd.buffer); | 305 return Send(tpm_ppassert_cmd.buffer); |
313 } | 306 } |
314 | 307 |
315 uint32_t TlclLockPhysicalPresence(void) { | 308 uint32_t TlclLockPhysicalPresence(void) { |
316 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | 309 return Send(tpm_pplock_cmd.buffer); |
317 SendReceive(tpm_pplock_cmd.buffer, response, sizeof(response)); | |
318 return TpmReturnCode(response); | |
319 } | 310 } |
320 | 311 |
321 void TlclSetNvLocked(void) { | 312 uint32_t TlclSetNvLocked(void) { |
322 TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0); | 313 return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0); |
323 } | 314 } |
324 | 315 |
325 int TlclIsOwned(void) { | 316 int TlclIsOwned(void) { |
326 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE]; | 317 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE]; |
327 uint32_t result; | 318 uint32_t result; |
328 SendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response)); | 319 SendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response)); |
329 result = TpmReturnCode(response); | 320 result = TpmReturnCode(response); |
330 return (result != TPM_SUCCESS); | 321 return (result != TPM_SUCCESS); |
331 } | 322 } |
332 | 323 |
333 void TlclForceClear(void) { | 324 uint32_t TlclForceClear(void) { |
334 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | 325 return Send(tpm_forceclear_cmd.buffer); |
335 uint32_t result; | |
336 SendReceive(tpm_forceclear_cmd.buffer, response, sizeof(response)); | |
337 result = TpmReturnCode(response); | |
338 if (result != TPM_SUCCESS) { | |
339 warning("ForceClear failed with code %d (0x%x)\n", result, result); | |
340 } | |
341 } | 326 } |
342 | 327 |
343 void TlclSetEnable(void) { | 328 uint32_t TlclSetEnable(void) { |
344 Send(tpm_physicalenable_cmd.buffer); | 329 return Send(tpm_physicalenable_cmd.buffer); |
345 } | 330 } |
346 | 331 |
347 int TlclSetDeactivated(uint8_t flag) { | 332 uint32_t TlclSetDeactivated(uint8_t flag) { |
348 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | |
349 uint32_t result; | |
350 *((uint8_t*)tpm_physicalsetdeactivated_cmd.deactivated) = flag; | 333 *((uint8_t*)tpm_physicalsetdeactivated_cmd.deactivated) = flag; |
351 SendReceive(tpm_physicalsetdeactivated_cmd.buffer, | 334 return Send(tpm_physicalsetdeactivated_cmd.buffer); |
352 response, sizeof(response)); | |
353 result = TpmReturnCode(response); | |
354 return result; | |
355 } | 335 } |
356 | 336 |
357 int TlclGetFlags(uint8_t* disable, uint8_t* deactivated) { | 337 uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated) { |
358 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; | 338 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; |
359 TPM_PERMANENT_FLAGS* pflags; | 339 TPM_PERMANENT_FLAGS* pflags; |
360 uint32_t result; | 340 uint32_t result; |
361 uint32_t size; | 341 uint32_t size; |
362 | 342 |
363 SendReceive(tpm_getcapability_cmd.buffer, response, sizeof(response)); | 343 SendReceive(tpm_getcapability_cmd.buffer, response, sizeof(response)); |
364 result = TpmReturnCode(response); | 344 result = TpmReturnCode(response); |
365 if (result != TPM_SUCCESS) { | 345 if (result != TPM_SUCCESS) { |
366 return result; | 346 return result; |
367 } | 347 } |
368 FromTpmUint32(response + kTpmResponseHeaderLength, &size); | 348 FromTpmUint32(response + kTpmResponseHeaderLength, &size); |
369 assert(size == sizeof(TPM_PERMANENT_FLAGS)); | 349 assert(size == sizeof(TPM_PERMANENT_FLAGS)); |
370 pflags = | 350 pflags = |
371 (TPM_PERMANENT_FLAGS*) (response + kTpmResponseHeaderLength + sizeof(size)); | 351 (TPM_PERMANENT_FLAGS*) (response + kTpmResponseHeaderLength + sizeof(size)); |
372 *disable = pflags->disable; | 352 *disable = pflags->disable; |
373 *deactivated = pflags->deactivated; | 353 *deactivated = pflags->deactivated; |
374 return result; | 354 return result; |
375 } | 355 } |
376 | 356 |
377 uint32_t TlclSetGlobalLock(void) { | 357 uint32_t TlclSetGlobalLock(void) { |
378 uint32_t x; | 358 uint32_t x; |
379 return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); | 359 return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); |
380 } | 360 } |
OLD | NEW |