SHA256
1
0
forked from pool/grub2

Accepting request 945751 from home:michael-chang:branches:Base:System

- Power guest secure boot with static keys: GRUB2 signing portion
  (jsc#SLE-18271) (bsc#1192764)
  * grub2.spec
- Power guest secure boot with static keys: GRUB2 portion (jsc#SLE-18144)
  (bsc#1192686)
  * 0001-ieee1275-Drop-HEAP_MAX_ADDR-and-HEAP_MIN_SIZE-consta.patch
  * 0002-ieee1275-claim-more-memory.patch
  * 0003-ieee1275-request-memory-with-ibm-client-architecture.patch
  * 0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
  * 0005-docs-grub-Document-signing-grub-under-UEFI.patch
  * 0006-docs-grub-Document-signing-grub-with-an-appended-sig.patch
  * 0007-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch
  * 0008-pgp-factor-out-rsa_pad.patch
  * 0009-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch
  * 0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch
  * 0011-libtasn1-import-libtasn1-4.18.0.patch
  * 0012-libtasn1-disable-code-not-needed-in-grub.patch
  * 0013-libtasn1-changes-for-grub-compatibility.patch
  * 0014-libtasn1-compile-into-asn1-module.patch
  * 0015-test_asn1-test-module-for-libtasn1.patch
  * 0016-grub-install-support-embedding-x509-certificates.patch
  * 0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch
  * 0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch
  * 0019-appended-signatures-support-verifying-appended-signa.patch
  * 0020-appended-signatures-verification-tests.patch
  * 0021-appended-signatures-documentation.patch
  * 0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch
  * 0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch

- Fix no menuentry is found if hibernation on btrfs RAID1 (bsc#1193090)

OBS-URL: https://build.opensuse.org/request/show/945751
OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=401
This commit is contained in:
Michael Chang 2022-01-12 07:31:19 +00:00 committed by Git OBS Bridge
parent 005c99a035
commit d6d145b71a
26 changed files with 18060 additions and 25 deletions

View File

@ -0,0 +1,82 @@
From 41589d37934c7e4c464a584939de0137af7a181b Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 20 Jul 2021 17:14:46 -0400
Subject: [PATCH 01/23] ieee1275: Drop HEAP_MAX_ADDR and HEAP_MIN_SIZE
constants
The HEAP_MAX_ADDR is confusing. Currently it is set to 32MB, except on
ieee1275 on x86, where it is 64MB.
There is a comment which purports to explain it:
/* If possible, we will avoid claiming heap above this address, because it
seems to cause relocation problems with OSes that link at 4 MiB */
This doesn't make a lot of sense when the constants are well above 4MB
already. It was not always this way. Prior to commit 7b5d0fe4440c
(Increase heap limit) in 2010, HEAP_MAX_SIZE and HEAP_MAX_ADDR were
indeed 4MB. However, when the constants were increased the comment was
left unchanged.
It's been over a decade. It doesn't seem like we have problems with
claims over 4MB on powerpc or x86 ieee1275. The SPARC does things
completely differently and never used the constant.
Drop the constant and the check.
The only use of HEAP_MIN_SIZE was to potentially override the
HEAP_MAX_ADDR check. It is now unused. Remove it too.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/ieee1275/init.c | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 1187492ae..c15d40e55 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -45,9 +45,6 @@
#include <grub/machine/kernel.h>
#endif
-/* The minimal heap size we can live with. */
-#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024)
-
/* The maximum heap size we're going to claim */
#ifdef __i386__
#define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024)
@@ -55,14 +52,6 @@
#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024)
#endif
-/* If possible, we will avoid claiming heap above this address, because it
- seems to cause relocation problems with OSes that link at 4 MiB */
-#ifdef __i386__
-#define HEAP_MAX_ADDR (unsigned long) (64 * 1024 * 1024)
-#else
-#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024)
-#endif
-
extern char _start[];
extern char _end[];
@@ -184,12 +173,6 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
if (*total + len > HEAP_MAX_SIZE)
len = HEAP_MAX_SIZE - *total;
- /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */
- if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */
- (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */
- (*total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */
- len = HEAP_MAX_ADDR - addr;
-
/* In theory, firmware should already prevent this from happening by not
listing our own image in /memory/available. The check below is intended
as a safeguard in case that doesn't happen. However, it doesn't protect
--
2.31.1

View File

@ -0,0 +1,242 @@
From 7f2590e8715b634ffea9cb7b538ac076d86fab40 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Wed, 15 Apr 2020 23:28:29 +1000
Subject: [PATCH 02/23] ieee1275: claim more memory
On powerpc-ieee1275, we are running out of memory trying to verify
anything. This is because:
- we have to load an entire file into memory to verify it. This is
extremely difficult to change with appended signatures.
- We only have 32MB of heap.
- Distro kernels are now often around 30MB.
So we want to claim more memory from OpenFirmware for our heap.
There are some complications:
- The grub mm code isn't the only thing that will make claims on
memory from OpenFirmware:
* PFW/SLOF will have claimed some for their own use.
* The ieee1275 loader will try to find other bits of memory that we
haven't claimed to place the kernel and initrd when we go to boot.
* Once we load Linux, it will also try to claim memory. It claims
memory without any reference to /memory/available, it just starts
at min(top of RMO, 768MB) and works down. So we need to avoid this
area. See arch/powerpc/kernel/prom_init.c as of v5.11.
- The smallest amount of memory a ppc64 KVM guest can have is 256MB.
It doesn't work with distro kernels but can work with custom kernels.
We should maintain support for that. (ppc32 can boot with even less,
and we shouldn't break that either.)
- Even if a VM has more memory, the memory OpenFirmware makes available
as Real Memory Area can be restricted. A freshly created LPAR on a
PowerVM machine is likely to have only 256MB available to OpenFirmware
even if it has many gigabytes of memory allocated.
EFI systems will attempt to allocate 1/4th of the available memory,
clamped to between 1M and 1600M. That seems like a good sort of
approach, we just need to figure out if 1/4 is the right fraction
for us.
We don't know in advance how big the kernel and initrd are going to be,
which makes figuring out how much memory we can take a bit tricky.
To figure out how much memory we should leave unused, I looked at:
- an Ubuntu 20.04.1 ppc64le pseries KVM guest:
vmlinux: ~30MB
initrd: ~50MB
- a RHEL8.2 ppc64le pseries KVM guest:
vmlinux: ~30MB
initrd: ~30MB
Ubuntu VMs struggle to boot with just 256MB under SLOF.
RHEL likewise has a higher minimum supported memory figure.
So lets first consider a distro kernel and 512MB of addressible memory.
(This is the default case for anything booting under PFW.) Say we lose
131MB to PFW (based on some tests). This leaves us 381MB. 1/4 of 381MB
is ~95MB. That should be enough to verify a 30MB vmlinux and should
leave plenty of space to load Linux and the initrd.
If we consider 256MB of RMA under PFW, we have just 125MB remaining. 1/4
of that is a smidge under 32MB, which gives us very poor odds of verifying
a distro-sized kernel. However, if we need 80MB just to put the kernel
and initrd in memory, we can't claim any more than 45MB anyway. So 1/4
will do. We'll come back to this later.
grub is always built as a 32-bit binary, even if it's loading a ppc64
kernel. So we can't address memory beyond 4GB. This gives a natural cap
of 1GB for powerpc-ieee1275.
Also apply this 1/4 approach to i386-ieee1275, but keep the 32MB cap.
make check still works for both i386 and powerpc and I've booted
powerpc grub with this change under SLOF and PFW.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub-dev.texi | 6 ++-
grub-core/kern/ieee1275/init.c | 70 ++++++++++++++++++++++++++++------
2 files changed, 62 insertions(+), 14 deletions(-)
diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
index 6c629a23e..c11f1ac46 100644
--- a/docs/grub-dev.texi
+++ b/docs/grub-dev.texi
@@ -1047,7 +1047,9 @@ space is limited to 4GiB. GRUB allocates pages from EFI for its heap, at most
1.6 GiB.
On i386-ieee1275 and powerpc-ieee1275 GRUB uses same stack as IEEE1275.
-It allocates at most 32MiB for its heap.
+
+On i386-ieee1275, GRUB allocates at most 32MiB for its heap. On
+powerpc-ieee1275, GRUB allocates up to 1GiB.
On sparc64-ieee1275 stack is 256KiB and heap is 2MiB.
@@ -1075,7 +1077,7 @@ In short:
@item i386-qemu @tab 60 KiB @tab < 4 GiB
@item *-efi @tab ? @tab < 1.6 GiB
@item i386-ieee1275 @tab ? @tab < 32 MiB
-@item powerpc-ieee1275 @tab ? @tab < 32 MiB
+@item powerpc-ieee1275 @tab ? @tab < 1 GiB
@item sparc64-ieee1275 @tab 256KiB @tab 2 MiB
@item arm-uboot @tab 256KiB @tab 2 MiB
@item mips(el)-qemu_mips @tab 2MiB @tab 253 MiB
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index c15d40e55..d661a8da5 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -45,11 +45,12 @@
#include <grub/machine/kernel.h>
#endif
-/* The maximum heap size we're going to claim */
+/* The maximum heap size we're going to claim. Not used by sparc.
+ We allocate 1/4 of the available memory under 4G, up to this limit. */
#ifdef __i386__
#define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024)
-#else
-#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024)
+#else // __powerpc__
+#define HEAP_MAX_SIZE (unsigned long) (1 * 1024 * 1024 * 1024)
#endif
extern char _start[];
@@ -146,16 +147,45 @@ grub_claim_heap (void)
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}
#else
-/* Helper for grub_claim_heap. */
+/* Helper for grub_claim_heap on powerpc. */
+static int
+heap_size (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
+ void *data)
+{
+ grub_uint32_t total = *(grub_uint32_t *)data;
+
+ if (type != GRUB_MEMORY_AVAILABLE)
+ return 0;
+
+ /* Do not consider memory beyond 4GB */
+ if (addr > 0xffffffffUL)
+ return 0;
+
+ if (addr + len > 0xffffffffUL)
+ len = 0xffffffffUL - addr;
+
+ total += len;
+ *(grub_uint32_t *)data = total;
+
+ return 0;
+}
+
static int
heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
void *data)
{
- unsigned long *total = data;
+ grub_uint32_t total = *(grub_uint32_t *)data;
if (type != GRUB_MEMORY_AVAILABLE)
return 0;
+ /* Do not consider memory beyond 4GB */
+ if (addr > 0xffffffffUL)
+ return 0;
+
+ if (addr + len > 0xffffffffUL)
+ len = 0xffffffffUL - addr;
+
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM))
{
if (addr + len <= 0x180000)
@@ -169,10 +199,6 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
}
len -= 1; /* Required for some firmware. */
- /* Never exceed HEAP_MAX_SIZE */
- if (*total + len > HEAP_MAX_SIZE)
- len = HEAP_MAX_SIZE - *total;
-
/* In theory, firmware should already prevent this from happening by not
listing our own image in /memory/available. The check below is intended
as a safeguard in case that doesn't happen. However, it doesn't protect
@@ -184,6 +210,18 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
len = 0;
}
+ /* If this block contains 0x30000000 (768MB), do not claim below that.
+ Linux likes to claim memory at min(RMO top, 768MB) and works down
+ without reference to /memory/available. */
+ if ((addr < 0x30000000) && ((addr + len) > 0x30000000))
+ {
+ len = len - (0x30000000 - addr);
+ addr = 0x30000000;
+ }
+
+ if (len > total)
+ len = total;
+
if (len)
{
grub_err_t err;
@@ -192,10 +230,12 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
if (err)
return err;
grub_mm_init_region ((void *) (grub_addr_t) addr, len);
+ total -= len;
}
- *total += len;
- if (*total >= HEAP_MAX_SIZE)
+ *(grub_uint32_t *)data = total;
+
+ if (total == 0)
return 1;
return 0;
@@ -204,7 +244,13 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
static void
grub_claim_heap (void)
{
- unsigned long total = 0;
+ grub_uint32_t total = 0;
+
+ grub_machine_mmap_iterate (heap_size, &total);
+
+ total = total / 4;
+ if (total > HEAP_MAX_SIZE)
+ total = HEAP_MAX_SIZE;
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM))
heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN,
--
2.31.1

View File

@ -0,0 +1,263 @@
From bbfcae1cd408c4922ddcefc0528bfe19da845c90 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 16 Apr 2021 11:48:46 +1000
Subject: [PATCH 03/23] ieee1275: request memory with
ibm,client-architecture-support
On PowerVM, the first time we boot a Linux partition, we may only get
256MB of real memory area, even if the partition has more memory.
This isn't really enough. Fortunately, the Power Architecture Platform
Reference (PAPR) defines a method we can call to ask for more memory.
This is part of the broad and powerful ibm,client-architecture-support
(CAS) method.
CAS can do an enormous amount of things on a PAPR platform: as well as
asking for memory, you can set the supported processor level, the interrupt
controller, hash vs radix mmu, and so on. We want to touch as little of
this as possible because we don't want to step on the toes of the future OS.
If:
- we are running under what we think is PowerVM (compatible property of /
begins with "IBM"), and
- the full amount of RMA is less than 512MB (as determined by the reg
property of /memory)
then call CAS as follows: (refer to the Linux on Power Architecture
Reference, LoPAR, which is public, at B.5.2.3):
- Use the "any" PVR value and supply 2 option vectors.
- Set option vector 1 (PowerPC Server Processor Architecture Level)
to "ignore".
- Set option vector 2 with default or Linux-like options, including a
min-rma-size of 512MB.
This will cause a CAS reboot and the partition will restart with 512MB
of RMA. Grub will notice the 512MB and not call CAS again.
(A partition can be configured with only 256MB of memory, which would
mean this request couldn't be satisfied, but PFW refuses to load with
only 256MB of memory, so it's a bit moot. SLOF will run fine with 256MB,
but we will never call CAS under qemu/SLOF because /compatible won't
begin with "IBM".)
One of the first things Linux does while still running under OpenFirmware
is to call CAS with a much fuller set of options (including asking for
512MB of memory). This includes a much more restrictive set of PVR values
and processor support levels, and this will induce another reboot. On this
reboot grub will again notice the higher RMA, and not call CAS. We will get
to Linux, Linux will call CAS but because the values are now set for Linux
this will not induce another CAS reboot and we will finally boot.
On all subsequent boots, everything will be configured with 512MB of RMA
and all the settings Linux likes, so there will be no further CAS reboots.
(phyp is super sticky with the RMA size - it persists even on cold boots.
So if you've ever booted Linux in a partition, you'll probably never have
grub call CAS. It'll only ever fire the first time a partition loads grub,
or if you deliberately lower the amount of memory your partition has below
512MB.)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/kern/ieee1275/cmain.c | 3 +
grub-core/kern/ieee1275/init.c | 140 +++++++++++++++++++++++++++++++
include/grub/ieee1275/ieee1275.h | 8 +-
3 files changed, 150 insertions(+), 1 deletion(-)
diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c
index e9a184657..ee63c7b71 100644
--- a/grub-core/kern/ieee1275/cmain.c
+++ b/grub-core/kern/ieee1275/cmain.c
@@ -127,6 +127,9 @@ grub_ieee1275_find_options (void)
break;
}
}
+
+ if (grub_strncmp (tmp, "IBM,", 4) == 0)
+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY);
}
if (is_smartfirmware)
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index d661a8da5..446201165 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -241,11 +241,151 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
return 0;
}
+/* How much memory does OF believe it has? (regardless of whether
+ it's accessible or not) */
+static grub_err_t
+grub_ieee1275_total_mem (grub_uint64_t *total)
+{
+ grub_ieee1275_phandle_t root;
+ grub_ieee1275_phandle_t memory;
+ grub_uint32_t reg[4];
+ grub_ssize_t reg_size;
+ grub_uint32_t address_cells = 1;
+ grub_uint32_t size_cells = 1;
+ grub_uint64_t size;
+
+ /* If we fail to get to the end, report 0. */
+ *total = 0;
+
+ /* Determine the format of each entry in `reg'. */
+ grub_ieee1275_finddevice ("/", &root);
+ grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells,
+ sizeof address_cells, 0);
+ grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells,
+ sizeof size_cells, 0);
+
+ if (size_cells > address_cells)
+ address_cells = size_cells;
+
+ /* Load `/memory/reg'. */
+ if (grub_ieee1275_finddevice ("/memory", &memory))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+ "couldn't find /memory node");
+ if (grub_ieee1275_get_integer_property (memory, "reg", reg,
+ sizeof reg, &reg_size))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+ "couldn't examine /memory/reg property");
+ if (reg_size < 0 || (grub_size_t) reg_size > sizeof (reg))
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
+ "/memory response buffer exceeded");
+
+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS))
+ {
+ address_cells = 1;
+ size_cells = 1;
+ }
+
+ /* Decode only the size */
+ size = reg[address_cells];
+ if (size_cells == 2)
+ size = (size << 32) | reg[address_cells + 1];
+
+ *total = size;
+
+ return grub_errno;
+}
+
+/* Based on linux - arch/powerpc/kernel/prom_init.c */
+struct option_vector2 {
+ grub_uint8_t byte1;
+ grub_uint16_t reserved;
+ grub_uint32_t real_base;
+ grub_uint32_t real_size;
+ grub_uint32_t virt_base;
+ grub_uint32_t virt_size;
+ grub_uint32_t load_base;
+ grub_uint32_t min_rma;
+ grub_uint32_t min_load;
+ grub_uint8_t min_rma_percent;
+ grub_uint8_t max_pft_size;
+} __attribute__((packed));
+
+struct pvr_entry {
+ grub_uint32_t mask;
+ grub_uint32_t entry;
+};
+
+struct cas_vector {
+ struct {
+ struct pvr_entry terminal;
+ } pvr_list;
+ grub_uint8_t num_vecs;
+ grub_uint8_t vec1_size;
+ grub_uint8_t vec1;
+ grub_uint8_t vec2_size;
+ struct option_vector2 vec2;
+} __attribute__((packed));
+
+/* Call ibm,client-architecture-support to try to get more RMA.
+ We ask for 512MB which should be enough to verify a distro kernel.
+ We ignore most errors: if we don't succeed we'll proceed with whatever
+ memory we have. */
+static void
+grub_ieee1275_ibm_cas (void)
+{
+ int rc;
+ grub_ieee1275_ihandle_t root;
+ struct cas_args {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_ihandle_t ihandle;
+ grub_ieee1275_cell_t cas_addr;
+ grub_ieee1275_cell_t result;
+ } args;
+ struct cas_vector vector = {
+ .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
+ .num_vecs = 2 - 1,
+ .vec1_size = 0,
+ .vec1 = 0x80, /* ignore */
+ .vec2_size = 1 + sizeof(struct option_vector2) - 2,
+ .vec2 = {
+ 0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48
+ },
+ };
+
+ INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
+ args.method = (grub_ieee1275_cell_t)"ibm,client-architecture-support";
+ rc = grub_ieee1275_open("/", &root);
+ if (rc) {
+ grub_error (GRUB_ERR_IO, "could not open root when trying to call CAS");
+ return;
+ }
+ args.ihandle = root;
+ args.cas_addr = (grub_ieee1275_cell_t)&vector;
+
+ grub_printf("Calling ibm,client-architecture-support...");
+ IEEE1275_CALL_ENTRY_FN (&args);
+ grub_printf("done\n");
+
+ grub_ieee1275_close(root);
+}
+
static void
grub_claim_heap (void)
{
grub_uint32_t total = 0;
+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY))
+ {
+ grub_uint64_t rma_size;
+ grub_err_t err;
+
+ err = grub_ieee1275_total_mem (&rma_size);
+ /* if we have an error, don't call CAS, just hope for the best */
+ if (!err && rma_size < (512 * 1024 * 1024))
+ grub_ieee1275_ibm_cas();
+ }
+
grub_machine_mmap_iterate (heap_size, &total);
total = total / 4;
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
index debb7086a..591f4f12c 100644
--- a/include/grub/ieee1275/ieee1275.h
+++ b/include/grub/ieee1275/ieee1275.h
@@ -155,7 +155,13 @@ enum grub_ieee1275_flag
GRUB_IEEE1275_FLAG_RAW_DEVNAMES,
- GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT
+ GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT,
+
+ /* On PFW, the first time we boot a Linux partition, we may only get 256MB
+ of real memory area, even if the partition has more memory. Set this flag
+ if we think we're running under PFW. Then, if this flag is set, and the
+ RMA is only 256MB in size, try asking for more with CAS. */
+ GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY,
};
extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag);
--
2.31.1

