Index: src/platform/tpm_lite/src/tlcl/tlcl.c |
diff --git a/src/platform/tpm_lite/src/tlcl/tlcl.c b/src/platform/tpm_lite/src/tlcl/tlcl.c |
index 916fb9fb200bbdb854a9ee762194f8ee4d6d524d..b505f7238070c310ade69a79b39ec73d2649685f 100644 |
--- a/src/platform/tpm_lite/src/tlcl/tlcl.c |
+++ b/src/platform/tpm_lite/src/tlcl/tlcl.c |
@@ -14,14 +14,40 @@ |
#include "tlcl.h" |
+#include <errno.h> |
+#include <fcntl.h> |
#include <string.h> |
+#include <sys/types.h> |
+#include <sys/stat.h> |
#include <tss/tcs.h> |
+#include <unistd.h> |
#include "structures.h" |
#include "tlcl_internal.h" |
+#if USE_TPM_EMULATOR |
#include "tpmemu.h" |
+#endif |
#include "tpmextras.h" |
+/* The file descriptor for the TPM device. |
+ */ |
+int tpm_fd = -1; |
+ |
+/* Print |n| bytes from array |a|, with newlines. |
+ */ |
+static void PrintBytes(uint8_t* a, int n) { |
+ int i; |
+ for (i = 0; i < n; i++) { |
+ printf("%02x ", a[i]); |
+ if ((i + 1) % 16 == 0) { |
+ printf("\n"); |
+ } |
+ } |
+ if (i % 16 != 0) { |
+ printf("\n"); |
+ } |
+} |
+ |
/* Gets the tag field of a TPM command. |
*/ |
static INLINE int TpmTag(uint8_t* buffer) { |
@@ -33,14 +59,14 @@ static INLINE int TpmTag(uint8_t* buffer) { |
/* Sets the size field of a TPM command. |
*/ |
static INLINE void SetTpmCommandSize(uint8_t* buffer, uint32_t size) { |
- ToTpmUint32(buffer + 2, size); |
+ ToTpmUint32(buffer + sizeof(uint16_t), size); |
} |
/* Gets the size field of a TPM command. |
*/ |
static INLINE int TpmCommandSize(const uint8_t* buffer) { |
uint32_t size; |
- FromTpmUint32(buffer + 2, &size); |
+ FromTpmUint32(buffer + sizeof(uint16_t), &size); |
return (int) size; |
} |
@@ -48,11 +74,11 @@ static INLINE int TpmCommandSize(const uint8_t* buffer) { |
*/ |
static INLINE int TpmCommandCode(const uint8_t* buffer) { |
uint32_t code; |
- FromTpmUint32(buffer + 6, &code); |
+ FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code); |
return code; |
} |
-/* Gets the code field of a TPM result. |
+/* Gets the return code field of a TPM result. |
*/ |
static INLINE int TpmReturnCode(const uint8_t* buffer) { |
return TpmCommandCode(buffer); |
@@ -64,8 +90,38 @@ static void CheckResult(uint8_t* request, uint8_t* response, bool warn_only) { |
int command = TpmCommandCode(request); |
int result = TpmReturnCode(response); |
if (result != TPM_SUCCESS) { |
- (warn_only? warning : error)("command 0x%x failed: 0x%x\n", |
- command, result); |
+ (warn_only? warning : error)("command %d 0x%x failed: %d 0x%x\n", |
+ command, command, result, result); |
+ } |
+} |
+ |
+/* Executes a command on the TPM. |
+ */ |
+void TpmExecute(const uint8_t *in, const uint32_t in_len, |
+ uint8_t *out, uint32_t *pout_len) { |
+ uint8_t response[TPM_MAX_COMMAND_SIZE]; |
+ if (in_len <= 0) { |
+ error("invalid command length %d\n", in_len); |
+ } else if (tpm_fd < 0) { |
+ error("the TPM device was not opened. Forgot to call TlclLibinit?\n"); |
+ } else { |
+ int n = write(tpm_fd, in, in_len); |
+ if (n != in_len) { |
+ error("write failure to TPM device: %s\n", strerror(errno)); |
+ } |
+ n = read(tpm_fd, response, sizeof(response)); |
+ if (n == 0) { |
+ error("null read from TPM device\n"); |
+ } else if (n < 0) { |
+ error("read failure from TPM device: %s\n", strerror(errno)); |
+ } else { |
+ if (n > *pout_len) { |
+ error("TPM response too long for output buffer\n"); |
+ } else { |
+ *pout_len = n; |
+ memcpy(out, response, n); |
+ } |
+ } |
} |
} |
@@ -75,7 +131,22 @@ static void SendReceive(uint8_t* request, uint8_t* response, int max_length) { |
uint32_t response_length = max_length; |
int tag, response_tag; |
+#if USE_TPM_EMULATOR |
tpmemu_execute(request, TpmCommandSize(request), response, &response_length); |
+#else |
+ TpmExecute(request, TpmCommandSize(request), response, &response_length); |
+#endif |
+ |
+ { |
+ int x = TpmCommandSize(request); |
+ int y = response_length; |
+ printf("request (%d bytes): ", x); |
+ PrintBytes(request, 10); |
+ PrintBytes(request + 10, x - 10); |
+ printf("response (%d bytes): ", y); |
+ PrintBytes(response, 10); |
+ PrintBytes(response + 10, y - 10); |
+ } |
/* sanity checks */ |
tag = TpmTag(request); |
@@ -105,7 +176,14 @@ static void Send(uint8_t* command) { |
*/ |
void TlclLibinit(void) { |
+#if USE_TPM_EMULATOR |
tpmemu_init(); |
+#else |
+ tpm_fd = open("/dev/tpm0", O_RDWR); |
+ if (tpm_fd < 0) { |
+ error("cannot open TPM device: %s\n", strerror(errno)); |
+ } |
+#endif |
} |
void TlclStartup(void) { |
@@ -162,11 +240,15 @@ uint32_t TlclRead(uint32_t index, uint8_t* data, uint32_t length) { |
} |
void TlclWriteLock(uint32_t index) { |
- (void) TlclWrite(index, NULL, 0); |
+ if (TlclWrite(index, NULL, 0) != TPM_SUCCESS) { |
+ error("failed to write lock space 0x%x\n", index); |
+ } |
} |
void TlclReadLock(uint32_t index) { |
- (void) TlclRead(index, NULL, 0); |
+ if (TlclRead(index, NULL, 0) != TPM_SUCCESS) { |
+ error("failed to read lock space 0x%x\n", index); |
+ } |
} |
void TlclAssertPhysicalPresence(void) { |
@@ -176,3 +258,11 @@ void TlclAssertPhysicalPresence(void) { |
void TlclSetNvLocked(void) { |
TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0); |
} |
+ |
+int TlclIsOwned(void) { |
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE]; |
+ uint32_t result; |
+ SendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response)); |
+ result = TpmReturnCode(response); |
+ return (result != TPM_SUCCESS); |
+} |