Merge ~xnox/ubuntu/+source/linux/+git/focal:hwe-5.8-revocation-certs into ~ubuntu-kernel/ubuntu/+source/linux/+git/focal:hwe-5.8

Proposed by Dimitri John Ledkov
Status: Needs review
Proposed branch: ~xnox/ubuntu/+source/linux/+git/focal:hwe-5.8-revocation-certs
Merge into: ~ubuntu-kernel/ubuntu/+source/linux/+git/focal:hwe-5.8
Diff against target: 1245 lines (+830/-70)
25 files modified
arch/x86/kernel/setup.c (+1/-0)
arch/x86/platform/efi/efi.c (+3/-0)
certs/.gitignore (+1/-0)
certs/Kconfig (+17/-0)
certs/Makefile (+18/-3)
certs/blacklist.c (+67/-0)
certs/blacklist.h (+2/-0)
certs/common.c (+58/-0)
certs/common.h (+9/-0)
certs/revocation_certificates.S (+21/-0)
certs/system_keyring.c (+9/-47)
debian.hwe-5.8/config/config.common.ubuntu (+2/-0)
debian.master/config/annotations (+1/-0)
debian.master/config/config.common.ubuntu (+2/-0)
debian/revoked-certs/canonical-uefi-2012-all.pem (+86/-0)
debian/rules (+13/-1)
drivers/firmware/efi/Makefile (+1/-0)
drivers/firmware/efi/arm-init.c (+1/-0)
drivers/firmware/efi/efi.c (+6/-0)
drivers/firmware/efi/mokvar-table.c (+362/-0)
include/keys/system_keyring.h (+15/-0)
include/linux/efi.h (+34/-0)
scripts/Makefile (+1/-0)
security/integrity/platform_certs/keyring_handler.c (+12/-0)
security/integrity/platform_certs/load_uefi.c (+88/-19)
Reviewer Review Type Date Requested Status
Canonical Kernel Team Pending
Ubuntu Kernel Repositories Pending
Review via email: mp+409282@code.launchpad.net
To post a comment you must log in.

Unmerged commits

41e8fbe... by Dimitri John Ledkov

UBUNTU: [Config] Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys

BugLink: https://bugs.launchpad.net/bugs/1932029
Signed-off-by: Dimitri John Ledkov <email address hidden>
Signed-off-by: Andrea Righi <email address hidden>
(cherry picked from commit 741f622c4dbc162b82f8c9045f9c6c6446f57eb5)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden>

8139ffa... by Dimitri John Ledkov

UBUNTU: [Packaging] Revoke 2012 UEFI signing certificate as built-in

BugLink: https://bugs.launchpad.net/bugs/1932029
Signed-off-by: Dimitri John Ledkov <email address hidden>
Signed-off-by: Andrea Righi <email address hidden>
(cherry picked from commit 3f72ce72f0b51b6da2638cdded93bb32b9dad2ec)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden>

644278e... by Dimitri John Ledkov

UBUNTU: [Packaging] build canonical-revoked-certs.pem from branch/arch certs

BugLink: https://bugs.launchpad.net/bugs/1932029
Signed-off-by: Dimitri John Ledkov <email address hidden>
Signed-off-by: Andrea Righi <email address hidden>
(cherry picked from commit 3e44f229eef829ee3044651975512569824c4e5f)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden>

49ad197... by Tim Gardner

UBUNTU: SAUCE: Dump stack when X.509 certificates cannot be loaded

BugLink: https://bugs.launchpad.net/bugs/1932029

Signed-off-by: Tim Gardner <email address hidden>
(cherry picked from commit b5b4085dc5547a01593cd79dbf51bd9108f84e9f)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden>

552ecb7... by Dimitri John Ledkov

UBUNTU: SAUCE: integrity: add informational messages when revoking certs

integrity_load_cert() prints messages of the source and cert details
when adding certs as trusted. Mirror those messages in
uefi_revocation_list_x509() when adding certs as revoked.

Sample dmesg with this change:

    integrity: Platform Keyring initialized
    integrity: Loading X.509 certificate: UEFI:db
    integrity: Loaded X.509 cert 'Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed522988a1bd4'
    integrity: Revoking X.509 certificate: UEFI:MokListXRT (MOKvar table)
    blacklist: Revoked X.509 cert 'Canonical Ltd. Secure Boot Signing: 61482aa2830d0ab2ad5af10b7250da9033ddcef0'
    integrity: Loading X.509 certificate: UEFI:MokListRT (MOKvar table)
    integrity: Loaded X.509 cert 'Canonical Ltd. Master Certificate Authority: ad91990bc22ab1f517048c23b6655a268e345a63'

BugLink: https://bugs.launchpad.net/bugs/1928679
Signed-off-by: Dimitri John Ledkov <email address hidden>
Acked-by: Krzysztof Kozlowski <email address hidden>
Signed-off-by: Seth Forshee <email address hidden>
(cherry picked from commit ba9fb788f89cb81c5ed836db2355a7a3b0f8c248)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden>

428ff20... by Dimitri John Ledkov

UBUNTU: SAUCE: integrity: Load mokx certs from the EFI MOK config table

Refactor load_moklist_certs() to load either MokListRT into db, or
MokListXRT into dbx. Call load_moklist_certs() twice - first to load
mokx certs into dbx, then mok certs into db.

This thus now attempts to load mokx certs via the EFI MOKvar config
table first, and if that fails, via the EFI variable. Previously mokx
certs were only loaded via the EFI variable. Which fails when
MokListXRT is large. Instead of large MokListXRT variable, only
MokListXRT{1,2,3} are available which are not loaded. This is the case
with Ubuntu's 15.4 based shim. This patch is required to address
CVE-2020-26541 when certificates are revoked via MokListXRT.

Fixes: ebd9c2ae369a ("integrity: Load mokx variables into the blacklist keyring")
BugLink: https://bugs.launchpad.net/bugs/1928679
Signed-off-by: Dimitri John Ledkov <email address hidden>
Acked-by: Krzysztof Kozlowski <email address hidden>
Signed-off-by: Seth Forshee <email address hidden>
(cherry picked from commit a9e3aae16235d6af12509a64f1337da4485ccbae)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden>

0983bac... by Linus Torvalds <email address hidden>

certs: add 'x509_revocation_list' to gitignore

BugLink: https://bugs.launchpad.net/bugs/1932029

Commit d1f044103dad ("certs: Add ability to preload revocation certs")
created a new generated file for revocation certs, but didn't tell git
to ignore it. Thus causing unnecessary "git status" noise after a
kernel build with CONFIG_SYSTEM_REVOCATION_LIST enabled.

Add the proper gitignore magic.

Signed-off-by: Linus Torvalds <email address hidden>
(cherry picked from commit 81f202315856edb75a371f3376aa3a47543c16f0)
Signed-off-by: Dimitri John Ledkov <email address hidden>

7f447b9... by Eric Snowberg <email address hidden>

integrity: Load mokx variables into the blacklist keyring

BugLink: https://bugs.launchpad.net/bugs/1932029

During boot the Secure Boot Forbidden Signature Database, dbx,
is loaded into the blacklist keyring. Systems booted with shim
have an equivalent Forbidden Signature Database called mokx.
Currently mokx is only used by shim and grub, the contents are
ignored by the kernel.

Add the ability to load mokx into the blacklist keyring during boot.

Signed-off-by: Eric Snowberg <email address hidden>
Suggested-by: James Bottomley <email address hidden>
Signed-off-by: David Howells <email address hidden>
Reviewed-by: Jarkko Sakkinen <email address hidden>
cc: <email address hidden>
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v5
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v2
Link: https://<email address hidden>/ # v3
(cherry picked from commit ebd9c2ae369a45bdd9f8615484db09be58fc242b)
Signed-off-by: Dimitri John Ledkov <email address hidden>

e53bef9... by Eric Snowberg <email address hidden>

certs: Add ability to preload revocation certs

BugLink: https://bugs.launchpad.net/bugs/1932029

Add a new Kconfig option called SYSTEM_REVOCATION_KEYS. If set,
this option should be the filename of a PEM-formated file containing
X.509 certificates to be included in the default blacklist keyring.

