- 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
This commit is contained in:
commit
48bd67e6f2
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -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
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.osc
|
17
_service
Normal file
17
_service
Normal file
@ -0,0 +1,17 @@
|
||||
<!-- See https://en.opensuse.org/openSUSE:Build_Service_Concept_SourceService -->
|
||||
<!-- for more details on the syntax -->
|
||||
|
||||
<services>
|
||||
<service name="tar_scm" mode="disabled">
|
||||
<param name="scm">git</param>
|
||||
<param name="url">https://github.com/okirch/pcr-oracle.git</param>
|
||||
<param name="filename">pcr-oracle</param>
|
||||
<param name="versionformat">@PARENT_TAG@</param>
|
||||
<param name="revision">refs/tags/0.5.4</param>
|
||||
</service>
|
||||
<service name="recompress" mode="disabled">
|
||||
<param name="file">pcr-oracle*.tar</param>
|
||||
<param name="compression">xz</param>
|
||||
</service>
|
||||
<service mode="disabled" name="set_version" />
|
||||
</services>
|
58
fix-testcase-empty-efi-variables.patch
Normal file
58
fix-testcase-empty-efi-variables.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From 61f9b77634578c0bf0c3bf6c4b386057e8661a1c Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
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 <glin@suse.com>
|
||||
---
|
||||
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
|
||||
|
412
fix_efi_measure_and_shim.patch
Normal file
412
fix_efi_measure_and_shim.patch
Normal file
@ -0,0 +1,412 @@
|
||||
From 9489d98463a596ec8e4ba9f1f4a2b2af91c0968b Mon Sep 17 00:00:00 2001
|
||||
From: Alberto Planas <aplanas@suse.com>
|
||||
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 <aplanas@suse.com>
|
||||
---
|
||||
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 <aplanas@suse.com>
|
||||
Date: Wed, 10 Jan 2024 15:51:45 +0100
|
||||
Subject: [PATCH 2/8] Rename variable to cmdline
|
||||
|
||||
Signed-off-by: Alberto Planas <aplanas@suse.com>
|
||||
---
|
||||
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 <aplanas@suse.com>
|
||||
Date: Wed, 10 Jan 2024 15:55:41 +0100
|
||||
Subject: [PATCH 3/8] Add debug output for initrd
|
||||
|
||||
Signed-off-by: Alberto Planas <aplanas@suse.com>
|
||||
---
|
||||
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 <aplanas@suse.com>
|
||||
Date: Wed, 10 Jan 2024 18:54:04 +0100
|
||||
Subject: [PATCH 4/8] Add debug output during extension
|
||||
|
||||
Signed-off-by: Alberto Planas <aplanas@suse.com>
|
||||
---
|
||||
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 <aplanas@suse.com>
|
||||
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 <aplanas@suse.com>
|
||||
---
|
||||
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 <aplanas@suse.com>
|
||||
Date: Thu, 11 Jan 2024 14:35:07 +0100
|
||||
Subject: [PATCH 6/8] Bump version to 0.5.5
|
||||
|
||||
Signed-off-by: Alberto Planas <aplanas@suse.com>
|
||||
---
|
||||
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 <aplanas@suse.com>
|
||||
Date: Mon, 26 Feb 2024 13:34:13 +0100
|
||||
Subject: [PATCH 7/8] Add secure boot detector
|
||||
|
||||
Signed-off-by: Alberto Planas <aplanas@suse.com>
|
||||
---
|
||||
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 <aplanas@suse.com>
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#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 <aplanas@suse.com>
|
||||
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 <aplanas@suse.com>
|
||||
---
|
||||
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);
|
||||
|
335
fix_grub_bls_cmdline.patch
Normal file
335
fix_grub_bls_cmdline.patch
Normal file
@ -0,0 +1,335 @@
|
||||
From fca4a51b9aac712b3adc5b6b187cc31a8391bcf6 Mon Sep 17 00:00:00 2001
|
||||
From: Alberto Planas <aplanas@suse.com>
|
||||
Date: Fri, 22 Mar 2024 22:44:41 +0100
|
||||
Subject: [PATCH] GRUB: predict cmdline, linux and initrd lines
|
||||
|
||||
Signed-off-by: Alberto Planas <aplanas@suse.com>
|
||||
---
|
||||
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;
|
188
fix_grub_bls_entry.patch
Normal file
188
fix_grub_bls_entry.patch
Normal file
@ -0,0 +1,188 @@
|
||||
From b0c4c5fbdcc89b44cee2300c5a12cb5e8de0e446 Mon Sep 17 00:00:00 2001
|
||||
From: Alberto Planas <aplanas@suse.com>
|
||||
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 <aplanas@suse.com>
|
||||
---
|
||||
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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
+#include <limits.h>
|
||||
|
||||
#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);
|
79
fix_loader_conf.patch
Normal file
79
fix_loader_conf.patch
Normal file
@ -0,0 +1,79 @@
|
||||
From c2453df75ecdbc547e4637268dccde5cdc012881 Mon Sep 17 00:00:00 2001
|
||||
From: Alberto Planas <aplanas@suse.com>
|
||||
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 <aplanas@suse.com>
|
||||
---
|
||||
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
|
3
pcr-oracle-0.5.4.tar.xz
Normal file
3
pcr-oracle-0.5.4.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:130085dbd77b8e4001356cbe9411829228eb29cdd6f14931aea5ecb57c75a2e6
|
||||
size 81828
|
179
pcr-oracle.changes
Normal file
179
pcr-oracle.changes
Normal file
@ -0,0 +1,179 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Aug 5 06:11:52 UTC 2024 - Gary Ching-Pang Lin <glin@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- Add fix_grub_bls_entry.patch to measure boot entries in GRUB BLS
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Feb 26 15:14:37 UTC 2024 - Alberto Planas Dominguez <aplanas@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- Add fix_loader_conf.patch to measure the systemd-boot loader.conf file
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 12 07:28:55 UTC 2024 - Alberto Planas Dominguez <aplanas@suse.com>
|
||||
|
||||
- Add fix_efi_measure.patch to fix the measurement of EFI binaries
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 8 07:17:35 UTC 2023 - Gary Ching-Pang Lin <glin@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- 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 <aplanas@suse.com>
|
||||
|
||||
- Add systemd-boot.patch to support systemd-cryptenroll JSON files
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jul 26 14:06:43 UTC 2023 - Gary Ching-Pang Lin <glin@suse.com>
|
||||
|
||||
- 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 <okir@suse.com>
|
||||
|
||||
- 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 <glin@suse.com>
|
||||
|
||||
- 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 <meissner@suse.com>
|
||||
|
||||
- build with optflags, remove unneeded clean section, macro bindir
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Jan 16 08:52:50 UTC 2023 - Olaf Kirch <okir@suse.com>
|
||||
|
||||
- Updated to version 0.4.2
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 5 13:54:40 UTC 2023 - Michal Suchanek <msuchanek@suse.com>
|
||||
|
||||
- Fix project URL
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Jan 4 11:50:54 UTC 2023 - Olaf Kirch <okir@suse.com>
|
||||
|
||||
- add --rsa-generate-key option
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Jan 3 15:00:08 UTC 2023 - Olaf Kirch <okir@suse.com>
|
||||
|
||||
- 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 <okir@suse.com>
|
||||
|
||||
- Updated to version 0.4:
|
||||
- drop the dependency on tss2 fapi
|
||||
- introduce authorized policies
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Nov 8 11:18:07 UTC 2022 - Olaf Kirch <okir@suse.com>
|
||||
|
||||
- Establish pcr-oracle as standalone package, apart from fde-tools
|
72
pcr-oracle.spec
Normal file
72
pcr-oracle.spec
Normal file
@ -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
|
413
support-ecc-srk.patch
Normal file
413
support-ecc-srk.patch
Normal file
@ -0,0 +1,413 @@
|
||||
From 60ce42dbf61ce89012d9bc71c92c5cc92759b02c Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
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 <glin@suse.com>
|
||||
---
|
||||
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 <glin@suse.com>
|
||||
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 <glin@suse.com>
|
||||
---
|
||||
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 <glin@suse.com>
|
||||
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 <glin@suse.com>
|
||||
---
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user