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