DH Changes:
 - Make the new Kconfig option depend on SYSTEM_REVOCATION_LIST.
 - Fix SYSTEM_REVOCATION_KEYS=n, but CONFIG_SYSTEM_REVOCATION_LIST=y[1][2].
 - Use CONFIG_SYSTEM_REVOCATION_LIST for extract-cert[3].
 - Use CONFIG_SYSTEM_REVOCATION_LIST for revocation_certificates.o[3].

Signed-off-by: Eric Snowberg <email address hidden>
Acked-by: Jarkko Sakkinen <email address hidden>
Signed-off-by: David Howells <email address hidden>
cc: Randy Dunlap <email address hidden>
cc: <email address hidden>
Link: https://<email address hidden>/ [1]
Link: https://<email address hidden>/ [2]
Link: https://<email address hidden>/ [3]
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v5
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v2
Link: https://<email address hidden>/ # v3
(cherry picked from commit d1f044103dad70c1cec0a8f3abdf00834fec8b98)
Signed-off-by: Dimitri John Ledkov <email address hidden>

06f11ec... by Eric Snowberg <email address hidden>

certs: Move load_system_certificate_list to a common function

BugLink: https://bugs.launchpad.net/bugs/1932029

Move functionality within load_system_certificate_list to a common
function, so it can be reused in the future.

DH Changes:
 - Added inclusion of common.h to common.c (Eric [1]).

