fb10477
From cff9d37c9529fca5ff853f0050c7f0de0e819ea7 Mon Sep 17 00:00:00 2001
fb10477
From: Dave Howells <dhowells@redhat.com>
fb10477
Date: Tue, 23 Oct 2012 09:30:54 -0400
fb10477
Subject: [PATCH 1/4] Add EFI signature data types
fb10477
fb10477
Add the data types that are used for containing hashes, keys and certificates
fb10477
for cryptographic verification.
fb10477
fb10477
Signed-off-by: David Howells <dhowells@redhat.com>
fb10477
---
fb10477
 include/linux/efi.h | 20 ++++++++++++++++++++
fb10477
 1 file changed, 20 insertions(+)
fb10477
fb10477
diff --git a/include/linux/efi.h b/include/linux/efi.h
fb10477
index eed2202..1da1b3c 100644
fb10477
--- a/include/linux/efi.h
fb10477
+++ b/include/linux/efi.h
fb10477
@@ -389,6 +389,12 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long si
fb10477
 #define EFI_FILE_SYSTEM_GUID \
fb10477
     EFI_GUID(  0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
fb10477
 
fb10477
+#define EFI_CERT_SHA256_GUID \
fb10477
+    EFI_GUID(  0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 )
fb10477
+
fb10477
+#define EFI_CERT_X509_GUID \
fb10477
+    EFI_GUID(  0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 )
fb10477
+
fb10477
 typedef struct {
fb10477
 	efi_guid_t guid;
fb10477
 	u64 table;
fb10477
@@ -524,6 +530,20 @@ typedef struct {
fb10477
 
fb10477
 #define EFI_INVALID_TABLE_ADDR		(~0UL)
fb10477
 
fb10477
+typedef struct  {
fb10477
+	efi_guid_t signature_owner;
fb10477
+	u8 signature_data[];
fb10477
+} efi_signature_data_t;
fb10477
+
fb10477
+typedef struct {
fb10477
+	efi_guid_t signature_type;
fb10477
+	u32 signature_list_size;
fb10477
+	u32 signature_header_size;
fb10477
+	u32 signature_size;
fb10477
+	u8 signature_header[];
fb10477
+	/* efi_signature_data_t signatures[][] */
fb10477
+} efi_signature_list_t;
fb10477
+
fb10477
 /*
fb10477
  * All runtime access to EFI goes through this structure:
fb10477
  */
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
fb10477
From 2ce1c1d0d7110c4b06d65e4c8506f6c54aa72628 Mon Sep 17 00:00:00 2001
fb10477
From: Dave Howells <dhowells@redhat.com>
fb10477
Date: Tue, 23 Oct 2012 09:36:28 -0400
fb10477
Subject: [PATCH 2/4] Add an EFI signature blob parser and key loader.
fb10477
fb10477
X.509 certificates are loaded into the specified keyring as asymmetric type
fb10477
keys.
fb10477
fb10477
Signed-off-by: David Howells <dhowells@redhat.com>
fb10477
---
fb10477
 crypto/asymmetric_keys/Kconfig      |   8 +++
fb10477
 crypto/asymmetric_keys/Makefile     |   1 +
fb10477
 crypto/asymmetric_keys/efi_parser.c | 108 ++++++++++++++++++++++++++++++++++++
fb10477
 include/linux/efi.h                 |   4 ++
fb10477
 4 files changed, 121 insertions(+)
fb10477
 create mode 100644 crypto/asymmetric_keys/efi_parser.c
fb10477
fb10477
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
fb10477
index 6d2c2ea..ace9c30 100644
fb10477
--- a/crypto/asymmetric_keys/Kconfig
fb10477
+++ b/crypto/asymmetric_keys/Kconfig
fb10477
@@ -35,4 +35,12 @@ config X509_CERTIFICATE_PARSER
fb10477
 	  data and provides the ability to instantiate a crypto key from a
fb10477
 	  public key packet found inside the certificate.
fb10477
 
fb10477
+config EFI_SIGNATURE_LIST_PARSER
fb10477
+	bool "EFI signature list parser"
fb10477
+	depends on EFI
fb10477
+	select X509_CERTIFICATE_PARSER
fb10477
+	help
fb10477
+	  This option provides support for parsing EFI signature lists for
fb10477
+	  X.509 certificates and turning them into keys.
fb10477
+
fb10477
 endif # ASYMMETRIC_KEY_TYPE
fb10477
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
fb10477
index 0727204..cd8388e 100644
fb10477
--- a/crypto/asymmetric_keys/Makefile
fb10477
+++ b/crypto/asymmetric_keys/Makefile
fb10477
@@ -8,6 +8,7 @@ asymmetric_keys-y := asymmetric_type.o signature.o
fb10477
 
fb10477
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
fb10477
 obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
fb10477
+obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
fb10477
 
fb10477
 #
fb10477
 # X.509 Certificate handling
fb10477
diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c
fb10477
new file mode 100644
fb10477
index 0000000..636feb1
fb10477
--- /dev/null
fb10477
+++ b/crypto/asymmetric_keys/efi_parser.c
fb10477
@@ -0,0 +1,108 @@
fb10477
+/* EFI signature/key/certificate list parser
fb10477
+ *
fb10477
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
fb10477
+ * Written by David Howells (dhowells@redhat.com)
fb10477
+ *
fb10477
+ * This program is free software; you can redistribute it and/or
fb10477
+ * modify it under the terms of the GNU General Public Licence
fb10477
+ * as published by the Free Software Foundation; either version
fb10477
+ * 2 of the Licence, or (at your option) any later version.
fb10477
+ */
fb10477
+
fb10477
+#define pr_fmt(fmt) "EFI: "fmt
fb10477
+#include <linux/module.h>
fb10477
+#include <linux/printk.h>
fb10477
+#include <linux/err.h>
fb10477
+#include <linux/efi.h>
fb10477
+#include <keys/asymmetric-type.h>
fb10477
+
fb10477
+static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
fb10477
+
fb10477
+/**
fb10477
+ * parse_efi_signature_list - Parse an EFI signature list for certificates
fb10477
+ * @data: The data blob to parse
fb10477
+ * @size: The size of the data blob
fb10477
+ * @keyring: The keyring to add extracted keys to
fb10477
+ */
fb10477
+int __init parse_efi_signature_list(const void *data, size_t size, struct key *keyring)
fb10477
+{
fb10477
+	unsigned offs = 0;
fb10477
+	size_t lsize, esize, hsize, elsize;
fb10477
+
fb10477
+	pr_devel("-->%s(,%zu)\n", __func__, size);
fb10477
+
fb10477
+	while (size > 0) {
fb10477
+		efi_signature_list_t list;
fb10477
+		const efi_signature_data_t *elem;
fb10477
+		key_ref_t key;
fb10477
+
fb10477
+		if (size < sizeof(list))
fb10477
+			return -EBADMSG;
fb10477
+
fb10477
+		memcpy(&list, data, sizeof(list));
fb10477
+		pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n",
fb10477
+			 offs,
fb10477
+			 list.signature_type.b, list.signature_list_size,
fb10477
+			 list.signature_header_size, list.signature_size);
fb10477
+
fb10477
+		lsize = list.signature_list_size;
fb10477
+		hsize = list.signature_header_size;
fb10477
+		esize = list.signature_size;
fb10477
+		elsize = lsize - sizeof(list) - hsize;
fb10477
+
fb10477
+		if (lsize > size) {
fb10477
+			pr_devel("<--%s() = -EBADMSG [overrun @%x]\n",
fb10477
+				 __func__, offs);
fb10477
+			return -EBADMSG;
fb10477
+		}
fb10477
+		if (lsize < sizeof(list) ||
fb10477
+		    lsize - sizeof(list) < hsize ||
fb10477
+		    esize < sizeof(*elem) ||
fb10477
+		    elsize < esize ||
fb10477
+		    elsize % esize != 0) {
fb10477
+			pr_devel("- bad size combo @%x\n", offs);
fb10477
+			return -EBADMSG;
fb10477
+		}
fb10477
+
fb10477
+		if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) {
fb10477
+			data += lsize;
fb10477
+			size -= lsize;
fb10477
+			offs += lsize;
fb10477
+			continue;
fb10477
+		}
fb10477
+
fb10477
+		data += sizeof(list) + hsize;
fb10477
+		size -= sizeof(list) + hsize;
fb10477
+		offs += sizeof(list) + hsize;
fb10477
+
fb10477
+		for (; elsize > 0; elsize -= esize) {
fb10477
+			elem = data;
fb10477
+
fb10477
+			pr_devel("ELEM[%04x]\n", offs);
fb10477
+
fb10477
+			key = key_create_or_update(
fb10477
+				make_key_ref(keyring, 1),
fb10477
+				"asymmetric",
fb10477
+				NULL,
fb10477
+				&elem->signature_data,
fb10477
+				esize - sizeof(*elem),
fb10477
+				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
fb10477
+				KEY_USR_VIEW,
fb10477
+				KEY_ALLOC_NOT_IN_QUOTA);
fb10477
+
fb10477
+			if (IS_ERR(key))
fb10477
+				pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
fb10477
+				       PTR_ERR(key));
fb10477
+			else
fb10477
+				pr_notice("Loaded cert '%s' linked to '%s'\n",
fb10477
+					  key_ref_to_ptr(key)->description,
fb10477
+					  keyring->description);
fb10477
+
fb10477
+			data += esize;
fb10477
+			size -= esize;
fb10477
+			offs += esize;
fb10477
+		}
fb10477
+	}
fb10477
+
fb10477
+	return 0;
fb10477
+}
fb10477
diff --git a/include/linux/efi.h b/include/linux/efi.h
fb10477
index 1da1b3c..42a1d25 100644
fb10477
--- a/include/linux/efi.h
fb10477
+++ b/include/linux/efi.h
fb10477
@@ -619,6 +619,10 @@ extern int efi_set_rtc_mmss(const struct timespec *now);
fb10477
 extern void efi_reserve_boot_services(void);
