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:
parent
005c99a035
commit
d6d145b71a
@ -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
|
||||
|
242
0002-ieee1275-claim-more-memory.patch
Normal file
242
0002-ieee1275-claim-more-memory.patch
Normal 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
|
||||
|
263
0003-ieee1275-request-memory-with-ibm-client-architecture.patch
Normal file
263
0003-ieee1275-request-memory-with-ibm-client-architecture.patch
Normal 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, ®_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
|
||||
|
314
0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
Normal file
314
0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
Normal 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
|
||||
|
64
0005-docs-grub-Document-signing-grub-under-UEFI.patch
Normal file
64
0005-docs-grub-Document-signing-grub-under-UEFI.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
194
0008-pgp-factor-out-rsa_pad.patch
Normal file
194
0008-pgp-factor-out-rsa_pad.patch
Normal 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
|
||||
|
@ -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
|
||||
|
67
0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch
Normal file
67
0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch
Normal 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
|
||||
|
9044
0011-libtasn1-import-libtasn1-4.18.0.patch
Normal file
9044
0011-libtasn1-import-libtasn1-4.18.0.patch
Normal file
File diff suppressed because it is too large
Load Diff
310
0012-libtasn1-disable-code-not-needed-in-grub.patch
Normal file
310
0012-libtasn1-disable-code-not-needed-in-grub.patch
Normal 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
|
||||
|
212
0013-libtasn1-changes-for-grub-compatibility.patch
Normal file
212
0013-libtasn1-changes-for-grub-compatibility.patch
Normal 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
|
||||
|
73
0014-libtasn1-compile-into-asn1-module.patch
Normal file
73
0014-libtasn1-compile-into-asn1-module.patch
Normal 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
|
||||
|
1447
0015-test_asn1-test-module-for-libtasn1.patch
Normal file
1447
0015-test_asn1-test-module-for-libtasn1.patch
Normal file
File diff suppressed because one or more lines are too long
257
0016-grub-install-support-embedding-x509-certificates.patch
Normal file
257
0016-grub-install-support-embedding-x509-certificates.patch
Normal 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
|
||||
|
643
0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch
Normal file
643
0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch
Normal 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
|
||||
|
1891
0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch
Normal file
1891
0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch
Normal file
File diff suppressed because it is too large
Load Diff
764
0019-appended-signatures-support-verifying-appended-signa.patch
Normal file
764
0019-appended-signatures-support-verifying-appended-signa.patch
Normal 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
|
||||
|
1321
0020-appended-signatures-verification-tests.patch
Normal file
1321
0020-appended-signatures-verification-tests.patch
Normal file
File diff suppressed because it is too large
Load Diff
342
0021-appended-signatures-documentation.patch
Normal file
342
0021-appended-signatures-documentation.patch
Normal 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
|
||||
|
112
0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch
Normal file
112
0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
||||
|
144
grub2.spec
144
grub2.spec
@ -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}
|
||||
|
Loading…
Reference in New Issue
Block a user