TPM Lite: Add a "firmware" target for building TPM Lite
This CL adds a firmware target for standalone compilation of TPM lite for use in the firmware. In particular, it removes dependencies on external Trouser TSS headers and uses the snapshot version of structures.h which define TPM command structures.
I also removed the include/ directory and moved the tlcl.h header to src/tlcl/ since I think that having a separate directory for just a single header file seems overkill.
Review URL: http://codereview.chromium.org/1787004
diff --git a/src/Makefile b/src/Makefile
index 8f8b208..2762396 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -8,9 +8,12 @@
USE_TPM_EMULATOR ?= 1
default:
- @echo "Usage: make { local | cross } [ USE_TPM_EMULATOR=0 ]"
+ @echo "Usage: make { firmware | local | cross } [ USE_TPM_EMULATOR=0 ]"
@exit 1
+firmware:
+ (cd tlcl; $(MAKE) -f Makefile.firmware)
+
local:
(cd tlcl; $(MAKE) USE_TPM_EMULATOR=$(USE_TPM_EMULATOR))
(cd testsuite; $(MAKE) USE_TPM_EMULATOR=$(USE_TPM_EMULATOR) \
diff --git a/src/testsuite/Makefile b/src/testsuite/Makefile
index 184705b..74ff6fe 100644
--- a/src/testsuite/Makefile
+++ b/src/testsuite/Makefile
@@ -36,7 +36,7 @@
$(CC) $(LDFLAGS) -g $< -o $@ $(LIBS)
.c.o:
- $(CC) $(CFLAGS) -g -c $< -I../include
+ $(CC) $(CFLAGS) -g -c $< -I../tlcl/
clean:
rm -f $(TESTS) *.o *~
diff --git a/src/tlcl/Makefile b/src/tlcl/Makefile
index 0a4500b..4dc1cad 100644
--- a/src/tlcl/Makefile
+++ b/src/tlcl/Makefile
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-INCLUDEDIRS = -I../include -I../../../../third_party/tpm-emulator/tpmd/unix
+INCLUDEDIRS = -I../../../../third_party/tpm-emulator/tpmd/unix
LOCAL_CFLAGS = -g -Wall -Werror $(INCLUDEDIRS)
CFLAGS += $(LOCAL_CFLAGS)
# CFLAGS += -ansi -pedantic
@@ -18,12 +18,12 @@
libtlcl.a: tlcl.o
ar rcs libtlcl.a tlcl.o
-tlcl.o: tlcl.c tlcl_internal.h ../include/tlcl.h structures.h
+tlcl.o: tlcl.c tlcl_internal.h tlcl.h structures.h
structures.h: generator
./generator > structures.h
-generator: generator.c ../include/tlcl.h
+generator: generator.c tlcl.h
$(HOSTCC) $(LOCAL_CFLAGS) -I$(ROOT)/usr/include \
-fpack-struct generator.c -o generator
diff --git a/src/tlcl/Makefile.firmware b/src/tlcl/Makefile.firmware
new file mode 100644
index 0000000..06b4dda
--- /dev/null
+++ b/src/tlcl/Makefile.firmware
@@ -0,0 +1,16 @@
+# 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.
+
+CC ?= gcc
+CFLAGS += -Wall -Werror -ansi -DFIRMWARE
+
+all: firmware
+
+.PHONY: firmware
+
+firmware: tlcl.c tlcl_internal.h tlcl.h saved-structures.h
+ $(CC) -Wall -Werror -ansi -DFIRMWARE -c tlcl.c
+
+clean:
+ rm -f *.o
diff --git a/src/tlcl/structures.h.snapshot b/src/tlcl/saved-structures.h
similarity index 100%
rename from src/tlcl/structures.h.snapshot
rename to src/tlcl/saved-structures.h
diff --git a/src/tlcl/tlcl.c b/src/tlcl/tlcl.c
index f3fb33b..5afe83e 100644
--- a/src/tlcl/tlcl.c
+++ b/src/tlcl/tlcl.c
@@ -12,14 +12,6 @@
* as well as the offsets of the fields that need to be set at run time.
*/
-/* This should change, probably by removing this and defining BIOS in the build.
- */
-#if defined(unix)
-#define BIOS 0
-#else
-#define BIOS 1
-#endif
-
#include "tlcl.h"
#include <errno.h>
@@ -30,15 +22,22 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <tss/tcs.h>
#include <unistd.h>
+#ifdef FIRMWARE
+#include "saved-structures.h"
+#include "tss_constants.h"
+#else
+#include <tss/tcs.h>
#include "structures.h"
+#include "tpmextras.h"
+#endif /* FIRMWARE */
+
#include "tlcl_internal.h"
+
#if USE_TPM_EMULATOR
#include "tpmemu.h"
#endif
-#include "tpmextras.h"
/* The file descriptor for the TPM device.
*/
@@ -50,7 +49,7 @@
/* Print |n| bytes from array |a|, with newlines.
*/
-static void PrintBytes(uint8_t* a, int n) {
+POSSIBLY_UNUSED static void PrintBytes(uint8_t* a, int n) {
int i;
for (i = 0; i < n; i++) {
TlclLog("%02x ", a[i]);
@@ -65,7 +64,7 @@
/* Gets the tag field of a TPM command.
*/
-static INLINE int TpmTag(uint8_t* buffer) {
+POSSIBLY_UNUSED static INLINE int TpmTag(uint8_t* buffer) {
uint16_t tag;
FromTpmUint16(buffer, &tag);
return (int) tag;
@@ -79,7 +78,7 @@
/* Gets the size field of a TPM command.
*/
-static INLINE int TpmCommandSize(const uint8_t* buffer) {
+POSSIBLY_UNUSED static INLINE int TpmCommandSize(const uint8_t* buffer) {
uint32_t size;
FromTpmUint32(buffer + sizeof(uint16_t), &size);
return (int) size;
@@ -110,7 +109,7 @@
}
}
-#if !BIOS
+#ifndef FIRMWARE
/* Executes a command on the TPM.
*/
void TpmExecute(const uint8_t *in, const uint32_t in_len,
@@ -140,26 +139,32 @@
}
}
}
-#endif /* !BIOS */
+#endif /* !FIRMWARE */
/* Sends a request and receive a response.
*/
static void SendReceive(uint8_t* request, uint8_t* response, int max_length) {
+
+#ifdef FIRMWARE
+ /*
+ * FIXME: This #if block should contain the equivalent API call for the
+ * firmware TPM driver which takes a raw sequence of bytes as input
+ * command and a pointer to the output buffer for putting in the results.
+ *
+ * For EFI firmwares, this can make use of the EFI TPM driver as follows
+ * (based on page 16, of TCG EFI Protocol Specs Version 1.20 availaible from
+ * the TCG website):
+ *
+ * EFI_STATUS status;
+ * status = TcgProtocol->EFI_TCG_PASS_THROUGH_TO_TPM(TpmCommandSize(request),
+ * request,
+ * max_length,
+ * response);
+ * // Error checking depending on the value of the status above
+ */
+#else /* FIRMWARE */
uint32_t response_length = max_length;
int tag, response_tag;
-
-#if BIOS
- /*
- * Note: the code included for BIOS has not ever been compiled at Google. It
- * is here only to present what the interface to the EFI driver would look
- * like (see section 3.1.4, TCG EFI protocol specification, page 16). In
- * addition, error handling is not considered.
- */
- EFI_STATUS status;
- status = tgc_pass_through(tcg_protocol,
- TpmCommandSize(request), request,
- max_length, response);
-#else /* BIOS */
#if USE_TPM_EMULATOR
tpmemu_execute(request, TpmCommandSize(request), response, &response_length);
#else
@@ -181,10 +186,8 @@
TlclLog("execution time: %dms\n",
(int) ((after.tv_sec - before.tv_sec) * 1000 +
(after.tv_usec - before.tv_usec) / 1000));
-#endif
-#endif /* BIOS */
+#endif /* !USE_TPM_EMULATOR */
}
-
/* sanity checks */
tag = TpmTag(request);
response_tag = TpmTag(response);
@@ -196,6 +199,8 @@
(tag == TPM_TAG_RQU_AUTH2_COMMAND &&
response_tag == TPM_TAG_RSP_AUTH2_COMMAND));
assert(response_length == TpmCommandSize(response));
+#endif /* FIRMWARE */
+
}
/* Sends a command and checks the result for errors. Note that this error
@@ -229,12 +234,12 @@
#if USE_TPM_EMULATOR
tpmemu_init();
#else
-#if !BIOS
+#if !FIRMWARE
tpm_fd = open("/dev/tpm0", O_RDWR);
if (tpm_fd < 0) {
error("cannot open TPM device: %s\n", strerror(errno));
}
-#endif /* !BIOS */
+#endif /* !FIRMWARE */
#endif /* USE_TPM_EMULATOR */
}
diff --git a/src/include/tlcl.h b/src/tlcl/tlcl.h
similarity index 99%
rename from src/include/tlcl.h
rename to src/tlcl/tlcl.h
index 632d846..420bf41 100644
--- a/src/include/tlcl.h
+++ b/src/tlcl/tlcl.h
@@ -131,6 +131,5 @@
/* Sets the bGlobalLock flag, which only a reboot can clear.
*/
void TlclSetGlobalLock(void);
-
#endif /* TPM_LITE_TLCL_H_ */
diff --git a/src/tlcl/tlcl_internal.h b/src/tlcl/tlcl_internal.h
index e078fa9..e1059ee 100644
--- a/src/tlcl/tlcl_internal.h
+++ b/src/tlcl/tlcl_internal.h
@@ -62,4 +62,4 @@
const int kTpmReadInfoLength = 12;
const int kEncAuthLength = 20;
-#endif
+#endif /* TPM_LITE_TLCL_INTERNAL_H_ */
diff --git a/src/tlcl/tss_constants.h b/src/tlcl/tss_constants.h
new file mode 100644
index 0000000..a25fb43
--- /dev/null
+++ b/src/tlcl/tss_constants.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.
+ *
+ * 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 <stdint.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_NV_INDEX0 ((uint32_t)0x00000000)
+#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
+
+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_ */