fb10477
 extern struct efi_memory_map memmap;
fb10477
 
fb10477
+struct key;
fb10477
+extern int __init parse_efi_signature_list(const void *data, size_t size,
fb10477
+					   struct key *keyring);
fb10477
+
fb10477
 /**
fb10477
  * efi_range_is_wc - check the WC bit on an address range
fb10477
  * @start: starting kvirt address
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
fb10477
From 0e4e8acfd0932bbf6b02112218092c810d9469a5 Mon Sep 17 00:00:00 2001
fb10477
From: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
Date: Fri, 26 Oct 2012 12:36:24 -0400
fb10477
Subject: [PATCH 3/4] MODSIGN: Add module certificate blacklist keyring
fb10477
fb10477
This adds an additional keyring that is used to store certificates that
fb10477
are blacklisted.  This keyring is searched first when loading signed modules
fb10477
and if the module's certificate is found, it will refuse to load.  This is
fb10477
useful in cases where third party certificates are used for module signing.
fb10477
fb10477
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
---
fb10477
 init/Kconfig             |  8 ++++++++
fb10477
 kernel/modsign_pubkey.c  | 14 ++++++++++++++
fb10477
 kernel/module-internal.h |  3 +++
fb10477
 kernel/module_signing.c  | 12 ++++++++++++
fb10477
 4 files changed, 37 insertions(+)
fb10477
fb10477
diff --git a/init/Kconfig b/init/Kconfig
fb10477
index fed81b5..b4fa2d1 100644
fb10477
--- a/init/Kconfig
fb10477
+++ b/init/Kconfig
fb10477
@@ -1772,6 +1772,14 @@ config MODULE_SIG_ALL
fb10477
 comment "Do not forget to sign required modules with scripts/sign-file"
fb10477
 	depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
fb10477
 
fb10477
+config MODULE_SIG_BLACKLIST
fb10477
+	bool "Support for blacklisting module signature certificates"
fb10477
+	depends on MODULE_SIG
fb10477
+	help
fb10477
+	  This adds support for keeping a blacklist of certificates that
fb10477
+	  should not pass module signature verification.  If a module is
fb10477
+	  signed with something in this keyring, the load will be rejected.
fb10477
+
fb10477
 choice
fb10477
 	prompt "Which hash algorithm should modules be signed with?"
fb10477
 	depends on MODULE_SIG
fb10477
diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
fb10477
index 2b6e699..4cd408d 100644
fb10477
--- a/kernel/modsign_pubkey.c
fb10477
+++ b/kernel/modsign_pubkey.c
fb10477
@@ -17,6 +17,9 @@
fb10477
 #include "module-internal.h"
fb10477
 
fb10477
 struct key *modsign_keyring;
fb10477
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
fb10477
+struct key *modsign_blacklist;
fb10477
+#endif
fb10477
 
fb10477
 extern __initdata const u8 modsign_certificate_list[];
fb10477
 extern __initdata const u8 modsign_certificate_list_end[];
fb10477
@@ -43,6 +46,17 @@ static __init int module_verify_init(void)
fb10477
 	if (IS_ERR(modsign_keyring))
fb10477
 		panic("Can't allocate module signing keyring\n");
fb10477
 
fb10477
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
fb10477
+	modsign_blacklist = keyring_alloc(".modsign_blacklist",
fb10477
+				    KUIDT_INIT(0), KGIDT_INIT(0),
fb10477
+				    current_cred(),
fb10477
+				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
fb10477
+				    KEY_USR_VIEW | KEY_USR_READ,
fb10477
+				    KEY_ALLOC_NOT_IN_QUOTA, NULL);
fb10477
+	if (IS_ERR(modsign_blacklist))
fb10477
+		panic("Can't allocate module signing blacklist keyring\n");
fb10477
+#endif
fb10477
+
fb10477
 	return 0;
fb10477
 }
fb10477
 
fb10477
diff --git a/kernel/module-internal.h b/kernel/module-internal.h
fb10477
index 24f9247..51a8380 100644
fb10477
--- a/kernel/module-internal.h
fb10477
+++ b/kernel/module-internal.h
fb10477
@@ -10,5 +10,8 @@
fb10477
  */
