Sync from SUSE:SLFO:Main grub2 revision 3010d884e9d64ab422fda75d82b89c60
This commit is contained in:
parent
5668489852
commit
88730040a1
374
0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
Normal file
374
0001-cli_lock-Add-build-option-to-block-command-line-inte.patch
Normal file
@ -0,0 +1,374 @@
|
||||
From c7dd3dd296592fef6166170121b54aafe634369f Mon Sep 17 00:00:00 2001
|
||||
From: Alec Brown <alec.r.brown@oracle.com>
|
||||
Date: Wed, 24 Jan 2024 06:26:37 +0000
|
||||
Subject: [PATCH 1/2] cli_lock: Add build option to block command line
|
||||
interface
|
||||
|
||||
Add functionality to disable command line interface access and editing of GRUB
|
||||
menu entries if GRUB image is built with --disable-cli.
|
||||
|
||||
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
|
||||
Reviewed-by: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
docs/grub.texi | 6 ++++--
|
||||
grub-core/kern/main.c | 28 ++++++++++++++++++++++++++++
|
||||
grub-core/kern/rescue_reader.c | 13 +++++++++++++
|
||||
grub-core/normal/auth.c | 3 +++
|
||||
grub-core/normal/menu_text.c | 31 +++++++++++++++++--------------
|
||||
include/grub/kernel.h | 3 ++-
|
||||
include/grub/misc.h | 2 ++
|
||||
include/grub/util/install.h | 8 ++++++--
|
||||
util/grub-install-common.c | 11 ++++++++---
|
||||
util/grub-mkimage.c | 9 ++++++++-
|
||||
util/mkimage.c | 16 +++++++++++++++-
|
||||
11 files changed, 106 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 00c5fdc44..e89007920 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6523,8 +6523,10 @@ the GRUB command line, edit menu entries, and execute any menu entry. If
|
||||
@samp{superusers} is set, then use of the command line and editing of menu
|
||||
entries are automatically restricted to superusers. Setting @samp{superusers}
|
||||
to empty string effectively disables both access to CLI and editing of menu
|
||||
-entries. Note: The environment variable needs to be exported to also affect
|
||||
-the section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||
+entries. Building a grub image with @samp{--disable-cli} option will also
|
||||
+disable access to CLI and editing of menu entries, as well as disabling rescue
|
||||
+mode. Note: The environment variable needs to be exported to also affect the
|
||||
+section defined by the @samp{submenu} command (@pxref{submenu}).
|
||||
|
||||
Other users may be allowed to execute specific menu entries by giving a list of
|
||||
usernames (as above) using the @option{--users} option to the
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 02df49206..07b6940d2 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -30,11 +30,14 @@
|
||||
#include <grub/reader.h>
|
||||
#include <grub/parser.h>
|
||||
#include <grub/verify.h>
|
||||
+#include <grub/types.h>
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
#include <grub/machine/memory.h>
|
||||
#endif
|
||||
|
||||
+static bool cli_disabled = false;
|
||||
+
|
||||
grub_addr_t
|
||||
grub_modules_get_end (void)
|
||||
{
|
||||
@@ -237,6 +240,28 @@ grub_load_normal_mode (void)
|
||||
grub_command_execute ("normal", 0, 0);
|
||||
}
|
||||
|
||||
+bool
|
||||
+grub_is_cli_disabled (void)
|
||||
+{
|
||||
+ return cli_disabled;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+check_is_cli_disabled (void)
|
||||
+{
|
||||
+ struct grub_module_header *header;
|
||||
+ header = 0;
|
||||
+
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ if (header->type == OBJ_TYPE_DISABLE_CLI)
|
||||
+ {
|
||||
+ cli_disabled = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
reclaim_module_space (void)
|
||||
{
|
||||
@@ -294,6 +319,9 @@ grub_main (void)
|
||||
|
||||
grub_boot_time ("After loading embedded modules.");
|
||||
|
||||
+ /* Check if the CLI should be disabled */
|
||||
+ check_is_cli_disabled ();
|
||||
+
|
||||
/* It is better to set the root device as soon as possible,
|
||||
for convenience. */
|
||||
grub_set_prefix_and_root ();
|
||||
diff --git a/grub-core/kern/rescue_reader.c b/grub-core/kern/rescue_reader.c
|
||||
index dcd7d4439..4259857ba 100644
|
||||
--- a/grub-core/kern/rescue_reader.c
|
||||
+++ b/grub-core/kern/rescue_reader.c
|
||||
@@ -78,6 +78,19 @@ grub_rescue_read_line (char **line, int cont,
|
||||
void __attribute__ ((noreturn))
|
||||
grub_rescue_run (void)
|
||||
{
|
||||
+ /* Stall if the CLI has been disabled */
|
||||
+ if (grub_is_cli_disabled ())
|
||||
+ {
|
||||
+ grub_printf ("Rescue mode has been disabled...\n");
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ /* Do not optimize out the loop. */
|
||||
+ asm volatile ("");
|
||||
+ }
|
||||
+ while (1);
|
||||
+ }
|
||||
+
|
||||
grub_printf ("Entering rescue mode...\n");
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
|
||||
index 517fc623f..d94020186 100644
|
||||
--- a/grub-core/normal/auth.c
|
||||
+++ b/grub-core/normal/auth.c
|
||||
@@ -209,6 +209,9 @@ grub_auth_check_authentication (const char *userlist)
|
||||
char entered[GRUB_AUTH_MAX_PASSLEN];
|
||||
struct grub_auth_user *user;
|
||||
|
||||
+ if (grub_is_cli_disabled ())
|
||||
+ return GRUB_ACCESS_DENIED;
|
||||
+
|
||||
grub_memset (login, 0, sizeof (login));
|
||||
|
||||
if (is_authenticated (userlist))
|
||||
diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
|
||||
index ae92050d7..56c6f7797 100644
|
||||
--- a/grub-core/normal/menu_text.c
|
||||
+++ b/grub-core/normal/menu_text.c
|
||||
@@ -194,21 +194,24 @@ command-line or ESC to discard edits and return to the GRUB menu."),
|
||||
grub_free (msg_translated);
|
||||
#endif
|
||||
|
||||
- if (nested)
|
||||
+ if (!grub_is_cli_disabled ())
|
||||
{
|
||||
- ret += grub_print_message_indented_real
|
||||
- (_("Press enter to boot the selected OS, "
|
||||
- "`e' to edit the commands before booting "
|
||||
- "or `c' for a command-line. ESC to return previous menu."),
|
||||
- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- ret += grub_print_message_indented_real
|
||||
- (_("Press enter to boot the selected OS, "
|
||||
- "`e' to edit the commands before booting "
|
||||
- "or `c' for a command-line."),
|
||||
- STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ if (nested)
|
||||
+ {
|
||||
+ ret += grub_print_message_indented_real
|
||||
+ (_("Press enter to boot the selected OS, "
|
||||
+ "`e' to edit the commands before booting "
|
||||
+ "or `c' for a command-line. ESC to return previous menu."),
|
||||
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret += grub_print_message_indented_real
|
||||
+ (_("Press enter to boot the selected OS, "
|
||||
+ "`e' to edit the commands before booting "
|
||||
+ "or `c' for a command-line."),
|
||||
+ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
|
||||
index d3aafc884..9f3e2031f 100644
|
||||
--- a/include/grub/kernel.h
|
||||
+++ b/include/grub/kernel.h
|
||||
@@ -31,7 +31,8 @@ enum
|
||||
OBJ_TYPE_GPG_PUBKEY,
|
||||
OBJ_TYPE_X509_PUBKEY,
|
||||
OBJ_TYPE_DTB,
|
||||
- OBJ_TYPE_DISABLE_SHIM_LOCK
|
||||
+ OBJ_TYPE_DISABLE_SHIM_LOCK,
|
||||
+ OBJ_TYPE_DISABLE_CLI
|
||||
};
|
||||
|
||||
/* The module header. */
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index 1b35a167f..1578f36c3 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -391,6 +391,8 @@ grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
|
||||
grub_uint64_t d,
|
||||
grub_uint64_t *r);
|
||||
|
||||
+extern bool EXPORT_FUNC(grub_is_cli_disabled) (void);
|
||||
+
|
||||
/* Must match softdiv group in gentpl.py. */
|
||||
#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
|
||||
(defined(__riscv) && (__riscv_xlen == 32)))
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 38c6da73b..a4aac7b85 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -72,6 +72,8 @@
|
||||
{ "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
|
||||
"SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
|
||||
1}, \
|
||||
+ { "disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, \
|
||||
+ N_("disabled command line interface access"), 0 }, \
|
||||
{ "verbose", 'v', 0, 0, \
|
||||
N_("print verbose messages."), 1 }
|
||||
|
||||
@@ -136,7 +138,8 @@ enum grub_install_options {
|
||||
GRUB_INSTALL_OPTIONS_DTB,
|
||||
GRUB_INSTALL_OPTIONS_SBAT,
|
||||
GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
|
||||
- GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
|
||||
+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,
|
||||
+ GRUB_INSTALL_OPTIONS_DISABLE_CLI
|
||||
};
|
||||
|
||||
extern char *grub_install_source_directory;
|
||||
@@ -199,7 +202,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note, size_t appsig_size,
|
||||
grub_compression_t comp, const char *dtb_file,
|
||||
- const char *sbat_path, const int disable_shim_lock);
|
||||
+ const char *sbat_path, const int disable_shim_lock,
|
||||
+ const int disable_cli);
|
||||
|
||||
const struct grub_install_image_target_desc *
|
||||
grub_install_get_image_target (const char *arg);
|
||||
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
|
||||
index 75fa03995..344dca664 100644
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -469,6 +469,7 @@ static char **x509keys;
|
||||
static size_t nx509keys;
|
||||
static grub_compression_t compression;
|
||||
static size_t appsig_size;
|
||||
+static int disable_cli;
|
||||
|
||||
int
|
||||
grub_install_parse (int key, char *arg)
|
||||
@@ -514,6 +515,9 @@ grub_install_parse (int key, char *arg)
|
||||
* (nx509keys + 1));
|
||||
x509keys[nx509keys++] = xstrdup (arg);
|
||||
return 1;
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
|
||||
+ disable_cli = 1;
|
||||
+ return 1;
|
||||
|
||||
case GRUB_INSTALL_OPTIONS_VERBOSITY:
|
||||
verbosity++;
|
||||
@@ -707,12 +711,13 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
|
||||
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'"
|
||||
" --format '%s' --compression '%s'"
|
||||
- " --appended-signature-size %zu%s%s%s\n",
|
||||
+ " --appended-signature-size %zu%s%s%s%s\n",
|
||||
dir, prefix, outname,
|
||||
mkimage_target, compnames[compression],
|
||||
appsig_size,
|
||||
note ? " --note" : "",
|
||||
- disable_shim_lock ? " --disable-shim-lock" : "", s);
|
||||
+ disable_shim_lock ? " --disable-shim-lock" : "",
|
||||
+ disable_cli ? " --disable-cli" : "", s);
|
||||
free (s);
|
||||
|
||||
tgt = grub_install_get_image_target (mkimage_target);
|
||||
@@ -724,7 +729,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
|
||||
pubkeys, npubkeys, x509keys, nx509keys,
|
||||
config_path, tgt,
|
||||
note, appsig_size, compression, dtb, sbat,
|
||||
- disable_shim_lock);
|
||||
+ disable_shim_lock, disable_cli);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
}
|
||||
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
|
||||
index 7d61ef3ea..351a5e430 100644
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -84,6 +84,7 @@ static struct argp_option options[] = {
|
||||
{"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use for core image"), 0},
|
||||
{"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
|
||||
{"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
|
||||
+ {"disable-cli", GRUB_INSTALL_OPTIONS_DISABLE_CLI, 0, 0, N_("disable command line interface access"), 0},
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
{"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
@@ -133,6 +134,7 @@ struct arguments
|
||||
int note;
|
||||
int disable_shim_lock;
|
||||
size_t appsig_size;
|
||||
+ int disable_cli;
|
||||
const struct grub_install_image_target_desc *image_target;
|
||||
grub_compression_t comp;
|
||||
};
|
||||
@@ -259,6 +261,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||
arguments->disable_shim_lock = 1;
|
||||
break;
|
||||
|
||||
+ case GRUB_INSTALL_OPTIONS_DISABLE_CLI:
|
||||
+ arguments->disable_cli = 1;
|
||||
+ break;
|
||||
+
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
@@ -347,7 +353,8 @@ main (int argc, char *argv[])
|
||||
arguments.image_target, arguments.note,
|
||||
arguments.appsig_size,
|
||||
arguments.comp, arguments.dtb,
|
||||
- arguments.sbat, arguments.disable_shim_lock);
|
||||
+ arguments.sbat, arguments.disable_shim_lock,
|
||||
+ arguments.disable_cli);
|
||||
|
||||
if (grub_util_file_sync (fp) < 0)
|
||||
grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout",
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 0737935fd..d6cc13475 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -889,7 +889,8 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
int note, size_t appsig_size, grub_compression_t comp,
|
||||
const char *dtb_path, const char *sbat_path,
|
||||
- int disable_shim_lock)
|
||||
+ int disable_shim_lock,
|
||||
+ int disable_cli)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t total_module_size, core_size;
|
||||
@@ -964,6 +965,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
if (disable_shim_lock)
|
||||
total_module_size += sizeof (struct grub_module_header);
|
||||
|
||||
+ if (disable_cli)
|
||||
+ total_module_size += sizeof (struct grub_module_header);
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1);
|
||||
@@ -1130,6 +1134,16 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
offset += sizeof (*header);
|
||||
}
|
||||
|
||||
+ if (disable_cli)
|
||||
+ {
|
||||
+ struct grub_module_header *header;
|
||||
+
|
||||
+ header = (struct grub_module_header *) (kernel_img + offset);
|
||||
+ header->type = grub_host_to_target32 (OBJ_TYPE_DISABLE_CLI);
|
||||
+ header->size = grub_host_to_target32 (sizeof (*header));
|
||||
+ offset += sizeof (*header);
|
||||
+ }
|
||||
+
|
||||
if (config_path)
|
||||
{
|
||||
struct grub_module_header *header;
|
||||
--
|
||||
2.46.0
|
||||
|
66
0001-kern-main-Fix-cmdpath-in-root-directory.patch
Normal file
66
0001-kern-main-Fix-cmdpath-in-root-directory.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 56b221476d31310de485af26550c8651618832bb Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 29 Oct 2024 11:54:28 +0800
|
||||
Subject: [PATCH] kern/main: Fix cmdpath in root directory
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The "cmdpath" environment variable is set at startup to the location
|
||||
from which the grub image is loaded. It includes a device part and,
|
||||
optionally, an absolute directory name if the grub image is booted as a
|
||||
file in a local file-system directory, or in a remote server directory,
|
||||
like TFTP.
|
||||
|
||||
This entire process relies on firmware to provide the correct device
|
||||
path of the booted image.
|
||||
|
||||
We encountered an issue when the image is booted from the root
|
||||
directory, where the absolute directory name "/" is discarded. This
|
||||
makes it unclear whether the root path was missing in the firmware
|
||||
provided device path or if it is simply the root directory. This
|
||||
ambiguity can cause confusion in custom scripts, potentially causing
|
||||
them to interpret firmware data incorrectly and trigger unintended
|
||||
fallback measures.
|
||||
|
||||
This patch fixes the problem by properly assigning the "fwpath" returned
|
||||
by "grub_machine_get_bootlocation()" to "cmdpath". The fix is based on
|
||||
the fact that fwpath is NULL if the firmware didn’t provide a path part
|
||||
or an NUL character, "", if it represents the root directory. With this,
|
||||
it becomes possible to clearly distinguish:
|
||||
|
||||
- cmdpath=(hd0,1) - Either the image is booted from the first (raw)
|
||||
partition, or the firmware failed to provide the path part.
|
||||
- cmdpath=(hd0,1)/ - The image is booted from the root directory in the
|
||||
first partition.
|
||||
|
||||
As a side note, the fix is similar to [1], but without the renaming
|
||||
part.
|
||||
|
||||
[1] https://mail.gnu.org/archive/html/grub-devel/2024-10/msg00155.html
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/kern/main.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index ef3b3756d..f9ab12c74 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -136,7 +136,11 @@ grub_set_prefix_and_root (void)
|
||||
{
|
||||
char *cmdpath;
|
||||
|
||||
- cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : "");
|
||||
+ if (fwpath && *fwpath == '\0')
|
||||
+ cmdpath = grub_xasprintf ("(%s)/", fwdevice);
|
||||
+ else
|
||||
+ cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : "");
|
||||
+
|
||||
if (cmdpath)
|
||||
{
|
||||
grub_env_set ("cmdpath", cmdpath);
|
||||
--
|
||||
2.47.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
From bf09618c47c6632b763960e265436294ab98dd43 Mon Sep 17 00:00:00 2001
|
||||
From 1bc53f8fc980914132040670b85a010e094559ec Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:53 -0800
|
||||
Subject: [PATCH 1/5] key_protector: Add key protectors framework
|
||||
Subject: [PATCH] key_protector: Add key protectors framework
|
||||
|
||||
A key protector encapsulates functionality to retrieve an unlocking key
|
||||
for a fully-encrypted disk from a specific source. A key protector
|
||||
@ -19,17 +19,18 @@ Cc: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 5 +++
|
||||
grub-core/disk/key_protector.c | 78 ++++++++++++++++++++++++++++++++++
|
||||
include/grub/key_protector.h | 46 ++++++++++++++++++++
|
||||
4 files changed, 130 insertions(+)
|
||||
grub-core/disk/key_protector.c | 73 ++++++++++++++++++++++++++++++++++
|
||||
include/grub/key_protector.h | 47 ++++++++++++++++++++++
|
||||
4 files changed, 126 insertions(+)
|
||||
create mode 100644 grub-core/disk/key_protector.c
|
||||
create mode 100644 include/grub/key_protector.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index f18550c1c..9d3d5f519 100644
|
||||
index 1eda467e0..e50db8106 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -90,6 +90,7 @@ endif
|
||||
@ -41,10 +42,10 @@ index f18550c1c..9d3d5f519 100644
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index bc893e547..4307b8e2d 100644
|
||||
index a38955e18..37f131ae2 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1302,6 +1302,11 @@ module = {
|
||||
@@ -1282,6 +1282,11 @@ module = {
|
||||
common = disk/raid6_recover.c;
|
||||
};
|
||||
|
||||
@ -58,13 +59,14 @@ index bc893e547..4307b8e2d 100644
|
||||
common = disk/scsi.c;
|
||||
diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c
|
||||
new file mode 100644
|
||||
index 000000000..b84afe1c7
|
||||
index 000000000..0d146c1c0
|
||||
--- /dev/null
|
||||
+++ b/grub-core/disk/key_protector.c
|
||||
@@ -0,0 +1,78 @@
|
||||
@@ -0,0 +1,73 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft Corporation
|
||||
+ * Copyright (C) 2024 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
@ -93,16 +95,14 @@ index 000000000..b84afe1c7
|
||||
+grub_err_t
|
||||
+grub_key_protector_register (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (protector == NULL || protector->name == NULL || grub_strlen (protector->name) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ if (protector == NULL || protector->name == NULL || protector->name[0] == '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for registration");
|
||||
+
|
||||
+ if (grub_key_protectors &&
|
||||
+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
|
||||
+ protector->name))
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ if (grub_key_protectors != NULL &&
|
||||
+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector->name) != NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Key protector '%s' already registered", protector->name);
|
||||
+
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors),
|
||||
+ GRUB_AS_LIST (protector));
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
@ -111,7 +111,7 @@ index 000000000..b84afe1c7
|
||||
+grub_key_protector_unregister (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (protector == NULL)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector for unregistration");
|
||||
+
|
||||
+ grub_list_remove (GRUB_AS_LIST (protector));
|
||||
+
|
||||
@ -125,30 +125,27 @@ index 000000000..b84afe1c7
|
||||
+ struct grub_key_protector *kp = NULL;
|
||||
+
|
||||
+ if (grub_key_protectors == NULL)
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "No key protector registered");
|
||||
+
|
||||
+ if (protector == NULL || grub_strlen (protector) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ if (protector == NULL || protector[0] == '\0')
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid key protector");
|
||||
+
|
||||
+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
|
||||
+ protector);
|
||||
+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), protector);
|
||||
+ if (kp == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("A key protector with name '%s' could not be found. "
|
||||
+ "Is the name spelled correctly and is the "
|
||||
+ "corresponding module loaded?"), protector);
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "Key protector '%s' not found", protector);
|
||||
+
|
||||
+ return kp->recover_key (key, key_size);
|
||||
+}
|
||||
diff --git a/include/grub/key_protector.h b/include/grub/key_protector.h
|
||||
new file mode 100644
|
||||
index 000000000..6e6a6fb24
|
||||
index 000000000..00b15c13d
|
||||
--- /dev/null
|
||||
+++ b/include/grub/key_protector.h
|
||||
@@ -0,0 +1,46 @@
|
||||
@@ -0,0 +1,47 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft Corporation
|
||||
+ * Copyright (C) 2024 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
@ -193,5 +190,5 @@ index 000000000..6e6a6fb24
|
||||
+
|
||||
+#endif /* ! GRUB_PROTECTOR_HEADER */
|
||||
--
|
||||
2.35.3
|
||||
2.43.0
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From f41a45b080cb9c6f59879a3e23f9ec2380015a16 Mon Sep 17 00:00:00 2001
|
||||
From 5b4ecd408417249dec8bfc71a3c0b7ef1070d3fa Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 25 Apr 2024 16:21:45 +0800
|
||||
Subject: [PATCH] tpm2: Add extra RSA SRK types
|
||||
@ -8,16 +8,16 @@ to support those parameters.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/tpm2/args.c | 12 ++++++++++++
|
||||
grub-core/tpm2/module.c | 16 ++++++++++++++--
|
||||
util/grub-protect.c | 4 ++--
|
||||
grub-core/commands/tpm2_key_protector/args.c | 12 ++++++++++++
|
||||
grub-core/commands/tpm2_key_protector/module.c | 16 ++++++++++++++--
|
||||
util/grub-protect.c | 4 ++--
|
||||
3 files changed, 28 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c
|
||||
index c11280ab9..d140364d2 100644
|
||||
--- a/grub-core/tpm2/args.c
|
||||
+++ b/grub-core/tpm2/args.c
|
||||
@@ -92,6 +92,18 @@ grub_tpm2_protector_parse_asymmetric (const char *value,
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/args.c b/grub-core/commands/tpm2_key_protector/args.c
|
||||
index 48c39de01..b291793a7 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/args.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/args.c
|
||||
@@ -85,6 +85,18 @@ grub_tpm2_protector_parse_asymmetric (const char *value,
|
||||
srk_type->type = TPM_ALG_RSA;
|
||||
srk_type->detail.rsa_bits = 2048;
|
||||
}
|
||||
@ -34,13 +34,13 @@ index c11280ab9..d140364d2 100644
|
||||
+ srk_type->detail.rsa_bits = 4096;
|
||||
+ }
|
||||
else
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
N_("Value '%s' is not a valid asymmetric key type"),
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index b754b38df..8b72ed6fa 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -136,8 +136,8 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("value '%s' is not a valid asymmetric key type"), value);
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 74e79a545..ee16d7f15 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -138,8 +138,8 @@ static const struct grub_arg_option tpm2_protector_init_cmd_options[] =
|
||||
.arg = NULL,
|
||||
.type = ARG_TYPE_STRING,
|
||||
.doc =
|
||||
@ -51,18 +51,18 @@ index b754b38df..8b72ed6fa 100644
|
||||
},
|
||||
/* NV Index-mode options */
|
||||
{
|
||||
@@ -541,6 +541,10 @@ srk_type_to_name (grub_srk_type_t srk_type)
|
||||
{
|
||||
case 2048:
|
||||
return "RSA2048";
|
||||
+ case 3072:
|
||||
+ return "RSA3072";
|
||||
+ case 4096:
|
||||
+ return "RSA4096";
|
||||
}
|
||||
}
|
||||
@@ -517,6 +517,10 @@ srk_type_to_name (grub_srk_type_t srk_type)
|
||||
return "ECC_NIST_P256";
|
||||
else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 2048)
|
||||
return "RSA2048";
|
||||
+ else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 3072)
|
||||
+ return "RSA3072";
|
||||
+ else if (srk_type.type == TPM_ALG_RSA && srk_type.detail.rsa_bits == 4096)
|
||||
+ return "RSA4096";
|
||||
|
||||
@@ -561,6 +565,14 @@ grub_tpm2_protector_load_key (const struct grub_tpm2_protector_context *ctx,
|
||||
return "Unknown";
|
||||
}
|
||||
@@ -535,6 +539,14 @@ tpm2_protector_load_key (const tpm2_protector_context_t *ctx,
|
||||
.type = TPM_ALG_ECC,
|
||||
.detail.ecc_curve = TPM_ECC_NIST_P256,
|
||||
},
|
||||
@ -78,20 +78,20 @@ index b754b38df..8b72ed6fa 100644
|
||||
.type = TPM_ALG_RSA,
|
||||
.detail.rsa_bits = 2048,
|
||||
diff --git a/util/grub-protect.c b/util/grub-protect.c
|
||||
index 869f45861..00be03ca0 100644
|
||||
index 5b7e952f4..f1108f2c5 100644
|
||||
--- a/util/grub-protect.c
|
||||
+++ b/util/grub-protect.c
|
||||
@@ -199,8 +199,8 @@ static struct argp_option grub_protect_options[] =
|
||||
@@ -202,8 +202,8 @@ static struct argp_option protect_options[] =
|
||||
.arg = "TYPE",
|
||||
.flags = 0,
|
||||
.doc =
|
||||
- N_("The type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)."
|
||||
- N_("Set the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)."
|
||||
- "(default: ECC)"),
|
||||
+ N_("The type of SRK: RSA (RSA2048), RSA3072, RSA4096, "
|
||||
+ N_("Set the type of SRK: RSA (RSA2048), RSA3072, RSA4096, "
|
||||
+ "and ECC (ECC_NIST_P256). (default: ECC)"),
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
--
|
||||
2.35.3
|
||||
2.43.0
|
||||
|
||||
|
@ -1,171 +0,0 @@
|
||||
From 26a66098d5fa50b9462c8c815429a4c18f20310b Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 6 Apr 2023 16:00:25 +0800
|
||||
Subject: [PATCH] tpm2: Support authorized policy
|
||||
|
||||
This commit handles the TPM2_PolicyAuthorize command from the key file
|
||||
in TPM 2.0 Key File format.
|
||||
|
||||
TPM2_PolicyAuthorize is the essential command to support authorized
|
||||
policy which allows the users to sign TPM policies with their own keys.
|
||||
Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize
|
||||
comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and
|
||||
'TPMT_SIGNATURE signature'. To verify the signature, the current policy
|
||||
digest is hashed with the hash algorithm written in 'signature', and then
|
||||
'signature' is verified with the hashed policy digest and 'pubkey'. Once
|
||||
TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the
|
||||
signed policy.
|
||||
|
||||
To create the key file with authorized policy, here are the pcr-oracle(*2)
|
||||
commands:
|
||||
|
||||
# Generate the RSA key and create the authorized policy file
|
||||
$ pcr-oracle \
|
||||
--rsa-generate-key \
|
||||
--private-key policy-key.pem \
|
||||
--auth authorized.policy \
|
||||
create-authorized-policy 0,2,4,7,9
|
||||
|
||||
# Seal the secret with the authorized policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--auth authorized.policy \
|
||||
--input disk-secret.txt \
|
||||
--output sealed.key \
|
||||
seal-secret
|
||||
|
||||
# Sign the predicted PCR policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--private-key policy-key.pem \
|
||||
--from eventlog \
|
||||
--stop-event "grub-file=grub.cfg" \
|
||||
--after \
|
||||
--input sealed.key \
|
||||
--output sealed.tpm \
|
||||
sign 0,2,4,7,9
|
||||
|
||||
Then specify the key file and the key protector to grub.cfg in the EFI
|
||||
system partition:
|
||||
|
||||
tpm2_key_protector_init -a RSA --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
|
||||
cryptomount -u <PART_UUID> -P tpm2
|
||||
|
||||
For any change in the boot components, just run the 'sign' command again
|
||||
to update the signature in sealed.tpm, and TPM can unseal the key file
|
||||
with the updated PCR policy.
|
||||
|
||||
(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
|
||||
(*2) https://github.com/okirch/pcr-oracle
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/tpm2/module.c | 84 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 84 insertions(+)
|
||||
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index 3db25ceca..e83b02865 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -650,6 +650,87 @@ grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION session,
|
||||
+ struct grub_tpm2_buffer *cmd_buf)
|
||||
+{
|
||||
+ TPM2B_PUBLIC pubkey;
|
||||
+ TPM2B_DIGEST policy_ref;
|
||||
+ TPMT_SIGNATURE signature;
|
||||
+ TPM2B_DIGEST pcr_policy;
|
||||
+ TPM2B_DIGEST pcr_policy_hash;
|
||||
+ TPMI_ALG_HASH sig_hash;
|
||||
+ TPMT_TK_VERIFIED verification_ticket;
|
||||
+ TPM_HANDLE pubkey_handle = 0;
|
||||
+ TPM2B_NAME pubname;
|
||||
+ TPM_RC rc;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
|
||||
+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
|
||||
+ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
|
||||
+ if (cmd_buf->error != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("Failed to unmarshal the buffer for TPM2_PolicyAuthorize"));
|
||||
+
|
||||
+ /* Retrieve Policy Digest */
|
||||
+ rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x)."),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Calculate the digest of the polcy for VerifySignature */
|
||||
+ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature);
|
||||
+ if (sig_hash == TPM_ALG_NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("Failed to get the hash algorithm of the signature"));
|
||||
+
|
||||
+ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash,
|
||||
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to create PCR policy hash (TPM2_Hash: 0x%x)"),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Load the public key */
|
||||
+ rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER,
|
||||
+ &pubkey_handle, &pubname, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to load public key (TPM2_LoadExternal: 0x%x)"),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Verify the signature against the public key and the policy digest */
|
||||
+ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to verify signature (TPM2_VerifySignature: 0x%x)"),
|
||||
+ rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* Authorize the signed policy with the public key and the verification ticket */
|
||||
+ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, &policy_ref, &pubname,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)"),
|
||||
+ rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+
|
||||
+error:
|
||||
+ TPM2_FlushContext (pubkey_handle);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session)
|
||||
{
|
||||
@@ -669,6 +750,9 @@ grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO
|
||||
case TPM_CC_PolicyPCR:
|
||||
err = grub_tpm2_protector_policypcr (session, &buf);
|
||||
break;
|
||||
+ case TPM_CC_PolicyAuthorize:
|
||||
+ err = grub_tpm2_protector_policyauthorize (session, &buf);
|
||||
+ break;
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("Unknown TPM Command: 0x%x"), policy->cmd_code);
|
||||
--
|
||||
2.35.3
|
||||
|
@ -1,12 +1,12 @@
|
||||
From 947009d79e3f17b10a7753bdde8d3a4a7b757bed Mon Sep 17 00:00:00 2001
|
||||
From 53e24662523d033ae3506b73787b972ef332db36 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Colp <patrick.colp@oracle.com>
|
||||
Date: Mon, 31 Jul 2023 07:01:45 -0700
|
||||
Subject: [PATCH 1/4] tpm2: Implement NV index
|
||||
Subject: [PATCH] tpm2_key_protector: Implement NV index
|
||||
|
||||
Currently with the TPM2 protector, only SRK mode is supported and
|
||||
NV index support is just a stub. Implement the NV index option.
|
||||
|
||||
Note: This only extends support on the unseal path. grub2_protect
|
||||
Note: This only extends support on the unseal path. grub-protect
|
||||
has not been updated. tpm2-tools can be used to insert a key into
|
||||
the NV index.
|
||||
|
||||
@ -36,41 +36,40 @@ Then to unseal the key in grub, add this to grub.cfg:
|
||||
Signed-off-by: Patrick Colp <patrick.colp@oracle.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/tpm2/module.c | 25 ++++++++++++++++++++-----
|
||||
1 file changed, 20 insertions(+), 5 deletions(-)
|
||||
.../commands/tpm2_key_protector/module.c | 23 +++++++++++++++----
|
||||
1 file changed, 19 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index e83b02865..b754b38df 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -1035,12 +1035,27 @@ static grub_err_t
|
||||
grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx,
|
||||
grub_uint8_t **key, grub_size_t *key_size)
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 6b4b5d460..74e79a545 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -973,11 +973,26 @@ tpm2_protector_srk_recover (const tpm2_protector_context_t *ctx,
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx __attribute__ ((unused)),
|
||||
- grub_uint8_t **key __attribute__ ((unused)),
|
||||
- grub_size_t *key_size __attribute__ ((unused)))
|
||||
+tpm2_protector_nv_recover (const tpm2_protector_context_t *ctx,
|
||||
+ grub_uint8_t **key, grub_size_t *key_size)
|
||||
{
|
||||
- (void)ctx;
|
||||
- (void)key;
|
||||
- (void)key_size;
|
||||
+ TPM_HANDLE sealed_handle = ctx->nv;
|
||||
- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "NV Index mode is not implemented yet");
|
||||
+ TPM_HANDLE_t sealed_handle = ctx->nv;
|
||||
+ tpm2key_policy_t policy_seq = NULL;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ /* Create a basic policy sequence based on the given PCR selection */
|
||||
+ err = grub_tpm2_protector_simple_policy_seq (ctx, &policy_seq);
|
||||
+ err = tpm2_protector_simple_policy_seq (ctx, &policy_seq);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit;
|
||||
+
|
||||
+ err = grub_tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size);
|
||||
+ err = tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size);
|
||||
+
|
||||
+ /* Pop error messages on success */
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ while (grub_error_pop ());
|
||||
+ exit:
|
||||
+ grub_tpm2_flushcontext (sealed_handle);
|
||||
+
|
||||
+exit:
|
||||
+ TPM2_FlushContext (sealed_handle);
|
||||
|
||||
- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
- N_("NV Index mode is not implemented yet"));
|
||||
+ grub_tpm2key_free_policy_seq (policy_seq);
|
||||
+
|
||||
+ return err;
|
||||
@ -78,5 +77,5 @@ index e83b02865..b754b38df 100644
|
||||
|
||||
static grub_err_t
|
||||
--
|
||||
2.35.3
|
||||
2.43.0
|
||||
|
158
0001-tpm2_key_protector-Support-authorized-policy.patch
Normal file
158
0001-tpm2_key_protector-Support-authorized-policy.patch
Normal file
@ -0,0 +1,158 @@
|
||||
From 7ef1b9b357c803cb8e30bbbebd44494b2b5c9d09 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 6 Apr 2023 16:00:25 +0800
|
||||
Subject: [PATCH] tpm2_key_protector: Support authorized policy
|
||||
|
||||
This commit handles the TPM2_PolicyAuthorize command from the key file
|
||||
in TPM 2.0 Key File format.
|
||||
|
||||
TPM2_PolicyAuthorize is the essential command to support authorized
|
||||
policy which allows the users to sign TPM policies with their own keys.
|
||||
Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize
|
||||
comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and
|
||||
'TPMT_SIGNATURE signature'. To verify the signature, the current policy
|
||||
digest is hashed with the hash algorithm written in 'signature', and then
|
||||
'signature' is verified with the hashed policy digest and 'pubkey'. Once
|
||||
TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the
|
||||
signed policy.
|
||||
|
||||
To create the key file with authorized policy, here are the pcr-oracle(*2)
|
||||
commands:
|
||||
|
||||
# Generate the RSA key and create the authorized policy file
|
||||
$ pcr-oracle \
|
||||
--rsa-generate-key \
|
||||
--private-key policy-key.pem \
|
||||
--auth authorized.policy \
|
||||
create-authorized-policy 0,2,4,7,9
|
||||
|
||||
# Seal the secret with the authorized policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--auth authorized.policy \
|
||||
--input disk-secret.txt \
|
||||
--output sealed.key \
|
||||
seal-secret
|
||||
|
||||
# Sign the predicted PCR policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--private-key policy-key.pem \
|
||||
--from eventlog \
|
||||
--stop-event "grub-file=grub.cfg" \
|
||||
--after \
|
||||
--input sealed.key \
|
||||
--output /boot/efi/efi/grub/sealed.tpm \
|
||||
sign 0,2,4,7,9
|
||||
|
||||
Then specify the key file and the key protector to grub.cfg in the EFI
|
||||
system partition:
|
||||
|
||||
tpm2_key_protector_init -a RSA --tpm2key=(hd0,gpt1)/efi/grub/sealed.tpm
|
||||
cryptomount -u <PART_UUID> -P tpm2
|
||||
|
||||
For any change in the boot components, just run the 'sign' command again
|
||||
to update the signature in sealed.tpm, and TPM can unseal the key file
|
||||
with the updated PCR policy.
|
||||
|
||||
(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
|
||||
(*2) https://github.com/okirch/pcr-oracle
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
.../commands/tpm2_key_protector/module.c | 70 +++++++++++++++++++
|
||||
1 file changed, 70 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/tpm2_key_protector/module.c b/grub-core/commands/tpm2_key_protector/module.c
|
||||
index 70d4d0df7..6b4b5d460 100644
|
||||
--- a/grub-core/commands/tpm2_key_protector/module.c
|
||||
+++ b/grub-core/commands/tpm2_key_protector/module.c
|
||||
@@ -618,6 +618,73 @@ tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffe
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION_t session, struct grub_tpm2_buffer *cmd_buf)
|
||||
+{
|
||||
+ TPM2B_PUBLIC_t pubkey;
|
||||
+ TPM2B_DIGEST_t policy_ref;
|
||||
+ TPMT_SIGNATURE_t signature;
|
||||
+ TPM2B_DIGEST_t pcr_policy;
|
||||
+ TPM2B_DIGEST_t pcr_policy_hash;
|
||||
+ TPMI_ALG_HASH_t sig_hash;
|
||||
+ TPMT_TK_VERIFIED_t verification_ticket;
|
||||
+ TPM_HANDLE_t pubkey_handle = 0;
|
||||
+ TPM2B_NAME_t pubname;
|
||||
+ TPM_RC_t rc;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_Tss2_MU_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
|
||||
+ grub_Tss2_MU_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
|
||||
+ grub_Tss2_MU_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
|
||||
+ if (cmd_buf->error != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to unmarshal the buffer for TPM2_PolicyAuthorize");
|
||||
+
|
||||
+ /* Retrieve Policy Digest */
|
||||
+ rc = grub_tpm2_policygetdigest (session, NULL, &pcr_policy, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).", rc);
|
||||
+
|
||||
+ /* Calculate the digest of the polcy for VerifySignature */
|
||||
+ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature);
|
||||
+ if (sig_hash == TPM_ALG_NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to get the hash algorithm of the signature");
|
||||
+
|
||||
+ rc = grub_tpm2_hash (NULL, (TPM2B_MAX_BUFFER_t *) &pcr_policy, sig_hash,
|
||||
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to create PCR policy hash (TPM2_Hash: 0x%x)", rc);
|
||||
+
|
||||
+ /* Load the public key */
|
||||
+ rc = grub_tpm2_loadexternal (NULL, NULL, &pubkey, TPM_RH_OWNER, &pubkey_handle, &pubname, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE, "failed to load public key (TPM2_LoadExternal: 0x%x)", rc);
|
||||
+
|
||||
+ /* Verify the signature against the public key and the policy digest */
|
||||
+ rc = grub_tpm2_verifysignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to verify signature (TPM2_VerifySignature: 0x%x)", rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* Authorize the signed policy with the public key and the verification ticket */
|
||||
+ rc = grub_tpm2_policyauthorize (session, NULL, &pcr_policy, &policy_ref, &pubname,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE, "failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)", rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+
|
||||
+ error:
|
||||
+ grub_tpm2_flushcontext (pubkey_handle);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t session)
|
||||
{
|
||||
@@ -636,6 +703,9 @@ tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION_t s
|
||||
case TPM_CC_PolicyPCR:
|
||||
err = tpm2_protector_policypcr (session, &buf);
|
||||
break;
|
||||
+ case TPM_CC_PolicyAuthorize:
|
||||
+ err = tpm2_protector_policyauthorize (session, &buf);
|
||||
+ break;
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown TPM Command: 0x%x", policy->cmd_code);
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,411 +0,0 @@
|
||||
From 439de947262b0d8d4a02ca5afb1ef4f15853962c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 9 Dec 2016 15:40:29 -0500
|
||||
Subject: [PATCH 2/9] Add BLS support to grub-mkconfig
|
||||
|
||||
GRUB now has BootLoaderSpec support, the user can choose to use this by
|
||||
setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup,
|
||||
the boot menu entries are not added to the grub.cfg, instead BLS config
|
||||
files are parsed by blscfg command and the entries created dynamically.
|
||||
|
||||
A 10_linux_bls grub.d snippet to generate menu entries from BLS files
|
||||
is also added that can be used on platforms where the bootloader doesn't
|
||||
have BLS support and only can parse a normal grub configuration file.
|
||||
|
||||
Portions of the 10_linux_bls were taken from the ostree-grub-generator
|
||||
script that's included in the OSTree project.
|
||||
|
||||
Fixes to support multi-devices and generate a BLS section even if no
|
||||
kernels are found in the boot directory were proposed by Yclept Nemo
|
||||
and Tom Gundersen respectively.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
[javierm: remove outdated URL for BLS document]
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
[iwienand@redhat.com: skip machine ID check when updating entries]
|
||||
Signed-off-by: Ian Wienand <iwienand@redhat.com>
|
||||
[rharwood: commit message composits, drop man pages]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
util/grub-mkconfig.in | 9 +-
|
||||
util/grub-mkconfig_lib.in | 22 +++-
|
||||
util/grub.d/10_linux.in | 244 +++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 269 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index cf5b79342..7af15df94 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -49,6 +49,8 @@ grub_script_check="${bindir}/@grub_script_check@"
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR="@localedir@"
|
||||
|
||||
+export GRUB_GRUBENV_UPDATE="yes"
|
||||
+
|
||||
. "${pkgdatadir}/grub-mkconfig_lib"
|
||||
|
||||
# Usage: usage
|
||||
@@ -58,6 +60,7 @@ usage () {
|
||||
gettext "Generate a grub config file"; echo
|
||||
echo
|
||||
print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")"
|
||||
+ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")"
|
||||
print_option_help "-h, --help" "$(gettext "print this message and exit")"
|
||||
print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
||||
echo
|
||||
@@ -93,6 +96,9 @@ do
|
||||
--output=*)
|
||||
grub_cfg=`echo "$option" | sed 's/--output=//'`
|
||||
;;
|
||||
+ --no-grubenv-update)
|
||||
+ GRUB_GRUBENV_UPDATE="no"
|
||||
+ ;;
|
||||
-*)
|
||||
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
|
||||
usage
|
||||
@@ -300,7 +306,8 @@ export GRUB_DEFAULT \
|
||||
GRUB_DISABLE_SUBMENU \
|
||||
SUSE_BTRFS_SNAPSHOT_BOOTING \
|
||||
SUSE_CMDLINE_XENEFI \
|
||||
- SUSE_REMOVE_LINUX_ROOT_PARAM
|
||||
+ SUSE_REMOVE_LINUX_ROOT_PARAM \
|
||||
+ GRUB_ENABLE_BLSCFG
|
||||
|
||||
if test "x${grub_cfg}" != "x"; then
|
||||
rm -f "${grub_cfg}.new"
|
||||
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
|
||||
index 22fb7668f..5db4337c6 100644
|
||||
--- a/util/grub-mkconfig_lib.in
|
||||
+++ b/util/grub-mkconfig_lib.in
|
||||
@@ -30,6 +30,9 @@ fi
|
||||
if test "x$grub_file" = x; then
|
||||
grub_file="${bindir}/@grub_file@"
|
||||
fi
|
||||
+if test "x$grub_editenv" = x; then
|
||||
+ grub_editenv="${bindir}/@grub_editenv@"
|
||||
+fi
|
||||
if test "x$grub_mkrelpath" = x; then
|
||||
grub_mkrelpath="${bindir}/@grub_mkrelpath@"
|
||||
fi
|
||||
@@ -123,8 +126,19 @@ EOF
|
||||
fi
|
||||
}
|
||||
|
||||
+prepare_grub_to_access_device_with_variable ()
|
||||
+{
|
||||
+ device_variable="$1"
|
||||
+ shift
|
||||
+ prepare_grub_to_access_device "$@"
|
||||
+ unset "device_variable"
|
||||
+}
|
||||
+
|
||||
prepare_grub_to_access_device ()
|
||||
{
|
||||
+ if [ -z "$device_variable" ]; then
|
||||
+ device_variable="root"
|
||||
+ fi
|
||||
old_ifs="$IFS"
|
||||
IFS='
|
||||
'
|
||||
@@ -159,18 +173,18 @@ prepare_grub_to_access_device ()
|
||||
# otherwise set root as per value in device.map.
|
||||
fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
|
||||
if [ "x$fs_hint" != x ]; then
|
||||
- echo "set root='$fs_hint'"
|
||||
+ echo "set ${device_variable}='$fs_hint'"
|
||||
fi
|
||||
if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then
|
||||
hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints=
|
||||
if [ "x$hints" != x ]; then
|
||||
echo "if [ x\$feature_platform_search_hint = xy ]; then"
|
||||
- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
|
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}"
|
||||
echo "else"
|
||||
- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}"
|
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
|
||||
echo "fi"
|
||||
else
|
||||
- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}"
|
||||
+ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
|
||||
fi
|
||||
fi
|
||||
IFS="$old_ifs"
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 5531239eb..49eccbeaf 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -91,6 +91,244 @@ if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
|
||||
LINUX_ROOT_DEVICE=""
|
||||
fi
|
||||
|
||||
+populate_header_warn()
|
||||
+{
|
||||
+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
+ bls_parser="10_linux script"
|
||||
+else
|
||||
+ bls_parser="blscfg command"
|
||||
+fi
|
||||
+cat <<EOF
|
||||
+
|
||||
+# This section was generated by a script. Do not modify the generated file - all changes
|
||||
+# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
|
||||
+#
|
||||
+# The $bls_parser parses the BootLoaderSpec files stored in /boot/loader/entries and
|
||||
+# populates the boot menu. Please refer to the Boot Loader Specification documentation
|
||||
+# for the files format: https://systemd.io/BOOT_LOADER_SPECIFICATION/.
|
||||
+
|
||||
+EOF
|
||||
+}
|
||||
+
|
||||
+read_config()
|
||||
+{
|
||||
+ config_file=${1}
|
||||
+ title=""
|
||||
+ initrd=""
|
||||
+ options=""
|
||||
+ linux=""
|
||||
+ grub_arg=""
|
||||
+
|
||||
+ while read -r line
|
||||
+ do
|
||||
+ record=$(echo ${line} | cut -f 1 -d ' ')
|
||||
+ value=$(echo ${line} | cut -s -f2- -d ' ')
|
||||
+ case "${record}" in
|
||||
+ "title")
|
||||
+ title=${value}
|
||||
+ ;;
|
||||
+ "initrd")
|
||||
+ initrd=${value}
|
||||
+ ;;
|
||||
+ "linux")
|
||||
+ linux=${value}
|
||||
+ ;;
|
||||
+ "options")
|
||||
+ options=${value}
|
||||
+ ;;
|
||||
+ "grub_arg")
|
||||
+ grub_arg=${value}
|
||||
+ ;;
|
||||
+ esac
|
||||
+ done < ${config_file}
|
||||
+}
|
||||
+
|
||||
+blsdir="/boot/loader/entries"
|
||||
+
|
||||
+get_sorted_bls()
|
||||
+{
|
||||
+ if ! [ -d "${blsdir}" ]; then
|
||||
+ return
|
||||
+ fi
|
||||
+
|
||||
+ local IFS=$'\n'
|
||||
+
|
||||
+ files=($(for bls in ${blsdir}/*.conf; do
|
||||
+ if ! [[ -e "${bls}" ]] ; then
|
||||
+ continue
|
||||
+ fi
|
||||
+ bls="${bls%.conf}"
|
||||
+ bls="${bls##*/}"
|
||||
+ echo "${bls}"
|
||||
+ done | ${kernel_sort} 2>/dev/null | tac)) || :
|
||||
+
|
||||
+ echo "${files[@]}"
|
||||
+}
|
||||
+
|
||||
+update_bls_cmdline()
|
||||
+{
|
||||
+ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+ local -a files=($(get_sorted_bls))
|
||||
+
|
||||
+ for bls in "${files[@]}"; do
|
||||
+ local options="${cmdline}"
|
||||
+ if [ -z "${bls##*debug*}" ]; then
|
||||
+ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}"
|
||||
+ fi
|
||||
+ options="$(echo "${options}" | sed -e 's/\//\\\//g')"
|
||||
+ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf"
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+populate_menu()
|
||||
+{
|
||||
+ local -a files=($(get_sorted_bls))
|
||||
+
|
||||
+ gettext_printf "Generating boot entries from BLS files...\n" >&2
|
||||
+
|
||||
+ for bls in "${files[@]}"; do
|
||||
+ read_config "${blsdir}/${bls}.conf"
|
||||
+
|
||||
+ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n"
|
||||
+ menu="${menu}\t linux ${linux} ${options}\n"
|
||||
+ if [ -n "${initrd}" ] ; then
|
||||
+ menu="${menu}\t initrd ${boot_prefix}${initrd}\n"
|
||||
+ fi
|
||||
+ menu="${menu}}\n\n"
|
||||
+ done
|
||||
+ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation
|
||||
+ printf "$menu"
|
||||
+}
|
||||
+
|
||||
+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed.
|
||||
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then
|
||||
+ GRUB_ENABLE_BLSCFG="true"
|
||||
+fi
|
||||
+
|
||||
+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
|
||||
+ if [ x$dirname = x/ ]; then
|
||||
+ if [ -z "${prepare_root_cache}" ]; then
|
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE}
|
||||
+ fi
|
||||
+ else
|
||||
+ if [ -z "${prepare_boot_cache}" ]; then
|
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT}
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ if [ -d /sys/firmware/efi ]; then
|
||||
+ bootefi_device="`${grub_probe} --target=device /boot/efi/`"
|
||||
+ prepare_grub_to_access_device_with_variable boot ${bootefi_device}
|
||||
+ else
|
||||
+ boot_device="`${grub_probe} --target=device /boot/`"
|
||||
+ prepare_grub_to_access_device_with_variable boot ${boot_device}
|
||||
+ fi
|
||||
+
|
||||
+ arch="$(uname -m)"
|
||||
+ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then
|
||||
+
|
||||
+ BLS_POPULATE_MENU="true"
|
||||
+ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot"
|
||||
+
|
||||
+ if test -e ${petitboot_path}; then
|
||||
+ read -r -d '' petitboot_version < ${petitboot_path}
|
||||
+ petitboot_version="$(echo ${petitboot_version//v})"
|
||||
+
|
||||
+ if test -n ${petitboot_version}; then
|
||||
+ major_version="$(echo ${petitboot_version} | cut -d . -f1)"
|
||||
+ minor_version="$(echo ${petitboot_version} | cut -d . -f2)"
|
||||
+
|
||||
+ re='^[0-9]+$'
|
||||
+ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] &&
|
||||
+ ([[ ${major_version} -gt 1 ]] ||
|
||||
+ [[ ${major_version} -eq 1 &&
|
||||
+ ${minor_version} -ge 8 ]]); then
|
||||
+ BLS_POPULATE_MENU="false"
|
||||
+ fi
|
||||
+ fi
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ populate_header_warn
|
||||
+
|
||||
+ cat << EOF
|
||||
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
|
||||
+# entries populated from BootLoaderSpec files that use this variable work correctly even
|
||||
+# without a grubenv file, define a fallback kernelopts variable if this has not been set.
|
||||
+#
|
||||
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
|
||||
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
|
||||
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
|
||||
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
|
||||
+if [ -z "\${kernelopts}" ]; then
|
||||
+ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+fi
|
||||
+EOF
|
||||
+
|
||||
+ update_bls_cmdline
|
||||
+
|
||||
+ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
+ populate_menu
|
||||
+ else
|
||||
+ cat << EOF
|
||||
+
|
||||
+insmod blscfg
|
||||
+blscfg
|
||||
+EOF
|
||||
+ fi
|
||||
+
|
||||
+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
|
||||
+ blsdir="/boot/loader/entries"
|
||||
+ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})"
|
||||
+ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then
|
||||
+ blsdir=$(make_system_path_relative_to_its_root "${blsdir}")
|
||||
+ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then
|
||||
+ ${grub_editenv} - set blsdir="${blsdir}"
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then
|
||||
+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_DEFAULT_DTB}" ]; then
|
||||
+ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_SAVEDEFAULT}" ]; then
|
||||
+ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}"
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+mktitle ()
|
||||
+{
|
||||
+ local title_type
|
||||
+ local version
|
||||
+ local OS_NAME
|
||||
+ local OS_VERS
|
||||
+
|
||||
+ title_type=$1 && shift
|
||||
+ version=$1 && shift
|
||||
+
|
||||
+ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})"
|
||||
+ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})"
|
||||
+
|
||||
+ case $title_type in
|
||||
+ recovery)
|
||||
+ title=$(printf '%s (%s) %s (recovery mode)' \
|
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
+ ;;
|
||||
+ *)
|
||||
+ title=$(printf '%s (%s) %s' \
|
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
+ ;;
|
||||
+ esac
|
||||
+ echo -n ${title}
|
||||
+}
|
||||
+
|
||||
title_correction_code=
|
||||
|
||||
hotkey=1
|
||||
@@ -124,6 +362,7 @@ linux_entry ()
|
||||
if [ -z "$boot_device_id" ]; then
|
||||
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
|
||||
fi
|
||||
+
|
||||
if [ x$type != xsimple ] ; then
|
||||
case $type in
|
||||
recovery)
|
||||
@@ -298,6 +537,7 @@ fi
|
||||
is_top_level=true
|
||||
for linux in ${reverse_sorted_list}; do
|
||||
gettext_printf "Found linux image: %s\n" "$linux" >&2
|
||||
+
|
||||
basename=`basename $linux`
|
||||
dirname=`dirname $linux`
|
||||
rel_dirname=`make_system_path_relative_to_its_root $dirname`
|
||||
@@ -348,7 +588,9 @@ for linux in ${reverse_sorted_list}; do
|
||||
for i in ${initrd}; do
|
||||
initrd_display="${initrd_display} ${dirname}/${i}"
|
||||
done
|
||||
- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
|
||||
+ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
|
||||
+ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
|
||||
+ fi
|
||||
fi
|
||||
|
||||
config=
|
||||
--
|
||||
2.44.0
|
||||
|
290
0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
Normal file
290
0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch
Normal file
@ -0,0 +1,290 @@
|
||||
From af8b106667aa2ca7a7613e10d8746959e182f8f1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 29 Aug 2024 13:27:30 +0800
|
||||
Subject: [PATCH 2/2] Requiring authentication after tpm unlock for CLI access
|
||||
|
||||
GRUB may use TPM to verify the integrity of boot components, and the
|
||||
result can determine whether a previously sealed key can be released. If
|
||||
everything checks out, showing nothing has been tampered with, the key
|
||||
is released, and grub unlocks the encrypted root partition for the next
|
||||
stage of booting.
|
||||
|
||||
However, the liberal command line interface (CLI) can be misused by
|
||||
anyone in this case to access files in the encrypted partition one way
|
||||
or another. Despite efforts to keep the CLI secure by preventing utility
|
||||
command output from leaking file content, many techniques in the wild
|
||||
could still be used to exploit the CLI, enabling attacks or learning
|
||||
methods to attack. It's nearly impossible to account for all scenarios
|
||||
where a hack could be applied.
|
||||
|
||||
Therefore, to mitigate potential misuse of the CLI after the root device
|
||||
has been successfully unlocked via TPM, the user should be required to
|
||||
authenticate using the LUKS password. This added layer of security
|
||||
ensures that only authorized users can access the CLI, reducing the risk
|
||||
of exploitation or unauthorized access to the encrypted partition.
|
||||
|
||||
Fixes: CVE-2024-49504
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 80 +++++++++++++++++++++++++++++++++++
|
||||
grub-core/kern/main.c | 12 ++++++
|
||||
grub-core/normal/auth.c | 30 +++++++++++++
|
||||
grub-core/normal/main.c | 4 ++
|
||||
grub-core/normal/menu_entry.c | 4 ++
|
||||
include/grub/auth.h | 1 +
|
||||
include/grub/cryptodisk.h | 3 ++
|
||||
include/grub/misc.h | 2 +
|
||||
8 files changed, 136 insertions(+)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index babc94868..77bc782fd 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1188,6 +1188,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
goto error;
|
||||
#ifndef GRUB_UTIL
|
||||
is_tpmkey = 1;
|
||||
+ grub_cli_set_auth_needed ();
|
||||
#endif
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -1706,6 +1707,85 @@ luks_script_get (grub_size_t *sz)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t
|
||||
+grub_cryptodisk_challenge_password (void)
|
||||
+{
|
||||
+ grub_cryptodisk_t cr_dev;
|
||||
+
|
||||
+ for (cr_dev = cryptodisk_list; cr_dev != NULL; cr_dev = cr_dev->next)
|
||||
+ {
|
||||
+ grub_cryptodisk_dev_t cr;
|
||||
+ grub_disk_t source = NULL;
|
||||
+ grub_err_t ret = GRUB_ERR_NONE;
|
||||
+ grub_cryptodisk_t dev = NULL;
|
||||
+ char *part = NULL;
|
||||
+ struct grub_cryptomount_args cargs = {0};
|
||||
+
|
||||
+ cargs.check_boot = 0;
|
||||
+ cargs.search_uuid = cr_dev->uuid;
|
||||
+
|
||||
+ source = grub_disk_open (cr_dev->source);
|
||||
+
|
||||
+ if (source == NULL)
|
||||
+ goto error_out;
|
||||
+
|
||||
+ FOR_CRYPTODISK_DEVS (cr)
|
||||
+ {
|
||||
+ dev = cr->scan (source, &cargs);
|
||||
+ if (grub_errno)
|
||||
+ goto error_out;
|
||||
+ if (!dev)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (dev == NULL)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_MODULE,
|
||||
+ "no cryptodisk module can handle this device");
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), cr_dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ cargs.key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
+ if (cargs.key_data == NULL)
|
||||
+ goto error_out;
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs.key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+ cargs.key_len = grub_strlen ((char *) cargs.key_data);
|
||||
+ ret = cr->recover_key (source, dev, &cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error_out;
|
||||
+
|
||||
+ error_out:
|
||||
+ if (source)
|
||||
+ grub_disk_close (source);
|
||||
+ if (dev)
|
||||
+ cryptodisk_close (dev);
|
||||
+ if (cargs.key_data)
|
||||
+ {
|
||||
+ grub_memset (cargs.key_data, 0, cargs.key_len);
|
||||
+ grub_free (cargs.key_data);
|
||||
+ }
|
||||
+
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+#endif /* GRUB_MACHINE_EFI */
|
||||
+
|
||||
struct grub_procfs_entry luks_script =
|
||||
{
|
||||
.name = "luks_script",
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 07b6940d2..ef3b3756d 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#endif
|
||||
|
||||
static bool cli_disabled = false;
|
||||
+static bool cli_need_auth = false;
|
||||
|
||||
grub_addr_t
|
||||
grub_modules_get_end (void)
|
||||
@@ -246,6 +247,17 @@ grub_is_cli_disabled (void)
|
||||
return cli_disabled;
|
||||
}
|
||||
|
||||
+bool
|
||||
+grub_is_cli_need_auth (void)
|
||||
+{
|
||||
+ return cli_need_auth;
|
||||
+}
|
||||