diff --git a/_service b/_service
index 6dac258..839a19f 100644
--- a/_service
+++ b/_service
@@ -7,7 +7,7 @@
https://github.com/okirch/pcr-oracle.git
pcr-oracle
@PARENT_TAG@
- refs/tags/0.5.3
+ refs/tags/0.5.4
pcr-oracle*.tar
diff --git a/boot_entry.patch b/boot_entry.patch
deleted file mode 100644
index f7430a1..0000000
--- a/boot_entry.patch
+++ /dev/null
@@ -1,2093 +0,0 @@
-From 0be3db467f042cc030f9a4a840854ce36a0f8317 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Mon, 27 Nov 2023 16:48:28 +0100
-Subject: [PATCH 01/13] Remove obsolete pcr_policy_sign_systemd()
-
-Signed-off-by: Olaf Kirch
----
- src/pcr-policy.c | 51 ------------------------------------------------
- src/pcr.h | 3 ---
- 2 files changed, 54 deletions(-)
-
-diff --git a/src/pcr-policy.c b/src/pcr-policy.c
-index 95a4299..8f2c42c 100644
---- a/src/pcr-policy.c
-+++ b/src/pcr-policy.c
-@@ -1539,57 +1539,6 @@ pcr_unseal_secret(const target_platform_t *platform,
- return platform->unseal_secret(input_path, output_path, pcr_selection, signed_policy_path, public_key_file);
- }
-
--bool
--pcr_policy_sign_systemd(const tpm_pcr_bank_t *bank,
-- const stored_key_t *private_key_file,
-- const char *output_path)
--{
-- bool ok = false;
-- FILE *fp = NULL;
-- tpm_rsa_key_t *rsa_key = NULL;
-- const tpm_evdigest_t *digest;
-- ESYS_CONTEXT *esys_context = tss_esys_context();
-- TPM2B_DIGEST *pcr_policy = NULL;
-- TPMT_SIGNATURE *signed_policy = NULL;
--
-- if (!(fp = fopen(output_path, "w"))) {
-- error("Cannot open systemd JSON file %s: %m\n", output_path);
-- goto out;
-- }
--
-- if (!(rsa_key = stored_key_read_rsa_private(private_key_file)))
-- goto out;
-- digest = tpm_rsa_key_public_digest(rsa_key);
--
-- if (!(pcr_policy = __pcr_policy_make(esys_context, bank)))
-- goto out;
--
-- if (!__pcr_policy_sign(rsa_key, pcr_policy, &signed_policy))
-- goto out;
--
-- fprintf(fp, "{\n");
-- fprintf(fp, "\t\"%s\": [\n", bank->algo_name);
-- fprintf(fp, "\t\t\{\n");
-- fprintf(fp, "\t\t\t\"pcrs\": [\n");
-- fprintf(fp, "\t\t\t\t%s\n", print_pcr_mask(bank->pcr_mask));
-- fprintf(fp, "\t\t\t],\n");
-- fprintf(fp, "\t\t\t\"pkfp\": \"%s\",\n", print_hex_string(digest->data, digest->size));
-- fprintf(fp, "\t\t\t\"pol\": \"%s\",\n", print_hex_string(pcr_policy->buffer, pcr_policy->size));
-- fprintf(fp, "\t\t\t\"sig\": \"%s\"\n", print_base64_value(signed_policy->signature.rsassa.sig.buffer, signed_policy->signature.rsassa.sig.size));
-- fprintf(fp, "\t\t}\n");
-- fprintf(fp, "\t]\n");
-- fprintf(fp, "}\n");
--
-- ok = true;
--
--out:
-- if (rsa_key)
-- tpm_rsa_key_free(rsa_key);
--
-- fclose(fp);
-- return ok;
--}
--
- /*
- * Depending on the target platform, sealed data, authorized policies etc are
- * written to different types of files.
-diff --git a/src/pcr.h b/src/pcr.h
-index 1b0f544..4d8f816 100644
---- a/src/pcr.h
-+++ b/src/pcr.h
-@@ -65,9 +65,6 @@ extern bool pcr_policy_sign(const target_platform_t *platform, const tpm_pcr_ba
- const stored_key_t *private_key_file,
- const char *input_path,
- const char *output_path, const char *policy_name);
--extern bool pcr_policy_sign_systemd(const tpm_pcr_bank_t *bank,
-- const stored_key_t *private_key_file,
-- const char *output_path);
- extern bool pcr_authorized_policy_seal_secret(const target_platform_t *platform,
- const char *authorized_policy, const char *input_path,
- const char *output_path);
-
-From 3a66b6e1dc953ac95a715a4b1123e772024fba2c Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Mon, 27 Nov 2023 17:18:14 +0100
-Subject: [PATCH 02/13] Introduce read_single_line_file() and use it in
- sd-boot.c
-
-Signed-off-by: Olaf Kirch
----
- src/sd-boot.c | 30 ++----------------------------
- src/util.c | 19 +++++++++++++++++++
- src/util.h | 1 +
- 3 files changed, 22 insertions(+), 28 deletions(-)
-
-diff --git a/src/sd-boot.c b/src/sd-boot.c
-index 3eea1a1..bbdb498 100644
---- a/src/sd-boot.c
-+++ b/src/sd-boot.c
-@@ -37,21 +37,8 @@ static const char *
- read_entry_token(void)
- {
- static char id[SDB_LINE_MAX];
-- FILE *fp;
--
-- if (!(fp = fopen("/etc/kernel/entry-token", "r"))) {
-- debug("Cannot open /etc/kernel/entry-token\n");
-- goto fail;
-- }
--
-- if (fgets(id, SDB_LINE_MAX, fp))
-- id[strcspn(id, "\n")] = 0;
-
-- fclose(fp);
-- return id;
--
--fail:
-- return NULL;
-+ return read_single_line_file("/etc/kernel/entry-token", id, sizeof(id));
- }
-
- static const char *
-@@ -109,21 +96,8 @@ static const char *
- read_machine_id(void)
- {
- static char id[SDB_LINE_MAX];
-- FILE *fp;
--
-- if (!(fp = fopen("/etc/machine-id", "r"))) {
-- error("Cannot open /etc/machine_id: %m\n");
-- goto fail;
-- }
--
-- if (fgets(id, SDB_LINE_MAX, fp))
-- id[strcspn(id, "\n")] = 0;
-
-- fclose(fp);
-- return id;
--
--fail:
-- return NULL;
-+ return read_single_line_file("/etc/machine-id", id, sizeof(id));
- }
-
- static bool
-diff --git a/src/util.c b/src/util.c
-index 1f2640f..644d138 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -514,3 +514,22 @@ path_has_file_extension(const char *path, const char *suffix)
-
- return !strcasecmp(path + n, suffix);
- }
-+
-+const char *
-+read_single_line_file(const char *path, char *buffer, size_t size)
-+{
-+ FILE *fp;
-+
-+ if (!(fp = fopen(path, "r"))) {
-+ debug("Cannot open %s: %m\n", path);
-+ return NULL;
-+ }
-+
-+ if (fgets(buffer, size, fp) != NULL)
-+ buffer[strcspn(buffer, "\n")] = 0;
-+ else
-+ buffer[0] = '\0';
-+
-+ fclose(fp);
-+ return buffer;
-+}
-diff --git a/src/util.h b/src/util.h
-index c98017f..e63ef16 100644
---- a/src/util.h
-+++ b/src/util.h
-@@ -142,6 +142,7 @@ extern double timing_since(double);
- extern const char * path_unix2dos(const char *path);
- extern const char * path_dos2unix(const char *path);
- extern bool path_has_file_extension(const char *path, const char *suffix);
-+extern const char * read_single_line_file(const char *path, char *buffer, size_t size);
-
- extern int version_string_compare(const char *, const char *);
-
-
-From 32680d9efa0b866bd78d7ad5bd362aca511efc05 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Mon, 27 Nov 2023 18:26:36 +0100
-Subject: [PATCH 03/13] tpm_event_get_digest: changed second argument from
- algo_name to an algo_info pointer
-
-Signed-off-by: Olaf Kirch
----
- src/efi-application.c | 2 +-
- src/efi-variable.c | 6 +++---
- src/eventlog.c | 6 +-----
- src/eventlog.h | 2 +-
- src/oracle.c | 2 +-
- 5 files changed, 7 insertions(+), 11 deletions(-)
-
-diff --git a/src/efi-application.c b/src/efi-application.c
-index 14a2450..06ac9ff 100644
---- a/src/efi-application.c
-+++ b/src/efi-application.c
-@@ -287,7 +287,7 @@ __tpm_event_efi_bsa_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *pars
- */
- if (!evspec->efi_application) {
- debug("Unable to locate boot service application - probably not a file\n");
-- return tpm_event_get_digest(ev, ctx->algo->openssl_name);
-+ return tpm_event_get_digest(ev, ctx->algo);
- }
-
- /* The next boot can have a different kernel */
-diff --git a/src/efi-variable.c b/src/efi-variable.c
-index 7e9e38b..6c08cde 100644
---- a/src/efi-variable.c
-+++ b/src/efi-variable.c
-@@ -141,7 +141,7 @@ __tpm_event_efi_variable_detect_hash_strategy(const tpm_event_t *ev, const tpm_p
- {
- const tpm_evdigest_t *md, *old_md;
-
-- old_md = tpm_event_get_digest(ev, algo->openssl_name);
-+ old_md = tpm_event_get_digest(ev, algo);
- if (old_md == NULL) {
- debug("Event does not provide a digest for algorithm %s\n", algo->openssl_name);
- return -1;
-@@ -199,7 +199,7 @@ __tpm_event_efi_variable_rehash(const tpm_event_t *ev, const tpm_parsed_event_t
- * For the time being, just pretend these cannot be changed from
- * within the running system.
- */
-- md = tpm_event_get_digest(ev, algo->openssl_name);
-+ md = tpm_event_get_digest(ev, algo);
- goto out;
- }
- } else {
-@@ -214,7 +214,7 @@ __tpm_event_efi_variable_rehash(const tpm_event_t *ev, const tpm_parsed_event_t
- /* The content of the variable doesn't exist during the measurement
- * and is also not available at runtime. Let's skip this event.
- */
-- md = tpm_event_get_digest(ev, algo->openssl_name);
-+ md = tpm_event_get_digest(ev, algo);
- }
- goto out;
- }
-diff --git a/src/eventlog.c b/src/eventlog.c
-index e99a20f..32cc75c 100644
---- a/src/eventlog.c
-+++ b/src/eventlog.c
-@@ -406,14 +406,10 @@ tpm_event_type_to_string(unsigned int event_type)
- }
-
- const tpm_evdigest_t *
--tpm_event_get_digest(const tpm_event_t *ev, const char *algo_name)
-+tpm_event_get_digest(const tpm_event_t *ev, const tpm_algo_info_t *algo_info)
- {
-- const tpm_algo_info_t *algo_info;
- unsigned int i;
-
-- if ((algo_info = digest_by_name(algo_name)) < 0)
-- fatal("Unknown algo name \"%s\"\n", algo_name);
--
- for (i = 0; i < ev->pcr_count; ++i) {
- const tpm_evdigest_t *md = &ev->pcr_values[i];
-
-diff --git a/src/eventlog.h b/src/eventlog.h
-index 8951765..bd1106f 100644
---- a/src/eventlog.h
-+++ b/src/eventlog.h
-@@ -291,7 +291,7 @@ extern void tpm_event_log_scan_ctx_init(tpm_event_log_scan_ctx_t *);
- extern void tpm_event_log_scan_ctx_destroy(tpm_event_log_scan_ctx_t *);
- extern tpm_parsed_event_t * tpm_event_parse(tpm_event_t *ev, tpm_event_log_scan_ctx_t *);
- extern const char * tpm_event_type_to_string(unsigned int event_type);
--extern const tpm_evdigest_t * tpm_event_get_digest(const tpm_event_t *ev, const char *algo_name);
-+extern const tpm_evdigest_t * tpm_event_get_digest(const tpm_event_t *ev, const tpm_algo_info_t *algo_info);
- extern void tpm_parsed_event_print(tpm_parsed_event_t *parsed,
- tpm_event_bit_printer *);
- extern const char * tpm_parsed_event_describe(tpm_parsed_event_t *parsed);
-diff --git a/src/oracle.c b/src/oracle.c
-index 52fe261..c4e4873 100644
---- a/src/oracle.c
-+++ b/src/oracle.c
-@@ -670,7 +670,7 @@ predictor_update_eventlog(struct predictor *pred)
- debug("\n");
- __tpm_event_print(ev, debug);
-
-- if (!(old_digest = tpm_event_get_digest(ev, pred->algo)))
-+ if (!(old_digest = tpm_event_get_digest(ev, pred->algo_info)))
- fatal("Event log lacks a hash for digest algorithm %s\n", pred->algo);
-
- if (false) {
-
-From 4d88450e9da882c759a68ba8c15267b22a377cdc Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Mon, 27 Nov 2023 18:31:42 +0100
-Subject: [PATCH 04/13] Add uapi_ types and functions for dealing with UAPI
- boot entries
-
-Signed-off-by: Olaf Kirch
----
- Makefile.in | 3 +-
- src/types.h | 1 +
- src/uapi.c | 323 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- src/uapi.h | 43 +++++++
- 4 files changed, 369 insertions(+), 1 deletion(-)
- create mode 100644 src/uapi.c
- create mode 100644 src/uapi.h
-
-diff --git a/Makefile.in b/Makefile.in
-index a0508e9..02a915b 100644
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -33,7 +33,8 @@ ORACLE_SRCS = oracle.c \
- bufparser.c \
- store.c \
- util.c \
-- sd-boot.c
-+ sd-boot.c \
-+ uapi.c
- ORACLE_OBJS = $(addprefix build/,$(patsubst %.c,%.o,$(ORACLE_SRCS)))
-
- all: $(TOOLS) $(MANPAGES)
-diff --git a/src/types.h b/src/types.h
-index e76903a..5b01079 100644
---- a/src/types.h
-+++ b/src/types.h
-@@ -35,6 +35,7 @@ typedef struct pecoff_image_info pecoff_image_info_t;
- typedef struct testcase testcase_t;
- typedef struct stored_key stored_key_t;
- typedef struct target_platform target_platform_t;
-+typedef struct uapi_boot_entry uapi_boot_entry_t;
-
- #endif /* TYPES_H */
-
-diff --git a/src/uapi.c b/src/uapi.c
-new file mode 100644
-index 0000000..bbcaea9
---- /dev/null
-+++ b/src/uapi.c
-@@ -0,0 +1,323 @@
-+/*
-+ * Copyright (C) 2022, 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 , Olaf Kirch
-+ */
-+
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#include "uapi.h"
-+#include "util.h"
-+
-+#define UAPI_LINE_MAX 1024
-+
-+
-+static int vercmp(const void *va, const void *vb);
-+
-+static uapi_boot_entry_t *
-+uapi_boot_entry_new(void)
-+{
-+ uapi_boot_entry_t *ube;
-+
-+ ube = calloc(1, sizeof(*ube));
-+ return ube;
-+}
-+
-+static void
-+drop_boot_entry(uapi_boot_entry_t **entry_p)
-+{
-+ if (*entry_p) {
-+ uapi_boot_entry_free(*entry_p);
-+ *entry_p = NULL;
-+ }
-+}
-+
-+static uapi_boot_entry_t *
-+uapi_boot_entry_load(const char *path)
-+{
-+ uapi_boot_entry_t *result = NULL;
-+ char line[UAPI_LINE_MAX];
-+ FILE *fp;
-+
-+ if (!(fp = fopen(path, "r"))) {
-+ error("Unable to open %s: %m\n", path);
-+ return NULL;
-+ }
-+
-+ result = uapi_boot_entry_new();
-+ while (fgets(line, sizeof(line), fp)) {
-+ char *key, *value;
-+ unsigned int i;
-+
-+ if (!isalpha(line[0]))
-+ continue;
-+
-+ /* strip white space off the end */
-+ i = strlen(line);
-+ while (i > 0 && isspace(line[i-1]))
-+ line[--i] = '\0';
-+
-+ key = line;
-+ for (i = 0; line[i]; ++i) {
-+ if (isspace(line[i])) {
-+ line[i++] = '\0';
-+ break;
-+ }
-+ }
-+
-+ while (isspace(line[i]))
-+ ++i;
-+ value = line + i;
-+ if (*value == '\0')
-+ value = NULL;
-+
-+ if (!strcmp("sort-key", key))
-+ assign_string(&result->sort_key, value);
-+ else
-+ if (!strcmp("machine-id", key))
-+ assign_string(&result->machine_id, value);
-+ else
-+ if (!strcmp("version", key))
-+ assign_string(&result->version, value);
-+ else
-+ if (!strcmp("options", key))
-+ assign_string(&result->options, value);
-+ else
-+ if (!strcmp("linux", key))
-+ assign_string(&result->image_path, value);
-+ else
-+ if (!strcmp("initrd", key))
-+ assign_string(&result->initrd_path, value);
-+ }
-+
-+ fclose(fp);
-+ return result;
-+}
-+
-+static bool
-+uapi_boot_entry_applies(const uapi_boot_entry_t *entry, const char *machine_id, const char *architecture)
-+{
-+ if (entry->machine_id && machine_id && strcmp(entry->machine_id, machine_id))
-+ return false;
-+ if (entry->architecture && architecture && strcmp(entry->architecture, architecture))
-+ return false;
-+ /* We don't check the efi key because it can only express "entry is EFI only"; it cannot express
-+ * "this is a legacy BIOS entry" */
-+ return true;
-+}
-+
-+/*
-+ * Returns true iff entry_a is "more recent" or "better" than entry_b
-+ */
-+static bool
-+uapi_boot_entry_more_recent(const uapi_boot_entry_t *entry_a, const uapi_boot_entry_t *entry_b)
-+{
-+ int r = 0;
-+
-+ /* having a sort key is better than not having one. */
-+ r = strcmp(entry_a->sort_key? : "", entry_b->sort_key? : "");
-+
-+ if (r == 0)
-+ r = vercmp(entry_a->version? : "", entry_b->version? : "");
-+
-+ return r > 0;
-+}
-+
-+/*
-+ * We pass in a best_ret pointer in case we need to extend this
-+ * to search more than on directory
-+ */
-+uapi_boot_entry_t *
-+uapi_find_matching_boot_entry(const char *dir_path,
-+ const char *entry_id, const char *machine_id, const char *architecture,
-+ uapi_boot_entry_t **best_ret)
-+{
-+ uapi_boot_entry_t *best = *best_ret;
-+ unsigned int entry_id_len = 0;
-+ struct dirent *d;
-+ DIR *dir;
-+
-+ if (!(dir = opendir(dir_path))) {
-+ if (errno != ENOENT)
-+ error("Cannot open %s for reading: %m\n", dir_path);
-+ return NULL;
-+ }
-+
-+ if (entry_id)
-+ entry_id_len = strlen(entry_id);
-+
-+ while ((d = readdir(dir)) != NULL) {
-+ char config_path[PATH_MAX];
-+ uapi_boot_entry_t *entry;
-+
-+ if (d->d_type != DT_REG)
-+ continue;
-+
-+ if (entry_id && strncmp(d->d_name, entry_id, entry_id_len))
-+ continue;
-+
-+ snprintf(config_path, sizeof(config_path), "%s/%s", dir_path, d->d_name);
-+ if (!(entry = uapi_boot_entry_load(config_path))) {
-+ warning("Unable to process UAPI boot entry file at \"%s\"\n", config_path);
-+ continue;
-+ }
-+
-+ if (uapi_boot_entry_applies(entry, machine_id, architecture)) {
-+ if (best == NULL || uapi_boot_entry_more_recent(entry, best)) {
-+ /* swap best and entry */
-+ uapi_boot_entry_t *tmp = best;
-+ best = entry;
-+ entry = tmp;
-+ }
-+ }
-+
-+ drop_boot_entry(&entry);
-+ }
-+
-+ closedir(dir);
-+
-+ *best_ret = best;
-+ return best;
-+}
-+
-+uapi_boot_entry_t *
-+uapi_find_boot_entry(const char *id, const char *machine_id)
-+{
-+ uapi_boot_entry_t *best = NULL;
-+ struct utsname uts;
-+ const char *architecture;
-+
-+ if (uname(&uts) >= 0)
-+ architecture = uts.machine;
-+
-+ return uapi_find_matching_boot_entry(UAPI_BOOT_DIRECTORY,
-+ id, machine_id, architecture,
-+ &best);
-+}
-+
-+void
-+uapi_boot_entry_free(uapi_boot_entry_t *ube)
-+{
-+ drop_string(&ube->title);
-+ drop_string(&ube->version);
-+ drop_string(&ube->machine_id);
-+ drop_string(&ube->image_path);
-+ drop_string(&ube->initrd_path);
-+ drop_string(&ube->options);
-+ free(ube);
-+}
-+
-+/*
-+ * Version comparison
-+ */
-+static int
-+cmp(int a, int b)
-+{
-+ return a - b;
-+}
-+
-+static bool
-+isvalid(char a)
-+{
-+ return isalnum(a) || a == '~' || a == '-' || a == '^' || a == '.';
-+}
-+
-+static int
-+natoi(const char *a, unsigned int n)
-+{
-+ char line[UAPI_LINE_MAX];
-+
-+ strncpy(line, a, MIN(UAPI_LINE_MAX, n));
-+ return atoi(line);
-+}
-+
-+static int
-+vercmp(const void *va, const void *vb)
-+{
-+ /* https://uapi-group.org/specifications/specs/version_format_specification/ */
-+ /* This code is based on strverscmp_improved from systemd */
-+
-+ const char *a = va;
-+ const char *b = vb;
-+ const char *sep = "~-^.";
-+
-+ assert(a != NULL);
-+ assert(b != NULL);
-+
-+ for(;;) {
-+ const char *aa, *bb;
-+ int r;
-+
-+ while (*a != '\0' && !isvalid(*a))
-+ a++;
-+ while (*b != '\0' && !isvalid(*b))
-+ b++;
-+
-+ /* The longer string is considered new */
-+ if (*a == '\0' || *b == '\0')
-+ return cmp(*a, *b);
-+
-+ for (int i = 0; i < strlen(sep); i++) {
-+ char s = sep[i];
-+
-+ if (*a == s || *b == s) {
-+ r = cmp(*a != s, *b != s);
-+ if (r != 0)
-+ return r;
-+
-+ a++;
-+ b++;
-+ }
-+ }
-+
-+ if (isdigit(*a) || isdigit(*b)) {
-+ for (aa = a; isdigit(*aa); aa++);
-+ for (bb = b; isdigit(*bb); bb++);
-+
-+ r = cmp(a != aa, b != bb);
-+ if (r != 0)
-+ return r;
-+
-+ r = cmp(natoi(a, aa - a), natoi(b, bb - b));
-+ if (r != 0)
-+ return r;
-+ } else {
-+ for (aa = a; isalpha(*aa); aa++);
-+ for (bb = b; isalpha(*bb); bb++);
-+
-+ r = cmp(strncmp(a, b, MIN(aa - a, bb - b)), 0);
-+ if (r != 0)
-+ return r;
-+
-+ r = cmp(aa - a, bb - b);
-+ if (r != 0)
-+ return r;
-+ }
-+
-+ a = aa;
-+ b = bb;
-+ }
-+}
-+
-diff --git a/src/uapi.h b/src/uapi.h
-new file mode 100644
-index 0000000..ba1147e
---- /dev/null
-+++ b/src/uapi.h
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright (C) 2022, 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 Olaf Kirch
-+ */
-+
-+#ifndef UAPI_H
-+#define UAPI_H
-+
-+#include "types.h"
-+
-+struct uapi_boot_entry {
-+ char * title;
-+ bool efi;
-+ char * sort_key;
-+ char * version;
-+ char * machine_id;
-+ char * architecture;
-+ char * image_path;
-+ char * initrd_path;
-+ char * options;
-+};
-+
-+#define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries"
-+
-+extern uapi_boot_entry_t * uapi_find_boot_entry(const char *id, const char *machine_id);
-+extern void uapi_boot_entry_free(uapi_boot_entry_t *);
-+
-+#endif /* UAPI_H */
-
-From a7a4c854c9668900c8eb9ea9c99d51b6e822f376 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Mon, 27 Nov 2023 18:33:38 +0100
-Subject: [PATCH 05/13] Add --next-kernel command line option; use uapi to
- locate next kernel when given
-
-Signed-off-by: Olaf Kirch
----
- man/pcr-oracle.8.in | 12 ++++++++++++
- src/eventlog.h | 3 +++
- src/oracle.c | 23 +++++++++++++++++++++--
- src/sd-boot.c | 19 +++++++++++++++++++
- src/sd-boot.h | 3 +++
- 5 files changed, 58 insertions(+), 2 deletions(-)
-
-diff --git a/man/pcr-oracle.8.in b/man/pcr-oracle.8.in
-index eda3cfb..4bd60ba 100644
---- a/man/pcr-oracle.8.in
-+++ b/man/pcr-oracle.8.in
-@@ -495,6 +495,18 @@ events (tracked in PCR9). In this case, it would be totally sufficient
- to stop processing after grub loaded \fPgrub.cfg\fP from the EFI
- System Partition.
- .TP
-+.BI --next-kernel " id
-+In a systemd-boot environment, the values of PCR registers also depend on
-+the contents of the kernel and initrd image, as well as the kernel command line
-+options. After a kernel update or an initrd rebuild, these values will change.
-+So when predicting PCR values in this case, \fBpcr-oracle\fP needs to be
-+instructed to refer to the future kernel rather than the current one.
-+.IP
-+This is what the \fB--next-kernel\fP option is for. It takes one argument, which
-+is either an ID (in the sense of systemd-boot IDs), or \fBauto\fP. When
-+the latter is given, \fBpcr-oracle\fP will make a best guess as to what
-+kernel image will be used on next boot.
-+.TP
- .BI --authorized-policy " path
- Specify the location of the authorized policy. In conjunction with
- the \fBcreate-authorized-policy\fP action, the newly created policy
-diff --git a/src/eventlog.h b/src/eventlog.h
-index bd1106f..65e5322 100644
---- a/src/eventlog.h
-+++ b/src/eventlog.h
-@@ -200,6 +200,9 @@ typedef struct tpm_event_log_rehash_ctx {
- bool use_pesign; /* compute authenticode FP using external pesign application */
-
- const pecoff_image_info_t *next_stage_img;
-+
-+ /* This get set when the user specifies --next-kernel */
-+ uapi_boot_entry_t * next_kernel;
- } tpm_event_log_rehash_ctx_t;
-
- #define GRUB_COMMAND_ARGV_MAX 32
-diff --git a/src/oracle.c b/src/oracle.c
-index c4e4873..2cc53c1 100644
---- a/src/oracle.c
-+++ b/src/oracle.c
-@@ -34,6 +34,7 @@
- #include "rsa.h"
- #include "store.h"
- #include "testcase.h"
-+#include "sd-boot.h"
-
- enum {
- ACTION_NONE,
-@@ -58,6 +59,7 @@ struct predictor {
- const char * initial_source;
-
- const char * tpm_event_log_path;
-+ const char * next_kernel_id;
-
- const char * algo;
- const tpm_algo_info_t * algo_info;
-@@ -98,6 +100,7 @@ enum {
- OPT_POLICY_NAME,
- OPT_POLICY_FORMAT,
- OPT_TARGET_PLATFORM,
-+ OPT_NEXT_KERNEL,
- };
-
- static struct option options[] = {
-@@ -114,6 +117,7 @@ static struct option options[] = {
- { "before", no_argument, 0, OPT_BEFORE },
- { "verify", required_argument, 0, OPT_VERIFY },
- { "use-pesign", no_argument, 0, OPT_USE_PESIGN },
-+ { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL },
- { "create-testcase", required_argument, 0, OPT_CREATE_TESTCASE },
- { "replay-testcase", required_argument, 0, OPT_REPLAY_TESTCASE },
-
-@@ -129,6 +133,7 @@ static struct option options[] = {
- { "policy-name", required_argument, 0, OPT_POLICY_NAME },
- { "policy-format", required_argument, 0, OPT_POLICY_FORMAT },
- { "target-platform", required_argument, 0, OPT_TARGET_PLATFORM },
-+ { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL },
-
- { NULL }
- };
-@@ -250,7 +255,8 @@ predictor_load_eventlog(struct predictor *pred)
- static struct predictor *
- predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source,
- const char *tpm_eventlog_path,
-- const char *output_format)
-+ const char *output_format,
-+ const char *next_kernel_id)
- {
- struct predictor *pred;
-
-@@ -260,6 +266,7 @@ predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source,
- pred = calloc(1, sizeof(*pred));
- pred->pcr_mask = pcr_selection->pcr_mask;
- pred->initial_source = source;
-+ pred->next_kernel_id = next_kernel_id;
-
- pred->algo = pcr_selection->algo_info->openssl_name;
- pred->algo_info = pcr_selection->algo_info;
-@@ -651,6 +658,14 @@ predictor_update_eventlog(struct predictor *pred)
- tpm_event_log_rehash_ctx_init(&rehash_ctx, pred->algo_info);
- rehash_ctx.use_pesign = opt_use_pesign;
-
-+ /* The argument given to --next-kernel will be either "auto" or the
-+ * systemd ID of the next kernel entry to be booted.
-+ * FIXME: we should probably hide this behind a target_platform function.
-+ */
-+ if (pred->next_kernel_id != NULL
-+ && !(rehash_ctx.next_kernel = sdb_identify_next_kernel(pred->next_kernel_id)))
-+ fatal("unable to identify next kernel \"%s\"\n", pred->next_kernel_id);
-+
- for (ev = pred->event_log; ev; ev = ev->next) {
- tpm_evdigest_t *pcr;
- bool stop = false;
-@@ -1021,6 +1036,7 @@ main(int argc, char **argv)
- char *opt_rsa_bits = NULL;
- char *opt_policy_name = NULL;
- char *opt_target_platform = NULL;
-+ char *opt_next_kernel = NULL;
- const target_platform_t *target;
- unsigned int action_flags = 0;
- unsigned int rsa_bits = 2048;
-@@ -1055,6 +1071,9 @@ main(int argc, char **argv)
- case OPT_USE_PESIGN:
- opt_use_pesign = 1;
- break;
-+ case OPT_NEXT_KERNEL:
-+ opt_next_kernel = optarg;
-+ break;
- case OPT_STOP_EVENT:
- opt_stop_event = optarg;
- break;
-@@ -1296,7 +1315,7 @@ main(int argc, char **argv)
- fatal("BUG: action %u should have parsed a PCR selection argument", action);
-
- pred = predictor_new(pcr_selection, opt_from, opt_eventlog_path,
-- opt_output_format);
-+ opt_output_format, opt_next_kernel);
-
- if (opt_stop_event)
- predictor_set_stop_event(pred, opt_stop_event, !opt_stop_before);
-diff --git a/src/sd-boot.c b/src/sd-boot.c
-index bbdb498..2e7ec61 100644
---- a/src/sd-boot.c
-+++ b/src/sd-boot.c
-@@ -387,6 +387,25 @@ sdb_get_next_kernel(void)
- return NULL;
- }
-
-+/*
-+ * Identify the next kernel and initrd given an ID
-+ */
-+uapi_boot_entry_t *
-+sdb_identify_next_kernel(const char *id)
-+{
-+ const char *machine_id;
-+
-+ if (id == NULL || !strcasecmp(id, "default")) {
-+ if (!(id = get_token_id()))
-+ return NULL;
-+ }
-+
-+ if (!(machine_id = read_machine_id()))
-+ return NULL;
-+
-+ return uapi_find_boot_entry(id, machine_id);
-+}
-+
- /*
- * Update the systemd json file
- */
-diff --git a/src/sd-boot.h b/src/sd-boot.h
-index ef36ce7..fa56751 100644
---- a/src/sd-boot.h
-+++ b/src/sd-boot.h
-@@ -21,6 +21,8 @@
- #define SD_BOOT_H
-
- #include
-+#include "uapi.h"
-+#include "types.h"
-
- #define SDB_MAX_ENTRIES 16
- #define SDB_LINE_MAX 512
-@@ -40,6 +42,7 @@ typedef struct sdb_entry_list {
- sdb_entry_data_t entries[SDB_MAX_ENTRIES];
- } sdb_entry_list_t;
-
-+extern uapi_boot_entry_t * sdb_identify_next_kernel(const char *id);
- extern bool sdb_get_entry_list(sdb_entry_list_t *result);
- extern bool sdb_is_kernel(const char *application);
- extern const char * sdb_get_next_kernel(void);
-
-From dcfc751ac78400d5bca53b560768f6a3603443f7 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Mon, 27 Nov 2023 18:41:26 +0100
-Subject: [PATCH 06/13] Adjust EFI BSA and systemd event rehashing to use
- rehash_ctx->next_kernel
-
-Signed-off-by: Olaf Kirch
----
- src/efi-application.c | 4 ++--
- src/eventlog.c | 38 +++++++++++++++++++++-----------------
- 2 files changed, 23 insertions(+), 19 deletions(-)
-
-diff --git a/src/efi-application.c b/src/efi-application.c
-index 06ac9ff..9d7e531 100644
---- a/src/efi-application.c
-+++ b/src/efi-application.c
-@@ -291,8 +291,8 @@ __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)) {
-- new_application = sdb_get_next_kernel();
-+ if (sdb_is_kernel(evspec->efi_application) && ctx->next_kernel) {
-+ new_application = ctx->next_kernel->image_path;
- if (new_application) {
- evspec_clone = *evspec;
- evspec_clone.efi_application = strdup(new_application);
-diff --git a/src/eventlog.c b/src/eventlog.c
-index 32cc75c..3498790 100644
---- a/src/eventlog.c
-+++ b/src/eventlog.c
-@@ -32,7 +32,7 @@
- #include "runtime.h"
- #include "digest.h"
- #include "util.h"
--#include "sd-boot.h"
-+#include "uapi.h"
-
- #define TPM_EVENT_LOG_MAX_ALGOS 64
-
-@@ -789,21 +789,24 @@ __tpm_event_systemd_describe(const tpm_parsed_event_t *parsed)
- 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)
- {
-- sdb_entry_list_t entry_list;
-+ const uapi_boot_entry_t *next_kernel = ctx->next_kernel;
- char initrd[2048];
- char initrd_utf16[4096];
- unsigned int len;
-
-- memset(&entry_list, 0, sizeof(entry_list));
-- if (!sdb_get_entry_list(&entry_list)) {
-- error("Error generating the list of boot entries\n");
-+ /* If no --next-kernel option was given, do not rehash anything */
-+ if (next_kernel == NULL)
-+ return tpm_event_get_digest(ev, ctx->algo);
-+
-+ if (!next_kernel->image_path) {
-+ error("Unable to identify the next kernel\n");
- return NULL;
- }
-
-- debug("Next boot entry expected from: %s\n", entry_list.entries[0].path);
-+ debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : "");
- snprintf(initrd, sizeof(initrd), "initrd=%s %s",
-- path_unix2dos(entry_list.entries[0].path),
-- entry_list.entries[0].options);
-+ path_unix2dos(next_kernel->initrd_path),
-+ next_kernel->options? : "");
-
- len = (strlen(initrd) + 1) << 1;
- assert(len <= sizeof(initrd_utf16));
-@@ -860,19 +863,20 @@ __tpm_event_tag_initrd_describe(const tpm_parsed_event_t *parsed)
- static const tpm_evdigest_t *
- __tpm_event_tag_initrd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx)
- {
-- sdb_entry_list_t entry_list;
-- const tpm_evdigest_t *md = NULL;
-+ const uapi_boot_entry_t *next_kernel = ctx->next_kernel;
-+
-+ /* If no --next-kernel option was given, do not rehash anything */
-+ if (next_kernel == NULL)
-+ return tpm_event_get_digest(ev, ctx->algo);
-
-- memset(&entry_list, 0, sizeof(entry_list));
-- if (!sdb_get_entry_list(&entry_list)) {
-- error("Error generating the list of boot entries\n");
-+ if (!next_kernel->initrd_path) {
-+ /* Can this happen eg when going from a split kernel to a unified kernel? */
-+ error("Unable to identify the next initrd\n");
- return NULL;
- }
-
-- debug("Next boot entry expected from: %s\n", entry_list.entries[0].path);
-- md = runtime_digest_efi_file(ctx->algo, entry_list.entries[0].initrd);
--
-- return md;
-+ debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : "");
-+ return runtime_digest_efi_file(ctx->algo, next_kernel->initrd_path);
- }
-
- /*
-
-From 13f67d840ffadccbd0daf4fb133f9471a5b1a439 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Mon, 27 Nov 2023 18:44:05 +0100
-Subject: [PATCH 07/13] Remove old code from sd-boot.*
-
-Signed-off-by: Olaf Kirch
----
- src/sd-boot.c | 222 +-------------------------------------------------
- src/sd-boot.h | 2 -
- 2 files changed, 3 insertions(+), 221 deletions(-)
-
-diff --git a/src/sd-boot.c b/src/sd-boot.c
-index 2e7ec61..c878f6c 100644
---- a/src/sd-boot.c
-+++ b/src/sd-boot.c
-@@ -100,163 +100,6 @@ read_machine_id(void)
- return read_single_line_file("/etc/machine-id", id, sizeof(id));
- }
-
--static bool
--read_entry(sdb_entry_data_t *result)
--{
-- FILE *fp;
-- char line[SDB_LINE_MAX];
--
-- if (!(fp = fopen(result->path, "r"))) {
-- error("Cannot open %s: %m\n", result->path);
-- goto fail;
-- }
--
-- while (fgets(line, SDB_LINE_MAX, fp)) {
-- char *dest = NULL;
--
-- if (!strncmp("sort-key", line, strlen("sort-key")))
-- dest = result->sort_key;
-- else
-- if (!strncmp("machine-id", line, strlen("machine-id")))
-- dest = result->machine_id;
-- else
-- if (!strncmp("version", line, strlen("version")))
-- dest = result->version;
-- else
-- if (!strncmp("options", line, strlen("options")))
-- dest = result->options;
-- else
-- if (!strncmp("linux", line, strlen("linux")))
-- dest = result->image;
-- else
-- if (!strncmp("initrd", line, strlen("initrd")))
-- dest = result->initrd;
-- else
-- continue;
--
-- /* Position the index on the value section of the line */
-- unsigned int index = 0;
-- while (line[++index] != ' ');
-- while (line[++index] == ' ');
-- strncpy(dest, &line[index], strlen(&line[index]) - 1);
-- }
--
-- fclose(fp);
-- return true;
--
--fail:
-- return false;
--}
--
--static int
--cmp(int a, int b)
--{
-- return a - b;
--}
--
--static bool
--isvalid(char a)
--{
-- return isalnum(a) || a == '~' || a == '-' || a == '^' || a == '.';
--}
--
--static int
--natoi(const char *a, unsigned int n)
--{
-- char line[SDB_LINE_MAX];
--
-- strncpy(line, a, MIN(SDB_LINE_MAX, n));
-- return atoi(line);
--}
--
--static int
--vercmp(const void *va, const void *vb)
--{
-- /* https://uapi-group.org/specifications/specs/version_format_specification/ */
-- /* This code is based on strverscmp_improved from systemd */
--
-- const char *a = va;
-- const char *b = vb;
-- const char *sep = "~-^.";
--
-- assert(a != NULL);
-- assert(b != NULL);
--
-- for(;;) {
-- const char *aa, *bb;
-- int r;
--
-- while (*a != '\0' && !isvalid(*a))
-- a++;
-- while (*b != '\0' && !isvalid(*b))
-- b++;
--
-- /* The longer string is considered new */
-- if (*a == '\0' || *b == '\0')
-- return cmp(*a, *b);
--
-- for (int i = 0; i < strlen(sep); i++) {
-- char s = sep[i];
--
-- if (*a == s || *b == s) {
-- r = cmp(*a != s, *b != s);
-- if (r != 0)
-- return r;
--
-- a++;
-- b++;
-- }
-- }
--
-- if (isdigit(*a) || isdigit(*b)) {
-- for (aa = a; isdigit(*aa); aa++);
-- for (bb = b; isdigit(*bb); bb++);
--
-- r = cmp(a != aa, b != bb);
-- if (r != 0)
-- return r;
--
-- r = cmp(natoi(a, aa - a), natoi(b, bb - b));
-- if (r != 0)
-- return r;
-- } else {
-- for (aa = a; isalpha(*aa); aa++);
-- for (bb = b; isalpha(*bb); bb++);
--
-- r = cmp(strncmp(a, b, MIN(aa - a, bb - b)), 0);
-- if (r != 0)
-- return r;
--
-- r = cmp(aa - a, bb - b);
-- if (r != 0)
-- return r;
-- }
--
-- a = aa;
-- b = bb;
-- }
--}
--
--static int
--entrycmp(const void *va, const void *vb)
--{
-- /* https://uapi-group.org/specifications/specs/boot_loader_specification/#sorting */
-- int result;
-- const sdb_entry_data_t *a = va;
-- const sdb_entry_data_t *b = vb;
--
-- result = strcmp(a->sort_key, b->sort_key);
--
-- if (result == 0)
-- result = strcmp(a->machine_id, b->machine_id);
--
-- if (result == 0)
-- result = vercmp(a->version, b->version);
--
-- /* Reverse the order, so new kernels appears first */
-- return -result;
--}
--
- static bool
- exists_efi_dir(const char *path)
- {
-@@ -302,49 +145,9 @@ get_token_id(void)
- return token_id;
- }
-
--bool
--sdb_get_entry_list(sdb_entry_list_t *result)
--{
-- const char *token_id = NULL;
-- DIR *d = NULL;
-- struct dirent *dir;
-- char *path = "/boot/efi/loader/entries";
--
-- if (!(token_id = get_token_id()))
-- goto fail;
--
-- if (!(d = opendir(path))) {
-- error("Cannot read directory contents from /boot/efi/loader/entries: %m\n");
-- goto fail;
-- }
--
-- while ((dir = readdir(d)) != NULL) {
-- if (result->num_entries >= SDB_MAX_ENTRIES)
-- break;
--
-- if (strncmp(token_id, dir->d_name, strlen(token_id)))
-- continue;
--
-- debug("Bootloader entry %s\n", dir->d_name);
--
-- snprintf(result->entries[result->num_entries].path, PATH_MAX, "%s/%s", path, dir->d_name);
-- if (!read_entry(&result->entries[result->num_entries])) {
-- error("Cannot read bootloader entry %s\n", dir->d_name);
-- continue;
-- }
--
-- result->num_entries++;
-- }
--
-- qsort(result->entries, result->num_entries, sizeof(result->entries[0]), entrycmp);
--
-- closedir(d);
-- return true;
--
--fail:
-- return false;
--}
--
-+/*
-+ * This should probably use UAPI boot entry logic as well
-+ */
- bool
- sdb_is_kernel(const char *application)
- {
-@@ -368,25 +171,6 @@ sdb_is_kernel(const char *application)
- return false;
- }
-
--const char *
--sdb_get_next_kernel(void)
--{
-- static char result[SDB_LINE_MAX];
-- sdb_entry_list_t entry_list;
--
-- memset(&entry_list, 0, sizeof(entry_list));
-- if (!sdb_get_entry_list(&entry_list)) {
-- error("Error generating the list of boot entries\n");
-- goto fail;
-- }
--
-- strncpy(result, entry_list.entries[0].image, SDB_LINE_MAX);
-- return result;
--
--fail:
-- return NULL;
--}
--
- /*
- * Identify the next kernel and initrd given an ID
- */
-diff --git a/src/sd-boot.h b/src/sd-boot.h
-index fa56751..2b11dc1 100644
---- a/src/sd-boot.h
-+++ b/src/sd-boot.h
-@@ -43,9 +43,7 @@ typedef struct sdb_entry_list {
- } sdb_entry_list_t;
-
- extern uapi_boot_entry_t * sdb_identify_next_kernel(const char *id);
--extern bool sdb_get_entry_list(sdb_entry_list_t *result);
- extern bool sdb_is_kernel(const char *application);
--extern const char * sdb_get_next_kernel(void);
-
- /* This will have to update the systemd json file, and add a new entry. */
- extern bool sdb_policy_file_add_entry(const char *filename,
-
-From 737d8d561cfbd1dd03e7c4d37d7c515b709cce11 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Tue, 28 Nov 2023 10:30:10 +0100
-Subject: [PATCH 08/13] Manpage fixes
-
-Signed-off-by: Olaf Kirch
----
- man/pcr-oracle.8.in | 9 ++++-----
- 1 file changed, 4 insertions(+), 5 deletions(-)
-
-diff --git a/man/pcr-oracle.8.in b/man/pcr-oracle.8.in
-index 4bd60ba..3682afa 100644
---- a/man/pcr-oracle.8.in
-+++ b/man/pcr-oracle.8.in
-@@ -82,7 +82,7 @@ object in a native format defined in the TPM specification.
- Finally, the systemd-boot implementation for unlocking disk partitions
- stores policies in a JSON formatted file, which can be fed to the
- \fBsystemd-cryptenroll\fP tool. This file will contain any number of
--signed policies that we want \fBsystemd-cryptsetup\fB to recognize during
-+signed policies that we want \fBsystemd-cryptsetup\fP to recognize during
- boot time. Each entry contains the list of PCRs that compose the PCR policy, a
- finger print of the public key, the hash of the policy and the signature (in
- base64) of the PCR policy.
-@@ -366,7 +366,7 @@ that. The main difference is in the way the signed policy is stored:
- --from eventlog \\
- --output tpm2-pcr-signature.json \\
- --policy-format systemd \\
-- sign 0,2,4,7,9,11
-+ sign 0,2,4,7,9,12
- .fi
- .P
- This will predict a set of PCR values, sign them using the specified
-@@ -384,9 +384,8 @@ These policies can then be enrolled for future system boots using
- # systemd-cryptenroll \\
- --tpm2-device=auto \\
- --tpm2-public-key=public-key.pem \\
-- --tpm2-public-key-pcrs="0,2,4,7,9,11" \
-+ --tpm2-public-key-pcrs="0,2,4,7,9,12" \
- --tpm2-signature=tpm2-pcr-signature.json \\
-- --policy-format systemd \\
- /dev/sda3
- .fi
- .\" ##################################################################
-@@ -510,7 +509,7 @@ kernel image will be used on next boot.
- .BI --authorized-policy " path
- Specify the location of the authorized policy. In conjunction with
- the \fBcreate-authorized-policy\fP action, the newly created policy
--is written to this location. For subsequent actions, such as \fBseal\fB,
-+is written to this location. For subsequent actions, such as \fBseal\fP,
- the policy will be read from this location.
- .TP
- .BI --private-key " path
-
-From c0011884d8685d4f59523e45f69bd77d2c113838 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Tue, 28 Nov 2023 10:42:12 +0100
-Subject: [PATCH 09/13] Several fixes resulting from review by alberto
-
-Signed-off-by: Olaf Kirch
----
- src/uapi.c | 4 +---
- src/util.c | 2 +-
- 2 files changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/src/uapi.c b/src/uapi.c
-index bbcaea9..a12ad21 100644
---- a/src/uapi.c
-+++ b/src/uapi.c
-@@ -123,8 +123,6 @@ uapi_boot_entry_applies(const uapi_boot_entry_t *entry, const char *machine_id,
- return false;
- if (entry->architecture && architecture && strcmp(entry->architecture, architecture))
- return false;
-- /* We don't check the efi key because it can only express "entry is EFI only"; it cannot express
-- * "this is a legacy BIOS entry" */
- return true;
- }
-
-@@ -147,7 +145,7 @@ uapi_boot_entry_more_recent(const uapi_boot_entry_t *entry_a, const uapi_boot_en
-
- /*
- * We pass in a best_ret pointer in case we need to extend this
-- * to search more than on directory
-+ * to search more than one directory
- */
- uapi_boot_entry_t *
- uapi_find_matching_boot_entry(const char *dir_path,
-diff --git a/src/util.c b/src/util.c
-index 644d138..7343ffb 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -526,7 +526,7 @@ read_single_line_file(const char *path, char *buffer, size_t size)
- }
-
- if (fgets(buffer, size, fp) != NULL)
-- buffer[strcspn(buffer, "\n")] = 0;
-+ buffer[strcspn(buffer, "\n")] = '\0';
- else
- buffer[0] = '\0';
-
-
-From f0c09557aa72794c7149529056e6fc9ea1cd2763 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Tue, 28 Nov 2023 10:45:15 +0100
-Subject: [PATCH 10/13] When matching UAPI boot entries, check against all
- possible entry-tokens
-
-Signed-off-by: Olaf Kirch
----
- src/sd-boot.c | 87 +++++++++++++++++++++++++++++++++++++--------------
- src/uapi.c | 50 ++++++++++++++++++++++++-----
- src/uapi.h | 11 ++++++-
- 3 files changed, 115 insertions(+), 33 deletions(-)
-
-diff --git a/src/sd-boot.c b/src/sd-boot.c
-index c878f6c..8dc9bf1 100644
---- a/src/sd-boot.c
-+++ b/src/sd-boot.c
-@@ -32,7 +32,6 @@
- #include "sd-boot.h"
- #include "util.h"
-
--
- static const char *
- read_entry_token(void)
- {
-@@ -100,6 +99,34 @@ read_machine_id(void)
- return read_single_line_file("/etc/machine-id", id, sizeof(id));
- }
-
-+/*
-+ * Kernels installed by kernel-install can use a variety of IDs as entry-token.
-+ * Try to cater to all of them.
-+ */
-+static const uapi_kernel_entry_tokens_t *
-+get_valid_kernel_entry_tokens(void)
-+{
-+ static uapi_kernel_entry_tokens_t valid_tokens;
-+ const char *token;
-+
-+ if (valid_tokens.count != 0)
-+ return &valid_tokens; /* I've been here before */
-+
-+ if ((token = read_entry_token()) != NULL)
-+ uapi_kernel_entry_tokens_add(&valid_tokens, token);
-+
-+ if ((token = read_machine_id()) != NULL)
-+ uapi_kernel_entry_tokens_add(&valid_tokens, token);
-+
-+ if ((token = read_os_release("ID")) != NULL)
-+ uapi_kernel_entry_tokens_add(&valid_tokens, token);
-+
-+ if ((token = read_os_release("IMAGE_ID")) != NULL)
-+ uapi_kernel_entry_tokens_add(&valid_tokens, token);
-+
-+ return &valid_tokens;
-+}
-+
- static bool
- exists_efi_dir(const char *path)
- {
-@@ -151,24 +178,28 @@ get_token_id(void)
- bool
- sdb_is_kernel(const char *application)
- {
-- const char *token_id;
-- const char *prefix = "linux-";
-- char path[PATH_MAX];
--
-- if (!(token_id = get_token_id()))
-- goto fail;
--
-- snprintf(path, PATH_MAX, "/%s/", token_id);
-- if (strncmp(path, application, strlen(path)))
-- goto fail;
--
-- strncpy(path, application, PATH_MAX);
-- for (char *ptr = strtok(path, "/"); ptr; ptr = strtok(NULL, "/"))
-- if (!strncmp(ptr, prefix, strlen(prefix)))
-- return true;
-+ static const char prefix[] = "linux-";
-+ const uapi_kernel_entry_tokens_t *match;
-+ char *path_copy;
-+ int found = 0;
-+
-+ match = get_valid_kernel_entry_tokens();
-+ path_copy = strdup(application);
-+
-+ for (char *ptr = strtok(path_copy, "/"); ptr; ptr = strtok(NULL, "/")) {
-+ unsigned int i;
-+ for (i = 0; i < match->count; ++i) {
-+ const char *token = match->entry_token[i];
-+
-+ if (!strcmp(ptr, token))
-+ found |= 1;
-+ else if (!strncmp(ptr, prefix, sizeof(prefix) - 1))
-+ found |= 2;
-+ }
-+ }
-
--fail:
-- return false;
-+ free(path_copy);
-+ return (found == 3);
- }
-
- /*
-@@ -177,17 +208,25 @@ sdb_is_kernel(const char *application)
- uapi_boot_entry_t *
- sdb_identify_next_kernel(const char *id)
- {
-+ uapi_kernel_entry_tokens_t id_match = { 0 };
-+ const uapi_kernel_entry_tokens_t *match;
- const char *machine_id;
-+ uapi_boot_entry_t *result = NULL;
-
-- if (id == NULL || !strcasecmp(id, "default")) {
-- if (!(id = get_token_id()))
-- return NULL;
-+ if (id == NULL || !strcasecmp(id, "auto")) {
-+ match = get_valid_kernel_entry_tokens();
-+ } else {
-+ uapi_kernel_entry_tokens_add(&id_match, id);
-+ match = &id_match;
- }
-
-- if (!(machine_id = read_machine_id()))
-- return NULL;
-+ machine_id = read_machine_id();
-+
-+ if (machine_id != NULL)
-+ result = uapi_find_boot_entry(match, machine_id);
-
-- return uapi_find_boot_entry(id, machine_id);
-+ uapi_kernel_entry_tokens_destroy(&id_match);
-+ return result;
- }
-
- /*
-diff --git a/src/uapi.c b/src/uapi.c
-index a12ad21..acba37a 100644
---- a/src/uapi.c
-+++ b/src/uapi.c
-@@ -149,11 +149,10 @@ uapi_boot_entry_more_recent(const uapi_boot_entry_t *entry_a, const uapi_boot_en
- */
- uapi_boot_entry_t *
- uapi_find_matching_boot_entry(const char *dir_path,
-- const char *entry_id, const char *machine_id, const char *architecture,
-+ const uapi_kernel_entry_tokens_t *match, const char *machine_id, const char *architecture,
- uapi_boot_entry_t **best_ret)
- {
- uapi_boot_entry_t *best = *best_ret;
-- unsigned int entry_id_len = 0;
- struct dirent *d;
- DIR *dir;
-
-@@ -163,9 +162,6 @@ uapi_find_matching_boot_entry(const char *dir_path,
- return NULL;
- }
-
-- if (entry_id)
-- entry_id_len = strlen(entry_id);
--
- while ((d = readdir(dir)) != NULL) {
- char config_path[PATH_MAX];
- uapi_boot_entry_t *entry;
-@@ -173,7 +169,7 @@ uapi_find_matching_boot_entry(const char *dir_path,
- if (d->d_type != DT_REG)
- continue;
-
-- if (entry_id && strncmp(d->d_name, entry_id, entry_id_len))
-+ if (match && !uapi_kernel_entry_tokens_match_filename(match, d->d_name))
- continue;
-
- snprintf(config_path, sizeof(config_path), "%s/%s", dir_path, d->d_name);
-@@ -201,7 +197,7 @@ uapi_find_matching_boot_entry(const char *dir_path,
- }
-
- uapi_boot_entry_t *
--uapi_find_boot_entry(const char *id, const char *machine_id)
-+uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id)
- {
- uapi_boot_entry_t *best = NULL;
- struct utsname uts;
-@@ -211,7 +207,7 @@ uapi_find_boot_entry(const char *id, const char *machine_id)
- architecture = uts.machine;
-
- return uapi_find_matching_boot_entry(UAPI_BOOT_DIRECTORY,
-- id, machine_id, architecture,
-+ match, machine_id, architecture,
- &best);
- }
-
-@@ -227,6 +223,44 @@ uapi_boot_entry_free(uapi_boot_entry_t *ube)
- free(ube);
- }
-
-+/*
-+ * Manage list of valid entry-tokens
-+ */
-+void
-+uapi_kernel_entry_tokens_add(uapi_kernel_entry_tokens_t *match, const char *id)
-+{
-+ if (id == NULL)
-+ return;
-+
-+ if (match->count >= UAPI_MAX_ENTRY_TOKENS)
-+ fatal("%s: too many tokens\n", __func__);
-+
-+ match->entry_token[match->count++] = strdup(id);
-+}
-+
-+void
-+uapi_kernel_entry_tokens_destroy(uapi_kernel_entry_tokens_t *match)
-+{
-+ while (match->count)
-+ drop_string(&match->entry_token[--(match->count)]);
-+}
-+
-+bool
-+uapi_kernel_entry_tokens_match_filename(const uapi_kernel_entry_tokens_t *token_list, const char *filename)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < token_list->count; ++i) {
-+ const char *token = token_list->entry_token[i];
-+ int len = strlen(token);
-+
-+ if (!strncmp(filename, token, len) && filename[len] == '-')
-+ return true;
-+ }
-+
-+ return false;
-+}
-+
- /*
- * Version comparison
- */
-diff --git a/src/uapi.h b/src/uapi.h
-index ba1147e..cc38395 100644
---- a/src/uapi.h
-+++ b/src/uapi.h
-@@ -35,9 +35,18 @@ struct uapi_boot_entry {
- char * options;
- };
-
-+#define UAPI_MAX_ENTRY_TOKENS 8
-+typedef struct uapi_kernel_entry_tokens {
-+ unsigned int count;
-+ char * entry_token[UAPI_MAX_ENTRY_TOKENS];
-+} uapi_kernel_entry_tokens_t;
-+
- #define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries"
-
--extern uapi_boot_entry_t * uapi_find_boot_entry(const char *id, const char *machine_id);
-+extern uapi_boot_entry_t * uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id);
- extern void uapi_boot_entry_free(uapi_boot_entry_t *);
-+extern void uapi_kernel_entry_tokens_add(uapi_kernel_entry_tokens_t *, const char *);
-+extern void uapi_kernel_entry_tokens_destroy(uapi_kernel_entry_tokens_t *);
-+extern bool uapi_kernel_entry_tokens_match_filename(const uapi_kernel_entry_tokens_t *, const char *filename);
-
- #endif /* UAPI_H */
-
-From 8a0d1e8050340034e4690123c205a8b98abd7d24 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Tue, 28 Nov 2023 10:46:20 +0100
-Subject: [PATCH 11/13] Remove code that's been obsoleted by
- uapi_kernel_entry_tokens stuff
-
-Signed-off-by: Olaf Kirch
----
- src/sd-boot.c | 45 ---------------------------------------------
- 1 file changed, 45 deletions(-)
-
-diff --git a/src/sd-boot.c b/src/sd-boot.c
-index 8dc9bf1..3b72e37 100644
---- a/src/sd-boot.c
-+++ b/src/sd-boot.c
-@@ -127,51 +127,6 @@ get_valid_kernel_entry_tokens(void)
- return &valid_tokens;
- }
-
--static bool
--exists_efi_dir(const char *path)
--{
-- DIR *d = NULL;
-- char full_path[PATH_MAX];
--
-- if (path == NULL)
-- return false;
--
-- snprintf(full_path, PATH_MAX, "/boot/efi/%s", path);
-- if (!(d = opendir(full_path)))
-- return false;
--
-- closedir(d);
-- return true;
--}
--
--static const char *
--get_token_id(void)
--{
-- static const char *token_id = NULL;
-- const char *id = NULL;
-- const char *image_id = NULL;
-- const char *machine_id = NULL;
--
-- /* All IDs are optional (cannot be present), except machine_id */
-- token_id = read_entry_token();
-- id = read_os_release("ID");
-- image_id = read_os_release("IMAGE_ID");
-- if (!(machine_id = read_machine_id()))
-- return NULL;
--
-- /* The order is not correct, and it is using some heuristics
-- * to find the correct prefix. Other tools like sdbootutil
-- * seems to use parameters to decide */
-- if (token_id == NULL && exists_efi_dir(id))
-- token_id = id;
-- if (token_id == NULL && exists_efi_dir(image_id))
-- token_id = id;
-- if (token_id == NULL && exists_efi_dir(machine_id))
-- token_id = machine_id;
--
-- return token_id;
--}
--
- /*
- * This should probably use UAPI boot entry logic as well
- */
-
-From 07203a598a95a11afb4cf4a6f50bb92c7d4ae981 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Tue, 28 Nov 2023 14:01:40 +0100
-Subject: [PATCH 12/13] Fix an issue with not being able to find an entry
- referenced exactly by the boot id
-
-Signed-off-by: Olaf Kirch
----
- src/sd-boot.c | 8 ++++++++
- src/uapi.c | 31 ++++++++++++++++++++++++++++++-
- src/uapi.h | 1 +
- 3 files changed, 39 insertions(+), 1 deletion(-)
-
-diff --git a/src/sd-boot.c b/src/sd-boot.c
-index 3b72e37..e3e0568 100644
---- a/src/sd-boot.c
-+++ b/src/sd-boot.c
-@@ -171,6 +171,13 @@ sdb_identify_next_kernel(const char *id)
- if (id == NULL || !strcasecmp(id, "auto")) {
- match = get_valid_kernel_entry_tokens();
- } else {
-+ /* Try to load the entry referenced _exactly_ by the
-+ * given id. */
-+ result = uapi_get_boot_entry(id);
-+ if (result != NULL)
-+ goto done;
-+
-+ /* No cigar, revert to a prefix based search */
- uapi_kernel_entry_tokens_add(&id_match, id);
- match = &id_match;
- }
-@@ -180,6 +187,7 @@ sdb_identify_next_kernel(const char *id)
- if (machine_id != NULL)
- result = uapi_find_boot_entry(match, machine_id);
-
-+done:
- uapi_kernel_entry_tokens_destroy(&id_match);
- return result;
- }
-diff --git a/src/uapi.c b/src/uapi.c
-index acba37a..f0db62a 100644
---- a/src/uapi.c
-+++ b/src/uapi.c
-@@ -24,6 +24,7 @@
- #include
- #include
- #include
-+#include
- #include
- #include
- #include
-@@ -196,6 +197,29 @@ uapi_find_matching_boot_entry(const char *dir_path,
- return best;
- }
-
-+/*
-+ * Get the exact boot entry identified by id.
-+ * This is mainly for iterating over entries like
-+ * for name in "/boot/efi/loader/entries/"*.conf; do
-+ * pcr-oracle --boot-entry $(basename $name .conf) ...
-+ * done
-+ */
-+uapi_boot_entry_t *
-+uapi_get_boot_entry(const char *id)
-+{
-+ char path[PATH_MAX];
-+
-+ if (path_has_file_extension(id, ".conf"))
-+ snprintf(path, sizeof(path), "%s/%s", UAPI_BOOT_DIRECTORY, id);
-+ else
-+ snprintf(path, sizeof(path), "%s/%s.conf", UAPI_BOOT_DIRECTORY, id);
-+
-+ if (access(path, R_OK) < 0)
-+ return NULL;
-+
-+ return uapi_boot_entry_load(path);
-+}
-+
- uapi_boot_entry_t *
- uapi_find_boot_entry(const uapi_kernel_entry_tokens_t *match, const char *machine_id)
- {
-@@ -253,8 +277,13 @@ uapi_kernel_entry_tokens_match_filename(const uapi_kernel_entry_tokens_t *token_
- for (i = 0; i < token_list->count; ++i) {
- const char *token = token_list->entry_token[i];
- int len = strlen(token);
-+ char cc;
-+
-+ if (strncmp(filename, token, len))
-+ continue;
-
-- if (!strncmp(filename, token, len) && filename[len] == '-')
-+ cc = filename[len];
-+ if (cc == '\0' || cc == '-' || cc == '.')
- return true;
- }
-
-diff --git a/src/uapi.h b/src/uapi.h
-index cc38395..96ca7ed 100644
---- a/src/uapi.h
-+++ b/src/uapi.h
-@@ -43,6 +43,7 @@ typedef struct uapi_kernel_entry_tokens {
-
- #define UAPI_BOOT_DIRECTORY "/boot/efi/loader/entries"
-
-+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);
- extern void uapi_boot_entry_free(uapi_boot_entry_t *);
- extern void uapi_kernel_entry_tokens_add(uapi_kernel_entry_tokens_t *, const char *);
-
-From 0db6dae5c065944506255b92033314c97b45e4e4 Mon Sep 17 00:00:00 2001
-From: Olaf Kirch
-Date: Tue, 28 Nov 2023 14:04:43 +0100
-Subject: [PATCH 13/13] Rename --next-kernel to --boot-entry
-
-Signed-off-by: Olaf Kirch
----
- man/pcr-oracle.8.in | 4 ++--
- src/efi-application.c | 4 ++--
- src/eventlog.c | 22 +++++++++++-----------
- src/eventlog.h | 2 +-
- src/oracle.c | 26 +++++++++++++-------------
- src/sd-boot.c | 2 +-
- src/sd-boot.h | 2 +-
- 7 files changed, 31 insertions(+), 31 deletions(-)
-
-diff --git a/man/pcr-oracle.8.in b/man/pcr-oracle.8.in
-index 3682afa..86ac275 100644
---- a/man/pcr-oracle.8.in
-+++ b/man/pcr-oracle.8.in
-@@ -494,14 +494,14 @@ events (tracked in PCR9). In this case, it would be totally sufficient
- to stop processing after grub loaded \fPgrub.cfg\fP from the EFI
- System Partition.
- .TP
--.BI --next-kernel " id
-+.BI --boot-entry " id
- In a systemd-boot environment, the values of PCR registers also depend on
- the contents of the kernel and initrd image, as well as the kernel command line
- options. After a kernel update or an initrd rebuild, these values will change.
- So when predicting PCR values in this case, \fBpcr-oracle\fP needs to be
- instructed to refer to the future kernel rather than the current one.
- .IP
--This is what the \fB--next-kernel\fP option is for. It takes one argument, which
-+This is what the \fB--boot-entry\fP option is for. It takes one argument, which
- is either an ID (in the sense of systemd-boot IDs), or \fBauto\fP. When
- the latter is given, \fBpcr-oracle\fP will make a best guess as to what
- kernel image will be used on next boot.
-diff --git a/src/efi-application.c b/src/efi-application.c
-index 9d7e531..3e80083 100644
---- a/src/efi-application.c
-+++ b/src/efi-application.c
-@@ -291,8 +291,8 @@ __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->next_kernel) {
-- new_application = ctx->next_kernel->image_path;
-+ if (sdb_is_kernel(evspec->efi_application) && ctx->boot_entry) {
-+ new_application = ctx->boot_entry->image_path;
- if (new_application) {
- evspec_clone = *evspec;
- evspec_clone.efi_application = strdup(new_application);
-diff --git a/src/eventlog.c b/src/eventlog.c
-index 3498790..4277d42 100644
---- a/src/eventlog.c
-+++ b/src/eventlog.c
-@@ -789,24 +789,24 @@ __tpm_event_systemd_describe(const tpm_parsed_event_t *parsed)
- 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 *next_kernel = ctx->next_kernel;
-+ const uapi_boot_entry_t *boot_entry = ctx->boot_entry;
- char initrd[2048];
- char initrd_utf16[4096];
- unsigned int len;
-
- /* If no --next-kernel option was given, do not rehash anything */
-- if (next_kernel == NULL)
-+ if (boot_entry == NULL)
- return tpm_event_get_digest(ev, ctx->algo);
-
-- if (!next_kernel->image_path) {
-+ if (!boot_entry->image_path) {
- error("Unable to identify the next kernel\n");
- return NULL;
- }
-
-- debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : "");
-+ debug("Next boot entry expected from: %s %s\n", boot_entry->title, boot_entry->version? : "");
- snprintf(initrd, sizeof(initrd), "initrd=%s %s",
-- path_unix2dos(next_kernel->initrd_path),
-- next_kernel->options? : "");
-+ path_unix2dos(boot_entry->initrd_path),
-+ boot_entry->options? : "");
-
- len = (strlen(initrd) + 1) << 1;
- assert(len <= sizeof(initrd_utf16));
-@@ -863,20 +863,20 @@ __tpm_event_tag_initrd_describe(const tpm_parsed_event_t *parsed)
- static const tpm_evdigest_t *
- __tpm_event_tag_initrd_rehash(const tpm_event_t *ev, const tpm_parsed_event_t *parsed, tpm_event_log_rehash_ctx_t *ctx)
- {
-- const uapi_boot_entry_t *next_kernel = ctx->next_kernel;
-+ const uapi_boot_entry_t *boot_entry = ctx->boot_entry;
-
- /* If no --next-kernel option was given, do not rehash anything */
-- if (next_kernel == NULL)
-+ if (boot_entry == NULL)
- return tpm_event_get_digest(ev, ctx->algo);
-
-- if (!next_kernel->initrd_path) {
-+ if (!boot_entry->initrd_path) {
- /* Can this happen eg when going from a split kernel to a unified kernel? */
- error("Unable to identify the next initrd\n");
- return NULL;
- }
-
-- debug("Next boot entry expected from: %s %s\n", next_kernel->title, next_kernel->version? : "");
-- return runtime_digest_efi_file(ctx->algo, next_kernel->initrd_path);
-+ debug("Next boot entry expected from: %s %s\n", boot_entry->title, boot_entry->version? : "");
-+ return runtime_digest_efi_file(ctx->algo, boot_entry->initrd_path);
- }
-
- /*
-diff --git a/src/eventlog.h b/src/eventlog.h
-index 65e5322..3741b58 100644
---- a/src/eventlog.h
-+++ b/src/eventlog.h
-@@ -202,7 +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 */
-- uapi_boot_entry_t * next_kernel;
-+ uapi_boot_entry_t * boot_entry;
- } tpm_event_log_rehash_ctx_t;
-
- #define GRUB_COMMAND_ARGV_MAX 32
-diff --git a/src/oracle.c b/src/oracle.c
-index 2cc53c1..1cafafc 100644
---- a/src/oracle.c
-+++ b/src/oracle.c
-@@ -59,7 +59,7 @@ struct predictor {
- const char * initial_source;
-
- const char * tpm_event_log_path;
-- const char * next_kernel_id;
-+ const char * boot_entry_id;
-
- const char * algo;
- const tpm_algo_info_t * algo_info;
-@@ -100,7 +100,7 @@ enum {
- OPT_POLICY_NAME,
- OPT_POLICY_FORMAT,
- OPT_TARGET_PLATFORM,
-- OPT_NEXT_KERNEL,
-+ OPT_BOOT_ENTRY,
- };
-
- static struct option options[] = {
-@@ -117,7 +117,7 @@ static struct option options[] = {
- { "before", no_argument, 0, OPT_BEFORE },
- { "verify", required_argument, 0, OPT_VERIFY },
- { "use-pesign", no_argument, 0, OPT_USE_PESIGN },
-- { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL },
-+ { "boot-entry", required_argument, 0, OPT_BOOT_ENTRY },
- { "create-testcase", required_argument, 0, OPT_CREATE_TESTCASE },
- { "replay-testcase", required_argument, 0, OPT_REPLAY_TESTCASE },
-
-@@ -133,7 +133,7 @@ static struct option options[] = {
- { "policy-name", required_argument, 0, OPT_POLICY_NAME },
- { "policy-format", required_argument, 0, OPT_POLICY_FORMAT },
- { "target-platform", required_argument, 0, OPT_TARGET_PLATFORM },
-- { "next-kernel", required_argument, 0, OPT_NEXT_KERNEL },
-+ { "next-kernel", required_argument, 0, OPT_BOOT_ENTRY },
-
- { NULL }
- };
-@@ -256,7 +256,7 @@ static struct predictor *
- predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source,
- const char *tpm_eventlog_path,
- const char *output_format,
-- const char *next_kernel_id)
-+ const char *boot_entry_id)
- {
- struct predictor *pred;
-
-@@ -266,7 +266,7 @@ predictor_new(const tpm_pcr_selection_t *pcr_selection, const char *source,
- pred = calloc(1, sizeof(*pred));
- pred->pcr_mask = pcr_selection->pcr_mask;
- pred->initial_source = source;
-- pred->next_kernel_id = next_kernel_id;
-+ pred->boot_entry_id = boot_entry_id;
-
- pred->algo = pcr_selection->algo_info->openssl_name;
- pred->algo_info = pcr_selection->algo_info;
-@@ -662,9 +662,9 @@ 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->next_kernel_id != NULL
-- && !(rehash_ctx.next_kernel = sdb_identify_next_kernel(pred->next_kernel_id)))
-- fatal("unable to identify next kernel \"%s\"\n", pred->next_kernel_id);
-+ 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);
-
- for (ev = pred->event_log; ev; ev = ev->next) {
- tpm_evdigest_t *pcr;
-@@ -1036,7 +1036,7 @@ main(int argc, char **argv)
- char *opt_rsa_bits = NULL;
- char *opt_policy_name = NULL;
- char *opt_target_platform = NULL;
-- char *opt_next_kernel = NULL;
-+ char *opt_boot_entry = NULL;
- const target_platform_t *target;
- unsigned int action_flags = 0;
- unsigned int rsa_bits = 2048;
-@@ -1071,8 +1071,8 @@ main(int argc, char **argv)
- case OPT_USE_PESIGN:
- opt_use_pesign = 1;
- break;
-- case OPT_NEXT_KERNEL:
-- opt_next_kernel = optarg;
-+ case OPT_BOOT_ENTRY:
-+ opt_boot_entry = optarg;
- break;
- case OPT_STOP_EVENT:
- opt_stop_event = optarg;
-@@ -1315,7 +1315,7 @@ main(int argc, char **argv)
- fatal("BUG: action %u should have parsed a PCR selection argument", action);
-
- pred = predictor_new(pcr_selection, opt_from, opt_eventlog_path,
-- opt_output_format, opt_next_kernel);
-+ opt_output_format, opt_boot_entry);
-
- if (opt_stop_event)
- predictor_set_stop_event(pred, opt_stop_event, !opt_stop_before);
-diff --git a/src/sd-boot.c b/src/sd-boot.c
-index e3e0568..ad13617 100644
---- a/src/sd-boot.c
-+++ b/src/sd-boot.c
-@@ -161,7 +161,7 @@ sdb_is_kernel(const char *application)
- * Identify the next kernel and initrd given an ID
- */
- uapi_boot_entry_t *
--sdb_identify_next_kernel(const char *id)
-+sdb_identify_boot_entry(const char *id)
- {
- uapi_kernel_entry_tokens_t id_match = { 0 };
- const uapi_kernel_entry_tokens_t *match;
-diff --git a/src/sd-boot.h b/src/sd-boot.h
-index 2b11dc1..0472320 100644
---- a/src/sd-boot.h
-+++ b/src/sd-boot.h
-@@ -42,7 +42,7 @@ typedef struct sdb_entry_list {
- sdb_entry_data_t entries[SDB_MAX_ENTRIES];
- } sdb_entry_list_t;
-
--extern uapi_boot_entry_t * sdb_identify_next_kernel(const char *id);
-+extern uapi_boot_entry_t * sdb_identify_boot_entry(const char *id);
- extern bool sdb_is_kernel(const char *application);
-
- /* This will have to update the systemd json file, and add a new entry. */
diff --git a/fix_pcr_index.patch b/fix_pcr_index.patch
deleted file mode 100644
index 739b86e..0000000
--- a/fix_pcr_index.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 152f97b1b49ca12d1de1df67c892b1c35140c056 Mon Sep 17 00:00:00 2001
-From: Alberto Planas
-Date: Thu, 30 Nov 2023 13:20:54 +0100
-Subject: [PATCH 1/3] Remove old systemd parameter
-
-Signed-off-by: Alberto Planas
----
- man/pcr-oracle.8.in | 1 -
- 1 file changed, 1 deletion(-)
-
-Index: pcr-oracle-0.5.3/src/sd-boot.c
-===================================================================
---- pcr-oracle-0.5.3.orig/src/sd-boot.c
-+++ pcr-oracle-0.5.3/src/sd-boot.c
-@@ -233,7 +233,7 @@ sdb_policy_entry_set_pcr_mask(struct jso
- pcrs = json_object_new_array();
- json_object_object_add(entry, "pcrs", pcrs);
-
-- for (pcr_index = 1; pcr_mask; pcr_index++, pcr_mask >>= 1) {
-+ for (pcr_index = 0; pcr_mask; pcr_index++, pcr_mask >>= 1) {
- if (pcr_mask & 1)
- json_object_array_add(pcrs, json_object_new_int(pcr_index));
- }
-@@ -315,7 +315,7 @@ sdb_policy_file_add_entry(const char *fi
- goto out;
-
- sdb_policy_entry_set_pcr_mask(entry, pcr_mask);
-- json_object_object_add(entry, "pfkp",
-+ json_object_object_add(entry, "pkfp",
- json_object_new_string(print_hex_string(fingerprint, fingerprint_len)));
- json_object_object_add(entry, "sig",
- json_object_new_string(print_base64_value(signature, signature_len)));
diff --git a/pcr-oracle-0.5.3.tar.xz b/pcr-oracle-0.5.3.tar.xz
deleted file mode 100644
index fb394b1..0000000
--- a/pcr-oracle-0.5.3.tar.xz
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bc53ad505c90d59675f87bd00769d7be8a6c9a3fbfa30c8013dc26d2f9a96bf7
-size 80368
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
index 3c7c3d0..41c6959 100644
--- a/pcr-oracle.changes
+++ b/pcr-oracle.changes
@@ -1,3 +1,14 @@
+-------------------------------------------------------------------
+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
diff --git a/pcr-oracle.spec b/pcr-oracle.spec
index d44ca61..2949abd 100644
--- a/pcr-oracle.spec
+++ b/pcr-oracle.spec
@@ -18,17 +18,13 @@
Name: pcr-oracle
-Version: 0.5.3
+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-FEATURE-UPSTREAM boot_entry.patch gh#okirch/pcr-oracle#40
-Patch1: boot_entry.patch
-# PATCH-FEATURE-UPSTREAM boot_entry.patch gh#okirch/pcr-oracle#44
-Patch2: fix_pcr_index.patch
BuildRequires: libopenssl-devel >= 0.9.8
BuildRequires: tpm2-0-tss-devel >= 2.4.0
Requires: libtss2-tcti-device0