fb10477
 
fb10477
 extern struct key *modsign_keyring;
fb10477
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
fb10477
+extern struct key *modsign_blacklist;
fb10477
+#endif
fb10477
 
fb10477
 extern int mod_verify_sig(const void *mod, unsigned long *_modlen);
fb10477
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
fb10477
index f2970bd..5423195 100644
fb10477
--- a/kernel/module_signing.c
fb10477
+++ b/kernel/module_signing.c
fb10477
@@ -157,6 +157,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
fb10477
 
fb10477
 	pr_debug("Look up: \"%s\"\n", id);
fb10477
 
fb10477
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
fb10477
+	key = keyring_search(make_key_ref(modsign_blacklist, 1),
fb10477
+				   &key_type_asymmetric, id);
fb10477
+	if (!IS_ERR(key)) {
fb10477
+		/* module is signed with a cert in the blacklist.  reject */
fb10477
+		pr_err("Module key '%s' is in blacklist\n", id);
fb10477
+		key_ref_put(key);
fb10477
+		kfree(id);
fb10477
+		return ERR_PTR(-EKEYREJECTED);
fb10477
+	}
fb10477
+#endif
fb10477
+
fb10477
 	key = keyring_search(make_key_ref(modsign_keyring, 1),
fb10477
 			     &key_type_asymmetric, id);
