tpm2-util: add tpm2_get_vendor_info() helper for getting TPM2 vendor info from the device
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
#include "time-util.h"
|
||||
#include "tpm2-pcr.h"
|
||||
#include "tpm2-util.h"
|
||||
#include "unaligned.h"
|
||||
#include "virt.h"
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
@@ -348,6 +349,114 @@ static int tpm2_get_capability(
|
||||
return more == TPM2_YES;
|
||||
}
|
||||
|
||||
static char *mangle_vendor_chars(char *c, size_t n) {
|
||||
char *end = c;
|
||||
assert(c || n == 0);
|
||||
|
||||
/* Suppress all control characters, whitespace and non-ASCII bytes */
|
||||
for (char *x = c; x < c + n; x++) {
|
||||
if (!IN_SET(*x, ' ', 0))
|
||||
end = x + 1;
|
||||
|
||||
if ((unsigned char) *x <= (unsigned char) ' ' ||
|
||||
(unsigned char) *x >= 127)
|
||||
*x = '_';
|
||||
}
|
||||
|
||||
/* Drop trailing spaces and NUL bytes */
|
||||
*end = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
int tpm2_get_vendor_info(
|
||||
Tpm2Context *c,
|
||||
Tpm2VendorInfo *ret) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(ret);
|
||||
|
||||
TPMU_CAPABILITIES capabilities = {};
|
||||
r = tpm2_get_capability(
|
||||
c,
|
||||
TPM2_CAP_TPM_PROPERTIES,
|
||||
TPM2_PT_FAMILY_INDICATOR,
|
||||
TPM2_PT_FIRMWARE_VERSION_2 - TPM2_PT_FAMILY_INDICATOR + 1, /* get all relevant fields at once */
|
||||
&capabilities);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
Tpm2VendorInfo info = {};
|
||||
|
||||
for (uint32_t i = 0; i < capabilities.tpmProperties.count; i++) {
|
||||
TPMS_TAGGED_PROPERTY *p = capabilities.tpmProperties.tpmProperty + i;
|
||||
|
||||
switch (p->property) {
|
||||
|
||||
case TPM2_PT_FAMILY_INDICATOR:
|
||||
unaligned_write_be32(info.family_indicator, p->value);
|
||||
mangle_vendor_chars(info.family_indicator, sizeof(info.family_indicator));
|
||||
break;
|
||||
|
||||
case TPM2_PT_LEVEL:
|
||||
info.level = p->value;
|
||||
break;
|
||||
|
||||
case TPM2_PT_REVISION:
|
||||
info.revision_major = p->value / 100;
|
||||
info.revision_minor = p->value % 100;
|
||||
break;
|
||||
|
||||
case TPM2_PT_DAY_OF_YEAR:
|
||||
info.day_of_year = p->value;
|
||||
break;
|
||||
|
||||
case TPM2_PT_YEAR:
|
||||
info.year = p->value;
|
||||
break;
|
||||
|
||||
case TPM2_PT_MANUFACTURER:
|
||||
unaligned_write_be32(info.manufacturer, p->value);
|
||||
mangle_vendor_chars(info.manufacturer, sizeof(info.manufacturer));
|
||||
break;
|
||||
|
||||
case TPM2_PT_VENDOR_STRING_1:
|
||||
unaligned_write_be32(info.vendor_string+0, p->value);
|
||||
break;
|
||||
|
||||
case TPM2_PT_VENDOR_STRING_2:
|
||||
unaligned_write_be32(info.vendor_string+4, p->value);
|
||||
break;
|
||||
|
||||
case TPM2_PT_VENDOR_STRING_3:
|
||||
unaligned_write_be32(info.vendor_string+8, p->value);
|
||||
break;
|
||||
|
||||
case TPM2_PT_VENDOR_STRING_4:
|
||||
unaligned_write_be32(info.vendor_string+12, p->value);
|
||||
break;
|
||||
|
||||
case TPM2_PT_VENDOR_TPM_TYPE:
|
||||
info.vendor_tpm_type = p->value;
|
||||
break;
|
||||
|
||||
case TPM2_PT_FIRMWARE_VERSION_1:
|
||||
info.firmware_version_major = p->value >> 16;
|
||||
info.firmware_version_minor = p->value & 0xFFFFU;
|
||||
break;
|
||||
|
||||
case TPM2_PT_FIRMWARE_VERSION_2:
|
||||
info.firmware_version2 = p->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mangle_vendor_chars(info.vendor_string, sizeof(info.vendor_string));
|
||||
*ret = TAKE_STRUCT(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TPMA_CC_TO_TPM2_CC(cca) (((cca) & TPMA_CC_COMMANDINDEX_MASK) >> TPMA_CC_COMMANDINDEX_SHIFT)
|
||||
|
||||
static int tpm2_cache_capabilities(Tpm2Context *c) {
|
||||
|
||||
@@ -195,6 +195,23 @@ static inline int tpm2_digest_init(TPMI_ALG_HASH alg, TPM2B_DIGEST *digest) {
|
||||
return tpm2_digest_many(alg, digest, NULL, 0, false);
|
||||
}
|
||||
|
||||
typedef struct Tpm2VendorInfo {
|
||||
uint32_t level;
|
||||
uint32_t revision_major;
|
||||
uint32_t revision_minor;
|
||||
uint32_t day_of_year;
|
||||
uint32_t year;
|
||||
uint32_t vendor_tpm_type;
|
||||
uint16_t firmware_version_major;
|
||||
uint16_t firmware_version_minor;
|
||||
uint32_t firmware_version2;
|
||||
char family_indicator[4+1];
|
||||
char manufacturer[4+1];
|
||||
char vendor_string[4*4+1];
|
||||
} Tpm2VendorInfo;
|
||||
|
||||
int tpm2_get_vendor_info(Tpm2Context *c, Tpm2VendorInfo *ret);
|
||||
|
||||
void tpm2_log_debug_tpml_pcr_selection(const TPML_PCR_SELECTION *l, const char *msg);
|
||||
void tpm2_log_debug_pcr_value(const Tpm2PCRValue *pcr_value, const char *msg);
|
||||
void tpm2_log_debug_buffer(const void *buffer, size_t size, const char *msg);
|
||||
|
||||
Reference in New Issue
Block a user