summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattias Nissler <mnissler@chromium.org>2017-07-10 13:46:20 +0200
committerchrome-bot <chrome-bot@chromium.org>2017-07-18 00:32:48 -0700
commit2a7e9b84ac69c374112a13fd16fbf7cb996b78bf (patch)
tree3a3ddc06183f57bc31262fbc2456142f66cd4dae
parent68466c6d0a6cf629b77972773f523118b9cbb7be (diff)
downloadvboot-stabilize-9756.B.tar.gz
Implement tpmc getversion command.stabilize-9756.B
This command exposes the vendor and TPM firmware version. BRANCH=none BUG=chromium:728130 TEST=Builds and tpmc getversion prints plausible results. Change-Id: Iec556a298e025e10bda00121b40a25d8dc3839d1 Reviewed-on: https://chromium-review.googlesource.com/565287 Commit-Ready: Mattias Nissler <mnissler@chromium.org> Tested-by: Mattias Nissler <mnissler@chromium.org> Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r--firmware/include/tlcl.h5
-rw-r--r--firmware/include/tpm1_tss_constants.h7
-rw-r--r--firmware/include/tpm2_tss_constants.h3
-rw-r--r--firmware/lib/tpm2_lite/tlcl.c19
-rw-r--r--firmware/lib/tpm_lite/include/tlcl_structures.h5
-rw-r--r--firmware/lib/tpm_lite/mocked_tlcl.c7
-rw-r--r--firmware/lib/tpm_lite/tlcl.c36
-rw-r--r--tests/tlcl_tests.c42
-rw-r--r--utility/tlcl_generator.c16
-rw-r--r--utility/tpmc.c14
10 files changed, 151 insertions, 3 deletions
diff --git a/firmware/include/tlcl.h b/firmware/include/tlcl.h
index 53731200..293beb68 100644
--- a/firmware/include/tlcl.h
+++ b/firmware/include/tlcl.h
@@ -206,4 +206,9 @@ uint32_t TlclGetOwnership(uint8_t *owned);
*/
uint32_t TlclGetRandom(uint8_t *data, uint32_t length, uint32_t *size);
+/**
+ * Requests version information from the TPM.
+ */
+uint32_t TlclGetVersion(uint32_t *vendor, uint64_t *firmware_version);
+
#endif /* TPM_LITE_TLCL_H_ */
diff --git a/firmware/include/tpm1_tss_constants.h b/firmware/include/tpm1_tss_constants.h
index b4449ab8..12aca825 100644
--- a/firmware/include/tpm1_tss_constants.h
+++ b/firmware/include/tpm1_tss_constants.h
@@ -63,9 +63,10 @@ typedef uint32_t TPM_CAPABILITY_AREA;
#define TPM_CAP_FLAG_PERMANENT ((uint32_t) 0x00000108)
#define TPM_CAP_FLAG_VOLATILE ((uint32_t) 0x00000109)
-#define TPM_CAP_PROPERTY ((uint32_t) 0x00000005)
-#define TPM_CAP_PROP_OWNER ((uint32_t) 0x00000111)
-#define TPM_CAP_NV_INDEX ((uint32_t) 0x00000011)
+#define TPM_CAP_PROPERTY ((uint32_t) 0x00000005)
+#define TPM_CAP_PROP_OWNER ((uint32_t) 0x00000111)
+#define TPM_CAP_NV_INDEX ((uint32_t) 0x00000011)
+#define TPM_CAP_GET_VERSION_VAL ((uint32_t) 0x0000001a)
#define TPM_ST_CLEAR ((uint16_t) 0x0001)
#define TPM_ST_STATE ((uint16_t) 0x0002)
diff --git a/firmware/include/tpm2_tss_constants.h b/firmware/include/tpm2_tss_constants.h
index 454bf81a..0354004e 100644
--- a/firmware/include/tpm2_tss_constants.h
+++ b/firmware/include/tpm2_tss_constants.h
@@ -54,6 +54,9 @@
#define TPM_PT_NONE ((TPM_PT)0x00000000)
#define PT_GROUP ((TPM_PT)0x00000100)
#define PT_FIXED PT_GROUP
+#define TPM_PT_MANUFACTURER (PT_FIXED + 5)
+#define TPM_PT_FIRMWARE_VERSION_1 (PT_FIXED + 11)
+#define TPM_PT_FIRMWARE_VERSION_2 (PT_FIXED + 12)
#define PT_VAR (PT_GROUP * 2)
#define TPM_PT_PERMANENT (PT_VAR + 0)
#define TPM_PT_STARTUP_CLEAR (PT_VAR + 1)
diff --git a/firmware/lib/tpm2_lite/tlcl.c b/firmware/lib/tpm2_lite/tlcl.c
index 0af34d08..56829f11 100644
--- a/firmware/lib/tpm2_lite/tlcl.c
+++ b/firmware/lib/tpm2_lite/tlcl.c
@@ -522,3 +522,22 @@ uint32_t TlclGetRandom(uint8_t *data, uint32_t length, uint32_t *size)
VB2_DEBUG("NOT YET IMPLEMENTED\n");
return TPM_E_IOERROR;
}
+
+uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version)
+{
+ uint32_t result = tlcl_get_tpm_property(TPM_PT_MANUFACTURER, vendor);
+ if (result != TPM_SUCCESS)
+ return result;
+
+ uint32_t version_1;
+ uint32_t version_2;
+ result = tlcl_get_tpm_property(TPM_PT_FIRMWARE_VERSION_1, &version_1);
+ if (result != TPM_SUCCESS)
+ return result;
+ result = tlcl_get_tpm_property(TPM_PT_FIRMWARE_VERSION_2, &version_2);
+ if (result != TPM_SUCCESS)
+ return result;
+
+ *firmware_version = ((uint64_t) version_1 << 32) | version_2;
+ return TPM_SUCCESS;
+}
diff --git a/firmware/lib/tpm_lite/include/tlcl_structures.h b/firmware/lib/tpm_lite/include/tlcl_structures.h
index 36c1bb9e..cec33110 100644
--- a/firmware/lib/tpm_lite/include/tlcl_structures.h
+++ b/firmware/lib/tpm_lite/include/tlcl_structures.h
@@ -1,5 +1,10 @@
/* This file is automatically generated */
+const struct s_tpm_getversionval_cmd{
+ uint8_t buffer[18];
+} tpm_getversionval_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0x12, 0x0, 0x0, 0x0, 0x65, 0x0, 0x0, 0x0, 0x1a, 0x0, 0x0, 0x0, 0x0, },
+};
+
const struct s_tpm_extend_cmd{
uint8_t buffer[34];
uint16_t pcrNum;
diff --git a/firmware/lib/tpm_lite/mocked_tlcl.c b/firmware/lib/tpm_lite/mocked_tlcl.c
index 01762964..2de6ec79 100644
--- a/firmware/lib/tpm_lite/mocked_tlcl.c
+++ b/firmware/lib/tpm_lite/mocked_tlcl.c
@@ -186,6 +186,13 @@ uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size)
return TPM_SUCCESS;
}
+uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version)
+{
+ *vendor = 0x4e4f4e45;
+ *firmware_version = 0x1;
+ return TPM_SUCCESS;
+}
+
int TlclPacketSize(const uint8_t* packet)
{
uint32_t size;
diff --git a/firmware/lib/tpm_lite/tlcl.c b/firmware/lib/tpm_lite/tlcl.c
index 5a99fdc7..14acf966 100644
--- a/firmware/lib/tpm_lite/tlcl.c
+++ b/firmware/lib/tpm_lite/tlcl.c
@@ -512,3 +512,39 @@ uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size)
return result;
}
+
+uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version) {
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint32_t result = TlclSendReceive(tpm_getversionval_cmd.buffer,
+ response, sizeof(response));
+ if (result != TPM_SUCCESS)
+ return result;
+
+ uint8_t* cursor = response + kTpmResponseHeaderLength;
+
+ uint32_t size;
+ FromTpmUint32(cursor, &size);
+ cursor += sizeof(size);
+
+ /* Verify size >= sizeof(TPM_CAP_VERSION_INFO). */
+ const uint32_t kSizeofCapVersionInfo = 15;
+ if (size < kSizeofCapVersionInfo) {
+ return TPM_E_IOERROR;
+ }
+
+ cursor += sizeof(uint16_t); /* tag */
+ cursor += sizeof(uint16_t); /* spec version */
+
+ uint16_t version;
+ FromTpmUint16(cursor, &version);
+ cursor += sizeof(version);
+ *firmware_version = version;
+
+ cursor += sizeof(uint16_t); /* specLevel */
+ cursor += sizeof(uint8_t); /* errataRev */
+
+ FromTpmUint32(cursor, vendor);
+ cursor += sizeof(*vendor);
+
+ return TPM_SUCCESS;
+}
diff --git a/tests/tlcl_tests.c b/tests/tlcl_tests.c
index 50371615..f06947b9 100644
--- a/tests/tlcl_tests.c
+++ b/tests/tlcl_tests.c
@@ -335,6 +335,47 @@ static void RandomTest(void)
TEST_EQ(size, 0, " size 0");
}
+/**
+ * Test GetVersion
+ */
+static void GetVersionTest(void)
+{
+ uint8_t response[] = {
+ 0x00, 0xc4, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x30,
+ 0x01, 0x02, 0x04, 0x20, 0x00, 0x02, 0x03, 0x49,
+ 0x46, 0x58, 0x00, 0x00, 0x0d, 0x04, 0x20, 0x03,
+ 0x6f, 0x00, 0x74, 0x70, 0x6d, 0x33, 0x38, 0xff,
+ 0xff, 0xff
+ };
+
+ uint32_t vendor;
+ uint64_t firmware_version;
+
+ ResetMocks();
+ calls[0].rsp = response;
+ calls[0].rsp_size = sizeof(response);
+ TEST_EQ(TlclGetVersion(&vendor, &firmware_version), 0, "GetVersion");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, " cmd");
+ TEST_EQ(vendor, 0x49465800, " vendor");
+ TEST_EQ(firmware_version, 0x420, " firmware_version");
+
+ ResetMocks();
+ SetResponse(0, TPM_E_IOERROR, 0);
+ TEST_EQ(TlclGetVersion(&vendor, &firmware_version), TPM_E_IOERROR,
+ "GetVersion - error");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, " cmd");
+
+ /* Adjust response to indicate a 1 byte too short payload size. */
+ ToTpmUint32(response + kTpmResponseHeaderLength, 14);
+ ResetMocks();
+ calls[0].rsp = response;
+ calls[0].rsp_size = sizeof(response);
+ TEST_EQ(TlclGetVersion(&vendor, &firmware_version), TPM_E_IOERROR,
+ "GetVersion -- short");
+ TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, " cmd");
+}
+
int main(void)
{
TlclTest();
@@ -343,6 +384,7 @@ int main(void)
PcrTest();
FlagsTest();
RandomTest();
+ GetVersionTest();
return gTestSuccess ? 0 : 255;
}
diff --git a/utility/tlcl_generator.c b/utility/tlcl_generator.c
index 7ed1d6c3..70ce5fd9 100644
--- a/utility/tlcl_generator.c
+++ b/utility/tlcl_generator.c
@@ -389,6 +389,21 @@ Command* BuildGetRandomCommand(void) {
return cmd;
}
+Command* BuildGetVersionValCommand(void) {
+ int size = (kTpmRequestHeaderLength +
+ sizeof(TPM_CAPABILITY_AREA) + /* capArea */
+ sizeof(uint32_t)); /* subCapSize */
+
+ Command* cmd = newCommand(TPM_ORD_GetCapability, size);
+ cmd->name = "tpm_getversionval_cmd";
+ AddInitializedField(cmd, kTpmRequestHeaderLength,
+ sizeof(TPM_CAPABILITY_AREA), TPM_CAP_GET_VERSION_VAL);
+ AddInitializedField(cmd, kTpmRequestHeaderLength +
+ sizeof(TPM_CAPABILITY_AREA),
+ sizeof(uint32_t), 0);
+ return cmd;
+}
+
/* Output the fields of a structure.
*/
void OutputFields(Field* fld) {
@@ -510,6 +525,7 @@ Command* (*builders[])(void) = {
BuildGetOwnershipCommand,
BuildGetRandomCommand,
BuildExtendCommand,
+ BuildGetVersionValCommand,
};
static void FreeFields(Field* fld) {
diff --git a/utility/tpmc.c b/utility/tpmc.c
index 1e4e3026..ae45ca1c 100644
--- a/utility/tpmc.c
+++ b/utility/tpmc.c
@@ -9,6 +9,7 @@
* for other errors.
*/
+#include <inttypes.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
@@ -456,6 +457,17 @@ static uint32_t HandlerSendRaw(void) {
return result;
}
+static uint32_t HandlerGetVersion(void) {
+ uint32_t vendor;
+ uint64_t firmware_version;
+ uint32_t result = TlclGetVersion(&vendor, &firmware_version);
+ if (result == 0) {
+ printf("vendor %08x\nfirmware_version %016" PRIx64 "\n",
+ vendor, firmware_version);
+ }
+ return result;
+}
+
#ifdef TPM2_MODE
static uint32_t HandlerDoNothingForTPM2(void) {
return 0;
@@ -534,6 +546,8 @@ command_record command_table[] = {
{ "savestate", "save", "execute TPM_SaveState", TlclSaveState },
{ "sendraw", "raw", "send a raw request and print raw response",
HandlerSendRaw },
+ { "getversion", "getver", "get TPM vendor and firmware version",
+ HandlerGetVersion },
};
static int n_commands = sizeof(command_table) / sizeof(command_table[0]);