fb10477
 	if (IS_ERR(key))
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
fb10477
From c558b46370e850851a94795df67b7c57aecc48ea Mon Sep 17 00:00:00 2001
fb10477
From: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
Date: Fri, 26 Oct 2012 12:42:16 -0400
fb10477
Subject: [PATCH 4/4] MODSIGN: Import certificates from UEFI Secure Boot
fb10477
fb10477
Secure Boot stores a list of allowed certificates in the 'db' variable.
fb10477
This imports those certificates into the module signing keyring.  This
fb10477
allows for a third party signing certificate to be used in conjunction
fb10477
with signed modules.  By importing the public certificate into the 'db'
fb10477
variable, a user can allow a module signed with that certificate to
fb10477
load.  The shim UEFI bootloader has a similar certificate list stored
fb10477
in the 'MokListRT' variable.  We import those as well.
fb10477
fb10477
In the opposite case, Secure Boot maintains a list of disallowed
fb10477
certificates in the 'dbx' variable.  We load those certificates into
fb10477
the newly introduced module blacklist keyring and forbid any module
fb10477
signed with those from loading.
fb10477
fb10477
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
---
fb10477
 include/linux/efi.h   |  6 ++++
fb10477
 init/Kconfig          |  9 +++++
fb10477
 kernel/Makefile       |  3 ++
