1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/kernel.h>
4 #include <linux/sched.h>
5 #include <linux/cred.h>
6 #include <linux/err.h>
7 #include <linux/efi.h>
8 #include <linux/slab.h>
9 #include <linux/ima.h>
10 #include <keys/asymmetric-type.h>
11 #include <keys/system_keyring.h>
12 #include "../integrity.h"
13 #include "keyring_handler.h"
14 
15 /*
16  * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
17  * it does.
18  *
19  * This UEFI variable is set by the shim if a user tells the shim to not use
20  * the certs/hashes in the UEFI db variable for verification purposes.  If it
21  * is set, we should ignore the db variable also and the true return indicates
22  * this.
23  */
24 static __init bool uefi_check_ignore_db(void)
25 {
26 	efi_status_t status;
27 	unsigned int db = 0;
28 	unsigned long size = sizeof(db);
29 	efi_guid_t guid = EFI_SHIM_LOCK_GUID;
30 
31 	status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
32 	return status == EFI_SUCCESS;
33 }
34 
35 /*
36  * Get a certificate list blob from the named EFI variable.
37  */
38 static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
39 				  unsigned long *size, efi_status_t *status)
40 {
41 	unsigned long lsize = 4;
42 	unsigned long tmpdb[4];
43 	void *db;
44 
45 	*status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
46 	if (*status == EFI_NOT_FOUND)
47 		return NULL;
48 
49 	if (*status != EFI_BUFFER_TOO_SMALL) {
50 		pr_err("Couldn't get size: 0x%lx\n", *status);
51 		return NULL;
52 	}
53 
54 	db = kmalloc(lsize, GFP_KERNEL);
55 	if (!db)
56 		return NULL;
57 
58 	*status = efi.get_variable(name, guid, NULL, &lsize, db);
59 	if (*status != EFI_SUCCESS) {
60 		kfree(db);
61 		pr_err("Error reading db var: 0x%lx\n", *status);
62 		return NULL;
63 	}
64 
65 	*size = lsize;
66 	return db;
67 }
68 
69 /*
70  * load_moklist_certs() - Load MokList certs
71  *
72  * Load the certs contained in the UEFI MokListRT database into the
73  * platform trusted keyring.
74  *
75  * This routine checks the EFI MOK config table first. If and only if
76  * that fails, this routine uses the MokListRT ordinary UEFI variable.
77  *
78  * Return:	Status
79  */
80 static int __init load_moklist_certs(void)
81 {
82 	struct efi_mokvar_table_entry *mokvar_entry;
83 	efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
84 	void *mok;
85 	unsigned long moksize;
86 	efi_status_t status;
87 	int rc;
88 
89 	/* First try to load certs from the EFI MOKvar config table.
90 	 * It's not an error if the MOKvar config table doesn't exist
91 	 * or the MokListRT entry is not found in it.
92 	 */
93 	mokvar_entry = efi_mokvar_entry_find("MokListRT");
94 	if (mokvar_entry) {
95 		rc = parse_efi_signature_list("UEFI:MokListRT (MOKvar table)",
96 					      mokvar_entry->data,
97 					      mokvar_entry->data_size,
98 					      get_handler_for_db);
99 		/* All done if that worked. */
100 		if (!rc)
101 			return rc;
102 
103 		pr_err("Couldn't parse MokListRT signatures from EFI MOKvar config table: %d\n",
104 		       rc);
105 	}
106 
107 	/* Get MokListRT. It might not exist, so it isn't an error
108 	 * if we can't get it.
109 	 */
110 	mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status);
111 	if (mok) {
112 		rc = parse_efi_signature_list("UEFI:MokListRT",
113 					      mok, moksize, get_handler_for_db);
114 		kfree(mok);
115 		if (rc)
116 			pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
117 		return rc;
118 	}
119 	if (status == EFI_NOT_FOUND)
120 		pr_debug("MokListRT variable wasn't found\n");
121 	else
122 		pr_info("Couldn't get UEFI MokListRT\n");
123 	return 0;
124 }
125 
126 /*
127  * load_uefi_certs() - Load certs from UEFI sources
128  *
129  * Load the certs contained in the UEFI databases into the platform trusted
130  * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
131  * keyring.
132  */
133 static int __init load_uefi_certs(void)
134 {
135 	efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
136 	efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
137 	void *db = NULL, *dbx = NULL, *mokx = NULL;
138 	unsigned long dbsize = 0, dbxsize = 0, mokxsize = 0;
139 	efi_status_t status;
140 	int rc = 0;
141 
142 	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
143 		return false;
144 
145 	/* Get db and dbx.  They might not exist, so it isn't an error
146 	 * if we can't get them.
147 	 */
148 	if (!uefi_check_ignore_db()) {
149 		db = get_cert_list(L"db", &secure_var, &dbsize, &status);
150 		if (!db) {
151 			if (status == EFI_NOT_FOUND)
152 				pr_debug("MODSIGN: db variable wasn't found\n");
153 			else
154 				pr_err("MODSIGN: Couldn't get UEFI db list\n");
155 		} else {
156 			rc = parse_efi_signature_list("UEFI:db",
157 					db, dbsize, get_handler_for_db);
158 			if (rc)
159 				pr_err("Couldn't parse db signatures: %d\n",
160 				       rc);
161 			kfree(db);
162 		}
163 	}
164 
165 	dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status);
166 	if (!dbx) {
167 		if (status == EFI_NOT_FOUND)
168 			pr_debug("dbx variable wasn't found\n");
169 		else
170 			pr_info("Couldn't get UEFI dbx list\n");
171 	} else {
172 		rc = parse_efi_signature_list("UEFI:dbx",
173 					      dbx, dbxsize,
174 					      get_handler_for_dbx);
175 		if (rc)
176 			pr_err("Couldn't parse dbx signatures: %d\n", rc);
177 		kfree(dbx);
178 	}
179 
180 	/* the MOK/MOKx can not be trusted when secure boot is disabled */
181 	if (!arch_ima_get_secureboot())
182 		return 0;
183 
184 	mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status);
185 	if (!mokx) {
186 		if (status == EFI_NOT_FOUND)
187 			pr_debug("mokx variable wasn't found\n");
188 		else
189 			pr_info("Couldn't get mokx list\n");
190 	} else {
191 		rc = parse_efi_signature_list("UEFI:MokListXRT",
192 					      mokx, mokxsize,
193 					      get_handler_for_dbx);
194 		if (rc)
195 			pr_err("Couldn't parse mokx signatures %d\n", rc);
196 		kfree(mokx);
197 	}
198 
199 	/* Load the MokListRT certs */
200 	rc = load_moklist_certs();
201 
202 	return rc;
203 }
204 late_initcall(load_uefi_certs);
205