Signed-off-by: Eric Snowberg <email address hidden>
Acked-by: Jarkko Sakkinen <email address hidden>
Signed-off-by: David Howells <email address hidden>
cc: <email address hidden>
Link: https://<email address hidden>/ [1]
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v5
Link: https://<email address hidden>/
Link: https://<email address hidden>/ # v2
Link: https://<email address hidden>/ # v3
(cherry picked from commit 2565ca7f5ec1a98d51eea8860c4ab923f1ca2c85)
Signed-off-by: Dimitri John Ledkov <email address hidden>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index c619e19..1bdd6a4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1086,6 +1086,7 @@ void __init setup_arch(char **cmdline_p)
1086 efi_fake_memmap();1086 efi_fake_memmap();
1087 efi_find_mirror();1087 efi_find_mirror();
1088 efi_esrt_init();1088 efi_esrt_init();
1089 efi_mokvar_table_init();
10891090
1090 /*1091 /*
1091 * The EFI specification says that boot service code won't be1092 * The EFI specification says that boot service code won't be
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index e966115..8a9b86f 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -91,6 +91,9 @@ static const unsigned long * const efi_tables[] = {
91 &efi.tpm_log,91 &efi.tpm_log,
92 &efi.tpm_final_log,92 &efi.tpm_final_log,
93 &efi_rng_seed,93 &efi_rng_seed,
94#ifdef CONFIG_LOAD_UEFI_KEYS
95 &efi.mokvar_table,
96#endif
94};97};
9598
96u64 efi_setup; /* efi setup_data physical address */99u64 efi_setup; /* efi setup_data physical address */
diff --git a/certs/.gitignore b/certs/.gitignore
index 2a24839..6cbd1f1 100644
--- a/certs/.gitignore
+++ b/certs/.gitignore
@@ -1,2 +1,3 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2x509_certificate_list2x509_certificate_list
3x509_revocation_list
diff --git a/certs/Kconfig b/certs/Kconfig
index c94e93d..ab88d2a 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -83,4 +83,21 @@ config SYSTEM_BLACKLIST_HASH_LIST
83 wrapper to incorporate the list into the kernel. Each <hash> should83 wrapper to incorporate the list into the kernel. Each <hash> should
84 be a string of hex digits.84 be a string of hex digits.
8585
86config SYSTEM_REVOCATION_LIST
87 bool "Provide system-wide ring of revocation certificates"
88 depends on SYSTEM_BLACKLIST_KEYRING
89 depends on PKCS7_MESSAGE_PARSER=y
90 help
91 If set, this allows revocation certificates to be stored in the
92 blacklist keyring and implements a hook whereby a PKCS#7 message can
93 be checked to see if it matches such a certificate.
94
95config SYSTEM_REVOCATION_KEYS
96 string "X.509 certificates to be preloaded into the system blacklist keyring"
97 depends on SYSTEM_REVOCATION_LIST
98 help
99 If set, this option should be the filename of a PEM-formatted file
100 containing X.509 certificates to be included in the default blacklist
101 keyring.
102
86endmenu103endmenu
diff --git a/certs/Makefile b/certs/Makefile
index f4c25b6..b6db52e 100644
--- a/certs/Makefile
+++ b/certs/Makefile
@@ -3,8 +3,9 @@
3# Makefile for the linux kernel signature checking certificates.3# Makefile for the linux kernel signature checking certificates.
4#4#
55
6obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o6obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o
7obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o7obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o
8obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o
8ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"")9ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"")
9obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o10obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o
10else11else
@@ -29,7 +30,7 @@ $(obj)/x509_certificate_list: scripts/extract-cert $(SYSTEM_TRUSTED_KEYS_SRCPREF
29 $(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS))30 $(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS))
30endif # CONFIG_SYSTEM_TRUSTED_KEYRING31endif # CONFIG_SYSTEM_TRUSTED_KEYRING
3132
32clean-files := x509_certificate_list .x509.list33clean-files := x509_certificate_list .x509.list x509_revocation_list
3334
34ifeq ($(CONFIG_MODULE_SIG),y)35ifeq ($(CONFIG_MODULE_SIG),y)
35###############################################################################36###############################################################################
@@ -104,3 +105,17 @@ targets += signing_key.x509
104$(obj)/signing_key.x509: scripts/extract-cert $(X509_DEP) FORCE105$(obj)/signing_key.x509: scripts/extract-cert $(X509_DEP) FORCE
105 $(call if_changed,extract_certs,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY))106 $(call if_changed,extract_certs,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY))
106endif # CONFIG_MODULE_SIG107endif # CONFIG_MODULE_SIG
108
109ifeq ($(CONFIG_SYSTEM_REVOCATION_LIST),y)
110
111$(eval $(call config_filename,SYSTEM_REVOCATION_KEYS))
112
113$(obj)/revocation_certificates.o: $(obj)/x509_revocation_list
114
115quiet_cmd_extract_certs = EXTRACT_CERTS $(patsubst "%",%,$(2))
116 cmd_extract_certs = scripts/extract-cert $(2) $@
117
118targets += x509_revocation_list
119$(obj)/x509_revocation_list: scripts/extract-cert $(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(SYSTEM_REVOCATION_KEYS_FILENAME) FORCE
120 $(call if_changed,extract_certs,$(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_REVOCATION_KEYS))
121endif
diff --git a/certs/blacklist.c b/certs/blacklist.c
index f1c434b..7638dfa 100644
--- a/certs/blacklist.c
+++ b/certs/blacklist.c
@@ -16,9 +16,15 @@
16#include <linux/seq_file.h>16#include <linux/seq_file.h>
17#include <keys/system_keyring.h>17#include <keys/system_keyring.h>
18#include "blacklist.h"18#include "blacklist.h"
19#include "common.h"
1920
20static struct key *blacklist_keyring;21static struct key *blacklist_keyring;
2122
23#ifdef CONFIG_SYSTEM_REVOCATION_LIST
24extern __initconst const u8 revocation_certificate_list[];
25extern __initconst const unsigned long revocation_certificate_list_size;
26#endif
27
22/*28/*
23 * The description must be a type prefix, a colon and then an even number of29 * The description must be a type prefix, a colon and then an even number of
24 * hex digits. The hash is kept in the description.30 * hex digits. The hash is kept in the description.
@@ -144,6 +150,52 @@ int is_binary_blacklisted(const u8 *hash, size_t hash_len)
144}150}
145EXPORT_SYMBOL_GPL(is_binary_blacklisted);151EXPORT_SYMBOL_GPL(is_binary_blacklisted);
146152
153#ifdef CONFIG_SYSTEM_REVOCATION_LIST
154/**
155 * add_key_to_revocation_list - Add a revocation certificate to the blacklist
156 * @data: The data blob containing the certificate
157 * @size: The size of data blob
158 */
159int add_key_to_revocation_list(const char *data, size_t size)
160{
161 key_ref_t key;
162
163 key = key_create_or_update(make_key_ref(blacklist_keyring, true),
164 "asymmetric",
165 NULL,
166 data,
167 size,
168 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW),
169 KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN);
170
171 if (IS_ERR(key)) {
172 pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key));
173 return PTR_ERR(key);
174 } else {
175 pr_notice("Revoked X.509 cert '%s'\n",
176 key_ref_to_ptr(key)->description);
177 }
178
179 return 0;
180}
181
182/**
183 * is_key_on_revocation_list - Determine if the key for a PKCS#7 message is revoked
184 * @pkcs7: The PKCS#7 message to check
185 */
186int is_key_on_revocation_list(struct pkcs7_message *pkcs7)
187{
188 int ret;
189
190 ret = pkcs7_validate_trust(pkcs7, blacklist_keyring);
191
192 if (ret == 0)
193 return -EKEYREJECTED;
194
195 return -ENOKEY;
196}
197#endif
198
147/*199/*
148 * Initialise the blacklist200 * Initialise the blacklist
149 */201 */
@@ -177,3 +229,18 @@ static int __init blacklist_init(void)
177 * Must be initialised before we try and load the keys into the keyring.229 * Must be initialised before we try and load the keys into the keyring.
178 */230 */
179device_initcall(blacklist_init);231device_initcall(blacklist_init);
232
233#ifdef CONFIG_SYSTEM_REVOCATION_LIST
234/*
235 * Load the compiled-in list of revocation X.509 certificates.
236 */
237static __init int load_revocation_certificate_list(void)
238{
239 if (revocation_certificate_list_size)
240 pr_notice("Loading compiled-in revocation X.509 certificates\n");
241
242 return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size,
243 blacklist_keyring);
244}
245late_initcall(load_revocation_certificate_list);
246#endif
diff --git a/certs/blacklist.h b/certs/blacklist.h
index 1efd6fa..51b320c 100644
--- a/certs/blacklist.h
+++ b/certs/blacklist.h
@@ -1,3 +1,5 @@
1#include <linux/kernel.h>1#include <linux/kernel.h>
2#include <linux/errno.h>
3#include <crypto/pkcs7.h>
24
3extern const char __initconst *const blacklist_hashes[];5extern const char __initconst *const blacklist_hashes[];
diff --git a/certs/common.c b/certs/common.c
4new file mode 1006446new file mode 100644
index 0000000..23af4fc
--- /dev/null
+++ b/certs/common.c
@@ -0,0 +1,58 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3#include <linux/kernel.h>
4#include <linux/key.h>
5#include "common.h"
6
7int load_certificate_list(const u8 cert_list[],
8 const unsigned long list_size,
9 const struct key *keyring)
10{
11 key_ref_t key;
12 const u8 *p, *end;
13 size_t plen;
14
15 p = cert_list;
16 end = p + list_size;
17 while (p < end) {
18 /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
19 * than 256 bytes in size.
20 */
21 if (end - p < 4)
22 goto dodgy_cert;
23 if (p[0] != 0x30 &&
24 p[1] != 0x82)
25 goto dodgy_cert;
26 plen = (p[2] << 8) | p[3];
27 plen += 4;
28 if (plen > end - p)
29 goto dodgy_cert;
30
31 key = key_create_or_update(make_key_ref(keyring, 1),
32 "asymmetric",
33 NULL,
34 p,
35 plen,
36 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
37 KEY_USR_VIEW | KEY_USR_READ),
38 KEY_ALLOC_NOT_IN_QUOTA |
39 KEY_ALLOC_BUILT_IN |
40 KEY_ALLOC_BYPASS_RESTRICTION);
41 if (IS_ERR(key)) {
42 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
43 PTR_ERR(key));
44 WARN_ON_ONCE(1);
45 } else {
46 pr_notice("Loaded X.509 cert '%s'\n",
47 key_ref_to_ptr(key)->description);
48 key_ref_put(key);
49 }
50 p += plen;
51 }
52
53 return 0;
54
55dodgy_cert:
56 pr_err("Problem parsing in-kernel X.509 certificate list\n");
57 return 0;
58}
diff --git a/certs/common.h b/certs/common.h
0new file mode 10064459new file mode 100644
index 0000000..abdb579
--- /dev/null
+++ b/certs/common.h
@@ -0,0 +1,9 @@
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3#ifndef _CERT_COMMON_H
4#define _CERT_COMMON_H
5
6int load_certificate_list(const u8 cert_list[], const unsigned long list_size,
7 const struct key *keyring);
8
9#endif
diff --git a/certs/revocation_certificates.S b/certs/revocation_certificates.S
0new file mode 10064410new file mode 100644
index 0000000..f21aae8
--- /dev/null
+++ b/certs/revocation_certificates.S
@@ -0,0 +1,21 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#include <linux/export.h>
3#include <linux/init.h>
4
5 __INITRODATA
6
7 .align 8
8 .globl revocation_certificate_list
9revocation_certificate_list:
10__revocation_list_start:
11 .incbin "certs/x509_revocation_list"
12__revocation_list_end:
13
14 .align 8
15 .globl revocation_certificate_list_size
16revocation_certificate_list_size:
17#ifdef CONFIG_64BIT
18 .quad __revocation_list_end - __revocation_list_start
19#else
20 .long __revocation_list_end - __revocation_list_start
21#endif
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 7d4c816..a44a891 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -15,6 +15,7 @@
15#include <keys/asymmetric-type.h>15#include <keys/asymmetric-type.h>
16#include <keys/system_keyring.h>16#include <keys/system_keyring.h>
17#include <crypto/pkcs7.h>17#include <crypto/pkcs7.h>
18#include "common.h"
1819
19static struct key *builtin_trusted_keys;20static struct key *builtin_trusted_keys;
20#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING21#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
@@ -136,55 +137,10 @@ device_initcall(system_trusted_keyring_init);
136 */137 */
137static __init int load_system_certificate_list(void)138static __init int load_system_certificate_list(void)
138{139{
139 key_ref_t key;
140 const u8 *p, *end;
141 size_t plen;
142
143 pr_notice("Loading compiled-in X.509 certificates\n");140 pr_notice("Loading compiled-in X.509 certificates\n");
144141
145 p = system_certificate_list;142 return load_certificate_list(system_certificate_list, system_certificate_list_size,
146 end = p + system_certificate_list_size;143 builtin_trusted_keys);
147 while (p < end) {
148 /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
149 * than 256 bytes in size.
150 */
151 if (end - p < 4)
152 goto dodgy_cert;
153 if (p[0] != 0x30 &&
154 p[1] != 0x82)
155 goto dodgy_cert;
156 plen = (p[2] << 8) | p[3];
157 plen += 4;
158 if (plen > end - p)
159 goto dodgy_cert;
160
161 key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1),
162 "asymmetric",
163 NULL,
164 p,
165 plen,
166 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
167 KEY_USR_VIEW | KEY_USR_READ),
168 KEY_ALLOC_NOT_IN_QUOTA |
169 KEY_ALLOC_BUILT_IN |
170 KEY_ALLOC_BYPASS_RESTRICTION);
171 if (IS_ERR(key)) {
172 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
173 PTR_ERR(key));
174 WARN_ON_ONCE(1);
175 } else {
176 pr_notice("Loaded X.509 cert '%s'\n",
177 key_ref_to_ptr(key)->description);
178 key_ref_put(key);
179 }
180 p += plen;
181 }
182
183 return 0;
184
185dodgy_cert:
186 pr_err("Problem parsing in-kernel X.509 certificate list\n");
187 return 0;
188}144}
189late_initcall(load_system_certificate_list);145late_initcall(load_system_certificate_list);
190146
@@ -242,6 +198,12 @@ int verify_pkcs7_message_sig(const void *data, size_t len,
242 pr_devel("PKCS#7 platform keyring is not available\n");198 pr_devel("PKCS#7 platform keyring is not available\n");
243 goto error;199 goto error;
244 }200 }
201
202 ret = is_key_on_revocation_list(pkcs7);
203 if (ret != -ENOKEY) {
204 pr_devel("PKCS#7 platform key is on revocation list\n");
205 goto error;
206 }
245 }207 }
246 ret = pkcs7_validate_trust(pkcs7, trusted_keys);208 ret = pkcs7_validate_trust(pkcs7, trusted_keys);
247 if (ret < 0) {209 if (ret < 0) {
diff --git a/debian.hwe-5.8/config/config.common.ubuntu b/debian.hwe-5.8/config/config.common.ubuntu
index c3597d4..2a0d711 100644
--- a/debian.hwe-5.8/config/config.common.ubuntu
+++ b/debian.hwe-5.8/config/config.common.ubuntu
@@ -10197,6 +10197,8 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y
10197CONFIG_SYSTEM_DATA_VERIFICATION=y10197CONFIG_SYSTEM_DATA_VERIFICATION=y
10198CONFIG_SYSTEM_EXTRA_CERTIFICATE=y10198CONFIG_SYSTEM_EXTRA_CERTIFICATE=y
10199CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=409610199CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096
10200CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"
10201CONFIG_SYSTEM_REVOCATION_LIST=y
10200CONFIG_SYSTEM_TRUSTED_KEYRING=y10202CONFIG_SYSTEM_TRUSTED_KEYRING=y
10201CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"10203CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"
10202CONFIG_SYSVIPC=y10204CONFIG_SYSVIPC=y
diff --git a/debian.master/config/annotations b/debian.master/config/annotations
index 47c71de..ef064b0 100644
--- a/debian.master/config/annotations
+++ b/debian.master/config/annotations
@@ -369,6 +369,7 @@ CONFIG_SYSTEM_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': '
369CONFIG_SYSTEM_TRUSTED_KEYS policy<{'amd64': '"debian/canonical-certs.pem"', 'arm64': '"debian/canonical-certs.pem"', 'armhf': '"debian/canonical-certs.pem"', 'ppc64el': '"debian/canonical-certs.pem"', 's390x': '"debian/canonical-certs.pem"'}>369CONFIG_SYSTEM_TRUSTED_KEYS policy<{'amd64': '"debian/canonical-certs.pem"', 'arm64': '"debian/canonical-certs.pem"', 'armhf': '"debian/canonical-certs.pem"', 'ppc64el': '"debian/canonical-certs.pem"', 's390x': '"debian/canonical-certs.pem"'}>
370CONFIG_SYSTEM_EXTRA_CERTIFICATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>370CONFIG_SYSTEM_EXTRA_CERTIFICATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
371CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'ppc64el': '4096', 's390x': '4096'}>371CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'ppc64el': '4096', 's390x': '4096'}>
372CONFIG_SYSTEM_REVOCATION_KEYS policy<{'amd64': '"debian/canonical-revoked-certs.pem"', 'arm64': '"debian/canonical-revoked-certs.pem"', 'armhf': '"debian/canonical-revoked-certs.pem"', 'ppc64el': '"debian/canonical-revoked-certs.pem"', 's390x': '"debian/canonical-revoked-certs.pem"'}>
372CONFIG_SECONDARY_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>373CONFIG_SECONDARY_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
373374
374# Menu: Cryptographic API >> Hardware crypto devices375# Menu: Cryptographic API >> Hardware crypto devices
diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu
index f9392ab..fd4f39a 100644
--- a/debian.master/config/config.common.ubuntu
+++ b/debian.master/config/config.common.ubuntu
@@ -10198,6 +10198,8 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y
10198CONFIG_SYSTEM_DATA_VERIFICATION=y10198CONFIG_SYSTEM_DATA_VERIFICATION=y
10199CONFIG_SYSTEM_EXTRA_CERTIFICATE=y10199CONFIG_SYSTEM_EXTRA_CERTIFICATE=y
10200CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=409610200CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096
10201CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"
10202CONFIG_SYSTEM_REVOCATION_LIST=y
10201CONFIG_SYSTEM_TRUSTED_KEYRING=y10203CONFIG_SYSTEM_TRUSTED_KEYRING=y
10202CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"10204CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"
10203CONFIG_SYSVIPC=y10205CONFIG_SYSVIPC=y
diff --git a/debian/revoked-certs/canonical-uefi-2012-all.pem b/debian/revoked-certs/canonical-uefi-2012-all.pem
10204new file mode 10064410206new file mode 100644
index 0000000..06c116e
--- /dev/null
+++ b/debian/revoked-certs/canonical-uefi-2012-all.pem
@@ -0,0 +1,86 @@
1Certificate:
2 Data:
3 Version: 3 (0x2)
4 Serial Number: 1 (0x1)
5 Signature Algorithm: sha256WithRSAEncryption
6 Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
7 Validity
8 Not Before: Apr 12 11:39:08 2012 GMT
9 Not After : Apr 11 11:39:08 2042 GMT
10 Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing
11 Subject Public Key Info:
12 Public Key Algorithm: rsaEncryption
13 RSA Public-Key: (2048 bit)
14 Modulus:
15 00:c9:5f:9b:62:8f:0b:b0:64:82:ac:be:c9:e2:62:
16 e3:4b:d2:9f:1e:8a:d5:61:1a:2b:5d:38:f4:b7:ce:
17 b9:9a:b8:43:b8:43:97:77:ab:4f:7f:0c:70:46:0b:
18 fc:7f:6d:c6:6d:ea:80:5e:01:d2:b7:66:1e:87:de:
19 0d:6d:d0:41:97:a8:a5:af:0c:63:4f:f7:7c:c2:52:
20 cc:a0:31:a9:bb:89:5d:99:1e:46:6f:55:73:b9:76:
21 69:ec:d7:c1:fc:21:d6:c6:07:e7:4f:bd:22:de:e4:
22 a8:5b:2d:db:95:34:19:97:d6:28:4b:21:4c:ca:bb:
23 1d:79:a6:17:7f:5a:f9:67:e6:5c:78:45:3d:10:6d:
24 b0:17:59:26:11:c5:57:e3:7f:4e:82:ba:f6:2c:4e:
25 c8:37:4d:ff:85:15:84:47:e0:ed:3b:7c:7f:bc:af:
26 e9:01:05:a7:0c:6f:c3:e9:8d:a3:ce:be:a6:e3:cd:
27 3c:b5:58:2c:9e:c2:03:1c:60:22:37:39:ff:41:02:
28 c1:29:a4:65:51:ff:33:34:aa:42:15:f9:95:78:fc:
29 2d:f5:da:8a:85:7c:82:9d:fb:37:2c:6b:a5:a8:df:
30 7c:55:0b:80:2e:3c:b0:63:e1:cd:38:48:89:e8:14:
31 06:0b:82:bc:fd:d4:07:68:1b:0f:3e:d9:15:dd:94:
32 11:1b
33 Exponent: 65537 (0x10001)
34 X509v3 extensions:
35 X509v3 Basic Constraints: critical
36 CA:FALSE
37 X509v3 Extended Key Usage:
38 Code Signing, 1.3.6.1.4.1.311.10.3.6
39 Netscape Comment:
40 OpenSSL Generated Certificate
41 X509v3 Subject Key Identifier:
42 61:48:2A:A2:83:0D:0A:B2:AD:5A:F1:0B:72:50:DA:90:33:DD:CE:F0
43 X509v3 Authority Key Identifier:
44 keyid:AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
45
46 Signature Algorithm: sha256WithRSAEncryption
47 8f:8a:a1:06:1f:29:b7:0a:4a:d5:c5:fd:81:ab:25:ea:c0:7d:
48 e2:fc:6a:96:a0:79:93:67:ee:05:0e:25:12:25:e4:5a:f6:aa:
49 1a:f1:12:f3:05:8d:87:5e:f1:5a:5c:cb:8d:23:73:65:1d:15:
50 b9:de:22:6b:d6:49:67:c9:a3:c6:d7:62:4e:5c:b5:f9:03:83:
51 40:81:dc:87:9c:3c:3f:1c:0d:51:9f:94:65:0a:84:48:67:e4:
52 a2:f8:a6:4a:f0:e7:cd:cd:bd:94:e3:09:d2:5d:2d:16:1b:05:
53 15:0b:cb:44:b4:3e:61:42:22:c4:2a:5c:4e:c5:1d:a3:e2:e0:
54 52:b2:eb:f4:8b:2b:dc:38:39:5d:fb:88:a1:56:65:5f:2b:4f:
55 26:ff:06:78:10:12:eb:8c:5d:32:e3:c6:45:af:25:9b:a0:ff:
56 8e:ef:47:09:a3:e9:8b:37:92:92:69:76:7e:34:3b:92:05:67:
57 4e:b0:25:ed:bc:5e:5f:8f:b4:d6:ca:40:ff:e4:e2:31:23:0c:
58 85:25:ae:0c:55:01:ec:e5:47:5e:df:5b:bc:14:33:e3:c6:f5:
59 18:b6:d9:f7:dd:b3:b4:a1:31:d3:5a:5c:5d:7d:3e:bf:0a:e4:
60 e4:e8:b4:59:7d:3b:b4:8c:a3:1b:b5:20:a3:b9:3e:84:6f:8c:
61 21:00:c3:39
62-----BEGIN CERTIFICATE-----
63MIIEIDCCAwigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
64FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
65DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
66IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMjA0MTIxMTM5MDhaFw00MjA0MTEx
67MTM5MDhaMH8xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEXMBUG
68A1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MSswKQYD
69VQQDDCJDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nMIIBIjANBgkq
70hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyV+bYo8LsGSCrL7J4mLjS9KfHorVYRor
71XTj0t865mrhDuEOXd6tPfwxwRgv8f23GbeqAXgHSt2Yeh94NbdBBl6ilrwxjT/d8
72wlLMoDGpu4ldmR5Gb1VzuXZp7NfB/CHWxgfnT70i3uSoWy3blTQZl9YoSyFMyrsd
73eaYXf1r5Z+ZceEU9EG2wF1kmEcVX439Ogrr2LE7IN03/hRWER+DtO3x/vK/pAQWn
74DG/D6Y2jzr6m4808tVgsnsIDHGAiNzn/QQLBKaRlUf8zNKpCFfmVePwt9dqKhXyC
75nfs3LGulqN98VQuALjywY+HNOEiJ6BQGC4K8/dQHaBsPPtkV3ZQRGwIDAQABo4Gg
76MIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUHAwMGCisGAQQBgjcK
77AwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
78MB0GA1UdDgQWBBRhSCqigw0Ksq1a8QtyUNqQM93O8DAfBgNVHSMEGDAWgBStkZkL
79wiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEAj4qhBh8ptwpK1cX9
80gasl6sB94vxqlqB5k2fuBQ4lEiXkWvaqGvES8wWNh17xWlzLjSNzZR0Vud4ia9ZJ
81Z8mjxtdiTly1+QODQIHch5w8PxwNUZ+UZQqESGfkovimSvDnzc29lOMJ0l0tFhsF
82FQvLRLQ+YUIixCpcTsUdo+LgUrLr9Isr3Dg5XfuIoVZlXytPJv8GeBAS64xdMuPG
83Ra8lm6D/ju9HCaPpizeSkml2fjQ7kgVnTrAl7bxeX4+01spA/+TiMSMMhSWuDFUB
847OVHXt9bvBQz48b1GLbZ992ztKEx01pcXX0+vwrk5Oi0WX07tIyjG7Ugo7k+hG+M
85IQDDOQ==
86-----END CERTIFICATE-----
diff --git a/debian/rules b/debian/rules
index 3355879..557c9b1 100755
--- a/debian/rules
+++ b/debian/rules
@@ -127,7 +127,7 @@ binary: binary-indep binary-arch
127127
128build: build-arch build-indep128build: build-arch build-indep
129129
130clean: debian/control debian/canonical-certs.pem130clean: debian/control debian/canonical-certs.pem debian/canonical-revoked-certs.pem
131 dh_testdir131 dh_testdir
132 dh_testroot132 dh_testroot
133 dh_clean133 dh_clean
@@ -237,3 +237,15 @@ debian/canonical-certs.pem: $(wildcard $(DROOT)/certs/*-all.pem) $(wildcard $(DR
237 fi; \237 fi; \
238 done; \238 done; \
239 done >"$@"239 done >"$@"
240
241debian/canonical-revoked-certs.pem: $(wildcard $(DROOT)/revoked-certs/*-all.pem) $(wildcard $(DROOT)/revoked-certs/*-$(arch).pem) $(wildcard $(DEBIAN)/revoked-certs/*-all.pem) $(wildcard $(DEBIAN)/revoked-certs/*-$(arch).pem)
242 for cert in $(sort $(notdir $^)); \
243 do \
244 for dir in $(DEBIAN) $(DROOT); \
245 do \
246 if [ -f "$$dir/revoked-certs/$$cert" ]; then \
247 cat "$$dir/revoked-certs/$$cert"; \
248 break; \
249 fi; \
250 done; \
251 done >"$@"
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index f0ef02d..be5ee0b 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_EFI) += secureboot.o
29obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o29obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
30obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o30obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o
31obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o31obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o
32obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o
3233
33fake_map-y += fake_mem.o34fake_map-y += fake_mem.o
34fake_map-$(CONFIG_X86) += x86_fake_mem.o35fake_map-$(CONFIG_X86) += x86_fake_mem.o
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 788f227..c8e4481 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -244,6 +244,7 @@ void __init efi_init(void)
244244
245 reserve_regions();245 reserve_regions();
246 efi_esrt_init();246 efi_esrt_init();
247 efi_mokvar_table_init();
247248
248 memblock_reserve(data.phys_map & PAGE_MASK,249 memblock_reserve(data.phys_map & PAGE_MASK,
249 PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));250 PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index d1f6f77..a5faafd 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -44,6 +44,9 @@ struct efi __read_mostly efi = {
44 .esrt = EFI_INVALID_TABLE_ADDR,44 .esrt = EFI_INVALID_TABLE_ADDR,
45 .tpm_log = EFI_INVALID_TABLE_ADDR,45 .tpm_log = EFI_INVALID_TABLE_ADDR,
46 .tpm_final_log = EFI_INVALID_TABLE_ADDR,46 .tpm_final_log = EFI_INVALID_TABLE_ADDR,
47#ifdef CONFIG_LOAD_UEFI_KEYS
48 .mokvar_table = EFI_INVALID_TABLE_ADDR,
49#endif
47};50};
48EXPORT_SYMBOL(efi);51EXPORT_SYMBOL(efi);
4952
@@ -520,6 +523,9 @@ static const efi_config_table_type_t common_tables[] __initconst = {
520#ifdef CONFIG_EFI_RCI2_TABLE523#ifdef CONFIG_EFI_RCI2_TABLE
521 {DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys },524 {DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys },
522#endif525#endif
526#ifdef CONFIG_LOAD_UEFI_KEYS
527 {LINUX_EFI_MOK_VARIABLE_TABLE_GUID, &efi.mokvar_table, "MOKvar" },
528#endif
523 {},529 {},
524};530};
525531
diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c
526new file mode 100644532new file mode 100644
index 0000000..38722d2
--- /dev/null
+++ b/drivers/firmware/efi/mokvar-table.c
@@ -0,0 +1,362 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * mokvar-table.c
4 *
5 * Copyright (c) 2020 Red Hat
6 * Author: Lenny Szubowicz <lszubowi@redhat.com>
7 *
8 * This module contains the kernel support for the Linux EFI Machine
9 * Owner Key (MOK) variable configuration table, which is identified by
10 * the LINUX_EFI_MOK_VARIABLE_TABLE_GUID.
11 *
12 * This EFI configuration table provides a more robust alternative to
13 * EFI volatile variables by which an EFI boot loader can pass the
14 * contents of the Machine Owner Key (MOK) certificate stores to the
15 * kernel during boot. If both the EFI MOK config table and corresponding
16 * EFI MOK variables are present, the table should be considered as
17 * more authoritative.
18 *
19 * This module includes code that validates and maps the EFI MOK table,
20 * if it's presence was detected very early in boot.
21 *
22 * Kernel interface routines are provided to walk through all the
23 * entries in the MOK config table or to search for a specific named
24 * entry.
25 *
26 * The contents of the individual named MOK config table entries are
27 * made available to user space via read-only sysfs binary files under:
28 *
29 * /sys/firmware/efi/mok-variables/
30 *
31 */
32#define pr_fmt(fmt) "mokvar: " fmt
33
34#include <linux/capability.h>
35#include <linux/efi.h>
36#include <linux/init.h>
37#include <linux/io.h>
38#include <linux/kernel.h>
39#include <linux/kobject.h>
40#include <linux/list.h>
41#include <linux/slab.h>
42
43#include <asm/early_ioremap.h>
44
45/*
46 * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table is a packed
47 * sequence of struct efi_mokvar_table_entry, one for each named
48 * MOK variable. The sequence is terminated by an entry with a
49 * completely NULL name and 0 data size.
50 *
51 * efi_mokvar_table_size is set to the computed size of the
52 * MOK config table by efi_mokvar_table_init(). This will be
53 * non-zero if and only if the table if present and has been
54 * validated by efi_mokvar_table_init().
55 */
56static size_t efi_mokvar_table_size;
57
58/*
59 * efi_mokvar_table_va is the kernel virtual address at which the
60 * EFI MOK config table has been mapped by efi_mokvar_sysfs_init().
61 */
62static struct efi_mokvar_table_entry *efi_mokvar_table_va;
63
64/*
65 * Each /sys/firmware/efi/mok-variables/ sysfs file is represented by
66 * an instance of struct efi_mokvar_sysfs_attr on efi_mokvar_sysfs_list.
67 * bin_attr.private points to the associated EFI MOK config table entry.
68 *
69 * This list is created during boot and then remains unchanged.
70 * So no synchronization is currently required to walk the list.
71 */
72struct efi_mokvar_sysfs_attr {
73 struct bin_attribute bin_attr;
74 struct list_head node;
75};
76
77static LIST_HEAD(efi_mokvar_sysfs_list);
78static struct kobject *mokvar_kobj;
79
80/*
81 * efi_mokvar_table_init() - Early boot validation of EFI MOK config table
82 *
83 * If present, validate and compute the size of the EFI MOK variable
84 * configuration table. This table may be provided by an EFI boot loader
85 * as an alternative to ordinary EFI variables, due to platform-dependent
86 * limitations. The memory occupied by this table is marked as reserved.
87 *
88 * This routine must be called before efi_free_boot_services() in order
89 * to guarantee that it can mark the table as reserved.
90 *
91 * Implicit inputs:
92 * efi.mokvar_table: Physical address of EFI MOK variable config table
93 * or special value that indicates no such table.
94 *
95 * Implicit outputs:
96 * efi_mokvar_table_size: Computed size of EFI MOK variable config table.
97 * The table is considered present and valid if this
98 * is non-zero.
99 */
100void __init efi_mokvar_table_init(void)
101{
102 efi_memory_desc_t md;
103 void *va = NULL;
104 unsigned long cur_offset = 0;
105 unsigned long offset_limit;
106 unsigned long map_size = 0;
107 unsigned long map_size_needed = 0;
108 unsigned long size;
109 struct efi_mokvar_table_entry *mokvar_entry;
110 int err;
111
112 if (!efi_enabled(EFI_MEMMAP))
113 return;
114
115 if (efi.mokvar_table == EFI_INVALID_TABLE_ADDR)
116 return;
117 /*
118 * The EFI MOK config table must fit within a single EFI memory
119 * descriptor range.
120 */
121 err = efi_mem_desc_lookup(efi.mokvar_table, &md);
122 if (err) {
123 pr_warn("EFI MOKvar config table is not within the EFI memory map\n");
124 return;
125 }
126
127 offset_limit = efi_mem_desc_end(&md) - efi.mokvar_table;
128
129 /*
130 * Validate the MOK config table. Since there is no table header
131 * from which we could get the total size of the MOK config table,
132 * we compute the total size as we validate each variably sized
133 * entry, remapping as necessary.
134 */
135 err = -EINVAL;
136 while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
137 mokvar_entry = va + cur_offset;
138 map_size_needed = cur_offset + sizeof(*mokvar_entry);
139 if (map_size_needed > map_size) {
140 if (va)
141 early_memunmap(va, map_size);
142 /*
143 * Map a little more than the fixed size entry
144 * header, anticipating some data. It's safe to
145 * do so as long as we stay within current memory
146 * descriptor.
147 */
148 map_size = min(map_size_needed + 2*EFI_PAGE_SIZE,
149 offset_limit);
150 va = early_memremap(efi.mokvar_table, map_size);
151 if (!va) {
152 pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n",
153 efi.mokvar_table, map_size);
154 return;
155 }
156 mokvar_entry = va + cur_offset;
157 }
158
159 /* Check for last sentinel entry */
160 if (mokvar_entry->name[0] == '\0') {
161 if (mokvar_entry->data_size != 0)
162 break;
163 err = 0;
164 break;
165 }
166
167 /* Sanity check that the name is null terminated */
168 size = strnlen(mokvar_entry->name,
169 sizeof(mokvar_entry->name));
170 if (size >= sizeof(mokvar_entry->name))
171 break;
172
173 /* Advance to the next entry */
174 cur_offset = map_size_needed + mokvar_entry->data_size;
175 }
176
177 if (va)
178 early_memunmap(va, map_size);
179 if (err) {
180 pr_err("EFI MOKvar config table is not valid\n");
181 return;
182 }
183
184 if (md.type == EFI_BOOT_SERVICES_DATA)
185 efi_mem_reserve(efi.mokvar_table, map_size_needed);
186
187 efi_mokvar_table_size = map_size_needed;
188}
189
190/*
191 * efi_mokvar_entry_next() - Get next entry in the EFI MOK config table
192 *
193 * mokvar_entry: Pointer to current EFI MOK config table entry
194 * or null. Null indicates get first entry.
195 * Passed by reference. This is updated to the
196 * same value as the return value.
197 *
198 * Returns: Pointer to next EFI MOK config table entry
199 * or null, if there are no more entries.
200 * Same value is returned in the mokvar_entry
201 * parameter.
202 *
203 * This routine depends on the EFI MOK config table being entirely
204 * mapped with it's starting virtual address in efi_mokvar_table_va.
205 */
206struct efi_mokvar_table_entry *efi_mokvar_entry_next(
207 struct efi_mokvar_table_entry **mokvar_entry)
208{
209 struct efi_mokvar_table_entry *mokvar_cur;
210 struct efi_mokvar_table_entry *mokvar_next;
211 size_t size_cur;
212
213 mokvar_cur = *mokvar_entry;
214 *mokvar_entry = NULL;
215
216 if (efi_mokvar_table_va == NULL)
217 return NULL;
218
219 if (mokvar_cur == NULL) {
220 mokvar_next = efi_mokvar_table_va;
221 } else {
222 if (mokvar_cur->name[0] == '\0')
223 return NULL;
224 size_cur = sizeof(*mokvar_cur) + mokvar_cur->data_size;
225 mokvar_next = (void *)mokvar_cur + size_cur;
226 }
227
228 if (mokvar_next->name[0] == '\0')
229 return NULL;
230
231 *mokvar_entry = mokvar_next;
232 return mokvar_next;
233}
234
235/*
236 * efi_mokvar_entry_find() - Find EFI MOK config entry by name
237 *
238 * name: Name of the entry to look for.
239 *
240 * Returns: Pointer to EFI MOK config table entry if found;
241 * null otherwise.
242 *
243 * This routine depends on the EFI MOK config table being entirely
244 * mapped with it's starting virtual address in efi_mokvar_table_va.
245 */
246struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name)
247{
248 struct efi_mokvar_table_entry *mokvar_entry = NULL;
249
250 while (efi_mokvar_entry_next(&mokvar_entry)) {
251 if (!strncmp(name, mokvar_entry->name,
252 sizeof(mokvar_entry->name)))
253 return mokvar_entry;
254 }
255 return NULL;
256}
257
258/*
259 * efi_mokvar_sysfs_read() - sysfs binary file read routine
260 *
261 * Returns: Count of bytes read.
262 *
263 * Copy EFI MOK config table entry data for this mokvar sysfs binary file
264 * to the supplied buffer, starting at the specified offset into mokvar table
265 * entry data, for the specified count bytes. The copy is limited by the
266 * amount of data in this mokvar config table entry.
267 */
268static ssize_t efi_mokvar_sysfs_read(struct file *file, struct kobject *kobj,
269 struct bin_attribute *bin_attr, char *buf,
270 loff_t off, size_t count)
271{
272 struct efi_mokvar_table_entry *mokvar_entry = bin_attr->private;
273
274 if (!capable(CAP_SYS_ADMIN))
275 return 0;
276
277 if (off >= mokvar_entry->data_size)
278 return 0;
279 if (count > mokvar_entry->data_size - off)
280 count = mokvar_entry->data_size - off;
281
282 memcpy(buf, mokvar_entry->data + off, count);
283 return count;
284}
285
286/*
287 * efi_mokvar_sysfs_init() - Map EFI MOK config table and create sysfs
288 *
289 * Map the EFI MOK variable config table for run-time use by the kernel
290 * and create the sysfs entries in /sys/firmware/efi/mok-variables/
291 *
292 * This routine just returns if a valid EFI MOK variable config table
293 * was not found earlier during boot.
294 *
295 * This routine must be called during a "middle" initcall phase, i.e.
296 * after efi_mokvar_table_init() but before UEFI certs are loaded
297 * during late init.
298 *
299 * Implicit inputs:
300 * efi.mokvar_table: Physical address of EFI MOK variable config table
301 * or special value that indicates no such table.
302 *
303 * efi_mokvar_table_size: Computed size of EFI MOK variable config table.
304 * The table is considered present and valid if this
305 * is non-zero.
306 *
307 * Implicit outputs:
308 * efi_mokvar_table_va: Start virtual address of the EFI MOK config table.
309 */
310static int __init efi_mokvar_sysfs_init(void)
311{
312 void *config_va;
313 struct efi_mokvar_table_entry *mokvar_entry = NULL;
314 struct efi_mokvar_sysfs_attr *mokvar_sysfs = NULL;
315 int err = 0;
316
317 if (efi_mokvar_table_size == 0)
318 return -ENOENT;
319
320 config_va = memremap(efi.mokvar_table, efi_mokvar_table_size,
321 MEMREMAP_WB);
322 if (!config_va) {
323 pr_err("Failed to map EFI MOKvar config table\n");
324 return -ENOMEM;
325 }
326 efi_mokvar_table_va = config_va;
327
328 mokvar_kobj = kobject_create_and_add("mok-variables", efi_kobj);
329 if (!mokvar_kobj) {
330 pr_err("Failed to create EFI mok-variables sysfs entry\n");
331 return -ENOMEM;
332 }
333
334 while (efi_mokvar_entry_next(&mokvar_entry)) {
335 mokvar_sysfs = kzalloc(sizeof(*mokvar_sysfs), GFP_KERNEL);
336 if (!mokvar_sysfs) {
337 err = -ENOMEM;
338 break;
339 }
340
341 sysfs_bin_attr_init(&mokvar_sysfs->bin_attr);
342 mokvar_sysfs->bin_attr.private = mokvar_entry;
343 mokvar_sysfs->bin_attr.attr.name = mokvar_entry->name;
344 mokvar_sysfs->bin_attr.attr.mode = 0400;
345 mokvar_sysfs->bin_attr.size = mokvar_entry->data_size;
346 mokvar_sysfs->bin_attr.read = efi_mokvar_sysfs_read;
347
348 err = sysfs_create_bin_file(mokvar_kobj,
349 &mokvar_sysfs->bin_attr);
350 if (err)
351 break;
352
353 list_add_tail(&mokvar_sysfs->node, &efi_mokvar_sysfs_list);
354 }
355
356 if (err) {
357 pr_err("Failed to create some EFI mok-variables sysfs entries\n");
358 kfree(mokvar_sysfs);
359 }
360 return err;
361}
362device_initcall(efi_mokvar_sysfs_init);
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index fb8b07d..875e002 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -31,6 +31,7 @@ extern int restrict_link_by_builtin_and_secondary_trusted(
31#define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted31#define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted
32#endif32#endif
3333
34extern struct pkcs7_message *pkcs7;
34#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING35#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
35extern int mark_hash_blacklisted(const char *hash);36extern int mark_hash_blacklisted(const char *hash);
36extern int is_hash_blacklisted(const u8 *hash, size_t hash_len,37extern int is_hash_blacklisted(const u8 *hash, size_t hash_len,
@@ -49,6 +50,20 @@ static inline int is_binary_blacklisted(const u8 *hash, size_t hash_len)
49}50}
50#endif51#endif
5152
53#ifdef CONFIG_SYSTEM_REVOCATION_LIST
54extern int add_key_to_revocation_list(const char *data, size_t size);
55extern int is_key_on_revocation_list(struct pkcs7_message *pkcs7);
56#else
57static inline int add_key_to_revocation_list(const char *data, size_t size)
58{
59 return 0;
60}
61static inline int is_key_on_revocation_list(struct pkcs7_message *pkcs7)
62{
63 return -ENOKEY;
64}
65#endif
66
52#ifdef CONFIG_IMA_BLACKLIST_KEYRING67#ifdef CONFIG_IMA_BLACKLIST_KEYRING
53extern struct key *ima_blacklist_keyring;68extern struct key *ima_blacklist_keyring;
5469
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 2793a2d..09c0939 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -361,6 +361,7 @@ void efi_native_runtime_setup(void);
361#define LINUX_EFI_TPM_FINAL_LOG_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)361#define LINUX_EFI_TPM_FINAL_LOG_GUID EFI_GUID(0x1e2ed096, 0x30e2, 0x4254, 0xbd, 0x89, 0x86, 0x3b, 0xbe, 0xf8, 0x23, 0x25)
362#define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)362#define LINUX_EFI_MEMRESERVE_TABLE_GUID EFI_GUID(0x888eb0c6, 0x8ede, 0x4ff5, 0xa8, 0xf0, 0x9a, 0xee, 0x5c, 0xb9, 0x77, 0xc2)
363#define LINUX_EFI_INITRD_MEDIA_GUID EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)363#define LINUX_EFI_INITRD_MEDIA_GUID EFI_GUID(0x5568e427, 0x68fc, 0x4f3d, 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68)
364#define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
364365
365/* OEM GUIDs */366/* OEM GUIDs */
366#define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55)367#define DELLEMC_EFI_RCI2_TABLE_GUID EFI_GUID(0x2d9f28a2, 0xa886, 0x456a, 0x97, 0xa8, 0xf1, 0x1e, 0xf2, 0x4f, 0xf4, 0x55)
@@ -550,6 +551,7 @@ extern struct efi {
550 unsigned long esrt; /* ESRT table */551 unsigned long esrt; /* ESRT table */
551 unsigned long tpm_log; /* TPM2 Event Log table */552 unsigned long tpm_log; /* TPM2 Event Log table */
552 unsigned long tpm_final_log; /* TPM2 Final Events Log table */553 unsigned long tpm_final_log; /* TPM2 Final Events Log table */
554 unsigned long mokvar_table; /* MOK variable config table */
553555
554 efi_get_time_t *get_time;556 efi_get_time_t *get_time;
555 efi_set_time_t *set_time;557 efi_set_time_t *set_time;
@@ -1271,4 +1273,36 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size);
12711273
1272char *efi_systab_show_arch(char *str);1274char *efi_systab_show_arch(char *str);
12731275
1276/*
1277 * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table can be provided
1278 * to the kernel by an EFI boot loader. The table contains a packed
1279 * sequence of these entries, one for each named MOK variable.
1280 * The sequence is terminated by an entry with a completely NULL
1281 * name and 0 data size.
1282 */
1283struct efi_mokvar_table_entry {
1284 char name[256];
1285 u64 data_size;
1286 u8 data[];
1287} __attribute((packed));
1288
1289#ifdef CONFIG_LOAD_UEFI_KEYS
1290extern void __init efi_mokvar_table_init(void);
1291extern struct efi_mokvar_table_entry *efi_mokvar_entry_next(
1292 struct efi_mokvar_table_entry **mokvar_entry);
1293extern struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name);
1294#else
1295static inline void efi_mokvar_table_init(void) { }
1296static inline struct efi_mokvar_table_entry *efi_mokvar_entry_next(
1297 struct efi_mokvar_table_entry **mokvar_entry)
1298{
1299 return NULL;
1300}
1301static inline struct efi_mokvar_table_entry *efi_mokvar_entry_find(
1302 const char *name)
1303{
1304 return NULL;
1305}
1306#endif
1307
1274#endif /* _LINUX_EFI_H */1308#endif /* _LINUX_EFI_H */
diff --git a/scripts/Makefile b/scripts/Makefile
index b3f6415..99ff04d 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -14,6 +14,7 @@ always-$(CONFIG_ASN1) += asn1_compiler
14always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file14always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file
15always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert15always-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert
16always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert16always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert
17hostprogs-always-$(CONFIG_SYSTEM_REVOCATION_LIST) += extract-cert
1718
18HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include19HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
19HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include20HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
diff --git a/security/integrity/platform_certs/keyring_handler.c b/security/integrity/platform_certs/keyring_handler.c
index c5ba695..9f85626 100644
--- a/security/integrity/platform_certs/keyring_handler.c
+++ b/security/integrity/platform_certs/keyring_handler.c
@@ -56,6 +56,16 @@ static __init void uefi_blacklist_binary(const char *source,
56}56}
5757
58/*58/*
59 * Add an X509 cert to the revocation list.
60 */
61static __init void uefi_revocation_list_x509(const char *source,
62 const void *data, size_t len)
63{
64 pr_info("Revoking X.509 certificate: %s\n", source);
65 add_key_to_revocation_list(data, len);
66}
67
68/*
59 * Return the appropriate handler for particular signature list types found in69 * Return the appropriate handler for particular signature list types found in
60 * the UEFI db and MokListRT tables.70 * the UEFI db and MokListRT tables.
61 */71 */
@@ -76,5 +86,7 @@ __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type)
76 return uefi_blacklist_x509_tbs;86 return uefi_blacklist_x509_tbs;
77 if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0)87 if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0)
78 return uefi_blacklist_binary;88 return uefi_blacklist_binary;
89 if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
90 return uefi_revocation_list_x509;
79 return 0;91 return 0;
80}92}
diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
index 8c95b68..b010b4a 100644
--- a/security/integrity/platform_certs/load_uefi.c
+++ b/security/integrity/platform_certs/load_uefi.c
@@ -68,6 +68,80 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
68}68}
6969
70/*70/*
71 * load_moklist_certs() - Load Mok(X)List certs
72 * @load_db: Load MokListRT into db when true; MokListXRT into dbx when false
73 *
74 * Load the certs contained in the UEFI MokList(X)RT database into the
75 * platform trusted/denied keyring.
76 *
77 * This routine checks the EFI MOK config table first. If and only if
78 * that fails, this routine uses the MokList(X)RT ordinary UEFI variable.
79 *
80 * Return: Status
81 */
82static int __init load_moklist_certs(const bool load_db)
83{
84 struct efi_mokvar_table_entry *mokvar_entry;
85 efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
86 void *mok;
87 unsigned long moksize;
88 efi_status_t status;
89 int rc;
90 const char *mokvar_name = "MokListRT";
91 /* Should be const, but get_cert_list() doesn't have it as const yet */
92 efi_char16_t *efivar_name = L"MokListRT";
93 const char *parse_mokvar_name = "UEFI:MokListRT (MOKvar table)";
94 const char *parse_efivar_name = "UEFI:MokListRT";
95 efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *) = get_handler_for_db;
96
97 if (!load_db) {
98 mokvar_name = "MokListXRT";
99 efivar_name = L"MokListXRT";
100 parse_mokvar_name = "UEFI:MokListXRT (MOKvar table)";
101 parse_efivar_name = "UEFI:MokListXRT";
102 get_handler_for_guid = get_handler_for_dbx;
103 }
104
105 /* First try to load certs from the EFI MOKvar config table.
106 * It's not an error if the MOKvar config table doesn't exist
107 * or the MokListRT entry is not found in it.
108 */
109 mokvar_entry = efi_mokvar_entry_find(mokvar_name);
110 if (mokvar_entry) {
111 rc = parse_efi_signature_list(parse_mokvar_name,
112 mokvar_entry->data,
113 mokvar_entry->data_size,
114 get_handler_for_guid);
115 /* All done if that worked. */
116 if (!rc)
117 return rc;
118
119 pr_err("Couldn't parse %s signatures from EFI MOKvar config table: %d\n",
120 mokvar_name, rc);
121 }
122
123 /* Get MokListRT. It might not exist, so it isn't an error
124 * if we can't get it.
125 */
126 mok = get_cert_list(efivar_name, &mok_var, &moksize, &status);
127 if (mok) {
128 rc = parse_efi_signature_list(parse_efivar_name,
129 mok, moksize, get_handler_for_guid);
130 kfree(mok);
131 if (rc)
132 pr_err("Couldn't parse %s signatures: %d\n", mokvar_name, rc);
133 return rc;
134 }
135 if (status == EFI_NOT_FOUND)
136 pr_debug("%s variable wasn't found\n", mokvar_name);
137 else
138 pr_info("Couldn't get UEFI %s\n", mokvar_name);
139 return 0;
140}
141
142/*
143 * load_uefi_certs() - Load certs from UEFI sources
144 *
71 * Load the certs contained in the UEFI databases into the platform trusted145 * Load the certs contained in the UEFI databases into the platform trusted
72 * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist146 * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
73 * keyring.147 * keyring.
@@ -75,17 +149,16 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
75static int __init load_uefi_certs(void)149static int __init load_uefi_certs(void)
76{150{
77 efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;151 efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
78 efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;152 void *db = NULL, *dbx = NULL;
79 void *db = NULL, *dbx = NULL, *mok = NULL;153 unsigned long dbsize = 0, dbxsize = 0;
80 unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
81 efi_status_t status;154 efi_status_t status;
82 int rc = 0;155 int rc = 0;
83156
84 if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))157 if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
85 return false;158 return false;
86159
87 /* Get db, MokListRT, and dbx. They might not exist, so it isn't160 /* Get db and dbx. They might not exist, so it isn't an error
88 * an error if we can't get them.161 * if we can't get them.
89 */162 */
90 if (!uefi_check_ignore_db()) {163 if (!uefi_check_ignore_db()) {
91 db = get_cert_list(L"db", &secure_var, &dbsize, &status);164 db = get_cert_list(L"db", &secure_var, &dbsize, &status);
@@ -104,20 +177,6 @@ static int __init load_uefi_certs(void)
104 }177 }
105 }178 }
106179
107 mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status);
108 if (!mok) {
109 if (status == EFI_NOT_FOUND)
110 pr_debug("MokListRT variable wasn't found\n");
111 else
112 pr_info("Couldn't get UEFI MokListRT\n");
113 } else {
114 rc = parse_efi_signature_list("UEFI:MokListRT",
115 mok, moksize, get_handler_for_db);
116 if (rc)
117 pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
118 kfree(mok);
119 }
120
121 dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status);180 dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status);
122 if (!dbx) {181 if (!dbx) {
123 if (status == EFI_NOT_FOUND)182 if (status == EFI_NOT_FOUND)
@@ -133,6 +192,16 @@ static int __init load_uefi_certs(void)
133 kfree(dbx);192 kfree(dbx);
134 }193 }
135194
195 /* Load the MokListXRT certs */
196 rc = load_moklist_certs(false);
197 if (rc)
198 pr_err("Couldn't parse mokx signatures: %d\n", rc);
199
200 /* Load the MokListRT certs */
201 rc = load_moklist_certs(true);
202 if (rc)
203 pr_err("Couldn't parse mok signatures: %d\n", rc);
204
136 return rc;205 return rc;
137}206}
138late_initcall(load_uefi_certs);207late_initcall(load_uefi_certs);

Subscribers

People subscribed via source and target branches