View File

@ -0,0 +1,314 @@
From cf6b16f113b1b5e6efce79b569be1de3e504de8f Mon Sep 17 00:00:00 2001
From: Rashmica Gupta <rashmica.g@gmail.com>
Date: Thu, 11 Jun 2020 11:26:23 +1000
Subject: [PATCH 04/23] Add suport for signing grub with an appended signature
Add infrastructure to allow firmware to verify the integrity of grub
by use of a Linux-kernel-module-style appended signature. We initially
target powerpc-ieee1275, but the code should be extensible to other
platforms.
Usually these signatures are appended to a file without modifying the
ELF file itself. (This is what the 'sign-file' tool does, for example.)
The verifier loads the signed file from the file system and looks at the
end of the file for the appended signature. However, on powerpc-ieee1275
platforms, the bootloader is often stored directly in the PReP partition
as raw bytes without a file-system. This makes determining the location
of an appended signature more difficult.
To address this, we add a new ELF note.
The name field of shall be the string "Appended-Signature", zero-padded
to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values
for the string "ASig"). It must be the final section in the ELF binary.
The description shall contain the appended signature structure as defined
by the Linux kernel. The description will also be padded to be a multiple
of 4 bytes. The padding shall be added before the appended signature
structure (not at the end) so that the final bytes of a signed ELF file
are the appended signature magic.
A subsequent patch documents how to create a grub core.img validly signed
under this scheme.
Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
---
You can experiment with this code with a patched version of SLOF
that verifies these signatures. You can find one at:
https://github.com/daxtens/SLOF
I will be proposing this for inclusion in a future Power Architecture
Platform Reference (PAPR).
---
include/grub/util/install.h | 8 ++++++--
include/grub/util/mkimage.h | 4 ++--
util/grub-install-common.c | 15 +++++++++++---
util/grub-mkimage.c | 11 +++++++++++
util/grub-mkimagexx.c | 39 ++++++++++++++++++++++++++++++++++++-
util/mkimage.c | 13 +++++++------
6 files changed, 76 insertions(+), 14 deletions(-)
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 9e83e1339..0b2e8a06d 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -67,6 +67,9 @@
N_("SBAT metadata"), 0 }, \
{ "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \
N_("disable shim_lock verifier"), 0 }, \
+ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
+ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
+ 1}, \
{ "verbose", 'v', 0, 0, \
N_("print verbose messages."), 1 }
@@ -129,7 +132,8 @@ enum grub_install_options {
GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
GRUB_INSTALL_OPTIONS_DTB,
GRUB_INSTALL_OPTIONS_SBAT,
- GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK
+ GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
};
extern char *grub_install_source_directory;
@@ -189,7 +193,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
size_t npubkeys,
char *config_path,
const struct grub_install_image_target_desc *image_target,
- int note,
+ int note, size_t appsig_size,
grub_compression_t comp, const char *dtb_file,
const char *sbat_path, const int disable_shim_lock);
diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h
index 3819a6744..6f1da89b9 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, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, 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, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
Elf64_Addr target_addr,
struct grub_mkimage_layout *layout);
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index c6c561292..954df20eb 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -461,10 +461,12 @@ static size_t npubkeys;
static char *sbat;
static int disable_shim_lock;
static grub_compression_t compression;
+static size_t appsig_size;
int
grub_install_parse (int key, char *arg)
{
+ const char *end;
switch (key)
{
case 'C':
@@ -562,6 +564,12 @@ grub_install_parse (int key, char *arg)
grub_util_error (_("Unrecognized compression `%s'"), arg);
case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
return 1;
+ case GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE:
+ grub_errno = 0;
+ appsig_size = grub_strtol(arg, &end, 10);
+ if (grub_errno)
+ return 0;
+ return 1;
default:
return 0;
}
@@ -661,10 +669,11 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
" --output '%s' "
" --dtb '%s' "
"--sbat '%s' "
- "--format '%s' --compression '%s' %s %s %s\n",
+ "--format '%s' --compression '%s' "
+ "--appended-signature-size %zu %s %s %s\n",
dir, prefix,
outname, dtb ? : "", sbat ? : "", mkimage_target,
- compnames[compression], note ? "--note" : "",
+ compnames[compression], appsig_size, note ? "--note" : "",
disable_shim_lock ? "--disable-shim-lock" : "", s);
free (s);
@@ -675,7 +684,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
grub_install_generate_image (dir, prefix, fp, outname,
modules.entries, memdisk_path,
pubkeys, npubkeys, config_path, tgt,
- note, compression, dtb, sbat,
+ note, appsig_size, compression, dtb, sbat,
disable_shim_lock);
while (dc--)
grub_install_pop_module ();
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
index c0d559937..d01eaeb84 100644
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -84,6 +84,7 @@ static struct argp_option options[] = {
{"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
{"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
+ {"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0},
{ 0, 0, 0, 0, 0, 0 }
};
@@ -128,6 +129,7 @@ struct arguments
char *sbat;
int note;
int disable_shim_lock;
+ size_t appsig_size;
const struct grub_install_image_target_desc *image_target;
grub_compression_t comp;
};
@@ -138,6 +140,7 @@ argp_parser (int key, char *arg, struct argp_state *state)
/* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */
struct arguments *arguments = state->input;
+ const char* end;
switch (key)
{
@@ -170,6 +173,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
arguments->note = 1;
break;
+ case 'S':
+ grub_errno = 0;
+ arguments->appsig_size = grub_strtol(arg, &end, 10);
+ if (grub_errno)
+ return 0;
+ break;
+
case 'm':
if (arguments->memdisk)
free (arguments->memdisk);
@@ -324,6 +334,7 @@ main (int argc, char *argv[])
arguments.memdisk, arguments.pubkeys,
arguments.npubkeys, arguments.config,
arguments.image_target, arguments.note,
+ arguments.appsig_size,
arguments.comp, arguments.dtb,
arguments.sbat, arguments.disable_shim_lock);
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index d78fa3e53..393119486 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -84,6 +84,15 @@ struct grub_ieee1275_note
struct grub_ieee1275_note_desc descriptor;
};
+#define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature"
+#define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */
+
+struct grub_appended_signature_note
+{
+ Elf32_Nhdr header;
+ char name[ALIGN_UP(sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME), 4)];
+};
+
#define GRUB_XEN_NOTE_NAME "Xen"
struct fixup_block_list
@@ -207,7 +216,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, char **core_img, size_t *core_size,
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
Elf_Addr target_addr,
struct grub_mkimage_layout *layout)
{
@@ -221,6 +230,12 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
int shnum = 4;
int string_size = sizeof (".text") + sizeof ("mods") + 1;
+ if (appsig_size)
+ {
+ phnum++;
+ footer_size += ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
+ }
+
if (image_target->id != IMAGE_LOONGSON_ELF)
phnum += 2;
@@ -484,6 +499,28 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc
phdr->p_offset = grub_host_to_target32 (header_size + program_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));
+ }
+
{
char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
+ shnum * sizeof (*shdr));
diff --git a/util/mkimage.c b/util/mkimage.c
index a26cf76f7..d2cb33883 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -869,8 +869,9 @@ grub_install_generate_image (const char *dir, const char *prefix,
char *memdisk_path, char **pubkey_paths,
size_t npubkeys, char *config_path,
const struct grub_install_image_target_desc *image_target,
- int note, grub_compression_t comp, const char *dtb_path,
- const char *sbat_path, int disable_shim_lock)
+ int note, size_t appsig_size, grub_compression_t comp,
+ const char *dtb_path, const char *sbat_path,
+ int disable_shim_lock)
{
char *kernel_img, *core_img;
size_t total_module_size, core_size;
@@ -1773,11 +1774,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, &core_img, &core_size,
- target_addr, &layout);
+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img,
+ &core_size, target_addr, &layout);
else
- grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
- target_addr, &layout);
+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img,
+ &core_size, target_addr, &layout);
}
break;
}
--
2.31.1

View File

@ -0,0 +1,64 @@
From f7b9580133cf346d77f345d175fa5cb8a591be16 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 15 Aug 2020 02:00:57 +1000
Subject: [PATCH 05/23] docs/grub: Document signing grub under UEFI
Before adding information about how grub is signed with an appended
signature scheme, it's worth adding some information about how it
can currently be signed for UEFI.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index e48018c5f..b1d808d93 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -5814,6 +5814,7 @@ environment variables and commands are listed in the same order.
* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
* Measured Boot:: Measuring boot components
* Lockdown:: Lockdown when booting on a secure setup
+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
@end menu
@node Authentication and authorisation
@@ -5892,7 +5893,7 @@ commands.
GRUB's @file{core.img} can optionally provide enforcement that all files
subsequently read from disk are covered by a valid digital signature.
-This document does @strong{not} cover how to ensure that your
+This section does @strong{not} cover how to ensure that your
platform's firmware (e.g., Coreboot) validates @file{core.img}.
If environment variable @code{check_signatures}
@@ -6054,6 +6055,25 @@ be restricted and some operations/commands cannot be executed.
The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down.
Otherwise it does not exit.
+@node Signing GRUB itself
+@section Signing GRUB itself
+
+To ensure a complete secure-boot chain, there must be a way for the code that
+loads GRUB to verify the integrity of the core image.
+
+This is ultimately platform-specific and individual platforms can define their
+own mechanisms. However, there are general-purpose mechanisms that can be used
+with GRUB.
+
+@section Signing GRUB for UEFI secure boot
+
+On UEFI platforms, @file{core.img} is a PE binary. Therefore, it can be signed
+with a tool such as @command{pesign} or @command{sbsign}. Refer to the
+suggestions in @pxref{UEFI secure boot and shim} to ensure that the final
+image works under UEFI secure boot and can maintain the secure-boot chain. It
+will also be necessary to enrol the public key used into a relevant firmware
+key database.
+
@node Platform limitations
@chapter Platform limitations
--
2.31.1

View File

@ -0,0 +1,71 @@
From ac539a315495792cd75fe8ab1c474f26e0a78852 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 15 Aug 2020 02:19:36 +1000
Subject: [PATCH 06/23] docs/grub: Document signing grub with an appended
signature
Signing grub for firmware that verifies an appended signature is a
bit fiddly. I don't want people to have to figure it out from scratch
so document it here.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/docs/grub.texi b/docs/grub.texi
index b1d808d93..dc1c58304 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -6074,6 +6074,48 @@ image works under UEFI secure boot and can maintain the secure-boot chain. It
will also be necessary to enrol the public key used into a relevant firmware
key database.
+@section Signing GRUB with an appended signature
+
+The @file{core.img} itself can be signed with a Linux kernel module-style
+appended signature.
+
+To support IEEE1275 platforms where the boot image is often loaded directly
+from a disk partition rather than from a file system, the @file{core.img}
+can specify the size and location of the appended signature with an ELF
+note added by @command{grub-install}.
+
+An image can be signed this way using the @command{sign-file} command from
+the Linux kernel:
+
+@example
+@group
+# grub.key is your private key and certificate.der is your public key
+
+# Determine the size of the appended signature. It depends on the signing
+# certificate and the hash algorithm
+touch empty
+sign-file SHA256 grub.key certificate.der empty empty.sig
+SIG_SIZE=`stat -c '%s' empty.sig`
+rm empty empty.sig
+
+# Build a grub image with $SIG_SIZE reserved for the signature
+grub-install --appended-signature-size $SIG_SIZE --modules="..." ...
+
+# Replace the reserved size with a signature:
+# cut off the last $SIG_SIZE bytes with truncate's minus modifier
+truncate -s -$SIG_SIZE /boot/grub/powerpc-ieee1275/core.elf core.elf.unsigned
+# sign the trimmed file with an appended signature, restoring the correct size
+sign-file SHA256 grub.key certificate.der core.elf.unsigned core.elf.signed
+
+# Don't forget to install the signed image as required
+# (e.g. on powerpc-ieee1275, to the PReP partition)
+@end group
+@end example
+
+As with UEFI secure boot, it is necessary to build in the required modules,
+or sign them separately.
+
+
@node Platform limitations
@chapter Platform limitations
--
2.31.1

View File

@ -0,0 +1,48 @@
From 4773f90bdefb72dde55fb5961f7f37b467307016 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 30 Jul 2020 00:13:21 +1000
Subject: [PATCH 07/23] dl: provide a fake grub_dl_set_persistent for the emu
target
Trying to start grub-emu with a module that calls grub_dl_set_persistent
will crash because grub-emu fakes modules and passes NULL to the module
init function.
Provide an empty function for the emu case.
Fixes: ee7808e2197c (dl: Add support for persistent modules)
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
include/grub/dl.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/include/grub/dl.h b/include/grub/dl.h
index b3753c9ca..5decbe2f2 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -243,11 +243,22 @@ grub_dl_get (const char *name)
return 0;
}
+#ifdef GRUB_MACHINE_EMU
+/*
+ * Under grub-emu, modules are faked and NULL is passed to GRUB_MOD_INIT.
+ * So we fake this out to avoid a NULL deref.
+ */
+static inline void
+grub_dl_set_persistent (grub_dl_t mod __attribute__((unused)))
+{
+}
+#else
static inline void
grub_dl_set_persistent (grub_dl_t mod)
{
mod->persistent = 1;
}
+#endif
static inline int
grub_dl_is_persistent (grub_dl_t mod)
--
2.31.1

View File

