summaryrefslogtreecommitdiff
path: root/src/shared/tpm2-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-10-11 18:20:14 +0200
committerLennart Poettering <lennart@poettering.net>2023-01-17 09:42:16 +0100
commit15c591d1e2b555070f540cafb1b3d1e564e3410a (patch)
treefeddb449b26d1fb6c32d470ceaff5c688e421dd6 /src/shared/tpm2-util.c
parente4481cc512f48d423115b10d4ae1c8e1381ff84b (diff)
downloadsystemd-15c591d1e2b555070f540cafb1b3d1e564e3410a.tar.gz
tpm2-util: split out code that extends a PCR from pcrphase
This way we can reuse it later outside of pcrphase
Diffstat (limited to 'src/shared/tpm2-util.c')
-rw-r--r--src/shared/tpm2-util.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
index abe15b54a8..36023c6de2 100644
--- a/src/shared/tpm2-util.c
+++ b/src/shared/tpm2-util.c
@@ -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;