mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-26 17:57:16 +00:00
tlcl, tpmc: extend GetVersion to report vendor specific data
1) Extend TlclGetVersion to return vendor specific data, if requested. 2) Extend 'tpmc getver' to include vendor specific data. BRANCH=none BUG=chromium:771561 TEST=unit tests, running 'tpmc getver' Change-Id: Ic04c242d4e6f33b45a80479be9ab9777b317ebe2 Reviewed-on: https://chromium-review.googlesource.com/706240 Commit-Ready: Andrey Pronin <apronin@chromium.org> Tested-by: Andrey Pronin <apronin@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
5d5b2f1610
commit
3b805725c1
@@ -208,8 +208,17 @@ uint32_t TlclGetRandom(uint8_t *data, uint32_t length, uint32_t *size);
|
||||
|
||||
/**
|
||||
* Requests version information from the TPM.
|
||||
* If vendor_specific_buf_size != NULL, requests also the vendor-specific
|
||||
* variable-length part of the version:
|
||||
* if vendor_specific_buf == NULL, determines its size and returns in
|
||||
* *vendor_specific_buf_size;
|
||||
* if vendor_specific_buf != NULL, fills the buffer until either the
|
||||
* end of the vendor specific data or the end of the buffer, sets
|
||||
* *vendor_specific_buf_size to the length of the filled data.
|
||||
*/
|
||||
uint32_t TlclGetVersion(uint32_t *vendor, uint64_t *firmware_version);
|
||||
uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
|
||||
uint8_t* vendor_specific_buf,
|
||||
size_t* vendor_specific_buf_size);
|
||||
|
||||
/**
|
||||
* Issues the IFX specific FieldUpgradeInfoRequest2 TPM_FieldUpgrade subcommand
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
#define PT_GROUP ((TPM_PT)0x00000100)
|
||||
#define PT_FIXED PT_GROUP
|
||||
#define TPM_PT_MANUFACTURER (PT_FIXED + 5)
|
||||
#define TPM_PT_VENDOR_STRING_1 (PT_FIXED + 6)
|
||||
#define TPM_PT_VENDOR_STRING_4 (PT_FIXED + 9)
|
||||
#define TPM_PT_FIRMWARE_VERSION_1 (PT_FIXED + 11)
|
||||
#define TPM_PT_FIRMWARE_VERSION_2 (PT_FIXED + 12)
|
||||
#define PT_VAR (PT_GROUP * 2)
|
||||
|
||||
@@ -523,7 +523,25 @@ uint32_t TlclGetRandom(uint8_t *data, uint32_t length, uint32_t *size)
|
||||
return TPM_E_IOERROR;
|
||||
}
|
||||
|
||||
uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version)
|
||||
// Converts TPM_PT_VENDOR_STRING_x |value| to an array of bytes in |buf|.
|
||||
// Returns the number of bytes in the array.
|
||||
// |buf| should be at least 4 bytes long.
|
||||
size_t tlcl_vendor_string_parse(uint32_t value, uint8_t* buf)
|
||||
{
|
||||
size_t len = 0;
|
||||
int shift = 24;
|
||||
for (; len < 4; shift -= 8) {
|
||||
uint8_t byte = (value >> shift) & 0xffu;
|
||||
if (!byte)
|
||||
break;
|
||||
buf[len++] = byte;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
|
||||
uint8_t* vendor_specific_buf,
|
||||
size_t* vendor_specific_buf_size)
|
||||
{
|
||||
uint32_t result = tlcl_get_tpm_property(TPM_PT_MANUFACTURER, vendor);
|
||||
if (result != TPM_SUCCESS)
|
||||
@@ -539,6 +557,35 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version)
|
||||
return result;
|
||||
|
||||
*firmware_version = ((uint64_t) version_1 << 32) | version_2;
|
||||
|
||||
if (!vendor_specific_buf_size)
|
||||
return TPM_SUCCESS;
|
||||
|
||||
size_t total_size = 0;
|
||||
uint32_t prop_id;
|
||||
uint8_t prop_string[16];
|
||||
for (prop_id = TPM_PT_VENDOR_STRING_1;
|
||||
prop_id <= TPM_PT_VENDOR_STRING_4;
|
||||
++prop_id) {
|
||||
uint32_t prop_value;
|
||||
result = tlcl_get_tpm_property(prop_id, &prop_value);
|
||||
if (result != TPM_SUCCESS)
|
||||
break;
|
||||
|
||||
size_t prop_len = tlcl_vendor_string_parse(
|
||||
prop_value, prop_string + total_size);
|
||||
VbAssert(prop_len <= 4 &&
|
||||
total_size + prop_len <= sizeof(prop_string));
|
||||
total_size += prop_len;
|
||||
if (prop_len < 4)
|
||||
break;
|
||||
}
|
||||
if (vendor_specific_buf) {
|
||||
if (total_size > *vendor_specific_buf_size)
|
||||
total_size = *vendor_specific_buf_size;
|
||||
memcpy(vendor_specific_buf, prop_string, total_size);
|
||||
}
|
||||
*vendor_specific_buf_size = total_size;
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -186,10 +186,15 @@ 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)
|
||||
uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
|
||||
uint8_t* vendor_specific_buf,
|
||||
size_t* vendor_specific_buf_size)
|
||||
{
|
||||
*vendor = 0x4e4f4e45;
|
||||
*firmware_version = 0x1;
|
||||
if (vendor_specific_buf_size) {
|
||||
*vendor_specific_buf_size = 0;
|
||||
}
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -513,7 +513,10 @@ uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t *size)
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version) {
|
||||
uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
|
||||
uint8_t* vendor_specific_buf,
|
||||
size_t* vendor_specific_buf_size)
|
||||
{
|
||||
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
||||
uint32_t result = TlclSendReceive(tpm_getversionval_cmd.buffer,
|
||||
response, sizeof(response));
|
||||
@@ -528,7 +531,9 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version) {
|
||||
|
||||
/* Verify size >= sizeof(TPM_CAP_VERSION_INFO). */
|
||||
const uint32_t kSizeofCapVersionInfo = 15;
|
||||
if (size < kSizeofCapVersionInfo) {
|
||||
if (size < kSizeofCapVersionInfo ||
|
||||
kTpmResponseHeaderLength + sizeof(size) + size >
|
||||
TPM_LARGE_ENOUGH_COMMAND_SIZE) {
|
||||
return TPM_E_IOERROR;
|
||||
}
|
||||
|
||||
@@ -546,6 +551,26 @@ uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version) {
|
||||
FromTpmUint32(cursor, vendor);
|
||||
cursor += sizeof(*vendor);
|
||||
|
||||
if (vendor_specific_buf_size) {
|
||||
uint16_t vendor_specific_size;
|
||||
FromTpmUint16(cursor, &vendor_specific_size);
|
||||
cursor += sizeof(vendor_specific_size);
|
||||
|
||||
if (size < kSizeofCapVersionInfo + vendor_specific_size) {
|
||||
return TPM_E_IOERROR;
|
||||
}
|
||||
if (vendor_specific_buf) {
|
||||
if (vendor_specific_size > *vendor_specific_buf_size) {
|
||||
vendor_specific_size =
|
||||
*vendor_specific_buf_size;
|
||||
}
|
||||
memcpy(vendor_specific_buf, cursor,
|
||||
vendor_specific_size);
|
||||
cursor += vendor_specific_size;
|
||||
}
|
||||
*vendor_specific_buf_size = vendor_specific_size;
|
||||
}
|
||||
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -563,7 +588,8 @@ static void ParseIFXFirmwarePackage(uint8_t** cursor,
|
||||
uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO* info) {
|
||||
uint32_t vendor;
|
||||
uint64_t firmware_version;
|
||||
uint32_t result = TlclGetVersion(&vendor, &firmware_version);
|
||||
uint32_t result =
|
||||
TlclGetVersion(&vendor, &firmware_version, NULL, NULL);
|
||||
if (result != TPM_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -351,19 +351,54 @@ static void GetVersionTest(void)
|
||||
|
||||
uint32_t vendor;
|
||||
uint64_t firmware_version;
|
||||
uint8_t vendor_specific[32];
|
||||
size_t vendor_specific_size;
|
||||
|
||||
ResetMocks();
|
||||
calls[0].rsp = response;
|
||||
calls[0].rsp_size = sizeof(response);
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version), 0, "GetVersion");
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version, NULL, NULL), 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();
|
||||
calls[0].rsp = response;
|
||||
calls[0].rsp_size = sizeof(response);
|
||||
vendor_specific_size = 100;
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version,
|
||||
NULL, &vendor_specific_size), 0,
|
||||
"GetVersion - vendor specific size");
|
||||
TEST_EQ(vendor_specific_size, 0xd, " vendor specific size");
|
||||
|
||||
ResetMocks();
|
||||
calls[0].rsp = response;
|
||||
calls[0].rsp_size = sizeof(response);
|
||||
vendor_specific_size = sizeof(vendor_specific);
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version,
|
||||
vendor_specific, &vendor_specific_size), 0,
|
||||
"GetVersion - vendor specific data");
|
||||
TEST_EQ(vendor_specific_size, 0xd, " vendor specific size");
|
||||
TEST_EQ(memcmp(vendor_specific, response + 29, 0xd), 0,
|
||||
" vendor specific data check");
|
||||
|
||||
ResetMocks();
|
||||
calls[0].rsp = response;
|
||||
calls[0].rsp_size = sizeof(response);
|
||||
vendor_specific_size = 4;
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version,
|
||||
vendor_specific, &vendor_specific_size), 0,
|
||||
"GetVersion - vendor specific data, short buf");
|
||||
TEST_EQ(vendor_specific_size, 4,
|
||||
" min(vendor specific size, buf size)");
|
||||
TEST_EQ(memcmp(vendor_specific, response + 29, 4), 0,
|
||||
" vendor specific data check");
|
||||
|
||||
ResetMocks();
|
||||
SetResponse(0, TPM_E_IOERROR, 0);
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version), TPM_E_IOERROR,
|
||||
"GetVersion - error");
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version, NULL, NULL),
|
||||
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. */
|
||||
@@ -371,8 +406,32 @@ static void GetVersionTest(void)
|
||||
ResetMocks();
|
||||
calls[0].rsp = response;
|
||||
calls[0].rsp_size = sizeof(response);
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version), TPM_E_IOERROR,
|
||||
"GetVersion -- short");
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version, NULL, NULL),
|
||||
TPM_E_IOERROR, "GetVersion -- short");
|
||||
TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, " cmd");
|
||||
|
||||
/* Adjust response to indicate a payload size too long for the
|
||||
* response buffer. */
|
||||
ToTpmUint32(response + kTpmResponseHeaderLength,
|
||||
TPM_LARGE_ENOUGH_COMMAND_SIZE - sizeof(uint32_t) -
|
||||
kTpmResponseHeaderLength + 1);
|
||||
ResetMocks();
|
||||
calls[0].rsp = response;
|
||||
calls[0].rsp_size = sizeof(response);
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version, NULL, NULL),
|
||||
TPM_E_IOERROR, "GetVersion -- long");
|
||||
TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, " cmd");
|
||||
|
||||
/* Restore the original payload length and adjust response to contain
|
||||
* less vendor specific data than indicated in its size. */
|
||||
ToTpmUint32(response + kTpmResponseHeaderLength, 0x1c);
|
||||
ToTpmUint16(response + 27, 0xd + 1);
|
||||
ResetMocks();
|
||||
calls[0].rsp = response;
|
||||
calls[0].rsp_size = sizeof(response);
|
||||
TEST_EQ(TlclGetVersion(&vendor, &firmware_version,
|
||||
NULL, &vendor_specific_size), TPM_E_IOERROR,
|
||||
"GetVersion -- short with vendor specific");
|
||||
TEST_EQ(calls[0].req_cmd, TPM_ORD_GetCapability, " cmd");
|
||||
}
|
||||
|
||||
|
||||
@@ -460,10 +460,18 @@ static uint32_t HandlerSendRaw(void) {
|
||||
static uint32_t HandlerGetVersion(void) {
|
||||
uint32_t vendor;
|
||||
uint64_t firmware_version;
|
||||
uint32_t result = TlclGetVersion(&vendor, &firmware_version);
|
||||
uint8_t vendor_specific[32];
|
||||
size_t vendor_specific_size = sizeof(vendor_specific);
|
||||
uint32_t result = TlclGetVersion(&vendor, &firmware_version, vendor_specific,
|
||||
&vendor_specific_size);
|
||||
if (result == 0) {
|
||||
printf("vendor %08x\nfirmware_version %016" PRIx64 "\n",
|
||||
printf("vendor %08x\nfirmware_version %016" PRIx64 "\nvendor_specific ",
|
||||
vendor, firmware_version);
|
||||
size_t n;
|
||||
for (n = 0; n < vendor_specific_size; ++n) {
|
||||
printf("%02x", vendor_specific[n]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user