@ -0,0 +1,194 @@
From 923c8f6807cbd93b72d4dcb16c213d0d2a6b5b9a Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 1 Oct 2020 20:23:48 +1000
Subject: [PATCH 08/23] pgp: factor out rsa_pad
rsa_pad does the PKCS#1 v1.5 padding for the RSA signature scheme.
We want to use it in other RSA signature verification applications.
I considered and rejected putting it in lib/crypto.c. That file doesn't
currently require any MPI functions, but rsa_pad does. That's not so
much of a problem for the grub kernel and modules, but crypto.c also
gets built into all the grub utilities. So - despite the utils not
using any asymmetric ciphers - we would need to built the entire MPI
infrastructure in to them.
A better and simpler solution is just to spin rsa_pad out into its own
PKCS#1 v1.5 module.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/Makefile.core.def | 8 +++++
grub-core/commands/pgp.c | 28 ++----------------
grub-core/lib/pkcs1_v15.c | 59 +++++++++++++++++++++++++++++++++++++
include/grub/pkcs1_v15.h | 27 +++++++++++++++++
4 files changed, 96 insertions(+), 26 deletions(-)
create mode 100644 grub-core/lib/pkcs1_v15.c
create mode 100644 include/grub/pkcs1_v15.h
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 46a488131..5525aa194 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2504,6 +2504,14 @@ module = {
cppflags = '$(CPPFLAGS_GCRY)';
};
+module = {
+ name = pkcs1_v15;
+ common = lib/pkcs1_v15.c;
+
+ cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';
+ cppflags = '$(CPPFLAGS_GCRY)';
+};
+
module = {
name = all_video;
common = lib/fake_module.c;
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index 5daa1e9d0..2408db499 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -24,6 +24,7 @@
#include <grub/file.h>
#include <grub/command.h>
#include <grub/crypto.h>
+#include <grub/pkcs1_v15.h>
#include <grub/i18n.h>
#include <grub/gcrypt/gcrypt.h>
#include <grub/pubkey.h>
@@ -411,32 +412,7 @@ static int
rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
const gcry_md_spec_t *hash, struct grub_public_subkey *sk)
{
- grub_size_t tlen, emlen, fflen;
- grub_uint8_t *em, *emptr;
- unsigned nbits = gcry_mpi_get_nbits (sk->mpis[0]);
- int ret;
- tlen = hash->mdlen + hash->asnlen;
- emlen = (nbits + 7) / 8;
- if (emlen < tlen + 11)
- return 1;
-
- em = grub_malloc (emlen);
- if (!em)
- return 1;
-
- em[0] = 0x00;
- em[1] = 0x01;
- fflen = emlen - tlen - 3;
- for (emptr = em + 2; emptr < em + 2 + fflen; emptr++)
- *emptr = 0xff;
- *emptr++ = 0x00;
- grub_memcpy (emptr, hash->asnoid, hash->asnlen);
- emptr += hash->asnlen;
- grub_memcpy (emptr, hval, hash->mdlen);
-
- ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0);
- grub_free (em);
- return ret;
+ return grub_crypto_rsa_pad(hmpi, hval, hash, sk->mpis[0]);
}
struct grub_pubkey_context
diff --git a/grub-core/lib/pkcs1_v15.c b/grub-core/lib/pkcs1_v15.c
new file mode 100644
index 000000000..dbacd563d
--- /dev/null
+++ b/grub-core/lib/pkcs1_v15.c
@@ -0,0 +1,59 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/gcrypt/gcrypt.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+/*
+ * Given a hash value 'hval', of hash specification 'hash', perform
+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod'
+ * (see RFC 8017 s 9.2) and place the result in 'hmpi'.
+ */
+gcry_err_code_t
+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval,
+ const gcry_md_spec_t * hash, gcry_mpi_t mod)
+{
+ grub_size_t tlen, emlen, fflen;
+ grub_uint8_t *em, *emptr;
+ unsigned nbits = gcry_mpi_get_nbits (mod);
+ int ret;
+ tlen = hash->mdlen + hash->asnlen;
+ emlen = (nbits + 7) / 8;
+ if (emlen < tlen + 11)
+ return GPG_ERR_TOO_SHORT;
+
+ em = grub_malloc (emlen);
+ if (!em)
+ return 1;
+
+ em[0] = 0x00;
+ em[1] = 0x01;
+ fflen = emlen - tlen - 3;
+ for (emptr = em + 2; emptr < em + 2 + fflen; emptr++)
+ *emptr = 0xff;
+ *emptr++ = 0x00;
+ grub_memcpy (emptr, hash->asnoid, hash->asnlen);
+ emptr += hash->asnlen;
+ grub_memcpy (emptr, hval, hash->mdlen);
+
+ ret = gcry_mpi_scan (hmpi, GCRYMPI_FMT_USG, em, emlen, 0);
+ grub_free (em);
+ return ret;
+}
diff --git a/include/grub/pkcs1_v15.h b/include/grub/pkcs1_v15.h
new file mode 100644
index 000000000..5c338c84a
--- /dev/null
+++ b/include/grub/pkcs1_v15.h
@@ -0,0 +1,27 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Given a hash value 'hval', of hash specification 'hash', perform
+ * the EMSA-PKCS1-v1_5 padding suitable for a key with modulus 'mod'
+ * (See RFC 8017 s 9.2)
+ */
+gcry_err_code_t
+grub_crypto_rsa_pad (gcry_mpi_t * hmpi, grub_uint8_t * hval,
+ const gcry_md_spec_t * hash, gcry_mpi_t mod);
+
--
2.31.1

View File

@ -0,0 +1,74 @@
From def9a985bdb1a12db49be42b748b646abc156411 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 2 Oct 2020 10:49:26 +1000
Subject: [PATCH 09/23] crypto: move storage for grub_crypto_pk_* to crypto.c
The way gcry_rsa and friends (the asymmetric ciphers) are loaded for the
pgp module is a bit quirky.
include/grub/crypto.h contains:
extern struct gcry_pk_spec *grub_crypto_pk_rsa;
commands/pgp.c contains the actual storage:
struct gcry_pk_spec *grub_crypto_pk_rsa;
And the module itself saves to the storage in pgp.c:
GRUB_MOD_INIT(gcry_rsa)
{
grub_crypto_pk_rsa = &_gcry_pubkey_spec_rsa;
}
This is annoying: gcry_rsa now has a dependency on pgp!
We want to be able to bring in gcry_rsa without bringing in PGP,
so move the storage to crypto.c.
Previously, gcry_rsa depended on pgp and mpi. Now it depends on
crypto and mpi. As pgp depends on crypto, this doesn't add any new
module dependencies using the PGP verfier.
[FWIW, the story is different for the symmetric ciphers. cryptodisk
and friends (zfs encryption etc) use grub_crypto_lookup_cipher_by_name()
to get a cipher handle. That depends on grub_ciphers being populated
by people calling grub_cipher_register. import_gcry.py ensures that the
symmetric ciphers call it.]
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/pgp.c | 4 ----
grub-core/lib/crypto.c | 4 ++++
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index 2408db499..355a43844 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -147,10 +147,6 @@ const char *hashes[] = {
[0x0b] = "sha224"
};
-struct gcry_pk_spec *grub_crypto_pk_dsa;
-struct gcry_pk_spec *grub_crypto_pk_ecdsa;
-struct gcry_pk_spec *grub_crypto_pk_rsa;
-
static int
dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval,
const gcry_md_spec_t *hash, struct grub_public_subkey *sk);
diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c
index ca334d5a4..c578128a5 100644
--- a/grub-core/lib/crypto.c
+++ b/grub-core/lib/crypto.c
@@ -121,6 +121,10 @@ grub_md_unregister (gcry_md_spec_t *cipher)
}
}
+struct gcry_pk_spec *grub_crypto_pk_dsa;
+struct gcry_pk_spec *grub_crypto_pk_ecdsa;
+struct gcry_pk_spec *grub_crypto_pk_rsa;
+
void
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
grub_size_t inlen)
--
2.31.1

View File

