summaryrefslogtreecommitdiff
path: root/firmware/lib/tpm_lite
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2010-07-14 09:10:23 -0700
committerRandall Spangler <rspangler@chromium.org>2010-07-14 09:10:23 -0700
commit39f66114c03639715cb88774255f066a2d942557 (patch)
tree35d7d984412a124d252ad399c2b5e87b6e92ebfd /firmware/lib/tpm_lite
parent64aec24de8ac23707b97a8d8505b559dc2b204f1 (diff)
downloadvboot-39f66114c03639715cb88774255f066a2d942557.tar.gz
Add tpm lite to vboot reference
Review URL: http://codereview.chromium.org/2919010
Diffstat (limited to 'firmware/lib/tpm_lite')
-rw-r--r--firmware/lib/tpm_lite/include/tlcl.h141
-rw-r--r--firmware/lib/tpm_lite/include/tlcl_internal.h61
-rw-r--r--firmware/lib/tpm_lite/include/tlcl_structures.h96
-rw-r--r--firmware/lib/tpm_lite/include/tss_constants.h73
-rw-r--r--firmware/lib/tpm_lite/tlcl.c241
5 files changed, 612 insertions, 0 deletions
diff --git a/firmware/lib/tpm_lite/include/tlcl.h b/firmware/lib/tpm_lite/include/tlcl.h
new file mode 100644
index 00000000..5dfd7ef7
--- /dev/null
+++ b/firmware/lib/tpm_lite/include/tlcl.h
@@ -0,0 +1,141 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* TPM Lightweight Command Library.
+ *
+ * A low-level library for interfacing to TPM hardware or an emulator.
+ */
+
+#ifndef TPM_LITE_TLCL_H_
+#define TPM_LITE_TLCL_H_
+
+#include "sysincludes.h"
+
+/*****************************************************************************/
+/* Functions to be implemented by the stub library */
+
+/* Initialize the stub library */
+void TlclStubInit(void);
+
+/* Close and open the device. This is needed for running more complex commands
+ * at user level, such as TPM_TakeOwnership, since the TPM device can be opened
+ * only by one process at a time.
+ */
+void TlclCloseDevice(void);
+void TlclOpenDevice(void);
+
+void TlclStubSendReceive(uint8_t* request, int request_length,
+ uint8_t* response, int max_length);
+
+/*****************************************************************************/
+/* Functions implemented in tlcl.c */
+
+/* Call this first.
+ */
+void TlclLibInit(void);
+
+
+/* Logs to stdout. Arguments like printf.
+ */
+void TlclLog(char* format, ...);
+
+/* Sets the log level. 0 is quietest.
+ */
+void TlclSetLogLevel(int level);
+
+/* Sends a TPM_Startup(ST_CLEAR). The TPM error code is returned (0
+ * for success).
+ */
+uint32_t TlclStartup(void);
+
+/* Run the self test. Note---this is synchronous. To run this in parallel
+ * with other firmware, use ContinueSelfTest. The TPM error code is returned.
+ */
+uint32_t TlclSelftestfull(void);
+
+/* Runs the self test in the background.
+ */
+uint32_t TlclContinueSelfTest(void);
+
+/* Defines a space with permission [perm]. [index] is the index for the space,
+ * [size] the usable data size. The TPM error code is returned.
+ */
+uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size);
+
+/* Defines a space with permission [perm]. [index] is the index for the space,
+ * [size] the usable data size. Returns the TPM error code.
+ */
+uint32_t TlclDefineSpaceResult(uint32_t index, uint32_t perm, uint32_t size);
+
+/* Writes [length] bytes of [data] to space at [index]. The TPM error code is
+ * returned.
+ */
+uint32_t TlclWrite(uint32_t index, uint8_t *data, uint32_t length);
+
+/* Reads [length] bytes from space at [index] into [data]. The TPM error code
+ * is returned.
+ */
+uint32_t TlclRead(uint32_t index, uint8_t *data, uint32_t length);
+
+/* Write-locks space at [index]. The TPM error code is returned.
+ */
+uint32_t TlclWriteLock(uint32_t index);
+
+/* Read-locks space at [index]. The TPM error code is returned.
+ */
+uint32_t TlclReadLock(uint32_t index);
+
+/* Asserts physical presence in software. The TPM error code is returned.
+ */
+uint32_t TlclAssertPhysicalPresence(void);
+
+/* Turns off physical presence and locks it off until next reboot. The TPM
+ * error code is returned.
+ */
+uint32_t TlclLockPhysicalPresence(void);
+
+/* Sets the nvLocked bit. The TPM error code is returned.
+ */
+uint32_t TlclSetNvLocked(void);
+
+/* Returns 1 if the TPM is owned, 0 otherwise.
+ */
+int TlclIsOwned(void);
+
+/* Issues a ForceClear. The TPM error code is returned.
+ */
+uint32_t TlclForceClear(void);
+
+/* Issues a PhysicalEnable. The TPM error code is returned.
+ */
+uint32_t TlclSetEnable(void);
+
+/* Issues a PhysicalDisable. The TPM error code is returned.
+ */
+uint32_t TlclClearEnable(void);
+
+/* Issues a SetDeactivated. Pass 0 to activate. Returns result code.
+ */
+uint32_t TlclSetDeactivated(uint8_t flag);
+
+/* Gets flags of interest. (Add more here as needed.) The TPM error code is
+ * returned.
+ */
+uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated);
+
+/* Sets the bGlobalLock flag, which only a reboot can clear. The TPM error
+ * code is returned.
+ */
+uint32_t TlclSetGlobalLock(void);
+
+/* Performs a TPM_Extend.
+ */
+uint32_t TlclExtend(int pcr_num, uint8_t* in_digest, uint8_t* out_digest);
+
+/* Gets the permission bits for the NVRAM space with |index|.
+ */
+uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions);
+
+#endif /* TPM_LITE_TLCL_H_ */
diff --git a/firmware/lib/tpm_lite/include/tlcl_internal.h b/firmware/lib/tpm_lite/include/tlcl_internal.h
new file mode 100644
index 00000000..91d3ee15
--- /dev/null
+++ b/firmware/lib/tpm_lite/include/tlcl_internal.h
@@ -0,0 +1,61 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef TPM_LITE_TLCL_INTERNAL_H_
+#define TPM_LITE_TLCL_INTERNAL_H_
+
+/*
+ * These numbers derive from adding the sizes of command fields as shown in the
+ * TPM commands manual.
+ */
+#define kTpmRequestHeaderLength 10
+#define kTpmResponseHeaderLength 10
+#define kTpmReadInfoLength 12
+#define kEncAuthLength 20
+#define kPcrDigestLength 20
+
+
+/*
+ * Conversion functions. ToTpmTYPE puts a value of type TYPE into a TPM
+ * command buffer. FromTpmTYPE gets a value of type TYPE from a TPM command
+ * buffer into a variable.
+ */
+POSSIBLY_UNUSED
+static INLINE void ToTpmUint32(uint8_t *buffer, uint32_t x) {
+ buffer[0] = (uint8_t)(x >> 24);
+ buffer[1] = (uint8_t)((x >> 16) & 0xff);
+ buffer[2] = (uint8_t)((x >> 8) & 0xff);
+ buffer[3] = (uint8_t)(x & 0xff);
+}
+
+/*
+ * See comment for above function.
+ */
+POSSIBLY_UNUSED
+static INLINE void FromTpmUint32(const uint8_t *buffer, uint32_t *x) {
+ *x = ((buffer[0] << 24) |
+ (buffer[1] << 16) |
+ (buffer[2] << 8) |
+ buffer[3]);
+}
+
+/*
+ * See comment for above function.
+ */
+POSSIBLY_UNUSED
+static INLINE void ToTpmUint16(uint8_t *buffer, uint16_t x) {
+ buffer[0] = (uint8_t)(x >> 8);
+ buffer[1] = (uint8_t)(x & 0xff);
+}
+
+/*
+ * See comment for above function.
+ */
+POSSIBLY_UNUSED
+static INLINE void FromTpmUint16(const uint8_t *buffer, uint16_t *x) {
+ *x = (buffer[0] << 8) | buffer[1];
+}
+
+#endif /* TPM_LITE_TLCL_INTERNAL_H_ */
diff --git a/firmware/lib/tpm_lite/include/tlcl_structures.h b/firmware/lib/tpm_lite/include/tlcl_structures.h
new file mode 100644
index 00000000..85754bb2
--- /dev/null
+++ b/firmware/lib/tpm_lite/include/tlcl_structures.h
@@ -0,0 +1,96 @@
+/* This file is automatically generated */
+
+struct {
+ uint8_t buffer[34];
+ uint8_t* pcrNum;
+ uint8_t* inDigest;
+} tpm_extend_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14, },
+tpm_extend_cmd.buffer + 10, tpm_extend_cmd.buffer + 14, };
+
+struct {
+ uint8_t buffer[22];
+ uint8_t* index;
+} tpm_getpermissions_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x11, 0x0, 0x0, 0x0, 0x4, },
+tpm_getpermissions_cmd.buffer + 18, };
+
+struct {
+ uint8_t buffer[22];
+} tpm_getflags_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x1, 0x8, },
+};
+
+struct {
+ uint8_t buffer[11];
+ uint8_t* deactivated;
+} tpm_physicalsetdeactivated_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72, },
+tpm_physicalsetdeactivated_cmd.buffer + 10, };
+
+struct {
+ uint8_t buffer[10];
+} tpm_physicalenable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f, },
+};
+
+struct {
+ uint8_t buffer[10];
+} tpm_physicaldisable_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70, },
+};
+
+struct {
+ uint8_t buffer[10];
+} tpm_forceclear_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d, },
+};
+
+struct {
+ uint8_t buffer[30];
+} tpm_readpubek_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c, },
+};
+
+struct {
+ uint8_t buffer[10];
+} tpm_continueselftest_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53, },
+};
+
+struct {
+ uint8_t buffer[10];
+} tpm_selftestfull_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50, },
+};
+
+struct {
+ uint8_t buffer[12];
+} tpm_startup_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1, },
+};
+
+struct {
+ uint8_t buffer[12];
+} tpm_pplock_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x4, },
+};
+
+struct {
+ uint8_t buffer[12];
+} tpm_ppassert_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x8, },
+};
+
+struct {
+ uint8_t buffer[22];
+ uint8_t* index;
+ uint8_t* length;
+} tpm_nv_read_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf, },
+tpm_nv_read_cmd.buffer + 10, tpm_nv_read_cmd.buffer + 18, };
+
+struct {
+ uint8_t buffer[256];
+ uint8_t* index;
+ uint8_t* length;
+ uint8_t* data;
+} tpm_nv_write_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd, },
+tpm_nv_write_cmd.buffer + 10, tpm_nv_write_cmd.buffer + 18, tpm_nv_write_cmd.buffer + 22, };
+
+struct {
+ uint8_t buffer[101];
+ uint8_t* index;
+ uint8_t* perm;
+ uint8_t* size;
+} tpm_nv_definespace_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0xcc, 0x0, 0x18, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x3, 0, 0, 0, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0, 0x17, },
+tpm_nv_definespace_cmd.buffer + 12, tpm_nv_definespace_cmd.buffer + 70, tpm_nv_definespace_cmd.buffer + 77, };
+
+const int kWriteInfoLength = 12;
+const int kNvDataPublicPermissionsOffset = 60;
diff --git a/firmware/lib/tpm_lite/include/tss_constants.h b/firmware/lib/tpm_lite/include/tss_constants.h
new file mode 100644
index 00000000..aaeacbea
--- /dev/null
+++ b/firmware/lib/tpm_lite/include/tss_constants.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Some TPM constants and type definitions for standalone compilation for use in
+ * the firmware
+ */
+
+#ifndef TPM_LITE_TSS_CONSTANTS_H_
+#define TPM_LITE_TSS_CONSTANTS_H_
+
+#include "sysincludes.h"
+
+#define TPM_MAX_COMMAND_SIZE 4096
+#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
+
+#define TPM_SUCCESS ((uint32_t)0x00000000)
+#define TPM_E_BADINDEX ((uint32_t)0x00000002)
+#define TPM_E_MAXNVWRITES ((uint32_t)0x00000048)
+#define TPM_E_OWNER_SET ((uint32_t)0x00000014)
+
+#define TPM_E_ALREADY_INITIALIZED ((uint32_t)0x00005000) /* vboot local */
+#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_NV_INDEX0 ((uint32_t)0x00000000)
+#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
+#define TPM_NV_PER_WRITE_STCLEAR (((uint32_t)1)<<14)
+#define TPM_NV_PER_PPWRITE (((uint32_t)1)<<0)
+#define TPM_NV_PER_GLOBALLOCK (((uint32_t)1)<<15)
+
+typedef uint8_t TSS_BOOL;
+typedef uint16_t TPM_STRUCTURE_TAG;
+
+typedef struct tdTPM_WRITE_INFO {
+ uint32_t nvIndex;
+ uint32_t offset;
+ uint32_t dataSize;
+} TPM_WRITE_INFO;
+
+typedef struct tdTPM_PERMANENT_FLAGS
+{
+ TPM_STRUCTURE_TAG tag;
+ TSS_BOOL disable;
+ TSS_BOOL ownership;
+ TSS_BOOL deactivated;
+ TSS_BOOL readPubek;
+ TSS_BOOL disableOwnerClear;
+ TSS_BOOL allowMaintenance;
+ TSS_BOOL physicalPresenceLifetimeLock;
+ TSS_BOOL physicalPresenceHWEnable;
+ TSS_BOOL physicalPresenceCMDEnable;
+ TSS_BOOL CEKPUsed;
+ TSS_BOOL TPMpost;
+ TSS_BOOL TPMpostLock;
+ TSS_BOOL FIPS;
+ TSS_BOOL Operator;
+ TSS_BOOL enableRevokeEK;
+ TSS_BOOL nvLocked;
+ TSS_BOOL readSRKPub;
+ TSS_BOOL tpmEstablished;
+ TSS_BOOL maintenanceDone;
+ TSS_BOOL disableFullDALogicInfo;
+} TPM_PERMANENT_FLAGS;
+
+#define TPM_ALL_LOCALITIES (TPM_LOC_ZERO | TPM_LOC_ONE | TPM_LOC_TWO \
+ | TPM_LOC_THREE | TPM_LOC_FOUR) /* 0x1f */
+
+#define TPM_ENCAUTH_SIZE 20
+#define TPM_PUBEK_SIZE 256
+
+#endif /* TPM_LITE_TSS_CONSTANTS_H_ */
diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c
new file mode 100644
index 00000000..4ca8b87e
--- /dev/null
+++ b/firmware/lib/tpm_lite/tlcl.c
@@ -0,0 +1,241 @@
+/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* A lightweight TPM command library.
+ *
+ * The general idea is that TPM commands are array of bytes whose
+ * fields are mostly compile-time constant. The goal is to build much
+ * of the commands at compile time (or build time) and change some of
+ * the fields at run time as needed. The code in
+ * utility/tlcl_generator.c builds structures containing the commands,
+ * as well as the offsets of the fields that need to be set at run
+ * time.
+ */
+
+#include "sysincludes.h"
+#include "tlcl.h"
+#include "tlcl_internal.h"
+#include "tlcl_structures.h"
+#include "tss_constants.h"
+#include "utility.h"
+
+
+/* Sets the size field of a TPM command. */
+static INLINE void SetTpmCommandSize(uint8_t* buffer, uint32_t size) {
+ ToTpmUint32(buffer + sizeof(uint16_t), size);
+}
+
+/* Gets the size field of a TPM command. */
+POSSIBLY_UNUSED static INLINE int TpmCommandSize(const uint8_t* buffer) {
+ uint32_t size;
+ FromTpmUint32(buffer + sizeof(uint16_t), &size);
+ return (int) size;
+}
+
+/* Gets the code field of a TPM command. */
+static INLINE int TpmCommandCode(const uint8_t* buffer) {
+ uint32_t code;
+ FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
+ return code;
+}
+
+/* Gets the return code field of a TPM result. */
+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 %d 0x%x failed: %d 0x%x\n",
+ command, command, result, result));
+ else
+ error("TPM command %d 0x%x failed: %d 0x%x\n",
+ command, command, result, result);
+ }
+}
+
+/* Sends a TPM command and gets a response. */
+static void TlclSendReceive(uint8_t* request, uint8_t* response,
+ int max_length) {
+ TlclStubSendReceive(request, TpmCommandSize(request),
+ response, max_length);
+}
+
+
+/* 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);
+}
+
+/* Exported functions. */
+
+void TlclLibInit(void) {
+ TlclStubInit();
+}
+
+uint32_t TlclStartup(void) {
+ return Send(tpm_startup_cmd.buffer);
+}
+
+uint32_t TlclSelftestfull(void) {
+ return Send(tpm_selftestfull_cmd.buffer);
+}
+
+uint32_t TlclContinueSelfTest(void) {
+ return Send(tpm_continueselftest_cmd.buffer);
+}
+
+uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) {
+ ToTpmUint32(tpm_nv_definespace_cmd.index, index);
+ ToTpmUint32(tpm_nv_definespace_cmd.perm, perm);
+ ToTpmUint32(tpm_nv_definespace_cmd.size, size);
+ return Send(tpm_nv_definespace_cmd.buffer);
+}
+
+uint32_t TlclWrite(uint32_t index, uint8_t* data, uint32_t length) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ const int total_length =
+ kTpmRequestHeaderLength + kWriteInfoLength + length;
+
+ assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ SetTpmCommandSize(tpm_nv_write_cmd.buffer, total_length);
+
+ ToTpmUint32(tpm_nv_write_cmd.index, index);
+ ToTpmUint32(tpm_nv_write_cmd.length, length);
+ Memcpy(tpm_nv_write_cmd.data, data, length);
+
+ TlclSendReceive(tpm_nv_write_cmd.buffer, response, sizeof(response));
+ CheckResult(tpm_nv_write_cmd.buffer, response, 1);
+
+ return TpmReturnCode(response);
+}
+
+uint32_t TlclRead(uint32_t index, uint8_t* data, uint32_t length) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint32_t result_length;
+ uint32_t result;
+
+ ToTpmUint32(tpm_nv_read_cmd.index, index);
+ ToTpmUint32(tpm_nv_read_cmd.length, length);
+
+ TlclSendReceive(tpm_nv_read_cmd.buffer, response, sizeof(response));
+ result = TpmReturnCode(response);
+ if (result == TPM_SUCCESS && length > 0) {
+ uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
+ FromTpmUint32(nv_read_cursor, &result_length);
+ nv_read_cursor += sizeof(uint32_t);
+ Memcpy(data, nv_read_cursor, result_length);
+ }
+
+ return result;
+}
+
+uint32_t TlclWriteLock(uint32_t index) {
+ return TlclWrite(index, NULL, 0);
+}
+
+uint32_t TlclReadLock(uint32_t index) {
+ return TlclRead(index, NULL, 0);
+}
+
+uint32_t TlclAssertPhysicalPresence(void) {
+ return Send(tpm_ppassert_cmd.buffer);
+}
+
+uint32_t TlclAssertPhysicalPresenceResult(void) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response));
+ return TpmReturnCode(response);
+}
+
+uint32_t TlclLockPhysicalPresence(void) {
+ return Send(tpm_pplock_cmd.buffer);
+}
+
+uint32_t TlclSetNvLocked(void) {
+ return TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0);
+}
+
+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);
+ return (result != TPM_SUCCESS);
+}
+
+uint32_t TlclForceClear(void) {
+ return Send(tpm_forceclear_cmd.buffer);
+}
+
+uint32_t TlclSetEnable(void) {
+ return Send(tpm_physicalenable_cmd.buffer);
+}
+
+uint32_t TlclClearEnable(void) {
+ return Send(tpm_physicaldisable_cmd.buffer);
+}
+
+uint32_t TlclSetDeactivated(uint8_t flag) {
+ *((uint8_t*)tpm_physicalsetdeactivated_cmd.deactivated) = flag;
+ return Send(tpm_physicalsetdeactivated_cmd.buffer);
+}
+
+uint32_t TlclGetFlags(uint8_t* disable, uint8_t* deactivated) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ TPM_PERMANENT_FLAGS* pflags;
+ uint32_t result;
+ uint32_t size;
+
+ TlclSendReceive(tpm_getflags_cmd.buffer, response, sizeof(response));
+ result = TpmReturnCode(response);
+ if (result != TPM_SUCCESS) {
+ return result;
+ }
+ FromTpmUint32(response + kTpmResponseHeaderLength, &size);
+ assert(size == sizeof(TPM_PERMANENT_FLAGS));
+ pflags =
+ (TPM_PERMANENT_FLAGS*) (response + kTpmResponseHeaderLength + sizeof(size));
+ *disable = pflags->disable;
+ *deactivated = pflags->deactivated;
+ return result;
+}
+
+uint32_t TlclSetGlobalLock(void) {
+ uint32_t x;
+ return TlclWrite(TPM_NV_INDEX0, (uint8_t*) &x, 0);
+}
+
+uint32_t TlclExtend(int pcr_num, uint8_t* in_digest, uint8_t* out_digest) {
+ uint8_t response[kTpmResponseHeaderLength + kPcrDigestLength];
+ ToTpmUint32(tpm_extend_cmd.pcrNum, pcr_num);
+ Memcpy(tpm_extend_cmd.inDigest, in_digest, kPcrDigestLength);
+ TlclSendReceive(tpm_extend_cmd.buffer, response, sizeof(response));
+ Memcpy(out_digest, response + kTpmResponseHeaderLength, kPcrDigestLength);
+ return TpmReturnCode(response);
+}
+
+uint32_t TlclGetPermissions(uint32_t index, uint32_t* permissions) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint8_t* nvdata;
+ uint32_t result;
+ uint32_t size;
+
+ ToTpmUint32(tpm_getpermissions_cmd.index, index);
+ TlclSendReceive(tpm_getpermissions_cmd.buffer, response, sizeof(response));
+ result = TpmReturnCode(response);
+ if (result != TPM_SUCCESS) {
+ return result;
+ }
+ nvdata = response + kTpmResponseHeaderLength + sizeof(size);
+ FromTpmUint32(nvdata + kNvDataPublicPermissionsOffset, permissions);
+ return result;
+}