summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Pronin <apronin@google.com>2016-07-06 19:10:46 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-07-15 19:23:56 -0700
commit1becb0dabecf6d15b0e7d88704fda86b3912be4c (patch)
treeb4169adb80f6470d9ed08c6e5ff3af19bee3194c
parentd5820a79fc1354d68ead43a3bf88bdee8a6a2f3d (diff)
downloadvboot-1becb0dabecf6d15b0e7d88704fda86b3912be4c.tar.gz
Stub tlcl implementation for tpm2 case
Build a special version of TPM Lightweight Command Library in libvboot_host for TPM2. Create the framework for implementation, stub functions for now. libvboot_host is used by tpmc and other user-space utilities that talk directly to tpm bypassing trunks/trousers. BRANCH=none BUG=chrome-os-partner:54981 BUG=chrome-os-partner:55210 TEST=Boot on kevin, verify that 'tpmc read' works. Change-Id: I4cc41028041193041defc319687697eb9edb1f3e Reviewed-on: https://chromium-review.googlesource.com/358623 Commit-Ready: Andrey Pronin <apronin@chromium.org> Tested-by: Stephen Barber <smbarber@chromium.org> Tested-by: Andrey Pronin <apronin@chromium.org> Reviewed-by: Stephen Barber <smbarber@chromium.org>
-rw-r--r--Makefile49
-rw-r--r--firmware/include/tpm2_tss_constants.h14
-rw-r--r--firmware/lib/rollback_index.c4
-rw-r--r--firmware/lib/tpm2_lite/tlcl.c128
-rw-r--r--firmware/linktest/main.c10
-rw-r--r--utility/tpmc.c32
6 files changed, 218 insertions, 19 deletions
diff --git a/Makefile b/Makefile
index a5460c2c..2cfd2060 100644
--- a/Makefile
+++ b/Makefile
@@ -385,18 +385,22 @@ BDBLIB_SRCS = \
firmware/bdb/stub.c \
firmware/bdb/nvm.c
-# Support real TPM unless BIOS sets MOCK_TPM
-ifeq (${MOCK_TPM},)
-VBINIT_SRCS += \
- firmware/lib/rollback_index.c
+# TPM lightweight command library
ifeq (${TPM2_MODE},)
-VBINIT_SRCS += \
+TLCL_SRCS = \
firmware/lib/tpm_lite/tlcl.c
else
-VBINIT_SRCS += \
+TLCL_SRCS = \
firmware/lib/tpm2_lite/tlcl.c \
firmware/lib/tpm2_lite/marshaling.c
endif
+TLCL_OBJS_FOR_TEST = $(TLCL_SRCS:%.c=${BUILD}/%_for_test.o)
+
+# Support real TPM unless BIOS sets MOCK_TPM
+ifeq (${MOCK_TPM},)
+VBINIT_SRCS += \
+ firmware/lib/rollback_index.c \
+ ${TLCL_SRCS}
VBSF_SRCS += \
firmware/lib/tpm_bootmode.c
@@ -505,7 +509,7 @@ HOSTLIB_SRCS = \
firmware/lib/cgptlib/crc32.c \
firmware/lib/crc8.c \
firmware/lib/gpt_misc.c \
- firmware/lib/tpm_lite/tlcl.c \
+ ${TLCL_SRCS} \
firmware/lib/utility_string.c \
firmware/lib/vboot_nvstorage.c \
firmware/stub/tpm_lite_stub.c \
@@ -607,10 +611,13 @@ UTIL_NAMES_STATIC = \
utility/crossystem
UTIL_NAMES = ${UTIL_NAMES_STATIC} \
- utility/tpm_init_temp_fix \
utility/dumpRSAPublicKey \
utility/tpmc
+ifeq (${TPM2_MODE},)
+UTIL_NAMES += utility/tpm_init_temp_fix
+endif
+
# TODO: Do we still need eficompress and efidecompress for anything?
ifeq (${MINIMAL},)
UTIL_NAMES += \
@@ -721,7 +728,6 @@ TEST_OBJS += ${TESTLIB_OBJS}
# And some compiled tests.
TEST_NAMES = \
tests/cgptlib_test \
- tests/rollback_index2_tests \
tests/rollback_index3_tests \
tests/rsa_padding_test \
tests/rsa_utility_tests \
@@ -729,7 +735,6 @@ TEST_NAMES = \
tests/sha_benchmark \
tests/sha_tests \
tests/stateful_util_tests \
- tests/tlcl_tests \
tests/tpm_bootmode_tests \
tests/utility_string_tests \
tests/utility_tests \
@@ -752,6 +757,13 @@ TEST_NAMES = \
tests/vboot_nvstorage_test \
tests/verify_kernel
+ifeq (${TPM2_MODE},)
+# TODO(apronin): tests for TPM2 case?
+TEST_NAMES += \
+ tests/tlcl_tests \
+ tests/rollback_index2_tests
+endif
+
ifdef REGION_READ
TEST_NAMES += tests/vboot_region_tests
endif
@@ -805,6 +817,7 @@ TESTBDB_NAMES = \
TEST_NAMES += ${TEST2X_NAMES} ${TEST20_NAMES} ${TEST21_NAMES} ${TESTBDB_NAMES}
# And a few more...
+ifeq (${TPM2_MODE},)
TLCL_TEST_NAMES = \
tests/tpm_lite/tpmtest_earlyextend \
tests/tpm_lite/tpmtest_earlynvram \
@@ -817,6 +830,10 @@ TLCL_TEST_NAMES = \
tests/tpm_lite/tpmtest_testsetup \
tests/tpm_lite/tpmtest_timing \
tests/tpm_lite/tpmtest_writelimit
+else
+# TODO(apronin): tests for TPM2 case?
+TLCL_TEST_NAMES =
+endif
TEST_NAMES += ${TLCL_TEST_NAMES}
@@ -1309,17 +1326,20 @@ ${BUILD}/tests/%: CFLAGS += -Xlinker --allow-multiple-definition
${BUILD}/tests/%: LDLIBS += -lrt -luuid
${BUILD}/tests/%: LIBS += ${TESTLIB}
+ifeq (${TPM2_MODE},)
+# TODO(apronin): tests for TPM2 case?
${BUILD}/tests/rollback_index2_tests: OBJS += \
${BUILD}/firmware/lib/rollback_index_for_test.o
${BUILD}/tests/rollback_index2_tests: \
${BUILD}/firmware/lib/rollback_index_for_test.o
TEST_OBJS += ${BUILD}/firmware/lib/rollback_index_for_test.o
+endif
${BUILD}/tests/tlcl_tests: OBJS += \
- ${BUILD}/firmware/lib/tpm_lite/tlcl_for_test.o
+ ${TLCL_OBJS_FOR_TEST}
${BUILD}/tests/tlcl_tests: \
- ${BUILD}/firmware/lib/tpm_lite/tlcl_for_test.o
-TEST_OBJS += ${BUILD}/firmware/lib/tpm_lite/tlcl_for_test.o
+ ${TLCL_OBJS_FOR_TEST}
+TEST_OBJS += ${TLCL_OBJS_FOR_TEST}
${BUILD}/tests/vboot_audio_tests: OBJS += \
${BUILD}/firmware/lib/vboot_audio_for_test.o
@@ -1327,10 +1347,13 @@ ${BUILD}/tests/vboot_audio_tests: \
${BUILD}/firmware/lib/vboot_audio_for_test.o
TEST_OBJS += ${BUILD}/firmware/lib/vboot_audio_for_test.o
+ifeq (${TPM2_MODE},)
+# TODO(apronin): tests for TPM2 case?
TLCL_TEST_BINS = $(addprefix ${BUILD}/,${TLCL_TEST_NAMES})
${TLCL_TEST_BINS}: OBJS += ${BUILD}/tests/tpm_lite/tlcl_tests.o
${TLCL_TEST_BINS}: ${BUILD}/tests/tpm_lite/tlcl_tests.o
TEST_OBJS += ${BUILD}/tests/tpm_lite/tlcl_tests.o
+endif
# ----------------------------------------------------------------------------
# Here are the special rules that don't fit in the generic rules.
diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h
index fa341c0f..5a4b49fe 100644
--- a/firmware/include/tpm2_tss_constants.h
+++ b/firmware/include/tpm2_tss_constants.h
@@ -22,9 +22,13 @@
#define TPM2_NV_WriteLock ((TPM_CC)0x00000138)
#define TPM2_NV_Read ((TPM_CC)0x0000014E)
-/* TCG Spec defined, verify for TPM2. */
+/* TCG Spec defined, verify for TPM2.
+ * TODO(apronin): find TPM2 RC substitutes for TPM1.2 error codes.
+ */
#define TPM_E_BADINDEX ((uint32_t) 0x00000002)
#define TPM_E_INVALID_POSTINIT ((uint32_t) 0x00000026)
+#define TPM_E_BADTAG ((uint32_t) 0x0000001E)
+#define TPM_E_IOERROR ((uint32_t) 0x0000001F)
#define TPM_E_MAXNVWRITES ((uint32_t) 0x00000048)
#define HR_SHIFT 24
@@ -121,4 +125,12 @@ struct tpm2_response {
typedef struct {} TPM_PERMANENT_FLAGS;
typedef struct {} TPM_STCLEAR_FLAGS;
+/* TODO(apronin): For TPM2 certain properties must be received using
+ * TPM2_GetCapability instead of being hardcoded as they are now:
+ * TPM_MAX_COMMAND_SIZE -> use TPM_PT_MAX_COMMAND_SIZE for TPM2.
+ * TPM_PCR_DIGEST -> use TPM_PT_MAX_DIGEST for TPM2.
+ */
+#define TPM_MAX_COMMAND_SIZE 4096
+#define TPM_PCR_DIGEST 32
+
#endif /* ! __VBOOT_REFERENCE_FIRMWARE_INCLUDE_TPM2_TSS_CONSTANTS_H */
diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c
index 232a0a47..5c949dbe 100644
--- a/firmware/lib/rollback_index.c
+++ b/firmware/lib/rollback_index.c
@@ -353,8 +353,10 @@ uint32_t SetupTPM(int developer_mode, int disable_dev_request,
int clear_tpm_owner_request, RollbackSpaceFirmware* rsf)
{
uint8_t in_flags;
+#ifndef TPM2_MODE
uint8_t disable;
uint8_t deactivated;
+#endif
uint32_t result;
uint32_t versions;
@@ -396,6 +398,7 @@ uint32_t SetupTPM(int developer_mode, int disable_dev_request,
#endif
RETURN_ON_FAILURE(TlclContinueSelfTest());
#endif
+#ifndef TPM2_MODE
result = TlclAssertPhysicalPresence();
if (result != TPM_SUCCESS) {
/*
@@ -417,6 +420,7 @@ uint32_t SetupTPM(int developer_mode, int disable_dev_request,
VBDEBUG(("TPM: Must reboot to re-enable\n"));
return TPM_E_MUST_REBOOT;
}
+#endif
/* Read the firmware space. */
result = ReadSpaceFirmware(rsf);
diff --git a/firmware/lib/tpm2_lite/tlcl.c b/firmware/lib/tpm2_lite/tlcl.c
index efd73928..f335ffb6 100644
--- a/firmware/lib/tpm2_lite/tlcl.c
+++ b/firmware/lib/tpm2_lite/tlcl.c
@@ -42,6 +42,65 @@ static struct tpm2_response *tpm_process_command(TPM_CC command,
return response;
}
+uint32_t TlclLibInit(void)
+{
+ return VbExTpmInit();
+}
+
+uint32_t TlclLibClose(void)
+{
+ return VbExTpmClose();
+}
+
+uint32_t TlclSendReceive(const uint8_t *request, uint8_t *response,
+ int max_length)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+int TlclPacketSize(const uint8_t *packet)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return 0;
+}
+
+uint32_t TlclStartup(void)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclSaveState(void)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclResume(void)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclSelfTestFull(void)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclContinueSelfTest(void)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+int32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
/**
* Issue a ForceClear. The TPM error code is returned.
*/
@@ -63,6 +122,31 @@ uint32_t TlclSetEnable(void)
return TPM_SUCCESS;
}
+uint32_t TlclGetFlags(uint8_t* disable,
+ uint8_t* deactivated,
+ uint8_t *nvlocked)
+{
+ /* For TPM2 the flags are always the same */
+ if (disable)
+ *disable = 0;
+ if (deactivated)
+ *deactivated = 0;
+ if (nvlocked)
+ *nvlocked = 1;
+ return TPM_SUCCESS;
+}
+
+int TlclIsOwned(void)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return 0;
+}
+
+uint32_t TlclExtend(int pcr_num, const uint8_t *in_digest, uint8_t *out_digest)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
/**
* Get the permission bits for the NVRAM space with |index|.
@@ -74,6 +158,25 @@ uint32_t TlclGetPermissions(uint32_t index, uint32_t *permissions)
return TPM_SUCCESS;
}
+uint32_t TlclGetPermanentFlags(TPM_PERMANENT_FLAGS *pflags)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclGetSTClearFlags(TPM_STCLEAR_FLAGS *pflags)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclGetOwnership(uint8_t *owned)
+{
+ *owned = 0;
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
static uint32_t tlcl_lock_nv_write(uint32_t index)
{
struct tpm2_response *response;
@@ -184,3 +287,28 @@ uint32_t TlclWrite(uint32_t index, const void *data, uint32_t length)
return TPM_SUCCESS;
}
+
+int32_t TlclPCRRead(uint32_t index, void *data, uint32_t length)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclWriteLock(uint32_t index)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclReadLock(uint32_t index)
+{
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_SUCCESS;
+}
+
+uint32_t TlclGetRandom(uint8_t *data, uint32_t length, uint32_t *size)
+{
+ *size = 0;
+ VBDEBUG(("%s called, NOT YET IMPLEMENTED\n", __func__));
+ return TPM_E_IOERROR;
+}
diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c
index b4ef4e5c..aec180e1 100644
--- a/firmware/linktest/main.c
+++ b/firmware/linktest/main.c
@@ -51,17 +51,19 @@ int main(void)
TlclRead(0, 0, 0);
TlclWriteLock(0);
TlclReadLock(0);
- TlclAssertPhysicalPresence();
- TlclSetNvLocked();
TlclIsOwned();
TlclForceClear();
TlclSetEnable();
- TlclClearEnable();
TlclSetDeactivated(0);
TlclGetFlags(0, 0, 0);
- TlclSetGlobalLock();
TlclExtend(0, 0, 0);
TlclGetPermissions(0, 0);
+#ifndef TPM2_MODE
+ TlclAssertPhysicalPresence();
+ TlclSetNvLocked();
+ TlclClearEnable();
+ TlclSetGlobalLock();
+#endif
/* vboot_api.h - entry points INTO vboot_reference */
VbInit(0, 0);
diff --git a/utility/tpmc.c b/utility/tpmc.c
index d7c3e15e..f69bcd07 100644
--- a/utility/tpmc.c
+++ b/utility/tpmc.c
@@ -103,6 +103,13 @@ uint8_t ErrorCheck(uint32_t result, const char* cmd) {
/* Handler functions. These wouldn't exist if C had closures.
*/
+/* TODO(apronin): stub for selecte flags for TPM2 */
+#ifdef TPM2_MODE
+static uint32_t HandlerGetFlags(void) {
+ fprintf(stderr, "getflags not implemented for TPM2\n");
+ return OTHER_ERROR;
+}
+#else
static uint32_t HandlerGetFlags(void) {
uint8_t disabled;
uint8_t deactivated;
@@ -114,7 +121,9 @@ static uint32_t HandlerGetFlags(void) {
}
return result;
}
+#endif
+#ifndef TPM2_MODE
static uint32_t HandlerActivate(void) {
return TlclSetDeactivated(0);
}
@@ -122,6 +131,7 @@ static uint32_t HandlerActivate(void) {
static uint32_t HandlerDeactivate(void) {
return TlclSetDeactivated(1);
}
+#endif
static uint32_t HandlerDefineSpace(void) {
uint32_t index, size, perm;
@@ -168,11 +178,13 @@ static uint32_t HandlerWrite(void) {
}
if (size == 0) {
+#ifndef TPM2_MODE
if (index == TPM_NV_INDEX_LOCK) {
fprintf(stderr, "This would set the nvLocked bit. "
"Use \"tpmc setnv\" instead.\n");
exit(OTHER_ERROR);
}
+#endif
printf("warning: zero-length write\n");
} else {
printf("writing %d byte%s\n", size, size > 1 ? "s" : "");
@@ -310,6 +322,18 @@ static uint32_t HandlerGetRandom(void) {
return result;
}
+/* TODO(apronin): stubs for permanent and ST_CLEAR flags for TPM2 */
+#ifdef TPM2_MODE
+static uint32_t HandlerGetPermanentFlags(void) {
+ fprintf(stderr, "getpermanentflags not implemented for TPM2\n");
+ return OTHER_ERROR;
+}
+
+static uint32_t HandlerGetSTClearFlags(void) {
+ fprintf(stderr, "getstclearflags not implemented for TPM2\n");
+ return OTHER_ERROR;
+}
+#else
static uint32_t HandlerGetPermanentFlags(void) {
TPM_PERMANENT_FLAGS pflags;
uint32_t result = TlclGetPermanentFlags(&pflags);
@@ -354,7 +378,7 @@ static uint32_t HandlerGetSTClearFlags(void) {
}
return result;
}
-
+#endif /* TPM2_MODE */
static uint32_t HandlerSendRaw(void) {
uint8_t request[4096];
@@ -407,6 +431,7 @@ command_record command_table[] = {
{ "selftestfull", "test", "issue a SelfTestFull command", TlclSelfTestFull },
{ "continueselftest", "ctest", "issue a ContinueSelfTest command",
TlclContinueSelfTest },
+#ifndef TPM2_MODE
{ "assertphysicalpresence", "ppon", "assert Physical Presence",
TlclAssertPhysicalPresence },
{ "physicalpresencecmdenable", "ppcmd", "turn on software PP",
@@ -417,13 +442,18 @@ command_record command_table[] = {
HandlerActivate },
{ "deactivate", "deact", "deactivate the TPM (needs PP, maybe reboot)",
HandlerDeactivate },
+#endif
{ "clear", "clr", "clear the TPM owner (needs PP)", TlclForceClear },
+#ifndef TPM2_MODE
{ "setnvlocked", "setnv", "set the nvLocked flag permanently (IRREVERSIBLE!)",
TlclSetNvLocked },
+#endif
{ "lockphysicalpresence", "pplock", "lock (turn off) PP until reboot",
TlclLockPhysicalPresence },
+#ifndef TPM2_MODE
{ "setbgloballock", "block", "set the bGlobalLock until reboot",
TlclSetGlobalLock },
+#endif
{ "definespace", "def", "define a space (def <index> <size> <perm>)",
HandlerDefineSpace },
{ "write", "write", "write to a space (write <index> [<byte0> <byte1> ...])",