From 48bd67e6f2a4deac1fb65337fe23d1317fbdddb770fbb2c66f303803e38b20cb Mon Sep 17 00:00:00 2001 From: Alberto Planas Dominguez Date: Wed, 7 Aug 2024 06:20:05 +0000 Subject: [PATCH] - Add support-ecc-srk.patch to support ECC SRK - Add fix-testcase-empty-efi-variables.patch to fix the testcase playback on empty EFI variables OBS-URL: https://build.opensuse.org/package/show/Base:System/pcr-oracle?expand=0&rev=32 --- .gitattributes | 23 ++ .gitignore | 1 + _service | 17 + fix-testcase-empty-efi-variables.patch | 58 ++++ fix_efi_measure_and_shim.patch | 412 ++++++++++++++++++++++++ fix_grub_bls_cmdline.patch | 335 ++++++++++++++++++++ fix_grub_bls_entry.patch | 188 +++++++++++ fix_loader_conf.patch | 79 +++++ pcr-oracle-0.5.4.tar.xz | 3 + pcr-oracle.changes | 179 +++++++++++ pcr-oracle.spec | 72 +++++ support-ecc-srk.patch | 413 +++++++++++++++++++++++++ 12 files changed, 1780 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 _service create mode 100644 fix-testcase-empty-efi-variables.patch create mode 100644 fix_efi_measure_and_shim.patch create mode 100644 fix_grub_bls_cmdline.patch create mode 100644 fix_grub_bls_entry.patch create mode 100644 fix_loader_conf.patch create mode 100644 pcr-oracle-0.5.4.tar.xz create mode 100644 pcr-oracle.changes create mode 100644 pcr-oracle.spec create mode 100644 support-ecc-srk.patch diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/_service b/_service new file mode 100644 index 0000000..839a19f --- /dev/null +++ b/_service @@ -0,0 +1,17 @@ + + + + + + git + https://github.com/okirch/pcr-oracle.git + pcr-oracle + @PARENT_TAG@ + refs/tags/0.5.4 + + + pcr-oracle*.tar + xz + + + diff --git a/fix-testcase-empty-efi-variables.patch b/fix-testcase-empty-efi-variables.patch new file mode 100644 index 0000000..6bcaa48 --- /dev/null +++ b/fix-testcase-empty-efi-variables.patch @@ -0,0 +1,58 @@ +From 61f9b77634578c0bf0c3bf6c4b386057e8661a1c Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Wed, 12 Jun 2024 14:41:38 +0800 +Subject: [PATCH] testcase: fix playback on empty EFI variables + +For systems in UEFI Setup mode, there is no PK, KEK, or db. However, +those variables are still recorded in the TPM event log with zero +length. To avoid failing on reading those files, this commit changes the +file reading flag so that testcase playback won't stop on those EFI +variables. + +Signed-off-by: Gary Lin +--- + src/testcase.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/src/testcase.c b/src/testcase.c +index f74238b..998aedd 100644 +--- a/src/testcase.c ++++ b/src/testcase.c +@@ -224,12 +224,18 @@ testcase_write_file(const char *directory, const char *name, const buffer_t *bp) + } + + static buffer_t * +-testcase_read_file(const char *directory, const char *name) ++__testcase_read_file(const char *directory, const char *name, int flags) + { + char path[PATH_MAX]; + + snprintf(path, sizeof(path), "%s/%s", directory, name); +- return runtime_read_file(path, 0); ++ return runtime_read_file(path, flags); ++} ++ ++static buffer_t * ++testcase_read_file(const char *directory, const char *name) ++{ ++ return __testcase_read_file(directory, name, 0); + } + + testcase_t * +@@ -314,7 +320,12 @@ testcase_record_efi_variable(testcase_t *tc, const char *name, const buffer_t *d + buffer_t * + testcase_playback_efi_variable(testcase_t *tc, const char *name) + { +- return testcase_read_file(tc->efi_directory, name); ++ /* For systems in UEFI Setup mode, there is no PK, KEK, or db, but those ++ * variables are still recorded in the TPM event log with zero length. ++ * Set the file reading flag to skip those EFI variable files. ++ */ ++ return __testcase_read_file(tc->efi_directory, name, ++ RUNTIME_MISSING_FILE_OKAY); + } + + void +-- +2.35.3 + diff --git a/fix_efi_measure_and_shim.patch b/fix_efi_measure_and_shim.patch new file mode 100644 index 0000000..523665b --- /dev/null +++ b/fix_efi_measure_and_shim.patch @@ -0,0 +1,412 @@ +From 9489d98463a596ec8e4ba9f1f4a2b2af91c0968b Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Wed, 10 Jan 2024 15:32:07 +0100 +Subject: [PATCH 1/8] Print the measured kernel + +The debug output can be missleading, as print information about the +current event log, but not about the measured element, that can be +different as in the kernel case. + +Signed-off-by: Alberto Planas +--- + src/efi-application.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/efi-application.c b/src/efi-application.c +index 3e80083..2fd33ec 100644 +--- a/src/efi-application.c ++++ b/src/efi-application.c +@@ -292,6 +292,12 @@ __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars + + /* The next boot can have a different kernel */ + if (sdb_is_kernel(evspec->efi_application) && ctx->boot_entry) { ++ /* TODO: the parsed data type did not change, so all ++ * the description correspond to the current event ++ * log, and not the asset that has been measured. The ++ * debug output can then be missleading. ++ */ ++ debug("Measuring %s\n", ctx->boot_entry->image_path); + new_application = ctx->boot_entry->image_path; + if (new_application) { + evspec_clone = *evspec; + +From d8d97a3c233e326e0b1836b77fa08f483ea8f410 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Wed, 10 Jan 2024 15:51:45 +0100 +Subject: [PATCH 2/8] Rename variable to cmdline + +Signed-off-by: Alberto Planas +--- + src/eventlog.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/src/eventlog.c b/src/eventlog.c +index 4277d42..377f4d6 100644 +--- a/src/eventlog.c ++++ b/src/eventlog.c +@@ -790,8 +790,8 @@ static const tpm_evdigest_t * + __tpm_event_systemd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) + { + const uapi_boot_entry_t *boot_entry = ctx->boot_entry; +- char initrd[2048]; +- char initrd_utf16[4096]; ++ char cmdline[2048]; ++ char cmdline_utf16[4096]; + unsigned int len; + + /* If no --next-kernel option was given, do not rehash anything */ +@@ -804,15 +804,16 @@ __tpm_event_systemd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars + } + + debug("Next boot entry expected from: %s %s\n", boot_entry->title, boot_entry->version? : ""); +- snprintf(initrd, sizeof(initrd), "initrd=%s %s", ++ snprintf(cmdline, sizeof(cmdline), "initrd=%s %s", + path_unix2dos(boot_entry->initrd_path), + boot_entry->options? : ""); ++ debug("Measuring Kernel command line: %s\n", cmdline); + +- len = (strlen(initrd) + 1) << 1; +- assert(len <= sizeof(initrd_utf16)); +- __convert_to_utf16le(initrd, strlen(initrd) + 1, initrd_utf16, len); ++ len = (strlen(cmdline) + 1) << 1; ++ assert(len <= sizeof(cmdline_utf16)); ++ __convert_to_utf16le(cmdline, strlen(cmdline) + 1, cmdline_utf16, len); + +- return digest_compute(ctx->algo, initrd_utf16, len); ++ return digest_compute(ctx->algo, cmdline_utf16, len); + } + + /* + +From 4f8e3f4760ff7fe97df1e6af569d049e30f3ee06 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Wed, 10 Jan 2024 15:55:41 +0100 +Subject: [PATCH 3/8] Add debug output for initrd + +Signed-off-by: Alberto Planas +--- + src/eventlog.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/eventlog.c b/src/eventlog.c +index 377f4d6..3574a4d 100644 +--- a/src/eventlog.c ++++ b/src/eventlog.c +@@ -877,6 +877,7 @@ __tpm_event_tag_initrd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *p + } + + debug("Next boot entry expected from: %s %s\n", boot_entry->title, boot_entry->version? : ""); ++ debug("Measuring initrd: %s\n", boot_entry->initrd_path); + return runtime_digest_efi_file(ctx->algo, boot_entry->initrd_path); + } + + +From 90ee8dab9d972b741bc0c27a04a872afbecdef82 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Wed, 10 Jan 2024 18:54:04 +0100 +Subject: [PATCH 4/8] Add debug output during extension + +Signed-off-by: Alberto Planas +--- + src/oracle.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/oracle.c b/src/oracle.c +index 1cafafc..0afd910 100644 +--- a/src/oracle.c ++++ b/src/oracle.c +@@ -366,6 +366,7 @@ pcr_bank_extend_register(tpm_pcr_bank_t *bank, unsigned int pcr_index, const tpm + static void + predictor_extend_hash(struct predictor *pred, unsigned int pcr_index, const tpm_evdigest_t *d) + { ++ debug("Extend PCR#%d: %s\n", pcr_index, digest_print(d)); + pcr_bank_extend_register(&pred->prediction, pcr_index, d); + } + + +From 5133fe6f3c00a41aee362a51621a278dd472497e Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Thu, 11 Jan 2024 14:09:03 +0100 +Subject: [PATCH 5/8] Update the EFI image info before rehash + +If the new EFI image is in a new place, the image information stored in +the parsed event should be updated, so the rehash will use this +information instead of the one from the event log. + +Signed-off-by: Alberto Planas +--- + src/efi-application.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/efi-application.c b/src/efi-application.c +index 2fd33ec..842bca6 100644 +--- a/src/efi-application.c ++++ b/src/efi-application.c +@@ -40,7 +40,7 @@ + */ + static const tpm_evdigest_t * __tpm_event_efi_bsa_rehash(const tpm_event_t *, const tpm_parsed_event_t *, tpm_event_log_rehash_ctx_t *); + static bool __tpm_event_efi_bsa_extract_location(tpm_parsed_event_t *parsed); +-static bool __tpm_event_efi_bsa_inspect_image(tpm_parsed_event_t *parsed); ++static bool __tpm_event_efi_bsa_inspect_image(struct efi_bsa_event *evspec); + + static void + __tpm_event_efi_bsa_destroy(tpm_parsed_event_t *parsed) +@@ -111,7 +111,7 @@ __tpm_event_parse_efi_bsa(tpm_event_t *ev, tpm_parsed_event_t *parsed, buffer_t + assign_string(&ctx->efi_partition, evspec->efi_partition); + else + assign_string(&evspec->efi_partition, ctx->efi_partition); +- __tpm_event_efi_bsa_inspect_image(parsed); ++ __tpm_event_efi_bsa_inspect_image(evspec); + } + + return true; +@@ -150,9 +150,8 @@ __tpm_event_efi_bsa_extract_location(tpm_parsed_event_t *parsed) + } + + static bool +-__tpm_event_efi_bsa_inspect_image(tpm_parsed_event_t *parsed) ++__tpm_event_efi_bsa_inspect_image(struct efi_bsa_event *evspec) + { +- struct efi_bsa_event *evspec = &parsed->efi_bsa_event; + char path[PATH_MAX]; + const char *display_name; + buffer_t *img_data; +@@ -302,6 +301,7 @@ __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars + if (new_application) { + evspec_clone = *evspec; + evspec_clone.efi_application = strdup(new_application); ++ __tpm_event_efi_bsa_inspect_image(&evspec_clone); + evspec = &evspec_clone; + } + } + +From 93cbe02ca05297c638b1ac7f32b3da3a6cd2f684 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Thu, 11 Jan 2024 14:35:07 +0100 +Subject: [PATCH 6/8] Bump version to 0.5.5 + +Signed-off-by: Alberto Planas +--- + configure | 2 +- + microconf/version | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/configure b/configure +index 1dccbdc..854cc0a 100755 +--- a/configure ++++ b/configure +@@ -12,7 +12,7 @@ + # Invoke with --help for a description of options + # + # microconf:begin +-# version 0.5.4 ++# version 0.5.5 + # require libtss2 + # require json + # disable debug-authenticode +diff --git a/microconf/version b/microconf/version +index 7e913d9..591473f 100644 +--- a/microconf/version ++++ b/microconf/version +@@ -1 +1 @@ +-uc_version=0.5.4 ++uc_version=0.5.5 + +From e622620a8de5eaf499265adf6c5e8d2ecdaa295b Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Mon, 26 Feb 2024 13:34:13 +0100 +Subject: [PATCH 7/8] Add secure boot detector + +Signed-off-by: Alberto Planas +--- + Makefile.in | 3 ++- + src/eventlog.h | 2 ++ + src/secure_boot.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 48 insertions(+), 1 deletion(-) + create mode 100644 src/secure_boot.c + +diff --git a/Makefile.in b/Makefile.in +index 02a915b..9698253 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -34,7 +34,8 @@ ORACLE_SRCS = oracle.c \ + store.c \ + util.c \ + sd-boot.c \ +- uapi.c ++ uapi.c \ ++ secure_boot.c + ORACLE_OBJS = $(addprefix build/,$(patsubst %.c,%.o,$(ORACLE_SRCS))) + + all: $(TOOLS) $(MANPAGES) +diff --git a/src/eventlog.h b/src/eventlog.h +index 3741b58..8af5eb0 100644 +--- a/src/eventlog.h ++++ b/src/eventlog.h +@@ -323,4 +323,6 @@ extern bool shim_variable_name_valid(const char *name); + extern const char * shim_variable_get_rtname(const char *name); + extern const char * shim_variable_get_full_rtname(const char *name); + ++extern bool secure_boot_enabled(); ++ + #endif /* EVENTLOG_H */ +diff --git a/src/secure_boot.c b/src/secure_boot.c +new file mode 100644 +index 0000000..215baa6 +--- /dev/null ++++ b/src/secure_boot.c +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (C) 2023 SUSE LLC ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * Written by Alberto Planas ++ */ ++ ++#include ++#include "bufparser.h" ++#include "runtime.h" ++ ++#define SECURE_BOOT_EFIVAR_NAME "SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c" ++ ++ ++bool ++secure_boot_enabled() ++{ ++ buffer_t *data; ++ uint8_t enabled; ++ ++ data = runtime_read_efi_variable(SECURE_BOOT_EFIVAR_NAME); ++ if (data == NULL) { ++ return false; ++ } ++ ++ if (!buffer_get_u8(data, &enabled)) { ++ return false; ++ } ++ ++ return enabled == 1; ++} + +From 211502ec5cac7e252f8af251ee34872f7adae9ca Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Mon, 26 Feb 2024 14:52:37 +0100 +Subject: [PATCH 8/8] Detect when device path is missing for kernel + +Signed-off-by: Alberto Planas +--- + src/efi-application.c | 48 ++++++++++++++++++++++++++++++++++++++++--- + src/sd-boot.c | 3 +++ + 2 files changed, 48 insertions(+), 3 deletions(-) + +diff --git a/src/efi-application.c b/src/efi-application.c +index 842bca6..1f434fc 100644 +--- a/src/efi-application.c ++++ b/src/efi-application.c +@@ -42,6 +42,8 @@ static const tpm_evdigest_t * __tpm_event_efi_bsa_rehash(const tpm_event_t *, co + static bool __tpm_event_efi_bsa_extract_location(tpm_parsed_event_t *parsed); + static bool __tpm_event_efi_bsa_inspect_image(struct efi_bsa_event *evspec); + ++static bool __is_shim_issue(const tpm_event_t *ev, const struct efi_bsa_event *evspec); ++ + static void + __tpm_event_efi_bsa_destroy(tpm_parsed_event_t *parsed) + { +@@ -114,6 +116,15 @@ __tpm_event_parse_efi_bsa(tpm_event_t *ev, tpm_parsed_event_t *parsed, buffer_t + __tpm_event_efi_bsa_inspect_image(evspec); + } + ++ /* When the shim issue is present the efi_application will be ++ * empty. The binary path will be reconstructed with the ++ * --next-kernel parameter, but to generate the full path the ++ * `efi_partition` is needed. ++ */ ++ if (__is_shim_issue(ev, evspec)) ++ assign_string(&evspec->efi_partition, ctx->efi_partition); ++ ++ + return true; + } + +@@ -273,6 +284,31 @@ efi_application_extract_signer(const tpm_parsed_event_t *parsed) + return authenticode_get_signer(evspec->img_info); + } + ++static bool __is_shim_issue(const tpm_event_t *ev, const struct efi_bsa_event *evspec) ++{ ++ /* When secure boot is enabled and shim is installed, ++ * systemd-boot installs some security overrides that will ++ * delegate into shim (via shim_validate from systemd-boot) ++ * the validation of the kernel signature. ++ * ++ * The shim_validate function receives the device path from ++ * the firmware, and is used to load the kernel into memory. ++ * At the end call shim_verify from shim, but pass only the ++ * buffer with the loaded image. ++ * ++ * The net result is that the event log ++ * EV_EFI_BOOT_SERVICES_APPLICATION registered by shim_verify ++ * will not contain the device path that pcr-oracle requires ++ * to rehash the binary. ++ * ++ * So far only the kernel is presenting this issue (when ++ * systemd-boot is used, GRUB2 needs to be evaluated), so this ++ * can be detected if there is an event registered in PCR 4 ++ * without path. ++ */ ++ return (secure_boot_enabled() && ev->pcr_index == 4 && !evspec->efi_application); ++} ++ + static const tpm_evdigest_t * + __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) + { +@@ -284,13 +320,19 @@ __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars + * We're not yet prepared to handle these, so we hope the user doesn't mess with them, and + * return the original digest from the event log. + */ +- if (!evspec->efi_application) { +- debug("Unable to locate boot service application - probably not a file\n"); ++ if (!evspec->efi_application && !(__is_shim_issue(ev, evspec) && ctx->boot_entry)) { ++ if (__is_shim_issue(ev, evspec) && !ctx->boot_entry) ++ debug("Unable to locate boot service application - missing device path because shim issue"); ++ else ++ debug("Unable to locate boot service application - probably not a file\n"); + return tpm_event_get_digest(ev, ctx->algo); + } + + /* The next boot can have a different kernel */ +- if (sdb_is_kernel(evspec->efi_application) && ctx->boot_entry) { ++ if ((sdb_is_kernel(evspec->efi_application) || __is_shim_issue(ev, evspec)) && ctx->boot_entry) { ++ if (__is_shim_issue(ev, evspec)) ++ debug("Empty device path for the kernel - building one based on next kernel\n"); ++ + /* TODO: the parsed data type did not change, so all + * the description correspond to the current event + * log, and not the asset that has been measured. The +diff --git a/src/sd-boot.c b/src/sd-boot.c +index cbdaa49..ede2569 100644 +--- a/src/sd-boot.c ++++ b/src/sd-boot.c +@@ -138,6 +138,9 @@ sdb_is_kernel(const char *application) + char *path_copy; + int found = 0; + ++ if (!application) ++ return false; ++ + match = get_valid_kernel_entry_tokens(); + path_copy = strdup(application); + diff --git a/fix_grub_bls_cmdline.patch b/fix_grub_bls_cmdline.patch new file mode 100644 index 0000000..2996eb9 --- /dev/null +++ b/fix_grub_bls_cmdline.patch @@ -0,0 +1,335 @@ +From fca4a51b9aac712b3adc5b6b187cc31a8391bcf6 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Fri, 22 Mar 2024 22:44:41 +0100 +Subject: [PATCH] GRUB: predict cmdline, linux and initrd lines + +Signed-off-by: Alberto Planas +--- + src/eventlog.c | 195 ++++++++++++++++++++++++++++++++++++++----------- + src/eventlog.h | 26 ++++--- + 2 files changed, 169 insertions(+), 52 deletions(-) + +diff --git a/src/eventlog.c b/src/eventlog.c +index db18f41..727f6a9 100644 +--- a/src/eventlog.c ++++ b/src/eventlog.c +@@ -549,14 +549,66 @@ tpm_event_decode_uuid(const unsigned char *data) + return uuid; + } + ++/* ++ * For files residing on the EFI partition, grub usually formats these as ++ * (hdX,gptY)/EFI/BOOT/some.file ++ * Once it has determined the final root device, the device part will be ++ * omitted (eg for kernel and initrd). ++ */ ++static bool ++__grub_file_parse(grub_file_t *grub_file, const char *value) ++{ ++ if (value[0] == '/') { ++ grub_file->device = NULL; ++ grub_file->path = strdup(value); ++ } else if (value[0] == '(') { ++ char *copy = strdup(value); ++ char *path; ++ ++ if ((path = strchr(copy, ')')) == NULL) { ++ free(copy); ++ return false; ++ } ++ ++ *path++ = '\0'; ++ ++ grub_file->device = strdup(copy + 1); ++ grub_file->path = strdup(path); ++ free(copy); ++ } else { ++ return false; ++ } ++ ++ return true; ++} ++ ++static const char * ++__grub_file_join(grub_file_t grub_file) ++{ ++ static char path[PATH_MAX]; ++ ++ if (grub_file.device == NULL) ++ snprintf(path, sizeof(path), "%s", grub_file.path); ++ else ++ snprintf(path, sizeof(path), "(%s)%s", grub_file.device, grub_file.path); ++ ++ return path; ++} ++ ++static void ++__grub_file_destroy(grub_file_t *grub_file) ++{ ++ drop_string(&grub_file->device); ++ drop_string(&grub_file->path); ++} ++ + /* + * Handle IPL events, which grub2 and sd-boot uses to hide its stuff in + */ + static void + __tpm_event_grub_file_destroy(tpm_parsed_event_t *parsed) + { +- drop_string(&parsed->grub_file.device); +- drop_string(&parsed->grub_file.path); ++ __grub_file_destroy(&parsed->grub_file); + } + + const char * +@@ -564,10 +616,7 @@ __tpm_event_grub_file_describe(const tpm_parsed_event_t *parsed) + { + static char buffer[1024]; + +- if (parsed->grub_file.device == NULL) +- snprintf(buffer, sizeof(buffer), "grub2 file load from %s", parsed->grub_file.path); +- else +- snprintf(buffer, sizeof(buffer), "grub2 file load from (%s)%s", parsed->grub_file.device, parsed->grub_file.path); ++ snprintf(buffer, sizeof(buffer), "grub2 file load from %s", __grub_file_join(parsed->grub_file)); + return buffer; + } + +@@ -575,7 +624,7 @@ __tpm_event_grub_file_describe(const tpm_parsed_event_t *parsed) + static const tpm_evdigest_t * + __tpm_event_grub_file_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) + { +- const struct grub_file_event *evspec = &parsed->grub_file; ++ const grub_file_event *evspec = &parsed->grub_file; + const tpm_evdigest_t *md = NULL; + + debug(" re-hashing %s\n", __tpm_event_grub_file_describe(parsed)); +@@ -606,35 +655,11 @@ __tpm_event_grub_file_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pa + return md; + } + +-/* +- * For files residing on the EFI partition, grub usually formats these as +- * (hdX,gptY)/EFI/BOOT/some.file +- * Once it has determined the final root device, the device part will be +- * omitted (eg for kernel and initrd). +- */ + static bool + __tpm_event_grub_file_event_parse(tpm_event_t *ev, tpm_parsed_event_t *parsed, const char *value) + { +- if (value[0] == '/') { +- parsed->grub_file.device = NULL; +- parsed->grub_file.path = strdup(value); +- } else if (value[0] == '(') { +- char *copy = strdup(value); +- char *path; +- +- if ((path = strchr(copy, ')')) == NULL) { +- free(copy); +- return false; +- } +- +- *path++ = '\0'; +- +- parsed->grub_file.device = strdup(copy + 1); +- parsed->grub_file.path = strdup(path); +- free(copy); +- } else { ++ if (!__grub_file_parse(&parsed->grub_file, value)) + return false; +- } + + parsed->event_subtype = GRUB_EVENT_FILE; + parsed->destroy = __tpm_event_grub_file_destroy; +@@ -658,21 +683,87 @@ static const char * + __tpm_event_grub_command_describe(const tpm_parsed_event_t *parsed) + { + static char buffer[128]; ++ static char *topic = NULL; ++ ++ switch (parsed->event_subtype) { ++ case GRUB_EVENT_COMMAND: ++ topic = "grub2 command"; ++ break; ++ case GRUB_EVENT_COMMAND_LINUX: ++ topic = "grub2 linux command"; ++ break; ++ case GRUB_EVENT_COMMAND_INITRD: ++ topic = "grub2 initrd command"; ++ break; ++ case GRUB_EVENT_KERNEL_CMDLINE: ++ topic = "grub2 kernel cmdline"; ++ break; ++ } ++ ++ snprintf(buffer, sizeof(buffer), "%s \"%s\"", topic, parsed->grub_command.string); + +- if (parsed->event_subtype == GRUB_EVENT_COMMAND) +- snprintf(buffer, sizeof(buffer), "grub2 command \"%s\"", parsed->grub_command.string); +- else +- snprintf(buffer, sizeof(buffer), "grub2 kernel cmdline \"%s\"", parsed->grub_command.string); + return buffer; + } + + static const tpm_evdigest_t * + __tpm_event_grub_command_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) + { +- if (parsed->grub_command.string == NULL) +- return NULL; ++ char *str = NULL; ++ size_t sz = 0; ++ const tpm_evdigest_t *digest = NULL; ++ grub_file_t file; ++ ++ switch (parsed->event_subtype) { ++ case GRUB_EVENT_COMMAND: ++ str = strdup(parsed->grub_command.string); ++ break; ++ case GRUB_EVENT_COMMAND_LINUX: ++ if (ctx->boot_entry && parsed->grub_command.file.path) { ++ file = (grub_file_t) { ++ .device = parsed->grub_command.file.device, ++ .path = ctx->boot_entry->image_path, ++ }; ++ sz = snprintf(NULL, 0, "linux %s %s", __grub_file_join(file), ctx->boot_entry->options); ++ str = malloc(sz + 1); ++ snprintf(str, sz + 1, "linux %s %s", __grub_file_join(file), ctx->boot_entry->options); ++ debug("Hashed linux command: %s\n", str); ++ } else ++ str = strdup(parsed->grub_command.string); ++ break; ++ case GRUB_EVENT_COMMAND_INITRD: ++ if (ctx->boot_entry && parsed->grub_command.file.path) { ++ file = (grub_file_t) { ++ .device = parsed->grub_command.file.device, ++ .path = ctx->boot_entry->initrd_path, ++ }; ++ sz = snprintf(NULL, 0, "initrd %s", __grub_file_join(file)); ++ str = malloc(sz + 1); ++ snprintf(str, sz + 1, "initrd %s", __grub_file_join(file)); ++ debug("Hashed initrd command: %s\n", str); ++ } else ++ str = strdup(parsed->grub_command.string); ++ break; ++ case GRUB_EVENT_KERNEL_CMDLINE: ++ if (ctx->boot_entry && parsed->grub_command.file.path) { ++ file = (grub_file_t) { ++ .device = parsed->grub_command.file.device, ++ .path = ctx->boot_entry->image_path, ++ }; ++ sz = snprintf(NULL, 0, "%s %s", __grub_file_join(file), ctx->boot_entry->options); ++ str = malloc(sz + 1); ++ snprintf(str, sz + 1, "%s %s", __grub_file_join(file), ctx->boot_entry->options); ++ debug("Hashed kernel cmdline: %s\n", str); ++ } else ++ str = strdup(parsed->grub_command.string); ++ break; ++ } ++ ++ if (str) { ++ digest = digest_compute(ctx->algo, str, strlen(str)); ++ free(str); ++ } + +- return digest_compute(ctx->algo, parsed->grub_command.string, strlen(parsed->grub_command.string)); ++ return digest; + } + + /* +@@ -703,15 +794,29 @@ __tpm_event_grub_command_event_parse(tpm_event_t *ev, tpm_parsed_event_t *parsed + keyword = copy; + arg = copy + wordlen; + ++ if (!strcmp(keyword, "grub_cmd") && !strncmp(arg, "linux", strlen("linux"))) { ++ for (wordlen = 0; (cc = arg[wordlen]) && (cc != ' '); ++wordlen) ++ ; ++ if (arg[wordlen] == ' ' && !__grub_file_parse(&parsed->grub_command.file, arg + wordlen + 1)) ++ goto failed; ++ parsed->event_subtype = GRUB_EVENT_COMMAND_LINUX; ++ } else ++ if (!strcmp(keyword, "grub_cmd") && !strncmp(arg, "initrd", strlen("initrd"))) { ++ for (wordlen = 0; (cc = arg[wordlen]) && (cc != ' '); ++wordlen) ++ ; ++ if (arg[wordlen] == ' ' && !__grub_file_parse(&parsed->grub_command.file, arg + wordlen + 1)) ++ goto failed; ++ parsed->event_subtype = GRUB_EVENT_COMMAND_INITRD; ++ } else + if (!strcmp(keyword, "grub_cmd")) { + parsed->event_subtype = GRUB_EVENT_COMMAND; + } else + if (!strcmp(keyword, "kernel_cmdline")) { ++ if (!__grub_file_parse(&parsed->grub_command.file, arg)) ++ goto failed; + parsed->event_subtype = GRUB_EVENT_KERNEL_CMDLINE; +- } else { +- free(copy); +- return false; +- } ++ } else ++ goto failed; + + parsed->grub_command.string = strdup(arg); + for (argc = 0, s = strtok(arg, " \t"); s && argc < GRUB_COMMAND_ARGV_MAX - 1; s = strtok(NULL, " \t")) { +@@ -725,6 +830,10 @@ __tpm_event_grub_command_event_parse(tpm_event_t *ev, tpm_parsed_event_t *parsed + + free(copy); + return true; ++ ++failed: ++ free(copy); ++ return false; + } + + static void +diff --git a/src/eventlog.h b/src/eventlog.h +index d142744..6a8c3a4 100644 +--- a/src/eventlog.h ++++ b/src/eventlog.h +@@ -89,10 +89,12 @@ enum { + enum { + /* IPL subtypes for grub */ + GRUB_EVENT_COMMAND = 0x0001, +- GRUB_EVENT_FILE = 0x0002, +- GRUB_EVENT_KERNEL_CMDLINE = 0x0003, +- SHIM_EVENT_VARIABLE = 0x0004, +- SYSTEMD_EVENT_VARIABLE = 0x0005, ++ GRUB_EVENT_COMMAND_LINUX = 0x0002, ++ GRUB_EVENT_COMMAND_INITRD = 0x0003, ++ GRUB_EVENT_FILE = 0x0004, ++ GRUB_EVENT_KERNEL_CMDLINE = 0x0005, ++ SHIM_EVENT_VARIABLE = 0x0006, ++ SYSTEMD_EVENT_VARIABLE = 0x0007, + }; + + enum { +@@ -208,6 +210,13 @@ typedef struct tpm_event_log_rehash_ctx { + + #define GRUB_COMMAND_ARGV_MAX 32 + ++typedef struct grub_file { ++ char * device; ++ char * path; ++} grub_file_t; ++ ++typedef grub_file_t grub_file_event; ++ + /* + * Parsed event types + */ +@@ -247,13 +256,12 @@ typedef struct tpm_parsed_event { + /* for GRUB_COMMAND, GRUB_KERNEL_CMDLINE */ + struct grub_command_event { + char * string; +- char * argv[GRUB_COMMAND_ARGV_MAX]; ++ char * argv[GRUB_COMMAND_ARGV_MAX]; ++ grub_file_t file; + } grub_command; + +- struct grub_file_event { +- char * device; +- char * path; +- } grub_file; ++ /* for GRUB_FILE */ ++ grub_file_event grub_file; + + struct shim_event { + char * string; diff --git a/fix_grub_bls_entry.patch b/fix_grub_bls_entry.patch new file mode 100644 index 0000000..e22fc98 --- /dev/null +++ b/fix_grub_bls_entry.patch @@ -0,0 +1,188 @@ +From b0c4c5fbdcc89b44cee2300c5a12cb5e8de0e446 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Wed, 13 Mar 2024 22:57:17 +0100 +Subject: [PATCH] GRUB with BLS measure boot entries + +This includes the boot entry file, the kernel and the initrd specified +in the entry file. + +Signed-off-by: Alberto Planas +--- + src/eventlog.c | 21 +++++++++++++++++++-- + src/eventlog.h | 1 + + src/oracle.c | 12 +++++++++--- + src/sd-boot.c | 28 ++++++++++++++++++++++++---- + src/sd-boot.h | 2 ++ + src/uapi.h | 3 ++- + 6 files changed, 57 insertions(+), 10 deletions(-) + +diff --git a/src/eventlog.c b/src/eventlog.c +index 3574a4d..db18f41 100644 +--- a/src/eventlog.c ++++ b/src/eventlog.c +@@ -33,6 +33,7 @@ + #include "digest.h" + #include "util.h" + #include "uapi.h" ++#include "sd-boot.h" + + #define TPM_EVENT_LOG_MAX_ALGOS 64 + +@@ -582,8 +583,24 @@ __tpm_event_grub_file_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pa + debug(" assuming the file resides on system partition\n"); + md = runtime_digest_rootfs_file(ctx->algo, evspec->path); + } else { +- debug(" assuming the file resides on EFI boot partition\n"); +- md = runtime_digest_efi_file(ctx->algo, evspec->path); ++ if (sdb_is_boot_entry(evspec->path) && ctx->boot_entry_path) { ++ debug(" getting different boot entry file from EFI boot partition: %s\n", ++ ctx->boot_entry_path); ++ md = runtime_digest_rootfs_file(ctx->algo, ctx->boot_entry_path); ++ } else ++ if (sdb_is_kernel(evspec->path) && ctx->boot_entry) { ++ debug(" getting different kernel from EFI boot partition: %s\n", ++ ctx->boot_entry->image_path); ++ md = runtime_digest_efi_file(ctx->algo, ctx->boot_entry->image_path); ++ } else ++ if (sdb_is_initrd(evspec->path) && ctx->boot_entry) { ++ debug(" getting different initrd from EFI boot partition: %s\n", ++ ctx->boot_entry->initrd_path); ++ md = runtime_digest_efi_file(ctx->algo, ctx->boot_entry->initrd_path); ++ } else { ++ debug(" assuming the file resides on EFI boot partition\n"); ++ md = runtime_digest_efi_file(ctx->algo, evspec->path); ++ } + } + + return md; +diff --git a/src/eventlog.h b/src/eventlog.h +index 8af5eb0..d142744 100644 +--- a/src/eventlog.h ++++ b/src/eventlog.h +@@ -202,6 +202,7 @@ typedef struct tpm_event_log_rehash_ctx { + const pecoff_image_info_t *next_stage_img; + + /* This get set when the user specifies --next-kernel */ ++ char * boot_entry_path; + uapi_boot_entry_t * boot_entry; + } tpm_event_log_rehash_ctx_t; + +diff --git a/src/oracle.c b/src/oracle.c +index 0afd910..ac48823 100644 +--- a/src/oracle.c ++++ b/src/oracle.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + #include "oracle.h" + #include "util.h" +@@ -653,6 +654,7 @@ predictor_update_eventlog(struct predictor *pred) + tpm_event_log_rehash_ctx_t rehash_ctx; + tpm_event_t *ev, *stop_event = NULL; + bool okay = true; ++ char boot_entry_path[PATH_MAX]; + + predictor_pre_scan_eventlog(pred, &stop_event); + +@@ -663,9 +665,13 @@ predictor_update_eventlog(struct predictor *pred) + * systemd ID of the next kernel entry to be booted. + * FIXME: we should probably hide this behind a target_platform function. + */ +- if (pred->boot_entry_id != NULL +- && !(rehash_ctx.boot_entry = sdb_identify_boot_entry(pred->boot_entry_id))) +- fatal("unable to identify next kernel \"%s\"\n", pred->boot_entry_id); ++ if (pred->boot_entry_id != NULL) { ++ snprintf(boot_entry_path, sizeof(boot_entry_path), ++ "%s/%s", UAPI_BOOT_DIRECTORY, pred->boot_entry_id); ++ assign_string(&rehash_ctx.boot_entry_path, boot_entry_path); ++ if (!(rehash_ctx.boot_entry = sdb_identify_boot_entry(pred->boot_entry_id))) ++ fatal("unable to identify next kernel \"%s\"\n", pred->boot_entry_id); ++ } + + for (ev = pred->event_log; ev; ev = ev->next) { + tpm_evdigest_t *pcr; +diff --git a/src/sd-boot.c b/src/sd-boot.c +index ede2569..a16f814 100644 +--- a/src/sd-boot.c ++++ b/src/sd-boot.c +@@ -130,10 +130,9 @@ get_valid_kernel_entry_tokens(void) + /* + * This should probably use UAPI boot entry logic as well + */ +-bool +-sdb_is_kernel(const char *application) ++static bool ++is_valid_entry_token(const char *application, const char *prefix) + { +- static const char prefix[] = "linux-"; + const uapi_kernel_entry_tokens_t *match; + char *path_copy; + int found = 0; +@@ -151,7 +150,7 @@ sdb_is_kernel(const char *application) + + if (!strcmp(ptr, token)) + found |= 1; +- else if (!strncmp(ptr, prefix, sizeof(prefix) - 1)) ++ else if (!strncmp(ptr, prefix, strlen(prefix))) + found |= 2; + } + } +@@ -160,6 +159,27 @@ sdb_is_kernel(const char *application) + return (found == 3); + } + ++bool ++sdb_is_kernel(const char *application) ++{ ++ return is_valid_entry_token(application, "linux-"); ++} ++ ++bool ++sdb_is_initrd(const char *application) ++{ ++ return is_valid_entry_token(application, "initrd-"); ++} ++ ++bool ++sdb_is_boot_entry(const char *application) ++{ ++ if (!application) ++ return false; ++ ++ return !strncmp(application, UAPI_BOOT_DIRECTORY_EFI, sizeof(UAPI_BOOT_DIRECTORY_EFI) - 1); ++} ++ + /* + * Identify the next kernel and initrd given an ID + */ +diff --git a/src/sd-boot.h b/src/sd-boot.h +index 0472320..ceab13d 100644 +--- a/src/sd-boot.h ++++ b/src/sd-boot.h +@@ -43,7 +43,9 @@ typedef struct sdb_entry_list { + } sdb_entry_list_t; + + extern uapi_boot_entry_t * sdb_identify_boot_entry(const char *id); ++extern bool sdb_is_boot_entry(const char *application); + extern bool sdb_is_kernel(const char *application); ++extern bool sdb_is_initrd(const char *application); + + /* This will have to update the systemd json file, and add a new entry. */ + extern bool sdb_policy_file_add_entry(const char *filename, +diff --git a/src/uapi.h b/src/uapi.h +index 96ca7ed..8bcb94f 100644 +--- a/src/uapi.h ++++ b/src/uapi.h +@@ -41,7 +41,8 @@ typedef struct uapi_kernel_entry_tokens { + char * entry_token[UAPI_MAX_ENTRY_TOKENS]; + } uapi_kernel_entry_tokens_t; + +-#define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries" ++#define UAPI_BOOT_DIRECTORY_EFI "/loader/entries" ++#define UAPI_BOOT_DIRECTORY "/boot/efi" UAPI_BOOT_DIRECTORY_EFI + + extern uapi_boot_entry_t * uapi_get_boot_entry(const char *id); + extern uapi_boot_entry_t * uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id); diff --git a/fix_loader_conf.patch b/fix_loader_conf.patch new file mode 100644 index 0000000..8205e04 --- /dev/null +++ b/fix_loader_conf.patch @@ -0,0 +1,79 @@ +From c2453df75ecdbc547e4637268dccde5cdc012881 Mon Sep 17 00:00:00 2001 +From: Alberto Planas +Date: Tue, 20 Feb 2024 19:12:08 +0100 +Subject: [PATCH] Measure systemd-boot loader.conf + +Since systemd-boot v255 the /loader/loader.conf file can be measured +under a EV_EVENT_TAG event in PCR#5. + +This commit measure the file in the ESP. + +Fix #49 + +Signed-off-by: Alberto Planas +--- + src/eventlog.c | 18 ++++++++++++++++++ + src/eventlog.h | 7 +++++-- + 2 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/src/eventlog.c b/src/eventlog.c +index 4277d42..2e29b0e 100644 +--- a/src/eventlog.c ++++ b/src/eventlog.c +@@ -842,6 +842,19 @@ __tpm_event_tag_destroy(tpm_parsed_event_t *parsed) + { + } + ++static const char * ++__tpm_event_tag_loader_conf_describe(const tpm_parsed_event_t *parsed) ++{ ++ return "/loader/loader.conf (measured by systemd-boot)"; ++} ++ ++static const tpm_evdigest_t * ++__tpm_event_tag_loader_conf_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx) ++{ ++ debug(" re-hashing /loader/loader.conf"); ++ return runtime_digest_efi_file(ctx->algo, "/loader/loader.conf"); ++} ++ + static const char * + __tpm_event_tag_options_describe(const tpm_parsed_event_t *parsed) + { +@@ -880,6 +893,7 @@ __tpm_event_tag_initrd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *p + } + + /* ++ * Generated by systemd-boot (PCR#5), to measure loader.conf + * Generated by the kernel (PCR#9), to measure the cmdline and initrd + */ + static bool +@@ -900,6 +914,10 @@ __tpm_event_parse_tag(tpm_event_t *ev, tpm_parsed_event_t *parsed, buffer_t *bp) + return false; + + parsed->destroy = __tpm_event_tag_destroy; ++ if (evspec->event_id == LOADER_CONF_EVENT_TAG_ID) { ++ parsed->rehash = __tpm_event_tag_loader_conf_rehash; ++ parsed->describe = __tpm_event_tag_loader_conf_describe; ++ } else + if (evspec->event_id == LOAD_OPTIONS_EVENT_TAG_ID) { + parsed->rehash = __tpm_event_tag_options_rehash; + parsed->describe = __tpm_event_tag_options_describe; +diff --git a/src/eventlog.h b/src/eventlog.h +index 3741b58..d78e3da 100644 +--- a/src/eventlog.h ++++ b/src/eventlog.h +@@ -96,8 +96,11 @@ enum { + }; + + enum { +- LOAD_OPTIONS_EVENT_TAG_ID = 0x8F3B22EDU, +- INITRD_EVENT_TAG_ID = 0x8F3B22ECU, ++ /* systemd-boot */ ++ LOADER_CONF_EVENT_TAG_ID = 0xF5BC582A, ++ /* kernel */ ++ LOAD_OPTIONS_EVENT_TAG_ID = 0x8F3B22ED, ++ INITRD_EVENT_TAG_ID = 0x8F3B22EC, + }; + + #define EFI_DEVICE_PATH_MAX 16 diff --git a/pcr-oracle-0.5.4.tar.xz b/pcr-oracle-0.5.4.tar.xz new file mode 100644 index 0000000..4df482d --- /dev/null +++ b/pcr-oracle-0.5.4.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:130085dbd77b8e4001356cbe9411829228eb29cdd6f14931aea5ecb57c75a2e6 +size 81828 diff --git a/pcr-oracle.changes b/pcr-oracle.changes new file mode 100644 index 0000000..b1e05f5 --- /dev/null +++ b/pcr-oracle.changes @@ -0,0 +1,179 @@ +------------------------------------------------------------------- +Mon Aug 5 06:11:52 UTC 2024 - Gary Ching-Pang Lin + +- Add support-ecc-srk.patch to support ECC SRK +- Add fix-testcase-empty-efi-variables.patch to fix the testcase + playback on empty EFI variables + +------------------------------------------------------------------- +Mon Mar 25 20:16:53 UTC 2024 - Alberto Planas Dominguez + +- Add fix_grub_bls_cmdline.patch to include the measurements of the + cmdline and the linux and initrd grub commands + +------------------------------------------------------------------- +Thu Mar 14 10:33:23 UTC 2024 - Alberto Planas Dominguez + +- Add fix_grub_bls_entry.patch to measure boot entries in GRUB BLS + +------------------------------------------------------------------- +Mon Feb 26 15:14:37 UTC 2024 - Alberto Planas Dominguez + +- Remove fix_efi_measure.patch +- Add fix_efi_measure_and_shim.patch (bsc#1219807) + +------------------------------------------------------------------- +Tue Feb 20 18:16:53 UTC 2024 - Alberto Planas Dominguez + +- Add fix_loader_conf.patch to measure the systemd-boot loader.conf file + +------------------------------------------------------------------- +Fri Jan 12 07:28:55 UTC 2024 - Alberto Planas Dominguez + +- Add fix_efi_measure.patch to fix the measurement of EFI binaries + +------------------------------------------------------------------- +Fri Dec 8 07:17:35 UTC 2023 - Gary Ching-Pang Lin + +- Update to 0.5.4 + - Improve systemd-boot support + - Add --boot-entry for systemd-boot + - Manpage fixes + - Fix PCR index in JSON file + - Fix GrubPcrSnapshot parsing +- Drop upstreamed patches: boot_entry.patch and fix_pcr_index.patch + +------------------------------------------------------------------- +Wed Nov 29 15:56:39 UTC 2023 - Alberto Planas Dominguez + +- Update to 0.5.3 + - Improve documentation + - Detect key format store via extension + - Replace --key-format and --policy-format options with a single + --target-platform option + - The json file can contain multiple predictions +- Remove fix_rsa.patch as is already upstream +- Add boot_entry.patch to add new parameter to point to a new systemd + boot entry +- Add fix_pcr_index.patch to fix the PCR index number in the JSON file + +------------------------------------------------------------------- +Mon Nov 20 10:24:32 UTC 2023 - Alberto Planas Dominguez + +- Add fix_rsa.patch to support the export in PEM format of the public + key + +------------------------------------------------------------------- +Mon Nov 20 10:16:20 UTC 2023 - Alberto Planas Dominguez + +- FAPI is not present until tpm2-tss >= 2.4.0. Express that in the + BuildRequirement + +------------------------------------------------------------------- +Wed Nov 15 20:54:57 UTC 2023 - Alberto Planas Dominguez + +- Update to 0.5.2 + - Support EV_EVENT_TAG events from the kernel (PCR9 for the cmdline + and the kernel) + - Fix cmdline measurements +- Update to 0.5.1 + - Measure the kernel as an EFI binary (PCR4) + +------------------------------------------------------------------- +Mon Nov 13 10:53:20 UTC 2023 - Alberto Planas Dominguez + +- Update to 0.5.0 + - Support systemd-cryptenroll JSON files + - Generate RSA keys in more scenarios + - Select RSA key size +- Drop systemd-boot.patch (already present in upstream) + +------------------------------------------------------------------- +Thu Oct 19 11:01:10 UTC 2023 - Alberto Planas Dominguez + +- Add systemd-boot.patch to support systemd-cryptenroll JSON files + +------------------------------------------------------------------- +Wed Jul 26 14:06:43 UTC 2023 - Gary Ching-Pang Lin + +- Add libtss2-tcti-device0 as the default TCTI interface to avoid + the following error: + Esys_Initialize() Initialize default tcti. ErrorCode (0x000a000a) + +------------------------------------------------------------------- +Tue Jul 4 07:44:10 UTC 2023 - Olaf Kirch + +- Added a _service file +- BuildRequire libopenssl-devel rather than openssl +- Updated to version 0.4.6: + - recognize SOURCE_DATE_EPOCH for reproducible builds + - Remove authorized policy file from the unseal action + - Unseal the data without calling __pcr_policy_make() + - Skip the variable event with 0 length (#26) + - Add the new parameter: policy-name (#27) + - Skip the leading operators when matching grub2 commands (#28) + - microconf change: force rebuilding the sed script + +------------------------------------------------------------------- +Mon Jun 5 07:45:13 UTC 2023 - Gary Ching-Pang Lin + +- Update to version 0.4.5 + - update manpage to reflect added support of unseal w/ tpm2.0 key + format + - Implement unseal for TPM 2.0 Key File + - Update manpage to describe the new key-format switch + - Add TPM 2.0 Key File support to 'seal-secret' and 'sign' + - Add comment to SRK template regarding NODA flag. + - pcr-oracle.8: add a section on pcr policy sealing + - Add self-test subcommand to pcr-oracle + - Rename __tss_check_error -> tss_check_error + - Moved two tss related functions to a file of their own + - Add test-pcr.sh script + - Use the same SRK template as the one in grub2 + - Implement seal/unseal using a regular PCR policy + - When displaying the DevicePath, print ACPI PNP ids + - Handle failure to read EFI variables more gracefully + - Gracefully handle AUTHORITY events for eg driver BSAs that + reside in ROM + - efi-variable rehash: break out the code to detect how the + firmware hashed the event + +------------------------------------------------------------------- +Thu Jun 1 07:07:04 UTC 2023 - Marcus Meissner + +- build with optflags, remove unneeded clean section, macro bindir + +------------------------------------------------------------------- +Mon Jan 16 08:52:50 UTC 2023 - Olaf Kirch + +- Updated to version 0.4.2 + +------------------------------------------------------------------- +Thu Jan 5 13:54:40 UTC 2023 - Michal Suchanek + +- Fix project URL + +------------------------------------------------------------------- +Wed Jan 4 11:50:54 UTC 2023 - Olaf Kirch + +- add --rsa-generate-key option + +------------------------------------------------------------------- +Tue Jan 3 15:00:08 UTC 2023 - Olaf Kirch + +- Updated to version 0.4.1: + - disable debug messages from authenticode PECOFF parser + - add --tpm-eventlog option + - add manpage + +------------------------------------------------------------------- +Mon Jan 2 16:36:29 UTC 2023 - Olaf Kirch + +- Updated to version 0.4: + - drop the dependency on tss2 fapi + - introduce authorized policies + +------------------------------------------------------------------- +Tue Nov 8 11:18:07 UTC 2022 - Olaf Kirch + +- Establish pcr-oracle as standalone package, apart from fde-tools diff --git a/pcr-oracle.spec b/pcr-oracle.spec new file mode 100644 index 0000000..8f7bd43 --- /dev/null +++ b/pcr-oracle.spec @@ -0,0 +1,72 @@ +# +# spec file for package pcr-oracle +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# +# needssslcertforbuild + + +Name: pcr-oracle +Version: 0.5.4 +Release: 0 +Summary: Predict TPM PCR values +License: GPL-2.0-only +Group: System/Boot +URL: https://github.com/okirch/pcr-oracle +Source: %{name}-%{version}.tar.xz +# PATCH-FIX-UPSTREAM fix_efi_measure_and_shim.patch gh#okirch/pcr-oracle!47 +# PATCH-FIX-UPSTREAM fix_efi_measure_and_shim.patch gh#okirch/pcr-oracle!51 +Patch0: fix_efi_measure_and_shim.patch +# PATCH-FIX-UPSTREAM fix_loader_conf.patch gh#okirch/pcr-oracle!50 +Patch1: fix_loader_conf.patch +# PATCH-FIX-UPSTREAM fix_grub_bls_entry.patch gh#okirch/pcr-oracle!52 +Patch2: fix_grub_bls_entry.patch +# PATCH-FIX-UPSTREAM fix_grub_bls_cmdline.patch gh#okirch/pcr-oracle!52 (cont) +Patch3: fix_grub_bls_cmdline.patch +# PATCH-FIX-UPSTREAM support-ecc-srk.patch gh#okirch/pcr-oracle!56 +Patch4: support-ecc-srk.patch +# PATCH-FIX-UPSTREAM fix-testcase-empty-efi-variables.patch gh#okirch/pcr-oracle!58 +Patch5: fix-testcase-empty-efi-variables.patch +BuildRequires: libopenssl-devel >= 0.9.8 +BuildRequires: tpm2-0-tss-devel >= 2.4.0 +Requires: libtss2-tcti-device0 +ExclusiveArch: x86_64 aarch64 ppc64le riscv64 + +%description +This utility tries to predict the values of the TPM's Platform +Configuration Registers following an update of system components +like shim, grub, etc. + +%prep +%autosetup -p1 + +%build +# beware, this is not autoconf +./configure --prefix /usr +make CCOPT="%optflags" + +%install +make install DESTDIR=%{buildroot} +install -d %{buildroot}/%{_bindir} +mv %{buildroot}/bin/pcr-oracle %{buildroot}/%{_bindir} +rmdir %{buildroot}/bin + +%files +%defattr(-,root,root) +%doc README.md +%doc test-authorized.sh +%{_bindir}/pcr-oracle +%{_mandir}/man8/pcr-oracle.8* + +%changelog diff --git a/support-ecc-srk.patch b/support-ecc-srk.patch new file mode 100644 index 0000000..d4ba306 --- /dev/null +++ b/support-ecc-srk.patch @@ -0,0 +1,413 @@ +From 60ce42dbf61ce89012d9bc71c92c5cc92759b02c Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Wed, 3 Apr 2024 14:41:49 +0800 +Subject: [PATCH 1/3] Update the comment for SRK template + +USERWITHAUTH and NODA are set according to "TCG TPM v2.0 Provisioning +Guidance". This commit updates the comment to add the reference. + +Signed-off-by: Gary Lin +--- + src/pcr-policy.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/pcr-policy.c b/src/pcr-policy.c +index 8f2c42c..f03b6e0 100644 +--- a/src/pcr-policy.c ++++ b/src/pcr-policy.c +@@ -67,8 +67,9 @@ static TPM2B_PUBLIC SRK_template = { + .publicArea = { + .type = TPM2_ALG_RSA, + .nameAlg = TPM2_ALG_SHA256, +- /* For reasons not clear to me, grub2 derives the SRK using the NODA attribute, +- * which means it is not subject to dictionary attack protections. */ ++ /* Per "Storage Primary Key (SRK) Templates" in section 7.5.1 of ++ * TCG TPM v2.0 Provisioning Guidance 1.0 Revision 1.0, the ++ * template for shared SRKs sets USERWITHAUTH and NODA. */ + .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT \ + |TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT \ + |TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH \ +-- +2.35.3 + + +From 0085c5a6a47f433dc69739c54b9db11796aff62e Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Wed, 10 Apr 2024 16:20:44 +0800 +Subject: [PATCH 2/3] Support SRK template with ECC_NIST_P256 + +When sealing data with SRK, the data is actually encrypted with the +symmetric key, and the selection of the asymmetric algorithm is only +a parameter for KDF to derive the symmetric key. Compared with RSA, +ECC NIST-P256 provides the faster key generation, so it's a better +choice for the SRK template in general. + +This commit adds a new option, '--ecc-srk', to switch the default SRK +template from the RSA one to the ECC one, so that the user can specify +the SRK template when sealing/unsealing data. + +Signed-off-by: Gary Lin +--- + src/oracle.c | 7 +++++++ + src/pcr-policy.c | 44 +++++++++++++++++++++++++++++++++++++++++--- + src/pcr.h | 1 + + 3 files changed, 49 insertions(+), 3 deletions(-) + +diff --git a/src/oracle.c b/src/oracle.c +index 1cafafc..f391430 100644 +--- a/src/oracle.c ++++ b/src/oracle.c +@@ -92,6 +92,7 @@ enum { + OPT_RSA_PUBLIC_KEY, + OPT_RSA_GENERATE_KEY, + OPT_RSA_BITS, ++ OPT_ECC_SRK, + OPT_INPUT, + OPT_OUTPUT, + OPT_AUTHORIZED_POLICY, +@@ -125,6 +126,7 @@ static struct option options[] = { + { "public-key", required_argument, 0, OPT_RSA_PUBLIC_KEY }, + { "rsa-generate-key", no_argument, 0, OPT_RSA_GENERATE_KEY }, + { "rsa-bits", required_argument, 0, OPT_RSA_BITS }, ++ { "ecc-srk", no_argument, 0, OPT_ECC_SRK }, + { "input", required_argument, 0, OPT_INPUT }, + { "output", required_argument, 0, OPT_OUTPUT }, + { "authorized-policy", required_argument, 0, OPT_AUTHORIZED_POLICY }, +@@ -1042,6 +1044,8 @@ main(int argc, char **argv) + unsigned int rsa_bits = 2048; + int c, exit_code = 0; + ++ set_srk_alg("RSA"); ++ + while ((c = getopt_long(argc, argv, "dhA:CF:LSZ", options, NULL)) != EOF) { + switch (c) { + case 'A': +@@ -1109,6 +1113,9 @@ main(int argc, char **argv) + case OPT_RSA_BITS: + opt_rsa_bits = optarg; + break; ++ case OPT_ECC_SRK: ++ set_srk_alg("ECC"); ++ break; + case OPT_INPUT: + opt_input = optarg; + break; +diff --git a/src/pcr-policy.c b/src/pcr-policy.c +index f03b6e0..f65becf 100644 +--- a/src/pcr-policy.c ++++ b/src/pcr-policy.c +@@ -62,7 +62,7 @@ struct target_platform { + const stored_key_t *public_key_file); + }; + +-static TPM2B_PUBLIC SRK_template = { ++static TPM2B_PUBLIC RSA_SRK_template = { + .size = sizeof(TPMT_PUBLIC), + .publicArea = { + .type = TPM2_ALG_RSA, +@@ -88,6 +88,35 @@ static TPM2B_PUBLIC SRK_template = { + } + }; + ++static TPM2B_PUBLIC ECC_SRK_template = { ++ .size = sizeof(TPMT_PUBLIC), ++ .publicArea = { ++ .type = TPM2_ALG_ECC, ++ .nameAlg = TPM2_ALG_SHA256, ++ /* Per "Storage Primary Key (SRK) Templates" in section 7.5.1 of ++ * TCG TPM v2.0 Provisioning Guidance 1.0 Revision 1.0, the ++ * template for shared SRKs sets USERWITHAUTH and NODA. */ ++ .objectAttributes = TPMA_OBJECT_RESTRICTED|TPMA_OBJECT_DECRYPT \ ++ |TPMA_OBJECT_FIXEDTPM|TPMA_OBJECT_FIXEDPARENT \ ++ |TPMA_OBJECT_SENSITIVEDATAORIGIN|TPMA_OBJECT_USERWITHAUTH \ ++ |TPMA_OBJECT_NODA, ++ .parameters = { ++ .eccDetail = { ++ .symmetric = { ++ .algorithm = TPM2_ALG_AES, ++ .keyBits = { .sym = 128 }, ++ .mode = { .sym = TPM2_ALG_CFB }, ++ }, ++ .scheme = { TPM2_ALG_NULL }, ++ .curveID = TPM2_ECC_NIST_P256, ++ .kdf.scheme = TPM2_ALG_NULL ++ } ++ } ++ } ++}; ++ ++static const TPM2B_PUBLIC *SRK_template; ++ + static const TPM2B_PUBLIC seal_public_template = { + .size = sizeof(TPMT_PUBLIC), + .publicArea = { +@@ -107,10 +136,19 @@ static const TPM2B_PUBLIC seal_public_template = { + } + }; + ++void ++set_srk_alg (const char *alg) ++{ ++ if (strcmp(alg, "RSA") == 0) ++ SRK_template = &RSA_SRK_template; ++ else ++ SRK_template = &ECC_SRK_template; ++} ++ + void + set_srk_rsa_bits (const unsigned int rsa_bits) + { +- SRK_template.publicArea.parameters.rsaDetail.keyBits = rsa_bits; ++ RSA_SRK_template.publicArea.parameters.rsaDetail.keyBits = rsa_bits; + } + + static inline const tpm_evdigest_t * +@@ -609,7 +647,7 @@ esys_create_primary(ESYS_CONTEXT *esys_context, ESYS_TR *handle_ret) + t0 = timing_begin(); + rc = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, + ESYS_TR_PASSWORD, +- ESYS_TR_NONE, ESYS_TR_NONE, &in_sensitive, &SRK_template, ++ ESYS_TR_NONE, ESYS_TR_NONE, &in_sensitive, SRK_template, + NULL, &creation_pcr, handle_ret, + NULL, NULL, + NULL, NULL); +diff --git a/src/pcr.h b/src/pcr.h +index 4d8f816..f1dc9af 100644 +--- a/src/pcr.h ++++ b/src/pcr.h +@@ -39,6 +39,7 @@ typedef struct tpm_pcr_selection { + const tpm_algo_info_t * algo_info; + } tpm_pcr_selection_t; + ++extern void set_srk_alg (const char *alg); + extern void set_srk_rsa_bits (const unsigned int rsa_bits); + extern void pcr_bank_initialize(tpm_pcr_bank_t *bank, unsigned int pcr_mask, const tpm_algo_info_t *algo); + extern bool pcr_bank_wants_pcr(tpm_pcr_bank_t *bank, unsigned int index); +-- +2.35.3 + + +From 207bd496868d65455e63aa9586bfc6e02900a4a1 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Wed, 24 Apr 2024 14:53:25 +0800 +Subject: [PATCH 3/3] Update to conform the latest TPM 2.0 Key File + +For TPM 2.0 Key File, the default asymmetric algorithm of SRK is ECC +NIST-P256, not RSA 2048. A new field 'rsaParent' is introduced to note +the key is sealed with RSA SRK. + +This commit implements two new fields: description and rsaParent in +tpm2key.c/tpm2key-asn.h and sets rsaParent when RSA SRK is used to seal +the key. When unsealing a tpm2key, the SRK template is set to the RSA +template if rsaParent is TRUE. Otherwise, the SRK template is switched +to the ECC SRK template. + +A new testing script, test-tpm2key-ecc.sh, is also added to test the +tpm2key file sealed with ECC SRK. + +Signed-off-by: Gary Lin +--- + src/pcr-policy.c | 8 +++ + src/tpm2key-asn.h | 4 ++ + src/tpm2key.c | 2 + + test-tpm2key-ecc.sh | 127 ++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 141 insertions(+) + create mode 100755 test-tpm2key-ecc.sh + +diff --git a/src/pcr-policy.c b/src/pcr-policy.c +index f65becf..90f60ff 100644 +--- a/src/pcr-policy.c ++++ b/src/pcr-policy.c +@@ -1505,6 +1505,11 @@ tpm2key_unseal_secret(const char *input_path, const char *output_path, + if (!tpm2key_read_file(input_path, &tpm2key)) + return false; + ++ if (tpm2key->rsaParent == 1) ++ SRK_template = &RSA_SRK_template; ++ else ++ SRK_template = &ECC_SRK_template; ++ + buffer_init_read(&buf, tpm2key->pubkey->data, tpm2key->pubkey->length); + rc = Tss2_MU_TPM2B_PUBLIC_Unmarshal(buf.data, buf.size, &buf.rpos, &pub); + if (rc != TSS2_RC_SUCCESS) +@@ -1634,6 +1639,9 @@ tpm2key_write_sealed_secret(const char *pathname, + if (!tpm2key_basekey(&tpm2key, TPM2_RH_OWNER, sealed_public, sealed_private)) + goto cleanup; + ++ if (SRK_template->publicArea.type == TPM2_ALG_RSA) ++ tpm2key->rsaParent = 1; ++ + if (pcr_sel && !tpm2key_add_policy_policypcr(tpm2key, pcr_sel)) + goto cleanup; + +diff --git a/src/tpm2key-asn.h b/src/tpm2key-asn.h +index 3f1c0d7..d0cdfaa 100644 +--- a/src/tpm2key-asn.h ++++ b/src/tpm2key-asn.h +@@ -77,6 +77,8 @@ DEFINE_STACK_OF(TSSAUTHPOLICY); + * policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL + * secret [2] EXPLICIT OCTET STRING OPTIONAL + * authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL ++ * description [4] EXPLICIT UTF8String OPTIONAL ++ * rsaParent [5] EXPLICIT BOOLEAN OPTIONAL + * parent INTEGER + * pubkey OCTET STRING + * privkey OCTET STRING +@@ -89,6 +91,8 @@ typedef struct { + STACK_OF(TSSOPTPOLICY) *policy; + ASN1_OCTET_STRING *secret; + STACK_OF(TSSAUTHPOLICY) *authPolicy; ++ ASN1_UTF8STRING description; ++ ASN1_BOOLEAN rsaParent; + ASN1_INTEGER *parent; + ASN1_OCTET_STRING *pubkey; + ASN1_OCTET_STRING *privkey; +diff --git a/src/tpm2key.c b/src/tpm2key.c +index cabd791..af4c984 100644 +--- a/src/tpm2key.c ++++ b/src/tpm2key.c +@@ -278,6 +278,8 @@ ASN1_SEQUENCE(TSSPRIVKEY) = { + ASN1_EXP_SEQUENCE_OF_OPT(TSSPRIVKEY, policy, TSSOPTPOLICY, 1), + ASN1_EXP_OPT(TSSPRIVKEY, secret, ASN1_OCTET_STRING, 2), + ASN1_EXP_SEQUENCE_OF_OPT(TSSPRIVKEY, authPolicy, TSSAUTHPOLICY, 3), ++ ASN1_EXP_OPT(TSSPRIVKEY, description, ASN1_UTF8STRING, 4), ++ ASN1_EXP_OPT(TSSPRIVKEY, rsaParent, ASN1_BOOLEAN, 5), + ASN1_SIMPLE(TSSPRIVKEY, parent, ASN1_INTEGER), + ASN1_SIMPLE(TSSPRIVKEY, pubkey, ASN1_OCTET_STRING), + ASN1_SIMPLE(TSSPRIVKEY, privkey, ASN1_OCTET_STRING) +diff --git a/test-tpm2key-ecc.sh b/test-tpm2key-ecc.sh +new file mode 100755 +index 0000000..d87acff +--- /dev/null ++++ b/test-tpm2key-ecc.sh +@@ -0,0 +1,127 @@ ++#!/bin/bash ++# ++# This script needs to be run with root privilege ++# ++ ++# TESTDIR=policy.test ++PCR_MASK=0,2,4,12 ++ ++pcr_oracle=pcr-oracle ++if [ -x pcr-oracle ]; then ++ pcr_oracle=$PWD/pcr-oracle ++fi ++ ++function call_oracle { ++ ++ echo "****************" ++ echo "pcr-oracle $*" ++ $pcr_oracle --target-platform tpm2.0 -d "$@" ++} ++ ++if [ -z "$TESTDIR" ]; then ++ tmpdir=$(mktemp -d /tmp/pcrtestXXXXXX) ++ trap "cd / && rm -rf $tmpdir" 0 1 2 10 11 15 ++ ++ TESTDIR=$tmpdir ++fi ++ ++trap "echo 'FAIL: command exited with error'; exit 1" ERR ++ ++echo "This is super secret" >$TESTDIR/secret ++ ++set -e ++cd $TESTDIR ++ ++echo "Seal the secret with PCR policy" ++call_oracle \ ++ --from current \ ++ --input secret \ ++ --output sealed \ ++ --ecc-srk \ ++ seal-secret $PCR_MASK ++ ++echo "Unseal the sealed with PCR policy" ++call_oracle \ ++ --input sealed \ ++ --output recovered \ ++ unseal-secret ++ ++if ! cmp secret recovered; then ++ echo "BAD: Unable to recover original secret" ++ echo "Secret:" ++ od -tx1c secret ++ echo "Recovered:" ++ od -tx1c recovered ++ exit 1 ++else ++ echo "NICE: we were able to recover the original secret" ++fi ++ ++rm -f sealed recovered ++ ++call_oracle \ ++ --rsa-generate-key \ ++ --private-key policy-key.pem \ ++ --auth authorized.policy \ ++ create-authorized-policy $PCR_MASK ++ ++call_oracle \ ++ --private-key policy-key.pem \ ++ --public-key policy-pubkey \ ++ store-public-key ++ ++call_oracle \ ++ --auth authorized.policy \ ++ --input secret \ ++ --output sealed \ ++ --ecc-srk \ ++ seal-secret ++ ++for attempt in first second; do ++ echo "Sign the set of PCRs we want to authorize" ++ call_oracle \ ++ --policy-name "authorized-policy-test" \ ++ --private-key policy-key.pem \ ++ --from current \ ++ --input sealed \ ++ --output sealed-signed \ ++ sign $PCR_MASK ++ ++ echo "$attempt attempt to unseal the secret" ++ call_oracle \ ++ --input sealed-signed \ ++ --output recovered \ ++ unseal-secret ++ ++ if ! cmp secret recovered; then ++ echo "BAD: Unable to recover original secret" ++ echo "Secret:" ++ od -tx1c secret ++ echo "Recovered:" ++ od -tx1c recovered ++ exit 1 ++ else ++ echo "NICE: we were able to recover the original secret" ++ fi ++ ++ if [ "$attempt" = "second" ]; then ++ break ++ fi ++ ++ echo "Extend PCR 12. Unsealing should fail afterwards" ++ tpm2_pcrextend 12:sha256=21d2013e3081f1e455fdd5ba6230a8620c3cfc9a9c31981d857fe3891f79449e ++ rm -f recovered ++ call_oracle \ ++ --input sealed-signed \ ++ --output recovered \ ++ unseal-secret || true ++ ++ if [ -s recovered ] && ! cmp secret recovered; then ++ echo "BAD: We were still able to recover the original secret. Something stinks" ++ exit 1 ++ else ++ echo "GOOD: After changing a PCR, the secret can no longer be unsealed" ++ fi ++ ++ echo "Now recreate the signed PCR policy" ++done +-- +2.35.3 +