76b66ee
From 725d7e7fb9ca1065102e640cf8af606169e63075 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
76b66ee
From f204253a34b477c5d68df711326a694b58e51c76 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 +
76b66ee
 crypto/asymmetric_keys/efi_parser.c | 109 ++++++++++++++++++++++++++++++++++++
fb10477
 include/linux/efi.h                 |   4 ++
76b66ee
 4 files changed, 122 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
76b66ee
index 0000000..424896a
fb10477
--- /dev/null
fb10477
+++ b/crypto/asymmetric_keys/efi_parser.c
76b66ee
@@ -0,0 +1,109 @@
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,
76b66ee
+				KEY_ALLOC_NOT_IN_QUOTA |
76b66ee
+				KEY_ALLOC_TRUSTED);
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
76b66ee
From cebc8870a8f0b97b2585a07d9957ead0f21cdc8a Mon Sep 17 00:00:00 2001
fb10477
From: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
Date: Fri, 26 Oct 2012 12:36:24 -0400
76b66ee
Subject: [PATCH 3/4] KEYS: Add a system 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
---
76b66ee
 include/keys/system_keyring.h |  4 ++++
76b66ee
 init/Kconfig                  |  9 +++++++++
76b66ee
 kernel/module_signing.c       | 12 ++++++++++++
76b66ee
 kernel/system_keyring.c       | 17 +++++++++++++++++
76b66ee
 4 files changed, 42 insertions(+)
fb10477
76b66ee
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
76b66ee
index 8dabc39..e466de1 100644
76b66ee
--- a/include/keys/system_keyring.h
76b66ee
+++ b/include/keys/system_keyring.h
76b66ee
@@ -18,6 +18,10 @@
fb10477
 
76b66ee
 extern struct key *system_trusted_keyring;
fb10477
 
76b66ee
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
76b66ee
+extern struct key *system_blacklist_keyring;
fb10477
+#endif
fb10477
+
76b66ee
 #endif
fb10477
 
76b66ee
 #endif /* _KEYS_SYSTEM_KEYRING_H */
76b66ee
diff --git a/init/Kconfig b/init/Kconfig
76b66ee
index 9f3cfdc..547f617 100644
76b66ee
--- a/init/Kconfig
76b66ee
+++ b/init/Kconfig
76b66ee
@@ -1676,6 +1676,15 @@ config SYSTEM_TRUSTED_KEYRING
fb10477
 
76b66ee
 	  Keys in this keyring are used by module signature checking.
fb10477
 
76b66ee
+config SYSTEM_BLACKLIST_KEYRING
76b66ee
+	bool "Provide system-wide ring of blacklisted keys"
76b66ee
+	depends on KEYS
76b66ee
+	help
76b66ee
+	  Provide a system keyring to which blacklisted keys can be added.  Keys
76b66ee
+	  in the keyring are considered entirely untrusted.  Keys in this keyring
76b66ee
+	  are used by the module signature checking to reject loading of modules
76b66ee
+	  signed with a blacklisted key.
76b66ee
+
76b66ee
 menuconfig MODULES
76b66ee
 	bool "Enable loadable module support"
76b66ee
 	help
fb10477
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
76b66ee
index 0b6b870..0a29b40 100644
fb10477
--- a/kernel/module_signing.c
fb10477
+++ b/kernel/module_signing.c
76b66ee
@@ -158,6 +158,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
fb10477
 
fb10477
 	pr_debug("Look up: \"%s\"\n", id);
fb10477
 
76b66ee
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
76b66ee
+	key = keyring_search(make_key_ref(system_blacklist_keyring, 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
+
76b66ee
 	key = keyring_search(make_key_ref(system_trusted_keyring, 1),
fb10477
 			     &key_type_asymmetric, id);
fb10477
 	if (IS_ERR(key))
76b66ee
diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c
76b66ee
index 4ca7072..b19cc6e 100644
76b66ee
--- a/kernel/system_keyring.c
76b66ee
+++ b/kernel/system_keyring.c
76b66ee
@@ -20,6 +20,9 @@
76b66ee
 
76b66ee
 struct key *system_trusted_keyring;
76b66ee
 EXPORT_SYMBOL_GPL(system_trusted_keyring);
76b66ee
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
76b66ee
+struct key *system_blacklist_keyring;
76b66ee
+#endif
76b66ee
 
76b66ee
 extern __initdata const u8 system_certificate_list[];
76b66ee
 extern __initdata const u8 system_certificate_list_end[];
76b66ee
@@ -41,6 +44,20 @@ static __init int system_trusted_keyring_init(void)
76b66ee
 		panic("Can't allocate system trusted keyring\n");
76b66ee
 
76b66ee
 	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
76b66ee
+
76b66ee
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
76b66ee
+	system_blacklist_keyring = keyring_alloc(".system_blacklist_keyring",
76b66ee
+				    KUIDT_INIT(0), KGIDT_INIT(0),
76b66ee
+				    current_cred(),
76b66ee
+				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
76b66ee
+				    KEY_USR_VIEW | KEY_USR_READ,
76b66ee
+				    KEY_ALLOC_NOT_IN_QUOTA, NULL);
76b66ee
+	if (IS_ERR(system_blacklist_keyring))
76b66ee
+		panic("Can't allocate system blacklist keyring\n");
76b66ee
+
76b66ee
+	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_blacklist_keyring->flags);
76b66ee
+#endif
76b66ee
+
76b66ee
 	return 0;
76b66ee
 }
76b66ee
 
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From aa4f39ac51f8b9f589c13766e5e32a5b7794ed68 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.
76b66ee
This imports those certificates into the system trusted 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
76b66ee
the newly introduced system 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 ++
76b66ee
 kernel/modsign_uefi.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++
76b66ee
 4 files changed, 110 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
76b66ee
index 547f617..8e943bf 100644
fb10477
--- a/init/Kconfig
fb10477
+++ b/init/Kconfig
76b66ee
@@ -1794,6 +1794,15 @@ config MODULE_SIG_ALL
76b66ee
 comment "Do not forget to sign required modules with scripts/sign-file"
76b66ee
 	depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
fb10477
 
fb10477
+config MODULE_SIG_UEFI
fb10477
+	bool "Allow modules signed with certs stored in UEFI"
76b66ee
+	depends on MODULE_SIG && SYSTEM_BLACKLIST_KEYRING && 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
76b66ee
index 1ff5e3b..f9b9998 100644
fb10477
--- a/kernel/Makefile
fb10477
+++ b/kernel/Makefile
76b66ee
@@ -56,6 +56,7 @@ obj-$(CONFIG_UID16) += uid16.o
76b66ee
 obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
fb10477
 obj-$(CONFIG_MODULES) += module.o
76b66ee
 obj-$(CONFIG_MODULE_SIG) += module_signing.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
76b66ee
@@ -115,6 +116,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
76b66ee
index 0000000..94b0eb3
fb10477
--- /dev/null
fb10477
+++ b/kernel/modsign_uefi.c
76b66ee
@@ -0,0 +1,92 @@
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>
76b66ee
+#include <keys/system_keyring.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 {
76b66ee
+		rc = parse_efi_signature_list(db, dbsize, system_trusted_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 {
76b66ee
+		rc = parse_efi_signature_list(mok, moksize, system_trusted_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,
76b66ee
+			system_blacklist_keyring);
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