From c8bcf7ecf715aadd077cb2850e24122bebf19b6e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 2 Jul 2024 09:14:38 +0200 Subject: [PATCH] measure: drop incomplete support for PCRs != 11 At this point we have a clearer model: * systemd-measure should be used for measuring UKIs on vendor build systems, i.e. only cover stuff predictable by the OS vendor, and identical on all systems. And that is pretty much only PCR 11. * systemd-pcrlock should cover the other PCRs, which carry inherently local information, and can only be predicted locally and not already on vendor build systems. Because of that, let's not bother with any PCRs except for 11 in systemd-measure. This was added at a time where systemd-pcrlock didn't exist yet, and hence it wasn't clear how this will play out in the end. --- man/systemd-measure.xml | 10 +-- src/boot/measure.c | 133 ++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 80 deletions(-) diff --git a/man/systemd-measure.xml b/man/systemd-measure.xml index 8ea667426ed..931b62c12e7 100644 --- a/man/systemd-measure.xml +++ b/man/systemd-measure.xml @@ -17,7 +17,7 @@ systemd-measure - Pre-calculate and sign expected TPM2 PCR values for booted unified kernel images + Pre-calculate and sign expected TPM2 PCR 11 values for booted unified kernel images @@ -62,7 +62,7 @@ status This is the default command if none is specified. This queries the local system's - TPM2 PCR 11+12+13 values and displays them. The data is written in a similar format as the + TPM2 PCR 11 values and displays them. The data is written in a similar format as the calculate command below, and may be used to quickly compare expectation with reality. @@ -76,9 +76,9 @@ kernel image consisting of the components specified with , , , , , , , - , , see below. - Only is mandatory. (Alternatively, specify to use the current values of PCR - register 11 instead.) + , , see below. Only + is mandatory. (Alternatively, specify to use the + current values of PCR register 11 instead.) diff --git a/src/boot/measure.c b/src/boot/measure.c index 9fdc37dfb5c..81f1a9fbd2a 100644 --- a/src/boot/measure.c +++ b/src/boot/measure.c @@ -1017,14 +1017,6 @@ static int validate_stub(void) { if (r < 0) return r; - r = compare_reported_pcr_nr(TPM2_PCR_KERNEL_CONFIG, EFI_LOADER_VARIABLE(StubPcrKernelParameters), "kernel parameters"); - if (r < 0) - return r; - - r = compare_reported_pcr_nr(TPM2_PCR_SYSEXTS, EFI_LOADER_VARIABLE(StubPcrInitRDSysExts), "initrd system extension images"); - if (r < 0) - return r; - STRV_FOREACH(bank, arg_banks) { _cleanup_free_ char *b = NULL, *p = NULL; @@ -1049,12 +1041,6 @@ static int validate_stub(void) { } static int verb_status(int argc, char *argv[], void *userdata) { - static const uint32_t relevant_pcrs[] = { - TPM2_PCR_KERNEL_BOOT, - TPM2_PCR_KERNEL_CONFIG, - TPM2_PCR_SYSEXTS, - }; - _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; int r; @@ -1062,72 +1048,69 @@ static int verb_status(int argc, char *argv[], void *userdata) { if (r < 0) return r; - for (size_t i = 0; i < ELEMENTSOF(relevant_pcrs); i++) { + STRV_FOREACH(bank, arg_banks) { + _cleanup_free_ char *b = NULL, *p = NULL, *s = NULL; + _cleanup_free_ void *h = NULL; + size_t l; - STRV_FOREACH(bank, arg_banks) { - _cleanup_free_ char *b = NULL, *p = NULL, *s = NULL; - _cleanup_free_ void *h = NULL; - size_t l; + b = strdup(*bank); + if (!b) + return log_oom(); - b = strdup(*bank); - if (!b) + if (asprintf(&p, "/sys/class/tpm/tpm0/pcr-%s/%" PRIu32, ascii_strlower(b), (uint32_t) TPM2_PCR_KERNEL_BOOT) < 0) + return log_oom(); + + r = read_virtual_file(p, 4096, &s, NULL); + if (r == -ENOENT) + continue; + if (r < 0) + return log_error_errno(r, "Failed to read '%s': %m", p); + + r = unhexmem(strstrip(s), &h, &l); + if (r < 0) + return log_error_errno(r, "Failed to decode PCR value '%s': %m", s); + + if (arg_json_format_flags & SD_JSON_FORMAT_OFF) { + _cleanup_free_ char *f = NULL; + + f = hexmem(h, l); + if (!h) return log_oom(); - if (asprintf(&p, "/sys/class/tpm/tpm0/pcr-%s/%" PRIu32, ascii_strlower(b), relevant_pcrs[i]) < 0) - return log_oom(); - - r = read_virtual_file(p, 4096, &s, NULL); - if (r == -ENOENT) - continue; - if (r < 0) - return log_error_errno(r, "Failed to read '%s': %m", p); - - r = unhexmem(strstrip(s), &h, &l); - if (r < 0) - return log_error_errno(r, "Failed to decode PCR value '%s': %m", s); - - if (arg_json_format_flags & SD_JSON_FORMAT_OFF) { - _cleanup_free_ char *f = NULL; - - f = hexmem(h, l); - if (!h) - return log_oom(); - - if (bank == arg_banks) { - /* before the first line for each PCR, write a short descriptive text to - * stderr, and leave the primary content on stdout */ - fflush(stdout); - fprintf(stderr, "%s# PCR[%" PRIu32 "] %s%s%s\n", - ansi_grey(), - relevant_pcrs[i], - tpm2_pcr_index_to_string(relevant_pcrs[i]), - memeqzero(h, l) ? " (NOT SET!)" : "", - ansi_normal()); - fflush(stderr); - } - - printf("%" PRIu32 ":%s=%s\n", relevant_pcrs[i], b, f); - - } else { - _cleanup_(sd_json_variant_unrefp) sd_json_variant *bv = NULL, *a = NULL; - - r = sd_json_buildo( - &bv, - SD_JSON_BUILD_PAIR("pcr", SD_JSON_BUILD_INTEGER(relevant_pcrs[i])), - SD_JSON_BUILD_PAIR("hash", SD_JSON_BUILD_HEX(h, l))); - if (r < 0) - return log_error_errno(r, "Failed to build JSON object: %m"); - - a = sd_json_variant_ref(sd_json_variant_by_key(v, b)); - - r = sd_json_variant_append_array(&a, bv); - if (r < 0) - return log_error_errno(r, "Failed to append PCR entry to JSON array: %m"); - - r = sd_json_variant_set_field(&v, b, a); - if (r < 0) - return log_error_errno(r, "Failed to add bank info to object: %m"); + if (bank == arg_banks) { + /* before the first line for each PCR, write a short descriptive text to + * stderr, and leave the primary content on stdout */ + fflush(stdout); + fprintf(stderr, "%s# PCR[%" PRIu32 "] %s%s%s\n", + ansi_grey(), + (uint32_t) TPM2_PCR_KERNEL_BOOT, + tpm2_pcr_index_to_string(TPM2_PCR_KERNEL_BOOT), + memeqzero(h, l) ? " (NOT SET!)" : "", + ansi_normal()); + fflush(stderr); } + + printf("%" PRIu32 ":%s=%s\n", (uint32_t) TPM2_PCR_KERNEL_BOOT, b, f); + + } else { + _cleanup_(sd_json_variant_unrefp) sd_json_variant *bv = NULL, *a = NULL; + + r = sd_json_buildo( + &bv, + SD_JSON_BUILD_PAIR("pcr", SD_JSON_BUILD_INTEGER(TPM2_PCR_KERNEL_BOOT)), + SD_JSON_BUILD_PAIR("hash", SD_JSON_BUILD_HEX(h, l))); + if (r < 0) + return log_error_errno(r, "Failed to build JSON object: %m"); + + a = sd_json_variant_ref(sd_json_variant_by_key(v, b)); + + r = sd_json_variant_append_array(&a, bv); + if (r < 0) + return log_error_errno(r, "Failed to append PCR entry to JSON array: %m"); + + r = sd_json_variant_set_field(&v, b, a); + if (r < 0) + return log_error_errno(r, "Failed to add bank info to object: %m"); } }