1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/kernel.h>
4 #include <linux/sched.h>
5 #include <linux/cred.h>
8 #include <linux/slab.h>
9 #include <keys/asymmetric-type.h>
10 #include <keys/system_keyring.h>
11 #include "../integrity.h"
12 #include "keyring_handler.h"
15 * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
18 * This UEFI variable is set by the shim if a user tells the shim to not use
19 * the certs/hashes in the UEFI db variable for verification purposes. If it
20 * is set, we should ignore the db variable also and the true return indicates
23 static __init
bool uefi_check_ignore_db(void)
27 unsigned long size
= sizeof(db
);
28 efi_guid_t guid
= EFI_SHIM_LOCK_GUID
;
30 status
= efi
.get_variable(L
"MokIgnoreDB", &guid
, NULL
, &size
, &db
);
31 return status
== EFI_SUCCESS
;
35 * Get a certificate list blob from the named EFI variable.
37 static __init
void *get_cert_list(efi_char16_t
*name
, efi_guid_t
*guid
,
38 unsigned long *size
, efi_status_t
*status
)
40 unsigned long lsize
= 4;
41 unsigned long tmpdb
[4];
44 *status
= efi
.get_variable(name
, guid
, NULL
, &lsize
, &tmpdb
);
45 if (*status
== EFI_NOT_FOUND
)
48 if (*status
!= EFI_BUFFER_TOO_SMALL
) {
49 pr_err("Couldn't get size: 0x%lx\n", *status
);
53 db
= kmalloc(lsize
, GFP_KERNEL
);
57 *status
= efi
.get_variable(name
, guid
, NULL
, &lsize
, db
);
58 if (*status
!= EFI_SUCCESS
) {
60 pr_err("Error reading db var: 0x%lx\n", *status
);
69 * load_moklist_certs() - Load MokList certs
71 * Load the certs contained in the UEFI MokListRT database into the
72 * platform trusted keyring.
74 * This routine checks the EFI MOK config table first. If and only if
75 * that fails, this routine uses the MokListRT ordinary UEFI variable.
79 static int __init
load_moklist_certs(void)
81 struct efi_mokvar_table_entry
*mokvar_entry
;
82 efi_guid_t mok_var
= EFI_SHIM_LOCK_GUID
;
84 unsigned long moksize
;
88 /* First try to load certs from the EFI MOKvar config table.
89 * It's not an error if the MOKvar config table doesn't exist
90 * or the MokListRT entry is not found in it.
92 mokvar_entry
= efi_mokvar_entry_find("MokListRT");
94 rc
= parse_efi_signature_list("UEFI:MokListRT (MOKvar table)",
96 mokvar_entry
->data_size
,
98 /* All done if that worked. */
102 pr_err("Couldn't parse MokListRT signatures from EFI MOKvar config table: %d\n",
106 /* Get MokListRT. It might not exist, so it isn't an error
107 * if we can't get it.
109 mok
= get_cert_list(L
"MokListRT", &mok_var
, &moksize
, &status
);
111 rc
= parse_efi_signature_list("UEFI:MokListRT",
112 mok
, moksize
, get_handler_for_db
);
115 pr_err("Couldn't parse MokListRT signatures: %d\n", rc
);
118 if (status
== EFI_NOT_FOUND
)
119 pr_debug("MokListRT variable wasn't found\n");
121 pr_info("Couldn't get UEFI MokListRT\n");
126 * load_uefi_certs() - Load certs from UEFI sources
128 * Load the certs contained in the UEFI databases into the platform trusted
129 * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
132 static int __init
load_uefi_certs(void)
134 efi_guid_t secure_var
= EFI_IMAGE_SECURITY_DATABASE_GUID
;
135 void *db
= NULL
, *dbx
= NULL
;
136 unsigned long dbsize
= 0, dbxsize
= 0;
140 if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE
))
143 /* Get db and dbx. They might not exist, so it isn't an error
144 * if we can't get them.
146 if (!uefi_check_ignore_db()) {
147 db
= get_cert_list(L
"db", &secure_var
, &dbsize
, &status
);
149 if (status
== EFI_NOT_FOUND
)
150 pr_debug("MODSIGN: db variable wasn't found\n");
152 pr_err("MODSIGN: Couldn't get UEFI db list\n");
154 rc
= parse_efi_signature_list("UEFI:db",
155 db
, dbsize
, get_handler_for_db
);
157 pr_err("Couldn't parse db signatures: %d\n",
163 dbx
= get_cert_list(L
"dbx", &secure_var
, &dbxsize
, &status
);
165 if (status
== EFI_NOT_FOUND
)
166 pr_debug("dbx variable wasn't found\n");
168 pr_info("Couldn't get UEFI dbx list\n");
170 rc
= parse_efi_signature_list("UEFI:dbx",
172 get_handler_for_dbx
);
174 pr_err("Couldn't parse dbx signatures: %d\n", rc
);
178 /* Load the MokListRT certs */
179 rc
= load_moklist_certs();
183 late_initcall(load_uefi_certs
);