diff options
author | Mattias Nissler <mnissler@chromium.org> | 2017-07-10 13:46:20 +0200 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-07-18 00:32:48 -0700 |
commit | 2a7e9b84ac69c374112a13fd16fbf7cb996b78bf (patch) | |
tree | 3a3ddc06183f57bc31262fbc2456142f66cd4dae | |
parent | 68466c6d0a6cf629b77972773f523118b9cbb7be (diff) | |
download | vboot-2a7e9b84ac69c374112a13fd16fbf7cb996b78bf.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.h | 5 | ||||
-rw-r--r-- | firmware/include/tpm1_tss_constants.h | 7 | ||||
-rw-r--r-- | firmware/include/tpm2_tss_constants.h | 3 | ||||
-rw-r--r-- | firmware/lib/tpm2_lite/tlcl.c | 19 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/include/tlcl_structures.h | 5 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/mocked_tlcl.c | 7 | ||||
-rw-r--r-- | firmware/lib/tpm_lite/tlcl.c | 36 | ||||
-rw-r--r-- | tests/tlcl_tests.c | 42 | ||||
-rw-r--r-- | utility/tlcl_generator.c | 16 | ||||
-rw-r--r-- | utility/tpmc.c | 14 |
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]); |