Merge ~xnox/ubuntu/+source/linux/+git/bionic:revocation-keys into ~ubuntu-kernel/ubuntu/+source/linux/+git/bionic:master-next
- Git
- lp:~xnox/ubuntu/+source/linux/+git/bionic
- revocation-keys
- Merge into master-next
Status: | Needs review |
---|---|
Proposed branch: | ~xnox/ubuntu/+source/linux/+git/bionic:revocation-keys |
Merge into: | ~ubuntu-kernel/ubuntu/+source/linux/+git/bionic:master-next |
Diff against target: |
1208 lines (+824/-65) 22 files modified
arch/x86/kernel/setup.c (+1/-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/load_uefi.c (+95/-14) certs/revocation_certificates.S (+21/-0) certs/system_keyring.c (+10/-47) 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 (+9/-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) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Kernel Repositories | Pending | ||
Review via email: mp+412577@code.launchpad.net |
Commit message
Support builtin revoked certificates and mokvar-table
Same story as before, backport support for builtin revoked
certificates, add support loading revoked certificates from
mokvar-table.
Some of the patches had to be adjusted during backport. For example,
instead of patching security/
which does not exist in v4.15 kernel certs/load_uefi.c is. Some error
handling is done differently as well. For example, EFI status not
found is not handled when loading keys from variables.
This series doesn't have any reverts, as the lockdown patchset is
mostly older without any major reorgs that didn't make upstream. It is
slightly larger than focal's one as support for EFI_CERT_X509_GUID did
not land via linux-stable updates.
After this patch is applied, the RT boot testing & kernel built-in
final check will catch any kernels that do not have
CONFIG_
snapdgaron, kvm flavours as they in theory can support UEFI, but are
not signed and may not enable all the lockdown and keyring
features. These flavours may need reverting 70de61082d ("UBUNTU:
[Packaging] Add system trusted and revocation keys final check") as
was done in Focal. Or enable all the keyrings and builtin revocation
keys.
Description of the change
Unmerged commits
- 750558e... 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 741f622c4dbc162b82f8c9045f9c6c 6446f57eb5)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden> - b0d255c... 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 3f72ce72f0b51b6da2638cdded93bb 32b9dad2ec)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 8d7c952... 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 3e44f229eef829ee30446519755125 69824c4e5f)
(xnox: cherry-pick is from impish:linux)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 3b9b048... 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 b5b4085dc5547a01593cd79dbf51bd 9108f84e9f)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 4dab349... 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: 13adbf4309bd82709c8cd54f316ed5 22988a1bd4'
integrity: Revoking X.509 certificate: UEFI:MokListXRT (MOKvar table)
blacklist: Revoked X.509 cert 'Canonical Ltd. Secure Boot Signing: 61482aa2830d0ab2ad5af10b7250da 9033ddcef0'
integrity: Loading X.509 certificate: UEFI:MokListRT (MOKvar table)
integrity: Loaded X.509 cert 'Canonical Ltd. Master Certificate Authority: ad91990bc22ab1f517048c23b6655a 268e345a63' 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 ba9fb788f89cb81c5ed836db2355a7 a3b0f8c248)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 1a3d39e... 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 a9e3aae16235d6af12509a64f1337d a4485ccbae)
(xnox: cherry-pick is from impish:linux SAUCE)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 5db8878... by Linus Torvalds <email address hidden>
-
certs: add 'x509_revocatio
n_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 81f202315856edb75a371f3376aa3a 47543c16f0)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 52ad86c... 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 d1f044103dad70c1cec0a8f3abdf00 834fec8b98)
Signed-off-by: Dimitri John Ledkov <email address hidden> - 849f596... by Lenny Szubowicz <email address hidden>
-
integrity: Load certs from the EFI MOK config table
BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029 Because of system-specific EFI firmware limitations, EFI volatile
variables may not be capable of holding the required contents of
the Machine Owner Key (MOK) certificate store when the certificate
list grows above some size. Therefore, an EFI boot loader may pass
the MOK certs via a EFI configuration table created specifically for
this purpose to avoid this firmware limitation.An EFI configuration table is a much more primitive mechanism
compared to EFI variables and is well suited for one-way passage
of static information from a pre-OS environment to the kernel.This patch adds the support to load certs from the MokListRT
entry in the MOK variable configuration table, if it's present.
The pre-existing support to load certs from the MokListRT EFI
variable remains and is used if the EFI MOK configuration table
isn't present or can't be successfully used.Signed-off-by: Lenny Szubowicz <email address hidden>
Link: https://<email address hidden>
Signed-off-by: Ard Biesheuvel <email address hidden>
(cherry picked from commit 726bd8965a5f112d9601f7ce68effa 1e46e02bf2)
Signed-off-by: Dimitri John Ledkov <email address hidden> - ba184a1... by Lenny Szubowicz <email address hidden>
-
integrity: Move import of MokListRT certs to a separate routine
BugLink: https:/
/bugs.launchpad .net/bugs/ 1932029 Move the loading of certs from the UEFI MokListRT into a separate
routine to facilitate additional MokList functionality.There is no visible functional change as a result of this patch.
Although the UEFI dbx certs are now loaded before the MokList certs,
they are loaded onto different key rings. So the order of the keys
on their respective key rings is the same.Signed-off-by: Lenny Szubowicz <email address hidden>
Reviewed-by: Mimi Zohar <email address hidden>
Link: https://<email address hidden>
Signed-off-by: Ard Biesheuvel <email address hidden>
(cherry picked from commit 38a1f03aa24094b4a8de846700cb6c b21cc06468)
Signed-off-by: Dimitri John Ledkov <email address hidden>
Preview Diff
1 | diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c |
2 | index 02b5b81..179c63d 100644 |
3 | --- a/arch/x86/kernel/setup.c |
4 | +++ b/arch/x86/kernel/setup.c |
5 | @@ -1108,6 +1108,7 @@ void __init setup_arch(char **cmdline_p) |
6 | efi_fake_memmap(); |
7 | efi_find_mirror(); |
8 | efi_esrt_init(); |
9 | + efi_mokvar_table_init(); |
10 | |
11 | /* |
12 | * The EFI specification says that boot service code won't be |
13 | diff --git a/certs/.gitignore b/certs/.gitignore |
14 | index f51aea4..6ce8116 100644 |
15 | --- a/certs/.gitignore |
16 | +++ b/certs/.gitignore |
17 | @@ -2,3 +2,4 @@ |
18 | # Generated files |
19 | # |
20 | x509_certificate_list |
21 | +x509_revocation_list |
22 | diff --git a/certs/Kconfig b/certs/Kconfig |
23 | index 9e3ca57..3575c4f 100644 |
24 | --- a/certs/Kconfig |
25 | +++ b/certs/Kconfig |
26 | @@ -107,4 +107,21 @@ config LOAD_UEFI_KEYS |
27 | mode, modules signed with UEFI-stored keys will be permitted to be |
28 | loaded and keys that match the blacklist will be rejected. |
29 | |
30 | +config SYSTEM_REVOCATION_LIST |
31 | + bool "Provide system-wide ring of revocation certificates" |
32 | + depends on SYSTEM_BLACKLIST_KEYRING |
33 | + depends on PKCS7_MESSAGE_PARSER=y |
34 | + help |
35 | + If set, this allows revocation certificates to be stored in the |
36 | + blacklist keyring and implements a hook whereby a PKCS#7 message can |
37 | + be checked to see if it matches such a certificate. |
38 | + |
39 | +config SYSTEM_REVOCATION_KEYS |
40 | + string "X.509 certificates to be preloaded into the system blacklist keyring" |
41 | + depends on SYSTEM_REVOCATION_LIST |
42 | + help |
43 | + If set, this option should be the filename of a PEM-formatted file |
44 | + containing X.509 certificates to be included in the default blacklist |
45 | + keyring. |
46 | + |
47 | endmenu |
48 | diff --git a/certs/Makefile b/certs/Makefile |
49 | index ba3b209..0e43070 100644 |
50 | --- a/certs/Makefile |
51 | +++ b/certs/Makefile |
52 | @@ -3,8 +3,9 @@ |
53 | # Makefile for the linux kernel signature checking certificates. |
54 | # |
55 | |
56 | -obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o |
57 | -obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o |
58 | +obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o |
59 | +obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o |
60 | +obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o |
61 | ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"") |
62 | obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o |
63 | else |
64 | @@ -34,7 +35,7 @@ $(obj)/x509_certificate_list: scripts/extract-cert $(SYSTEM_TRUSTED_KEYS_SRCPREF |
65 | $(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS)) |
66 | endif # CONFIG_SYSTEM_TRUSTED_KEYRING |
67 | |
68 | -clean-files := x509_certificate_list .x509.list |
69 | +clean-files := x509_certificate_list .x509.list x509_revocation_list |
70 | |
71 | ifeq ($(CONFIG_MODULE_SIG),y) |
72 | ############################################################################### |
73 | @@ -117,3 +118,17 @@ targets += signing_key.x509 |
74 | $(obj)/signing_key.x509: scripts/extract-cert $(X509_DEP) FORCE |
75 | $(call if_changed,extract_certs,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY)) |
76 | endif # CONFIG_MODULE_SIG |
77 | + |
78 | +ifeq ($(CONFIG_SYSTEM_REVOCATION_LIST),y) |
79 | + |
80 | +$(eval $(call config_filename,SYSTEM_REVOCATION_KEYS)) |
81 | + |
82 | +$(obj)/revocation_certificates.o: $(obj)/x509_revocation_list |
83 | + |
84 | +quiet_cmd_extract_certs = EXTRACT_CERTS $(patsubst "%",%,$(2)) |
85 | + cmd_extract_certs = scripts/extract-cert $(2) $@ |
86 | + |
87 | +targets += x509_revocation_list |
88 | +$(obj)/x509_revocation_list: scripts/extract-cert $(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(SYSTEM_REVOCATION_KEYS_FILENAME) FORCE |
89 | + $(call if_changed,extract_certs,$(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_REVOCATION_KEYS)) |
90 | +endif |
91 | diff --git a/certs/blacklist.c b/certs/blacklist.c |
92 | index e9f3f81..a97d50b 100644 |
93 | --- a/certs/blacklist.c |
94 | +++ b/certs/blacklist.c |
95 | @@ -20,9 +20,15 @@ |
96 | #include <linux/seq_file.h> |
97 | #include <keys/system_keyring.h> |
98 | #include "blacklist.h" |
99 | +#include "common.h" |
100 | |
101 | static struct key *blacklist_keyring; |
102 | |
103 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
104 | +extern __initconst const u8 revocation_certificate_list[]; |
105 | +extern __initconst const unsigned long revocation_certificate_list_size; |
106 | +#endif |
107 | + |
108 | /* |
109 | * The description must be a type prefix, a colon and then an even number of |
110 | * hex digits. The hash is kept in the description. |
111 | @@ -139,6 +145,52 @@ int is_hash_blacklisted(const u8 *hash, size_t hash_len, const char *type) |
112 | } |
113 | EXPORT_SYMBOL_GPL(is_hash_blacklisted); |
114 | |
115 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
116 | +/** |
117 | + * add_key_to_revocation_list - Add a revocation certificate to the blacklist |
118 | + * @data: The data blob containing the certificate |
119 | + * @size: The size of data blob |
120 | + */ |
121 | +int add_key_to_revocation_list(const char *data, size_t size) |
122 | +{ |
123 | + key_ref_t key; |
124 | + |
125 | + key = key_create_or_update(make_key_ref(blacklist_keyring, true), |
126 | + "asymmetric", |
127 | + NULL, |
128 | + data, |
129 | + size, |
130 | + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW), |
131 | + KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN); |
132 | + |
133 | + if (IS_ERR(key)) { |
134 | + pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key)); |
135 | + return PTR_ERR(key); |
136 | + } else { |
137 | + pr_notice("Revoked X.509 cert '%s'\n", |
138 | + key_ref_to_ptr(key)->description); |
139 | + } |
140 | + |
141 | + return 0; |
142 | +} |
143 | + |
144 | +/** |
145 | + * is_key_on_revocation_list - Determine if the key for a PKCS#7 message is revoked |
146 | + * @pkcs7: The PKCS#7 message to check |
147 | + */ |
148 | +int is_key_on_revocation_list(struct pkcs7_message *pkcs7) |
149 | +{ |
150 | + int ret; |
151 | + |
152 | + ret = pkcs7_validate_trust(pkcs7, blacklist_keyring); |
153 | + |
154 | + if (ret == 0) |
155 | + return -EKEYREJECTED; |
156 | + |
157 | + return -ENOKEY; |
158 | +} |
159 | +#endif |
160 | + |
161 | /* |
162 | * Initialise the blacklist |
163 | */ |
164 | @@ -172,3 +224,18 @@ static int __init blacklist_init(void) |
165 | * Must be initialised before we try and load the keys into the keyring. |
166 | */ |
167 | device_initcall(blacklist_init); |
168 | + |
169 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
170 | +/* |
171 | + * Load the compiled-in list of revocation X.509 certificates. |
172 | + */ |
173 | +static __init int load_revocation_certificate_list(void) |
174 | +{ |
175 | + if (revocation_certificate_list_size) |
176 | + pr_notice("Loading compiled-in revocation X.509 certificates\n"); |
177 | + |
178 | + return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size, |
179 | + blacklist_keyring); |
180 | +} |
181 | +late_initcall(load_revocation_certificate_list); |
182 | +#endif |
183 | diff --git a/certs/blacklist.h b/certs/blacklist.h |
184 | index 150d82d..d4f9fac 100644 |
185 | --- a/certs/blacklist.h |
186 | +++ b/certs/blacklist.h |
187 | @@ -1,3 +1,5 @@ |
188 | #include <linux/kernel.h> |
189 | +#include <linux/errno.h> |
190 | +#include <crypto/pkcs7.h> |
191 | |
192 | extern const char __initdata *const blacklist_hashes[]; |
193 | diff --git a/certs/common.c b/certs/common.c |
194 | new file mode 100644 |
195 | index 0000000..23af4fc |
196 | --- /dev/null |
197 | +++ b/certs/common.c |
198 | @@ -0,0 +1,58 @@ |
199 | +// SPDX-License-Identifier: GPL-2.0-or-later |
200 | + |
201 | +#include <linux/kernel.h> |
202 | +#include <linux/key.h> |
203 | +#include "common.h" |
204 | + |
205 | +int load_certificate_list(const u8 cert_list[], |
206 | + const unsigned long list_size, |
207 | + const struct key *keyring) |
208 | +{ |
209 | + key_ref_t key; |
210 | + const u8 *p, *end; |
211 | + size_t plen; |
212 | + |
213 | + p = cert_list; |
214 | + end = p + list_size; |
215 | + while (p < end) { |
216 | + /* Each cert begins with an ASN.1 SEQUENCE tag and must be more |
217 | + * than 256 bytes in size. |
218 | + */ |
219 | + if (end - p < 4) |
220 | + goto dodgy_cert; |
221 | + if (p[0] != 0x30 && |
222 | + p[1] != 0x82) |
223 | + goto dodgy_cert; |
224 | + plen = (p[2] << 8) | p[3]; |
225 | + plen += 4; |
226 | + if (plen > end - p) |
227 | + goto dodgy_cert; |
228 | + |
229 | + key = key_create_or_update(make_key_ref(keyring, 1), |
230 | + "asymmetric", |
231 | + NULL, |
232 | + p, |
233 | + plen, |
234 | + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | |
235 | + KEY_USR_VIEW | KEY_USR_READ), |
236 | + KEY_ALLOC_NOT_IN_QUOTA | |
237 | + KEY_ALLOC_BUILT_IN | |
238 | + KEY_ALLOC_BYPASS_RESTRICTION); |
239 | + if (IS_ERR(key)) { |
240 | + pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", |
241 | + PTR_ERR(key)); |
242 | + WARN_ON_ONCE(1); |
243 | + } else { |
244 | + pr_notice("Loaded X.509 cert '%s'\n", |
245 | + key_ref_to_ptr(key)->description); |
246 | + key_ref_put(key); |
247 | + } |
248 | + p += plen; |
249 | + } |
250 | + |
251 | + return 0; |
252 | + |
253 | +dodgy_cert: |
254 | + pr_err("Problem parsing in-kernel X.509 certificate list\n"); |
255 | + return 0; |
256 | +} |
257 | diff --git a/certs/common.h b/certs/common.h |
258 | new file mode 100644 |
259 | index 0000000..abdb579 |
260 | --- /dev/null |
261 | +++ b/certs/common.h |
262 | @@ -0,0 +1,9 @@ |
263 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
264 | + |
265 | +#ifndef _CERT_COMMON_H |
266 | +#define _CERT_COMMON_H |
267 | + |
268 | +int load_certificate_list(const u8 cert_list[], const unsigned long list_size, |
269 | + const struct key *keyring); |
270 | + |
271 | +#endif |
272 | diff --git a/certs/load_uefi.c b/certs/load_uefi.c |
273 | index 3d88459..9783e59 100644 |
274 | --- a/certs/load_uefi.c |
275 | +++ b/certs/load_uefi.c |
276 | @@ -109,6 +109,16 @@ static __init void uefi_blacklist_binary(const char *source, |
277 | } |
278 | |
279 | /* |
280 | + * Add an X509 cert to the revocation list. |
281 | + */ |
282 | +static __init void uefi_revocation_list_x509(const char *source, |
283 | + const void *data, size_t len) |
284 | +{ |
285 | + pr_info("Revoking X.509 certificate: %s\n", source); |
286 | + add_key_to_revocation_list(data, len); |
287 | +} |
288 | + |
289 | +/* |
290 | * Return the appropriate handler for particular signature list types found in |
291 | * the UEFI db and MokListRT tables. |
292 | */ |
293 | @@ -129,10 +139,83 @@ static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_ty |
294 | return uefi_blacklist_x509_tbs; |
295 | if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0) |
296 | return uefi_blacklist_binary; |
297 | + if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) |
298 | + return uefi_revocation_list_x509; |
299 | + return 0; |
300 | +} |
301 | + |
302 | +/* |
303 | + * load_moklist_certs() - Load Mok(X)List certs |
304 | + * @load_db: Load MokListRT into db when true; MokListXRT into dbx when false |
305 | + * |
306 | + * Load the certs contained in the UEFI MokList(X)RT database into the |
307 | + * platform trusted/denied keyring. |
308 | + * |
309 | + * This routine checks the EFI MOK config table first. If and only if |
310 | + * that fails, this routine uses the MokList(X)RT ordinary UEFI variable. |
311 | + * |
312 | + * Return: Status |
313 | + */ |
314 | +static int __init load_moklist_certs(const bool load_db) |
315 | +{ |
316 | + struct efi_mokvar_table_entry *mokvar_entry; |
317 | + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; |
318 | + void *mok; |
319 | + unsigned long moksize; |
320 | + int rc; |
321 | + const char *mokvar_name = "MokListRT"; |
322 | + /* Should be const, but get_cert_list() doesn't have it as const yet */ |
323 | + efi_char16_t *efivar_name = L"MokListRT"; |
324 | + const char *parse_mokvar_name = "UEFI:MokListRT (MOKvar table)"; |
325 | + const char *parse_efivar_name = "UEFI:MokListRT"; |
326 | + efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *) = get_handler_for_db; |
327 | + |
328 | + if (!load_db) { |
329 | + mokvar_name = "MokListXRT"; |
330 | + efivar_name = L"MokListXRT"; |
331 | + parse_mokvar_name = "UEFI:MokListXRT (MOKvar table)"; |
332 | + parse_efivar_name = "UEFI:MokListXRT"; |
333 | + get_handler_for_guid = get_handler_for_dbx; |
334 | + } |
335 | + |
336 | + /* First try to load certs from the EFI MOKvar config table. |
337 | + * It's not an error if the MOKvar config table doesn't exist |
338 | + * or the MokListRT entry is not found in it. |
339 | + */ |
340 | + mokvar_entry = efi_mokvar_entry_find(mokvar_name); |
341 | + if (mokvar_entry) { |
342 | + rc = parse_efi_signature_list(parse_mokvar_name, |
343 | + mokvar_entry->data, |
344 | + mokvar_entry->data_size, |
345 | + get_handler_for_guid); |
346 | + /* All done if that worked. */ |
347 | + if (!rc) |
348 | + return rc; |
349 | + |
350 | + pr_err("Couldn't parse %s signatures from EFI MOKvar config table: %d\n", |
351 | + mokvar_name, rc); |
352 | + } |
353 | + |
354 | + /* Get MokListRT. It might not exist, so it isn't an error |
355 | + * if we can't get it. |
356 | + */ |
357 | + mok = get_cert_list(efivar_name, &mok_var, &moksize); |
358 | + if (mok) { |
359 | + rc = parse_efi_signature_list(parse_efivar_name, |
360 | + mok, moksize, get_handler_for_guid); |
361 | + kfree(mok); |
362 | + if (rc) |
363 | + pr_err("Couldn't parse %s signatures: %d\n", mokvar_name, rc); |
364 | + return rc; |
365 | + } else |
366 | + pr_info("Couldn't get UEFI %s\n", mokvar_name); |
367 | return 0; |
368 | } |
369 | |
370 | /* |
371 | + * load_uefi_certs() - Load certs from UEFI sources |
372 | + * |
373 | + * |
374 | * Load the certs contained in the UEFI databases into the secondary trusted |
375 | * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist |
376 | * keyring. |
377 | @@ -140,9 +223,8 @@ static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_ty |
378 | static int __init load_uefi_certs(void) |
379 | { |
380 | efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; |
381 | - efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; |
382 | - void *db = NULL, *dbx = NULL, *mok = NULL; |
383 | - unsigned long dbsize = 0, dbxsize = 0, moksize = 0; |
384 | + void *db = NULL, *dbx = NULL; |
385 | + unsigned long dbsize = 0, dbxsize = 0; |
386 | int rc = 0; |
387 | |
388 | if (!efi.get_variable) |
389 | @@ -164,17 +246,6 @@ static int __init load_uefi_certs(void) |
390 | } |
391 | } |
392 | |
393 | - mok = get_cert_list(L"MokListRT", &mok_var, &moksize); |
394 | - if (!mok) { |
395 | - pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); |
396 | - } else { |
397 | - rc = parse_efi_signature_list("UEFI:MokListRT", |
398 | - mok, moksize, get_handler_for_db); |
399 | - if (rc) |
400 | - pr_err("Couldn't parse MokListRT signatures: %d\n", rc); |
401 | - kfree(mok); |
402 | - } |
403 | - |
404 | dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); |
405 | if (!dbx) { |
406 | pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); |
407 | @@ -187,6 +258,16 @@ static int __init load_uefi_certs(void) |
408 | kfree(dbx); |
409 | } |
410 | |
411 | + /* Load the MokListXRT certs */ |
412 | + rc = load_moklist_certs(false); |
413 | + if (rc) |
414 | + pr_err("Couldn't parse mokx signatures: %d\n", rc); |
415 | + |
416 | + /* Load the MokListRT certs */ |
417 | + rc = load_moklist_certs(true); |
418 | + if (rc) |
419 | + pr_err("Couldn't parse mok signatures: %d\n", rc); |
420 | + |
421 | return rc; |
422 | } |
423 | late_initcall(load_uefi_certs); |
424 | diff --git a/certs/revocation_certificates.S b/certs/revocation_certificates.S |
425 | new file mode 100644 |
426 | index 0000000..f21aae8 |
427 | --- /dev/null |
428 | +++ b/certs/revocation_certificates.S |
429 | @@ -0,0 +1,21 @@ |
430 | +/* SPDX-License-Identifier: GPL-2.0 */ |
431 | +#include <linux/export.h> |
432 | +#include <linux/init.h> |
433 | + |
434 | + __INITRODATA |
435 | + |
436 | + .align 8 |
437 | + .globl revocation_certificate_list |
438 | +revocation_certificate_list: |
439 | +__revocation_list_start: |
440 | + .incbin "certs/x509_revocation_list" |
441 | +__revocation_list_end: |
442 | + |
443 | + .align 8 |
444 | + .globl revocation_certificate_list_size |
445 | +revocation_certificate_list_size: |
446 | +#ifdef CONFIG_64BIT |
447 | + .quad __revocation_list_end - __revocation_list_start |
448 | +#else |
449 | + .long __revocation_list_end - __revocation_list_start |
450 | +#endif |
451 | diff --git a/certs/system_keyring.c b/certs/system_keyring.c |
452 | index 3821699..83f6472 100644 |
453 | --- a/certs/system_keyring.c |
454 | +++ b/certs/system_keyring.c |
455 | @@ -19,6 +19,7 @@ |
456 | #include <keys/asymmetric-type.h> |
457 | #include <keys/system_keyring.h> |
458 | #include <crypto/pkcs7.h> |
459 | +#include "common.h" |
460 | #include "internal.h" |
461 | |
462 | static struct key *builtin_trusted_keys; |
463 | @@ -138,55 +139,10 @@ device_initcall(system_trusted_keyring_init); |
464 | */ |
465 | static __init int load_system_certificate_list(void) |
466 | { |
467 | - key_ref_t key; |
468 | - const u8 *p, *end; |
469 | - size_t plen; |
470 | - |
471 | pr_notice("Loading compiled-in X.509 certificates\n"); |
472 | |
473 | - p = system_certificate_list; |
474 | - end = p + system_certificate_list_size; |
475 | - while (p < end) { |
476 | - /* Each cert begins with an ASN.1 SEQUENCE tag and must be more |
477 | - * than 256 bytes in size. |
478 | - */ |
479 | - if (end - p < 4) |
480 | - goto dodgy_cert; |
481 | - if (p[0] != 0x30 && |
482 | - p[1] != 0x82) |
483 | - goto dodgy_cert; |
484 | - plen = (p[2] << 8) | p[3]; |
485 | - plen += 4; |
486 | - if (plen > end - p) |
487 | - goto dodgy_cert; |
488 | - |
489 | - key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1), |
490 | - "asymmetric", |
491 | - NULL, |
492 | - p, |
493 | - plen, |
494 | - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | |
495 | - KEY_USR_VIEW | KEY_USR_READ), |
496 | - KEY_ALLOC_NOT_IN_QUOTA | |
497 | - KEY_ALLOC_BUILT_IN | |
498 | - KEY_ALLOC_BYPASS_RESTRICTION); |
499 | - if (IS_ERR(key)) { |
500 | - pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", |
501 | - PTR_ERR(key)); |
502 | - WARN_ON_ONCE(1); |
503 | - } else { |
504 | - pr_notice("Loaded X.509 cert '%s'\n", |
505 | - key_ref_to_ptr(key)->description); |
506 | - key_ref_put(key); |
507 | - } |
508 | - p += plen; |
509 | - } |
510 | - |
511 | - return 0; |
512 | - |
513 | -dodgy_cert: |
514 | - pr_err("Problem parsing in-kernel X.509 certificate list\n"); |
515 | - return 0; |
516 | + return load_certificate_list(system_certificate_list, system_certificate_list_size, |
517 | + builtin_trusted_keys); |
518 | } |
519 | late_initcall(load_system_certificate_list); |
520 | |
521 | @@ -240,6 +196,13 @@ int verify_pkcs7_signature(const void *data, size_t len, |
522 | trusted_keys = builtin_trusted_keys; |
523 | #endif |
524 | } |
525 | + |
526 | + ret = is_key_on_revocation_list(pkcs7); |
527 | + if (ret != -ENOKEY) { |
528 | + pr_devel("PKCS#7 key is on revocation list\n"); |
529 | + goto error; |
530 | + } |
531 | + |
532 | ret = pkcs7_validate_trust(pkcs7, trusted_keys); |
533 | if (ret < 0) { |
534 | if (ret == -ENOKEY) |
535 | diff --git a/debian.master/config/annotations b/debian.master/config/annotations |
536 | index 8275667..ea24044 100644 |
537 | --- a/debian.master/config/annotations |
538 | +++ b/debian.master/config/annotations |
539 | @@ -502,6 +502,7 @@ CONFIG_SYSTEM_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': ' |
540 | CONFIG_SYSTEM_TRUSTED_KEYS policy<{'amd64': '"debian/canonical-certs.pem"', 'arm64': '"debian/canonical-certs.pem"', 'armhf': '"debian/canonical-certs.pem"', 'i386': '"debian/canonical-certs.pem"', 'ppc64el': '"debian/canonical-certs.pem"', 's390x': '"debian/canonical-certs.pem"'}> |
541 | CONFIG_SYSTEM_EXTRA_CERTIFICATE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> |
542 | CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'i386': '4096', 'ppc64el': '4096', 's390x': '4096'}> |
543 | +CONFIG_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"'}> |
544 | CONFIG_SECONDARY_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'i386': 'y', 'ppc64el': 'y', 's390x': 'y'}> |
545 | |
546 | # Menu: Cryptographic API >> Hardware crypto devices |
547 | diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu |
548 | index fba5bed..57190d6 100644 |
549 | --- a/debian.master/config/config.common.ubuntu |
550 | +++ b/debian.master/config/config.common.ubuntu |
551 | @@ -9018,6 +9018,8 @@ CONFIG_SYSTEM_BLACKLIST_KEYRING=y |
552 | CONFIG_SYSTEM_DATA_VERIFICATION=y |
553 | CONFIG_SYSTEM_EXTRA_CERTIFICATE=y |
554 | CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE=4096 |
555 | +CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem" |
556 | +CONFIG_SYSTEM_REVOCATION_LIST=y |
557 | CONFIG_SYSTEM_TRUSTED_KEYRING=y |
558 | CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem" |
559 | CONFIG_SYSVIPC=y |
560 | diff --git a/debian/revoked-certs/canonical-uefi-2012-all.pem b/debian/revoked-certs/canonical-uefi-2012-all.pem |
561 | new file mode 100644 |
562 | index 0000000..06c116e |
563 | --- /dev/null |
564 | +++ b/debian/revoked-certs/canonical-uefi-2012-all.pem |
565 | @@ -0,0 +1,86 @@ |
566 | +Certificate: |
567 | + Data: |
568 | + Version: 3 (0x2) |
569 | + Serial Number: 1 (0x1) |
570 | + Signature Algorithm: sha256WithRSAEncryption |
571 | + Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority |
572 | + Validity |
573 | + Not Before: Apr 12 11:39:08 2012 GMT |
574 | + Not After : Apr 11 11:39:08 2042 GMT |
575 | + Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing |
576 | + Subject Public Key Info: |
577 | + Public Key Algorithm: rsaEncryption |
578 | + RSA Public-Key: (2048 bit) |
579 | + Modulus: |
580 | + 00:c9:5f:9b:62:8f:0b:b0:64:82:ac:be:c9:e2:62: |
581 | + e3:4b:d2:9f:1e:8a:d5:61:1a:2b:5d:38:f4:b7:ce: |
582 | + b9:9a:b8:43:b8:43:97:77:ab:4f:7f:0c:70:46:0b: |
583 | + fc:7f:6d:c6:6d:ea:80:5e:01:d2:b7:66:1e:87:de: |
584 | + 0d:6d:d0:41:97:a8:a5:af:0c:63:4f:f7:7c:c2:52: |
585 | + cc:a0:31:a9:bb:89:5d:99:1e:46:6f:55:73:b9:76: |
586 | + 69:ec:d7:c1:fc:21:d6:c6:07:e7:4f:bd:22:de:e4: |
587 | + a8:5b:2d:db:95:34:19:97:d6:28:4b:21:4c:ca:bb: |
588 | + 1d:79:a6:17:7f:5a:f9:67:e6:5c:78:45:3d:10:6d: |
589 | + b0:17:59:26:11:c5:57:e3:7f:4e:82:ba:f6:2c:4e: |
590 | + c8:37:4d:ff:85:15:84:47:e0:ed:3b:7c:7f:bc:af: |
591 | + e9:01:05:a7:0c:6f:c3:e9:8d:a3:ce:be:a6:e3:cd: |
592 | + 3c:b5:58:2c:9e:c2:03:1c:60:22:37:39:ff:41:02: |
593 | + c1:29:a4:65:51:ff:33:34:aa:42:15:f9:95:78:fc: |
594 | + 2d:f5:da:8a:85:7c:82:9d:fb:37:2c:6b:a5:a8:df: |
595 | + 7c:55:0b:80:2e:3c:b0:63:e1:cd:38:48:89:e8:14: |
596 | + 06:0b:82:bc:fd:d4:07:68:1b:0f:3e:d9:15:dd:94: |
597 | + 11:1b |
598 | + Exponent: 65537 (0x10001) |
599 | + X509v3 extensions: |
600 | + X509v3 Basic Constraints: critical |
601 | + CA:FALSE |
602 | + X509v3 Extended Key Usage: |
603 | + Code Signing, 1.3.6.1.4.1.311.10.3.6 |
604 | + Netscape Comment: |
605 | + OpenSSL Generated Certificate |
606 | + X509v3 Subject Key Identifier: |
607 | + 61:48:2A:A2:83:0D:0A:B2:AD:5A:F1:0B:72:50:DA:90:33:DD:CE:F0 |
608 | + X509v3 Authority Key Identifier: |
609 | + keyid:AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63 |
610 | + |
611 | + Signature Algorithm: sha256WithRSAEncryption |
612 | + 8f:8a:a1:06:1f:29:b7:0a:4a:d5:c5:fd:81:ab:25:ea:c0:7d: |
613 | + e2:fc:6a:96:a0:79:93:67:ee:05:0e:25:12:25:e4:5a:f6:aa: |
614 | + 1a:f1:12:f3:05:8d:87:5e:f1:5a:5c:cb:8d:23:73:65:1d:15: |
615 | + b9:de:22:6b:d6:49:67:c9:a3:c6:d7:62:4e:5c:b5:f9:03:83: |
616 | + 40:81:dc:87:9c:3c:3f:1c:0d:51:9f:94:65:0a:84:48:67:e4: |
617 | + a2:f8:a6:4a:f0:e7:cd:cd:bd:94:e3:09:d2:5d:2d:16:1b:05: |
618 | + 15:0b:cb:44:b4:3e:61:42:22:c4:2a:5c:4e:c5:1d:a3:e2:e0: |
619 | + 52:b2:eb:f4:8b:2b:dc:38:39:5d:fb:88:a1:56:65:5f:2b:4f: |
620 | + 26:ff:06:78:10:12:eb:8c:5d:32:e3:c6:45:af:25:9b:a0:ff: |
621 | + 8e:ef:47:09:a3:e9:8b:37:92:92:69:76:7e:34:3b:92:05:67: |
622 | + 4e:b0:25:ed:bc:5e:5f:8f:b4:d6:ca:40:ff:e4:e2:31:23:0c: |
623 | + 85:25:ae:0c:55:01:ec:e5:47:5e:df:5b:bc:14:33:e3:c6:f5: |
624 | + 18:b6:d9:f7:dd:b3:b4:a1:31:d3:5a:5c:5d:7d:3e:bf:0a:e4: |
625 | + e4:e8:b4:59:7d:3b:b4:8c:a3:1b:b5:20:a3:b9:3e:84:6f:8c: |
626 | + 21:00:c3:39 |
627 | +-----BEGIN CERTIFICATE----- |
628 | +MIIEIDCCAwigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix |
629 | +FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK |
630 | +DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy |
631 | +IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMjA0MTIxMTM5MDhaFw00MjA0MTEx |
632 | +MTM5MDhaMH8xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEXMBUG |
633 | +A1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MSswKQYD |
634 | +VQQDDCJDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nMIIBIjANBgkq |
635 | +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyV+bYo8LsGSCrL7J4mLjS9KfHorVYRor |
636 | +XTj0t865mrhDuEOXd6tPfwxwRgv8f23GbeqAXgHSt2Yeh94NbdBBl6ilrwxjT/d8 |
637 | +wlLMoDGpu4ldmR5Gb1VzuXZp7NfB/CHWxgfnT70i3uSoWy3blTQZl9YoSyFMyrsd |
638 | +eaYXf1r5Z+ZceEU9EG2wF1kmEcVX439Ogrr2LE7IN03/hRWER+DtO3x/vK/pAQWn |
639 | +DG/D6Y2jzr6m4808tVgsnsIDHGAiNzn/QQLBKaRlUf8zNKpCFfmVePwt9dqKhXyC |
640 | +nfs3LGulqN98VQuALjywY+HNOEiJ6BQGC4K8/dQHaBsPPtkV3ZQRGwIDAQABo4Gg |
641 | +MIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUHAwMGCisGAQQBgjcK |
642 | +AwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl |
643 | +MB0GA1UdDgQWBBRhSCqigw0Ksq1a8QtyUNqQM93O8DAfBgNVHSMEGDAWgBStkZkL |
644 | +wiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEAj4qhBh8ptwpK1cX9 |
645 | +gasl6sB94vxqlqB5k2fuBQ4lEiXkWvaqGvES8wWNh17xWlzLjSNzZR0Vud4ia9ZJ |
646 | +Z8mjxtdiTly1+QODQIHch5w8PxwNUZ+UZQqESGfkovimSvDnzc29lOMJ0l0tFhsF |
647 | +FQvLRLQ+YUIixCpcTsUdo+LgUrLr9Isr3Dg5XfuIoVZlXytPJv8GeBAS64xdMuPG |
648 | +Ra8lm6D/ju9HCaPpizeSkml2fjQ7kgVnTrAl7bxeX4+01spA/+TiMSMMhSWuDFUB |
649 | +7OVHXt9bvBQz48b1GLbZ992ztKEx01pcXX0+vwrk5Oi0WX07tIyjG7Ugo7k+hG+M |
650 | +IQDDOQ== |
651 | +-----END CERTIFICATE----- |
652 | diff --git a/debian/rules b/debian/rules |
653 | index 73c0ee1..ca87ccf 100755 |
654 | --- a/debian/rules |
655 | +++ b/debian/rules |
656 | @@ -126,7 +126,7 @@ binary: binary-indep binary-arch |
657 | |
658 | build: build-arch build-indep |
659 | |
660 | -clean: debian/control debian/canonical-certs.pem |
661 | +clean: debian/control debian/canonical-certs.pem debian/canonical-revoked-certs.pem |
662 | dh_testdir |
663 | dh_testroot |
664 | dh_clean |
665 | @@ -222,3 +222,15 @@ debian/canonical-certs.pem: $(wildcard $(DROOT)/certs/*-all.pem) $(wildcard $(DR |
666 | fi; \ |
667 | done; \ |
668 | done >"$@" |
669 | + |
670 | +debian/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) |
671 | + for cert in $(sort $(notdir $^)); \ |
672 | + do \ |
673 | + for dir in $(DEBIAN) $(DROOT); \ |
674 | + do \ |
675 | + if [ -f "$$dir/revoked-certs/$$cert" ]; then \ |
676 | + cat "$$dir/revoked-certs/$$cert"; \ |
677 | + break; \ |
678 | + fi; \ |
679 | + done; \ |
680 | + done >"$@" |
681 | diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile |
682 | index f40f25c..2e52a34 100644 |
683 | --- a/drivers/firmware/efi/Makefile |
684 | +++ b/drivers/firmware/efi/Makefile |
685 | @@ -26,6 +26,7 @@ obj-$(CONFIG_EFI_TEST) += test/ |
686 | obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o |
687 | obj-$(CONFIG_EFI) += secureboot.o |
688 | obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o |
689 | +obj-$(CONFIG_LOAD_UEFI_KEYS) += mokvar-table.o |
690 | |
691 | arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o |
692 | obj-$(CONFIG_ARM) += $(arm-obj-y) |
693 | diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c |
694 | index 312f9f3..cd61e25 100644 |
695 | --- a/drivers/firmware/efi/arm-init.c |
696 | +++ b/drivers/firmware/efi/arm-init.c |
697 | @@ -259,6 +259,7 @@ void __init efi_init(void) |
698 | |
699 | reserve_regions(); |
700 | efi_esrt_init(); |
701 | + efi_mokvar_table_init(); |
702 | |
703 | memblock_reserve(params.mmap & PAGE_MASK, |
704 | PAGE_ALIGN(params.mmap_size + |
705 | diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c |
706 | index 9bf9e27..50cc4a6 100644 |
707 | --- a/drivers/firmware/efi/efi.c |
708 | +++ b/drivers/firmware/efi/efi.c |
709 | @@ -52,6 +52,9 @@ struct efi __read_mostly efi = { |
710 | .properties_table = EFI_INVALID_TABLE_ADDR, |
711 | .mem_attr_table = EFI_INVALID_TABLE_ADDR, |
712 | .rng_seed = EFI_INVALID_TABLE_ADDR, |
713 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
714 | + .mokvar_table = EFI_INVALID_TABLE_ADDR, |
715 | +#endif |
716 | }; |
717 | EXPORT_SYMBOL(efi); |
718 | |
719 | @@ -72,6 +75,9 @@ static unsigned long *efi_tables[] = { |
720 | &efi.esrt, |
721 | &efi.properties_table, |
722 | &efi.mem_attr_table, |
723 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
724 | + &efi.mokvar_table, |
725 | +#endif |
726 | }; |
727 | |
728 | static bool disable_runtime; |
729 | @@ -472,6 +478,9 @@ static __initdata efi_config_table_type_t common_tables[] = { |
730 | {EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table}, |
731 | {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table}, |
732 | {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed}, |
733 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
734 | + {LINUX_EFI_MOK_VARIABLE_TABLE_GUID, "MOKvar", &efi.mokvar_table}, |
735 | +#endif |
736 | {NULL_GUID, NULL, NULL}, |
737 | }; |
738 | |
739 | diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c |
740 | new file mode 100644 |
741 | index 0000000..38722d2 |
742 | --- /dev/null |
743 | +++ b/drivers/firmware/efi/mokvar-table.c |
744 | @@ -0,0 +1,362 @@ |
745 | +// SPDX-License-Identifier: GPL-2.0 |
746 | +/* |
747 | + * mokvar-table.c |
748 | + * |
749 | + * Copyright (c) 2020 Red Hat |
750 | + * Author: Lenny Szubowicz <lszubowi@redhat.com> |
751 | + * |
752 | + * This module contains the kernel support for the Linux EFI Machine |
753 | + * Owner Key (MOK) variable configuration table, which is identified by |
754 | + * the LINUX_EFI_MOK_VARIABLE_TABLE_GUID. |
755 | + * |
756 | + * This EFI configuration table provides a more robust alternative to |
757 | + * EFI volatile variables by which an EFI boot loader can pass the |
758 | + * contents of the Machine Owner Key (MOK) certificate stores to the |
759 | + * kernel during boot. If both the EFI MOK config table and corresponding |
760 | + * EFI MOK variables are present, the table should be considered as |
761 | + * more authoritative. |
762 | + * |
763 | + * This module includes code that validates and maps the EFI MOK table, |
764 | + * if it's presence was detected very early in boot. |
765 | + * |
766 | + * Kernel interface routines are provided to walk through all the |
767 | + * entries in the MOK config table or to search for a specific named |
768 | + * entry. |
769 | + * |
770 | + * The contents of the individual named MOK config table entries are |
771 | + * made available to user space via read-only sysfs binary files under: |
772 | + * |
773 | + * /sys/firmware/efi/mok-variables/ |
774 | + * |
775 | + */ |
776 | +#define pr_fmt(fmt) "mokvar: " fmt |
777 | + |
778 | +#include <linux/capability.h> |
779 | +#include <linux/efi.h> |
780 | +#include <linux/init.h> |
781 | +#include <linux/io.h> |
782 | +#include <linux/kernel.h> |
783 | +#include <linux/kobject.h> |
784 | +#include <linux/list.h> |
785 | +#include <linux/slab.h> |
786 | + |
787 | +#include <asm/early_ioremap.h> |
788 | + |
789 | +/* |
790 | + * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table is a packed |
791 | + * sequence of struct efi_mokvar_table_entry, one for each named |
792 | + * MOK variable. The sequence is terminated by an entry with a |
793 | + * completely NULL name and 0 data size. |
794 | + * |
795 | + * efi_mokvar_table_size is set to the computed size of the |
796 | + * MOK config table by efi_mokvar_table_init(). This will be |
797 | + * non-zero if and only if the table if present and has been |
798 | + * validated by efi_mokvar_table_init(). |
799 | + */ |
800 | +static size_t efi_mokvar_table_size; |
801 | + |
802 | +/* |
803 | + * efi_mokvar_table_va is the kernel virtual address at which the |
804 | + * EFI MOK config table has been mapped by efi_mokvar_sysfs_init(). |
805 | + */ |
806 | +static struct efi_mokvar_table_entry *efi_mokvar_table_va; |
807 | + |
808 | +/* |
809 | + * Each /sys/firmware/efi/mok-variables/ sysfs file is represented by |
810 | + * an instance of struct efi_mokvar_sysfs_attr on efi_mokvar_sysfs_list. |
811 | + * bin_attr.private points to the associated EFI MOK config table entry. |
812 | + * |
813 | + * This list is created during boot and then remains unchanged. |
814 | + * So no synchronization is currently required to walk the list. |
815 | + */ |
816 | +struct efi_mokvar_sysfs_attr { |
817 | + struct bin_attribute bin_attr; |
818 | + struct list_head node; |
819 | +}; |
820 | + |
821 | +static LIST_HEAD(efi_mokvar_sysfs_list); |
822 | +static struct kobject *mokvar_kobj; |
823 | + |
824 | +/* |
825 | + * efi_mokvar_table_init() - Early boot validation of EFI MOK config table |
826 | + * |
827 | + * If present, validate and compute the size of the EFI MOK variable |
828 | + * configuration table. This table may be provided by an EFI boot loader |
829 | + * as an alternative to ordinary EFI variables, due to platform-dependent |
830 | + * limitations. The memory occupied by this table is marked as reserved. |
831 | + * |
832 | + * This routine must be called before efi_free_boot_services() in order |
833 | + * to guarantee that it can mark the table as reserved. |
834 | + * |
835 | + * Implicit inputs: |
836 | + * efi.mokvar_table: Physical address of EFI MOK variable config table |
837 | + * or special value that indicates no such table. |
838 | + * |
839 | + * Implicit outputs: |
840 | + * efi_mokvar_table_size: Computed size of EFI MOK variable config table. |
841 | + * The table is considered present and valid if this |
842 | + * is non-zero. |
843 | + */ |
844 | +void __init efi_mokvar_table_init(void) |
845 | +{ |
846 | + efi_memory_desc_t md; |
847 | + void *va = NULL; |
848 | + unsigned long cur_offset = 0; |
849 | + unsigned long offset_limit; |
850 | + unsigned long map_size = 0; |
851 | + unsigned long map_size_needed = 0; |
852 | + unsigned long size; |
853 | + struct efi_mokvar_table_entry *mokvar_entry; |
854 | + int err; |
855 | + |
856 | + if (!efi_enabled(EFI_MEMMAP)) |
857 | + return; |
858 | + |
859 | + if (efi.mokvar_table == EFI_INVALID_TABLE_ADDR) |
860 | + return; |
861 | + /* |
862 | + * The EFI MOK config table must fit within a single EFI memory |
863 | + * descriptor range. |
864 | + */ |
865 | + err = efi_mem_desc_lookup(efi.mokvar_table, &md); |
866 | + if (err) { |
867 | + pr_warn("EFI MOKvar config table is not within the EFI memory map\n"); |
868 | + return; |
869 | + } |
870 | + |
871 | + offset_limit = efi_mem_desc_end(&md) - efi.mokvar_table; |
872 | + |
873 | + /* |
874 | + * Validate the MOK config table. Since there is no table header |
875 | + * from which we could get the total size of the MOK config table, |
876 | + * we compute the total size as we validate each variably sized |
877 | + * entry, remapping as necessary. |
878 | + */ |
879 | + err = -EINVAL; |
880 | + while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) { |
881 | + mokvar_entry = va + cur_offset; |
882 | + map_size_needed = cur_offset + sizeof(*mokvar_entry); |
883 | + if (map_size_needed > map_size) { |
884 | + if (va) |
885 | + early_memunmap(va, map_size); |
886 | + /* |
887 | + * Map a little more than the fixed size entry |
888 | + * header, anticipating some data. It's safe to |
889 | + * do so as long as we stay within current memory |
890 | + * descriptor. |
891 | + */ |
892 | + map_size = min(map_size_needed + 2*EFI_PAGE_SIZE, |
893 | + offset_limit); |
894 | + va = early_memremap(efi.mokvar_table, map_size); |
895 | + if (!va) { |
896 | + pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n", |
897 | + efi.mokvar_table, map_size); |
898 | + return; |
899 | + } |
900 | + mokvar_entry = va + cur_offset; |
901 | + } |
902 | + |
903 | + /* Check for last sentinel entry */ |
904 | + if (mokvar_entry->name[0] == '\0') { |
905 | + if (mokvar_entry->data_size != 0) |
906 | + break; |
907 | + err = 0; |
908 | + break; |
909 | + } |
910 | + |
911 | + /* Sanity check that the name is null terminated */ |
912 | + size = strnlen(mokvar_entry->name, |
913 | + sizeof(mokvar_entry->name)); |
914 | + if (size >= sizeof(mokvar_entry->name)) |
915 | + break; |
916 | + |
917 | + /* Advance to the next entry */ |
918 | + cur_offset = map_size_needed + mokvar_entry->data_size; |
919 | + } |
920 | + |
921 | + if (va) |
922 | + early_memunmap(va, map_size); |
923 | + if (err) { |
924 | + pr_err("EFI MOKvar config table is not valid\n"); |
925 | + return; |
926 | + } |
927 | + |
928 | + if (md.type == EFI_BOOT_SERVICES_DATA) |
929 | + efi_mem_reserve(efi.mokvar_table, map_size_needed); |
930 | + |
931 | + efi_mokvar_table_size = map_size_needed; |
932 | +} |
933 | + |
934 | +/* |
935 | + * efi_mokvar_entry_next() - Get next entry in the EFI MOK config table |
936 | + * |
937 | + * mokvar_entry: Pointer to current EFI MOK config table entry |
938 | + * or null. Null indicates get first entry. |
939 | + * Passed by reference. This is updated to the |
940 | + * same value as the return value. |
941 | + * |
942 | + * Returns: Pointer to next EFI MOK config table entry |
943 | + * or null, if there are no more entries. |
944 | + * Same value is returned in the mokvar_entry |
945 | + * parameter. |
946 | + * |
947 | + * This routine depends on the EFI MOK config table being entirely |
948 | + * mapped with it's starting virtual address in efi_mokvar_table_va. |
949 | + */ |
950 | +struct efi_mokvar_table_entry *efi_mokvar_entry_next( |
951 | + struct efi_mokvar_table_entry **mokvar_entry) |
952 | +{ |
953 | + struct efi_mokvar_table_entry *mokvar_cur; |
954 | + struct efi_mokvar_table_entry *mokvar_next; |
955 | + size_t size_cur; |
956 | + |
957 | + mokvar_cur = *mokvar_entry; |
958 | + *mokvar_entry = NULL; |
959 | + |
960 | + if (efi_mokvar_table_va == NULL) |
961 | + return NULL; |
962 | + |
963 | + if (mokvar_cur == NULL) { |
964 | + mokvar_next = efi_mokvar_table_va; |
965 | + } else { |
966 | + if (mokvar_cur->name[0] == '\0') |
967 | + return NULL; |
968 | + size_cur = sizeof(*mokvar_cur) + mokvar_cur->data_size; |
969 | + mokvar_next = (void *)mokvar_cur + size_cur; |
970 | + } |
971 | + |
972 | + if (mokvar_next->name[0] == '\0') |
973 | + return NULL; |
974 | + |
975 | + *mokvar_entry = mokvar_next; |
976 | + return mokvar_next; |
977 | +} |
978 | + |
979 | +/* |
980 | + * efi_mokvar_entry_find() - Find EFI MOK config entry by name |
981 | + * |
982 | + * name: Name of the entry to look for. |
983 | + * |
984 | + * Returns: Pointer to EFI MOK config table entry if found; |
985 | + * null otherwise. |
986 | + * |
987 | + * This routine depends on the EFI MOK config table being entirely |
988 | + * mapped with it's starting virtual address in efi_mokvar_table_va. |
989 | + */ |
990 | +struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name) |
991 | +{ |
992 | + struct efi_mokvar_table_entry *mokvar_entry = NULL; |
993 | + |
994 | + while (efi_mokvar_entry_next(&mokvar_entry)) { |
995 | + if (!strncmp(name, mokvar_entry->name, |
996 | + sizeof(mokvar_entry->name))) |
997 | + return mokvar_entry; |
998 | + } |
999 | + return NULL; |
1000 | +} |
1001 | + |
1002 | +/* |
1003 | + * efi_mokvar_sysfs_read() - sysfs binary file read routine |
1004 | + * |
1005 | + * Returns: Count of bytes read. |
1006 | + * |
1007 | + * Copy EFI MOK config table entry data for this mokvar sysfs binary file |
1008 | + * to the supplied buffer, starting at the specified offset into mokvar table |
1009 | + * entry data, for the specified count bytes. The copy is limited by the |
1010 | + * amount of data in this mokvar config table entry. |
1011 | + */ |
1012 | +static ssize_t efi_mokvar_sysfs_read(struct file *file, struct kobject *kobj, |
1013 | + struct bin_attribute *bin_attr, char *buf, |
1014 | + loff_t off, size_t count) |
1015 | +{ |
1016 | + struct efi_mokvar_table_entry *mokvar_entry = bin_attr->private; |
1017 | + |
1018 | + if (!capable(CAP_SYS_ADMIN)) |
1019 | + return 0; |
1020 | + |
1021 | + if (off >= mokvar_entry->data_size) |
1022 | + return 0; |
1023 | + if (count > mokvar_entry->data_size - off) |
1024 | + count = mokvar_entry->data_size - off; |
1025 | + |
1026 | + memcpy(buf, mokvar_entry->data + off, count); |
1027 | + return count; |
1028 | +} |
1029 | + |
1030 | +/* |
1031 | + * efi_mokvar_sysfs_init() - Map EFI MOK config table and create sysfs |
1032 | + * |
1033 | + * Map the EFI MOK variable config table for run-time use by the kernel |
1034 | + * and create the sysfs entries in /sys/firmware/efi/mok-variables/ |
1035 | + * |
1036 | + * This routine just returns if a valid EFI MOK variable config table |
1037 | + * was not found earlier during boot. |
1038 | + * |
1039 | + * This routine must be called during a "middle" initcall phase, i.e. |
1040 | + * after efi_mokvar_table_init() but before UEFI certs are loaded |
1041 | + * during late init. |
1042 | + * |
1043 | + * Implicit inputs: |
1044 | + * efi.mokvar_table: Physical address of EFI MOK variable config table |
1045 | + * or special value that indicates no such table. |
1046 | + * |
1047 | + * efi_mokvar_table_size: Computed size of EFI MOK variable config table. |
1048 | + * The table is considered present and valid if this |
1049 | + * is non-zero. |
1050 | + * |
1051 | + * Implicit outputs: |
1052 | + * efi_mokvar_table_va: Start virtual address of the EFI MOK config table. |
1053 | + */ |
1054 | +static int __init efi_mokvar_sysfs_init(void) |
1055 | +{ |
1056 | + void *config_va; |
1057 | + struct efi_mokvar_table_entry *mokvar_entry = NULL; |
1058 | + struct efi_mokvar_sysfs_attr *mokvar_sysfs = NULL; |
1059 | + int err = 0; |
1060 | + |
1061 | + if (efi_mokvar_table_size == 0) |
1062 | + return -ENOENT; |
1063 | + |
1064 | + config_va = memremap(efi.mokvar_table, efi_mokvar_table_size, |
1065 | + MEMREMAP_WB); |
1066 | + if (!config_va) { |
1067 | + pr_err("Failed to map EFI MOKvar config table\n"); |
1068 | + return -ENOMEM; |
1069 | + } |
1070 | + efi_mokvar_table_va = config_va; |
1071 | + |
1072 | + mokvar_kobj = kobject_create_and_add("mok-variables", efi_kobj); |
1073 | + if (!mokvar_kobj) { |
1074 | + pr_err("Failed to create EFI mok-variables sysfs entry\n"); |
1075 | + return -ENOMEM; |
1076 | + } |
1077 | + |
1078 | + while (efi_mokvar_entry_next(&mokvar_entry)) { |
1079 | + mokvar_sysfs = kzalloc(sizeof(*mokvar_sysfs), GFP_KERNEL); |
1080 | + if (!mokvar_sysfs) { |
1081 | + err = -ENOMEM; |
1082 | + break; |
1083 | + } |
1084 | + |
1085 | + sysfs_bin_attr_init(&mokvar_sysfs->bin_attr); |
1086 | + mokvar_sysfs->bin_attr.private = mokvar_entry; |
1087 | + mokvar_sysfs->bin_attr.attr.name = mokvar_entry->name; |
1088 | + mokvar_sysfs->bin_attr.attr.mode = 0400; |
1089 | + mokvar_sysfs->bin_attr.size = mokvar_entry->data_size; |
1090 | + mokvar_sysfs->bin_attr.read = efi_mokvar_sysfs_read; |
1091 | + |
1092 | + err = sysfs_create_bin_file(mokvar_kobj, |
1093 | + &mokvar_sysfs->bin_attr); |
1094 | + if (err) |
1095 | + break; |
1096 | + |
1097 | + list_add_tail(&mokvar_sysfs->node, &efi_mokvar_sysfs_list); |
1098 | + } |
1099 | + |
1100 | + if (err) { |
1101 | + pr_err("Failed to create some EFI mok-variables sysfs entries\n"); |
1102 | + kfree(mokvar_sysfs); |
1103 | + } |
1104 | + return err; |
1105 | +} |
1106 | +device_initcall(efi_mokvar_sysfs_init); |
1107 | diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h |
1108 | index 359c2f9..f961e88 100644 |
1109 | --- a/include/keys/system_keyring.h |
1110 | +++ b/include/keys/system_keyring.h |
1111 | @@ -35,6 +35,7 @@ extern int restrict_link_by_builtin_and_secondary_trusted( |
1112 | #define restrict_link_by_builtin_and_secondary_trusted restrict_link_by_builtin_trusted |
1113 | #endif |
1114 | |
1115 | +extern struct pkcs7_message *pkcs7; |
1116 | #ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING |
1117 | extern int mark_hash_blacklisted(const char *hash); |
1118 | extern int is_hash_blacklisted(const u8 *hash, size_t hash_len, |
1119 | @@ -47,6 +48,20 @@ static inline int is_hash_blacklisted(const u8 *hash, size_t hash_len, |
1120 | } |
1121 | #endif |
1122 | |
1123 | +#ifdef CONFIG_SYSTEM_REVOCATION_LIST |
1124 | +extern int add_key_to_revocation_list(const char *data, size_t size); |
1125 | +extern int is_key_on_revocation_list(struct pkcs7_message *pkcs7); |
1126 | +#else |
1127 | +static inline int add_key_to_revocation_list(const char *data, size_t size) |
1128 | +{ |
1129 | + return 0; |
1130 | +} |
1131 | +static inline int is_key_on_revocation_list(struct pkcs7_message *pkcs7) |
1132 | +{ |
1133 | + return -ENOKEY; |
1134 | +} |
1135 | +#endif |
1136 | + |
1137 | #ifdef CONFIG_IMA_BLACKLIST_KEYRING |
1138 | extern struct key *ima_blacklist_keyring; |
1139 | |
1140 | diff --git a/include/linux/efi.h b/include/linux/efi.h |
1141 | index 14590ff..a7192cd 100644 |
1142 | --- a/include/linux/efi.h |
1143 | +++ b/include/linux/efi.h |
1144 | @@ -641,6 +641,7 @@ void efi_native_runtime_setup(void); |
1145 | #define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) |
1146 | #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) |
1147 | #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) |
1148 | +#define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) |
1149 | |
1150 | typedef struct { |
1151 | efi_guid_t guid; |
1152 | @@ -936,6 +937,7 @@ extern struct efi { |
1153 | unsigned long properties_table; /* properties table */ |
1154 | unsigned long mem_attr_table; /* memory attributes table */ |
1155 | unsigned long rng_seed; /* UEFI firmware random seed */ |
1156 | + unsigned long mokvar_table; /* MOK variable config table */ |
1157 | efi_get_time_t *get_time; |
1158 | efi_set_time_t *set_time; |
1159 | efi_get_wakeup_time_t *get_wakeup_time; |
1160 | @@ -1650,4 +1652,36 @@ struct linux_efi_random_seed { |
1161 | u8 bits[]; |
1162 | }; |
1163 | |
1164 | +/* |
1165 | + * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table can be provided |
1166 | + * to the kernel by an EFI boot loader. The table contains a packed |
1167 | + * sequence of these entries, one for each named MOK variable. |
1168 | + * The sequence is terminated by an entry with a completely NULL |
1169 | + * name and 0 data size. |
1170 | + */ |
1171 | +struct efi_mokvar_table_entry { |
1172 | + char name[256]; |
1173 | + u64 data_size; |
1174 | + u8 data[]; |
1175 | +} __attribute((packed)); |
1176 | + |
1177 | +#ifdef CONFIG_LOAD_UEFI_KEYS |
1178 | +extern void __init efi_mokvar_table_init(void); |
1179 | +extern struct efi_mokvar_table_entry *efi_mokvar_entry_next( |
1180 | + struct efi_mokvar_table_entry **mokvar_entry); |
1181 | +extern struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name); |
1182 | +#else |
1183 | +static inline void efi_mokvar_table_init(void) { } |
1184 | +static inline struct efi_mokvar_table_entry *efi_mokvar_entry_next( |
1185 | + struct efi_mokvar_table_entry **mokvar_entry) |
1186 | +{ |
1187 | + return NULL; |
1188 | +} |
1189 | +static inline struct efi_mokvar_table_entry *efi_mokvar_entry_find( |
1190 | + const char *name) |
1191 | +{ |
1192 | + return NULL; |
1193 | +} |
1194 | +#endif |
1195 | + |
1196 | #endif /* _LINUX_EFI_H */ |
1197 | diff --git a/scripts/Makefile b/scripts/Makefile |
1198 | index fb82ada..47d0a97 100644 |
1199 | --- a/scripts/Makefile |
1200 | +++ b/scripts/Makefile |
1201 | @@ -22,6 +22,7 @@ hostprogs-$(CONFIG_ASN1) += asn1_compiler |
1202 | hostprogs-$(CONFIG_MODULE_SIG) += sign-file |
1203 | hostprogs-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += extract-cert |
1204 | hostprogs-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert |
1205 | +hostprogs-$(CONFIG_SYSTEM_REVOCATION_LIST) += extract-cert |
1206 | |
1207 | HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include |
1208 | HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include |