From 0691d0e5a1f6d12c1df0e34c79a1a6e6510a1ec8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 Feb 2024 14:42:50 +0100 Subject: [PATCH 1/2] pcrlock: document the env vars we honour to find measurement logs This env vars have been supported for a while, let's document them where we usually document them. --- docs/ENVIRONMENT.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 6fa82d7177..eab1ce23e4 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -622,6 +622,16 @@ SYSTEMD_HOME_DEBUG_SUFFIX=foo \ to expose a single device only, since those identifiers better should be kept unique. +`systemd-pcrlock`, `systemd-pcrextend`: + +* `$SYSTEMD_MEASURE_LOG_USERSPACE` – the path to the `tpm2-measure.log` file + (containing userspace measurement data) to read. This allows overriding the + default of `/run/log/systemd/tpm2-measure.log`. + +* `$SYSTEMD_MEASURE_LOG_FIRMWARE` – the path to the `binary_bios_measurements` + file (containing firmware measurement data) to read. This allows overriding + the default of `/sys/kernel/security/tpm0/binary_bios_measurements`. + Tools using the Varlink protocol (such as `varlinkctl`) or sd-bus (such as `busctl`): From e90a255e55e3af0effac927ccaa10c2662501e1a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 Feb 2024 14:43:42 +0100 Subject: [PATCH 2/2] pcrlock: handle measurement logs where hash algs in header are announced in different order than in records Apparently on HyperV the measurement logs announce the hash algs in a different order in the header than the records have them. Let's handle this gracefully --- src/pcrlock/pcrlock.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c index e70c44c675..1fb9d692a2 100644 --- a/src/pcrlock/pcrlock.c +++ b/src/pcrlock/pcrlock.c @@ -936,23 +936,30 @@ static int event_log_load_firmware(EventLog *el) { assert(event->digests.count == n_algorithms); for (size_t i = 0; i < n_algorithms; i++, ha = ha_next) { - ha_next = (const uint8_t*) ha + offsetof(TPMT_HA, digest) + algorithms[i].digestSize; - /* The TPMT_HA is not aligned in the record, hence read the hashAlg field via an unaligned read */ assert_cc(__builtin_types_compatible_p(uint16_t, typeof(TPMI_ALG_HASH))); uint16_t hash_alg = unaligned_read_ne16((const uint8_t*) ha + offsetof(TPMT_HA, hashAlg)); - if (hash_alg != algorithms[i].algorithmId) - return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Hash algorithms in event log record don't match log."); + /* On some systems (some HyperV?) the order of hash algorithms announced in the + * header does not match the order in the records. Let's hence search for the right + * mapping */ + size_t j; + for (j = 0; j < n_algorithms; j++) + if (hash_alg == algorithms[j].algorithmId) + break; + if (j >= n_algorithms) + return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Hash algorithms in event log record not among those advertised by log header."); - if (!tpm2_hash_alg_to_string(algorithms[i].algorithmId)) + ha_next = (const uint8_t*) ha + offsetof(TPMT_HA, digest) + algorithms[j].digestSize; + + if (!tpm2_hash_alg_to_string(hash_alg)) continue; r = event_log_record_add_bank( record, - algorithms[i].algorithmId, + hash_alg, (const uint8_t*) ha + offsetof(TPMT_HA, digest), - algorithms[i].digestSize, + algorithms[j].digestSize, /* ret= */ NULL); if (r < 0) return log_error_errno(r, "Failed to add bank to event log record: %m");