Sync from SUSE:SLFO:Main grub2 revision 63018e250eec224553909fb27623e281
This commit is contained in:
parent
a1d205fd6c
commit
5668489852
188
0001-Streamline-BLS-and-improve-PCR-stability.patch
Normal file
188
0001-Streamline-BLS-and-improve-PCR-stability.patch
Normal file
@ -0,0 +1,188 @@
|
||||
From 8201e8e6fbb7ee992c430679705852ede91efcd6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 20 Aug 2024 12:14:35 +0800
|
||||
Subject: [PATCH] Streamline BLS and improve PCR stability
|
||||
|
||||
Introduce an environment variable enable_blscfg to allow looking for and
|
||||
reading BLS (Boot Loader Specification) configurations right at startup,
|
||||
rather than relying on the traditional grub.cfg. The benefit of this
|
||||
approach is that it eliminates the layer of using an external grub.cfg
|
||||
to piggyback the blscfg command. This change reduces the complexity of
|
||||
managing command sequences, which would otherwise complicate the PCR
|
||||
(Platform Configuration Register) policy. Managing a sequence of
|
||||
commands can be difficult to maintain and ensure they remain in order
|
||||
indefinitely.
|
||||
|
||||
Along the way, we can remove the external grub.cfg and have everything
|
||||
embedded in memdisk and early embedded configurations. This approach
|
||||
significantly improves the overall stability and makes it easier to
|
||||
maintain a consistent and predictable PCR outcome.
|
||||
|
||||
The grubenv in the EFI boot directory can be used to override default
|
||||
settings in the grubbls image, allowing for continued customization.
|
||||
|
||||
By introducing grubbls.efi for managing BLS configuration integration,
|
||||
all necessary modules are built-in, and sensible default settings are
|
||||
applied. This allows us to remove the following hardcoded command
|
||||
sequences in blscfg:
|
||||
|
||||
load_video
|
||||
set gfxpalyload=keep
|
||||
insmod gzio
|
||||
|
||||
Since these are now part of the EFI image, this change effectively
|
||||
simplifies the TPM event log, making it easier to handle with tools like
|
||||
pcr-oracle or systemd-pcrlock.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 4 ++
|
||||
grub-core/normal/main.c | 82 +++++++++++++++++++++++++++++++++++++
|
||||
include/grub/parser.h | 4 ++
|
||||
3 files changed, 90 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index cbe2a289e..e08f35817 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -953,10 +953,14 @@ static void create_entry (struct bls_entry *entry)
|
||||
|
||||
const char *sdval = grub_env_get("save_default");
|
||||
bool savedefault = ((NULL != sdval) && (grub_strcmp(sdval, "true") == 0));
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ src = grub_xasprintf ("%slinux %s%s%s%s\n"
|
||||
+#else
|
||||
src = grub_xasprintf ("%sload_video\n"
|
||||
"set gfxpayload=keep\n"
|
||||
"insmod gzio\n"
|
||||
"linux %s%s%s%s\n"
|
||||
+#endif
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 03631f07a..8e58ced67 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -113,6 +113,65 @@ read_config_file_getline (char **line, int cont __attribute__ ((unused)),
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+
|
||||
+static void
|
||||
+read_envblk_from_cmdpath (void)
|
||||
+{
|
||||
+ const char *cmdpath;
|
||||
+ char *envfile = NULL;
|
||||
+ int found = 0;
|
||||
+
|
||||
+ cmdpath = grub_env_get ("cmdpath");
|
||||
+
|
||||
+ if (cmdpath)
|
||||
+ envfile = grub_xasprintf ("%s/grubenv", cmdpath);
|
||||
+
|
||||
+ if (envfile)
|
||||
+ {
|
||||
+ grub_file_t file;
|
||||
+
|
||||
+ file = grub_file_open (envfile, GRUB_FILE_TYPE_FS_SEARCH
|
||||
+ | GRUB_FILE_TYPE_NO_DECOMPRESS | GRUB_FILE_TYPE_SKIP_SIGNATURE);
|
||||
+ if (file)
|
||||
+ {
|
||||
+ found = 1;
|
||||
+ grub_file_close (file);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (found)
|
||||
+ {
|
||||
+ char *cfg;
|
||||
+
|
||||
+ cfg = grub_xasprintf ("load_env -f %s\n", envfile);
|
||||
+ grub_parser_execute ((char *)cfg);
|
||||
+ grub_free (cfg);
|
||||
+ }
|
||||
+
|
||||
+ grub_free (envfile);
|
||||
+}
|
||||
+
|
||||
+static grub_menu_t
|
||||
+read_blscfg (void)
|
||||
+{
|
||||
+ grub_menu_t newmenu;
|
||||
+ newmenu = grub_env_get_menu ();
|
||||
+ if (! newmenu)
|
||||
+ {
|
||||
+ newmenu = grub_zalloc (sizeof (*newmenu));
|
||||
+ if (! newmenu)
|
||||
+ return 0;
|
||||
+
|
||||
+ grub_env_set_menu (newmenu);
|
||||
+ }
|
||||
+
|
||||
+ grub_parser_execute ((char *)"blscfg\n");
|
||||
+ return newmenu;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static grub_menu_t
|
||||
read_config_file (const char *config)
|
||||
{
|
||||
@@ -282,6 +341,26 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executing config file");
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ const char *val;
|
||||
+
|
||||
+ val = grub_env_get ("enable_blscfg");
|
||||
+ if (val && (val[0] == '1' || val[0] == 'y'))
|
||||
+ read_envblk_from_cmdpath ();
|
||||
+
|
||||
+ /* Above would be used to override enable_blscfg, so verify again */
|
||||
+ val = grub_env_get ("enable_blscfg");
|
||||
+ if (val && (val[0] == '1' || val[0] == 'y'))
|
||||
+ {
|
||||
+ menu = read_blscfg ();
|
||||
+ /* Ignore any error. */
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ /* unset to let configfile and source commands continue to work */
|
||||
+ grub_env_unset ("enable_blscfg");
|
||||
+ goto check_batch;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (config)
|
||||
{
|
||||
menu = read_config_file (config);
|
||||
@@ -307,6 +386,9 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executed config file");
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ check_batch:
|
||||
+#endif
|
||||
if (! batch)
|
||||
{
|
||||
if (menu && menu->size)
|
||||
diff --git a/include/grub/parser.h b/include/grub/parser.h
|
||||
index 64f9f5cc2..9d702571a 100644
|
||||
--- a/include/grub/parser.h
|
||||
+++ b/include/grub/parser.h
|
||||
@@ -86,7 +86,11 @@ struct grub_parser
|
||||
};
|
||||
typedef struct grub_parser *grub_parser_t;
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t EXPORT_FUNC (grub_parser_execute) (char *source);
|
||||
+#else
|
||||
grub_err_t grub_parser_execute (char *source);
|
||||
+#endif
|
||||
|
||||
grub_err_t
|
||||
grub_rescue_parse_line (char *line,
|
||||
--
|
||||
2.46.0
|
||||
|
82
0001-bli-Fix-crash-in-get_part_uuid.patch
Normal file
82
0001-bli-Fix-crash-in-get_part_uuid.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From 552a2de0642bb95dd38fcdb7894ea7e07171975e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 15 Jul 2024 11:43:07 +0800
|
||||
Subject: [PATCH] bli: Fix crash in get_part_uuid
|
||||
|
||||
The get_part_uuid() function made an assumption that the target grub
|
||||
device is a partition device and accessed device->disk->partition
|
||||
without checking for NULL. There are four situations where this
|
||||
assumption is problematic:
|
||||
|
||||
1. The device is a net device instead of a disk.
|
||||
2. The device is an abstraction device, like LVM, RAID, or CRYPTO, which
|
||||
is mostly logical "disk" ((lvmid/<UUID>) and so on).
|
||||
3. Firmware RAID may present the ESP to grub as an EFI disk (hd0) device
|
||||
if it is contained within a Linux software RAID.
|
||||
4. When booting from a cdrom, the ESP is a vfat image indexed by the El
|
||||
Torito boot catalog. The boot device is set to (cd0), corresponding
|
||||
to the cdrom image mounted as an iso9660 filesystem.
|
||||
|
||||
As a result, get_part_uuid() could lead to a NULL pointer dereference
|
||||
and trigger a synchronous exception during boot if the ESP falls into
|
||||
one of these categories. This patch fixes the problem by adding the
|
||||
necessary checks to handle cases where the ESP is not a partition
|
||||
device.
|
||||
|
||||
Additionally, to avoid disrupting the boot process, this patch relaxes
|
||||
the severity of the errors in this context to non-critical. Errors will
|
||||
be logged, but they will not prevent the boot process from continuing.
|
||||
|
||||
Fixes: e0fa7dc84 (bli: Add a module for the Boot Loader Interface)
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Reviewed-By: Oliver Steffen <osteffen@redhat.com>
|
||||
---
|
||||
grub-core/commands/bli.c | 20 +++++++++++++++++++-
|
||||
1 file changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
|
||||
index e0d8a54f7..298c5f70a 100644
|
||||
--- a/grub-core/commands/bli.c
|
||||
+++ b/grub-core/commands/bli.c
|
||||
@@ -48,6 +48,22 @@ get_part_uuid (const char *device_name, char **part_uuid)
|
||||
if (device == NULL)
|
||||
return grub_error (grub_errno, N_("cannot open device: %s"), device_name);
|
||||
|
||||
+ if (device->disk == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name);
|
||||
+ *part_uuid = NULL;
|
||||
+ grub_device_close (device);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ if (device->disk->partition == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name);
|
||||
+ *part_uuid = NULL;
|
||||
+ grub_device_close (device);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
disk = grub_disk_open (device->disk->name);
|
||||
if (disk == NULL)
|
||||
{
|
||||
@@ -99,7 +115,7 @@ set_loader_device_part_uuid (void)
|
||||
|
||||
status = get_part_uuid (device_name, &part_uuid);
|
||||
|
||||
- if (status == GRUB_ERR_NONE)
|
||||
+ if (status == GRUB_ERR_NONE && part_uuid)
|
||||
status = grub_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid,
|
||||
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
@@ -117,4 +133,6 @@ GRUB_MOD_INIT (bli)
|
||||
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
set_loader_device_part_uuid ();
|
||||
+ /* No error here is critical, other than being logged */
|
||||
+ grub_print_error ();
|
||||
}
|
||||
--
|
||||
2.46.0
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 8b9234c7e482edd49a9b3377da8e48fbd54aab28 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 24 Sep 2024 18:59:34 +0800
|
||||
Subject: [PATCH] efinet: Skip virtual VLAN devices during card enumeration
|
||||
|
||||
Similar to the fix in commit "c52ae4057 efinet: skip virtual IPv4 and
|
||||
IPv6 devices during card enumeration", the UEFI PXE driver creates
|
||||
additional VLAN child devices when a VLAN ID is configured on a network
|
||||
interface associated with a physical NIC. These virtual VLAN devices
|
||||
must be skipped during card enumeration to ensure that the subsequent
|
||||
SNP exclusive open operation targets the correct physical card
|
||||
instances, otherwise packet transfer would fail.
|
||||
|
||||
Example device path with VLAN nodes:
|
||||
|
||||
/MAC(123456789ABC,0x1)/Vlan(20)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/net/drivers/efi/efinet.c | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
|
||||
index 720b5d0e1..3d0bf34fa 100644
|
||||
--- a/grub-core/net/drivers/efi/efinet.c
|
||||
+++ b/grub-core/net/drivers/efi/efinet.c
|
||||
@@ -280,7 +280,8 @@ grub_efinet_findcards (void)
|
||||
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)
|
||||
&& parent
|
||||
&& GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
- && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
|
||||
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE
|
||||
+ || GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE))
|
||||
continue;
|
||||
|
||||
net = grub_efi_open_protocol (*handle, &net_io_guid,
|
||||
@@ -810,6 +811,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
|
||||
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
dup_ldp->length = sizeof (*dup_ldp);
|
||||
+
|
||||
+ dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE)
|
||||
+ {
|
||||
+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
+ dup_ldp->length = sizeof (*dup_ldp);
|
||||
+ }
|
||||
+
|
||||
match = grub_efi_compare_device_paths (dup_dp, cdp) == 0;
|
||||
grub_free (dup_dp);
|
||||
if (!match)
|
||||
--
|
||||
2.46.1
|
||||
|
48
0001-fix-grub-screen-filled-with-post-screen-artifects.patch
Normal file
48
0001-fix-grub-screen-filled-with-post-screen-artifects.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 44f3c7978a8ac5cc94a5c885ac9e983ba2980f5e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 29 May 2024 12:32:32 +0800
|
||||
Subject: [PATCH] fix grub screen filled with post screen artifects
|
||||
|
||||
---
|
||||
grub-core/normal/menu.c | 7 ++++---
|
||||
grub-core/term/efi/console.c | 2 +-
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 1df2638d7..b11b28e0d 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -975,13 +975,14 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||
if (! e)
|
||||
continue; /* Menu is empty. */
|
||||
|
||||
- grub_cls ();
|
||||
-
|
||||
if (auto_boot)
|
||||
grub_menu_execute_with_fallback (menu, e, autobooted,
|
||||
&execution_callback, ¬ify_boot);
|
||||
else
|
||||
- grub_menu_execute_entry (e, 0);
|
||||
+ {
|
||||
+ grub_cls ();
|
||||
+ grub_menu_execute_entry (e, 0);
|
||||
+ }
|
||||
if (autobooted)
|
||||
break;
|
||||
}
|
||||
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
|
||||
index bb587f39d..258b52737 100644
|
||||
--- a/grub-core/term/efi/console.c
|
||||
+++ b/grub-core/term/efi/console.c
|
||||
@@ -432,7 +432,7 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
grub_efi_int32_t orig_attr;
|
||||
|
||||
- if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE)
|
||||
+ if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE)
|
||||
return;
|
||||
|
||||
o = grub_efi_system_table->con_out;
|
||||
--
|
||||
2.45.1
|
||||
|
@ -1,44 +0,0 @@
|
||||
From a59b58f6ae327a8f6949991cb5531db01e1ba14d Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
Date: Tue, 7 Feb 2023 15:10:15 -0500
|
||||
Subject: [PATCH] grub2: Can't setup a default boot device correctly on nvme
|
||||
device in Beta3
|
||||
|
||||
The patch in Bug 200486 - SUSE1205666 - SLES15SP5 Beta1: Setup multiple dev path
|
||||
for a nvmf boot device in grub2 caused the issue. That patch didn't consider
|
||||
nvme devices carefully.
|
||||
|
||||
The new patch will check "nvme-of" instead of "nvme" to call
|
||||
build_multi_boot_device().
|
||||
|
||||
Signed-off-by: Wen Xiong<wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/unix/platform.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index db8fa4b95..fb47c0ffa 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -288,11 +288,15 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
- else if (grub_strstr(install_device, "nvme"))
|
||||
- boot_device = build_multi_boot_device(install_device);
|
||||
- else
|
||||
+ else {
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
+ if (grub_strstr(boot_device, "nvme-of")) {
|
||||
+ free (boot_device);
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
|
||||
boot_device, NULL }))
|
||||
{
|
||||
--
|
||||
2.39.1
|
||||
|
@ -1,164 +0,0 @@
|
||||
From 3e77c5494fd06f430588ae9c304fea370439d531 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <Wen Xiong>
|
||||
Date: Thu, 15 Dec 2022 21:33:41 -0500
|
||||
Subject: [PATCH] grub2: Set multiple device path for a nvmf boot device
|
||||
|
||||
nvmf support native multipath(ANA) by default.
|
||||
The patch added the support for setting multiple
|
||||
device path for a nvmf boot device.
|
||||
|
||||
localhost:~ grub2-install -v /dev/nvme1n1p1
|
||||
...
|
||||
...
|
||||
...
|
||||
grub2-install: info: executing nvsetenv boot-device /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec.
|
||||
Installation finished. No error reported.
|
||||
|
||||
localhost:~ # bootlist -m normal -o
|
||||
nvme7n1
|
||||
nvme5n1
|
||||
nvme1n1
|
||||
nvme4n1
|
||||
|
||||
localhost:~ # bootlist -m normal -r
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
|
||||
Signed-off-by: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 ++---
|
||||
grub-core/osdep/unix/platform.c | 48 +++++++++++++++++++++++++++++++++
|
||||
include/grub/util/install.h | 3 +++
|
||||
include/grub/util/ofpath.h | 9 +++++++
|
||||
4 files changed, 63 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -209,7 +209,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@
|
||||
return out;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -535,7 +535,7 @@
|
||||
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
nvme_get_syspath(const char *nvmedev)
|
||||
{
|
||||
char *sysfs_path, *controller_node;
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <grub/util/install.h>
|
||||
+#include <grub/util/ofpath.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/misc.h>
|
||||
@@ -131,6 +132,51 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device)
|
||||
+{
|
||||
+ char *sysfs_path;
|
||||
+ char *nvme_ns;
|
||||
+ unsigned int nsid;
|
||||
+ char *ptr;
|
||||
+ char *boot_device_string;
|
||||
+ struct dirent *ep;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ nvme_ns = strchr(install_device, 'n');
|
||||
+ nsid = of_path_get_nvme_nsid(nvme_ns);
|
||||
+ sysfs_path = nvme_get_syspath(nvme_ns);
|
||||
+ strcat(sysfs_path, "/device");
|
||||
+ sysfs_path = xrealpath(sysfs_path);
|
||||
+
|
||||
+ dp = opendir(sysfs_path);
|
||||
+ ptr = boot_device_string = xmalloc (1000);
|
||||
+
|
||||
+ /* We cannot have a boot list with more than five entries */
|
||||
+ while((ep = readdir(dp)) != NULL){
|
||||
+ char *nvme_device;
|
||||
+
|
||||
+ if (grub_strstr(ep->d_name, "nvme")) {
|
||||
+ nvme_device = xasprintf ("%s%s%x ",
|
||||
+ get_ofpathname(ep->d_name),"/namespace@", nsid);
|
||||
+ if ((strlen(boot_device_string) + strlen(nvme_device)) >= 200*5 - 1) {
|
||||
+ grub_util_warn (_("More than five entries cannot be specified in the bootlist"));
|
||||
+ free(nvme_device);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ strncpy(ptr, nvme_device, strlen(nvme_device));
|
||||
+ ptr += strlen(nvme_device);
|
||||
+ free(nvme_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *--ptr = '\0';
|
||||
+ closedir(dp);
|
||||
+
|
||||
+ return boot_device_string;
|
||||
+}
|
||||
+
|
||||
int
|
||||
grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efifile_path,
|
||||
@@ -242,6 +288,8 @@
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
+ else if (grub_strstr(install_device, "nvme"))
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
else
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -241,6 +241,9 @@
|
||||
const char *efi_distributor,
|
||||
const char *force_disk);
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device);
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath);
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -32,4 +32,13 @@
|
||||
|
||||
char* of_find_fc_host(char* host_wwpn);
|
||||
|
||||
+char* nvme_get_syspath(const char *nvmedev);
|
||||
+
|
||||
+char* block_device_get_sysfs_path_and_link(const char *devicenode);
|
||||
+
|
||||
+char* xrealpath (const char *in);
|
||||
+
|
||||
+unsigned int of_path_get_nvme_nsid(const char* devname);
|
||||
+
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
171
0001-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
171
0001-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
@ -0,0 +1,171 @@
|
||||
From 04e8509f04a4cd123bc9f290e60f582d57b2f258 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 27 Dec 2022 17:47:41 +0530
|
||||
Subject: [PATCH 1/8] ieee1275: Platform Keystore (PKS) Support
|
||||
|
||||
enhancing the infrastructure to enable the Platform Keystore (PKS) feature,
|
||||
which provides access to the SB VERSION, DB, and DBX secure boot variables
|
||||
from PKS.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/ieee1275.c | 117 +++++++++++++++++++++++++++++
|
||||
include/grub/ieee1275/ieee1275.h | 15 ++++
|
||||
2 files changed, 132 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c
|
||||
index 36ca2dbfc..8d0048844 100644
|
||||
--- a/grub-core/kern/ieee1275/ieee1275.c
|
||||
+++ b/grub-core/kern/ieee1275/ieee1275.c
|
||||
@@ -807,3 +807,120 @@ grub_ieee1275_get_block_size (grub_ieee1275_ihandle_t ihandle)
|
||||
|
||||
return args.size;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_test (const char *name, grub_ieee1275_cell_t *missing)
|
||||
+{
|
||||
+ struct test_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t name;
|
||||
+ grub_ieee1275_cell_t missing;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "test", 1, 1);
|
||||
+ args.name = (grub_ieee1275_cell_t) name;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.missing == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *missing = args.missing;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_max_object_size (grub_size_t *result)
|
||||
+{
|
||||
+ struct mos_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t size;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-max-object-size", 0, 1);
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.size == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *result = args.size;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies)
|
||||
+{
|
||||
+ struct pks_read_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t consumer;
|
||||
+ grub_ieee1275_cell_t label;
|
||||
+ grub_ieee1275_cell_t label_len;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t policies;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-object", 5, 3);
|
||||
+ args.consumer = (grub_ieee1275_cell_t) consumer;
|
||||
+ args.label = (grub_ieee1275_cell_t) label;
|
||||
+ args.label_len = (grub_ieee1275_cell_t) label_len;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+ *policies = args.policies;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len)
|
||||
+{
|
||||
+ struct pks_read_sbvar_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t sbvarflags;
|
||||
+ grub_ieee1275_cell_t sbvartype;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-sbvar", 4, 2);
|
||||
+ args.sbvarflags = (grub_ieee1275_cell_t) sbvarflags;
|
||||
+ args.sbvartype = (grub_ieee1275_cell_t) sbvartype;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
|
||||
index ea90d79f7..6d8dd9463 100644
|
||||
--- a/include/grub/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/ieee1275/ieee1275.h
|
||||
@@ -237,6 +237,21 @@ char *EXPORT_FUNC(grub_ieee1275_encode_uint4) (grub_ieee1275_ihandle_t ihandle,
|
||||
grub_size_t *size);
|
||||
int EXPORT_FUNC(grub_ieee1275_get_block_size) (grub_ieee1275_ihandle_t ihandle);
|
||||
|
||||
+int EXPORT_FUNC (grub_ieee1275_test) (const char *name,
|
||||
+ grub_ieee1275_cell_t *missing);
|
||||
+
|
||||
+// not exported: I don't want modules interacting with PKS.
|
||||
+int grub_ieee1275_pks_max_object_size (grub_size_t *result);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len);
|
||||
+
|
||||
grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
|
||||
void EXPORT_FUNC(grub_releasemap) (void);
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
170
0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
Normal file
170
0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 219b06c69d38a10349183002efb82bfec3b7ff5b Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Wed, 21 Aug 2024 14:13:05 +0530
|
||||
Subject: [PATCH] ieee1275: support added for multiple nvme bootpaths
|
||||
|
||||
This patch sets mupltiple NVMe boot-devices for more robust boot.
|
||||
Scenario where NVMe multipaths are available, all the available bootpaths (Max 5)
|
||||
will be added as the boot-device.
|
||||
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 +--
|
||||
grub-core/osdep/unix/platform.c | 65 ++++++++++++++++++++++++++++++++-
|
||||
include/grub/util/install.h | 3 ++
|
||||
include/grub/util/ofpath.h | 4 ++
|
||||
4 files changed, 74 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 51d331f06..55ed7ddf2 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -209,7 +209,7 @@ find_obppath (const char *sysfs_path_orig)
|
||||
}
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@ xrealpath (const char *in)
|
||||
return out;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -535,7 +535,7 @@ of_path_get_nvme_nsid(const char* devname)
|
||||
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
nvme_get_syspath(const char *nvmedev)
|
||||
{
|
||||
char *sysfs_path, *controller_node;
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index 1e2961e00..bafcc84d7 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
+#include <grub/util/ofpath.h>
|
||||
+#define BOOTDEV_BUFFER 1000
|
||||
|
||||
static char *
|
||||
get_ofpathname (const char *dev)
|
||||
@@ -203,6 +205,56 @@ grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+char *
|
||||
+add_multiple_nvme_bootdevices (const char *install_device)
|
||||
+{
|
||||
+ char *sysfs_path, *nvme_ns, *ptr;
|
||||
+ unsigned int nsid;
|
||||
+ char *multipath_boot;
|
||||
+ struct dirent *ep;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ /*
|
||||
+ * Extracting the namespace from install_device.
|
||||
+ * ex. install_device : /dev/nvme1n1
|
||||
+ */
|
||||
+ nvme_ns = grub_strstr (install_device, "nvme");
|
||||
+ nsid = of_path_get_nvme_nsid (nvme_ns);
|
||||
+ if (nsid == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ sysfs_path = nvme_get_syspath (nvme_ns);
|
||||
+ strcat (sysfs_path, "/subsystem");
|
||||
+ sysfs_path = xrealpath (sysfs_path);
|
||||
+ dp = opendir (sysfs_path);
|
||||
+ if (!dp)
|
||||
+ return NULL;
|
||||
+
|
||||
+ ptr = multipath_boot = xmalloc (BOOTDEV_BUFFER);
|
||||
+ while ((ep = readdir (dp)) != NULL)
|
||||
+ {
|
||||
+ char *path;
|
||||
+ if (grub_strstr (ep->d_name, "nvme"))
|
||||
+ {
|
||||
+ path = xasprintf ("%s%s%x ", get_ofpathname (ep->d_name), "/namespace@", nsid);
|
||||
+ if ((strlen (multipath_boot) + strlen (path)) > BOOTDEV_BUFFER)
|
||||
+ {
|
||||
+ grub_util_warn (_("Maximum five entries are allowed in the bootlist"));
|
||||
+ free (path);
|
||||
+ break;
|
||||
+ }
|
||||
+ strncpy (ptr, path, strlen (path));
|
||||
+ ptr += strlen (path);
|
||||
+ free (path);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *--ptr = '\0';
|
||||
+ closedir (dp);
|
||||
+
|
||||
+ return multipath_boot;
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath)
|
||||
@@ -242,8 +294,19 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
+ else if (grub_strstr (install_device, "nvme"))
|
||||
+ {
|
||||
+ boot_device = add_multiple_nvme_bootdevices (install_device);
|
||||
+ }
|
||||
else
|
||||
- boot_device = get_ofpathname (install_device);
|
||||
+ {
|
||||
+ boot_device = get_ofpathname (install_device);
|
||||
+ if (grub_strstr (boot_device, "nvme-of"))
|
||||
+ {
|
||||
+ free (boot_device);
|
||||
+ boot_device = add_multiple_nvme_bootdevices (install_device);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
|
||||
boot_device, NULL }))
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 563cf68e9..2fd102649 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -241,6 +241,9 @@ grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efi_distributor,
|
||||
const char *force_disk);
|
||||
|
||||
+char *
|
||||
+add_multiple_nvme_bootdevices (const char *install_device);
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath);
|
||||
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
|
||||
index a0ec30620..cc3c4bfbd 100644
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -31,5 +31,9 @@ void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root);
|
||||
void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
|
||||
|
||||
char* of_find_fc_host(char* host_wwpn);
|
||||
+char* nvme_get_syspath (const char *nvmedev);
|
||||
+char* block_device_get_sysfs_path_and_link (const char *devicenode);
|
||||
+char* xrealpath (const char *in);
|
||||
+unsigned int of_path_get_nvme_nsid (const char* devname);
|
||||
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
--
|
||||
2.47.0
|
||||
|
122
0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
Normal file
122
0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From ba65f46ffd2952a3f69d85a4534b1e55291f080c Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Thu, 23 May 2024 18:43:14 +0530
|
||||
Subject: [PATCH] kern/ieee1275/init: Add IEEE 1275 Radix support for KVM on
|
||||
Power
|
||||
|
||||
This patch adds support for Radix, Xive and Radix_gtse in Options
|
||||
vector5 which is required for KVM LPARs. KVM LPARs ONLY support
|
||||
Radix and not the Hash. Not enabling Radix on any PowerVM KVM LPARs
|
||||
will result in boot failure.
|
||||
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 63 +++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 62 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index bb800b275..8e08e5dd5 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -115,6 +115,16 @@ grub_addr_t grub_ieee1275_original_stack;
|
||||
#define DRC_INFO 0x40
|
||||
#define BYTE22 (DY_MEM_V2 | DRC_INFO)
|
||||
|
||||
+/* For ibm,arch-vec-5-platform-support. */
|
||||
+#define XIVE_INDEX 0x17
|
||||
+#define MMU_INDEX 0x18
|
||||
+#define RADIX_GTSE_INDEX 0x1a
|
||||
+#define RADIX_ENABLED 0x40
|
||||
+#define XIVE_ENABLED 0x40
|
||||
+#define HASH_ENABLED 0x00
|
||||
+#define MAX_SUPPORTED 0xC0
|
||||
+#define RADIX_GTSE_ENABLED 0x40
|
||||
+
|
||||
void
|
||||
grub_exit (void)
|
||||
{
|
||||
@@ -740,6 +750,10 @@ struct option_vector5
|
||||
grub_uint32_t platform_facilities;
|
||||
grub_uint8_t sub_processors;
|
||||
grub_uint8_t byte22;
|
||||
+ grub_uint8_t xive;
|
||||
+ grub_uint8_t mmu;
|
||||
+ grub_uint8_t hpt_ext;
|
||||
+ grub_uint8_t radix_gtse;
|
||||
} GRUB_PACKED;
|
||||
|
||||
struct pvr_entry
|
||||
@@ -778,6 +792,13 @@ grub_ieee1275_ibm_cas (void)
|
||||
{
|
||||
int rc;
|
||||
grub_ieee1275_ihandle_t root;
|
||||
+ grub_uint8_t ibm_arch_platform_support[8];
|
||||
+ grub_ssize_t actual;
|
||||
+ grub_uint8_t xive_support = 0;
|
||||
+ grub_uint8_t mmu_support = 0;
|
||||
+ grub_uint8_t radix_gtse_support = 0;
|
||||
+ int i = 0;
|
||||
+ int prop_len = 8;
|
||||
struct cas_args
|
||||
{
|
||||
struct grub_ieee1275_common_hdr common;
|
||||
@@ -786,6 +807,46 @@ grub_ieee1275_ibm_cas (void)
|
||||
grub_ieee1275_cell_t cas_addr;
|
||||
grub_ieee1275_cell_t result;
|
||||
} args;
|
||||
+
|
||||
+ grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
|
||||
+ "ibm,arch-vec-5-platform-support",
|
||||
+ (grub_uint32_t *) ibm_arch_platform_support,
|
||||
+ sizeof (ibm_arch_platform_support),
|
||||
+ &actual);
|
||||
+
|
||||
+ for (i = 0; i < prop_len; i++)
|
||||
+ {
|
||||
+ switch (ibm_arch_platform_support[i])
|
||||
+ {
|
||||
+ case XIVE_INDEX:
|
||||
+ if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED)
|
||||
+ xive_support = XIVE_ENABLED;
|
||||
+ else
|
||||
+ xive_support = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case MMU_INDEX:
|
||||
+ if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED)
|
||||
+ mmu_support = RADIX_ENABLED;
|
||||
+ else
|
||||
+ mmu_support = HASH_ENABLED;
|
||||
+ break;
|
||||
+
|
||||
+ case RADIX_GTSE_INDEX:
|
||||
+ if (mmu_support == RADIX_ENABLED)
|
||||
+ radix_gtse_support = ibm_arch_platform_support[i + 1] & RADIX_GTSE_ENABLED;
|
||||
+ else
|
||||
+ radix_gtse_support = 0;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ /* Ignoring the other indexes of ibm,arch-vec-5-platform-support. */
|
||||
+ break;
|
||||
+ }
|
||||
+ /* Skipping the property value. */
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
struct cas_vector vector =
|
||||
{
|
||||
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
|
||||
@@ -802,7 +863,7 @@ grub_ieee1275_ibm_cas (void)
|
||||
.vec4 = 0x0001, /* set required minimum capacity % to the lowest value */
|
||||
.vec5_size = 1 + sizeof (struct option_vector5) - 2,
|
||||
.vec5 = {
|
||||
- 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22
|
||||
+ 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22, xive_support, mmu_support, 0, radix_gtse_support
|
||||
}
|
||||
};
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
44
0001-tpm-Skip-loopback-image-measurement.patch
Normal file
44
0001-tpm-Skip-loopback-image-measurement.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From cda4b7a415eb45743ea54a7760b302c0cfe718cf Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 23 Sep 2024 10:32:18 +0800
|
||||
Subject: [PATCH] tpm: Skip loopback image measurement
|
||||
|
||||
The loopback image is configured to function as a disk by being mapped
|
||||
as a block device. Instead of measuring the entire block device, we
|
||||
should focus on tracking the individual files accessed from it. For
|
||||
example, we do not directly measure block devices like disk hd0, but the
|
||||
files opened from it.
|
||||
|
||||
This method is important to avoid running out of memory, since loopback
|
||||
images can be very large. Trying to read and measure the whole image at
|
||||
once could cause out of memory errors and disrupt the boot process.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/tpm.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c
|
||||
index bb9aee210..ebbb4fef0 100644
|
||||
--- a/grub-core/commands/tpm.c
|
||||
+++ b/grub-core/commands/tpm.c
|
||||
@@ -41,6 +41,16 @@ grub_tpm_verify_init (grub_file_t io,
|
||||
{
|
||||
*context = io->name;
|
||||
*flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||
+
|
||||
+ /*
|
||||
+ * The loopback image is mapped as a disk, allowing it to function like a
|
||||
+ * block device. However, we measure the files read from the block device,
|
||||
+ * not the device itself. For example, we don't measure block devices like
|
||||
+ * disk hd0 directly. This process is crucial to prevent out-of-memory
|
||||
+ * errors, as loopback images are inherently large.
|
||||
+ */
|
||||
+ if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_LOOPBACK)
|
||||
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
--
|
||||
2.46.1
|
||||
|
671
0002-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
671
0002-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
@ -0,0 +1,671 @@
|
||||
From 8ef821ea18ed35f5969b98f2df6a76fefb71b175 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 28 Dec 2022 17:49:24 +0530
|
||||
Subject: [PATCH 2/8] ieee1275: Read the DB and DBX secure boot variables
|
||||
|
||||
If secure boot is enabled with PKS, it will read secure boot variables
|
||||
such as db and dbx from PKS and extract certificates from ESL.
|
||||
It would be saved in the platform keystore buffer, and
|
||||
the appendedsig (module) would read it later to extract
|
||||
the certificate's details.
|
||||
|
||||
In the following scenarios, static key mode will be activated:
|
||||
1. When secure boot is enabled with static
|
||||
2. When SB Version is unavailable but Secure Boot is enabled
|
||||
3. When PKS support is unavailable but secure boot is enabled
|
||||
|
||||
Note:-
|
||||
|
||||
SB Version - secure boot mode
|
||||
1 - PKS
|
||||
0 - static key (embeded key)
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/ieee1275/init.c | 12 +-
|
||||
grub-core/kern/ieee1275/platform_keystore.c | 377 ++++++++++++++++++++
|
||||
include/grub/platform_keystore.h | 190 ++++++++++
|
||||
5 files changed, 580 insertions(+), 1 deletion(-)
|
||||
create mode 100644 grub-core/kern/ieee1275/platform_keystore.c
|
||||
create mode 100644 include/grub/platform_keystore.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index 9d3d5f519..4630e2ba3 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -79,6 +79,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/platform_keystore.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index dc639dd24..4ff35afb7 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -170,6 +170,7 @@ kernel = {
|
||||
ieee1275 = kern/ieee1275/openfw.c;
|
||||
ieee1275 = term/ieee1275/console.c;
|
||||
ieee1275 = kern/ieee1275/init.c;
|
||||
+ ieee1275 = kern/ieee1275/platform_keystore.c;
|
||||
|
||||
uboot = disk/uboot/ubootdisk.c;
|
||||
uboot = kern/uboot/uboot.c;
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index 38f1f1f6e..bb800b275 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <grub/ieee1275/alloc.h>
|
||||
#endif
|
||||
#include <grub/lockdown.h>
|
||||
+#include <grub/platform_keystore.h>
|
||||
|
||||
/* The maximum heap size we're going to claim at boot. Not used by sparc. */
|
||||
#ifdef __i386__
|
||||
@@ -915,7 +916,16 @@ grub_get_ieee1275_secure_boot (void)
|
||||
* We only support enforce.
|
||||
*/
|
||||
if (rc >= 0 && is_sb >= 2)
|
||||
- grub_lockdown ();
|
||||
+ {
|
||||
+ grub_printf ("secure boot enabled\n");
|
||||
+ rc = grub_platform_keystore_init ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("Warning: initialization of the platform keystore failed!\n");
|
||||
+
|
||||
+ grub_lockdown ();
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("secure boot disabled\n");
|
||||
}
|
||||
|
||||
grub_addr_t grub_modbase;
|
||||
diff --git a/grub-core/kern/ieee1275/platform_keystore.c b/grub-core/kern/ieee1275/platform_keystore.c
|
||||
new file mode 100644
|
||||
index 000000000..976e4e9b5
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/ieee1275/platform_keystore.c
|
||||
@@ -0,0 +1,377 @@
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/lockdown.h>
|
||||
+#include <grub/platform_keystore.h>
|
||||
+
|
||||
+#define PKS_CONSUMER_FW 1
|
||||
+#define SB_VERSION_KEY_NAME ((grub_uint8_t *) "SB_VERSION")
|
||||
+#define SB_VERSION_KEY_LEN 10
|
||||
+#define DB 1
|
||||
+#define DBX 2
|
||||
+
|
||||
+#define PKS_OBJECT_NOT_FOUND -7
|
||||
+#define PKS_UNPACK_ERROR 0x200
|
||||
+#define PKS_UNPACK_VERSION_ERROR 0x201
|
||||
+
|
||||
+struct pks_timestamp
|
||||
+{
|
||||
+ grub_uint16_t year;
|
||||
+ grub_uint8_t month;
|
||||
+ grub_uint8_t day;
|
||||
+ grub_uint8_t hour;
|
||||
+ grub_uint8_t minute;
|
||||
+ grub_uint8_t second;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+struct pks_signed_var
|
||||
+{
|
||||
+ grub_uint8_t version;
|
||||
+ struct pks_timestamp time;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* Platform Keystore */
|
||||
+static grub_size_t pks_max_object_size;
|
||||
+grub_uint8_t grub_use_platform_keystore = 0;
|
||||
+grub_pks_t grub_platform_keystore = { .use_static_keys = 0, .db = NULL, .dbx = NULL, .db_entries = 0, .dbx_entries = 0 };
|
||||
+
|
||||
+/* converts the esl data into the ESL */
|
||||
+static grub_esl_t *
|
||||
+grub_convert_to_esl (const grub_uint8_t *esl_data, const grub_size_t esl_data_size)
|
||||
+{
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+
|
||||
+ if (esl_data_size < sizeof (grub_esl_t) || esl_data == NULL)
|
||||
+ return esl;
|
||||
+
|
||||
+ esl = (grub_esl_t *) esl_data;
|
||||
+
|
||||
+ return esl;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * imports the GUID, esd, and its size into the pks sd buffer and
|
||||
+ * pks sd entries from the EFI signature list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_esd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ const grub_size_t signature_size, const grub_uuid_t *guid,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_esd_t *esd = NULL;
|
||||
+ grub_pks_sd_t *signature = *pks_sd;
|
||||
+ grub_size_t entries = *pks_sd_entries;
|
||||
+ grub_size_t data_size = 0, offset = 0;
|
||||
+
|
||||
+ /* reads the esd from esl */
|
||||
+ while (esl_size > 0)
|
||||
+ {
|
||||
+ esd = (grub_esd_t *) (esl_data + offset);
|
||||
+ data_size = signature_size - sizeof (grub_esd_t);
|
||||
+
|
||||
+ if (signature != NULL)
|
||||
+ signature = grub_realloc (signature, (entries + 1) * sizeof (grub_pks_sd_t));
|
||||
+ else
|
||||
+ signature = grub_malloc (sizeof (grub_pks_sd_t));
|
||||
+
|
||||
+ if (signature == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ signature[entries].data = grub_malloc (data_size * sizeof (grub_uint8_t));
|
||||
+ if (signature[entries].data == NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * allocated memory will be freed by
|
||||
+ * grub_release_platform_keystore
|
||||
+ */
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries + 1;
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (signature[entries].data, esd->signaturedata, data_size);
|
||||
+ signature[entries].data_size = data_size;
|
||||
+ signature[entries].guid = *guid;
|
||||
+ entries++;
|
||||
+ esl_size -= signature_size;
|
||||
+ offset += signature_size;
|
||||
+ }
|
||||
+
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * extracts the esd after removing the esl header from esl.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_esl_to_esd (const grub_uint8_t *esl_data, grub_size_t *next_esl,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_uuid_t guid = { 0 };
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+ grub_size_t offset = 0, esl_size = 0,
|
||||
+ signature_size = 0, signature_header_size = 0;
|
||||
+
|
||||
+ esl = grub_convert_to_esl (esl_data, *next_esl);
|
||||
+ if (esl == NULL)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL");
|
||||
+
|
||||
+ esl_size = grub_le_to_cpu32 (esl->signaturelistsize);
|
||||
+ signature_header_size = grub_le_to_cpu32 (esl->signatureheadersize);
|
||||
+ signature_size = grub_le_to_cpu32 (esl->signaturesize);
|
||||
+ guid = esl->signaturetype;
|
||||
+
|
||||
+ if (esl_size < sizeof (grub_esl_t) || esl_size > *next_esl)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL size (%u)\n", esl_size);
|
||||
+
|
||||
+ *next_esl = esl_size;
|
||||
+ offset = sizeof (grub_esl_t) + signature_header_size;
|
||||
+ esl_size = esl_size - offset;
|
||||
+
|
||||
+ return grub_esd_from_esl (esl_data + offset, esl_size, signature_size, &guid,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * imports the EFI signature data and the number of esd from the esl
|
||||
+ * into the pks sd buffer and pks sd entries.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_pks_sd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t next_esl = esl_size;
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ rc = grub_esl_to_esd (esl_data, &next_esl, pks_sd, pks_sd_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+
|
||||
+ esl_data += next_esl;
|
||||
+ esl_size -= next_esl;
|
||||
+ next_esl = esl_size;
|
||||
+ }
|
||||
+ while (esl_size > 0);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * unpacking the signed secure boot variable
|
||||
+ * return error if size too small or version mismatch
|
||||
+ * discards timestamp, only needed in verifying updates
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_unpack_signed_variable (grub_uint8_t *indata, grub_size_t insize,
|
||||
+ grub_uint8_t **data, grub_size_t *size)
|
||||
+{
|
||||
+ struct pks_signed_var *psv = NULL;
|
||||
+
|
||||
+ /* do not permit negative or size 0 data */
|
||||
+ if (insize <= sizeof (struct pks_signed_var))
|
||||
+ return PKS_UNPACK_ERROR;
|
||||
+
|
||||
+ psv = (struct pks_signed_var *) indata;
|
||||
+ if (psv->version != 0)
|
||||
+ return PKS_UNPACK_VERSION_ERROR;
|
||||
+
|
||||
+ *data = indata + sizeof (struct pks_signed_var);
|
||||
+ *size = insize - sizeof (struct pks_signed_var);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * reads the secure boot version from PKS as an object.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_sbversion_from_pks (grub_uint8_t **out, grub_size_t *outlen, grub_size_t *policy)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_object (PKS_CONSUMER_FW, SB_VERSION_KEY_NAME,
|
||||
+ SB_VERSION_KEY_LEN, *out, pks_max_object_size,
|
||||
+ outlen, policy);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * reads the secure boot variable from PKS.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_sbvar_from_pks (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t **out, grub_size_t *outlen)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_sbvar (sbvarflags, sbvartype, *out,
|
||||
+ pks_max_object_size, outlen);
|
||||
+}
|
||||
+
|
||||
+/* Test the availability of PKS support. */
|
||||
+static grub_err_t
|
||||
+grub_is_support_pks (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_ieee1275_cell_t missing = 0;
|
||||
+
|
||||
+ rc = grub_ieee1275_test ("pks-max-object-size", &missing);
|
||||
+ if (rc != GRUB_ERR_NONE || (int) missing == -1)
|
||||
+ grub_printf ("Warning: doesn't have PKS support!\n");
|
||||
+ else
|
||||
+ {
|
||||
+ rc = grub_ieee1275_pks_max_object_size (&pks_max_object_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("Warning: PKS support is there but it has zero objects!\n");
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * retrieves the secure boot variable from PKS, unpacks it, reads the esd
|
||||
+ * from ESL, and stores the information in the pks sd buffer.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_secure_boot_variables (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *data = NULL, *esl_data = NULL;
|
||||
+ grub_size_t data_len = 0, esl_data_size = 0;
|
||||
+
|
||||
+ rc = grub_sbvar_from_pks (sbvarflags, sbvartype, &data, &data_len);
|
||||
+ /*
|
||||
+ * at this point we have SB_VERSION, so any error is worth
|
||||
+ * at least some user-visible info
|
||||
+ */
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (rc, "secure boot variable %s reading (%d)",
|
||||
+ (sbvartype == DB ? "db" : "dbx"), rc);
|
||||
+ else
|
||||
+ {
|
||||
+ rc = grub_unpack_signed_variable (data, data_len, &esl_data, &esl_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (rc, "unpacking of signed variable %s structure (%d)",
|
||||
+ (sbvartype == DB ? "db" : "dbx"), rc);
|
||||
+ else
|
||||
+ rc = grub_pks_sd_from_esl ((const grub_uint8_t *) esl_data, esl_data_size,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+ }
|
||||
+
|
||||
+ grub_free (data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* reads secure boot version (SB_VERSION) */
|
||||
+static grub_err_t
|
||||
+grub_secure_boot_version (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *data = NULL;
|
||||
+ grub_size_t len = 0, policy = 0;
|
||||
+
|
||||
+ rc = grub_sbversion_from_pks (&data, &len, &policy);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("Warning: SB version read failed! (%d)\n", rc);
|
||||
+ else if (len != 1 || (*data != 1 && *data != 0))
|
||||
+ {
|
||||
+ grub_printf ("Warning: found unexpected SB version! (%d)\n", *data);
|
||||
+ rc = GRUB_ERR_INVALID_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: switch to static key!\n");
|
||||
+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||||
+ grub_fatal ("Secure Boot locked down");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_use_platform_keystore = *data;
|
||||
+
|
||||
+ grub_free (data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* releasing allocated memory */
|
||||
+void
|
||||
+grub_release_platform_keystore (void)
|
||||
+{
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.db_entries; i++)
|
||||
+ grub_free (grub_platform_keystore.db[i].data);
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
|
||||
+ grub_free (grub_platform_keystore.dbx[i].data);
|
||||
+
|
||||
+ grub_free (grub_platform_keystore.db);
|
||||
+ grub_free (grub_platform_keystore.dbx);
|
||||
+ grub_memset (&grub_platform_keystore, 0x00, sizeof (grub_pks_t));
|
||||
+}
|
||||
+
|
||||
+/* initialization of the Platform Keystore */
|
||||
+grub_err_t
|
||||
+grub_platform_keystore_init (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ grub_printf ("trying to load Platform Keystore\n");
|
||||
+
|
||||
+ rc = grub_is_support_pks ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: switch to static key!\n");
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* SB_VERSION */
|
||||
+ rc = grub_secure_boot_version ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+
|
||||
+ if (grub_use_platform_keystore)
|
||||
+ {
|
||||
+ grub_memset (&grub_platform_keystore, 0x00, sizeof (grub_pks_t));
|
||||
+ /* DB */
|
||||
+ rc = grub_secure_boot_variables (0, DB, &grub_platform_keystore.db,
|
||||
+ &grub_platform_keystore.db_entries);
|
||||
+ if ((int)rc == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ /* DB variable won't be available by default in PKS, So, it will loads the Default Keys from ELF Note */
|
||||
+ grub_platform_keystore.use_static_keys = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (rc == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ /* DBX */
|
||||
+ rc = grub_secure_boot_variables (0, DBX, &grub_platform_keystore.dbx,
|
||||
+ &grub_platform_keystore.dbx_entries);
|
||||
+ if ((int)rc == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ grub_printf ("Warning: dbx is not found!\n");
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_release_platform_keystore ();
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
diff --git a/include/grub/platform_keystore.h b/include/grub/platform_keystore.h
|
||||
new file mode 100644
|
||||
index 000000000..8cc4266c9
|
||||
--- /dev/null
|
||||
+++ b/include/grub/platform_keystore.h
|
||||
@@ -0,0 +1,190 @@
|
||||
+#ifndef __PLATFORM_KEYSTORE_H__
|
||||
+#define __PLATFORM_KEYSTORE_H__
|
||||
+
|
||||
+#include <grub/symbol.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+#if __GNUC__ >= 9
|
||||
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
+#endif
|
||||
+
|
||||
+#define GRUB_UUID_SIZE 16
|
||||
+#define GRUB_MAX_HASH_SIZE 64
|
||||
+
|
||||
+typedef struct grub_uuid grub_uuid_t;
|
||||
+typedef struct grub_esd grub_esd_t;
|
||||
+typedef struct grub_esl grub_esl_t;
|
||||
+
|
||||
+/* The structure of a UUID.*/
|
||||
+struct grub_uuid
|
||||
+{
|
||||
+ grub_uint8_t b[GRUB_UUID_SIZE];
|
||||
+};
|
||||
+
|
||||
+/* The structure of an EFI signature database (ESD).*/
|
||||
+struct grub_esd
|
||||
+{
|
||||
+ /*
|
||||
+ * An identifier which identifies the agent which added
|
||||
+ * the signature to the list.
|
||||
+ */
|
||||
+ grub_uuid_t signatureowner;
|
||||
+ /* The format of the signature is defined by the SignatureType.*/
|
||||
+ grub_uint8_t signaturedata[];
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* The structure of an EFI signature list (ESL).*/
|
||||
+struct grub_esl
|
||||
+{
|
||||
+ /* Type of the signature. GUID signature types are defined in below.*/
|
||||
+ grub_uuid_t signaturetype;
|
||||
+ /* Total size of the signature list, including this header.*/
|
||||
+ grub_uint32_t signaturelistsize;
|
||||
+ /*
|
||||
+ * Size of the signature header which precedes
|
||||
+ * the array of signatures.
|
||||
+ */
|
||||
+ grub_uint32_t signatureheadersize;
|
||||
+ /* Size of each signature.*/
|
||||
+ grub_uint32_t signaturesize;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/*
|
||||
+ * The GRUB_PKS_CERT_* is derived from the following files referred from edk2-staging[1] repo
|
||||
+ * of tianocore
|
||||
+ *
|
||||
+ * MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * [1] https://github.com/tianocore/edk2-staging
|
||||
+ */
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, \
|
||||
+ 0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, \
|
||||
+ 0x5c, 0x2b, 0xf0, 0x72 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA1_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x12, 0xa5, 0x6c, 0x82, 0x10, 0xcf, \
|
||||
+ 0xc9, 0x4a, 0xb1, 0x87, 0xbe, 0x1, \
|
||||
+ 0x49, 0x66, 0x31, 0xbd \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA224_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x33, 0x52, 0x6e, 0xb, 0x5c, 0xa6, \
|
||||
+ 0xc9, 0x44, 0x94, 0x7, 0xd9, 0xab, \
|
||||
+ 0x83, 0xbf, 0xc8, 0xbd \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x26, 0x16, 0xc4, 0xc1, 0x4c, 0x50, \
|
||||
+ 0x92, 0x40, 0xac, 0xa9, 0x41, 0xf9, \
|
||||
+ 0x36, 0x93, 0x43, 0x28 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x07, 0x53, 0x3e, 0xff, 0xd0, 0x9f, \
|
||||
+ 0xc9, 0x48, 0x85, 0xf1, 0x8a, 0xd5, \
|
||||
+ 0x6c, 0x70, 0x1e, 0x1 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xae, 0x0f, 0x3e, 0x09, 0xc4, 0xa6, \
|
||||
+ 0x50, 0x4f, 0x9f, 0x1b, 0xd4, 0x1e, \
|
||||
+ 0x2b, 0x89, 0xc1, 0x9a \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x92, 0xa4, 0xd2, 0x3b, 0xc0, 0x96, \
|
||||
+ 0x79, 0x40, 0xb4, 0x20, 0xfc, 0xf9, \
|
||||
+ 0x8e, 0xf1, 0x03, 0xed \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x6e, 0x87, 0x76, 0x70, 0xc2, 0x80, \
|
||||
+ 0xe6, 0x4e, 0xaa, 0xd2, 0x28, 0xb3, \
|
||||
+ 0x49, 0xa6, 0x86, 0x5b \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x63, 0xbf, 0x6d, 0x44, 0x02, 0x25, \
|
||||
+ 0xda, 0x4c, 0xbc, 0xfa, 0x24, 0x65, \
|
||||
+ 0xd2, 0xb0, 0xfe, 0x9d \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+typedef struct grub_pks_sd grub_pks_sd_t;
|
||||
+typedef struct grub_pks grub_pks_t;
|
||||
+
|
||||
+/* The structure of a PKS signature data.*/
|
||||
+struct grub_pks_sd
|
||||
+{
|
||||
+ grub_uuid_t guid; /* signature type */
|
||||
+ grub_uint8_t *data; /* signature data */
|
||||
+ grub_size_t data_size; /* size of signature data */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* The structure of a PKS.*/
|
||||
+struct grub_pks
|
||||
+{
|
||||
+ grub_uint8_t use_static_keys;
|
||||
+ grub_pks_sd_t *db; /* signature database */
|
||||
+ grub_pks_sd_t *dbx; /* forbidden signature database */
|
||||
+ grub_size_t db_entries; /* size of signature database */
|
||||
+ grub_size_t dbx_entries; /* size of forbidden signature database */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+#ifdef __powerpc__
|
||||
+
|
||||
+/* initialization of the Platform Keystore */
|
||||
+grub_err_t grub_platform_keystore_init (void);
|
||||
+/* releasing allocated memory */
|
||||
+void EXPORT_FUNC(grub_release_platform_keystore) (void);
|
||||
+extern grub_uint8_t EXPORT_VAR(grub_use_platform_keystore);
|
||||
+extern grub_pks_t EXPORT_VAR(grub_platform_keystore);
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#define grub_use_platform_keystore 0
|
||||
+grub_pks_t grub_platform_keystore = {0, NULL, NULL, 0, 0};
|
||||
+void grub_release_platform_keystore (void);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.47.0
|
||||
|
831
0003-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
Normal file
831
0003-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
Normal file
@ -0,0 +1,831 @@
|
||||
From 350e8d823db1febc2c81635115ef3c4c0f41f3e7 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 17 Jan 2023 22:38:05 +0530
|
||||
Subject: [PATCH 3/8] appendedsig: The creation of trusted and distrusted lists
|
||||
|
||||
The trusted certificates and binary hashes, distrusted certificates and
|
||||
binary/certificate hashes will be extracted from the platform keystore buffer
|
||||
if Secure Boot is enabled with PKS.
|
||||
In order to verify the integerity of the kernel, the extracted data
|
||||
would be stored in the buffer db and dbx.
|
||||
|
||||
The trusted certificates will be extracted from the grub ELFNOTE if Secure Boot is
|
||||
enabled with static key. In order to verify the integerity of the kernel,
|
||||
the extracted data would be stored in the buffer db.
|
||||
|
||||
Note:-
|
||||
|
||||
if the trusted certificate nor binary hash exists in the distrusted list (DBX),
|
||||
rejected it while extracting it from the platform keystore buffer.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 701 +++++++++++++++++--
|
||||
1 file changed, 635 insertions(+), 66 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index e63ad1ac6..5bb09e349 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <grub/libtasn1.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/lockdown.h>
|
||||
-
|
||||
+#include <grub/platform_keystore.h>
|
||||
#include "appendedsig.h"
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
@@ -66,8 +66,23 @@ struct grub_appended_signature
|
||||
struct pkcs7_signedData pkcs7; /* Parsed PKCS#7 data */
|
||||
};
|
||||
|
||||
-/* Trusted certificates for verifying appended signatures */
|
||||
-struct x509_certificate *grub_trusted_key;
|
||||
+/* This represents a trusted/distrusted list*/
|
||||
+struct grub_database
|
||||
+{
|
||||
+ struct x509_certificate *keys; /* Certificates */
|
||||
+ grub_size_t key_entries; /* Number of certificates */
|
||||
+ grub_uint8_t **signatures; /* Certificate/binary hashes */
|
||||
+ grub_size_t *signature_size; /* Size of certificate/binary hashes */
|
||||
+ grub_size_t signature_entries; /* Number of certificate/binary hashes */
|
||||
+};
|
||||
+
|
||||
+/* Trusted list */
|
||||
+struct grub_database grub_db = {.keys = NULL, .key_entries = 0, .signatures = NULL,
|
||||
+ .signature_size = NULL, .signature_entries = 0};
|
||||
+
|
||||
+/* Distrusted list */
|
||||
+struct grub_database grub_dbx = {.signatures = NULL, .signature_size = NULL,
|
||||
+ .signature_entries = 0};
|
||||
|
||||
/*
|
||||
* Force gcry_rsa to be a module dependency.
|
||||
@@ -90,12 +105,263 @@ struct x509_certificate *grub_trusted_key;
|
||||
*/
|
||||
extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
|
||||
|
||||
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
|
||||
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
|
||||
+
|
||||
+/* releasing trusted list memory */
|
||||
+static void grub_release_trusted_list (void);
|
||||
+/* releasing distrusted list memory */
|
||||
+static void grub_release_distrusted_list (void);
|
||||
+
|
||||
static enum
|
||||
{ check_sigs_no = 0,
|
||||
check_sigs_enforce = 1,
|
||||
check_sigs_forced = 2
|
||||
} check_sigs = check_sigs_no;
|
||||
|
||||
+/*
|
||||
+ * GUID can be used to determine the hashing function and
|
||||
+ * generate the hash using determined hashing function.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_get_hash (const grub_uuid_t *guid, const grub_uint8_t *data, const grub_size_t data_size,
|
||||
+ grub_uint8_t *hash, grub_size_t *hash_size)
|
||||
+{
|
||||
+ gcry_md_spec_t *hash_func = NULL;
|
||||
+
|
||||
+ if (guid == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "signature data type is null");
|
||||
+
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha256;
|
||||
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha384;
|
||||
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ hash_func = &_gcry_digest_spec_sha512;
|
||||
+ else
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+
|
||||
+ grub_memset (hash, 0x00, GRUB_MAX_HASH_SIZE);
|
||||
+ grub_crypto_hash (hash_func, hash, data, data_size);
|
||||
+ *hash_size = hash_func->mdlen;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/* adding the certificate/binary hash into the trusted/distrusted list */
|
||||
+static grub_err_t
|
||||
+grub_add_hash (const grub_uint8_t **data, const grub_size_t data_size,
|
||||
+ grub_uint8_t ***signature_list, grub_size_t **signature_size_list,
|
||||
+ grub_size_t *signature_list_entries)
|
||||
+{
|
||||
+ grub_uint8_t **signatures = *signature_list;
|
||||
+ grub_size_t *signature_size = *signature_size_list;
|
||||
+ grub_size_t signature_entries = *signature_list_entries;
|
||||
+
|
||||
+ if (*data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate/binary hash data/size is null");
|
||||
+
|
||||
+ if (signatures == NULL && signature_size == NULL)
|
||||
+ {
|
||||
+ signatures = grub_zalloc (sizeof (grub_uint8_t *));
|
||||
+ signature_size = grub_zalloc (sizeof (grub_size_t));
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ signatures = grub_realloc (signatures, sizeof (grub_uint8_t *) * (signature_entries + 1));
|
||||
+ signature_size = grub_realloc (signature_size,
|
||||
+ sizeof (grub_size_t) * (signature_entries + 1));
|
||||
+ }
|
||||
+
|
||||
+ if (signatures == NULL || signature_size == NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * allocated memory will be freed by
|
||||
+ * grub_release_trusted_list/grub_release_distrusted_list
|
||||
+ */
|
||||
+ if (signatures != NULL)
|
||||
+ {
|
||||
+ *signature_list = signatures;
|
||||
+ *signature_list_entries = signature_entries + 1;
|
||||
+ }
|
||||
+
|
||||
+ if (signature_size != NULL)
|
||||
+ *signature_size_list = signature_size;
|
||||
+
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+ }
|
||||
+
|
||||
+ signatures[signature_entries] = (grub_uint8_t *) *data;
|
||||
+ signature_size[signature_entries] = data_size;
|
||||
+ signature_entries++;
|
||||
+ *data = NULL;
|
||||
+
|
||||
+ *signature_list = signatures;
|
||||
+ *signature_size_list = signature_size;
|
||||
+ *signature_list_entries = signature_entries;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_is_x509 (const grub_uuid_t *guid)
|
||||
+{
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_is_cert_match (const struct x509_certificate *distrusted_cert,
|
||||
+ const struct x509_certificate *db_cert)
|
||||
+{
|
||||
+
|
||||
+ if (grub_memcmp (distrusted_cert->subject, db_cert->subject, db_cert->subject_len) == 0
|
||||
+ && grub_memcmp (distrusted_cert->serial, db_cert->serial, db_cert->serial_len) == 0
|
||||
+ && grub_memcmp (distrusted_cert->mpis[0], db_cert->mpis[0], sizeof (db_cert->mpis[0])) == 0
|
||||
+ && grub_memcmp (distrusted_cert->mpis[1], db_cert->mpis[1], sizeof (db_cert->mpis[1])) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * verify the certificate against the certificate from platform keystore buffer's
|
||||
+ * distrusted list, if it is present, return a bad signature.
|
||||
+ * else, no errors.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_is_distrusted_cert (const struct x509_certificate *db_cert)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+ struct x509_certificate *distrusted_cert = NULL;
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_platform_keystore.dbx[i].data == NULL &&
|
||||
+ grub_platform_keystore.dbx[i].data_size == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ if (grub_is_x509 (&grub_platform_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ distrusted_cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
+ if (distrusted_cert == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ rc = parse_x509_certificate (grub_platform_keystore.dbx[i].data,
|
||||
+ grub_platform_keystore.dbx[i].data_size, distrusted_cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_free (distrusted_cert);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_is_cert_match (distrusted_cert, db_cert) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted certificate CN='%s' is ignored "
|
||||
+ "because it is on the distrusted list (dbx).\n", db_cert->subject);
|
||||
+ grub_free (grub_platform_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_platform_keystore.dbx[i], 0x00,
|
||||
+ sizeof (grub_platform_keystore.dbx[i]));
|
||||
+ certificate_release (distrusted_cert);
|
||||
+ grub_free (distrusted_cert);
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+
|
||||
+ certificate_release (distrusted_cert);
|
||||
+ grub_free (distrusted_cert);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/* adding the certificate into the trusted/distrusted list */
|
||||
+static grub_err_t
|
||||
+grub_add_certificate (const grub_uint8_t *data, const grub_size_t data_size,
|
||||
+ struct grub_database *database, const grub_uint8_t is_db)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t key_entries = database->key_entries;
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+
|
||||
+ if (data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate data/size is null");
|
||||
+
|
||||
+ cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
+ if (cert == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ rc = parse_x509_certificate (data, data_size, cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: skipping %s certificate (%d)\n",
|
||||
+ (is_db ? "trusted":"distrused"), rc);
|
||||
+ grub_free (cert);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ if (is_db)
|
||||
+ {
|
||||
+ rc = grub_is_distrusted_cert (cert);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ return rc;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "add a %s certificate CN='%s'\n",
|
||||
+ (is_db ? "trusted":"distrused"), cert->subject);
|
||||
+
|
||||
+ key_entries++;
|
||||
+ cert->next = database->keys;
|
||||
+ database->keys = cert;
|
||||
+ database->key_entries = key_entries;
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_read_file (const grub_file_t file, grub_uint8_t **data, grub_ssize_t *data_size)
|
||||
+{
|
||||
+ grub_uint8_t *buffer = NULL;
|
||||
+ grub_ssize_t read_size = 0;
|
||||
+ grub_off_t total_read_size = 0;
|
||||
+ grub_off_t file_size = grub_file_size (file);
|
||||
+
|
||||
+ if (file_size == GRUB_FILE_SIZE_UNKNOWN)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("could not parse the unknown size of the file."));
|
||||
+
|
||||
+ buffer = grub_zalloc (file_size);
|
||||
+ if (buffer == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+
|
||||
+ while (total_read_size < file_size)
|
||||
+ {
|
||||
+ read_size = grub_file_read (file, &buffer[total_read_size], file_size - total_read_size);
|
||||
+ if (read_size < 0)
|
||||
+ {
|
||||
+ grub_free (buffer);
|
||||
+ return grub_error (GRUB_ERR_READ_ERROR, N_("unable to read the file"));
|
||||
+ }
|
||||
+
|
||||
+ total_read_size += read_size;
|
||||
+ }
|
||||
+
|
||||
+ *data = buffer;
|
||||
+ *data_size = total_read_size;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static const char *
|
||||
grub_env_read_sec (struct grub_env_var *var __attribute__((unused)),
|
||||
const char *val __attribute__((unused)))
|
||||
@@ -153,10 +419,7 @@ file_read_all (grub_file_t file, grub_uint8_t **buf, grub_size_t *len)
|
||||
|
||||
while (total_read_size < file_size)
|
||||
{
|
||||
- read_size =
|
||||
- grub_file_read (file, *buf + total_read_size,
|
||||
- file_size - total_read_size);
|
||||
-
|
||||
+ read_size = grub_file_read (file, *buf + total_read_size, file_size - total_read_size);
|
||||
if (read_size < 0)
|
||||
{
|
||||
grub_free (*buf);
|
||||
@@ -267,9 +530,8 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
struct pkcs7_signerInfo *si;
|
||||
int i;
|
||||
|
||||
- if (!grub_trusted_key)
|
||||
- return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("No trusted keys to verify against"));
|
||||
+ if (!grub_db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to verify against"));
|
||||
|
||||
err = extract_appended_signature (buf, bufsize, &sig);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
@@ -299,17 +561,16 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
|
||||
err = GRUB_ERR_BAD_SIGNATURE;
|
||||
- for (pk = grub_trusted_key; pk; pk = pk->next)
|
||||
- {
|
||||
- rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
- if (rc)
|
||||
- {
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Error padding hash for RSA verification: %d"),
|
||||
- rc);
|
||||
- grub_free (context);
|
||||
- goto cleanup;
|
||||
- }
|
||||
+ for (pk = grub_db.keys; pk; pk = pk->next)
|
||||
+ {
|
||||
+ rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
+ if (rc)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("Error padding hash for RSA verification: %d"), rc);
|
||||
+ grub_free (context);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
|
||||
rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi,
|
||||
pk->mpis, NULL, NULL);
|
||||
@@ -402,16 +663,16 @@ grub_cmd_distrust (grub_command_t cmd __attribute__((unused)),
|
||||
|
||||
if (cert_num == 1)
|
||||
{
|
||||
- cert = grub_trusted_key;
|
||||
- grub_trusted_key = cert->next;
|
||||
+ cert = grub_db.keys;
|
||||
+ grub_db.keys = cert->next;
|
||||
|
||||
certificate_release (cert);
|
||||
grub_free (cert);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
i = 2;
|
||||
- prev = grub_trusted_key;
|
||||
- cert = grub_trusted_key->next;
|
||||
+ prev = grub_db.keys;
|
||||
+ cert = grub_db.keys->next;
|
||||
while (cert)
|
||||
{
|
||||
if (i == cert_num)
|
||||
@@ -464,8 +725,8 @@ grub_cmd_trust (grub_command_t cmd __attribute__((unused)),
|
||||
grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
|
||||
cert->subject);
|
||||
|
||||
- cert->next = grub_trusted_key;
|
||||
- grub_trusted_key = cert;
|
||||
+ cert->next = grub_db.keys;
|
||||
+ grub_db.keys = cert;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -479,7 +740,7 @@ grub_cmd_list (grub_command_t cmd __attribute__((unused)),
|
||||
int cert_num = 1;
|
||||
grub_size_t i;
|
||||
|
||||
- for (cert = grub_trusted_key; cert; cert = cert->next)
|
||||
+ for (cert = grub_db.keys; cert; cert = cert->next)
|
||||
{
|
||||
grub_printf (N_("Certificate %d:\n"), cert_num);
|
||||
|
||||
@@ -577,6 +838,305 @@ static struct grub_fs pseudo_fs = {
|
||||
.fs_read = pseudo_read
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * verify the trusted certificate against the certificate hashes from platform keystore buffer's
|
||||
+ * distrusted list, if it is present, return a bad signature.
|
||||
+ * else, no errors.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_is_distrusted_cert_hash (const grub_uint8_t *data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0, cert_hash_size = 0;
|
||||
+ grub_uint8_t cert_hash[GRUB_MAX_HASH_SIZE] = { 0 };
|
||||
+
|
||||
+ if (data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted certificate data/size is null");
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_platform_keystore.dbx[i].data == NULL &&
|
||||
+ grub_platform_keystore.dbx[i].data_size == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ rc = grub_get_hash (&grub_platform_keystore.dbx[i].guid, data, data_size,
|
||||
+ cert_hash, &cert_hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (cert_hash_size == grub_platform_keystore.dbx[i].data_size &&
|
||||
+ grub_memcmp (grub_platform_keystore.dbx[i].data, cert_hash, cert_hash_size) == 0)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted certificate (%02x%02x%02x%02x) is ignored "
|
||||
+ "because this certificate hash is on the distrusted list (dbx).\n",
|
||||
+ cert_hash[0], cert_hash[1], cert_hash[2], cert_hash[3]);
|
||||
+ grub_free (grub_platform_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_platform_keystore.dbx[i], 0x00,
|
||||
+ sizeof (grub_platform_keystore.dbx[i]));
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * verify the trusted binary hash against the platform keystore buffer's
|
||||
+ * distrusted list, if it is present, return a bad signature.
|
||||
+ * else, no errors.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_is_distrusted_binary_hash (const grub_uint8_t *binary_hash,
|
||||
+ const grub_size_t binary_hash_size)
|
||||
+{
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_platform_keystore.dbx[i].data == NULL &&
|
||||
+ grub_platform_keystore.dbx[i].data_size == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ if (binary_hash_size == grub_platform_keystore.dbx[i].data_size &&
|
||||
+ grub_memcmp (grub_platform_keystore.dbx[i].data, binary_hash, binary_hash_size) == 0)
|
||||
+ {
|
||||
+ grub_printf ("Warning: a trusted binary hash (%02x%02x%02x%02x) is ignored"
|
||||
+ " because it is on the distrusted list (dbx).\n",
|
||||
+ binary_hash[0], binary_hash[1], binary_hash[2], binary_hash[3]);
|
||||
+ grub_free (grub_platform_keystore.dbx[i].data);
|
||||
+ grub_memset (&grub_platform_keystore.dbx[i], 0x00,
|
||||
+ sizeof (grub_platform_keystore.dbx[i]));
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * extracts the binary hashes from the platform keystore buffer,
|
||||
+ * and adds it to the trusted list if not exists in distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_add_trusted_binary_hash (const grub_uint8_t **data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ if (*data == NULL || data_size == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted binary hash data/size is null");
|
||||
+
|
||||
+ rc = grub_is_distrusted_binary_hash (*data, data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+
|
||||
+ rc = grub_add_hash (data, data_size, &grub_db.signatures, &grub_db.signature_size,
|
||||
+ &grub_db.signature_entries);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_is_hash (const grub_uuid_t *guid)
|
||||
+{
|
||||
+ /* GUID type of the binary hash */
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ /* GUID type of the certificate hash */
|
||||
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
|
||||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE) == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * extracts the x509 certificates/binary hashes from the platform keystore buffer,
|
||||
+ * parses it, and adds it to the trusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_create_trusted_list (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.db_entries; i++)
|
||||
+ {
|
||||
+ if (grub_is_hash (&grub_platform_keystore.db[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = grub_add_trusted_binary_hash ((const grub_uint8_t **)
|
||||
+ &grub_platform_keystore.db[i].data,
|
||||
+ grub_platform_keystore.db[i].data_size);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (grub_is_x509 (&grub_platform_keystore.db[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+
|
||||
+ rc = grub_is_distrusted_cert_hash (grub_platform_keystore.db[i].data,
|
||||
+ grub_platform_keystore.db[i].data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ rc = grub_add_certificate (grub_platform_keystore.db[i].data,
|
||||
+ grub_platform_keystore.db[i].data_size, &grub_db, 1);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ else if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("Warning: unsupported signature data type and "
|
||||
+ "skipping trusted data (%" PRIuGRUB_SIZE ")\n", i + 1);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * extracts the certificates, certificate/binary hashes out of the platform keystore buffer,
|
||||
+ * and adds it to the distrusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_create_distrusted_list (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
|
||||
+ {
|
||||
+ if (grub_platform_keystore.dbx[i].data != NULL &&
|
||||
+ grub_platform_keystore.dbx[i].data_size > 0)
|
||||
+ {
|
||||
+ if (grub_is_x509 (&grub_platform_keystore.dbx[i].guid))
|
||||
+ {
|
||||
+ rc = grub_add_certificate (grub_platform_keystore.dbx[i].data,
|
||||
+ grub_platform_keystore.dbx[i].data_size, &grub_dbx, 0);
|
||||
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else if (grub_is_hash (&grub_platform_keystore.dbx[i].guid) == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ rc = grub_add_hash ((const grub_uint8_t **) &grub_platform_keystore.dbx[i].data,
|
||||
+ grub_platform_keystore.dbx[i].data_size,
|
||||
+ &grub_dbx.signatures, &grub_dbx.signature_size,
|
||||
+ &grub_dbx.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("Warning: unsupported signature data type and "
|
||||
+ "skipping distrusted data (%" PRIuGRUB_SIZE ")\n", i + 1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * extracts the x509 certificates from the ELF note header,
|
||||
+ * parses it, and adds it to the trusted list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_build_static_trusted_list (const struct grub_module_header *header, bool mode)
|
||||
+{
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+ struct grub_file pseudo_file;
|
||||
+ grub_uint8_t *cert_data = NULL;
|
||||
+ grub_ssize_t cert_data_size = 0;
|
||||
+
|
||||
+ grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
|
||||
+ pseudo_file.fs = &pseudo_fs;
|
||||
+ pseudo_file.size = header->size - sizeof (struct grub_module_header);
|
||||
+ pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
|
||||
+ pseudo_file.size);
|
||||
+
|
||||
+ err = grub_read_file (&pseudo_file, &cert_data, &cert_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+
|
||||
+ if (mode)
|
||||
+ {
|
||||
+ err = grub_is_distrusted_cert_hash (cert_data, cert_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ err = grub_add_certificate (cert_data, cert_data_size, &grub_db, mode);
|
||||
+ if (cert_data != NULL)
|
||||
+ grub_free (cert_data);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* releasing memory */
|
||||
+static void
|
||||
+grub_release_trusted_list (void)
|
||||
+{
|
||||
+ struct x509_certificate *cert;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ while (grub_db.keys != NULL)
|
||||
+ {
|
||||
+ cert = grub_db.keys;
|
||||
+ grub_db.keys = grub_db.keys->next;
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < grub_db.signature_entries; i++)
|
||||
+ grub_free (grub_db.signatures[i]);
|
||||
+
|
||||
+ grub_free (grub_db.signatures);
|
||||
+ grub_free (grub_db.signature_size);
|
||||
+ grub_memset (&grub_db, 0x00, sizeof (grub_db));
|
||||
+}
|
||||
+
|
||||
+/* releasing memory */
|
||||
+static void
|
||||
+grub_release_distrusted_list (void)
|
||||
+{
|
||||
+ struct x509_certificate *cert;
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ while (grub_dbx.keys != NULL)
|
||||
+ {
|
||||
+ cert = grub_dbx.keys;
|
||||
+ grub_dbx.keys = grub_dbx.keys->next;
|
||||
+ certificate_release (cert);
|
||||
+ grub_free (cert);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < grub_dbx.signature_entries; i++)
|
||||
+ grub_free (grub_dbx.signatures[i]);
|
||||
+
|
||||
+ grub_free (grub_dbx.signatures);
|
||||
+ grub_free (grub_dbx.signature_size);
|
||||
+ grub_memset (&grub_dbx, 0x00, sizeof (grub_dbx));
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_load_static_keys (struct grub_module_header *header, bool mode)
|
||||
+{
|
||||
+ int rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ /* Not an ELF module, skip. */
|
||||
+ if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
+ continue;
|
||||
+ rc = grub_build_static_trusted_list (header, mode);
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
|
||||
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
@@ -588,10 +1148,7 @@ GRUB_MOD_INIT (appendedsig)
|
||||
if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||||
check_sigs = check_sigs_forced;
|
||||
|
||||
- grub_trusted_key = NULL;
|
||||
-
|
||||
- grub_register_variable_hook ("check_appended_signatures",
|
||||
- grub_env_read_sec, grub_env_write_sec);
|
||||
+ grub_register_variable_hook ("check_appended_signatures", grub_env_read_sec, grub_env_write_sec);
|
||||
grub_env_export ("check_appended_signatures");
|
||||
|
||||
rc = asn1_init ();
|
||||
@@ -599,40 +1156,52 @@ GRUB_MOD_INIT (appendedsig)
|
||||
grub_fatal ("Error initing ASN.1 data structures: %d: %s\n", rc,
|
||||
asn1_strerror (rc));
|
||||
|
||||
- FOR_MODULES (header)
|
||||
- {
|
||||
- struct grub_file pseudo_file;
|
||||
- struct x509_certificate *pk = NULL;
|
||||
- grub_err_t err;
|
||||
-
|
||||
- /* Not an ELF module, skip. */
|
||||
- if (header->type != OBJ_TYPE_X509_PUBKEY)
|
||||
- continue;
|
||||
-
|
||||
- grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
|
||||
- pseudo_file.fs = &pseudo_fs;
|
||||
- pseudo_file.size = header->size - sizeof (struct grub_module_header);
|
||||
- pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
|
||||
-
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "Found an x509 key, size=%" PRIuGRUB_UINT64_T "\n",
|
||||
- pseudo_file.size);
|
||||
-
|
||||
- pk = grub_zalloc (sizeof (struct x509_certificate));
|
||||
- if (!pk)
|
||||
- {
|
||||
- grub_fatal ("Out of memory loading initial certificates");
|
||||
- }
|
||||
-
|
||||
- err = read_cert_from_file (&pseudo_file, pk);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- grub_fatal ("Error loading initial key: %s", grub_errmsg);
|
||||
-
|
||||
- grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", pk->subject);
|
||||
-
|
||||
- pk->next = grub_trusted_key;
|
||||
- grub_trusted_key = pk;
|
||||
- }
|
||||
+ if (!grub_use_platform_keystore && check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ rc = grub_load_static_keys (header, 0);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_release_trusted_list ();
|
||||
+ grub_error (rc, "static trusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("appendedsig: the trusted list now has %" PRIuGRUB_SIZE " static keys\n",
|
||||
+ grub_db.key_entries);
|
||||
+ }
|
||||
+ else if (grub_use_platform_keystore && check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ if (grub_platform_keystore.use_static_keys == 1)
|
||||
+ {
|
||||
+ grub_printf ("Warning: db variable not available and using a static key"
|
||||
+ "as a default key in trusted list");
|
||||
+ rc = grub_load_static_keys (header, 1);
|
||||
+ }
|
||||
+ else
|
||||
+ rc = grub_create_trusted_list ();
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_release_trusted_list ();
|
||||
+ grub_error (rc, "trusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ rc = grub_create_distrusted_list ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_release_trusted_list ();
|
||||
+ grub_release_distrusted_list ();
|
||||
+ grub_error (rc, "distrusted list creation failed");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("appendedsig: the trusted list now has %" PRIuGRUB_SIZE " keys.\n"
|
||||
+ "appendedsig: the distrusted list now has %" PRIuGRUB_SIZE " keys.\n",
|
||||
+ grub_db.signature_entries + grub_db.key_entries,
|
||||
+ grub_dbx.signature_entries);
|
||||
+ }
|
||||
+
|
||||
+ grub_release_platform_keystore ();
|
||||
+ }
|
||||
|
||||
cmd_trust =
|
||||
grub_register_command ("trust_certificate", grub_cmd_trust,
|
||||
--
|
||||
2.47.0
|
||||
|
253
0004-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
Normal file
253
0004-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
Normal file
@ -0,0 +1,253 @@
|
||||
From 5bff27911bb6575b80b5decf5364b7e6bde801d3 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 18 Jan 2023 23:04:38 +0530
|
||||
Subject: [PATCH 4/8] appendedsig: While verifying the kernel, use trusted and
|
||||
distrusted lists
|
||||
|
||||
To verify the kernel's, the trusted key will be used from
|
||||
the trusted key list. If it fails, verify it against the list of hashes
|
||||
that are distrusted and trusted.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 187 +++++++++++++------
|
||||
1 file changed, 131 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index 5bb09e349..f9638220e 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -36,6 +36,10 @@
|
||||
#include <grub/platform_keystore.h>
|
||||
#include "appendedsig.h"
|
||||
|
||||
+#define SHA256_LEN 32
|
||||
+#define SHA384_LEN 48
|
||||
+#define SHA512_LEN 64
|
||||
+
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
const char magic[] = "~Module signature appended~\n";
|
||||
@@ -516,6 +520,80 @@ extract_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_get_binary_hash (const grub_size_t binary_hash_size, const grub_uint8_t *data,
|
||||
+ const grub_size_t data_size, grub_uint8_t *hash, grub_size_t *hash_size)
|
||||
+{
|
||||
+ grub_uuid_t guid = { 0 };
|
||||
+
|
||||
+ /* support SHA256, SHA384 and SHA512 for binary hash */
|
||||
+ if (binary_hash_size == SHA256_LEN)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE);
|
||||
+ else if (binary_hash_size == SHA384_LEN)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE);
|
||||
+ else if (binary_hash_size == SHA512_LEN)
|
||||
+ grub_memcpy (&guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE);
|
||||
+ else
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "unsupported hash type (%" PRIuGRUB_SIZE ") and skipping binary hash\n",
|
||||
+ binary_hash_size);
|
||||
+ return GRUB_ERR_UNKNOWN_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ return grub_get_hash (&guid, data, data_size, hash, hash_size);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * verify binary hash against the list of binary hashes that are distrusted
|
||||
+ * and trusted.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_verify_binary_hash (const grub_uint8_t *data, const grub_size_t data_size)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t i = 0, hash_size = 0;
|
||||
+ grub_uint8_t hash[GRUB_MAX_HASH_SIZE] = { 0 };
|
||||
+
|
||||
+ for (i = 0; i < grub_dbx.signature_entries; i++)
|
||||
+ {
|
||||
+ rc = grub_get_binary_hash (grub_dbx.signature_size[i], data, data_size,
|
||||
+ hash, &hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (hash_size == grub_dbx.signature_size[i] &&
|
||||
+ grub_memcmp (grub_dbx.signatures[i], hash, hash_size) == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "the binary hash (%02x%02x%02x%02x) was listed "
|
||||
+ "as distrusted\n", hash[0], hash[1], hash[2], hash[3]);
|
||||
+ return GRUB_ERR_BAD_SIGNATURE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < grub_db.signature_entries; i++)
|
||||
+ {
|
||||
+ rc = grub_get_binary_hash (grub_db.signature_size[i], data, data_size,
|
||||
+ hash, &hash_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ continue;
|
||||
+
|
||||
+ if (hash_size == grub_db.signature_size[i] &&
|
||||
+ grub_memcmp (grub_db.signatures[i], hash, hash_size) == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "verified with a trusted binary hash "
|
||||
+ "(%02x%02x%02x%02x)\n", hash[0], hash[1], hash[2], hash[3]);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_EOF;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * verify the kernel's integrity, the trusted key will be used from
|
||||
+ * the trusted key list. If it fails, verify it against the list of binary hashes
|
||||
+ * that are distrusted and trusted.
|
||||
+ */
|
||||
static grub_err_t
|
||||
grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
{
|
||||
@@ -525,12 +603,12 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
unsigned char *hash;
|
||||
gcry_mpi_t hashmpi;
|
||||
gcry_err_code_t rc;
|
||||
- struct x509_certificate *pk;
|
||||
+ struct x509_certificate *cert;
|
||||
struct grub_appended_signature sig;
|
||||
struct pkcs7_signerInfo *si;
|
||||
int i;
|
||||
|
||||
- if (!grub_db.key_entries)
|
||||
+ if (!grub_db.key_entries && !grub_db.signature_entries)
|
||||
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to verify against"));
|
||||
|
||||
err = extract_appended_signature (buf, bufsize, &sig);
|
||||
@@ -538,70 +616,67 @@ grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
|
||||
return err;
|
||||
|
||||
datasize = bufsize - sig.signature_len;
|
||||
-
|
||||
- for (i = 0; i < sig.pkcs7.signerInfo_count; i++)
|
||||
+ /* checking kernel binary hash is presents in trusted list (db)/distrusted list (dbx) */
|
||||
+ err = grub_verify_binary_hash (buf, datasize);
|
||||
+ if (err == GRUB_ERR_EOF)
|
||||
{
|
||||
- /* This could be optimised in a couple of ways:
|
||||
- - we could only compute hashes once per hash type
|
||||
- - we could track signer information and only verify where IDs match
|
||||
- For now we do the naive O(trusted keys * pkcs7 signers) approach.
|
||||
- */
|
||||
- si = &sig.pkcs7.signerInfos[i];
|
||||
- context = grub_zalloc (si->hash->contextsize);
|
||||
- if (!context)
|
||||
- return grub_errno;
|
||||
-
|
||||
- si->hash->init (context);
|
||||
- si->hash->write (context, buf, datasize);
|
||||
- si->hash->final (context);
|
||||
- hash = si->hash->read (context);
|
||||
-
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "data size %" PRIxGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n",
|
||||
- datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
-
|
||||
- err = GRUB_ERR_BAD_SIGNATURE;
|
||||
- for (pk = grub_db.keys; pk; pk = pk->next)
|
||||
+ /* verifying kernel binary signature using trusted keys from trusted list (db) */
|
||||
+ for (i = 0; i < sig.pkcs7.signerInfo_count; i++)
|
||||
{
|
||||
- rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
|
||||
- if (rc)
|
||||
+ si = &sig.pkcs7.signerInfos[i];
|
||||
+ context = grub_zalloc (si->hash->contextsize);
|
||||
+ if (!context)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ si->hash->init (context);
|
||||
+ si->hash->write (context, buf, datasize);
|
||||
+ si->hash->final (context);
|
||||
+ hash = si->hash->read (context);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig",
|
||||
+ "data size %" PRIxGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n",
|
||||
+ datasize, i, hash[0], hash[1], hash[2], hash[3]);
|
||||
+
|
||||
+ err = GRUB_ERR_BAD_SIGNATURE;
|
||||
+ for (cert = grub_db.keys; cert; cert = cert->next)
|
||||
{
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Error padding hash for RSA verification: %d"), rc);
|
||||
- grub_free (context);
|
||||
- goto cleanup;
|
||||
+ rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, cert->mpis[0]);
|
||||
+ if (rc)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("Error padding hash for RSA verification: %d"), rc);
|
||||
+ grub_free (context);
|
||||
+ pkcs7_signedData_release (&sig.pkcs7);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi, cert->mpis, NULL, NULL);
|
||||
+ gcry_mpi_release (hashmpi);
|
||||
+
|
||||
+ if (rc == 0)
|
||||
+ {
|
||||
+ grub_dprintf ("appendedsig", "verify signer %d with key '%s' succeeded\n",
|
||||
+ i, cert->subject);
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "verify signer %d with key '%s' failed with %d\n",
|
||||
+ i, cert->subject, rc);
|
||||
}
|
||||
|
||||
- rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi,
|
||||
- pk->mpis, NULL, NULL);
|
||||
- gcry_mpi_release (hashmpi);
|
||||
-
|
||||
- if (rc == 0)
|
||||
- {
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "verify signer %d with key '%s' succeeded\n", i,
|
||||
- pk->subject);
|
||||
- err = GRUB_ERR_NONE;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- grub_dprintf ("appendedsig",
|
||||
- "verify signer %d with key '%s' failed with %d\n", i,
|
||||
- pk->subject, rc);
|
||||
- }
|
||||
-
|
||||
- grub_free (context);
|
||||
+ grub_free (context);
|
||||
|
||||
- if (err == GRUB_ERR_NONE)
|
||||
- break;
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
- /* If we didn't verify, provide a neat message */
|
||||
if (err != GRUB_ERR_NONE)
|
||||
- err = grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
- N_("Failed to verify signature against a trusted key"));
|
||||
+ grub_printf ("appendedsig: failed to verify signature with any trusted key\n");
|
||||
+ else
|
||||
+ grub_printf ("appendedsig: successfully verified the signature with a trusted key\n");
|
||||
|
||||
-cleanup:
|
||||
pkcs7_signedData_release (&sig.pkcs7);
|
||||
|
||||
return err;
|
||||
--
|
||||
2.47.0
|
||||
|
684
0005-appendedsig-The-grub-command-s-trusted-and-distruste.patch
Normal file
684
0005-appendedsig-The-grub-command-s-trusted-and-distruste.patch
Normal file
@ -0,0 +1,684 @@
|
||||
From f05acf089fb80fc44112a7feec3529af494a41f7 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 1 Feb 2023 21:42:36 +0530
|
||||
Subject: [PATCH 5/8] appendedsig: The grub command's trusted and distrusted
|
||||
support
|
||||
|
||||
To support the following trusted and distrusted commands
|
||||
|
||||
1. trusted_list:
|
||||
It will show the list of trusted certificates and binary hashes
|
||||
2. distrusted_list:
|
||||
It will show the list of distrusted certificates and binary/certificate hashes
|
||||
3. trusted_certificate:
|
||||
It will add the trusted certificate to the trusted list
|
||||
4. trusted_signature:
|
||||
It will add the certificate/binary hash to the trusted list
|
||||
5. distrusted_certificate:
|
||||
It will remove the trusted certificate from trsuted list
|
||||
6. distrusted_signature:
|
||||
It will add the certificate/binary hash to the distrsuted list
|
||||
|
||||
Note:-
|
||||
The addition/deletion of trusted certificates and binary hashes
|
||||
are not allowed in grub command prompt while secure boot is enabled.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||||
---
|
||||
grub-core/commands/appendedsig/appendedsig.c | 547 ++++++++++++-------
|
||||
1 file changed, 361 insertions(+), 186 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
|
||||
index f9638220e..7d2bba079 100644
|
||||
--- a/grub-core/commands/appendedsig/appendedsig.c
|
||||
+++ b/grub-core/commands/appendedsig/appendedsig.c
|
||||
@@ -123,6 +123,38 @@ static enum
|
||||
check_sigs_forced = 2
|
||||
} check_sigs = check_sigs_no;
|
||||
|
||||
+enum
|
||||
+{
|
||||
+ OPTION_BINARY_HASH = 0,
|
||||
+ OPTION_CERT_HASH = 1
|
||||
+};
|
||||
+
|
||||
+static const struct grub_arg_option options[] =
|
||||
+{
|
||||
+ {"binary-hash", 'b', 0, N_("hash file of the binary."), 0, ARG_TYPE_NONE},
|
||||
+ {"cert-hash", 'c', 1, N_("hash file of the certificate."), 0, ARG_TYPE_NONE},
|
||||
+ {0, 0, 0, 0, 0, 0}
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+grub_printhex (const grub_uint8_t *data, const grub_size_t length)
|
||||
+{
|
||||
+ grub_size_t i, count = 0;
|
||||
+
|
||||
+ for (i = 0; i < length-1; i++)
|
||||
+ {
|
||||
+ grub_printf ("%02x:", data[i]);
|
||||
+ count++;
|
||||
+ if (count == 16)
|
||||
+ {
|
||||
+ grub_printf ("\n\t ");
|
||||
+ count = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ grub_printf ("%02x\n", data[i]);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* GUID can be used to determine the hashing function and
|
||||
* generate the hash using determined hashing function.
|
||||
@@ -396,75 +428,6 @@ grub_env_write_sec (struct grub_env_var *var __attribute__((unused)),
|
||||
return grub_strdup (grub_env_read_sec (NULL, NULL));
|
||||
}
|
||||
|
||||
-static grub_err_t
|
||||
-file_read_all (grub_file_t file, grub_uint8_t **buf, grub_size_t *len)
|
||||
-{
|
||||
- grub_off_t full_file_size;
|
||||
- grub_size_t file_size, total_read_size = 0;
|
||||
- grub_ssize_t read_size;
|
||||
-
|
||||
- full_file_size = grub_file_size (file);
|
||||
- if (full_file_size == GRUB_FILE_SIZE_UNKNOWN)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("Cannot read a file of unknown size into a buffer"));
|
||||
-
|
||||
- if (full_file_size > GRUB_SIZE_MAX)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
- N_("File is too large to read: %" PRIuGRUB_UINT64_T
|
||||
- " bytes"), full_file_size);
|
||||
-
|
||||
- file_size = (grub_size_t) full_file_size;
|
||||
-
|
||||
- *buf = grub_malloc (file_size);
|
||||
- if (!*buf)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
- N_("Could not allocate file data buffer size %"
|
||||
- PRIuGRUB_SIZE), file_size);
|
||||
-
|
||||
- while (total_read_size < file_size)
|
||||
- {
|
||||
- read_size = grub_file_read (file, *buf + total_read_size, file_size - total_read_size);
|
||||
- if (read_size < 0)
|
||||
- {
|
||||
- grub_free (*buf);
|
||||
- return grub_errno;
|
||||
- }
|
||||
- else if (read_size == 0)
|
||||
- {
|
||||
- grub_free (*buf);
|
||||
- return grub_error (GRUB_ERR_IO,
|
||||
- N_("Could not read full file size (%"
|
||||
- PRIuGRUB_SIZE "), only %" PRIuGRUB_SIZE
|
||||
- " bytes read"), file_size, total_read_size);
|
||||
- }
|
||||
-
|
||||
- total_read_size += read_size;
|
||||
- }
|
||||
- *len = file_size;
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
-
|
||||
-static grub_err_t
|
||||
-read_cert_from_file (grub_file_t f, struct x509_certificate *certificate)
|
||||
-{
|
||||
- grub_err_t err;
|
||||
- grub_uint8_t *buf;
|
||||
- grub_size_t file_size;
|
||||
-
|
||||
- err = file_read_all (f, &buf, &file_size);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- return err;
|
||||
-
|
||||
- err = parse_x509_certificate (buf, file_size, certificate);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
- {
|
||||
- grub_free (buf);
|
||||
- return err;
|
||||
- }
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
-
|
||||
static grub_err_t
|
||||
extract_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize,
|
||||
struct grub_appended_signature *sig)
|
||||
@@ -686,159 +649,357 @@ static grub_err_t
|
||||
grub_cmd_verify_signature (grub_command_t cmd __attribute__((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
- grub_file_t f;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
- grub_uint8_t *data;
|
||||
- grub_size_t file_size;
|
||||
+ grub_file_t signed_file = NULL;
|
||||
+ grub_uint8_t *signed_data = NULL;
|
||||
+ grub_ssize_t signed_data_size = 0;
|
||||
+
|
||||
+ if (argc != 1)
|
||||
+ {
|
||||
+ grub_printf (N_("a signed file is expected\n"
|
||||
+ "Example:\n\tverify_appended <SIGNED FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- if (argc < 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
+ if (grub_strlen (args[0]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing signed file"));
|
||||
|
||||
grub_dprintf ("appendedsig", "verifying %s\n", args[0]);
|
||||
|
||||
- f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
|
||||
- if (!f)
|
||||
+ signed_file = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
|
||||
+ if (signed_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("unable to open a signed file"));
|
||||
+
|
||||
+ err = grub_read_file (signed_file, &signed_data, &signed_data_size);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_file_close (signed_file);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (signed_file);
|
||||
+ err = grub_verify_appended_signature (signed_data, signed_data_size);
|
||||
+ grub_free (signed_data);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_trusted_list (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc __attribute__((unused)), char **args __attribute__((unused)))
|
||||
+{
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+ grub_size_t i = 0, cert_num = 1;
|
||||
+
|
||||
+ for (cert = grub_db.keys; cert; cert = cert->next)
|
||||
+ {
|
||||
+ grub_printf (N_("trusted certificate %" PRIuGRUB_SIZE ":\n"), cert_num);
|
||||
+ grub_printf (N_("\tserial: "));
|
||||
+
|
||||
+ for (i = 0; i < cert->serial_len - 1; i++)
|
||||
+ grub_printf ("%02x:", cert->serial[i]);
|
||||
+
|
||||
+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
+ cert_num++;
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < grub_db.signature_entries; i++)
|
||||
{
|
||||
- err = grub_errno;
|
||||
- goto cleanup;
|
||||
+ grub_printf (N_("trusted binary hash %" PRIuGRUB_SIZE ":\n"), i+1);
|
||||
+ grub_printf (N_("\thash: "));
|
||||
+ grub_printhex (grub_db.signatures[i], grub_db.signature_size[i]);
|
||||
}
|
||||
|
||||
- err = file_read_all (f, &data, &file_size);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_distrusted_list (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc __attribute__((unused)),
|
||||
+ char **args __attribute__((unused)))
|
||||
+{
|
||||
+ struct x509_certificate *cert = NULL;
|
||||
+ grub_size_t i = 0, cert_num = 1;
|
||||
+
|
||||
+ for (cert = grub_dbx.keys; cert; cert = cert->next)
|
||||
+ {
|
||||
+ grub_printf (N_("distrusted certificate %" PRIuGRUB_SIZE ":\n"), cert_num);
|
||||
+ grub_printf (N_("\tserial: "));
|
||||
+
|
||||
+ for (i = 0; i < cert->serial_len - 1; i++)
|
||||
+ grub_printf ("%02x:", cert->serial[i]);
|
||||
+
|
||||
+ grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
+ cert_num++;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < grub_dbx.signature_entries; i++)
|
||||
+ {
|
||||
+ grub_printf (N_("distrusted certificate/binary hash %" PRIuGRUB_SIZE ":\n"), i+1);
|
||||
+ grub_printf (N_("\thash: "));
|
||||
+ grub_printhex (grub_dbx.signatures[i], grub_dbx.signature_size[i]);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_trusted_cert (grub_command_t cmd __attribute__((unused)),
|
||||
+ int argc, char **args)
|
||||
+{
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+ grub_file_t cert_file = NULL;
|
||||
+ grub_uint8_t *cert_data = NULL;
|
||||
+ grub_ssize_t cert_data_size = 0;
|
||||
+
|
||||
+ if (argc != 1)
|
||||
+ {
|
||||
+ grub_printf (N_("a trusted X.509 certificate file is expected\n"
|
||||
+ "Example:\n\ttrusted_certificate <CERT FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
+
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of trusted X.509 certificate is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_strlen (args[0]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME,
|
||||
+ N_("missing trusted X.509 certificate file"));
|
||||
+
|
||||
+ cert_file = grub_file_open (args[0], GRUB_FILE_TYPE_CERTIFICATE_TRUST |
|
||||
+ GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (cert_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the trusted X.509 certificate file"));
|
||||
+
|
||||
+ err = grub_read_file (cert_file, &cert_data, &cert_data_size);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
- goto cleanup;
|
||||
+ {
|
||||
+ grub_file_close (cert_file);
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
- err = grub_verify_appended_signature (data, file_size);
|
||||
+ grub_file_close (cert_file);
|
||||
+ err = grub_add_certificate (cert_data, cert_data_size, &grub_db, 1);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_release_trusted_list ();
|
||||
+ grub_release_distrusted_list ();
|
||||
+ grub_error (err, "adding of trusted certificate failed");
|
||||
+ }
|
||||
|
||||
- grub_free (data);
|
||||
+ grub_free (cert_data);
|
||||
|
||||
-cleanup:
|
||||
- if (f)
|
||||
- grub_file_close (f);
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_distrust (grub_command_t cmd __attribute__((unused)),
|
||||
- int argc, char **args)
|
||||
+grub_cmd_trusted_hash (grub_command_t cmd __attribute__((unused)), int argc, char**args)
|
||||
{
|
||||
- unsigned long cert_num, i;
|
||||
- struct x509_certificate *cert, *prev;
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_file_t hash_file = NULL;
|
||||
+ grub_uint8_t *hash_data = NULL;
|
||||
+ grub_ssize_t hash_data_size = 0;
|
||||
|
||||
if (argc != 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("One argument expected"));
|
||||
+ {
|
||||
+ grub_printf (N_("a trusted binary hash file is expected\n"
|
||||
+ "Example:\n\ttrusted_signature <BINARY HASH FILE>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- grub_errno = GRUB_ERR_NONE;
|
||||
- cert_num = grub_strtoul (args[0], NULL, 10);
|
||||
- if (grub_errno != GRUB_ERR_NONE)
|
||||
- return grub_errno;
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of trusted binary hash is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
|
||||
- if (cert_num < 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("Certificate number too small - numbers start at 1"));
|
||||
+ if (grub_strlen (args[0]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing trusted binary hash file"));
|
||||
|
||||
- if (cert_num == 1)
|
||||
- {
|
||||
- cert = grub_db.keys;
|
||||
- grub_db.keys = cert->next;
|
||||
+ hash_file = grub_file_open (args[0], GRUB_FILE_TYPE_TO_HASH | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (hash_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the trusted binary hash file"));
|
||||
|
||||
- certificate_release (cert);
|
||||
- grub_free (cert);
|
||||
- return GRUB_ERR_NONE;
|
||||
+ rc = grub_read_file (hash_file, &hash_data, &hash_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_file_close (hash_file);
|
||||
+ return rc;
|
||||
}
|
||||
- i = 2;
|
||||
- prev = grub_db.keys;
|
||||
- cert = grub_db.keys->next;
|
||||
- while (cert)
|
||||
+
|
||||
+ grub_file_close (hash_file);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "adding a trusted binary hash %s\n with size of %" PRIdGRUB_SSIZE "\n",
|
||||
+ hash_data, hash_data_size);
|
||||
+
|
||||
+ /* only accept SHA256, SHA384 and SHA512 binary hash */
|
||||
+ if (hash_data_size != SHA256_LEN && hash_data_size != SHA384_LEN &&
|
||||
+ hash_data_size != SHA512_LEN)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("unacceptable trusted binary hash type"));
|
||||
+
|
||||
+ rc = grub_add_hash ((const grub_uint8_t **) &hash_data, hash_data_size, &grub_db.signatures,
|
||||
+ &grub_db.signature_size, &grub_db.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
{
|
||||
- if (i == cert_num)
|
||||
- {
|
||||
- prev->next = cert->next;
|
||||
- certificate_release (cert);
|
||||
- grub_free (cert);
|
||||
- return GRUB_ERR_NONE;
|
||||
- }
|
||||
- i++;
|
||||
- prev = cert;
|
||||
- cert = cert->next;
|
||||
+ grub_release_trusted_list ();
|
||||
+ grub_release_distrusted_list ();
|
||||
+ grub_error (rc, "adding of trusted binary hash failed");
|
||||
}
|
||||
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
- N_("No certificate number %lu found - only %lu certificates in the store"),
|
||||
- cert_num, i - 1);
|
||||
+ grub_free (hash_data);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_trust (grub_command_t cmd __attribute__((unused)),
|
||||
- int argc, char **args)
|
||||
+grub_cmd_distrusted_cert (grub_command_t cmd __attribute__((unused)), int argc, char **args)
|
||||
{
|
||||
- grub_file_t certf;
|
||||
- struct x509_certificate *cert = NULL;
|
||||
- grub_err_t err;
|
||||
+ grub_size_t cert_num = 0, i = 1;
|
||||
+ struct x509_certificate *current_cert = grub_db.keys;
|
||||
+ struct x509_certificate *previous_cert = grub_db.keys;
|
||||
|
||||
if (argc != 1)
|
||||
- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||
+ {
|
||||
+ grub_printf (N_("trusted certificate number is expected\n"
|
||||
+ "Example:\n\tdistrusted_certificate <CERT_NUMER>\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- certf = grub_file_open (args[0],
|
||||
- GRUB_FILE_TYPE_CERTIFICATE_TRUST
|
||||
- | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
- if (!certf)
|
||||
- return grub_errno;
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "removing of trusted certificate is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
|
||||
+ cert_num = grub_strtoul (args[0], NULL, 10);
|
||||
+ if (cert_num < 1)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("trusted certificate number should to begin with 1"));
|
||||
|
||||
- cert = grub_zalloc (sizeof (struct x509_certificate));
|
||||
- if (!cert)
|
||||
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
- N_("Could not allocate memory for certificate"));
|
||||
+ if (cert_num > grub_db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("trusted certificate number should not exceed %" PRIuGRUB_SIZE),
|
||||
+ grub_db.key_entries);
|
||||
+ else if (cert_num < grub_db.key_entries)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("there is no certificate on the trusted list. so, not permitted"));
|
||||
|
||||
- err = read_cert_from_file (certf, cert);
|
||||
- grub_file_close (certf);
|
||||
- if (err != GRUB_ERR_NONE)
|
||||
+ for (i = 1; i < grub_db.key_entries; i++)
|
||||
{
|
||||
- grub_free (cert);
|
||||
- return err;
|
||||
+ if (cert_num == 1)
|
||||
+ {
|
||||
+ previous_cert = current_cert->next;
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (cert_num == i)
|
||||
+ {
|
||||
+ previous_cert->next = current_cert->next;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ previous_cert = current_cert;
|
||||
+ current_cert = current_cert->next;
|
||||
}
|
||||
- grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
|
||||
- cert->subject);
|
||||
|
||||
- cert->next = grub_db.keys;
|
||||
- grub_db.keys = cert;
|
||||
+ certificate_release (current_cert);
|
||||
+ grub_free (current_cert);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_list (grub_command_t cmd __attribute__((unused)),
|
||||
- int argc __attribute__((unused)),
|
||||
- char **args __attribute__((unused)))
|
||||
+grub_cmd_distrusted_hash (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
- struct x509_certificate *cert;
|
||||
- int cert_num = 1;
|
||||
- grub_size_t i;
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_file_t hash_file = NULL;
|
||||
+ grub_uint8_t *hash_data = NULL;
|
||||
+ grub_ssize_t hash_data_size = 0;
|
||||
|
||||
- for (cert = grub_db.keys; cert; cert = cert->next)
|
||||
+ if (argc != 2)
|
||||
{
|
||||
- grub_printf (N_("Certificate %d:\n"), cert_num);
|
||||
+ grub_printf (N_("a distrusted certificate/binary hash file is expected\n"
|
||||
+ "Example:\n\tdistrusted_signature [option] <FILE>\n"
|
||||
+ "option:\n[-b|--binary-hash] FILE [BINARY HASH FILE]\n"
|
||||
+ "[-c|--cert-hash] FILE [CERTFICATE HASH FILE]\n"));
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+ }
|
||||
|
||||
- grub_printf (N_("\tSerial: "));
|
||||
- for (i = 0; i < cert->serial_len - 1; i++)
|
||||
- {
|
||||
- grub_printf ("%02x:", cert->serial[i]);
|
||||
- }
|
||||
- grub_printf ("%02x\n", cert->serial[cert->serial_len - 1]);
|
||||
+ if (check_sigs == check_sigs_forced)
|
||||
+ {
|
||||
+ grub_printf ("Warning: since secure boot is enabled, "
|
||||
+ "adding of distrusted certificate/binary hash is not permitted!\n");
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
|
||||
- grub_printf ("\tCN: %s\n\n", cert->subject);
|
||||
- cert_num++;
|
||||
+ if (!ctxt->state[OPTION_BINARY_HASH].set && !ctxt->state[OPTION_CERT_HASH].set)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("missing options and use --help to konw"));
|
||||
+
|
||||
+ if (grub_strlen (args[1]) == 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_FILENAME,
|
||||
+ N_("missing distrusted certificate/binary hash file"));
|
||||
+
|
||||
+ hash_file = grub_file_open (args[1], GRUB_FILE_TYPE_TO_HASH | GRUB_FILE_TYPE_NO_DECOMPRESS);
|
||||
+ if (hash_file == NULL)
|
||||
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
|
||||
+ N_("unable to open the distrusted certificate/binary hash file"));
|
||||
|
||||
+ rc = grub_read_file (hash_file, &hash_data, &hash_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_file_close (hash_file);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
- return GRUB_ERR_NONE;
|
||||
+ grub_file_close (hash_file);
|
||||
+
|
||||
+ grub_dprintf ("appendedsig", "adding a distrusted certificate/binary hash %s\n"
|
||||
+ " with size of %" PRIdGRUB_SSIZE "\n", hash_data, hash_data_size);
|
||||
+
|
||||
+ if (ctxt->state[OPTION_BINARY_HASH].set)
|
||||
+ {
|
||||
+ /* only accept SHA256, SHA384 and SHA512 binary hash */
|
||||
+ if (hash_data_size != SHA256_LEN && hash_data_size != SHA384_LEN &&
|
||||
+ hash_data_size != SHA512_LEN)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("unacceptable distrusted binary hash type"));
|
||||
+ }
|
||||
+ else if (ctxt->state[OPTION_CERT_HASH].set)
|
||||
+ {
|
||||
+ /* only accept SHA256, SHA384 and SHA512 certificate hash */
|
||||
+ if (hash_data_size != SHA256_LEN && hash_data_size != SHA384_LEN &&
|
||||
+ hash_data_size != SHA512_LEN)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
|
||||
+ N_("unacceptable distrusted certificate hash type"));
|
||||
+ }
|
||||
+
|
||||
+ rc = grub_add_hash ((const grub_uint8_t **) &hash_data, hash_data_size, &grub_dbx.signatures,
|
||||
+ &grub_dbx.signature_size, &grub_dbx.signature_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_release_trusted_list ();
|
||||
+ grub_release_distrusted_list ();
|
||||
+ grub_error (rc, "adding of distrusted binary/certificate hash failed");
|
||||
+ }
|
||||
+
|
||||
+ grub_free (hash_data);
|
||||
+
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-appendedsig_init (grub_file_t io __attribute__((unused)),
|
||||
- enum grub_file_type type,
|
||||
- void **context __attribute__((unused)),
|
||||
- enum grub_verify_flags *flags)
|
||||
+appendedsig_init (grub_file_t io __attribute__ ((unused)), enum grub_file_type type,
|
||||
+ void **context __attribute__ ((unused)), enum grub_verify_flags *flags)
|
||||
{
|
||||
if (check_sigs == check_sigs_no)
|
||||
{
|
||||
@@ -1212,7 +1373,9 @@ grub_load_static_keys (struct grub_module_header *header, bool mode)
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
|
||||
+static grub_extcmd_t cmd_distrusted_hash;
|
||||
+static grub_command_t cmd_verify, cmd_trusted_list, cmd_trusted_cert, cmd_trusted_hash,
|
||||
+ cmd_distrusted_list, cmd_distrusted_cert;
|
||||
|
||||
GRUB_MOD_INIT (appendedsig)
|
||||
{
|
||||
@@ -1278,21 +1441,31 @@ GRUB_MOD_INIT (appendedsig)
|
||||
grub_release_platform_keystore ();
|
||||
}
|
||||
|
||||
- cmd_trust =
|
||||
- grub_register_command ("trust_certificate", grub_cmd_trust,
|
||||
- N_("X509_CERTIFICATE"),
|
||||
- N_("Add X509_CERTIFICATE to trusted certificates."));
|
||||
- cmd_list =
|
||||
- grub_register_command ("list_certificates", grub_cmd_list, 0,
|
||||
- N_("Show the list of trusted x509 certificates."));
|
||||
- cmd_verify =
|
||||
- grub_register_command ("verify_appended", grub_cmd_verify_signature,
|
||||
- N_("FILE"),
|
||||
- N_("Verify FILE against the trusted x509 certificates."));
|
||||
- cmd_distrust =
|
||||
- grub_register_command ("distrust_certificate", grub_cmd_distrust,
|
||||
- N_("CERT_NUMBER"),
|
||||
- N_("Remove CERT_NUMBER (as listed by list_certificates) from trusted certificates."));
|
||||
+ cmd_trusted_cert = grub_register_command ("trusted_certificate", grub_cmd_trusted_cert,
|
||||
+ N_("X509_CERTIFICATE"),
|
||||
+ N_("Add X509_CERTIFICATE to trusted list."));
|
||||
+ cmd_trusted_hash = grub_register_command ("trusted_signature", grub_cmd_trusted_hash,
|
||||
+ N_("BINARY HASH FILE"),
|
||||
+ N_("Add trusted BINARY HASH to trusted list."));
|
||||
+ cmd_distrusted_cert = grub_register_command ("distrusted_certificate", grub_cmd_distrusted_cert,
|
||||
+ N_("CERT_NUMBER"),
|
||||
+ N_("Remove CERT_NUMBER (as listed by list_trusted)"
|
||||
+ " from trusted list."));
|
||||
+ cmd_distrusted_hash = grub_register_extcmd ("distrusted_signature", grub_cmd_distrusted_hash, 0,
|
||||
+ N_("[-b|--binary-hash] FILE [BINARY HASH FILE]\n"
|
||||
+ "[-c|--cert-hash] FILE [CERTFICATE HASH FILE]"),
|
||||
+ N_("Add distrusted CERTFICATE/BINARY HASH "
|
||||
+ "to distrusted list."),
|
||||
+ options);
|
||||
+ cmd_trusted_list = grub_register_command ("trusted_list", grub_cmd_trusted_list, 0,
|
||||
+ N_("Show the list of trusted x509 certificates and"
|
||||
+ " trusted binary hashes."));
|
||||
+ cmd_distrusted_list = grub_register_command ("distrusted_list", grub_cmd_distrusted_list, 0,
|
||||
+ N_("Show the list of distrusted certificates and"
|
||||
+ " certificate/binary hashes"));
|
||||
+ cmd_verify = grub_register_command ("verify_appended", grub_cmd_verify_signature, N_("FILE"),
|
||||
+ N_("Verify FILE against the trusted x509 certificates/"
|
||||
+ "trusted binary hashes."));
|
||||
|
||||
grub_verifier_register (&grub_appendedsig_verifier);
|
||||
grub_dl_set_persistent (mod);
|
||||
@@ -1304,10 +1477,12 @@ GRUB_MOD_FINI (appendedsig)
|
||||
* grub_dl_set_persistent should prevent this from actually running, but
|
||||
* it does still run under emu.
|
||||
*/
|
||||
-
|
||||
grub_verifier_unregister (&grub_appendedsig_verifier);
|
||||
grub_unregister_command (cmd_verify);
|
||||
- grub_unregister_command (cmd_list);
|
||||
- grub_unregister_command (cmd_trust);
|
||||
- grub_unregister_command (cmd_distrust);
|
||||
+ grub_unregister_command (cmd_trusted_list);
|
||||
+ grub_unregister_command (cmd_distrusted_list);
|
||||
+ grub_unregister_command (cmd_trusted_cert);
|
||||
+ grub_unregister_command (cmd_distrusted_cert);
|
||||
+ grub_unregister_command (cmd_trusted_hash);
|
||||
+ grub_unregister_extcmd (cmd_distrusted_hash);
|
||||
}
|
||||
--
|
||||
2.47.0
|
||||
|
223
0006-appendedsig-documentation.patch
Normal file
223
0006-appendedsig-documentation.patch
Normal file
@ -0,0 +1,223 @@
|
||||
From 87831c6ce3536e5e2eeb3e2cd8a6184b9509ee04 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 17 Apr 2024 23:04:43 +0530
|
||||
Subject: [PATCH 6/8] appendedsig: documentation
|
||||
|
||||
This explains appended signatures static key and dynamic key,
|
||||
and documents the commands and variables introduced.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
docs/grub.texi | 115 ++++++++++++++++++++++++++++++++++---------------
|
||||
1 file changed, 80 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index 00c5fdc44..68d7cbb90 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -4373,7 +4373,9 @@ you forget a command, you can run the command @command{help}
|
||||
* date:: Display or set current date and time
|
||||
* devicetree:: Load a device tree blob
|
||||
* distrust:: Remove a pubkey from trusted keys
|
||||
-* distrust_certificate:: Remove a certificate from the list of trusted certificates
|
||||
+* distrusted_certificate:: Remove a certificate from the trusted list
|
||||
+* distrusted_list:: List distrusted certificates and binary/certificate hashes
|
||||
+* distrusted_signature:: Add a binary hash to the distrusted list
|
||||
* drivemap:: Map a drive to another
|
||||
* echo:: Display a line of text
|
||||
* efitextmode:: Set/Get text output mode resolution
|
||||
@@ -4390,7 +4392,6 @@ you forget a command, you can run the command @command{help}
|
||||
* hexdump:: Show raw contents of a file or memory
|
||||
* insmod:: Insert a module
|
||||
* keystatus:: Check key modifier status
|
||||
-* list_certificates:: List trusted certificates
|
||||
* list_env:: List variables in environment block
|
||||
* list_trusted:: List trusted public keys
|
||||
* load_env:: Load variables from environment block
|
||||
@@ -4429,7 +4430,9 @@ you forget a command, you can run the command @command{help}
|
||||
* test:: Check file types and compare values
|
||||
* true:: Do nothing, successfully
|
||||
* trust:: Add public key to list of trusted keys
|
||||
-* trust_certificate:: Add an x509 certificate to the list of trusted certificates
|
||||
+* trusted_certificate:: Add an x509 certificate to the trusted list
|
||||
+* trusted_list:: List trusted certificates and binary hashes
|
||||
+* trusted_signature:: Add a binary hash to the trusted list.
|
||||
* unset:: Unset an environment variable
|
||||
@comment * vbeinfo:: List available video modes
|
||||
* verify_appended:: Verify appended digital signature
|
||||
@@ -4776,15 +4779,15 @@ GPG-style digital signatures}, for more information.
|
||||
@end deffn
|
||||
|
||||
|
||||
-@node distrust_certificate
|
||||
-@subsection distrust_certificate
|
||||
+@node distrusted_certificate
|
||||
+@subsection distrusted_certificate
|
||||
|
||||
-@deffn Command distrust_certificate cert_number
|
||||
+@deffn Command distrusted_certificate cert_number
|
||||
Remove the x509 certificate numbered @var{cert_number} from GRUB's keyring of
|
||||
trusted x509 certificates for verifying appended signatures.
|
||||
|
||||
@var{cert_number} is the certificate number as listed by
|
||||
-@command{list_certificates} (@pxref{list_certificates}).
|
||||
+@command{trusted_list} (@pxref{trusted_list}).
|
||||
|
||||
These certificates are used to validate appended signatures when environment
|
||||
variable @code{check_appended_signatures} is set to @code{enforce}
|
||||
@@ -4793,6 +4796,27 @@ variable @code{check_appended_signatures} is set to @code{enforce}
|
||||
information.
|
||||
@end deffn
|
||||
|
||||
+@node distrusted_list
|
||||
+@subsection distrusted_list
|
||||
+
|
||||
+@deffn Command distrusted_list
|
||||
+List all the distrusted x509 certificates and binary/certificate hashes.
|
||||
+The output is a numbered list of certificates and binary/certificate hashes,
|
||||
+showing the certificate's serial number and Common Name.
|
||||
+@end deffn
|
||||
+
|
||||
+@node distrusted_signature
|
||||
+@subsection distrusted_signature
|
||||
+
|
||||
+@deffn Command distrusted_signature
|
||||
+Read a binary hash from the file @var{binary hash file}
|
||||
+and add it to GRUB's internal distrusted list. These hash are used to
|
||||
+restrict validation of linux image integrity using trusted list if appended
|
||||
+signatures validation failed when the environment variable
|
||||
+@code{check_appended_signatures} is set to @code{enforce}.
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
|
||||
@node drivemap
|
||||
@subsection drivemap
|
||||
@@ -5069,22 +5093,6 @@ without any options, the @command{keystatus} command returns true if and
|
||||
only if checking key modifier status is supported.
|
||||
@end deffn
|
||||
|
||||
-
|
||||
-@node list_certificates
|
||||
-@subsection list_certificates
|
||||
-
|
||||
-@deffn Command list_certificates
|
||||
-List all x509 certificates trusted by GRUB for validating appended signatures.
|
||||
-The output is a numbered list of certificates, showing the certificate's serial
|
||||
-number and Common Name.
|
||||
-
|
||||
-The certificate number can be used as an argument to
|
||||
-@command{distrust_certificate} (@pxref{distrust_certificate}).
|
||||
-
|
||||
-See @xref{Using appended signatures} for more information.
|
||||
-@end deffn
|
||||
-
|
||||
-
|
||||
@node list_env
|
||||
@subsection list_env
|
||||
|
||||
@@ -5935,9 +5943,8 @@ and manual booting. @xref{Using GPG-style digital signatures}, for more
|
||||
information.
|
||||
@end deffn
|
||||
|
||||
-
|
||||
-@node trust_certificate
|
||||
-@subsection trust_certificate
|
||||
+@node trusted_certificate
|
||||
+@subsection trusted_certificate
|
||||
|
||||
@deffn Command trust_certificate x509_certificate
|
||||
Read a DER-formatted x509 certificate from the file @var{x509_certificate}
|
||||
@@ -5946,7 +5953,7 @@ certificates are used to validate appended signatures when the environment
|
||||
variable @code{check_appended_signatures} is set to @code{enforce}.
|
||||
|
||||
Note that if @code{check_appended_signatures} is set to @code{enforce}
|
||||
-when @command{trust_certificate} is executed, then @var{x509_certificate}
|
||||
+when @command{trusted_certificate} is executed, then @var{x509_certificate}
|
||||
must itself bear an appended signature. (It is not sufficient that
|
||||
@var{x509_certificate} be signed by a trusted certificate according to the
|
||||
x509 rules: grub does not include support for validating signatures within x509
|
||||
@@ -5955,6 +5962,32 @@ certificates themselves.)
|
||||
See @xref{Using appended signatures} for more information.
|
||||
@end deffn
|
||||
|
||||
+@node trusted_list
|
||||
+@subsection trusted_list
|
||||
+
|
||||
+@deffn Command trusted_list
|
||||
+List all x509 certificates and binary hases trusted by GRUB for validating
|
||||
+appended signatures. The output is a numbered list of certificates and binary
|
||||
+hashes, showing the certificate's serial number and Common Name.
|
||||
+
|
||||
+The certificate number can be used as an argument to
|
||||
+@command{distrusted_certificate} (@pxref{distrusted_certificate}).
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
+
|
||||
+@node trusted_signature
|
||||
+@subsection trusted_signature
|
||||
+
|
||||
+@deffn Command trust_signature
|
||||
+Read a binary hash from the file @var{binary hash file}
|
||||
+and add it to GRUB's internal trusted list. These binary hash are used to
|
||||
+validate linux image integrity if appended signatures validation failed
|
||||
+when the environment variable @code{check_appended_signatures} is set
|
||||
+to @code{enforce}.
|
||||
+
|
||||
+See @xref{Using appended signatures} for more information.
|
||||
+@end deffn
|
||||
|
||||
@node unset
|
||||
@subsection unset
|
||||
@@ -5979,8 +6012,8 @@ only on PC BIOS platforms.
|
||||
|
||||
@deffn Command verify_appended file
|
||||
Verifies an appended signature on @var{file} against the trusted certificates
|
||||
-known to GRUB (See @pxref{list_certificates}, @pxref{trust_certificate}, and
|
||||
-@pxref{distrust_certificate}).
|
||||
+known to GRUB (See @pxref{trusted_list}, @pxref{trusted_certificate}, and
|
||||
+@pxref{distrusted_certificate}).
|
||||
|
||||
Exit code @code{$?} is set to 0 if the signature validates
|
||||
successfully. If validation fails, it is set to a non-zero value.
|
||||
@@ -6664,17 +6697,29 @@ with an appended signature ends with the magic string:
|
||||
where @code{\n} represents the carriage-return character, @code{0x0a}.
|
||||
|
||||
To enable appended signature verification, load the appendedsig module and an
|
||||
-x509 certificate for verification. Building the appendedsig module into the
|
||||
+trusted keys for verification. Building the appendedsig module into the
|
||||
core grub image is recommended.
|
||||
|
||||
-Certificates can be managed at boot time using the @pxref{trust_certificate},
|
||||
-@pxref{distrust_certificate} and @pxref{list_certificates} commands.
|
||||
-Certificates can also be built in to the core image using the @code{--x509}
|
||||
-parameter to @command{grub-install} or @command{grub-mkimage}.
|
||||
+For static key, Certificates will be built in to the core image using
|
||||
+the @code{--x509} parameter to @command{grub-install} or @command{grub-mkimage}.
|
||||
+it can allow to list the trusted certificates and binary hashes at boot time using
|
||||
+@pxref{trusted_list} and list distrusted certificates and binary/certificate hashes
|
||||
+at boot time using @pxref{distrusted_list} commands.
|
||||
+
|
||||
+For dynamic key, loads the signature database (DB) and forbidden
|
||||
+signature database (DBX) from platform keystore (PKS) and it can allow to list
|
||||
+the trusted certificates and binary hashes at boot time using @pxref{trusted_list}
|
||||
+and list distrusted certificates and binary/certificate hashes at boot time using
|
||||
+@pxref{distrusted_list} commands.
|
||||
+
|
||||
+Also, it will not allow to manage add/delete of certificates/signature at boot time using
|
||||
+@pxref{trusted_certificate} and @pxref{trusted_signature}, @pxref{distrusted_certificate}
|
||||
+and @pxref{distrusted_signature} commands when the environment variable
|
||||
+@code{check_appended_signatures} is set to @code{enforce}.
|
||||
|
||||
A file can be explictly verified using the @pxref{verify_appended} command.
|
||||
|
||||
-Only signatures made with the SHA-256 or SHA-512 hash algorithm are supported,
|
||||
+Only signatures made with the SHA-256, SH-384 and SHA-512 hash algorithm are supported,
|
||||
and only RSA signatures are supported.
|
||||
|
||||
A file can be signed with the @command{sign-file} utility supplied with the
|
||||
--
|
||||
2.47.0
|
||||
|
189
0007-mkimage-create-new-ELF-Note-for-SBAT.patch
Normal file
189
0007-mkimage-create-new-ELF-Note-for-SBAT.patch
Normal file
@ -0,0 +1,189 @@
|
||||
From 77316f09f133e9c7c5e1026b2b4f5749daac644a Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 17 Apr 2024 23:48:51 +0530
|
||||
Subject: [PATCH 7/8] mkimage: create new ELF Note for SBAT
|
||||
|
||||
we add a new ELF note for SBAT which store the SBAT data.
|
||||
The name field of shall be the string "Secure-Boot-Advanced-Targeting", zero-padded
|
||||
to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values
|
||||
for the string "sbat").
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Co-authored-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
include/grub/util/mkimage.h | 4 +-
|
||||
util/grub-mkimagexx.c | 92 +++++++++++++++++++++++++++----------
|
||||
2 files changed, 71 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
|
||||
index 6f1da89b9..881e3031f 100644
|
||||
--- a/include/grub/util/mkimage.h
|
||||
+++ b/include/grub/util/mkimage.h
|
||||
@@ -51,12 +51,12 @@ grub_mkimage_load_image64 (const char *kernel_path,
|
||||
const struct grub_install_image_target_desc *image_target);
|
||||
void
|
||||
grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
|
||||
Elf32_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout);
|
||||
void
|
||||
grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
|
||||
Elf64_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout);
|
||||
|
||||
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
|
||||
index 9488f0525..0041b2d0b 100644
|
||||
--- a/util/grub-mkimagexx.c
|
||||
+++ b/util/grub-mkimagexx.c
|
||||
@@ -85,6 +85,14 @@ struct grub_ieee1275_note
|
||||
struct grub_ieee1275_note_desc descriptor;
|
||||
};
|
||||
|
||||
+#define GRUB_SBAT_NOTE_NAME "Secure-Boot-Advanced-Targeting"
|
||||
+#define GRUB_SBAT_NOTE_TYPE 0x73626174 /* "sbat" */
|
||||
+
|
||||
+struct grub_sbat_note {
|
||||
+ Elf32_Nhdr header;
|
||||
+ char name[ALIGN_UP(sizeof(GRUB_SBAT_NOTE_NAME), 4)];
|
||||
+};
|
||||
+
|
||||
#define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature"
|
||||
#define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */
|
||||
|
||||
@@ -217,7 +225,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
|
||||
|
||||
void
|
||||
SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char *sbat, char **core_img, size_t *core_size,
|
||||
Elf_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout)
|
||||
{
|
||||
@@ -226,10 +234,17 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
Elf_Ehdr *ehdr;
|
||||
Elf_Phdr *phdr;
|
||||
Elf_Shdr *shdr;
|
||||
- int header_size, footer_size = 0;
|
||||
+ int header_size, footer_size = 0, footer_offset = 0;
|
||||
int phnum = 1;
|
||||
int shnum = 4;
|
||||
int string_size = sizeof (".text") + sizeof ("mods") + 1;
|
||||
+ char *footer;
|
||||
+
|
||||
+ if (sbat)
|
||||
+ {
|
||||
+ phnum++;
|
||||
+ footer_size += ALIGN_UP (sizeof (struct grub_sbat_note) + layout->sbat_size, 4);
|
||||
+ }
|
||||
|
||||
if (appsig_size)
|
||||
{
|
||||
@@ -263,6 +278,7 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
ehdr = (void *) elf_img;
|
||||
phdr = (void *) (elf_img + sizeof (*ehdr));
|
||||
shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr));
|
||||
+ footer = elf_img + program_size + header_size;
|
||||
memcpy (ehdr->e_ident, ELFMAG, SELFMAG);
|
||||
ehdr->e_ident[EI_CLASS] = ELFCLASSXX;
|
||||
if (!image_target->bigendian)
|
||||
@@ -435,6 +451,8 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE);
|
||||
phdr->p_memsz = 0;
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
+ footer = ptr;
|
||||
+ footer_offset = XEN_NOTE_SIZE;
|
||||
}
|
||||
|
||||
if (image_target->id == IMAGE_XEN_PVH)
|
||||
@@ -468,6 +486,8 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE);
|
||||
phdr->p_memsz = 0;
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
+ footer = ptr;
|
||||
+ footer_offset = XEN_PVH_NOTE_SIZE;
|
||||
}
|
||||
|
||||
if (note)
|
||||
@@ -498,29 +518,55 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
|
||||
phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
phdr->p_memsz = 0;
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
+ footer = (elf_img + program_size + header_size + note_size);
|
||||
+ footer_offset += note_size;
|
||||
}
|
||||
|
||||
- if (appsig_size) {
|
||||
- int note_size = ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
|
||||
- struct grub_appended_signature_note *note_ptr = (struct grub_appended_signature_note *)
|
||||
- (elf_img + program_size + header_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
|
||||
-
|
||||
- note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME));
|
||||
- /* needs to sit at the end, so we round this up and sign some zero padding */
|
||||
- note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(appsig_size, 4));
|
||||
- note_ptr->header.n_type = grub_host_to_target32 (GRUB_APPENDED_SIGNATURE_NOTE_TYPE);
|
||||
- strcpy (note_ptr->name, GRUB_APPENDED_SIGNATURE_NOTE_NAME);
|
||||
-
|
||||
- phdr++;
|
||||
- phdr->p_type = grub_host_to_target32 (PT_NOTE);
|
||||
- phdr->p_flags = grub_host_to_target32 (PF_R);
|
||||
- phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
|
||||
- phdr->p_vaddr = 0;
|
||||
- phdr->p_paddr = 0;
|
||||
- phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
- phdr->p_memsz = 0;
|
||||
- phdr->p_offset = grub_host_to_target32 (header_size + program_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
|
||||
- }
|
||||
+ if (sbat)
|
||||
+ {
|
||||
+ int note_size = ALIGN_UP(sizeof (struct grub_sbat_note) + layout->sbat_size, 4);
|
||||
+ struct grub_sbat_note *note_ptr = (struct grub_sbat_note *)footer;
|
||||
+
|
||||
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_SBAT_NOTE_NAME));
|
||||
+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(layout->sbat_size, 4));
|
||||
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_SBAT_NOTE_TYPE);
|
||||
+ memcpy (note_ptr->name, GRUB_SBAT_NOTE_NAME, sizeof (GRUB_SBAT_NOTE_NAME));
|
||||
+ memcpy ((char *)(note_ptr + 1), sbat, layout->sbat_size);
|
||||
+
|
||||
+ phdr++;
|
||||
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
|
||||
+ phdr->p_flags = grub_host_to_target32 (PF_R);
|
||||
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
|
||||
+ phdr->p_vaddr = 0;
|
||||
+ phdr->p_paddr = 0;
|
||||
+ phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
+ phdr->p_memsz = 0;
|
||||
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size + footer_offset);
|
||||
+
|
||||
+ footer += note_size;
|
||||
+ footer_offset += note_size;
|
||||
+ }
|
||||
+
|
||||
+ if (appsig_size)
|
||||
+ {
|
||||
+ int note_size = ALIGN_UP (sizeof (struct grub_appended_signature_note) + appsig_size, 4);
|
||||
+ struct grub_appended_signature_note *note_ptr = (struct grub_appended_signature_note *)footer;
|
||||
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME));
|
||||
+ /* needs to sit at the end, so we round this up and sign some zero padding */
|
||||
+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP (appsig_size, 4));
|
||||
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_APPENDED_SIGNATURE_NOTE_TYPE);
|
||||
+ strcpy (note_ptr->name, GRUB_APPENDED_SIGNATURE_NOTE_NAME);
|
||||
+
|
||||
+ phdr++;
|
||||
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
|
||||
+ phdr->p_flags = grub_host_to_target32 (PF_R);
|
||||
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
|
||||
+ phdr->p_vaddr = 0;
|
||||
+ phdr->p_paddr = 0;
|
||||
+ phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
+ phdr->p_memsz = 0;
|
||||
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size + footer_offset);
|
||||
+ }
|
||||
|
||||
{
|
||||
char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
|
||||
--
|
||||
2.47.0
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 32d4823762e5a0e7f8bfc5a878d39e1a019392fe Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Thu, 18 Apr 2024 00:00:55 +0530
|
||||
Subject: [PATCH 8/8] mkimage: adding sbat data into sbat ELF Note on powerpc
|
||||
|
||||
it reads the SBAT data from sbat.csv and create the ELF Note for it then
|
||||
store the SBAT data on it while generate image with -s option
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Co-authored-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
util/mkimage.c | 23 +++++++++++++++++------
|
||||
1 file changed, 17 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 0737935fd..136e4a90c 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -958,8 +958,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
total_module_size += dtb_size + sizeof (struct grub_module_header);
|
||||
}
|
||||
|
||||
- if (sbat_path != NULL && image_target->id != IMAGE_EFI)
|
||||
- grub_util_error (_(".sbat section can be embedded into EFI images only"));
|
||||
+ if (sbat_path != NULL && (image_target->id != IMAGE_EFI && image_target->id != IMAGE_PPC))
|
||||
+ grub_util_error (_(".sbat section can be embedded into EFI images/"
|
||||
+ "sbat ELF Note cab be added into powerpc-ieee1275 images only"));
|
||||
|
||||
if (disable_shim_lock)
|
||||
total_module_size += sizeof (struct grub_module_header);
|
||||
@@ -1835,6 +1836,16 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
case IMAGE_I386_IEEE1275:
|
||||
{
|
||||
grub_uint64_t target_addr;
|
||||
+ char *sbat = NULL;
|
||||
+
|
||||
+ if (sbat_path != NULL)
|
||||
+ {
|
||||
+ sbat_size = grub_util_get_image_size (sbat_path);
|
||||
+ sbat = xmalloc (sbat_size);
|
||||
+ grub_util_load_image (sbat_path, sbat);
|
||||
+ layout.sbat_size = sbat_size;
|
||||
+ }
|
||||
+
|
||||
if (image_target->id == IMAGE_LOONGSON_ELF)
|
||||
{
|
||||
if (comp == GRUB_COMPRESSION_NONE)
|
||||
@@ -1846,11 +1857,11 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
else
|
||||
target_addr = image_target->link_addr;
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
- grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img,
|
||||
- &core_size, target_addr, &layout);
|
||||
+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, sbat, &core_img, &core_size,
|
||||
+ target_addr, &layout);
|
||||
else
|
||||
- grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img,
|
||||
- &core_size, target_addr, &layout);
|
||||
+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, sbat, &core_img, &core_size,
|
||||
+ target_addr, &layout);
|
||||
}
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.47.0
|
||||
|
@ -21,6 +21,11 @@ v2 -> v3 (by fvogt@suse.de)
|
||||
|
||||
- make it a runtime decision (bsc#1164385)
|
||||
|
||||
v3 -> v4
|
||||
|
||||
- display the message only when necessary
|
||||
- clear the screen to enhance visual comfort (bsc#1224465)
|
||||
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -552,6 +552,12 @@
|
||||
@ -38,17 +43,25 @@ v2 -> v3 (by fvogt@suse.de)
|
||||
name = grub-mkrescue;
|
||||
--- a/util/grub.d/00_header.in
|
||||
+++ b/util/grub.d/00_header.in
|
||||
@@ -247,6 +247,10 @@
|
||||
@@ -246,6 +246,18 @@
|
||||
fi
|
||||
fi
|
||||
|
||||
cat << EOF
|
||||
+if echo "$GRUB_TERMINAL_OUTPUT" | grep -qwv console &&
|
||||
+ ([ x"$GRUB_TIMEOUT_STYLE" = xmenu ] ||
|
||||
+ ([ x"$GRUB_TIMEOUT_STYLE" = x ] &&
|
||||
+ [ x"$GRUB_HIDDEN_TIMEOUT" = x -o x"$GRUB_HIDDEN_TIMEOUT" = x0 ])); then
|
||||
+ cat <<EOF
|
||||
+ if [ "\${grub_platform}" = "efi" ]; then
|
||||
+ clear
|
||||
+ echo "Please press 't' to show the boot menu on this console"
|
||||
+ fi
|
||||
+EOF
|
||||
+fi
|
||||
+
|
||||
cat << EOF
|
||||
set gfxmode=${GRUB_GFXMODE}
|
||||
load_video
|
||||
insmod gfxterm
|
||||
--- /dev/null
|
||||
+++ b/util/grub.d/95_textmode.in
|
||||
@@ -0,0 +1,12 @@
|
||||
|
@ -22,17 +22,23 @@ minix.
|
||||
[1] https://savannah.gnu.org/bugs/index.php?57652
|
||||
[2] https://bugzilla.opensuse.org/attachment.cgi?id=828118
|
||||
|
||||
v2:
|
||||
We are still encountering the error. Instead of ensuring ext[234] is tried
|
||||
before minix, make sure everything is tried before minix unless its detection
|
||||
issue can be properly addressed.
|
||||
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -51,8 +51,11 @@
|
||||
@@ -51,8 +51,12 @@
|
||||
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libgrub.pp
|
||||
|
||||
+# the grep/sed ensures that ext2 gets initialized before minix*
|
||||
+# the grep/sed ensures that every other file system gets tested before minix*"
|
||||
+# see https://savannah.gnu.org/bugs/?57652
|
||||
+# see https://bugzilla.suse.com/show_bug.cgi?id=1231604
|
||||
libgrub_a_init.lst: libgrub.pp
|
||||
cat $< | grep '^@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
|
||||
+ if grep ^ext2 $@ >/dev/null; then sed '/ext2/d;/newc/iext2' < $@ > $@.tmp && mv $@.tmp $@; fi
|
||||
+ if grep ^minix $@ >/dev/null; then sed -n '/^minix/p;/^minix/!H;$${x;s/^\n//;p}' < $@ > $@.tmp && mv $@.tmp $@; fi
|
||||
CLEANFILES += libgrub_a_init.lst
|
||||
|
||||
libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh
|
||||
|
@ -1,3 +1,89 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 30 00:44:41 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Enable support of Radix, Xive and Radix_gtse on Power (jsc#PED-9881)
|
||||
* 0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 23 06:17:54 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix error: /boot/grub2/x86_64-efi/bli.mod not found (bsc#1231591)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Oct 22 07:34:04 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Keep grub packaging and dependencies in the SLE-12 and SLE-15 builds
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 18 07:42:27 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Power guest secure boot with key management (jsc#PED-3520) (jsc#PED-9892)
|
||||
* 0001-ieee1275-Platform-Keystore-PKS-Support.patch
|
||||
* 0002-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
|
||||
* 0003-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
|
||||
* 0004-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
|
||||
* 0005-appendedsig-The-grub-command-s-trusted-and-distruste.patch
|
||||
* 0006-appendedsig-documentation.patch
|
||||
* 0007-mkimage-create-new-ELF-Note-for-SBAT.patch
|
||||
* 0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch
|
||||
* grub2.spec : Building signed grub.elf with SBAT metadata
|
||||
- Support for NVMe multipath splitter (jsc#PED-10538)
|
||||
* 0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
|
||||
- Deleted path (jsc#PED-10538)
|
||||
* 0001-grub2-Can-t-setup-a-default-boot-device-correctly-on.patch
|
||||
* 0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 16 13:50:00 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix not a directory error from the minix filesystem, as leftover data on disk
|
||||
may contain its magic header so it gets misdetected (bsc#1231604)
|
||||
* grub2-install-fix-not-a-directory-error.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 4 06:58:06 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix missng menu entry "Start bootloader from a read-only snapshot" by
|
||||
ensuring grub2-snapper-plugin is installed when both snapper and grub2-common
|
||||
are installed (bsc#1231271)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 4 06:49:12 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix OOM error in loading loopback file (bsc#1230840)
|
||||
* 0001-tpm-Skip-loopback-image-measurement.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Oct 4 06:41:11 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix UEFI PXE boot failure on tagged VLAN network (bsc#1230263)
|
||||
* 0001-efinet-Skip-virtual-VLAN-devices-during-card-enumera.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Oct 3 08:25:57 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix grub screen is filled with artifects from earlier post menu (bsc#1224465)
|
||||
* grub2-SUSE-Add-the-t-hotkey.patch
|
||||
* 0001-fix-grub-screen-filled-with-post-screen-artifects.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Aug 13 07:12:58 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Introduces a new package, grub2-x86_64-efi-bls, which includes a
|
||||
straightforward grubbls.efi file. This file can be copied to the EFI System
|
||||
Partition (ESP) along with boot fragments in the Boot Loader Specification
|
||||
(BLS) format
|
||||
* 0001-Streamline-BLS-and-improve-PCR-stability.patch
|
||||
- Fix crash in bli module (bsc#1226497)
|
||||
* 0001-bli-Fix-crash-in-get_part_uuid.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Aug 13 02:42:42 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Rework package dependencies: grub2-common now includes common userland
|
||||
utilities and is required by grub2 platform packages. grub2 is now a meta
|
||||
package that pulls in the default platform package.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Aug 2 08:44:40 UTC 2024 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
225
grub2.spec
225
grub2.spec
@ -356,8 +356,6 @@ Patch164: 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
|
||||
Patch165: 0004-ofpath-controller-name-update.patch
|
||||
Patch166: 0002-Mark-environmet-blocks-as-used-for-image-embedding.patch
|
||||
Patch167: grub2-increase-crypttab-path-buffer.patch
|
||||
Patch168: 0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch
|
||||
Patch169: 0001-grub2-Can-t-setup-a-default-boot-device-correctly-on.patch
|
||||
Patch170: 0001-tpm2-Support-authorized-policy.patch
|
||||
Patch171: 0001-tpm2-Add-extra-RSA-SRK-types.patch
|
||||
Patch174: 0001-clean-up-crypttab-and-linux-modules-dependency.patch
|
||||
@ -406,7 +404,48 @@ Patch215: 0008-blscfg-reading-bls-fragments-if-boot-present.patch
|
||||
Patch216: 0009-10_linux-Some-refinement-for-BLS.patch
|
||||
Patch217: 0001-net-drivers-ieee1275-ofnet-Remove-200-ms-timeout-in-.patch
|
||||
Patch218: grub2-s390x-set-hostonly.patch
|
||||
Patch219: 0001-bli-Fix-crash-in-get_part_uuid.patch
|
||||
Patch220: 0001-Streamline-BLS-and-improve-PCR-stability.patch
|
||||
Patch221: 0001-fix-grub-screen-filled-with-post-screen-artifects.patch
|
||||
Patch222: 0001-efinet-Skip-virtual-VLAN-devices-during-card-enumera.patch
|
||||
Patch223: 0001-tpm-Skip-loopback-image-measurement.patch
|
||||
Patch224: 0001-ieee1275-Platform-Keystore-PKS-Support.patch
|
||||
Patch225: 0002-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
|
||||
Patch226: 0003-appendedsig-The-creation-of-trusted-and-distrusted-l.patch
|
||||
Patch227: 0004-appendedsig-While-verifying-the-kernel-use-trusted-a.patch
|
||||
Patch228: 0005-appendedsig-The-grub-command-s-trusted-and-distruste.patch
|
||||
Patch229: 0006-appendedsig-documentation.patch
|
||||
Patch230: 0007-mkimage-create-new-ELF-Note-for-SBAT.patch
|
||||
Patch231: 0008-mkimage-adding-sbat-data-into-sbat-ELF-Note-on-power.patch
|
||||
Patch232: 0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
|
||||
Patch233: 0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
# Always requires a default cpu-platform package
|
||||
Requires: grub2-%{grubarch} = %{version}-%{release}
|
||||
%else
|
||||
%if ! 0%{?only_efi:1}
|
||||
Requires: grub2-%{grubarch} = %{version}-%{release}
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%if 0%{?only_x86_64:1}
|
||||
ExclusiveArch: x86_64
|
||||
%else
|
||||
ExclusiveArch: %{ix86} x86_64 ppc ppc64 ppc64le s390x aarch64 %{arm} riscv64
|
||||
%endif
|
||||
|
||||
%description
|
||||
This is the second version of the GRUB (Grand Unified Bootloader), a
|
||||
highly configurable and customizable bootloader with modular
|
||||
architecture. It support rich scale of kernel formats, file systems,
|
||||
computer architectures and hardware devices.
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%package common
|
||||
Summary: Utilies to manage grub
|
||||
Group: System/Boot
|
||||
%endif
|
||||
Requires: gettext-runtime
|
||||
%if 0%{?suse_version} >= 1140
|
||||
%ifnarch s390x
|
||||
@ -417,9 +456,6 @@ Recommends: os-prober
|
||||
Suggests: libburnia-tools
|
||||
Suggests: mtools
|
||||
%endif
|
||||
%if ! 0%{?only_efi:1}
|
||||
Requires: grub2-%{grubarch} = %{version}-%{release}
|
||||
%endif
|
||||
%ifarch s390x
|
||||
# required utilities by grub2-s390x-04-grub2-install.patch
|
||||
# use 'showconsole' to determine console device. (bnc#876743)
|
||||
@ -436,25 +472,21 @@ Requires: powerpc-utils
|
||||
Recommends: memtest86+
|
||||
%endif
|
||||
|
||||
%if 0%{?only_x86_64:1}
|
||||
ExclusiveArch: x86_64
|
||||
%else
|
||||
ExclusiveArch: %{ix86} x86_64 ppc ppc64 ppc64le s390x aarch64 %{arm} riscv64
|
||||
%endif
|
||||
|
||||
%description
|
||||
This is the second version of the GRUB (Grand Unified Bootloader), a
|
||||
highly configurable and customizable bootloader with modular
|
||||
architecture. It support rich scale of kernel formats, file systems,
|
||||
computer architectures and hardware devices.
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%description common
|
||||
This package includes user space utlities to manage GRUB on your system.
|
||||
%endif
|
||||
|
||||
%package branding-upstream
|
||||
|
||||
Summary: Upstream branding for GRUB2's graphical console
|
||||
Group: System/Fhs
|
||||
BuildArch: noarch
|
||||
%if 0%{?suse_version} > 1600
|
||||
Requires: %{name}-common = %{version}
|
||||
%else
|
||||
Requires: %{name} = %{version}
|
||||
%endif
|
||||
|
||||
%description branding-upstream
|
||||
Upstream branding for GRUB2's graphical console
|
||||
@ -467,8 +499,13 @@ Group: System/Boot
|
||||
%if "%{platform}" != "emu"
|
||||
BuildArch: noarch
|
||||
%endif
|
||||
%if 0%{?suse_version} > 1600
|
||||
Requires: %{name}-common = %{version}
|
||||
Requires(post): %{name}-common = %{version}
|
||||
%else
|
||||
Requires: %{name} = %{version}
|
||||
Requires(post): %{name} = %{version}
|
||||
%endif
|
||||
%{?update_bootloader_requires}
|
||||
|
||||
%description %{grubarch}
|
||||
@ -516,8 +553,13 @@ BuildArch: noarch
|
||||
# Without it grub-install is broken so break the package as well if unavailable
|
||||
Requires: efibootmgr
|
||||
Requires(post): efibootmgr
|
||||
%if 0%{?suse_version} > 1600
|
||||
Requires: %{name}-common = %{version}
|
||||
Requires(post): %{name}-common = %{version}
|
||||
%else
|
||||
Requires: %{name} = %{version}
|
||||
Requires(post): %{name} = %{version}
|
||||
%endif
|
||||
%{?update_bootloader_requires}
|
||||
%{?fde_tpm_update_requires}
|
||||
Provides: %{name}-efi = %{version}-%{release}
|
||||
@ -529,6 +571,16 @@ bootloader with modular architecture. It supports rich variety of kernel format
|
||||
file systems, computer architectures and hardware devices. This subpackage
|
||||
provides support for EFI systems.
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%package %{grubefiarch}-bls
|
||||
Summary: Image for Boot Loader Specification (BLS) support on %{grubefiarch}
|
||||
Group: System/Boot
|
||||
BuildArch: noarch
|
||||
|
||||
%description %{grubefiarch}-bls
|
||||
Custom EFI build tailored for Boot Loader Specification (BLS) support.
|
||||
%endif
|
||||
|
||||
%package %{grubefiarch}-extras
|
||||
|
||||
Summary: Unsupported modules for %{grubefiarch}
|
||||
@ -592,9 +644,14 @@ Unsupported modules for %{name}-%{grubxenarch}
|
||||
|
||||
Summary: Grub2's snapper plugin
|
||||
Group: System/Fhs
|
||||
Requires: %{name} = %{version}
|
||||
Requires: libxml2-tools
|
||||
%if 0%{?suse_version} > 1600
|
||||
Requires: (grub2 or grub2-common)
|
||||
Supplements: ((grub2 or grub2-common) and snapper)
|
||||
%else
|
||||
Requires: %{name} = %{version}
|
||||
Supplements: packageand(snapper:grub2)
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
|
||||
%description snapper-plugin
|
||||
@ -605,9 +662,14 @@ Grub2's snapper plugin for advanced btrfs snapshot boot menu management
|
||||
|
||||
Summary: Grub2's systemd-sleep plugin
|
||||
Group: System/Fhs
|
||||
Requires: grub2
|
||||
Requires: util-linux
|
||||
%if 0%{?suse_version} > 1600
|
||||
Requires: (grub2 or grub2-common)
|
||||
Supplements: ((grub2 or grub2-common) and systemd)
|
||||
%else
|
||||
Requires: grub2
|
||||
Supplements: packageand(systemd:grub2)
|
||||
%endif
|
||||
BuildArch: noarch
|
||||
|
||||
%description systemd-sleep-plugin
|
||||
@ -756,6 +818,59 @@ mksquashfs ./fonts memdisk.sqsh -keep-as-directory -comp xz -quiet -no-progress
|
||||
./grub-mkimage -O %{grubefiarch} -o grub.efi --memdisk=./memdisk.sqsh --prefix= %{?sbat_generation:--sbat sbat.csv} \
|
||||
-d grub-core ${GRUB_MODULES}
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
rm memdisk.sqsh
|
||||
|
||||
# Building grubbls.efi
|
||||
# FIXME: error out if theme_vendor missing
|
||||
theme_vendor=$(find %{_datadir}/%{name}/themes -type f -name activate-theme -exec dirname {} \; -quit)
|
||||
theme_vendor=${theme_vendor##*/}
|
||||
|
||||
# [ -n "$theme_vendor" ] || { echo "ERROR: no grub2 theme vendor found, missing branding package ??"; exit 1 }
|
||||
|
||||
mkdir -p ./boot/grub
|
||||
cp -rf "%{_datadir}/%{name}/themes/$theme_vendor" ./boot/grub/themes
|
||||
rm -f "./boot/grub/themes/activate-theme"
|
||||
|
||||
cat > ./grubbls.cfg <<'EOF'
|
||||
|
||||
regexp --set 1:root '\((.*)\)' "$cmdpath"
|
||||
|
||||
set timeout=8
|
||||
set gfxmode=auto
|
||||
set gfxpayload=keep
|
||||
set enable_blscfg=1
|
||||
|
||||
terminal_input console
|
||||
terminal_output console
|
||||
terminal_output --append gfxterm
|
||||
|
||||
loadfont (memdisk)/boot/grub/themes/DejaVuSans-Bold14.pf2
|
||||
loadfont (memdisk)/boot/grub/themes/DejaVuSans10.pf2
|
||||
loadfont (memdisk)/boot/grub/themes/DejaVuSans12.pf2
|
||||
loadfont (memdisk)/boot/grub/themes/ascii.pf2
|
||||
|
||||
set theme=(memdisk)/boot/grub/themes/theme.txt
|
||||
export theme
|
||||
|
||||
EOF
|
||||
|
||||
%if 0%{?suse_version} > 1500
|
||||
tar --sort=name -cf - ./boot | mksquashfs - memdisk.sqsh -tar -comp xz -quiet -no-progress
|
||||
%else
|
||||
mksquashfs ./boot memdisk.sqsh -keep-as-directory -comp xz -quiet -no-progress
|
||||
%endif
|
||||
|
||||
./grub-mkimage -O %{grubefiarch} \
|
||||
-o grubbls.efi \
|
||||
--memdisk=./memdisk.sqsh \
|
||||
-c ./grubbls.cfg \
|
||||
%{?sbat_generation:--sbat sbat.csv} \
|
||||
-d grub-core \
|
||||
all_video boot font gfxmenu gfxterm gzio halt jpeg minicmd normal part_gpt png reboot video \
|
||||
fat tpm tpm2 memdisk tar squash4 xzio blscfg linux bli regexp loadenv test echo true sleep
|
||||
%endif
|
||||
|
||||
%ifarch x86_64 aarch64
|
||||
if test -e %{_sourcedir}/_projectcert.crt ; then
|
||||
prjsubject=$(openssl x509 -in %{_sourcedir}/_projectcert.crt -noout -subject_hash)
|
||||
@ -786,6 +901,14 @@ cd ..
|
||||
%if ! 0%{?only_efi:1}
|
||||
cd build
|
||||
|
||||
%ifarch ppc ppc64 ppc64le
|
||||
%if 0%{?sbat_generation}
|
||||
echo "sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md" > sbat.csv
|
||||
echo "grub,%{sbat_generation_grub},Free Software Foundation,grub,%{version},https://www.gnu.org/software/grub/" >> sbat.csv
|
||||
echo "grub.%{sbat_distro},%{sbat_generation},%{sbat_distro_summary},%{name},%{version},%{sbat_distro_url}" >> sbat.csv
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%if "%{platform}" != "emu"
|
||||
%define arch_specific --enable-device-mapper
|
||||
TLFLAGS="-static"
|
||||
@ -915,7 +1038,7 @@ fi
|
||||
EOF
|
||||
%{__tar} cvf memdisk.tar ./grub.cfg
|
||||
./grub-mkimage -O %{grubarch} -o grub.elf -d grub-core -x grub.der -m memdisk.tar \
|
||||
-c %{platform}-config --appended-signature-size %brp_pesign_reservation ${GRUB_MODULES}
|
||||
-c %{platform}-config -s sbat.csv --appended-signature-size %brp_pesign_reservation ${GRUB_MODULES}
|
||||
ls -l "grub.elf"
|
||||
truncate -s -%brp_pesign_reservation "grub.elf"
|
||||
fi
|
||||
@ -947,6 +1070,9 @@ install -m 644 grub.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/.
|
||||
%ifarch x86_64
|
||||
ln -srf %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/grub-tpm.efi
|
||||
%endif
|
||||
%if 0%{?suse_version} > 1600
|
||||
install -m 644 grubbls.efi %{buildroot}/%{_datadir}/%{name}/%{grubefiarch}/.
|
||||
%endif
|
||||
|
||||
# Create grub.efi link to system efi directory
|
||||
# This is for tools like kiwi not fiddling with the path
|
||||
@ -968,7 +1094,11 @@ EoM
|
||||
%endif
|
||||
|
||||
%ifarch x86_64 aarch64
|
||||
%if 0%{?suse_version} > 1600
|
||||
export BRP_PESIGN_FILES="%{_datadir}/%{name}/%{grubefiarch}/grub.efi %{_datadir}/%{name}/%{grubefiarch}/grubbls.efi"
|
||||
%else
|
||||
export BRP_PESIGN_FILES="%{_datadir}/%{name}/%{grubefiarch}/grub.efi"
|
||||
%endif
|
||||
install -m 444 grub.der %{buildroot}/%{sysefidir}/
|
||||
%endif
|
||||
|
||||
@ -1101,10 +1231,20 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst
|
||||
%fdupes %buildroot%{_libdir}
|
||||
%fdupes %buildroot%{_datadir}
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%pre common
|
||||
%else
|
||||
|
||||
%pre
|
||||
%endif
|
||||
%service_add_pre grub2-once.service
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%post common
|
||||
%else
|
||||
|
||||
%post
|
||||
%endif
|
||||
%service_add_post grub2-once.service
|
||||
|
||||
%if ! 0%{?only_efi:1}
|
||||
@ -1132,19 +1272,29 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst
|
||||
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%preun common
|
||||
%else
|
||||
|
||||
%preun
|
||||
%endif
|
||||
%service_del_preun grub2-once.service
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%postun common
|
||||
%else
|
||||
|
||||
%postun
|
||||
%endif
|
||||
%service_del_postun grub2-once.service
|
||||
|
||||
%files -f %{name}.lang
|
||||
%defattr(-,root,root,-)
|
||||
%if 0%{?suse_version} < 1500
|
||||
%doc COPYING
|
||||
%if 0%{?suse_version} > 1600
|
||||
%files
|
||||
%else
|
||||
%license COPYING
|
||||
|
||||
%files -f %{name}.lang
|
||||
%endif
|
||||
%defattr(-,root,root,-)
|
||||
%doc AUTHORS
|
||||
%doc NEWS README
|
||||
%doc THANKS TODO ChangeLog
|
||||
@ -1152,6 +1302,16 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst
|
||||
%ifarch s390x
|
||||
%doc README.ibm3215
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%files common -f %{name}.lang
|
||||
%defattr(-,root,root,-)
|
||||
%endif
|
||||
%if 0%{?suse_version} < 1500
|
||||
%doc COPYING
|
||||
%else
|
||||
%license COPYING
|
||||
%endif
|
||||
%dir /boot/%{name}
|
||||
%ghost %attr(600, root, root) /boot/%{name}/grub.cfg
|
||||
%{_datadir}/bash-completion/completions/grub*
|
||||
@ -1162,7 +1322,14 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/05_crypttab
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/10_linux
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/20_linux_xen
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/25_bli
|
||||
# The bli.mod is enabled in grubbls.efi, which will mostly adhere to systemd
|
||||
# standards. But it is not the case for grub.efi, as it serves no purpose
|
||||
# there, among other considerations. Therefore, the 25_bli script that loads
|
||||
# bli.mod as an external module should be disabled (by stripping off its
|
||||
# executable bit) to prevent showing 'file not found' error. This is because
|
||||
# grub.efi may intentionally lack access to external modules, as it is designed
|
||||
# to be a drop-in file, requires no external dependency (boo#1231591)
|
||||
%attr(0644, root, root) %config(noreplace) %{_sysconfdir}/grub.d/25_bli
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/30_uefi-firmware
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/40_custom
|
||||
%config(noreplace) %{_sysconfdir}/grub.d/41_custom
|
||||
@ -1333,6 +1500,12 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst
|
||||
%{sysefidir}/grub.der
|
||||
%endif
|
||||
|
||||
%if 0%{?suse_version} > 1600
|
||||
%files %{grubefiarch}-bls
|
||||
%defattr(-,root,root,-)
|
||||
%{_datadir}/%{name}/%{grubefiarch}/grubbls.efi
|
||||
%endif
|
||||
|
||||
%files %{grubefiarch}-extras -f %{grubefiarch}-mod-extras.lst
|
||||
%defattr(-,root,root,-)
|
||||
%dir %{_datadir}/%{name}/%{grubefiarch}
|
||||
|
Loading…
Reference in New Issue
Block a user