@ -0,0 +1,67 @@
From fa3436ad10a63d5ad3d27cc330fb2594e699cc34 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Sat, 2 May 2020 00:27:57 +1000
Subject: [PATCH 10/23] posix_wrap: tweaks in preparation for libtasn1
- Define SIZEOF_UNSIGNED_LONG_INT, it's the same as
SIZEOF_UNSIGNED_LONG.
- Define WORD_BIT, the size in bits of an int. This is a defined
in the Single Unix Specification and in gnulib's limits.h. gnulib
assumes it's 32 bits on all our platforms, including 64 bit
platforms, so we also use that value.
- Provide strto[u]l[l] preprocessor macros that resolve to
grub_strto[u]l[l]. To avoid gcrypt redefining strtoul, we
also define HAVE_STRTOUL here.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/lib/posix_wrap/limits.h | 1 +
grub-core/lib/posix_wrap/stdlib.h | 8 ++++++++
grub-core/lib/posix_wrap/sys/types.h | 1 +
3 files changed, 10 insertions(+)
diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h
index 7217138ff..591dbf328 100644
--- a/grub-core/lib/posix_wrap/limits.h
+++ b/grub-core/lib/posix_wrap/limits.h
@@ -37,5 +37,6 @@
#define LONG_MAX GRUB_LONG_MAX
#define CHAR_BIT 8
+#define WORD_BIT 32
#endif
diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h
index 7a8d385e9..4634db09f 100644
--- a/grub-core/lib/posix_wrap/stdlib.h
+++ b/grub-core/lib/posix_wrap/stdlib.h
@@ -58,4 +58,12 @@ abs (int c)
return (c >= 0) ? c : -c;
}
+#define strtol grub_strtol
+
+/* for libgcrypt */
+#define HAVE_STRTOUL
+#define strtoul grub_strtoul
+
+#define strtoull grub_strtoull
+
#endif
diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h
index 854eb0122..f63412c8d 100644
--- a/grub-core/lib/posix_wrap/sys/types.h
+++ b/grub-core/lib/posix_wrap/sys/types.h
@@ -51,6 +51,7 @@ typedef grub_uint8_t byte;
typedef grub_addr_t uintptr_t;
#define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG
+#define SIZEOF_UNSIGNED_LONG_INT GRUB_CPU_SIZEOF_LONG
#define SIZEOF_UNSIGNED_INT 4
#define SIZEOF_UNSIGNED_LONG_LONG 8
#define SIZEOF_UNSIGNED_SHORT 2
--
2.31.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,310 @@
From 40099cf0d4d68e79db9e71d78070f37c73f998a0 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 1 May 2020 17:12:23 +1000
Subject: [PATCH 12/23] libtasn1: disable code not needed in grub
We don't expect to be able to write ASN.1, only read it,
so we can disable some code.
Do that with #if 0/#endif, rather than deletion. This means
that the difference between upstream and grub is smaller,
which should make updating libtasn1 easier in the future.
With these exclusions we also avoid the need for minmax.h,
which is convenient because it means we don't have to
import it from gnulib.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/lib/libtasn1/lib/coding.c | 12 ++++++++++--
grub-core/lib/libtasn1/lib/decoding.c | 2 ++
grub-core/lib/libtasn1/lib/element.c | 4 ++--
grub-core/lib/libtasn1/lib/errors.c | 3 +++
grub-core/lib/libtasn1/lib/structure.c | 10 ++++++----
include/grub/libtasn1.h | 15 +++++++++++++++
6 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/grub-core/lib/libtasn1/lib/coding.c b/grub-core/lib/libtasn1/lib/coding.c
index 671104f63..b3d826710 100644
--- a/grub-core/lib/libtasn1/lib/coding.c
+++ b/grub-core/lib/libtasn1/lib/coding.c
@@ -30,11 +30,11 @@
#include "parser_aux.h"
#include <gstr.h>
#include "element.h"
-#include "minmax.h"
#include <structure.h>
#define MAX_TAG_LEN 16
+#if 0
/******************************************************/
/* Function : _asn1_error_description_value_not_found */
/* Description: creates the ErrorDescription string */
@@ -58,6 +58,7 @@ _asn1_error_description_value_not_found (asn1_node node,
Estrcat (ErrorDescription, "' not found");
}
+#endif
/**
* asn1_length_der:
@@ -244,6 +245,7 @@ asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
return ASN1_SUCCESS;
}
+#if 0
/******************************************************/
/* Function : _asn1_time_der */
/* Description: creates the DER coding for a TIME */
@@ -278,7 +280,7 @@ _asn1_time_der (unsigned char *str, int str_len, unsigned char *der,
return ASN1_SUCCESS;
}
-
+#endif
/*
void
@@ -519,6 +521,7 @@ asn1_bit_der (const unsigned char *str, int bit_len,
}
+#if 0
/******************************************************/
/* Function : _asn1_complete_explicit_tag */
/* Description: add the length coding to the EXPLICIT */
@@ -595,6 +598,7 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
return ASN1_SUCCESS;
}
+#endif
const tag_and_class_st _asn1_tags[] = {
[ASN1_ETYPE_GENERALSTRING] =
@@ -647,6 +651,8 @@ const tag_and_class_st _asn1_tags[] = {
unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]);
+
+#if 0
/******************************************************/
/* Function : _asn1_insert_tag_der */
/* Description: creates the DER coding of tags of one */
@@ -1423,3 +1429,5 @@ error:
asn1_delete_structure (&node);
return err;
}
+
+#endif
\ No newline at end of file
diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c
index b1a35356f..b8130b956 100644
--- a/grub-core/lib/libtasn1/lib/decoding.c
+++ b/grub-core/lib/libtasn1/lib/decoding.c
@@ -1620,6 +1620,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len,
return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription);
}
+#if 0
/**
* asn1_der_decoding_element:
* @structure: pointer to an ASN1 structure
@@ -1650,6 +1651,7 @@ asn1_der_decoding_element (asn1_node * structure, const char *elementName,
{
return asn1_der_decoding (structure, ider, len, errorDescription);
}
+#endif
/**
* asn1_der_decoding_startEnd:
diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c
index 86e64f2cf..8cd6b662c 100644
--- a/grub-core/lib/libtasn1/lib/element.c
+++ b/grub-core/lib/libtasn1/lib/element.c
@@ -191,7 +191,7 @@ _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache)
return ASN1_SUCCESS;
}
-
+#if 0
/**
* asn1_write_value:
* @node_root: pointer to a structure
@@ -646,7 +646,7 @@ asn1_write_value (asn1_node node_root, const char *name,
return ASN1_SUCCESS;
}
-
+#endif
#define PUT_VALUE( ptr, ptr_size, data, data_size) \
*len = data_size; \
diff --git a/grub-core/lib/libtasn1/lib/errors.c b/grub-core/lib/libtasn1/lib/errors.c
index 4dadbd96d..41921d813 100644
--- a/grub-core/lib/libtasn1/lib/errors.c
+++ b/grub-core/lib/libtasn1/lib/errors.c
@@ -57,6 +57,8 @@ static const libtasn1_error_entry error_algorithms[] = {
{0, 0}
};
+
+#if 0
/**
* asn1_perror:
* @error: is an error returned by a libtasn1 function.
@@ -73,6 +75,7 @@ asn1_perror (int error)
const char *str = asn1_strerror (error);
fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)");
}
+#endif
/**
* asn1_strerror:
diff --git a/grub-core/lib/libtasn1/lib/structure.c b/grub-core/lib/libtasn1/lib/structure.c
index c0802202e..45435732c 100644
--- a/grub-core/lib/libtasn1/lib/structure.c
+++ b/grub-core/lib/libtasn1/lib/structure.c
@@ -76,7 +76,7 @@ _asn1_find_left (asn1_node_const node)
return node->left;
}
-
+#if 0
int
_asn1_create_static_structure (asn1_node_const pointer,
char *output_file_name, char *vector_name)
@@ -155,7 +155,7 @@ _asn1_create_static_structure (asn1_node_const pointer,
return ASN1_SUCCESS;
}
-
+#endif
/**
* asn1_array2tree:
@@ -721,7 +721,7 @@ asn1_create_element (asn1_node_const definitions, const char *source_name,
return res;
}
-
+#if 0
/**
* asn1_print_structure:
* @out: pointer to the output file (e.g. stdout).
@@ -1062,7 +1062,7 @@ asn1_print_structure (FILE * out, asn1_node_const structure, const char *name,
}
}
}
-
+#endif
/**
@@ -1158,6 +1158,7 @@ asn1_find_structure_from_oid (asn1_node_const definitions,
return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
}
+#if 0
/**
* asn1_copy_node:
* @dst: Destination asn1 node.
@@ -1207,6 +1208,7 @@ asn1_copy_node (asn1_node dst, const char *dst_name,
return result;
}
+#endif
/**
* asn1_dup_node:
diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h
index fc695a28a..0c3a44881 100644
--- a/include/grub/libtasn1.h
+++ b/include/grub/libtasn1.h
@@ -314,6 +314,8 @@ extern "C"
/* Functions definitions */
/***********************************/
+/* These functions are not used in grub and should not be referenced. */
+# if 0
extern ASN1_API int
asn1_parser2tree (const char *file,
asn1_node * definitions, char *error_desc);
@@ -322,14 +324,17 @@ extern "C"
asn1_parser2array (const char *inputFileName,
const char *outputFileName,
const char *vectorName, char *error_desc);
+# endif
extern ASN1_API int
asn1_array2tree (const asn1_static_node * array,
asn1_node * definitions, char *errorDescription);
+# if 0
extern ASN1_API void
asn1_print_structure (FILE * out, asn1_node_const structure,
const char *name, int mode);
+# endif
extern ASN1_API int
asn1_create_element (asn1_node_const definitions,
@@ -343,9 +348,11 @@ extern "C"
extern ASN1_API int
asn1_delete_element (asn1_node structure, const char *element_name);
+# if 0
extern ASN1_API int
asn1_write_value (asn1_node node_root, const char *name,
const void *ivalue, int len);
+# endif
extern ASN1_API int
asn1_read_value (asn1_node_const root, const char *name,
@@ -362,9 +369,11 @@ extern "C"
asn1_number_of_elements (asn1_node_const element, const char *name,
int *num);
+# if 0
extern ASN1_API int
asn1_der_coding (asn1_node_const element, const char *name,
void *ider, int *len, char *ErrorDescription);
+# endif
extern ASN1_API int
asn1_der_decoding2 (asn1_node * element, const void *ider,
@@ -375,6 +384,7 @@ extern "C"
asn1_der_decoding (asn1_node * element, const void *ider,
int ider_len, char *errorDescription);
+# if 0
/* Do not use. Use asn1_der_decoding() instead. */
extern ASN1_API int
asn1_der_decoding_element (asn1_node * structure,
@@ -382,6 +392,7 @@ extern "C"
const void *ider, int len,
char *errorDescription)
_ASN1_GCC_ATTR_DEPRECATED;
+# endif
extern ASN1_API int
asn1_der_decoding_startEnd (asn1_node element,
@@ -407,12 +418,16 @@ extern "C"
const char
*oidValue);
+# if 0
__LIBTASN1_PURE__
extern ASN1_API const char *asn1_check_version (const char *req_version);
+# endif
__LIBTASN1_PURE__ extern ASN1_API const char *asn1_strerror (int error);
+# if 0
extern ASN1_API void asn1_perror (int error);
+# endif
# define ASN1_MAX_TAG_SIZE 4
# define ASN1_MAX_LENGTH_SIZE 9
--
2.31.1

View File

@ -0,0 +1,212 @@
From f05ba09c9adea447d3ca837c73498b9619306180 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 1 May 2020 20:44:29 +1000
Subject: [PATCH 13/23] libtasn1: changes for grub compatibility
Do a few things to make libtasn1 compile as part of grub:
- redefine _asn1_strcat. grub removed strcat so replace it with the
appropriate calls to memcpy and strlen. Use this internally where
strcat was used.
- replace c_isdigit with grub_isdigit (and don't import c-ctype from
gnulib) grub_isdigit provides the same functionality as c_isdigit: it
determines if the input is an ASCII digit without regard for locale.
- replace GL_ATTRIBUTE_PURE with __attribute__((pure)) which been
supported since gcc-2.96. This avoids messing around with gnulib.
- adjust libtasn1.h: drop the ASN1_API logic, it's not needed for our
modules. Unconditionally support const and pure attributes and adjust
header paths.
- adjust header paths to "grub/libtasn1.h".
- replace a 64 bit division with a call to grub_divmod64, preventing
creation of __udivdi3 calls on 32 bit platforms.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
v2: Clean up strcat handling, thanks Stefan Berger.
---
grub-core/lib/libtasn1/lib/decoding.c | 11 +++++-----
grub-core/lib/libtasn1/lib/element.c | 3 ++-
grub-core/lib/libtasn1/lib/gstr.c | 4 ++--
grub-core/lib/libtasn1/lib/int.h | 4 ++--
grub-core/lib/libtasn1/lib/parser_aux.c | 7 +++---
include/grub/libtasn1.h | 29 +++++++------------------
6 files changed, 24 insertions(+), 34 deletions(-)
diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c
index b8130b956..beeb6a176 100644
--- a/grub-core/lib/libtasn1/lib/decoding.c
+++ b/grub-core/lib/libtasn1/lib/decoding.c
@@ -32,7 +32,8 @@
#include <element.h>
#include <limits.h>
#include <intprops.h>
-#include "c-ctype.h"
+
+#define c_isdigit grub_isdigit
#ifdef DEBUG
# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__)
@@ -2016,8 +2017,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element,
(p2->type & CONST_ASSIGN))
{
strcpy (name, definitions->name);
- strcat (name, ".");
- strcat (name, p2->name);
+ _asn1_strcat (name, ".");
+ _asn1_strcat (name, p2->name);
len = sizeof (value);
result = asn1_read_value (definitions, name, value, &len);
@@ -2034,8 +2035,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element,
if (p2)
{
strcpy (name, definitions->name);
- strcat (name, ".");
- strcat (name, p2->name);
+ _asn1_strcat (name, ".");
+ _asn1_strcat (name, p2->name);
result = asn1_create_element (definitions, name, &aux);
if (result == ASN1_SUCCESS)
diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c
index 8cd6b662c..150b9b377 100644
--- a/grub-core/lib/libtasn1/lib/element.c
+++ b/grub-core/lib/libtasn1/lib/element.c
@@ -30,9 +30,10 @@
#include "parser_aux.h"
#include <gstr.h>
#include "structure.h"
-#include "c-ctype.h"
#include "element.h"
+#define c_isdigit grub_isdigit
+
void
_asn1_hierarchical_name (asn1_node_const node, char *name, int name_size)
{
diff --git a/grub-core/lib/libtasn1/lib/gstr.c b/grub-core/lib/libtasn1/lib/gstr.c
index 1475ed51b..b729089db 100644
--- a/grub-core/lib/libtasn1/lib/gstr.c
+++ b/grub-core/lib/libtasn1/lib/gstr.c
@@ -36,13 +36,13 @@ _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src)
if (dest_tot_size - dest_size > str_size)
{
- strcat (dest, src);
+ _asn1_strcat (dest, src);
}
else
{
if (dest_tot_size > dest_size)
{
- strncat (dest, src, (dest_tot_size - dest_size) - 1);
+ memcpy (dest + dest_size, src, (dest_tot_size - dest_size) - 1);
dest[dest_tot_size - 1] = 0;
}
}
diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h
index 404cd1562..edfe84a0e 100644
--- a/grub-core/lib/libtasn1/lib/int.h
+++ b/grub-core/lib/libtasn1/lib/int.h
@@ -35,7 +35,7 @@
# include <sys/types.h>
# endif
-# include <libtasn1.h>
+# include "grub/libtasn1.h"
# define ASN1_SMALL_VALUE_SIZE 16
@@ -115,7 +115,7 @@ extern const tag_and_class_st _asn1_tags[];
# define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b)
# define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b)
# define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b)
-# define _asn1_strcat(a,b) strcat((char *)a, (const char *)b)
+# define _asn1_strcat(a,b) memcpy((char *)a + strlen((const char *)a), (const char *)b, strlen((const char *)b) + 1)
# if SIZEOF_UNSIGNED_LONG_INT == 8
# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b)
diff --git a/grub-core/lib/libtasn1/lib/parser_aux.c b/grub-core/lib/libtasn1/lib/parser_aux.c
index c99c5a4cb..a933f03ed 100644
--- a/grub-core/lib/libtasn1/lib/parser_aux.c
+++ b/grub-core/lib/libtasn1/lib/parser_aux.c
@@ -26,7 +26,8 @@
#include "gstr.h"
#include "structure.h"
#include "element.h"
-#include "c-ctype.h"
+
+#define c_isdigit grub_isdigit
char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
@@ -40,7 +41,7 @@ char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not fou
#ifdef __clang__
__attribute__((no_sanitize ("integer")))
#endif
- _GL_ATTRIBUTE_PURE static unsigned int _asn1_hash_name (const char *x)
+ __attribute__((__pure__)) static unsigned int _asn1_hash_name (const char *x)
{
const unsigned char *s = (unsigned char *) x;
unsigned h = 0;
@@ -632,7 +633,7 @@ _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE])
count = 0;
do
{
- d = val / 10;
+ d = grub_divmod64(val, 10, NULL);
r = val - d * 10;
temp[start + count] = '0' + (char) r;
count++;
diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h
index 0c3a44881..2ea058a3b 100644
--- a/include/grub/libtasn1.h
+++ b/include/grub/libtasn1.h
@@ -34,29 +34,16 @@
#ifndef LIBTASN1_H
# define LIBTASN1_H
-# ifndef ASN1_API
-# if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY
-# define ASN1_API __attribute__((__visibility__("default")))
-# elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC
-# define ASN1_API __declspec(dllexport)
-# elif defined _MSC_VER && ! defined ASN1_STATIC
-# define ASN1_API __declspec(dllimport)
-# else
-# define ASN1_API
-# endif
-# endif
+/* grub: ASN1_API is not used */
+# define ASN1_API
+
+/* grub: all our supported compilers support these attributes */
+# define __LIBTASN1_CONST__ __attribute__((const))
+# define __LIBTASN1_PURE__ __attribute__((pure))
-# ifdef __GNUC__
-# define __LIBTASN1_CONST__ __attribute__((const))
-# define __LIBTASN1_PURE__ __attribute__((pure))
-# else
-# define __LIBTASN1_CONST__
-# define __LIBTASN1_PURE__
-# endif
-# include <sys/types.h>
-# include <time.h>
-# include <stdio.h> /* for FILE* */
+# include <grub/types.h>
+# include <grub/time.h>
# ifdef __cplusplus
extern "C"
--
2.31.1

View File

@ -0,0 +1,73 @@
From f3b818444fe8628d581f5efe23d55554f23718c8 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 5 Jun 2020 17:47:25 +1000
Subject: [PATCH 14/23] libtasn1: compile into asn1 module
Create a wrapper file that specifies the module license.
Set up the makefile so it is built.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/Makefile.core.def | 15 +++++++++++++++
grub-core/lib/libtasn1_wrap/wrap.c | 26 ++++++++++++++++++++++++++
2 files changed, 41 insertions(+)
create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 5525aa194..f0df8ed94 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2575,3 +2575,18 @@ module = {
name = cmdline;
common = lib/cmdline.c;
};
+
+module = {
+ name = asn1;
+ common = lib/libtasn1/lib/decoding.c;
+ common = lib/libtasn1/lib/coding.c;
+ common = lib/libtasn1/lib/element.c;
+ common = lib/libtasn1/lib/structure.c;
+ common = lib/libtasn1/lib/parser_aux.c;
+ common = lib/libtasn1/lib/gstr.c;
+ common = lib/libtasn1/lib/errors.c;
+ common = lib/libtasn1_wrap/wrap.c;
+ cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
+ // -Wno-type-limits comes from libtasn1's configure.ac
+ cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1/lib -Wno-type-limits';
+};
diff --git a/grub-core/lib/libtasn1_wrap/wrap.c b/grub-core/lib/libtasn1_wrap/wrap.c
new file mode 100644
index 000000000..622ba942e
--- /dev/null
+++ b/grub-core/lib/libtasn1_wrap/wrap.c
@@ -0,0 +1,26 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2020 IBM Corporation
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+
+/*
+ * libtasn1 is provided under LGPL2.1+, which is compatible
+ * with GPL3+. As Grub as a whole is under GPL3+, this module
+ * is therefore under GPL3+ also.
+ */
+GRUB_MOD_LICENSE ("GPLv3+");
--
2.31.1

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,257 @@
From a0e17ba00ac128759d40e2bfc751716f45542ac0 Mon Sep 17 00:00:00 2001
From: Alastair D'Silva <alastair@d-silva.org>
Date: Mon, 6 Jul 2020 13:33:04 +1000
Subject: [PATCH 16/23] grub-install: support embedding x509 certificates
To support verification of appended signatures, we need a way to
embed the necessary public keys. Existing appended signature schemes
in the Linux kernel use X.509 certificates, so allow certificates to
be embedded in the grub core image in the same way as PGP keys.
Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/pgp.c | 2 +-
include/grub/kernel.h | 3 ++-
include/grub/util/install.h | 7 +++++--
util/grub-install-common.c | 22 +++++++++++++++++++-
util/grub-mkimage.c | 15 ++++++++++++--
util/mkimage.c | 41 ++++++++++++++++++++++++++++++++++---
6 files changed, 80 insertions(+), 10 deletions(-)
diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c
index 355a43844..b81ac0ae4 100644
--- a/grub-core/commands/pgp.c
+++ b/grub-core/commands/pgp.c
@@ -944,7 +944,7 @@ GRUB_MOD_INIT(pgp)
grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
/* Not an ELF module, skip. */
- if (header->type != OBJ_TYPE_PUBKEY)
+ if (header->type != OBJ_TYPE_GPG_PUBKEY)
continue;
pseudo_file.fs = &pseudo_fs;
diff --git a/include/grub/kernel.h b/include/grub/kernel.h
index abbca5ea3..d3aafc884 100644
--- a/include/grub/kernel.h
+++ b/include/grub/kernel.h
@@ -28,7 +28,8 @@ enum
OBJ_TYPE_MEMDISK,
OBJ_TYPE_CONFIG,
OBJ_TYPE_PREFIX,
- OBJ_TYPE_PUBKEY,
+ OBJ_TYPE_GPG_PUBKEY,
+ OBJ_TYPE_X509_PUBKEY,
OBJ_TYPE_DTB,
OBJ_TYPE_DISABLE_SHIM_LOCK
};
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 0b2e8a06d..c241a2a40 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -67,6 +67,8 @@
N_("SBAT metadata"), 0 }, \
{ "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \
N_("disable shim_lock verifier"), 0 }, \
+ { "x509key", 'x', N_("FILE"), 0, \
+ N_("embed FILE as an x509 certificate for signature checking"), 0}, \
{ "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
"SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
1}, \
@@ -189,8 +191,9 @@ void
grub_install_generate_image (const char *dir, const char *prefix,
FILE *out,
const char *outname, char *mods[],
- char *memdisk_path, char **pubkey_paths,
- size_t npubkeys,
+ char *memdisk_path,
+ char **pubkey_paths, size_t npubkeys,
+ char **x509key_paths, size_t nx509keys,
char *config_path,
const struct grub_install_image_target_desc *image_target,
int note, size_t appsig_size,
diff --git a/util/grub-install-common.c b/util/grub-install-common.c
index 954df20eb..44296afa0 100644
--- a/util/grub-install-common.c
+++ b/util/grub-install-common.c
@@ -460,6 +460,8 @@ static char **pubkeys;
static size_t npubkeys;
static char *sbat;
static int disable_shim_lock;
+static char **x509keys;
+static size_t nx509keys;
static grub_compression_t compression;
static size_t appsig_size;
@@ -501,6 +503,12 @@ grub_install_parse (int key, char *arg)
case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK:
disable_shim_lock = 1;
return 1;
+ case 'x':
+ x509keys = xrealloc (x509keys,
+ sizeof (x509keys[0])
+ * (nx509keys + 1));
+ x509keys[nx509keys++] = xstrdup (arg);
+ return 1;
case GRUB_INSTALL_OPTIONS_VERBOSITY:
verbosity++;
@@ -627,6 +635,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
for (pk = pubkeys; pk < pubkeys + npubkeys; pk++)
slen += 20 + grub_strlen (*pk);
+ for (pk = x509keys; pk < x509keys + nx509keys; pk++)
+ slen += 10 + grub_strlen (*pk);
+
for (md = modules.entries; *md; md++)
{
slen += 10 + grub_strlen (*md);
@@ -655,6 +666,14 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
*p++ = ' ';
}
+ for (pk = x509keys; pk < x509keys + nx509keys; pk++)
+ {
+ p = grub_stpcpy (p, "--x509 '");
+ p = grub_stpcpy (p, *pk);
+ *p++ = '\'';
+ *p++ = ' ';
+ }
+
for (md = modules.entries; *md; md++)
{
*p++ = '\'';
@@ -683,7 +702,8 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix,
grub_install_generate_image (dir, prefix, fp, outname,
modules.entries, memdisk_path,
- pubkeys, npubkeys, config_path, tgt,
+ pubkeys, npubkeys, x509keys, nx509keys,
+ config_path, tgt,
note, appsig_size, compression, dtb, sbat,
disable_shim_lock);
while (dc--)
diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c
index d01eaeb84..7d61ef3ea 100644
--- a/util/grub-mkimage.c
+++ b/util/grub-mkimage.c
@@ -75,7 +75,8 @@ static struct argp_option options[] = {
/* TRANSLATORS: "embed" is a verb (command description). "*/
{"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0},
/* TRANSLATORS: "embed" is a verb (command description). "*/
- {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for signature checking"), 0},
+ {"pubkey", 'k', N_("FILE"), 0, N_("embed FILE as public key for PGP signature checking"), 0},
+ {"x509", 'x', N_("FILE"), 0, N_("embed FILE as an x509 certificate for appended signature checking"), 0},
/* TRANSLATORS: NOTE is a name of segment. */
{"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0},
{"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
@@ -124,6 +125,8 @@ struct arguments
char *dtb;
char **pubkeys;
size_t npubkeys;
+ char **x509keys;
+ size_t nx509keys;
char *font;
char *config;
char *sbat;
@@ -206,6 +209,13 @@ argp_parser (int key, char *arg, struct argp_state *state)
arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg);
break;
+ case 'x':
+ arguments->x509keys = xrealloc (arguments->x509keys,
+ sizeof (arguments->x509keys[0])
+ * (arguments->nx509keys + 1));
+ arguments->x509keys[arguments->nx509keys++] = xstrdup (arg);
+ break;
+
case 'c':
if (arguments->config)
free (arguments->config);
@@ -332,7 +342,8 @@ main (int argc, char *argv[])
grub_install_generate_image (arguments.dir, arguments.prefix, fp,
arguments.output, arguments.modules,
arguments.memdisk, arguments.pubkeys,
- arguments.npubkeys, arguments.config,
+ arguments.npubkeys, arguments.x509keys,
+ arguments.nx509keys, arguments.config,
arguments.image_target, arguments.note,
arguments.appsig_size,
arguments.comp, arguments.dtb,
diff --git a/util/mkimage.c b/util/mkimage.c
index d2cb33883..5a8021a21 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -866,8 +866,10 @@ init_pe_section(const struct grub_install_image_target_desc *image_target,
void
grub_install_generate_image (const char *dir, const char *prefix,
FILE *out, const char *outname, char *mods[],
- char *memdisk_path, char **pubkey_paths,
- size_t npubkeys, char *config_path,
+ char *memdisk_path,
+ char **pubkey_paths, size_t npubkeys,
+ char **x509key_paths, size_t nx509keys,
+ char *config_path,
const struct grub_install_image_target_desc *image_target,
int note, size_t appsig_size, grub_compression_t comp,
const char *dtb_path, const char *sbat_path,
@@ -913,6 +915,19 @@ grub_install_generate_image (const char *dir, const char *prefix,
}
}
+ {
+ size_t i;
+ for (i = 0; i < nx509keys; i++)
+ {
+ size_t curs;
+ curs = ALIGN_ADDR (grub_util_get_image_size (x509key_paths[i]));
+ grub_util_info ("the size of x509 public key %u is 0x%"
+ GRUB_HOST_PRIxLONG_LONG,
+ (unsigned) i, (unsigned long long) curs);
+ total_module_size += curs + sizeof (struct grub_module_header);
+ }
+ }
+
if (memdisk_path)
{
memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512);
@@ -1034,7 +1049,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
curs = grub_util_get_image_size (pubkey_paths[i]);
header = (struct grub_module_header *) (kernel_img + offset);
- header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY);
+ header->type = grub_host_to_target32 (OBJ_TYPE_GPG_PUBKEY);
header->size = grub_host_to_target32 (curs + sizeof (*header));
offset += sizeof (*header);
@@ -1043,6 +1058,26 @@ grub_install_generate_image (const char *dir, const char *prefix,
}
}
+ {
+ size_t i;
+ for (i = 0; i < nx509keys; i++)
+ {
+ size_t curs;
+ struct grub_module_header *header;
+
+ curs = grub_util_get_image_size (x509key_paths[i]);
+
+ header = (struct grub_module_header *) (kernel_img + offset);
+ header->type = grub_host_to_target32 (OBJ_TYPE_X509_PUBKEY);
+ header->size = grub_host_to_target32 (curs + sizeof (*header));
+ offset += sizeof (*header);
+
+ grub_util_load_image (x509key_paths[i], kernel_img + offset);
+ offset += ALIGN_ADDR (curs);
+ }
+ }
+
+
if (memdisk_path)
{
struct grub_module_header *header;
--
2.31.1

View File

@ -0,0 +1,643 @@
From f948da0bef477fe9d95fbcb13eb2c4f45f1b6ea0 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 30 Jul 2020 01:35:10 +1000
Subject: [PATCH 17/23] appended signatures: import GNUTLS's ASN.1 description
files
In order to parse PKCS#7 messages and X.509 certificates with libtasn1,
we need some information about how they are encoded.
We get these from GNUTLS, which has the benefit that they support the
features we need and are well tested.
The GNUTLS license is LGPLv2.1+, which is GPLv3 compatible, allowing
us to import it without issue.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
.../commands/appendedsig/gnutls_asn1_tab.c | 121 +++++
.../commands/appendedsig/pkix_asn1_tab.c | 484 ++++++++++++++++++
2 files changed, 605 insertions(+)
create mode 100644 grub-core/commands/appendedsig/gnutls_asn1_tab.c
create mode 100644 grub-core/commands/appendedsig/pkix_asn1_tab.c
diff --git a/grub-core/commands/appendedsig/gnutls_asn1_tab.c b/grub-core/commands/appendedsig/gnutls_asn1_tab.c
new file mode 100644
index 000000000..ddd1314e6
--- /dev/null
+++ b/grub-core/commands/appendedsig/gnutls_asn1_tab.c
@@ -0,0 +1,121 @@
+#include <grub/mm.h>
+#include <grub/libtasn1.h>
+
+const asn1_static_node gnutls_asn1_tab[] = {
+ { "GNUTLS", 536872976, NULL },
+ { NULL, 1073741836, NULL },
+ { "RSAPublicKey", 1610612741, NULL },
+ { "modulus", 1073741827, NULL },
+ { "publicExponent", 3, NULL },
+ { "RSAPrivateKey", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "modulus", 1073741827, NULL },
+ { "publicExponent", 1073741827, NULL },
+ { "privateExponent", 1073741827, NULL },
+ { "prime1", 1073741827, NULL },
+ { "prime2", 1073741827, NULL },
+ { "exponent1", 1073741827, NULL },
+ { "exponent2", 1073741827, NULL },
+ { "coefficient", 1073741827, NULL },
+ { "otherPrimeInfos", 16386, "OtherPrimeInfos"},
+ { "ProvableSeed", 1610612741, NULL },
+ { "algorithm", 1073741836, NULL },
+ { "seed", 7, NULL },
+ { "OtherPrimeInfos", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "OtherPrimeInfo"},
+ { "OtherPrimeInfo", 1610612741, NULL },
+ { "prime", 1073741827, NULL },
+ { "exponent", 1073741827, NULL },
+ { "coefficient", 3, NULL },
+ { "AlgorithmIdentifier", 1610612741, NULL },
+ { "algorithm", 1073741836, NULL },
+ { "parameters", 541081613, NULL },
+ { "algorithm", 1, NULL },
+ { "DigestInfo", 1610612741, NULL },
+ { "digestAlgorithm", 1073741826, "DigestAlgorithmIdentifier"},
+ { "digest", 7, NULL },
+ { "DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
+ { "DSAPublicKey", 1073741827, NULL },
+ { "DSAParameters", 1610612741, NULL },
+ { "p", 1073741827, NULL },
+ { "q", 1073741827, NULL },
+ { "g", 3, NULL },
+ { "DSASignatureValue", 1610612741, NULL },
+ { "r", 1073741827, NULL },
+ { "s", 3, NULL },
+ { "DSAPrivateKey", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "p", 1073741827, NULL },
+ { "q", 1073741827, NULL },
+ { "g", 1073741827, NULL },
+ { "Y", 1073741827, NULL },
+ { "priv", 3, NULL },
+ { "DHParameter", 1610612741, NULL },
+ { "prime", 1073741827, NULL },
+ { "base", 1073741827, NULL },
+ { "privateValueLength", 16387, NULL },
+ { "ECParameters", 1610612754, NULL },
+ { "namedCurve", 12, NULL },
+ { "ECPrivateKey", 1610612741, NULL },
+ { "Version", 1073741827, NULL },
+ { "privateKey", 1073741831, NULL },
+ { "parameters", 1610637314, "ECParameters"},
+ { NULL, 2056, "0"},
+ { "publicKey", 536895494, NULL },
+ { NULL, 2056, "1"},
+ { "PrincipalName", 1610612741, NULL },
+ { "name-type", 1610620931, NULL },
+ { NULL, 2056, "0"},
+ { "name-string", 536879115, NULL },
+ { NULL, 1073743880, "1"},
+ { NULL, 27, NULL },
+ { "KRB5PrincipalName", 1610612741, NULL },
+ { "realm", 1610620955, NULL },
+ { NULL, 2056, "0"},
+ { "principalName", 536879106, "PrincipalName"},
+ { NULL, 2056, "1"},
+ { "RSAPSSParameters", 1610612741, NULL },
+ { "hashAlgorithm", 1610637314, "AlgorithmIdentifier"},
+ { NULL, 2056, "0"},
+ { "maskGenAlgorithm", 1610637314, "AlgorithmIdentifier"},
+ { NULL, 2056, "1"},
+ { "saltLength", 1610653699, NULL },
+ { NULL, 1073741833, "20"},
+ { NULL, 2056, "2"},
+ { "trailerField", 536911875, NULL },
+ { NULL, 1073741833, "1"},
+ { NULL, 2056, "3"},
+ { "GOSTParameters", 1610612741, NULL },
+ { "publicKeyParamSet", 1073741836, NULL },
+ { "digestParamSet", 16396, NULL },
+ { "GOSTParametersOld", 1610612741, NULL },
+ { "publicKeyParamSet", 1073741836, NULL },
+ { "digestParamSet", 1073741836, NULL },
+ { "encryptionParamSet", 16396, NULL },
+ { "GOSTPrivateKey", 1073741831, NULL },
+ { "GOSTPrivateKeyOld", 1073741827, NULL },
+ { "IssuerSignTool", 1610612741, NULL },
+ { "signTool", 1073741858, NULL },
+ { "cATool", 1073741858, NULL },
+ { "signToolCert", 1073741858, NULL },
+ { "cAToolCert", 34, NULL },
+ { "Gost28147-89-EncryptedKey", 1610612741, NULL },
+ { "encryptedKey", 1073741831, NULL },
+ { "maskKey", 1610637319, NULL },
+ { NULL, 4104, "0"},
+ { "macKey", 7, NULL },
+ { "SubjectPublicKeyInfo", 1610612741, NULL },
+ { "algorithm", 1073741826, "AlgorithmIdentifier"},
+ { "subjectPublicKey", 6, NULL },
+ { "GostR3410-TransportParameters", 1610612741, NULL },
+ { "encryptionParamSet", 1073741836, NULL },
+ { "ephemeralPublicKey", 1610637314, "SubjectPublicKeyInfo"},
+ { NULL, 4104, "0"},
+ { "ukm", 7, NULL },
+ { "GostR3410-KeyTransport", 536870917, NULL },
+ { "sessionEncryptedKey", 1073741826, "Gost28147-89-EncryptedKey"},
+ { "transportParameters", 536895490, "GostR3410-TransportParameters"},
+ { NULL, 4104, "0"},
+ { NULL, 0, NULL }
+};
diff --git a/grub-core/commands/appendedsig/pkix_asn1_tab.c b/grub-core/commands/appendedsig/pkix_asn1_tab.c
new file mode 100644
index 000000000..adef69d95
--- /dev/null
+++ b/grub-core/commands/appendedsig/pkix_asn1_tab.c
@@ -0,0 +1,484 @@
+#include <grub/mm.h>
+#include <grub/libtasn1.h>
+
+const asn1_static_node pkix_asn1_tab[] = {
+ { "PKIX1", 536875024, NULL },
+ { NULL, 1073741836, NULL },
+ { "PrivateKeyUsagePeriod", 1610612741, NULL },
+ { "notBefore", 1610637349, NULL },
+ { NULL, 4104, "0"},
+ { "notAfter", 536895525, NULL },
+ { NULL, 4104, "1"},
+ { "AuthorityKeyIdentifier", 1610612741, NULL },
+ { "keyIdentifier", 1610637319, NULL },
+ { NULL, 4104, "0"},
+ { "authorityCertIssuer", 1610637314, "GeneralNames"},
+ { NULL, 4104, "1"},
+ { "authorityCertSerialNumber", 536895490, "CertificateSerialNumber"},
+ { NULL, 4104, "2"},
+ { "SubjectKeyIdentifier", 1073741831, NULL },
+ { "KeyUsage", 1073741830, NULL },
+ { "DirectoryString", 1610612754, NULL },
+ { "teletexString", 1612709918, NULL },
+ { "MAX", 524298, "1"},
+ { "printableString", 1612709919, NULL },
+ { "MAX", 524298, "1"},
+ { "universalString", 1612709920, NULL },
+ { "MAX", 524298, "1"},
+ { "utf8String", 1612709922, NULL },
+ { "MAX", 524298, "1"},
+ { "bmpString", 1612709921, NULL },
+ { "MAX", 524298, "1"},
+ { "ia5String", 538968093, NULL },
+ { "MAX", 524298, "1"},
+ { "SubjectAltName", 1073741826, "GeneralNames"},
+ { "GeneralNames", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "GeneralName"},
+ { "GeneralName", 1610612754, NULL },
+ { "otherName", 1610620930, "AnotherName"},
+ { NULL, 4104, "0"},
+ { "rfc822Name", 1610620957, NULL },
+ { NULL, 4104, "1"},
+ { "dNSName", 1610620957, NULL },
+ { NULL, 4104, "2"},
+ { "x400Address", 1610620941, NULL },
+ { NULL, 4104, "3"},
+ { "directoryName", 1610620939, NULL },
+ { NULL, 1073743880, "4"},
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "ediPartyName", 1610620941, NULL },
+ { NULL, 4104, "5"},
+ { "uniformResourceIdentifier", 1610620957, NULL },
+ { NULL, 4104, "6"},
+ { "iPAddress", 1610620935, NULL },
+ { NULL, 4104, "7"},
+ { "registeredID", 536879116, NULL },
+ { NULL, 4104, "8"},
+ { "AnotherName", 1610612741, NULL },
+ { "type-id", 1073741836, NULL },
+ { "value", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "type-id", 1, NULL },
+ { "IssuerAltName", 1073741826, "GeneralNames"},
+ { "BasicConstraints", 1610612741, NULL },
+ { "cA", 1610645508, NULL },
+ { NULL, 131081, NULL },
+ { "pathLenConstraint", 537411587, NULL },
+ { "0", 10, "MAX"},
+ { "CRLDistributionPoints", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "DistributionPoint"},
+ { "DistributionPoint", 1610612741, NULL },
+ { "distributionPoint", 1610637314, "DistributionPointName"},
+ { NULL, 2056, "0"},
+ { "reasons", 1610637314, "ReasonFlags"},
+ { NULL, 4104, "1"},
+ { "cRLIssuer", 536895490, "GeneralNames"},
+ { NULL, 4104, "2"},
+ { "DistributionPointName", 1610612754, NULL },
+ { "fullName", 1610620930, "GeneralNames"},
+ { NULL, 4104, "0"},
+ { "nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"},
+ { NULL, 4104, "1"},
+ { "ReasonFlags", 1073741830, NULL },
+ { "ExtKeyUsageSyntax", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 12, NULL },
+ { "AuthorityInfoAccessSyntax", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "AccessDescription"},
+ { "AccessDescription", 1610612741, NULL },
+ { "accessMethod", 1073741836, NULL },
+ { "accessLocation", 2, "GeneralName"},
+ { "Attribute", 1610612741, NULL },
+ { "type", 1073741836, NULL },
+ { "values", 536870927, NULL },
+ { NULL, 13, NULL },
+ { "AttributeTypeAndValue", 1610612741, NULL },
+ { "type", 1073741836, NULL },
+ { "value", 13, NULL },
+ { "Name", 1610612754, NULL },
+ { "rdnSequence", 536870923, NULL },
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "DistinguishedName", 1610612747, NULL },
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "RelativeDistinguishedName", 1612709903, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "AttributeTypeAndValue"},
+ { "Certificate", 1610612741, NULL },
+ { "tbsCertificate", 1073741826, "TBSCertificate"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 6, NULL },
+ { "TBSCertificate", 1610612741, NULL },
+ { "version", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 2056, "0"},
+ { "serialNumber", 1073741826, "CertificateSerialNumber"},
+ { "signature", 1073741826, "AlgorithmIdentifier"},
+ { "issuer", 1073741826, "Name"},
+ { "validity", 1073741826, "Validity"},
+ { "subject", 1073741826, "Name"},
+ { "subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
+ { "issuerUniqueID", 1610637314, "UniqueIdentifier"},
+ { NULL, 4104, "1"},
+ { "subjectUniqueID", 1610637314, "UniqueIdentifier"},
+ { NULL, 4104, "2"},
+ { "extensions", 536895490, "Extensions"},
+ { NULL, 2056, "3"},
+ { "CertificateSerialNumber", 1073741827, NULL },
+ { "Validity", 1610612741, NULL },
+ { "notBefore", 1073741826, "Time"},
+ { "notAfter", 2, "Time"},
+ { "Time", 1610612754, NULL },
+ { "utcTime", 1073741860, NULL },
+ { "generalTime", 37, NULL },
+ { "UniqueIdentifier", 1073741830, NULL },
+ { "SubjectPublicKeyInfo", 1610612741, NULL },
+ { "algorithm", 1073741826, "AlgorithmIdentifier"},
+ { "subjectPublicKey", 6, NULL },
+ { "Extensions", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "Extension"},
+ { "Extension", 1610612741, NULL },
+ { "extnID", 1073741836, NULL },
+ { "critical", 1610645508, NULL },
+ { NULL, 131081, NULL },
+ { "extnValue", 7, NULL },
+ { "CertificateList", 1610612741, NULL },
+ { "tbsCertList", 1073741826, "TBSCertList"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 6, NULL },
+ { "TBSCertList", 1610612741, NULL },
+ { "version", 1073758211, NULL },
+ { "signature", 1073741826, "AlgorithmIdentifier"},
+ { "issuer", 1073741826, "Name"},
+ { "thisUpdate", 1073741826, "Time"},
+ { "nextUpdate", 1073758210, "Time"},
+ { "revokedCertificates", 1610629131, NULL },
+ { NULL, 536870917, NULL },
+ { "userCertificate", 1073741826, "CertificateSerialNumber"},
+ { "revocationDate", 1073741826, "Time"},
+ { "crlEntryExtensions", 16386, "Extensions"},
+ { "crlExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "0"},
+ { "AlgorithmIdentifier", 1610612741, NULL },
+ { "algorithm", 1073741836, NULL },
+ { "parameters", 541081613, NULL },
+ { "algorithm", 1, NULL },
+ { "Dss-Sig-Value", 1610612741, NULL },
+ { "r", 1073741827, NULL },
+ { "s", 3, NULL },
+ { "Dss-Parms", 1610612741, NULL },
+ { "p", 1073741827, NULL },
+ { "q", 1073741827, NULL },
+ { "g", 3, NULL },
+ { "pkcs-7-ContentInfo", 1610612741, NULL },
+ { "contentType", 1073741836, NULL },
+ { "content", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "contentType", 1, NULL },
+ { "pkcs-7-DigestInfo", 1610612741, NULL },
+ { "digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "digest", 7, NULL },
+ { "pkcs-7-SignedData", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"},
+ { "encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"},
+ { "certificates", 1610637314, "pkcs-7-CertificateSet"},
+ { NULL, 4104, "0"},
+ { "crls", 1610637314, "pkcs-7-CertificateRevocationLists"},
+ { NULL, 4104, "1"},
+ { "signerInfos", 2, "pkcs-7-SignerInfos"},
+ { "pkcs-7-DigestAlgorithmIdentifiers", 1610612751, NULL },
+ { NULL, 2, "AlgorithmIdentifier"},
+ { "pkcs-7-EncapsulatedContentInfo", 1610612741, NULL },
+ { "eContentType", 1073741836, NULL },
+ { "eContent", 536895501, NULL },
+ { NULL, 2056, "0"},
+ { "pkcs-7-CertificateRevocationLists", 1610612751, NULL },
+ { NULL, 13, NULL },
+ { "pkcs-7-CertificateChoices", 1610612754, NULL },
+ { "certificate", 13, NULL },
+ { "pkcs-7-CertificateSet", 1610612751, NULL },
+ { NULL, 2, "pkcs-7-CertificateChoices"},
+ { "IssuerAndSerialNumber", 1610612741, NULL },
+ { "issuer", 1073741826, "Name"},
+ { "serialNumber", 2, "CertificateSerialNumber"},
+ { "pkcs-7-SignerInfo", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "sid", 1073741826, "SignerIdentifier"},
+ { "digestAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signedAttrs", 1610637314, "SignedAttributes"},
+ { NULL, 4104, "0"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 1073741831, NULL },
+ { "unsignedAttrs", 536895490, "SignedAttributes"},
+ { NULL, 4104, "1"},
+ { "SignedAttributes", 1612709903, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "Attribute"},
+ { "SignerIdentifier", 1610612754, NULL },
+ { "issuerAndSerialNumber", 1073741826, "IssuerAndSerialNumber"},
+ { "subjectKeyIdentifier", 536879111, NULL },
+ { NULL, 4104, "0"},
+ { "pkcs-7-SignerInfos", 1610612751, NULL },
+ { NULL, 2, "pkcs-7-SignerInfo"},
+ { "pkcs-10-CertificationRequestInfo", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "subject", 1073741826, "Name"},
+ { "subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"},
+ { "attributes", 536879106, "Attributes"},
+ { NULL, 4104, "0"},
+ { "Attributes", 1610612751, NULL },
+ { NULL, 2, "Attribute"},
+ { "pkcs-10-CertificationRequest", 1610612741, NULL },
+ { "certificationRequestInfo", 1073741826, "pkcs-10-CertificationRequestInfo"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 6, NULL },
+ { "pkcs-9-at-challengePassword", 1879048204, NULL },
+ { "iso", 1073741825, "1"},
+ { "member-body", 1073741825, "2"},
+ { "us", 1073741825, "840"},
+ { "rsadsi", 1073741825, "113549"},
+ { "pkcs", 1073741825, "1"},
+ { NULL, 1073741825, "9"},
+ { NULL, 1, "7"},
+ { "pkcs-9-challengePassword", 1610612754, NULL },
+ { "printableString", 1073741855, NULL },
+ { "utf8String", 34, NULL },
+ { "pkcs-9-localKeyId", 1073741831, NULL },
+ { "pkcs-8-PrivateKeyInfo", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "privateKey", 1073741831, NULL },
+ { "attributes", 536895490, "Attributes"},
+ { NULL, 4104, "0"},
+ { "pkcs-8-EncryptedPrivateKeyInfo", 1610612741, NULL },
+ { "encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "encryptedData", 2, "pkcs-8-EncryptedData"},
+ { "pkcs-8-EncryptedData", 1073741831, NULL },
+ { "pkcs-5-des-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "8"},
+ { "pkcs-5-des-EDE3-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "8"},
+ { "pkcs-5-aes128-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "16"},
+ { "pkcs-5-aes192-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "16"},
+ { "pkcs-5-aes256-CBC-params", 1612709895, NULL },
+ { NULL, 1048586, "16"},
+ { "Gost28147-89-Parameters", 1610612741, NULL },
+ { "iv", 1073741831, NULL },
+ { "encryptionParamSet", 12, NULL },
+ { "pkcs-5-PBE-params", 1610612741, NULL },
+ { "salt", 1073741831, NULL },
+ { "iterationCount", 3, NULL },
+ { "pkcs-5-PBES2-params", 1610612741, NULL },
+ { "keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
+ { "encryptionScheme", 2, "AlgorithmIdentifier"},
+ { "pkcs-5-PBKDF2-params", 1610612741, NULL },
+ { "salt", 1610612754, NULL },
+ { "specified", 1073741831, NULL },
+ { "otherSource", 2, "AlgorithmIdentifier"},
+ { "iterationCount", 1611137027, NULL },
+ { "1", 10, "MAX"},
+ { "keyLength", 1611153411, NULL },
+ { "1", 10, "MAX"},
+ { "prf", 16386, "AlgorithmIdentifier"},
+ { "pkcs-12-PFX", 1610612741, NULL },
+ { "version", 1610874883, NULL },
+ { "v3", 1, "3"},
+ { "authSafe", 1073741826, "pkcs-7-ContentInfo"},
+ { "macData", 16386, "pkcs-12-MacData"},
+ { "pkcs-12-PbeParams", 1610612741, NULL },
+ { "salt", 1073741831, NULL },
+ { "iterations", 3, NULL },
+ { "pkcs-12-MacData", 1610612741, NULL },
+ { "mac", 1073741826, "pkcs-7-DigestInfo"},
+ { "macSalt", 1073741831, NULL },
+ { "iterations", 536903683, NULL },
+ { NULL, 9, "1"},
+ { "pkcs-12-AuthenticatedSafe", 1610612747, NULL },
+ { NULL, 2, "pkcs-7-ContentInfo"},
+ { "pkcs-12-SafeContents", 1610612747, NULL },
+ { NULL, 2, "pkcs-12-SafeBag"},
+ { "pkcs-12-SafeBag", 1610612741, NULL },
+ { "bagId", 1073741836, NULL },
+ { "bagValue", 1614815245, NULL },
+ { NULL, 1073743880, "0"},
+ { "badId", 1, NULL },
+ { "bagAttributes", 536887311, NULL },
+ { NULL, 2, "Attribute"},
+ { "pkcs-12-CertBag", 1610612741, NULL },
+ { "certId", 1073741836, NULL },
+ { "certValue", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "certId", 1, NULL },
+ { "pkcs-12-CRLBag", 1610612741, NULL },
+ { "crlId", 1073741836, NULL },
+ { "crlValue", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "crlId", 1, NULL },
+ { "pkcs-12-SecretBag", 1610612741, NULL },
+ { "secretTypeId", 1073741836, NULL },
+ { "secretValue", 541073421, NULL },
+ { NULL, 1073743880, "0"},
+ { "secretTypeId", 1, NULL },
+ { "pkcs-7-Data", 1073741831, NULL },
+ { "pkcs-7-EncryptedData", 1610612741, NULL },
+ { "version", 1073741827, NULL },
+ { "encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"},
+ { "unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"},
+ { NULL, 4104, "1"},
+ { "pkcs-7-EncryptedContentInfo", 1610612741, NULL },
+ { "contentType", 1073741836, NULL },
+ { "contentEncryptionAlgorithm", 1073741826, "pkcs-7-ContentEncryptionAlgorithmIdentifier"},
+ { "encryptedContent", 536895495, NULL },
+ { NULL, 4104, "0"},
+ { "pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
+ { "pkcs-7-UnprotectedAttributes", 1612709903, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "Attribute"},
+ { "ProxyCertInfo", 1610612741, NULL },
+ { "pCPathLenConstraint", 1611153411, NULL },
+ { "0", 10, "MAX"},
+ { "proxyPolicy", 2, "ProxyPolicy"},
+ { "ProxyPolicy", 1610612741, NULL },
+ { "policyLanguage", 1073741836, NULL },
+ { "policy", 16391, NULL },
+ { "certificatePolicies", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "PolicyInformation"},
+ { "PolicyInformation", 1610612741, NULL },
+ { "policyIdentifier", 1073741836, NULL },
+ { "policyQualifiers", 538984459, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "PolicyQualifierInfo"},
+ { "PolicyQualifierInfo", 1610612741, NULL },
+ { "policyQualifierId", 1073741836, NULL },
+ { "qualifier", 541065229, NULL },
+ { "policyQualifierId", 1, NULL },
+ { "CPSuri", 1073741853, NULL },
+ { "UserNotice", 1610612741, NULL },
+ { "noticeRef", 1073758210, "NoticeReference"},
+ { "explicitText", 16386, "DisplayText"},
+ { "NoticeReference", 1610612741, NULL },
+ { "organization", 1073741826, "DisplayText"},
+ { "noticeNumbers", 536870923, NULL },
+ { NULL, 3, NULL },
+ { "DisplayText", 1610612754, NULL },
+ { "ia5String", 1612709917, NULL },
+ { "200", 524298, "1"},
+ { "visibleString", 1612709923, NULL },
+ { "200", 524298, "1"},
+ { "bmpString", 1612709921, NULL },
+ { "200", 524298, "1"},
+ { "utf8String", 538968098, NULL },
+ { "200", 524298, "1"},
+ { "OCSPRequest", 1610612741, NULL },
+ { "tbsRequest", 1073741826, "TBSRequest"},
+ { "optionalSignature", 536895490, "Signature"},
+ { NULL, 2056, "0"},
+ { "TBSRequest", 1610612741, NULL },
+ { "version", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 2056, "0"},
+ { "requestorName", 1610637314, "GeneralName"},
+ { NULL, 2056, "1"},
+ { "requestList", 1610612747, NULL },
+ { NULL, 2, "Request"},
+ { "requestExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "2"},
+ { "Signature", 1610612741, NULL },
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 1073741830, NULL },
+ { "certs", 536895499, NULL },
+ { NULL, 1073743880, "0"},
+ { NULL, 2, "Certificate"},
+ { "Request", 1610612741, NULL },
+ { "reqCert", 1073741826, "CertID"},
+ { "singleRequestExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "0"},
+ { "CertID", 1610612741, NULL },
+ { "hashAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "issuerNameHash", 1073741831, NULL },
+ { "issuerKeyHash", 1073741831, NULL },
+ { "serialNumber", 2, "CertificateSerialNumber"},
+ { "OCSPResponse", 1610612741, NULL },
+ { "responseStatus", 1073741826, "OCSPResponseStatus"},
+ { "responseBytes", 536895490, "ResponseBytes"},
+ { NULL, 2056, "0"},
+ { "OCSPResponseStatus", 1610874901, NULL },
+ { "successful", 1073741825, "0"},
+ { "malformedRequest", 1073741825, "1"},
+ { "internalError", 1073741825, "2"},
+ { "tryLater", 1073741825, "3"},
+ { "sigRequired", 1073741825, "5"},
+ { "unauthorized", 1, "6"},
+ { "ResponseBytes", 1610612741, NULL },
+ { "responseType", 1073741836, NULL },
+ { "response", 7, NULL },
+ { "BasicOCSPResponse", 1610612741, NULL },
+ { "tbsResponseData", 1073741826, "ResponseData"},
+ { "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
+ { "signature", 1073741830, NULL },
+ { "certs", 536895499, NULL },
+ { NULL, 1073743880, "0"},
+ { NULL, 2, "Certificate"},
+ { "ResponseData", 1610612741, NULL },
+ { "version", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 2056, "0"},
+ { "responderID", 1073741826, "ResponderID"},
+ { "producedAt", 1073741861, NULL },
+ { "responses", 1610612747, NULL },
+ { NULL, 2, "SingleResponse"},
+ { "responseExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "1"},
+ { "ResponderID", 1610612754, NULL },
+ { "byName", 1610620939, NULL },
+ { NULL, 1073743880, "1"},
+ { NULL, 2, "RelativeDistinguishedName"},
+ { "byKey", 536879111, NULL },
+ { NULL, 2056, "2"},
+ { "SingleResponse", 1610612741, NULL },
+ { "certID", 1073741826, "CertID"},
+ { "certStatus", 1073741826, "CertStatus"},
+ { "thisUpdate", 1073741861, NULL },
+ { "nextUpdate", 1610637349, NULL },
+ { NULL, 2056, "0"},
+ { "singleExtensions", 536895490, "Extensions"},
+ { NULL, 2056, "1"},
+ { "CertStatus", 1610612754, NULL },
+ { "good", 1610620948, NULL },
+ { NULL, 4104, "0"},
+ { "revoked", 1610620930, "RevokedInfo"},
+ { NULL, 4104, "1"},
+ { "unknown", 536879106, "UnknownInfo"},
+ { NULL, 4104, "2"},
+ { "RevokedInfo", 1610612741, NULL },
+ { "revocationTime", 1073741861, NULL },
+ { "revocationReason", 537157653, NULL },
+ { NULL, 1073743880, "0"},
+ { "unspecified", 1, "0"},
+ { "UnknownInfo", 1073741844, NULL },
+ { "NameConstraints", 1610612741, NULL },
+ { "permittedSubtrees", 1610637314, "GeneralSubtrees"},
+ { NULL, 4104, "0"},
+ { "excludedSubtrees", 536895490, "GeneralSubtrees"},
+ { NULL, 4104, "1"},
+ { "GeneralSubtrees", 1612709899, NULL },
+ { "MAX", 1074266122, "1"},
+ { NULL, 2, "GeneralSubtree"},
+ { "GeneralSubtree", 1610612741, NULL },
+ { "base", 1073741826, "GeneralName"},
+ { "minimum", 1610653699, NULL },
+ { NULL, 1073741833, "0"},
+ { NULL, 4104, "0"},
+ { "maximum", 536895491, NULL },
+ { NULL, 4104, "1"},
+ { "TlsFeatures", 536870923, NULL },
+ { NULL, 3, NULL },
+ { NULL, 0, NULL }
+};
--
2.31.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,764 @@
From 97104dbd207a07fa3759b23766fa60f7bb8d16b4 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 30 Jul 2020 01:35:43 +1000
Subject: [PATCH 19/23] appended signatures: support verifying appended
signatures
Building on the parsers and the ability to embed x509 certificates, as
well as the existing gcrypt functionality, add a module for verifying
appended signatures.
This includes a verifier that requires that Linux kernels and grub modules
have appended signatures, and commands to manage the list of trusted
certificates for verification.
Verification must be enabled by setting check_appended_signatures. If
GRUB is locked down when the module is loaded, verification will be
enabled and locked automatically.
As with the PGP verifier, it is not a complete secure-boot solution:
other mechanisms, such as a password or lockdown, must be used to ensure
that a user cannot drop to the grub shell and disable verification.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
v2 changes:
- Improve x509 parser function name
- Constify data parameters in function signatures
- Support multiple signers
- Use an enum rather than 0, 1 and 2 for various signature
enforcement states.
- Spin out a file reading function that was duplicated.
- Fix some code style and clarity issues.
Thanks to Nayna Jain and Stefan Berger for their reviews.
Revert "fixups so that you can build pkcs7 without posixly"
This reverts commit 676a19fa8a7f9cca7a58ce2180110f609185b2bd.
---
grub-core/Makefile.core.def | 14 +
grub-core/commands/appendedsig/appendedsig.c | 669 +++++++++++++++++++
include/grub/file.h | 2 +
3 files changed, 685 insertions(+)
create mode 100644 grub-core/commands/appendedsig/appendedsig.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 6a3ff4265..b55294e25 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -952,6 +952,20 @@ module = {
enable = i386_pc;
};
+module = {
+ name = appendedsig;
+ common = commands/appendedsig/appendedsig.c;
+ common = commands/appendedsig/x509.c;
+ common = commands/appendedsig/pkcs7.c;
+ common = commands/appendedsig/asn1util.c;
+ common = commands/appendedsig/gnutls_asn1_tab.c;
+ common = commands/appendedsig/pkix_asn1_tab.c;
+
+ // posix wrapper required for gcry to get sys/types.h
+ cflags = '$(CFLAGS_POSIX)';
+ cppflags = '-I$(srcdir)/lib/posix_wrap';
+};
+
module = {
name = hdparm;
common = commands/hdparm.c;
diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c
new file mode 100644
index 000000000..e63ad1ac6
--- /dev/null
+++ b/grub-core/commands/appendedsig/appendedsig.c
@@ -0,0 +1,669 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2020-2021 IBM Corporation.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/command.h>
+#include <grub/crypto.h>
+#include <grub/pkcs1_v15.h>
+#include <grub/i18n.h>
+#include <grub/gcrypt/gcrypt.h>
+#include <grub/kernel.h>
+#include <grub/extcmd.h>
+#include <grub/verify.h>
+#include <grub/libtasn1.h>
+#include <grub/env.h>
+#include <grub/lockdown.h>
+
+#include "appendedsig.h"
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+const char magic[] = "~Module signature appended~\n";
+
+/*
+ * This structure is extracted from scripts/sign-file.c in the linux kernel
+ * source. It was licensed as LGPLv2.1+, which is GPLv3+ compatible.
+ */
+struct module_signature
+{
+ grub_uint8_t algo; /* Public-key crypto algorithm [0] */
+ grub_uint8_t hash; /* Digest algorithm [0] */
+ grub_uint8_t id_type; /* Key identifier type [PKEY_ID_PKCS7] */
+ grub_uint8_t signer_len; /* Length of signer's name [0] */
+ grub_uint8_t key_id_len; /* Length of key identifier [0] */
+ grub_uint8_t __pad[3];
+ grub_uint32_t sig_len; /* Length of signature data */
+} GRUB_PACKED;
+
+
+/* This represents an entire, parsed, appended signature */
+struct grub_appended_signature
+{
+ grub_size_t signature_len; /* Length of PKCS#7 data +
+ * metadata + magic */
+
+ struct module_signature sig_metadata; /* Module signature metadata */
+ struct pkcs7_signedData pkcs7; /* Parsed PKCS#7 data */
+};
+
+/* Trusted certificates for verifying appended signatures */
+struct x509_certificate *grub_trusted_key;
+
+/*
+ * Force gcry_rsa to be a module dependency.
+ *
+ * If we use grub_crypto_pk_rsa, then then the gcry_rsa module won't be built
+ * in if you add 'appendedsig' to grub-install --modules. You would need to
+ * add 'gcry_rsa' too. That's confusing and seems suboptimal, especially when
+ * we only support RSA.
+ *
+ * Dynamic loading also causes some concerns. We can't load gcry_rsa from the
+ * the filesystem after we install the verifier - we won't be able to verify
+ * it without having it already present. We also shouldn't load it before we
+ * install the verifier, because that would mean it wouldn't be verified - an
+ * attacker could insert any code they wanted into the module.
+ *
+ * So instead, reference the internal symbol from gcry_rsa. That creates a
+ * direct dependency on gcry_rsa, so it will be built in when this module
+ * is built in. Being built in (assuming the core image is itself signed!)
+ * also resolves our concerns about loading from the filesystem.
+ */
+extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
+
+static enum
+{ check_sigs_no = 0,
+ check_sigs_enforce = 1,
+ check_sigs_forced = 2
+} check_sigs = check_sigs_no;
+
+static const char *
+grub_env_read_sec (struct grub_env_var *var __attribute__((unused)),
+ const char *val __attribute__((unused)))
+{
+ if (check_sigs == check_sigs_forced)
+ return "forced";
+ else if (check_sigs == check_sigs_enforce)
+ return "enforce";
+ else
+ return "no";
+}
+
+static char *
+grub_env_write_sec (struct grub_env_var *var __attribute__((unused)),
+ const char *val)
+{
+ /* Do not allow the value to be changed if set to forced */
+ if (check_sigs == check_sigs_forced)
+ return grub_strdup ("forced");
+
+ if ((*val == '2') || (*val == 'f'))
+ check_sigs = check_sigs_forced;
+ else if ((*val == '1') || (*val == 'e'))
+ check_sigs = check_sigs_enforce;
+ else if ((*val == '0') || (*val == 'n'))
+ check_sigs = check_sigs_no;
+
+ 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)
+{
+ grub_err_t err;
+ grub_size_t pkcs7_size;
+ grub_size_t remaining_len;
+ const grub_uint8_t *appsigdata = buf + bufsize - grub_strlen (magic);
+
+ if (bufsize < grub_strlen (magic))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("File too short for signature magic"));
+
+ if (grub_memcmp (appsigdata, (grub_uint8_t *) magic, grub_strlen (magic)))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("Missing or invalid signature magic"));
+
+ remaining_len = bufsize - grub_strlen (magic);
+
+ if (remaining_len < sizeof (struct module_signature))
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("File too short for signature metadata"));
+
+ appsigdata -= sizeof (struct module_signature);
+
+ /* extract the metadata */
+ grub_memcpy (&(sig->sig_metadata), appsigdata,
+ sizeof (struct module_signature));
+
+ remaining_len -= sizeof (struct module_signature);
+
+ if (sig->sig_metadata.id_type != 2)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("Wrong signature type"));
+
+ pkcs7_size = grub_be_to_cpu32 (sig->sig_metadata.sig_len);
+
+ if (pkcs7_size > remaining_len)
+ return grub_error (GRUB_ERR_BAD_SIGNATURE,
+ N_("File too short for PKCS#7 message"));
+
+ grub_dprintf ("appendedsig", "sig len %" PRIuGRUB_SIZE "\n", pkcs7_size);
+
+ sig->signature_len =
+ grub_strlen (magic) + sizeof (struct module_signature) + pkcs7_size;
+
+ /* rewind pointer and parse pkcs7 data */
+ appsigdata -= pkcs7_size;
+
+ err = parse_pkcs7_signedData (appsigdata, pkcs7_size, &sig->pkcs7);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize)
+{
+ grub_err_t err = GRUB_ERR_NONE;
+ grub_size_t datasize;
+ void *context;
+ unsigned char *hash;
+ gcry_mpi_t hashmpi;
+ gcry_err_code_t rc;
+ struct x509_certificate *pk;
+ struct grub_appended_signature sig;
+ struct pkcs7_signerInfo *si;
+ int i;
+
+ if (!grub_trusted_key)
+ 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)
+ return err;
+
+ datasize = bufsize - sig.signature_len;
+
+ for (i = 0; i < sig.pkcs7.signerInfo_count; i++)
+ {
+ /* 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_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;
+ }
+
+ 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);
+
+ 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"));
+
+cleanup:
+ pkcs7_signedData_release (&sig.pkcs7);
+
+ return err;
+}
+
+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;
+
+ if (argc < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
+
+ grub_dprintf ("appendedsig", "verifying %s\n", args[0]);
+
+ f = grub_file_open (args[0], GRUB_FILE_TYPE_VERIFY_SIGNATURE);
+ if (!f)
+ {
+ err = grub_errno;
+ goto cleanup;
+ }
+
+ err = file_read_all (f, &data, &file_size);
+ if (err != GRUB_ERR_NONE)
+ goto cleanup;
+
+ err = grub_verify_appended_signature (data, file_size);
+
+ grub_free (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)
+{
+ unsigned long cert_num, i;
+ struct x509_certificate *cert, *prev;
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("One argument expected"));
+
+ grub_errno = GRUB_ERR_NONE;
+ cert_num = grub_strtoul (args[0], NULL, 10);
+ if (grub_errno != GRUB_ERR_NONE)
+ return grub_errno;
+
+ if (cert_num < 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("Certificate number too small - numbers start at 1"));
+
+ if (cert_num == 1)
+ {
+ cert = grub_trusted_key;
+ grub_trusted_key = cert->next;
+
+ certificate_release (cert);
+ grub_free (cert);
+ return GRUB_ERR_NONE;
+ }
+ i = 2;
+ prev = grub_trusted_key;
+ cert = grub_trusted_key->next;
+ while (cert)
+ {
+ if (i == cert_num)
+ {
+ prev->next = cert->next;
+ certificate_release (cert);
+ grub_free (cert);
+ return GRUB_ERR_NONE;
+ }
+ i++;
+ prev = cert;
+ cert = cert->next;
+ }
+
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("No certificate number %lu found - only %lu certificates in the store"),
+ cert_num, i - 1);
+}
+
+static grub_err_t
+grub_cmd_trust (grub_command_t cmd __attribute__((unused)),
+ int argc, char **args)
+{
+ grub_file_t certf;
+ struct x509_certificate *cert = NULL;
+ grub_err_t err;
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
+
+ certf = grub_file_open (args[0],
+ GRUB_FILE_TYPE_CERTIFICATE_TRUST
+ | GRUB_FILE_TYPE_NO_DECOMPRESS);
+ if (!certf)
+ return grub_errno;
+
+
+ cert = grub_zalloc (sizeof (struct x509_certificate));
+ if (!cert)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ N_("Could not allocate memory for certificate"));
+
+ err = read_cert_from_file (certf, cert);
+ grub_file_close (certf);
+ if (err != GRUB_ERR_NONE)
+ {
+ grub_free (cert);
+ return err;
+ }
+ grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
+ cert->subject);
+
+ cert->next = grub_trusted_key;
+ grub_trusted_key = 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)))
+{
+ struct x509_certificate *cert;
+ int cert_num = 1;
+ grub_size_t i;
+
+ for (cert = grub_trusted_key; cert; cert = cert->next)
+ {
+ grub_printf (N_("Certificate %d:\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++;
+
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+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)
+{
+ if (check_sigs == check_sigs_no)
+ {
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ return GRUB_ERR_NONE;
+ }
+
+ switch (type & GRUB_FILE_TYPE_MASK)
+ {
+ case GRUB_FILE_TYPE_CERTIFICATE_TRUST:
+ /*
+ * This is a certificate to add to trusted keychain.
+ *
+ * This needs to be verified or blocked. Ideally we'd write an x509
+ * verifier, but we lack the hubris required to take this on. Instead,
+ * require that it have an appended signature.
+ */
+
+ /* Fall through */
+
+ case GRUB_FILE_TYPE_LINUX_KERNEL:
+ case GRUB_FILE_TYPE_GRUB_MODULE:
+ /*
+ * Appended signatures are only defined for ELF binaries.
+ * Out of an abundance of caution, we only verify Linux kernels and
+ * GRUB modules at this point.
+ */
+ *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
+ return GRUB_ERR_NONE;
+
+ case GRUB_FILE_TYPE_ACPI_TABLE:
+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
+ /*
+ * It is possible to use appended signature verification without
+ * lockdown - like the PGP verifier. When combined with an embedded
+ * config file in a signed grub binary, this could still be a meaningful
+ * secure-boot chain - so long as it isn't subverted by something like a
+ * rouge ACPI table or DT image. Defer them explicitly.
+ */
+ *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH;
+ return GRUB_ERR_NONE;
+
+ default:
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
+ return GRUB_ERR_NONE;
+ }
+}
+
+static grub_err_t
+appendedsig_write (void *ctxt __attribute__((unused)),
+ void *buf, grub_size_t size)
+{
+ return grub_verify_appended_signature (buf, size);
+}
+
+struct grub_file_verifier grub_appendedsig_verifier = {
+ .name = "appendedsig",
+ .init = appendedsig_init,
+ .write = appendedsig_write,
+};
+
+static grub_ssize_t
+pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
+{
+ grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
+ return len;
+}
+
+/* Filesystem descriptor. */
+static struct grub_fs pseudo_fs = {
+ .name = "pseudo",
+ .fs_read = pseudo_read
+};
+
+static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
+
+GRUB_MOD_INIT (appendedsig)
+{
+ int rc;
+ struct grub_module_header *header;
+
+ /* If in lockdown, immediately enter forced mode */
+ 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_env_export ("check_appended_signatures");
+
+ rc = asn1_init ();
+ if (rc)
+ 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;
+ }
+
+ 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."));
+
+ grub_verifier_register (&grub_appendedsig_verifier);
+ grub_dl_set_persistent (mod);
+}
+
+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);
+}
diff --git a/include/grub/file.h b/include/grub/file.h
index 811728a99..99b1f3855 100644
--- a/include/grub/file.h
+++ b/include/grub/file.h
@@ -80,6 +80,8 @@ enum grub_file_type
GRUB_FILE_TYPE_PUBLIC_KEY,
/* File holding public key to add to trused keys. */
GRUB_FILE_TYPE_PUBLIC_KEY_TRUST,
+ /* File holding x509 certificiate to add to trusted keys. */
+ GRUB_FILE_TYPE_CERTIFICATE_TRUST,
/* File of which we intend to print a blocklist to the user. */
GRUB_FILE_TYPE_PRINT_BLOCKLIST,
/* File we intend to use for test loading or testing speed. */
--
2.31.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,342 @@
From 4edb825a012e9e7b9ad08aa693cfdebf42ae40e6 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 1 Oct 2020 13:02:09 +1000
Subject: [PATCH 21/23] appended signatures: documentation
This explains how appended signatures can be used to form part of
a secure boot chain, and documents the commands and variables
introduced.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
v2: fix a grammar issue, thanks Stefan Berger.
---
docs/grub.texi | 193 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 176 insertions(+), 17 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index dc1c58304..988ef8ddc 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -3209,6 +3209,7 @@ These variables have special meaning to GRUB.
@menu
* biosnum::
+* check_appended_signatures::
* check_signatures::
* chosen::
* cmdpath::
@@ -3268,11 +3269,18 @@ For an alternative approach which also changes BIOS drive mappings for the
chain-loaded system, @pxref{drivemap}.
+@node check_appended_signatures
+@subsection check_appended_signatures
+
+This variable controls whether GRUB enforces appended signature validation on
+certain loaded files. @xref{Using appended signatures}.
+
+
@node check_signatures
@subsection check_signatures
-This variable controls whether GRUB enforces digital signature
-validation on loaded files. @xref{Using digital signatures}.
+This variable controls whether GRUB enforces GPG-style digital signature
+validation on loaded files. @xref{Using GPG-style digital signatures}.
@node chosen
@subsection chosen
@@ -3989,6 +3997,7 @@ 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
* drivemap:: Map a drive to another
* echo:: Display a line of text
* eval:: Evaluate agruments as GRUB commands
@@ -4005,6 +4014,7 @@ you forget a command, you can run the command @command{help}
* keystatus:: Check key modifier status
* linux:: Load a Linux kernel
* linux16:: Load a Linux kernel (16-bit mode)
+* 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
@@ -4042,8 +4052,10 @@ 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
* unset:: Unset an environment variable
@comment * vbeinfo:: List available video modes
+* verify_appended:: Verify appended digital signature
* verify_detached:: Verify detached digital signature
* videoinfo:: List available video modes
@comment * xen_*:: Xen boot commands for AArch64
@@ -4371,9 +4383,28 @@ These keys are used to validate signatures when environment variable
@code{check_signatures} is set to @code{enforce}
(@pxref{check_signatures}), and by some invocations of
@command{verify_detached} (@pxref{verify_detached}). @xref{Using
-digital signatures}, for more information.
+GPG-style digital signatures}, for more information.
+@end deffn
+
+
+@node distrust_certificate
+@subsection distrust_certificate
+
+@deffn Command distrust_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}).
+
+These certificates are used to validate appended signatures when environment
+variable @code{check_appended_signatures} is set to @code{enforce}
+(@pxref{check_appended_signatures}), and by @command{verify_appended}
+(@pxref{verify_appended}). See @xref{Using appended signatures} for more
+information.
@end deffn
+
@node drivemap
@subsection drivemap
@@ -4631,6 +4662,21 @@ This command is only available on x86 systems.
@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
@@ -4650,7 +4696,7 @@ The output is in GPG's v4 key fingerprint format (i.e., the output of
@code{gpg --fingerprint}). The least significant four bytes (last
eight hexadecimal digits) can be used as an argument to
@command{distrust} (@pxref{distrust}).
-@xref{Using digital signatures}, for more information about uses for
+@xref{Using GPG-style digital signatures}, for more information about uses for
these keys.
@end deffn
@@ -4685,8 +4731,12 @@ When used with care, @option{--skip-sig} and the whitelist enable an
administrator to configure a system to boot only signed
configurations, but to allow the user to select from among multiple
configurations, and to enable ``one-shot'' boot attempts and
-``savedefault'' behavior. @xref{Using digital signatures}, for more
+``savedefault'' behavior. @xref{Using GPG-style digital signatures}, for more
information.
+
+Extra care should be taken when combining this command with appended signatures
+(@pxref{Using appended signatures}), as this file is not validated by an
+appended signature and could set @code{check_appended_signatures=no}.
@end deffn
@@ -4982,7 +5032,7 @@ read. It is possible to modify a digitally signed environment block
file from within GRUB using this command, such that its signature will
no longer be valid on subsequent boots. Care should be taken in such
advanced configurations to avoid rendering the system
-unbootable. @xref{Using digital signatures}, for more information.
+unbootable. @xref{Using GPG-style digital signatures}, for more information.
@end deffn
@@ -5382,11 +5432,31 @@ signatures when environment variable @code{check_signatures} is set to
must itself be properly signed. The @option{--skip-sig} option can be
used to disable signature-checking when reading @var{pubkey_file}
itself. It is expected that @option{--skip-sig} is useful for testing
-and manual booting. @xref{Using digital signatures}, for more
+and manual booting. @xref{Using GPG-style digital signatures}, for more
information.
@end deffn
+@node trust_certificate
+@subsection trust_certificate
+
+@deffn Command trust_certificate x509_certificate
+Read a DER-formatted x509 certificate from the file @var{x509_certificate}
+and add it to GRUB's internal list of trusted x509 certificates. These
+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}
+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
+certificates themselves.)
+
+See @xref{Using appended signatures} for more information.
+@end deffn
+
+
@node unset
@subsection unset
@@ -5405,6 +5475,18 @@ only on PC BIOS platforms.
@end deffn
@end ignore
+@node verify_appended
+@subsection verify_appended
+
+@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}).
+
+Exit code @code{$?} is set to 0 if the signature validates
+successfully. If validation fails, it is set to a non-zero value.
+See @xref{Using appended signatures}, for more information.
+@end deffn
@node verify_detached
@subsection verify_detached
@@ -5423,7 +5505,7 @@ tried.
Exit code @code{$?} is set to 0 if the signature validates
successfully. If validation fails, it is set to a non-zero value.
-@xref{Using digital signatures}, for more information.
+@xref{Using GPG-style digital signatures}, for more information.
@end deffn
@node videoinfo
@@ -5808,13 +5890,14 @@ environment variables and commands are listed in the same order.
@chapter Security
@menu
-* Authentication and authorisation:: Users and access control
-* Using digital signatures:: Booting digitally signed code
-* UEFI secure boot and shim:: Booting digitally signed PE files
-* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
-* Measured Boot:: Measuring boot components
-* Lockdown:: Lockdown when booting on a secure setup
-* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
+* Authentication and authorisation:: Users and access control
+* Using GPG-style digital signatures:: Booting digitally signed code
+* Using appended signatures:: An alternative approach to booting digitally signed code
+* UEFI secure boot and shim:: Booting digitally signed PE files
+* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
+* Measured Boot:: Measuring boot components
+* Lockdown:: Lockdown when booting on a secure setup
+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
@end menu
@node Authentication and authorisation
@@ -5888,8 +5971,8 @@ generating configuration files with authentication. You can use
adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2}
commands.
-@node Using digital signatures
-@section Using digital signatures in GRUB
+@node Using GPG-style digital signatures
+@section Using GPG-style digital signatures in GRUB
GRUB's @file{core.img} can optionally provide enforcement that all files
subsequently read from disk are covered by a valid digital signature.
@@ -5972,6 +6055,82 @@ or BIOS) configuration to cause the machine to boot from a different
(attacker-controlled) device. GRUB is at best only one link in a
secure boot chain.
+@node Using appended signatures
+@section Using appended signatures in GRUB
+
+GRUB supports verifying Linux-style 'appended signatures' for secure boot.
+Appended signatures are PKCS#7 messages containing a signature over the
+contents of a file, plus some metadata, appended to the end of a file. A file
+with an appended signature ends with the magic string:
+
+@example
+~Module signature appended~\n
+@end example
+
+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
+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}.
+
+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,
+and only RSA signatures are supported.
+
+A file can be signed with the @command{sign-file} utility supplied with the
+Linux kernel source. For example, if you have @code{signing.key} as the private
+key and @code{certificate.der} as the x509 certificate containing the public key:
+
+@example
+sign-file SHA256 signing.key certificate.der vmlinux vmlinux.signed
+@end example
+
+Enforcement of signature verification is controlled by the
+@code{check_appended_signatures} variable. Verification will only take place
+when files are loaded if the variable is set to @code{enforce}. If a
+certificate is built into the grub core image with the @code{--x509} parameter,
+the variable will be automatically set to @code{enforce} when the appendedsig
+module is loaded.
+
+Unlike GPG-style signatures, not all files loaded by GRUB are required to be
+signed. Once verification is turned on, the following file types must carry
+appended signatures:
+
+@enumerate
+@item Linux, Multiboot, BSD, XNU and Plan9 kernels
+@item Grub modules, except those built in to the core image
+@item Any new certificate files to be trusted
+@end enumerate
+
+ACPI tables and Device Tree images will not be checked for appended signatures
+but must be verified by another mechanism such as GPG-style signatures before
+they will be loaded.
+
+No attempt is made to validate any other file type. In particular,
+chain-loaded binaries are not verified - if your platform supports
+chain-loading and this cannot be disabled, consider an alternative secure
+boot mechanism.
+
+As with GPG-style appended signatures, signature checking does @strong{not}
+stop an attacker with console access from dropping manually to the GRUB
+console and executing:
+
+@example
+set check_appended_signatures=no
+@end example
+
+Refer to the section on password-protecting GRUB (@pxref{Authentication
+and authorisation}) for more information on preventing this.
+
+Additionally, special care must be taken around the @command{loadenv} command,
+which can be used to turn off @code{check_appended_signature}.
+
@node UEFI secure boot and shim
@section UEFI secure boot and shim support
--
2.31.1

View File

@ -0,0 +1,112 @@
From 806bb18c3493537530b6b0387143752478078f5b Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 28 Sep 2020 11:11:17 +1000
Subject: [PATCH 22/23] ieee1275: enter lockdown based on /ibm,secure-boot
If the 'ibm,secure-boot' property of the root node is 2 or greater,
enter lockdown.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
docs/grub.texi | 4 ++--
grub-core/Makefile.core.def | 1 +
grub-core/kern/ieee1275/init.c | 27 +++++++++++++++++++++++++++
include/grub/lockdown.h | 3 ++-
4 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/docs/grub.texi b/docs/grub.texi
index 988ef8ddc..f4794fdda 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -6208,8 +6208,8 @@ Measured boot is currently only supported on EFI platforms.
@section Lockdown when booting on a secure setup
The GRUB can be locked down when booted on a secure boot environment, for example
-if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will
-be restricted and some operations/commands cannot be executed.
+if UEFI or Power secure boot is enabled. On a locked down configuration, the
+GRUB will be restricted and some operations/commands cannot be executed.
The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down.
Otherwise it does not exit.
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 88eedd16d..49bdb63b6 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -317,6 +317,7 @@ kernel = {
powerpc_ieee1275 = kern/powerpc/cache.S;
powerpc_ieee1275 = kern/powerpc/dl.c;
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
+ powerpc_ieee1275 = kern/lockdown.c;
sparc64_ieee1275 = kern/sparc64/cache.S;
sparc64_ieee1275 = kern/sparc64/dl.c;
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 446201165..d77d89604 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -44,6 +44,7 @@
#ifdef __sparc__
#include <grub/machine/kernel.h>
#endif
+#include <grub/lockdown.h>
/* The maximum heap size we're going to claim. Not used by sparc.
We allocate 1/4 of the available memory under 4G, up to this limit. */
@@ -440,6 +441,30 @@ grub_parse_cmdline (void)
}
}
+static void
+grub_get_ieee1275_secure_boot (void)
+{
+ grub_ieee1275_phandle_t root;
+ int rc;
+ grub_uint32_t is_sb;
+
+ grub_ieee1275_finddevice ("/", &root);
+
+ rc = grub_ieee1275_get_integer_property (root, "ibm,secure-boot", &is_sb,
+ sizeof (is_sb), 0);
+
+ /* ibm,secure-boot:
+ * 0 - disabled
+ * 1 - audit
+ * 2 - enforce
+ * 3 - enforce + OS-specific behaviour
+ *
+ * We only support enforce.
+ */
+ if (rc >= 0 && is_sb >= 2)
+ grub_lockdown ();
+}
+
grub_addr_t grub_modbase;
void
@@ -465,6 +490,8 @@ grub_machine_init (void)
#else
grub_install_get_time_ms (grub_rtc_get_time_ms);
#endif
+
+ grub_get_ieee1275_secure_boot ();
}
void
diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h
index 40531fa82..ebfee4bf0 100644
--- a/include/grub/lockdown.h
+++ b/include/grub/lockdown.h
@@ -24,7 +24,8 @@
#define GRUB_LOCKDOWN_DISABLED 0
#define GRUB_LOCKDOWN_ENABLED 1
-#ifdef GRUB_MACHINE_EFI
+#if defined(GRUB_MACHINE_EFI) || \
+ (defined(__powerpc__) && defined(GRUB_MACHINE_IEEE1275))
extern void
EXPORT_FUNC (grub_lockdown) (void);
extern int
--
2.31.1

View File

@ -0,0 +1,48 @@
From 5a690183091c2c161481123b17e1925148e516e4 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 30 Nov 2021 15:00:57 +1100
Subject: [PATCH 23/23] x509: allow Digitial Signature plus other Key Usages
Currently the x509 certificate parser for appended signature
verification requires that the certificate have the Digitial Signature
key usage and _only_ the Digitial Signature use. This is overly strict
and becomes policy enforcement rather than a security property.
Require that the Digitial Signature usage is present, but do not
require that it is the only usage present.
Reported-by: Michal Suchanek <msuchanek@suse.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
grub-core/commands/appendedsig/x509.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/grub-core/commands/appendedsig/x509.c b/grub-core/commands/appendedsig/x509.c
index 70480aa73..6ae985b30 100644
--- a/grub-core/commands/appendedsig/x509.c
+++ b/grub-core/commands/appendedsig/x509.c
@@ -547,7 +547,7 @@ cleanup:
/*
* Verify the Key Usage extension.
- * We only permit the Digital signature usage.
+ * We require the Digital signature usage.
*/
static grub_err_t
verify_key_usage (grub_uint8_t *value, int value_size)
@@ -586,10 +586,10 @@ verify_key_usage (grub_uint8_t *value, int value_size)
goto cleanup;
}
- if (usage != digitalSignatureUsage)
+ if (!(usage & digitalSignatureUsage))
{
err =
- grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unexpected Key Usage value: %x",
+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "Key Usage (0x%x) missing Digital Signature usage",
usage);
goto cleanup;
}
--
2.31.1

