tpm2-util: split out code that extends a PCR from pcrphase

This way we can reuse it later outside of pcrphase
This commit is contained in:
Lennart Poettering
2023-01-17 09:42:16 +01:00
parent e4481cc512
commit 15c591d1e2
3 changed files with 72 additions and 39 deletions
+3 -39
View File
@@ -146,7 +146,6 @@ static int run(int argc, char *argv[]) {
const char *word;
unsigned pcr_nr;
size_t length;
TSS2_RC rc;
int r;
log_setup();
@@ -215,50 +214,15 @@ static int run(int argc, char *argv[]) {
if (strv_isempty(arg_banks)) /* Still none? */
return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Found a TPM2 without enabled PCR banks. Can't operate.");
TPML_DIGEST_VALUES values = {};
STRV_FOREACH(bank, arg_banks) {
const EVP_MD *implementation;
int id;
assert_se(implementation = EVP_get_digestbyname(*bank));
if (values.count >= ELEMENTSOF(values.digests))
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
id = tpm2_pcr_bank_from_string(EVP_MD_name(implementation));
if (id < 0)
return log_error_errno(id, "Can't map hash name to TPM2.");
values.digests[values.count].hashAlg = id;
if (EVP_Digest(word, length, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash word.");
values.count++;
}
joined = strv_join(arg_banks, ", ");
if (!joined)
return log_oom();
log_debug("Measuring '%s' into PCR index %u, banks %s.", word, TPM_PCR_INDEX_KERNEL_IMAGE, joined);
rc = sym_Esys_PCR_Extend(
c.esys_context,
ESYS_TR_PCR0 + TPM_PCR_INDEX_KERNEL_IMAGE, /* → PCR 11 */
ESYS_TR_PASSWORD,
ESYS_TR_NONE,
ESYS_TR_NONE,
&values);
if (rc != TSS2_RC_SUCCESS)
return log_error_errno(
SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to measure '%s': %s",
word,
sym_Tss2_RC_Decode(rc));
r = tpm2_extend_bytes(c.esys_context, arg_banks, TPM_PCR_INDEX_KERNEL_IMAGE, word, length); /* → PCR 11 */
if (r < 0)
return r;
log_struct(LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_TPM_PCR_EXTEND_STR,
+67
View File
@@ -1919,6 +1919,73 @@ int tpm2_find_device_auto(
#endif
}
#if HAVE_TPM2
int tpm2_extend_bytes(
ESYS_CONTEXT *c,
char **banks,
unsigned pcr_index,
const void *data,
size_t sz) {
#if HAVE_OPENSSL
TPML_DIGEST_VALUES values = {};
TSS2_RC rc;
assert(c);
assert(data || sz == 0);
if (pcr_index >= TPM2_PCRS_MAX)
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Can't measure into unsupported PCR %u, refusing.", pcr_index);
if (strv_isempty(banks))
return 0;
STRV_FOREACH(bank, banks) {
const EVP_MD *implementation;
int id;
assert_se(implementation = EVP_get_digestbyname(*bank));
if (values.count >= ELEMENTSOF(values.digests))
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Too many banks selected.");
if ((size_t) EVP_MD_size(implementation) > sizeof(values.digests[values.count].digest))
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Hash result too large for TPM2.");
id = tpm2_pcr_bank_from_string(EVP_MD_name(implementation));
if (id < 0)
return log_error_errno(id, "Can't map hash name to TPM2.");
values.digests[values.count].hashAlg = id;
if (EVP_Digest(data, sz, (unsigned char*) &values.digests[values.count].digest, NULL, implementation, NULL) != 1)
return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to hash word.");
values.count++;
}
rc = sym_Esys_PCR_Extend(
c,
ESYS_TR_PCR0 + pcr_index,
ESYS_TR_PASSWORD,
ESYS_TR_NONE,
ESYS_TR_NONE,
&values);
if (rc != TSS2_RC_SUCCESS)
return log_error_errno(
SYNTHETIC_ERRNO(ENOTRECOVERABLE),
"Failed to measure into PCR %u: %s",
pcr_index,
sym_Tss2_RC_Decode(rc));
return 0;
#else
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"OpenSSL not supported on this build.");
#endif
}
#endif
int tpm2_parse_pcrs(const char *s, uint32_t *ret) {
const char *p = ASSERT_PTR(s);
uint32_t mask = 0;
+2
View File
@@ -70,6 +70,8 @@ static inline void Esys_Freep(void *p) {
int tpm2_get_good_pcr_banks(ESYS_CONTEXT *c, uint32_t pcr_mask, TPMI_ALG_HASH **ret_banks);
int tpm2_get_good_pcr_banks_strv(ESYS_CONTEXT *c, uint32_t pcr_mask, char ***ret);
int tpm2_extend_bytes(ESYS_CONTEXT *c, char **banks, unsigned pcr_index, const void *data, size_t sz);
#else
struct tpm2_context;
#endif