fb10477
 kernel/modsign_uefi.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
fb10477
 4 files changed, 109 insertions(+)
fb10477
 create mode 100644 kernel/modsign_uefi.c
fb10477
fb10477
diff --git a/include/linux/efi.h b/include/linux/efi.h
fb10477
index 42a1d25..d3e6036 100644
fb10477
--- a/include/linux/efi.h
fb10477
+++ b/include/linux/efi.h
fb10477
@@ -395,6 +395,12 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long si
fb10477
 #define EFI_CERT_X509_GUID \
fb10477
     EFI_GUID(  0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 )
fb10477
 
fb10477
+#define EFI_IMAGE_SECURITY_DATABASE_GUID \
fb10477
+    EFI_GUID(  0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f )
fb10477
+
fb10477
+#define EFI_SHIM_LOCK_GUID \
fb10477
+    EFI_GUID(  0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 )
fb10477
+
fb10477
 typedef struct {
fb10477
 	efi_guid_t guid;
fb10477
 	u64 table;
fb10477
diff --git a/init/Kconfig b/init/Kconfig
fb10477
index b4fa2d1..94ce526 100644
fb10477
--- a/init/Kconfig
fb10477
+++ b/init/Kconfig
fb10477
@@ -1780,6 +1780,15 @@ config MODULE_SIG_BLACKLIST
fb10477
 	  should not pass module signature verification.  If a module is
fb10477
 	  signed with something in this keyring, the load will be rejected.
fb10477
 
fb10477
+config MODULE_SIG_UEFI
fb10477
+	bool "Allow modules signed with certs stored in UEFI"
fb10477
+	depends on MODULE_SIG && MODULE_SIG_BLACKLIST && EFI
fb10477
+	select EFI_SIGNATURE_LIST_PARSER
fb10477
+	help
fb10477
+	  This will import certificates stored in UEFI and allow modules
fb10477
+	  signed with those to be loaded.  It will also disallow loading
fb10477
+	  of modules stored in the UEFI dbx variable.
fb10477
+
fb10477
 choice
fb10477
 	prompt "Which hash algorithm should modules be signed with?"
fb10477
 	depends on MODULE_SIG
fb10477
diff --git a/kernel/Makefile b/kernel/Makefile
fb10477
index 35ef118..6ca1fea 100644
fb10477
--- a/kernel/Makefile
fb10477
+++ b/kernel/Makefile
fb10477
@@ -55,6 +55,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
fb10477
 obj-$(CONFIG_UID16) += uid16.o
fb10477
 obj-$(CONFIG_MODULES) += module.o
fb10477
 obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o
fb10477
+obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o
fb10477
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
fb10477
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
fb10477
 obj-$(CONFIG_KEXEC) += kexec.o
fb10477
@@ -114,6 +115,8 @@ obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
fb10477
 
fb10477
 $(obj)/configs.o: $(obj)/config_data.h
fb10477
 
fb10477
+$(obj)/modsign_uefi.o: KBUILD_CFLAGS += -fshort-wchar
fb10477
+
fb10477
 # config_data.h contains the same information as ikconfig.h but gzipped.
fb10477
 # Info from config_data can be extracted from /proc/config*
fb10477
 targets += config_data.gz
fb10477
diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c
fb10477
new file mode 100644
fb10477
index 0000000..7eae5b4
fb10477
--- /dev/null
fb10477
+++ b/kernel/modsign_uefi.c
fb10477
@@ -0,0 +1,91 @@
fb10477
+#include <linux/kernel.h>
fb10477
+#include <linux/sched.h>
fb10477
+#include <linux/cred.h>
fb10477
+#include <linux/err.h>
fb10477
+#include <linux/efi.h>
fb10477
+#include <linux/slab.h>
fb10477
+#include <keys/asymmetric-type.h>
fb10477
+#include "module-internal.h"
fb10477
+
fb10477
+static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size)
fb10477
+{
fb10477
+	efi_status_t status;
fb10477
+	unsigned long lsize = 4;
fb10477
+	unsigned long tmpdb[4];
fb10477
+	void *db = NULL;
fb10477
+
fb10477
+	status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
fb10477
+	if (status != EFI_BUFFER_TOO_SMALL) {
fb10477
+		pr_err("Couldn't get size: 0x%lx\n", status);
fb10477
+		return NULL;
fb10477
+	}
fb10477
+
fb10477
+	db = kmalloc(lsize, GFP_KERNEL);
fb10477
+	if (!db) {
fb10477
+		pr_err("Couldn't allocate memory for uefi cert list\n");
fb10477
+		goto out;
fb10477
+	}
fb10477
+
fb10477
+	status = efi.get_variable(name, guid, NULL, &lsize, db);
fb10477
+	if (status != EFI_SUCCESS) {
fb10477
+		kfree(db);
fb10477
+		db = NULL;
fb10477
+		pr_err("Error reading db var: 0x%lx\n", status);
fb10477
+	}
fb10477
+out:
fb10477
+	*size = lsize;
fb10477
+	return db;
fb10477
+}
fb10477
+
fb10477
+/*
fb10477
+ *  * Load the certs contained in the UEFI databases
fb10477
+ *   */
fb10477
+static int __init load_uefi_certs(void)
fb10477
+{
fb10477
+	efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
fb10477
+	efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
fb10477
+	void *db = NULL, *dbx = NULL, *mok = NULL;
fb10477
+	unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
fb10477
+	int rc = 0;
fb10477
+
fb10477
+	/* Check if SB is enabled and just return if not */
fb10477
+	if (!efi_enabled(EFI_SECURE_BOOT))
fb10477
+		return 0;
fb10477
+
fb10477
+	/* Get db, MokListRT, and dbx.  They might not exist, so it isn't
fb10477
+	 * an error if we can't get them.
fb10477
+	 */
fb10477
+	db = get_cert_list(L"db", &secure_var, &dbsize);
fb10477
+	if (!db) {
fb10477
+		pr_err("MODSIGN: Couldn't get UEFI db list\n");
fb10477
+	} else {
fb10477
+		rc = parse_efi_signature_list(db, dbsize, modsign_keyring);
fb10477
+		if (rc)
fb10477
+			pr_err("Couldn't parse db signatures: %d\n", rc);
fb10477
+		kfree(db);
fb10477
+	}
fb10477
+
fb10477
+	mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
fb10477
+	if (!mok) {
fb10477
+		pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
fb10477
+	} else {
fb10477
+		rc = parse_efi_signature_list(mok, moksize, modsign_keyring);
fb10477
+		if (rc)
fb10477
+			pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
fb10477
+		kfree(mok);
fb10477
+	}
fb10477
+
fb10477
+	dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
fb10477
+	if (!dbx) {
fb10477
+		pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
fb10477
+	} else {
fb10477
+		rc = parse_efi_signature_list(dbx, dbxsize,
fb10477
+			modsign_blacklist);
fb10477
+		if (rc)
fb10477
+			pr_err("Couldn't parse dbx signatures: %d\n", rc);
fb10477
+		kfree(dbx);
fb10477
+	}
fb10477
+
fb10477
+	return rc;
fb10477
+}
fb10477
+late_initcall(load_uefi_certs);
fb10477
-- 
fb10477
1.8.3.1
fb10477