View File

@ -10,6 +10,7 @@ GRUB_EDITENV="/usr/bin/grub2-editenv"
GRUB_CONF="/boot/grub2/grub.cfg"
GRUB_SETUP=
BLKID="/usr/sbin/blkid"
LSBLK="/usr/bin/lsblk"
ARCH=`uname -m`
VMLINUZ="vmlinuz"
case $ARCH in
@ -31,6 +32,15 @@ check-system()
[ -r "${GRUB_CONF}" ] || error_quit "ERROR: cannot find or read ${GRUB_CONF}"
}
compare-fsuuid()
{
local uuids=($($LSBLK -n -o UUID $1 $2 2>/dev/null))
if [ ${#uuids[@]} -eq 2 ] && [ "${uuids[0]}" = "${uuids[1]}" ]; then
return 0
fi
return 1
}
#####################################################################
# gets a list of available kernels from /boot/grub2/grub.cfg
# kernels are in the array $KERNELS
@ -87,9 +97,13 @@ get-kernels()
fi
if [ "$(stat -Lc '%t:%T' $ROOT || true)" != "$(stat -Lc '%t:%T' $ROOTDEV || true)" ]; then
echo " Skipping ${MENU_ENTRIES[$I]}, because its root= parameter ($ROOT)" >&2
echo " does not match the current root device ($ROOTDEV)." >&2
continue
if compare-fsuuid "$ROOT" "$ROOTDEV" ; then
echo " $ROOTDEV and $ROOT have the same filesystem UUID"
else
echo " Skipping ${MENU_ENTRIES[$I]}, because its root= parameter ($ROOT)" >&2
echo " does not match the current root device ($ROOTDEV)." >&2
continue
fi
fi
DUMMY=($LINE) # kernel (hd0,1)/boot/vmlinuz-ABC root=/dev/hda2

View File

@ -1,3 +1,41 @@
-------------------------------------------------------------------
Tue Jan 11 03:49:15 UTC 2022 - Michael Chang <mchang@suse.com>
- Power guest secure boot with static keys: GRUB2 signing portion
(jsc#SLE-18271) (bsc#1192764)
* grub2.spec
- Power guest secure boot with static keys: GRUB2 portion (jsc#SLE-18144)
(bsc#1192686)
* 0001-ieee1275-Drop-HEAP_MAX_ADDR-and-HEAP_MIN_SIZE-consta.patch
* 0002-ieee1275-claim-more-memory.patch
* 0003-ieee1275-request-memory-with-ibm-client-architecture.patch
* 0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
* 0005-docs-grub-Document-signing-grub-under-UEFI.patch
* 0006-docs-grub-Document-signing-grub-with-an-appended-sig.patch
* 0007-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch
* 0008-pgp-factor-out-rsa_pad.patch
* 0009-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch
* 0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch
* 0011-libtasn1-import-libtasn1-4.18.0.patch
* 0012-libtasn1-disable-code-not-needed-in-grub.patch
* 0013-libtasn1-changes-for-grub-compatibility.patch
* 0014-libtasn1-compile-into-asn1-module.patch
* 0015-test_asn1-test-module-for-libtasn1.patch
* 0016-grub-install-support-embedding-x509-certificates.patch
* 0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch
* 0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch
* 0019-appended-signatures-support-verifying-appended-signa.patch
* 0020-appended-signatures-verification-tests.patch
* 0021-appended-signatures-documentation.patch
* 0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch
* 0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch
-------------------------------------------------------------------
Mon Jan 10 09:38:46 UTC 2022 - Michael Chang <mchang@suse.com>
- Fix no menuentry is found if hibernation on btrfs RAID1 (bsc#1193090)
* grub2-systemd-sleep-plugin
-------------------------------------------------------------------
Tue Dec 21 03:03:47 UTC 2021 - Michael Chang <mchang@suse.com>

View File

@ -1,7 +1,7 @@
#
# spec file for package grub2
#
# Copyright (c) 2021 SUSE LLC
# Copyright (c) 2022 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -52,7 +52,7 @@ BuildRequires: %{pythons}
BuildRequires: python
%endif
BuildRequires: xz-devel
%ifarch x86_64 aarch64
%ifarch x86_64 aarch64 ppc ppc64 ppc64le
%if 0%{?suse_version} >= 1230 || 0%{?suse_version} == 1110
BuildRequires: openssl >= 0.9.8
BuildRequires: pesign-obs-integration
@ -76,6 +76,7 @@ BuildRequires: update-bootloader-rpm-macros
%ifarch ppc ppc64 ppc64le
%define grubcpu powerpc
%define platform ieee1275
%define brp_pesign_reservation 65536
# emu does not build here yet... :-(
%define emu 0
%endif
@ -328,6 +329,29 @@ Patch809: 0009-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch
Patch810: 0010-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch
Patch811: 0011-Also-define-GRUB_EFI_MAX_ALLOCATION_ADDRESS-for-RISC.patch
Patch812: 0001-grub-mkconfig-restore-umask-for-grub.cfg.patch
Patch813: 0001-ieee1275-Drop-HEAP_MAX_ADDR-and-HEAP_MIN_SIZE-consta.patch
Patch814: 0002-ieee1275-claim-more-memory.patch
Patch815: 0003-ieee1275-request-memory-with-ibm-client-architecture.patch
Patch816: 0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
Patch817: 0005-docs-grub-Document-signing-grub-under-UEFI.patch
Patch818: 0006-docs-grub-Document-signing-grub-with-an-appended-sig.patch
Patch819: 0007-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch
Patch820: 0008-pgp-factor-out-rsa_pad.patch
Patch821: 0009-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch
Patch822: 0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch
Patch823: 0011-libtasn1-import-libtasn1-4.18.0.patch
Patch824: 0012-libtasn1-disable-code-not-needed-in-grub.patch
Patch825: 0013-libtasn1-changes-for-grub-compatibility.patch
Patch826: 0014-libtasn1-compile-into-asn1-module.patch
Patch827: 0015-test_asn1-test-module-for-libtasn1.patch
Patch828: 0016-grub-install-support-embedding-x509-certificates.patch
Patch829: 0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch
Patch830: 0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch
Patch831: 0019-appended-signatures-support-verifying-appended-signa.patch
Patch832: 0020-appended-signatures-verification-tests.patch
Patch833: 0021-appended-signatures-documentation.patch
Patch834: 0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch
Patch835: 0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch
Requires: gettext-runtime
%if 0%{?suse_version} >= 1140
@ -354,8 +378,6 @@ Requires: s390-tools
Requires: powerpc-utils
%endif
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%if 0%{?only_x86_64:1}
ExclusiveArch: x86_64
%else
@ -591,6 +613,33 @@ make %{?_smp_mflags}
cd ..
%endif
FS_MODULES="btrfs ext2 xfs jfs reiserfs"
CD_MODULES="all_video boot cat configfile echo true \
font gfxmenu gfxterm gzio halt iso9660 \
jpeg minicmd normal part_apple part_msdos part_gpt \
password password_pbkdf2 png reboot search search_fs_uuid \
search_fs_file search_label sleep test video fat loadenv"
PXE_MODULES="tftp http"
CRYPTO_MODULES="luks gcry_rijndael gcry_sha1 gcry_sha256"
%ifarch %{efi}
CD_MODULES="${CD_MODULES} chain efifwsetup efinet"
PXE_MODULES="${PXE_MODULES} efinet"
%else
CD_MODULES="${CD_MODULES} net"
PXE_MODULES="${PXE_MODULES} net"
%endif
%ifarch x86_64
CD_MODULES="${CD_MODULES} linuxefi"
%else
CD_MODULES="${CD_MODULES} linux"
%endif
GRUB_MODULES="${CD_MODULES} ${FS_MODULES} ${PXE_MODULES} ${CRYPTO_MODULES} mdraid09 mdraid1x lvm serial"
%ifarch ppc ppc64 ppc64le
GRUB_MODULES="${GRUB_MODULES} appendedsig memdisk tar regexp"
%endif
%ifarch %{efi}
cd build-efi
../configure \
@ -603,23 +652,6 @@ cd build-efi
--program-transform-name=s,grub,%{name},
make %{?_smp_mflags}
#TODO: add efifwsetup module
FS_MODULES="btrfs ext2 xfs jfs reiserfs"
CD_MODULES=" all_video boot cat chain configfile echo true \
efifwsetup efinet font gfxmenu gfxterm gzio halt iso9660 \
jpeg minicmd normal part_apple part_msdos part_gpt \
password password_pbkdf2 png reboot search search_fs_uuid \
search_fs_file search_label sleep test video fat loadenv"
PXE_MODULES="efinet tftp http"
CRYPTO_MODULES="luks gcry_rijndael gcry_sha1 gcry_sha256"
%ifarch x86_64
CD_MODULES="${CD_MODULES} linuxefi"
%else
CD_MODULES="${CD_MODULES} linux"
%endif
# SBAT metadata
%if 0%{?is_opensuse} == 1
distro_id="opensuse"
@ -634,7 +666,6 @@ echo "sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.m
echo "grub,${upstream_sbat},Free Software Foundation,grub,%{version},https://www.gnu.org/software/grub/" >> sbat.csv
echo "grub.${distro_id},${distro_sbat},${distro_name},%{name},%{version},mail:security-team@suse.de" >> sbat.csv
GRUB_MODULES="${CD_MODULES} ${FS_MODULES} ${PXE_MODULES} ${CRYPTO_MODULES} mdraid09 mdraid1x lvm serial"
./grub-mkimage -O %{grubefiarch} -o grub.efi --prefix= --sbat sbat.csv \
-d grub-core ${GRUB_MODULES}
%ifarch x86_64
@ -695,6 +726,67 @@ TLFLAGS="-static"
%{arch_specific} \
--program-transform-name=s,grub,%{name},
make %{?_smp_mflags}
if [ "%{platform}" = "ieee1275" ]; then
cert="%{_sourcedir}/_projectcert.crt"
openssl x509 -in "$cert" -outform DER -out grub.der
cat > %{platform}-config <<'EOF'
set root=memdisk
set prefix=($root)/
echo "earlycfg: root=$root prefix=$prefix"
EOF
cat > ./grub.cfg <<'EOF'
regexp --set 1:bdev --set 2:bpart --set 3:bpath '\(([^,]+)(,?.*)?\)(.*)' "$cmdpath"
echo "bdev=$bdev"
echo "bpart=$bpart"
echo "bpath=$bpath"
if [ "$bdev" -a "$bpart" -a "$bpath" ]; then
hints="--hint $bdev$bpart"
cfg_dir="$bpath"
elif [ "$bdev" -a "$bpart" ]; then
hints="--hint $bdev$bpart"
cfg_dir="/boot/grub2 /grub2"
elif [ "$bdev" ]; then
hints="--hint ${bdev},"
cfg_dir="/boot/grub2 /grub2"
else
hints=""
cfg_dir="/boot/grub2 /grub2"
fi
set prefix=""
set root=""
set cfg="grub.cfg"
for d in ${cfg_dir}; do
set btrfs_relative_path=1
echo "start searching for $d/${cfg} with $hints"
if search --file --set=root "${d}/${cfg}" $hints; then
echo "${d}/${cfg} is on $root"
set btrfs_relative_path=0
if [ -f /@"${d}"/powerpc-ieee1275/command.lst ]; then
set btrfs_relative_path=1
echo "mounting subvolume @${d}/powerpc-ieee1275 on ${d}/powerpc-ieee1275"
btrfs-mount-subvol ($root) "${d}"/powerpc-ieee1275 @"${d}"/powerpc-ieee1275
fi
set btrfs_relative_path=1
set prefix="($root)${d}"
break
fi
done
echo "prefix=$prefix root=$root"
if [ -n "$prefix" ]; then
source "${prefix}/${cfg}"
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}
ls -l "grub.elf"
truncate -s -%brp_pesign_reservation "grub.elf"
fi
%endif
cd ..
%endif
@ -757,6 +849,12 @@ cd ..
%if ! 0%{?only_efi:1}
cd build
%make_install
if [ "%{platform}" = "ieee1275" ]; then
export BRP_PESIGN_FILES="%{_datadir}/%{name}/%{grubarch}/grub.elf"
export BRP_PESIGN_GRUB_RESERVATION=%brp_pesign_reservation
install -m 444 grub.der %{buildroot}%{_datadir}/%{name}/%{grubarch}/
install -m 644 grub.elf %{buildroot}%{_datadir}/%{name}/%{grubarch}/
fi
cd ..
%endif
@ -1132,6 +1230,8 @@ fi
%ifarch ppc ppc64 ppc64le
# This is intentionally "grub.chrp" and not "%%{name}.chrp"
%{_datadir}/%{name}/%{grubarch}/grub.chrp
%{_datadir}/%{name}/%{grubarch}/grub.elf
%{_datadir}/%{name}/%{grubarch}/grub.der
%{_datadir}/%{name}/%{grubarch}/bootinfo.txt
%endif
%ifnarch ppc ppc64 ppc64le s390x %{arm}