1f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 239f66114c03639715cb88774255f066a2d942557Randall Spangler * Use of this source code is governed by a BSD-style license that can be 339f66114c03639715cb88774255f066a2d942557Randall Spangler * found in the LICENSE file. 439f66114c03639715cb88774255f066a2d942557Randall Spangler */ 539f66114c03639715cb88774255f066a2d942557Randall Spangler 639f66114c03639715cb88774255f066a2d942557Randall Spangler/* A lightweight TPM command library. 739f66114c03639715cb88774255f066a2d942557Randall Spangler * 839f66114c03639715cb88774255f066a2d942557Randall Spangler * The general idea is that TPM commands are array of bytes whose 939f66114c03639715cb88774255f066a2d942557Randall Spangler * fields are mostly compile-time constant. The goal is to build much 1039f66114c03639715cb88774255f066a2d942557Randall Spangler * of the commands at compile time (or build time) and change some of 1139f66114c03639715cb88774255f066a2d942557Randall Spangler * the fields at run time as needed. The code in 1239f66114c03639715cb88774255f066a2d942557Randall Spangler * utility/tlcl_generator.c builds structures containing the commands, 1339f66114c03639715cb88774255f066a2d942557Randall Spangler * as well as the offsets of the fields that need to be set at run 1439f66114c03639715cb88774255f066a2d942557Randall Spangler * time. 1539f66114c03639715cb88774255f066a2d942557Randall Spangler */ 1639f66114c03639715cb88774255f066a2d942557Randall Spangler 1739f66114c03639715cb88774255f066a2d942557Randall Spangler#include "sysincludes.h" 180c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson 1939f66114c03639715cb88774255f066a2d942557Randall Spangler#include "tlcl.h" 2039f66114c03639715cb88774255f066a2d942557Randall Spangler#include "tlcl_internal.h" 2139f66114c03639715cb88774255f066a2d942557Randall Spangler#include "tlcl_structures.h" 2239f66114c03639715cb88774255f066a2d942557Randall Spangler#include "utility.h" 23e49e8af65fce38da7a308305566f8a14f102254aRandall Spangler#include "vboot_api.h" 2439f66114c03639715cb88774255f066a2d942557Randall Spangler 25c3d488d155961d2849dfdaa4f0461df1aa95c2caRandall Spangler#ifdef FOR_TEST 26c3d488d155961d2849dfdaa4f0461df1aa95c2caRandall Spangler/* Allow unit testing implementation of TlclSendReceive() */ 27c3d488d155961d2849dfdaa4f0461df1aa95c2caRandall Spangler#undef CHROMEOS_ENVIRONMENT 28c3d488d155961d2849dfdaa4f0461df1aa95c2caRandall Spangler#endif 29c3d488d155961d2849dfdaa4f0461df1aa95c2caRandall Spangler 3039f66114c03639715cb88774255f066a2d942557Randall Spangler/* Sets the size field of a TPM command. */ 31ac8805e7e9bd40c03baf44e37b26f28d9b763ab5Gabe Blackstatic inline void SetTpmCommandSize(uint8_t* buffer, uint32_t size) { 3239f66114c03639715cb88774255f066a2d942557Randall Spangler ToTpmUint32(buffer + sizeof(uint16_t), size); 3339f66114c03639715cb88774255f066a2d942557Randall Spangler} 3439f66114c03639715cb88774255f066a2d942557Randall Spangler 3539f66114c03639715cb88774255f066a2d942557Randall Spangler/* Gets the size field of a TPM command. */ 36ac8805e7e9bd40c03baf44e37b26f28d9b763ab5Gabe Black__attribute__((unused)) 37ac8805e7e9bd40c03baf44e37b26f28d9b763ab5Gabe Blackstatic inline int TpmCommandSize(const uint8_t* buffer) { 3839f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t size; 3939f66114c03639715cb88774255f066a2d942557Randall Spangler FromTpmUint32(buffer + sizeof(uint16_t), &size); 4039f66114c03639715cb88774255f066a2d942557Randall Spangler return (int) size; 4139f66114c03639715cb88774255f066a2d942557Randall Spangler} 4239f66114c03639715cb88774255f066a2d942557Randall Spangler 433428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3Luigi Semenzato/* Gets the size field of a TPM request or response. */ 443428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3Luigi Semenzatoint TlclPacketSize(const uint8_t* packet) { 453428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3Luigi Semenzato return TpmCommandSize(packet); 463428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3Luigi Semenzato} 473428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3Luigi Semenzato 4839f66114c03639715cb88774255f066a2d942557Randall Spangler/* Gets the code field of a TPM command. */ 49ac8805e7e9bd40c03baf44e37b26f28d9b763ab5Gabe Blackstatic inline int TpmCommandCode(const uint8_t* buffer) { 5039f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t code; 5139f66114c03639715cb88774255f066a2d942557Randall Spangler FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code); 5239f66114c03639715cb88774255f066a2d942557Randall Spangler return code; 5339f66114c03639715cb88774255f066a2d942557Randall Spangler} 5439f66114c03639715cb88774255f066a2d942557Randall Spangler 5539f66114c03639715cb88774255f066a2d942557Randall Spangler/* Gets the return code field of a TPM result. */ 56ac8805e7e9bd40c03baf44e37b26f28d9b763ab5Gabe Blackstatic inline int TpmReturnCode(const uint8_t* buffer) { 5739f66114c03639715cb88774255f066a2d942557Randall Spangler return TpmCommandCode(buffer); 5839f66114c03639715cb88774255f066a2d942557Randall Spangler} 5939f66114c03639715cb88774255f066a2d942557Randall Spangler 6006fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato/* Like TlclSendReceive below, but do not retry if NEEDS_SELFTEST or 6106fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * DOING_SELFTEST errors are returned. 6206fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato */ 6306fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzatostatic uint32_t TlclSendReceiveNoRetry(const uint8_t* request, 6406fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato uint8_t* response, int max_length) { 651b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler 661b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler uint32_t response_length = max_length; 67205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler uint32_t result; 683e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler 6963dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler#ifdef EXTRA_LOGGING 7063dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler VBDEBUG(("TPM: command: %x%x %x%x%x%x %x%x%x%x\n", 7163dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler request[0], request[1], 7263dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler request[2], request[3], request[4], request[5], 7363dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler request[6], request[7], request[8], request[9])); 7450d48feb9e0df6a990cc5890ce14e1398798eeb1Luigi Semenzato#endif 7563dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler 761b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler result = VbExTpmSendReceive(request, TpmCommandSize(request), 771b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler response, &response_length); 78205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler if (0 != result) { 79205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler /* Communication with TPM failed, so response is garbage */ 80205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler VBDEBUG(("TPM: command 0x%x send/receive failed: 0x%x\n", 81205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler TpmCommandCode(request), result)); 8200cc72894f3ce5c3b0d337e424f19da089140237Kees Cook return result; 83205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler } 84205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler /* Otherwise, use the result code from the response */ 85205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler result = TpmReturnCode(response); 8663dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler 871b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler /* TODO: add paranoia about returned response_length vs. max_length 881b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler * (and possibly expected length from the response header). See 891b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler * crosbug.com/17017 */ 901b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler 9163dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler#ifdef EXTRA_LOGGING 9263dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler VBDEBUG(("TPM: response: %x%x %x%x%x%x %x%x%x%x\n", 9363dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler response[0], response[1], 9463dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler response[2], response[3], response[4], response[5], 9563dffcb52b56f27d5315de249d20958b94eed47fRandall Spangler response[6], response[7], response[8], response[9])); 9650d48feb9e0df6a990cc5890ce14e1398798eeb1Luigi Semenzato#endif 973e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler 98205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler VBDEBUG(("TPM: command 0x%x returned 0x%x\n", 99205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler TpmCommandCode(request), result)); 100205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler 101205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler return result; 10239f66114c03639715cb88774255f066a2d942557Randall Spangler} 10339f66114c03639715cb88774255f066a2d942557Randall Spangler 10439f66114c03639715cb88774255f066a2d942557Randall Spangler 10506fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato/* Sends a TPM command and gets a response. Returns 0 if success or the TPM 10606fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * error code if error. In the firmware, waits for the self test to complete 10706fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * if needed. In the host, reports the first error without retries. */ 1083428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3Luigi Semenzatouint32_t TlclSendReceive(const uint8_t* request, uint8_t* response, 1093428b4bcd99a6d2e9f8b3e1bdf800d943fbe78c3Luigi Semenzato int max_length) { 11006fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato uint32_t result = TlclSendReceiveNoRetry(request, response, max_length); 11106fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato /* When compiling for the firmware, hide command failures due to the self 11206fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * test not having run or completed. */ 11306fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato#ifndef CHROMEOS_ENVIRONMENT 11406fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato /* If the command fails because the self test has not completed, try it 11506fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * again after attempting to ensure that the self test has completed. */ 11606fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato if (result == TPM_E_NEEDS_SELFTEST || result == TPM_E_DOING_SELFTEST) { 11706fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato result = TlclContinueSelfTest(); 11806fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato if (result != TPM_SUCCESS) { 11906fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato return result; 12006fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato } 12106fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato#if defined(TPM_BLOCKING_CONTINUESELFTEST) || defined(VB_RECOVERY_MODE) 12206fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato /* Retry only once */ 12306fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato result = TlclSendReceiveNoRetry(request, response, max_length); 12406fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato#else 12506fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato /* This needs serious testing. The TPM specification says: "iii. The 12606fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * caller MUST wait for the actions of TPM_ContinueSelfTest to complete 12706fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * before reissuing the command C1." But, if ContinueSelfTest is 12806fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * non-blocking, how do we know that the actions have completed other than 12906fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato * trying again? */ 13006fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato do { 13106fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato result = TlclSendReceiveNoRetry(request, response, max_length); 13206fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato } while (result == TPM_E_DOING_SELFTEST); 13306fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato#endif 13406fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato } 13506fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato#endif /* ! defined(CHROMEOS_ENVIRONMENT) */ 13606fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato return result; 13706fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato} 13806fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato 13939f66114c03639715cb88774255f066a2d942557Randall Spangler/* Sends a command and returns the error code. */ 14089a02c194f1b6da0de7f98784d85e6827c3a1aecLuigi Semenzatostatic uint32_t Send(const uint8_t* command) { 14139f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 142205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler return TlclSendReceive(command, response, sizeof(response)); 14339f66114c03639715cb88774255f066a2d942557Randall Spangler} 14439f66114c03639715cb88774255f066a2d942557Randall Spangler 14539f66114c03639715cb88774255f066a2d942557Randall Spangler/* Exported functions. */ 14639f66114c03639715cb88774255f066a2d942557Randall Spangler 1475d9509cbdee7b9c8dd91ed47d967569dbb9af83dChe-Liang Chiouuint32_t TlclLibInit(void) { 1481b1998dff0002f20b3f27a21e6e79d8951e64684Randall Spangler return VbExTpmInit(); 14939f66114c03639715cb88774255f066a2d942557Randall Spangler} 15039f66114c03639715cb88774255f066a2d942557Randall Spangler 151f9e82e9695d3f208b549cc0208baf24985bbb488Kees Cookuint32_t TlclLibClose(void) { 152f9e82e9695d3f208b549cc0208baf24985bbb488Kees Cook return VbExTpmClose(); 153f9e82e9695d3f208b549cc0208baf24985bbb488Kees Cook} 154f9e82e9695d3f208b549cc0208baf24985bbb488Kees Cook 15539f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclStartup(void) { 1563e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Startup\n")); 15739f66114c03639715cb88774255f066a2d942557Randall Spangler return Send(tpm_startup_cmd.buffer); 15839f66114c03639715cb88774255f066a2d942557Randall Spangler} 15939f66114c03639715cb88774255f066a2d942557Randall Spangler 16054992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzatouint32_t TlclSaveState(void) { 16154992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato VBDEBUG(("TPM: SaveState\n")); 16254992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato return Send(tpm_savestate_cmd.buffer); 16354992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato} 16454992f9d3379c4b048d8da6171f0e578b2db4facLuigi Semenzato 1653da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzatouint32_t TlclResume(void) { 1663da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato VBDEBUG(("TPM: Resume\n")); 1673da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato return Send(tpm_resume_cmd.buffer); 1683da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato} 1693da063e3f7612464a41a4c9b2b31fb7eade57a13Luigi Semenzato 1703e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangleruint32_t TlclSelfTestFull(void) { 1713e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Self test full\n")); 17239f66114c03639715cb88774255f066a2d942557Randall Spangler return Send(tpm_selftestfull_cmd.buffer); 17339f66114c03639715cb88774255f066a2d942557Randall Spangler} 17439f66114c03639715cb88774255f066a2d942557Randall Spangler 17539f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclContinueSelfTest(void) { 17606fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 1773e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Continue self test\n")); 17806fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato /* Call the No Retry version of SendReceive to avoid recursion. */ 17906fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato return TlclSendReceiveNoRetry(tpm_continueselftest_cmd.buffer, 18006fbb168ac49dd63f427beb3907f3c129d81bf84Luigi Semenzato response, sizeof(response)); 18139f66114c03639715cb88774255f066a2d942557Randall Spangler} 18239f66114c03639715cb88774255f066a2d942557Randall Spangler 18339f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) { 184553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah struct s_tpm_nv_definespace_cmd cmd; 1853e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: TlclDefineSpace(0x%x, 0x%x, %d)\n", index, perm, size)); 186553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah Memcpy(&cmd, &tpm_nv_definespace_cmd, sizeof(cmd)); 187553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.index, index); 188553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.perm, perm); 189553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_nv_definespace_cmd.size, size); 190553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah return Send(cmd.buffer); 19139f66114c03639715cb88774255f066a2d942557Randall Spangler} 19239f66114c03639715cb88774255f066a2d942557Randall Spangler 1934abede35afc8b5ecc8165d5d79f77c203bce51fcRandall Spangleruint32_t TlclWrite(uint32_t index, const void* data, uint32_t length) { 194553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah struct s_tpm_nv_write_cmd cmd; 19539f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 19639f66114c03639715cb88774255f066a2d942557Randall Spangler const int total_length = 19739f66114c03639715cb88774255f066a2d942557Randall Spangler kTpmRequestHeaderLength + kWriteInfoLength + length; 19839f66114c03639715cb88774255f066a2d942557Randall Spangler 1993e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: TlclWrite(0x%x, %d)\n", index, length)); 200553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah Memcpy(&cmd, &tpm_nv_write_cmd, sizeof(cmd)); 20132a6526d25d4bf9a1c137fc3d275d1c68935d184Randall Spangler VbAssert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE); 20250d48feb9e0df6a990cc5890ce14e1398798eeb1Luigi Semenzato SetTpmCommandSize(cmd.buffer, total_length); 20339f66114c03639715cb88774255f066a2d942557Randall Spangler 204553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.index, index); 205553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_nv_write_cmd.length, length); 206553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah Memcpy(cmd.buffer + tpm_nv_write_cmd.data, data, length); 20739f66114c03639715cb88774255f066a2d942557Randall Spangler 208205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler return TlclSendReceive(cmd.buffer, response, sizeof(response)); 20939f66114c03639715cb88774255f066a2d942557Randall Spangler} 21039f66114c03639715cb88774255f066a2d942557Randall Spangler 2114abede35afc8b5ecc8165d5d79f77c203bce51fcRandall Spangleruint32_t TlclRead(uint32_t index, void* data, uint32_t length) { 212553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah struct s_tpm_nv_read_cmd cmd; 21339f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 21439f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t result_length; 21539f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t result; 21639f66114c03639715cb88774255f066a2d942557Randall Spangler 2173e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: TlclRead(0x%x, %d)\n", index, length)); 218553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah Memcpy(&cmd, &tpm_nv_read_cmd, sizeof(cmd)); 219553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.index, index); 220553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_nv_read_cmd.length, length); 22139f66114c03639715cb88774255f066a2d942557Randall Spangler 222205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler result = TlclSendReceive(cmd.buffer, response, sizeof(response)); 22339f66114c03639715cb88774255f066a2d942557Randall Spangler if (result == TPM_SUCCESS && length > 0) { 22439f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength; 22539f66114c03639715cb88774255f066a2d942557Randall Spangler FromTpmUint32(nv_read_cursor, &result_length); 22639f66114c03639715cb88774255f066a2d942557Randall Spangler nv_read_cursor += sizeof(uint32_t); 22739f66114c03639715cb88774255f066a2d942557Randall Spangler Memcpy(data, nv_read_cursor, result_length); 22839f66114c03639715cb88774255f066a2d942557Randall Spangler } 22939f66114c03639715cb88774255f066a2d942557Randall Spangler 23039f66114c03639715cb88774255f066a2d942557Randall Spangler return result; 23139f66114c03639715cb88774255f066a2d942557Randall Spangler} 23239f66114c03639715cb88774255f066a2d942557Randall Spangler 233946370d012a809bba833ff9d37fe0ce86af09860Kees Cookuint32_t TlclPCRRead(uint32_t index, void* data, uint32_t length) { 23425d1c25efb6b3ad5b34905d4f8452b4a58613af1Kees Cook struct s_tpm_pcr_read_cmd cmd; 235946370d012a809bba833ff9d37fe0ce86af09860Kees Cook uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 236946370d012a809bba833ff9d37fe0ce86af09860Kees Cook uint32_t result; 237946370d012a809bba833ff9d37fe0ce86af09860Kees Cook 238946370d012a809bba833ff9d37fe0ce86af09860Kees Cook VBDEBUG(("TPM: TlclPCRRead(0x%x, %d)\n", index, length)); 239946370d012a809bba833ff9d37fe0ce86af09860Kees Cook if (length < kPcrDigestLength) { 240946370d012a809bba833ff9d37fe0ce86af09860Kees Cook return TPM_E_IOERROR; 241946370d012a809bba833ff9d37fe0ce86af09860Kees Cook } 242946370d012a809bba833ff9d37fe0ce86af09860Kees Cook Memcpy(&cmd, &tpm_pcr_read_cmd, sizeof(cmd)); 243946370d012a809bba833ff9d37fe0ce86af09860Kees Cook ToTpmUint32(cmd.buffer + tpm_pcr_read_cmd.pcrNum, index); 244946370d012a809bba833ff9d37fe0ce86af09860Kees Cook 245946370d012a809bba833ff9d37fe0ce86af09860Kees Cook result = TlclSendReceive(cmd.buffer, response, sizeof(response)); 246946370d012a809bba833ff9d37fe0ce86af09860Kees Cook if (result == TPM_SUCCESS) { 247946370d012a809bba833ff9d37fe0ce86af09860Kees Cook uint8_t* pcr_read_cursor = response + kTpmResponseHeaderLength; 248946370d012a809bba833ff9d37fe0ce86af09860Kees Cook Memcpy(data, pcr_read_cursor, kPcrDigestLength); 249946370d012a809bba833ff9d37fe0ce86af09860Kees Cook } 250946370d012a809bba833ff9d37fe0ce86af09860Kees Cook 251946370d012a809bba833ff9d37fe0ce86af09860Kees Cook return result; 252946370d012a809bba833ff9d37fe0ce86af09860Kees Cook} 253946370d012a809bba833ff9d37fe0ce86af09860Kees Cook 25439f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclWriteLock(uint32_t index) { 2553e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Write lock 0x%x\n", index)); 25639f66114c03639715cb88774255f066a2d942557Randall Spangler return TlclWrite(index, NULL, 0); 25739f66114c03639715cb88774255f066a2d942557Randall Spangler} 25839f66114c03639715cb88774255f066a2d942557Randall Spangler 25939f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclReadLock(uint32_t index) { 2603e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Read lock 0x%x\n", index)); 26139f66114c03639715cb88774255f066a2d942557Randall Spangler return TlclRead(index, NULL, 0); 26239f66114c03639715cb88774255f066a2d942557Randall Spangler} 26339f66114c03639715cb88774255f066a2d942557Randall Spangler 26439f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclAssertPhysicalPresence(void) { 2653e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Asserting physical presence\n")); 26639f66114c03639715cb88774255f066a2d942557Randall Spangler return Send(tpm_ppassert_cmd.buffer); 26739f66114c03639715cb88774255f066a2d942557Randall Spangler} 26839f66114c03639715cb88774255f066a2d942557Randall Spangler 2691d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzatouint32_t TlclPhysicalPresenceCMDEnable(void) { 2701d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato VBDEBUG(("TPM: Enable the physical presence command\n")); 2711d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato return Send(tpm_ppenable_cmd.buffer); 2721d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato} 2731d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato 274377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzatouint32_t TlclFinalizePhysicalPresence(void) { 275377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato VBDEBUG(("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n")); 276377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato return Send(tpm_finalizepp_cmd.buffer); 277377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato} 278377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato 27939f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclAssertPhysicalPresenceResult(void) { 28039f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 281205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response)); 28239f66114c03639715cb88774255f066a2d942557Randall Spangler} 28339f66114c03639715cb88774255f066a2d942557Randall Spangler 28439f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclLockPhysicalPresence(void) { 2853e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Lock physical presence\n")); 28639f66114c03639715cb88774255f066a2d942557Randall Spangler return Send(tpm_pplock_cmd.buffer); 28739f66114c03639715cb88774255f066a2d942557Randall Spangler} 28839f66114c03639715cb88774255f066a2d942557Randall Spangler 28939f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclSetNvLocked(void) { 2903e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Set NV locked\n")); 29139f66114c03639715cb88774255f066a2d942557Randall Spangler return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0); 29239f66114c03639715cb88774255f066a2d942557Randall Spangler} 29339f66114c03639715cb88774255f066a2d942557Randall Spangler 29439f66114c03639715cb88774255f066a2d942557Randall Spanglerint TlclIsOwned(void) { 29539f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE]; 29639f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t result; 297377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato result = TlclSendReceive(tpm_readpubek_cmd.buffer, 298377557fcb260c9b41abc36ebba5759336436e59cLuigi Semenzato response, sizeof(response)); 29939f66114c03639715cb88774255f066a2d942557Randall Spangler return (result != TPM_SUCCESS); 30039f66114c03639715cb88774255f066a2d942557Randall Spangler} 30139f66114c03639715cb88774255f066a2d942557Randall Spangler 30239f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclForceClear(void) { 3033e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Force clear\n")); 30439f66114c03639715cb88774255f066a2d942557Randall Spangler return Send(tpm_forceclear_cmd.buffer); 30539f66114c03639715cb88774255f066a2d942557Randall Spangler} 30639f66114c03639715cb88774255f066a2d942557Randall Spangler 30739f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclSetEnable(void) { 3083e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Enabling TPM\n")); 30939f66114c03639715cb88774255f066a2d942557Randall Spangler return Send(tpm_physicalenable_cmd.buffer); 31039f66114c03639715cb88774255f066a2d942557Randall Spangler} 31139f66114c03639715cb88774255f066a2d942557Randall Spangler 31239f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclClearEnable(void) { 3133e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: Disabling TPM\n")); 31439f66114c03639715cb88774255f066a2d942557Randall Spangler return Send(tpm_physicaldisable_cmd.buffer); 31539f66114c03639715cb88774255f066a2d942557Randall Spangler} 31639f66114c03639715cb88774255f066a2d942557Randall Spangler 31739f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclSetDeactivated(uint8_t flag) { 318553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah struct s_tpm_physicalsetdeactivated_cmd cmd; 3193e1081fb71385d72fd3a522599c35b516dda7a37Randall Spangler VBDEBUG(("TPM: SetDeactivated(%d)\n", flag)); 32050d48feb9e0df6a990cc5890ce14e1398798eeb1Luigi Semenzato Memcpy(&cmd, &tpm_physicalsetdeactivated_cmd, sizeof(cmd)); 321553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah *(cmd.buffer + cmd.deactivated) = flag; 322553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah return Send(cmd.buffer); 32339f66114c03639715cb88774255f066a2d942557Randall Spangler} 32439f66114c03639715cb88774255f066a2d942557Randall Spangler 3255896b9664d088699e246de964a7c374af663a34eLuigi Semenzatouint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS* pflags) { 32639f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 32739f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t size; 3285896b9664d088699e246de964a7c374af663a34eLuigi Semenzato uint32_t result = 3295896b9664d088699e246de964a7c374af663a34eLuigi Semenzato TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response)); 330205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler if (result != TPM_SUCCESS) 33139f66114c03639715cb88774255f066a2d942557Randall Spangler return result; 33239f66114c03639715cb88774255f066a2d942557Randall Spangler FromTpmUint32(response + kTpmResponseHeaderLength, &size); 3334c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson /* TODO(crbug.com/379255): This fails. Find out why. 3344c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson * VbAssert(size == sizeof(TPM_PERMANENT_FLAGS)); 3354c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson */ 3365896b9664d088699e246de964a7c374af663a34eLuigi Semenzato Memcpy(pflags, 3375896b9664d088699e246de964a7c374af663a34eLuigi Semenzato response + kTpmResponseHeaderLength + sizeof(size), 3385896b9664d088699e246de964a7c374af663a34eLuigi Semenzato sizeof(TPM_PERMANENT_FLAGS)); 3395896b9664d088699e246de964a7c374af663a34eLuigi Semenzato return result; 3405896b9664d088699e246de964a7c374af663a34eLuigi Semenzato} 3415896b9664d088699e246de964a7c374af663a34eLuigi Semenzato 3425896b9664d088699e246de964a7c374af663a34eLuigi Semenzatouint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS* vflags) { 3435896b9664d088699e246de964a7c374af663a34eLuigi Semenzato uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 3445896b9664d088699e246de964a7c374af663a34eLuigi Semenzato uint32_t size; 3455896b9664d088699e246de964a7c374af663a34eLuigi Semenzato uint32_t result = 3465896b9664d088699e246de964a7c374af663a34eLuigi Semenzato TlclSendReceive(tpm_getstclearflags_cmd.buffer, response, sizeof(response)); 3475896b9664d088699e246de964a7c374af663a34eLuigi Semenzato if (result != TPM_SUCCESS) 3485896b9664d088699e246de964a7c374af663a34eLuigi Semenzato return result; 3495896b9664d088699e246de964a7c374af663a34eLuigi Semenzato FromTpmUint32(response + kTpmResponseHeaderLength, &size); 3505896b9664d088699e246de964a7c374af663a34eLuigi Semenzato /* Ugly assertion, but the struct is padded up by one byte. */ 3514c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson /* TODO(crbug.com/379255): This fails. Find out why. 3524c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson * VbAssert(size == 7 && sizeof(TPM_STCLEAR_FLAGS) - 1 == 7); 3534c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson */ 3545896b9664d088699e246de964a7c374af663a34eLuigi Semenzato Memcpy(vflags, 3555896b9664d088699e246de964a7c374af663a34eLuigi Semenzato response + kTpmResponseHeaderLength + sizeof(size), 3565896b9664d088699e246de964a7c374af663a34eLuigi Semenzato sizeof(TPM_STCLEAR_FLAGS)); 35739f66114c03639715cb88774255f066a2d942557Randall Spangler return result; 35839f66114c03639715cb88774255f066a2d942557Randall Spangler} 35939f66114c03639715cb88774255f066a2d942557Randall Spangler 3605896b9664d088699e246de964a7c374af663a34eLuigi Semenzatouint32_t TlclGetFlags(uint8_t* disable, 3615896b9664d088699e246de964a7c374af663a34eLuigi Semenzato uint8_t* deactivated, 3625896b9664d088699e246de964a7c374af663a34eLuigi Semenzato uint8_t *nvlocked) { 3635896b9664d088699e246de964a7c374af663a34eLuigi Semenzato TPM_PERMANENT_FLAGS pflags; 3645896b9664d088699e246de964a7c374af663a34eLuigi Semenzato uint32_t result = TlclGetPermanentFlags(&pflags); 3655896b9664d088699e246de964a7c374af663a34eLuigi Semenzato if (result == TPM_SUCCESS) { 3665896b9664d088699e246de964a7c374af663a34eLuigi Semenzato if (disable) 3675896b9664d088699e246de964a7c374af663a34eLuigi Semenzato *disable = pflags.disable; 3685896b9664d088699e246de964a7c374af663a34eLuigi Semenzato if (deactivated) 3695896b9664d088699e246de964a7c374af663a34eLuigi Semenzato *deactivated = pflags.deactivated; 3705896b9664d088699e246de964a7c374af663a34eLuigi Semenzato if (nvlocked) 3715896b9664d088699e246de964a7c374af663a34eLuigi Semenzato *nvlocked = pflags.nvLocked; 3725896b9664d088699e246de964a7c374af663a34eLuigi Semenzato VBDEBUG(("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n", 3735896b9664d088699e246de964a7c374af663a34eLuigi Semenzato pflags.disable, pflags.deactivated, pflags.nvLocked)); 3745896b9664d088699e246de964a7c374af663a34eLuigi Semenzato } 3755896b9664d088699e246de964a7c374af663a34eLuigi Semenzato return result; 3765896b9664d088699e246de964a7c374af663a34eLuigi Semenzato} 3771d83dd1ba5b825407a8e17972c54577d14ba173dLuigi Semenzato 37839f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclSetGlobalLock(void) { 37939f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t x; 380205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler VBDEBUG(("TPM: Set global lock\n")); 38139f66114c03639715cb88774255f066a2d942557Randall Spangler return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0); 38239f66114c03639715cb88774255f066a2d942557Randall Spangler} 38339f66114c03639715cb88774255f066a2d942557Randall Spangler 384b64faaa7f4167344765eb32baebb0aa01a03bc29Gaurav Shahuint32_t TlclExtend(int pcr_num, const uint8_t* in_digest, 385b64faaa7f4167344765eb32baebb0aa01a03bc29Gaurav Shah uint8_t* out_digest) { 386553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah struct s_tpm_extend_cmd cmd; 38739f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength]; 388205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler uint32_t result; 389ada3fa9ee606c07d7675e235506522fa332c1747Randall Spangler 390ada3fa9ee606c07d7675e235506522fa332c1747Randall Spangler Memcpy(&cmd, &tpm_extend_cmd, sizeof(cmd)); 391553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_extend_cmd.pcrNum, pcr_num); 392553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah Memcpy(cmd.buffer + cmd.inDigest, in_digest, kPcrDigestLength); 393205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler 394205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler result = TlclSendReceive(cmd.buffer, response, sizeof(response)); 395205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler if (result != TPM_SUCCESS) 396205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler return result; 397205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler 39839f66114c03639715cb88774255f066a2d942557Randall Spangler Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength); 399205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler return result; 40039f66114c03639715cb88774255f066a2d942557Randall Spangler} 40139f66114c03639715cb88774255f066a2d942557Randall Spangler 40239f66114c03639715cb88774255f066a2d942557Randall Spangleruint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) { 403553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah struct s_tpm_getpermissions_cmd cmd; 40439f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 40539f66114c03639715cb88774255f066a2d942557Randall Spangler uint8_t* nvdata; 40639f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t result; 40739f66114c03639715cb88774255f066a2d942557Randall Spangler uint32_t size; 40839f66114c03639715cb88774255f066a2d942557Randall Spangler 409553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah Memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd)); 410553d00ec86fed95888dcaff1b911ce8c444d03fdGaurav Shah ToTpmUint32(cmd.buffer + tpm_getpermissions_cmd.index, index); 411205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler result = TlclSendReceive(cmd.buffer, response, sizeof(response)); 412205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler if (result != TPM_SUCCESS) 41339f66114c03639715cb88774255f066a2d942557Randall Spangler return result; 414205190d4ae8080298d9d1b580dd95c885f2af42cRandall Spangler 41539f66114c03639715cb88774255f066a2d942557Randall Spangler nvdata = response + kTpmResponseHeaderLength + sizeof(size); 41639f66114c03639715cb88774255f066a2d942557Randall Spangler FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions); 41739f66114c03639715cb88774255f066a2d942557Randall Spangler return result; 41839f66114c03639715cb88774255f066a2d942557Randall Spangler} 419f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook 4208b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cookuint32_t TlclGetOwnership(uint8_t* owned) { 4218b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 4228b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook uint32_t size; 4238b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook uint32_t result = 4248b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook TlclSendReceive(tpm_getownership_cmd.buffer, response, sizeof(response)); 4258b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook if (result != TPM_SUCCESS) 4268b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook return result; 4278b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook FromTpmUint32(response + kTpmResponseHeaderLength, &size); 4284c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson /* TODO(crbug.com/379255): This fails. Find out why. 4294c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson * VbAssert(size == sizeof(*owned)); 4304c3b4ea3d810a2ed907078a6b9a379442aaf6defBill Richardson */ 4318b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook Memcpy(owned, 4328b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook response + kTpmResponseHeaderLength + sizeof(size), 4338b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook sizeof(*owned)); 4348b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook return result; 4358b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook} 4368b6da26a6e5978a43233f7a43c7bab5889d3817aKees Cook 437f0605cbdc36f58829a908a3333e438c565c8c7afKees Cookuint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size) { 438f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook struct s_tpm_get_random_cmd cmd; 439f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 440f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook uint32_t result; 441f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook 442f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook VBDEBUG(("TPM: TlclGetRandom(%d)\n", length)); 443f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook Memcpy(&cmd, &tpm_get_random_cmd, sizeof(cmd)); 444f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook ToTpmUint32(cmd.buffer + tpm_get_random_cmd.bytesRequested, length); 445f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook /* There must be room in the response buffer for the bytes. */ 446f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook if (length > TPM_LARGE_ENOUGH_COMMAND_SIZE - kTpmResponseHeaderLength 447f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook - sizeof(uint32_t)) { 448f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook return TPM_E_IOERROR; 449f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook } 450f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook 451f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook result = TlclSendReceive(cmd.buffer, response, sizeof(response)); 452f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook if (result == TPM_SUCCESS) { 453f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook uint8_t* get_random_cursor; 454f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook FromTpmUint32(response + kTpmResponseHeaderLength, size); 455f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook 456f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook /* There must be room in the target buffer for the bytes. */ 457f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook if (*size > length) { 458f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook return TPM_E_RESPONSE_TOO_LARGE; 459f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook } 460f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook get_random_cursor = response + kTpmResponseHeaderLength 461f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook + sizeof(uint32_t); 462f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook Memcpy(data, get_random_cursor, *size); 463f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook } 464f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook 465f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook return result; 466f0605cbdc36f58829a908a3333e438c565c8c7afKees Cook} 467