summaryrefslogtreecommitdiffstats
path: root/debian/patches/features/all/db-mok-keyring
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/features/all/db-mok-keyring')
-rw-r--r--debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch91
-rw-r--r--debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch64
-rw-r--r--debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch60
-rw-r--r--debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch57
-rw-r--r--debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch129
-rw-r--r--debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch193
-rw-r--r--debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch242
-rw-r--r--debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch108
-rw-r--r--debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch85
-rw-r--r--debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch106
-rw-r--r--debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch28
-rw-r--r--debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch30
12 files changed, 1193 insertions, 0 deletions
diff --git a/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch
new file mode 100644
index 000000000..a67217c02
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch
@@ -0,0 +1,91 @@
+From: David Howells <dhowells@redhat.com>
+Date: Fri, 5 May 2017 08:21:56 +0100
+Subject: [PATCH 1/7] KEYS: Allow unrestricted boot-time addition of keys to
+ secondary keyring
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=40db8fc497d010ae6cee6297c3882d3dc3d76d48
+
+Allow keys to be added to the system secondary certificates keyring during
+kernel initialisation in an unrestricted fashion. Such keys are implicitly
+trusted and don't have their trust chains checked on link.
+
+This allows keys in the UEFI database to be added in secure boot mode for
+the purposes of module signing.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/internal.h | 18 ++++++++++++++++++
+ certs/system_keyring.c | 33 +++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+)
+ create mode 100644 certs/internal.h
+
+Index: linux/certs/internal.h
+===================================================================
+--- /dev/null
++++ linux/certs/internal.h
+@@ -0,0 +1,18 @@
++/* Internal definitions
++ *
++ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++/*
++ * system_keyring.c
++ */
++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
++extern void __init add_trusted_secondary_key(const char *source,
++ const void *data, size_t len);
++#endif
+Index: linux/certs/system_keyring.c
+===================================================================
+--- linux.orig/certs/system_keyring.c
++++ linux/certs/system_keyring.c
+@@ -19,6 +19,7 @@
+ #include <keys/asymmetric-type.h>
+ #include <keys/system_keyring.h>
+ #include <crypto/pkcs7.h>
++#include "internal.h"
+
+ static struct key *builtin_trusted_keys;
+ #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
+@@ -266,3 +267,35 @@ error:
+ EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
+
+ #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
++
++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
++/**
++ * add_trusted_secondary_key - Add to secondary keyring with no validation
++ * @source: Source of key
++ * @data: The blob holding the key
++ * @len: The length of the data blob
++ *
++ * Add a key to the secondary keyring without checking its trust chain. This
++ * is available only during kernel initialisation.
++ */
++void __init add_trusted_secondary_key(const char *source,
++ const void *data, size_t len)
++{
++ key_ref_t key;
++
++ key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
++ "asymmetric",
++ NULL, data, len,
++ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
++ KEY_USR_VIEW,
++ KEY_ALLOC_NOT_IN_QUOTA |
++ KEY_ALLOC_BYPASS_RESTRICTION);
++
++ if (IS_ERR(key))
++ pr_err("Problem loading %s X.509 certificate (%ld)\n",
++ source, PTR_ERR(key));
++ else
++ pr_notice("Loaded %s cert '%s' linked to secondary sys keyring\n",
++ source, key_ref_to_ptr(key)->description);
++}
++#endif /* CONFIG_SECONDARY_TRUSTED_KEYRING */
diff --git a/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch
new file mode 100644
index 000000000..d36028413
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch
@@ -0,0 +1,64 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:37:59 +0800
+Subject: [PATCH 1/5] MODSIGN: do not load mok when secure boot disabled
+Origin: https://lore.kernel.org/patchwork/patch/933173/
+
+The mok can not be trusted when the secure boot is disabled. Which
+means that the kernel embedded certificate is the only trusted key.
+
+Due to db/dbx are authenticated variables, they needs manufacturer's
+KEK for update. So db/dbx are secure when secureboot disabled.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ certs/load_uefi.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -171,17 +171,6 @@ static int __init load_uefi_certs(void)
+ }
+ }
+
+- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
+- if (rc < 0) {
+- pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
+- } else if (moksize != 0) {
+- rc = parse_efi_signature_list("UEFI:MokListRT",
+- mok, moksize, get_handler_for_db);
+- if (rc)
+- pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
+- kfree(mok);
+- }
+-
+ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
+@@ -194,6 +183,21 @@ static int __init load_uefi_certs(void)
+ kfree(dbx);
+ }
+
++ /* the MOK can not be trusted when secure boot is disabled */
++ if (!efi_enabled(EFI_SECURE_BOOT))
++ return 0;
++
++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
++ if (rc < 0) {
++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
++ } else if (moksize != 0) {
++ rc = parse_efi_signature_list("UEFI:MokListRT",
++ mok, moksize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
++ kfree(mok);
++ }
++
+ return rc;
+ }
+ late_initcall(load_uefi_certs);
diff --git a/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch
new file mode 100644
index 000000000..d23b7ac98
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch
@@ -0,0 +1,60 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:38:01 +0800
+Subject: [PATCH 2/4] MODSIGN: load blacklist from MOKx
+Origin: https://lore.kernel.org/patchwork/patch/933177/
+
+This patch adds the logic to load the blacklisted hash and
+certificates from MOKx which is maintained by shim bootloader.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ certs/load_uefi.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -148,8 +148,8 @@ static int __init load_uefi_certs(void)
+ {
+ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
+ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
+- void *db = NULL, *dbx = NULL, *mok = NULL;
+- unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
++ void *db = NULL, *dbx = NULL, *mok = NULL, *mokx = NULL;
++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0, mokxsize = 0;
+ int rc = 0;
+
+ if (!efi.get_variable)
+@@ -183,7 +183,7 @@ static int __init load_uefi_certs(void)
+ kfree(dbx);
+ }
+
+- /* the MOK can not be trusted when secure boot is disabled */
++ /* the MOK and MOKx can not be trusted when secure boot is disabled */
+ if (!efi_enabled(EFI_SECURE_BOOT))
+ return 0;
+
+@@ -198,6 +198,18 @@ static int __init load_uefi_certs(void)
+ kfree(mok);
+ }
+
++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx);
++ if (rc < 0) {
++ pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n");
++ } else if (mokxsize != 0) {
++ rc = parse_efi_signature_list("UEFI:mokx",
++ mokx, mokxsize,
++ get_handler_for_dbx);
++ if (rc)
++ pr_err("Couldn't parse MokListXRT signatures: %d\n", rc);
++ kfree(mokx);
++ }
++
+ return rc;
+ }
+ late_initcall(load_uefi_certs);
diff --git a/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch
new file mode 100644
index 000000000..bf8d40768
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch
@@ -0,0 +1,57 @@
+From: Dave Howells <dhowells@redhat.com>
+Date: Fri, 5 May 2017 08:21:58 +0100
+Subject: [PATCH 2/7] efi: Add EFI signature data types
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=446e0e29d7d53fe7786d33603df5a6682dd00c12
+
+Add the data types that are used for containing hashes, keys and
+certificates for cryptographic verification along with their corresponding
+type GUIDs.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ include/linux/efi.h | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+Index: linux/include/linux/efi.h
+===================================================================
+--- linux.orig/include/linux/efi.h
++++ linux/include/linux/efi.h
+@@ -663,6 +663,10 @@ void efi_native_runtime_setup(void);
+ #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
+ #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
+
++#define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28)
++#define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
++#define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed)
++
+ /*
+ * This GUID is used to pass to the kernel proper the struct screen_info
+ * structure that was populated by the stub based on the GOP protocol instance
+@@ -934,6 +938,27 @@ typedef struct {
+ efi_memory_desc_t entry[0];
+ } efi_memory_attributes_table_t;
+
++typedef struct {
++ efi_guid_t signature_owner;
++ u8 signature_data[];
++} efi_signature_data_t;
++
++typedef struct {
++ efi_guid_t signature_type;
++ u32 signature_list_size;
++ u32 signature_header_size;
++ u32 signature_size;
++ u8 signature_header[];
++ /* efi_signature_data_t signatures[][] */
++} efi_signature_list_t;
++
++typedef u8 efi_sha256_hash_t[32];
++
++typedef struct {
++ efi_sha256_hash_t to_be_signed_hash;
++ efi_time_t time_of_revocation;
++} efi_cert_x509_sha256_t;
++
+ /*
+ * All runtime access to EFI goes through this structure:
+ */
diff --git a/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch
new file mode 100644
index 000000000..1a43ca553
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch
@@ -0,0 +1,129 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:38:02 +0800
+Subject: [PATCH 3/4] MODSIGN: checking the blacklisted hash before loading a
+ kernel module
+Origin: https://lore.kernel.org/patchwork/patch/933175/
+
+This patch adds the logic for checking the kernel module's hash
+base on blacklist. The hash must be generated by sha256 and enrolled
+to dbx/mokx.
+
+For example:
+ sha256sum sample.ko
+ mokutil --mokx --import-hash $HASH_RESULT
+
+Whether the signature on ko file is stripped or not, the hash can be
+compared by kernel.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ kernel/module_signing.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 60 insertions(+), 2 deletions(-)
+
+Index: linux/kernel/module_signing.c
+===================================================================
+--- linux.orig/kernel/module_signing.c
++++ linux/kernel/module_signing.c
+@@ -11,9 +11,12 @@
+
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
++#include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/verification.h>
+ #include <crypto/public_key.h>
++#include <crypto/hash.h>
++#include <keys/system_keyring.h>
+ #include "module-internal.h"
+
+ enum pkey_id_type {
+@@ -42,19 +45,67 @@ struct module_signature {
+ __be32 sig_len; /* Length of signature data */
+ };
+
++static int mod_is_hash_blacklisted(const void *mod, size_t verifylen)
++{
++ struct crypto_shash *tfm;
++ struct shash_desc *desc;
++ size_t digest_size, desc_size;
++ u8 *digest;
++ int ret = 0;
++
++ tfm = crypto_alloc_shash("sha256", 0, 0);
++ if (IS_ERR(tfm))
++ goto error_return;
++
++ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
++ digest_size = crypto_shash_digestsize(tfm);
++ digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
++ if (!digest) {
++ pr_err("digest memory buffer allocate fail\n");
++ ret = -ENOMEM;
++ goto error_digest;
++ }
++ desc = (void *)digest + digest_size;
++ desc->tfm = tfm;
++ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
++ ret = crypto_shash_init(desc);
++ if (ret < 0)
++ goto error_shash;
++
++ ret = crypto_shash_finup(desc, mod, verifylen, digest);
++ if (ret < 0)
++ goto error_shash;
++
++ pr_debug("%ld digest: %*phN\n", verifylen, (int) digest_size, digest);
++
++ ret = is_hash_blacklisted(digest, digest_size, "bin");
++ if (ret == -EKEYREJECTED)
++ pr_err("Module hash %*phN is blacklisted\n",
++ (int) digest_size, digest);
++
++error_shash:
++ kfree(digest);
++error_digest:
++ crypto_free_shash(tfm);
++error_return:
++ return ret;
++}
++
+ /*
+ * Verify the signature on a module.
+ */
+ int mod_verify_sig(const void *mod, struct load_info *info)
+ {
+ struct module_signature ms;
+- size_t sig_len, modlen = info->len;
++ size_t sig_len, modlen = info->len, wholelen;
++ int ret;;
+
+ pr_devel("==>%s(,%zu)\n", __func__, modlen);
+
+ if (modlen <= sizeof(ms))
+ return -EBADMSG;
+
++ wholelen = modlen + sizeof(MODULE_SIG_STRING) - 1;
+ memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
+ modlen -= sizeof(ms);
+
+@@ -82,8 +133,15 @@ int mod_verify_sig(const void *mod, stru
+ return -EBADMSG;
+ }
+
+- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+ VERIFY_USE_SECONDARY_KEYRING,
+ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
++ pr_devel("verify_pkcs7_signature() = %d\n", ret);
++
++ /* checking hash of module is in blacklist */
++ if (!ret)
++ ret = mod_is_hash_blacklisted(mod, wholelen);
++
++ return ret;
+ }
diff --git a/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch
new file mode 100644
index 000000000..e82287cff
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch
@@ -0,0 +1,193 @@
+From: Dave Howells <dhowells@redhat.com>
+Date: Fri, 5 May 2017 08:21:58 +0100
+Subject: [PATCH 3/7] efi: Add an EFI signature blob parser
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=41a595bb0dc097c19ad377a0c32c993234aa2525
+
+Add a function to parse an EFI signature blob looking for elements of
+interest. A list is made up of a series of sublists, where all the
+elements in a sublist are of the same type, but sublists can be of
+different types.
+
+For each sublist encountered, the function pointed to by the
+get_handler_for_guid argument is called with the type specifier GUID and
+returns either a pointer to a function to handle elements of that type or
+NULL if the type is not of interest.
+
+If the sublist is of interest, each element is passed to the handler
+function in turn.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/Kconfig | 8 ++++
+ certs/Makefile | 1 +
+ certs/efi_parser.c | 112 ++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/efi.h | 9 ++++
+ 4 files changed, 130 insertions(+)
+ create mode 100644 certs/efi_parser.c
+
+Index: linux/certs/Kconfig
+===================================================================
+--- linux.orig/certs/Kconfig
++++ linux/certs/Kconfig
+@@ -83,4 +83,12 @@ config SYSTEM_BLACKLIST_HASH_LIST
+ wrapper to incorporate the list into the kernel. Each <hash> should
+ be a string of hex digits.
+
++config EFI_SIGNATURE_LIST_PARSER
++ bool "EFI signature list parser"
++ depends on EFI
++ select X509_CERTIFICATE_PARSER
++ help
++ This option provides support for parsing EFI signature lists for
++ X.509 certificates and turning them into keys.
++
+ endmenu
+Index: linux/certs/Makefile
+===================================================================
+--- linux.orig/certs/Makefile
++++ linux/certs/Makefile
+@@ -10,6 +10,7 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) +
+ else
+ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o
+ endif
++obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
+
+ ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
+
+Index: linux/certs/efi_parser.c
+===================================================================
+--- /dev/null
++++ linux/certs/efi_parser.c
+@@ -0,0 +1,112 @@
++/* EFI signature/key/certificate list parser
++ *
++ * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++#define pr_fmt(fmt) "EFI: "fmt
++#include <linux/module.h>
++#include <linux/printk.h>
++#include <linux/err.h>
++#include <linux/efi.h>
++
++/**
++ * parse_efi_signature_list - Parse an EFI signature list for certificates
++ * @source: The source of the key
++ * @data: The data blob to parse
++ * @size: The size of the data blob
++ * @get_handler_for_guid: Get the handler func for the sig type (or NULL)
++ *
++ * Parse an EFI signature list looking for elements of interest. A list is
++ * made up of a series of sublists, where all the elements in a sublist are of
++ * the same type, but sublists can be of different types.
++ *
++ * For each sublist encountered, the @get_handler_for_guid function is called
++ * with the type specifier GUID and returns either a pointer to a function to
++ * handle elements of that type or NULL if the type is not of interest.
++ *
++ * If the sublist is of interest, each element is passed to the handler
++ * function in turn.
++ *
++ * Error EBADMSG is returned if the list doesn't parse correctly and 0 is
++ * returned if the list was parsed correctly. No error can be returned from
++ * the @get_handler_for_guid function or the element handler function it
++ * returns.
++ */
++int __init parse_efi_signature_list(
++ const char *source,
++ const void *data, size_t size,
++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *))
++{
++ efi_element_handler_t handler;
++ unsigned offs = 0;
++
++ pr_devel("-->%s(,%zu)\n", __func__, size);
++
++ while (size > 0) {
++ const efi_signature_data_t *elem;
++ efi_signature_list_t list;
++ size_t lsize, esize, hsize, elsize;
++
++ if (size < sizeof(list))
++ return -EBADMSG;
++
++ memcpy(&list, data, sizeof(list));
++ pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n",
++ offs,
++ list.signature_type.b, list.signature_list_size,
++ list.signature_header_size, list.signature_size);
++
++ lsize = list.signature_list_size;
++ hsize = list.signature_header_size;
++ esize = list.signature_size;
++ elsize = lsize - sizeof(list) - hsize;
++
++ if (lsize > size) {
++ pr_devel("<--%s() = -EBADMSG [overrun @%x]\n",
++ __func__, offs);
++ return -EBADMSG;
++ }
++
++ if (lsize < sizeof(list) ||
++ lsize - sizeof(list) < hsize ||
++ esize < sizeof(*elem) ||
++ elsize < esize ||
++ elsize % esize != 0) {
++ pr_devel("- bad size combo @%x\n", offs);
++ return -EBADMSG;
++ }
++
++ handler = get_handler_for_guid(&list.signature_type);
++ if (!handler) {
++ data += lsize;
++ size -= lsize;
++ offs += lsize;
++ continue;
++ }
++
++ data += sizeof(list) + hsize;
++ size -= sizeof(list) + hsize;
++ offs += sizeof(list) + hsize;
++
++ for (; elsize > 0; elsize -= esize) {
++ elem = data;
++
++ pr_devel("ELEM[%04x]\n", offs);
++ handler(source,
++ &elem->signature_data,
++ esize - sizeof(*elem));
++
++ data += esize;
++ size -= esize;
++ offs += esize;
++ }
++ }
++
++ return 0;
++}
+Index: linux/include/linux/efi.h
+===================================================================
+--- linux.orig/include/linux/efi.h
++++ linux/include/linux/efi.h
+@@ -1139,6 +1139,15 @@ extern int efi_memattr_apply_permissions
+ char * __init efi_md_typeattr_format(char *buf, size_t size,
+ const efi_memory_desc_t *md);
+
++
++typedef void (*efi_element_handler_t)(const char *source,
++ const void *element_data,
++ size_t element_size);
++extern int __init parse_efi_signature_list(
++ const char *source,
++ const void *data, size_t size,
++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *));
++
+ /**
+ * efi_range_is_wc - check the WC bit on an address range
+ * @start: starting kvirt address
diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch
new file mode 100644
index 000000000..cdb3b7a22
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch
@@ -0,0 +1,242 @@
+From: Josh Boyer <jwboyer@fedoraproject.org>
+Date: Fri, 5 May 2017 08:21:59 +0100
+Subject: [PATCH 4/7] MODSIGN: Import certificates from UEFI Secure Boot
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=7b7aae2efea13b5a7b80305856c28f235ea8b2fa
+
+Secure Boot stores a list of allowed certificates in the 'db' variable.
+This imports those certificates into the system trusted keyring. This
+allows for a third party signing certificate to be used in conjunction
+with signed modules. By importing the public certificate into the 'db'
+variable, a user can allow a module signed with that certificate to
+load. The shim UEFI bootloader has a similar certificate list stored
+in the 'MokListRT' variable. We import those as well.
+
+Secure Boot also maintains a list of disallowed certificates in the 'dbx'
+variable. We load those certificates into the newly introduced system
+blacklist keyring and forbid any module signed with those from loading and
+forbid the use within the kernel of any key with a matching hash.
+
+This facility is enabled by setting CONFIG_LOAD_UEFI_KEYS.
+
+Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/Kconfig | 16 +++++
+ certs/Makefile | 4 ++
+ certs/load_uefi.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 188 insertions(+)
+ create mode 100644 certs/load_uefi.c
+
+Index: linux/certs/Kconfig
+===================================================================
+--- linux.orig/certs/Kconfig
++++ linux/certs/Kconfig
+@@ -91,4 +91,20 @@ config EFI_SIGNATURE_LIST_PARSER
+ This option provides support for parsing EFI signature lists for
+ X.509 certificates and turning them into keys.
+
++config LOAD_UEFI_KEYS
++ bool "Load certs and blacklist from UEFI db for module checking"
++ depends on SYSTEM_BLACKLIST_KEYRING
++ depends on SECONDARY_TRUSTED_KEYRING
++ depends on EFI
++ depends on EFI_SIGNATURE_LIST_PARSER
++ help
++ If the kernel is booted in secure boot mode, this option will cause
++ the kernel to load the certificates from the UEFI db and MokListRT
++ into the secondary trusted keyring. It will also load any X.509
++ SHA256 hashes in the dbx list into the blacklist.
++
++ The effect of this is that, if the kernel is booted in secure boot
++ mode, modules signed with UEFI-stored keys will be permitted to be
++ loaded and keys that match the blacklist will be rejected.
++
+ endmenu
+Index: linux/certs/Makefile
+===================================================================
+--- linux.orig/certs/Makefile
++++ linux/certs/Makefile
+@@ -12,6 +12,10 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) +
+ endif
+ obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
+
++obj-$(CONFIG_LOAD_UEFI_KEYS) += load_uefi.o
++$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
++
++
+ ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
+
+ $(eval $(call config_filename,SYSTEM_TRUSTED_KEYS))
+Index: linux/certs/load_uefi.c
+===================================================================
+--- /dev/null
++++ linux/certs/load_uefi.c
+@@ -0,0 +1,168 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/cred.h>
++#include <linux/err.h>
++#include <linux/efi.h>
++#include <linux/slab.h>
++#include <keys/asymmetric-type.h>
++#include <keys/system_keyring.h>
++#include "internal.h"
++
++static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
++static __initdata efi_guid_t efi_cert_x509_sha256_guid = EFI_CERT_X509_SHA256_GUID;
++static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID;
++
++/*
++ * Get a certificate list blob from the named EFI variable.
++ */
++static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
++ unsigned long *size)
++{
++ efi_status_t status;
++ unsigned long lsize = 4;
++ unsigned long tmpdb[4];
++ void *db;
++
++ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
++ if (status != EFI_BUFFER_TOO_SMALL) {
++ pr_err("Couldn't get size: 0x%lx\n", status);
++ return NULL;
++ }
++
++ db = kmalloc(lsize, GFP_KERNEL);
++ if (!db) {
++ pr_err("Couldn't allocate memory for uefi cert list\n");
++ return NULL;
++ }
++
++ status = efi.get_variable(name, guid, NULL, &lsize, db);
++ if (status != EFI_SUCCESS) {
++ kfree(db);
++ pr_err("Error reading db var: 0x%lx\n", status);
++ return NULL;
++ }
++
++ *size = lsize;
++ return db;
++}
++
++/*
++ * Blacklist an X509 TBS hash.
++ */
++static __init void uefi_blacklist_x509_tbs(const char *source,
++ const void *data, size_t len)
++{
++ char *hash, *p;
++
++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL);
++ if (!hash)
++ return;
++ p = memcpy(hash, "tbs:", 4);
++ p += 4;
++ bin2hex(p, data, len);
++ p += len * 2;
++ *p = 0;
++
++ mark_hash_blacklisted(hash);
++ kfree(hash);
++}
++
++/*
++ * Blacklist the hash of an executable.
++ */
++static __init void uefi_blacklist_binary(const char *source,
++ const void *data, size_t len)
++{
++ char *hash, *p;
++
++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL);
++ if (!hash)
++ return;
++ p = memcpy(hash, "bin:", 4);
++ p += 4;
++ bin2hex(p, data, len);
++ p += len * 2;
++ *p = 0;
++
++ mark_hash_blacklisted(hash);
++ kfree(hash);
++}
++
++/*
++ * Return the appropriate handler for particular signature list types found in
++ * the UEFI db and MokListRT tables.
++ */
++static __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type)
++{
++ if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
++ return add_trusted_secondary_key;
++ return 0;
++}
++
++/*
++ * Return the appropriate handler for particular signature list types found in
++ * the UEFI dbx and MokListXRT tables.
++ */
++static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type)
++{
++ if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0)
++ return uefi_blacklist_x509_tbs;
++ if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0)
++ return uefi_blacklist_binary;
++ return 0;
++}
++
++/*
++ * Load the certs contained in the UEFI databases
++ */
++static int __init load_uefi_certs(void)
++{
++ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
++ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
++ void *db = NULL, *dbx = NULL, *mok = NULL;
++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
++ int rc = 0;
++
++ if (!efi.get_variable)
++ return false;
++
++ /* Get db, MokListRT, and dbx. They might not exist, so it isn't
++ * an error if we can't get them.
++ */
++ db = get_cert_list(L"db", &secure_var, &dbsize);
++ if (!db) {
++ pr_err("MODSIGN: Couldn't get UEFI db list\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:db",
++ db, dbsize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse db signatures: %d\n", rc);
++ kfree(db);
++ }
++
++ mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
++ if (!mok) {
++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:MokListRT",
++ mok, moksize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
++ kfree(mok);
++ }
++
++ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
++ if (!dbx) {
++ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:dbx",
++ dbx, dbxsize,
++ get_handler_for_dbx);
++ if (rc)
++ pr_err("Couldn't parse dbx signatures: %d\n", rc);
++ kfree(dbx);
++ }
++
++ return rc;
++}
++late_initcall(load_uefi_certs);
diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch
new file mode 100644
index 000000000..57b6e61ff
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch
@@ -0,0 +1,108 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:38:03 +0800
+Subject: [PATCH 4/4] MODSIGN: check the attributes of db and mok
+Origin: https://lore.kernel.org/patchwork/patch/933176/
+
+That's better for checking the attributes of db and mok variables
+before loading certificates to kernel keyring.
+
+For db and dbx, both of them are authenticated variables. Which
+means that they can only be modified by manufacturer's key. So
+the kernel should checks EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
+attribute before we trust it.
+
+For mok-rt and mokx-rt, both of them are created by shim boot loader
+to forward the mok/mokx content to runtime. They must be runtime-volatile
+variables. So kernel should checks that the attributes map did not set
+EFI_VARIABLE_NON_VOLATILE bit before we trust it.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ certs/load_uefi.c | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -36,12 +36,14 @@ static __init bool uefi_check_ignore_db(
+ * Get a certificate list blob from the named EFI variable.
+ */
+ static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid,
+- unsigned long *size, void **cert_list)
++ unsigned long *size, void **cert_list,
++ u32 pos_attr, u32 neg_attr)
+ {
+ efi_status_t status;
+ unsigned long lsize = 4;
+ unsigned long tmpdb[4];
+ void *db;
++ u32 attr = 0;
+
+ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
+ if (status == EFI_NOT_FOUND) {
+@@ -61,12 +63,19 @@ static __init int get_cert_list(efi_char
+ return -ENOMEM;
+ }
+
+- status = efi.get_variable(name, guid, NULL, &lsize, db);
++ status = efi.get_variable(name, guid, &attr, &lsize, db);
+ if (status != EFI_SUCCESS) {
+ kfree(db);
+ pr_err("Error reading db var: 0x%lx\n", status);
+ return efi_status_to_err(status);
+ }
++ /* must have positive attributes and no negative attributes */
++ if ((pos_attr && !(attr & pos_attr)) ||
++ (neg_attr && (attr & neg_attr))) {
++ kfree(db);
++ pr_err("Error reading db var attributes: 0x%016x\n", attr);
++ return -1;
++ }
+
+ *size = lsize;
+ *cert_list = db;
+@@ -159,7 +168,8 @@ static int __init load_uefi_certs(void)
+ * an error if we can't get them.
+ */
+ if (!uefi_check_ignore_db()) {
+- rc = get_cert_list(L"db", &secure_var, &dbsize, &db);
++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db,
++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0);
+ if (rc < 0) {
+ pr_err("MODSIGN: Couldn't get UEFI db list\n");
+ } else if (dbsize != 0) {
+@@ -171,7 +181,8 @@ static int __init load_uefi_certs(void)
+ }
+ }
+
+- rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx);
++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx,
++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
+ } else if (dbxsize != 0) {
+@@ -187,7 +198,8 @@ static int __init load_uefi_certs(void)
+ if (!efi_enabled(EFI_SECURE_BOOT))
+ return 0;
+
+- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok,
++ 0, EFI_VARIABLE_NON_VOLATILE);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
+ } else if (moksize != 0) {
+@@ -198,7 +210,8 @@ static int __init load_uefi_certs(void)
+ kfree(mok);
+ }
+
+- rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx);
++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx,
++ 0, EFI_VARIABLE_NON_VOLATILE);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n");
+ } else if (mokxsize != 0) {
diff --git a/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch
new file mode 100644
index 000000000..b5e2e843c
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch
@@ -0,0 +1,85 @@
+From: Josh Boyer <jwboyer@fedoraproject.org>
+Date: Fri, 5 May 2017 08:21:59 +0100
+Subject: [PATCH 5/7] MODSIGN: Allow the "db" UEFI variable to be suppressed
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=b51ca4e4d6c0c8000789de31a1184a41ac611d33
+
+If a user tells shim to not use the certs/hashes in the UEFI db variable
+for verification purposes, shim will set a UEFI variable called
+MokIgnoreDB. Have the uefi import code look for this and ignore the db
+variable if it is found.
+
+Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/load_uefi.c | 44 ++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 34 insertions(+), 10 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -13,6 +13,26 @@ static __initdata efi_guid_t efi_cert_x5
+ static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID;
+
+ /*
++ * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
++ * it does.
++ *
++ * This UEFI variable is set by the shim if a user tells the shim to not use
++ * the certs/hashes in the UEFI db variable for verification purposes. If it
++ * is set, we should ignore the db variable also and the true return indicates
++ * this.
++ */
++static __init bool uefi_check_ignore_db(void)
++{
++ efi_status_t status;
++ unsigned int db = 0;
++ unsigned long size = sizeof(db);
++ efi_guid_t guid = EFI_SHIM_LOCK_GUID;
++
++ status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
++ return status == EFI_SUCCESS;
++}
++
++/*
+ * Get a certificate list blob from the named EFI variable.
+ */
+ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
+@@ -113,7 +133,9 @@ static __init efi_element_handler_t get_
+ }
+
+ /*
+- * Load the certs contained in the UEFI databases
++ * Load the certs contained in the UEFI databases into the secondary trusted
++ * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
++ * keyring.
+ */
+ static int __init load_uefi_certs(void)
+ {
+@@ -129,15 +151,17 @@ static int __init load_uefi_certs(void)
+ /* Get db, MokListRT, and dbx. They might not exist, so it isn't
+ * an error if we can't get them.
+ */
+- db = get_cert_list(L"db", &secure_var, &dbsize);
+- if (!db) {
+- pr_err("MODSIGN: Couldn't get UEFI db list\n");
+- } else {
+- rc = parse_efi_signature_list("UEFI:db",
+- db, dbsize, get_handler_for_db);
+- if (rc)
+- pr_err("Couldn't parse db signatures: %d\n", rc);
+- kfree(db);
++ if (!uefi_check_ignore_db()) {
++ db = get_cert_list(L"db", &secure_var, &dbsize);
++ if (!db) {
++ pr_err("MODSIGN: Couldn't get UEFI db list\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:db",
++ db, dbsize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse db signatures: %d\n", rc);
++ kfree(db);
++ }
+ }
+
+ mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
diff --git a/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch
new file mode 100644
index 000000000..c348e2f04
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch
@@ -0,0 +1,106 @@
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 2 Oct 2017 18:25:29 -0400
+Subject: [PATCH 6/7] Make get_cert_list() not complain about cert lists that
+ aren't present.
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=0f4d5c7b49b45e7cf038bb769e33451b78a6445d
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ certs/load_uefi.c | 37 ++++++++++++++++++++++---------------
+ 1 file changed, 22 insertions(+), 15 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -35,8 +35,8 @@ static __init bool uefi_check_ignore_db(
+ /*
+ * Get a certificate list blob from the named EFI variable.
+ */
+-static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
+- unsigned long *size)
++static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid,
++ unsigned long *size, void **cert_list)
+ {
+ efi_status_t status;
+ unsigned long lsize = 4;
+@@ -44,26 +44,33 @@ static __init void *get_cert_list(efi_ch
+ void *db;
+
+ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
++ if (status == EFI_NOT_FOUND) {
++ *size = 0;
++ *cert_list = NULL;
++ return 0;
++ }
++
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ pr_err("Couldn't get size: 0x%lx\n", status);
+- return NULL;
++ return efi_status_to_err(status);
+ }
+
+ db = kmalloc(lsize, GFP_KERNEL);
+ if (!db) {
+ pr_err("Couldn't allocate memory for uefi cert list\n");
+- return NULL;
++ return -ENOMEM;
+ }
+
+ status = efi.get_variable(name, guid, NULL, &lsize, db);
+ if (status != EFI_SUCCESS) {
+ kfree(db);
+ pr_err("Error reading db var: 0x%lx\n", status);
+- return NULL;
++ return efi_status_to_err(status);
+ }
+
+ *size = lsize;
+- return db;
++ *cert_list = db;
++ return 0;
+ }
+
+ /*
+@@ -152,10 +159,10 @@ static int __init load_uefi_certs(void)
+ * an error if we can't get them.
+ */
+ if (!uefi_check_ignore_db()) {
+- db = get_cert_list(L"db", &secure_var, &dbsize);
+- if (!db) {
++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db);
++ if (rc < 0) {
+ pr_err("MODSIGN: Couldn't get UEFI db list\n");
+- } else {
++ } else if (dbsize != 0) {
+ rc = parse_efi_signature_list("UEFI:db",
+ db, dbsize, get_handler_for_db);
+ if (rc)
+@@ -164,10 +171,10 @@ static int __init load_uefi_certs(void)
+ }
+ }
+
+- mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
+- if (!mok) {
++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
++ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
+- } else {
++ } else if (moksize != 0) {
+ rc = parse_efi_signature_list("UEFI:MokListRT",
+ mok, moksize, get_handler_for_db);
+ if (rc)
+@@ -175,10 +182,10 @@ static int __init load_uefi_certs(void)
+ kfree(mok);
+ }
+
+- dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
+- if (!dbx) {
++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx);
++ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
+- } else {
++ } else if (dbxsize != 0) {
+ rc = parse_efi_signature_list("UEFI:dbx",
+ dbx, dbxsize,
+ get_handler_for_dbx);
diff --git a/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch
new file mode 100644
index 000000000..b831869e4
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch
@@ -0,0 +1,28 @@
+From: Ke Wu <mikewu@google.com>
+Date: Tue, 6 Nov 2018 15:21:30 -0800
+Subject: modsign: use all trusted keys to verify module signature
+Origin: https://git.kernel.org/linus/e84cd7ee630e44a2cc8ae49e85920a271b214cb3
+
+Make mod_verify_sig to use all trusted keys. This allows keys in
+secondary_trusted_keys to be used to verify PKCS#7 signature on a
+kernel module.
+
+Signed-off-by: Ke Wu <mikewu@google.com>
+Signed-off-by: Jessica Yu <jeyu@kernel.org>
+---
+ kernel/module_signing.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: linux/kernel/module_signing.c
+===================================================================
+--- linux.orig/kernel/module_signing.c
++++ linux/kernel/module_signing.c
+@@ -83,6 +83,7 @@ int mod_verify_sig(const void *mod, stru
+ }
+
+ return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+- NULL, VERIFYING_MODULE_SIGNATURE,
++ VERIFY_USE_SECONDARY_KEYRING,
++ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
+ }
diff --git a/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch
new file mode 100644
index 000000000..a0aea95a2
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch
@@ -0,0 +1,30 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 05 May 2019 13:45:06 +0100
+Subject: MODSIGN: Make shash allocation failure fatal
+
+mod_is_hash_blacklisted() currently returns 0 (suceess) if
+crypto_alloc_shash() fails. This should instead be a fatal error,
+so unwrap and pass up the error code.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/kernel/module_signing.c
+===================================================================
+--- linux.orig/kernel/module_signing.c
++++ linux/kernel/module_signing.c
+@@ -51,11 +51,13 @@ static int mod_is_hash_blacklisted(const
+ struct shash_desc *desc;
+ size_t digest_size, desc_size;
+ u8 *digest;
+- int ret = 0;
++ int ret;
+
+ tfm = crypto_alloc_shash("sha256", 0, 0);
+- if (IS_ERR(tfm))
++ if (IS_ERR(tfm)) {
++ ret = PTR_ERR(tfm);
+ goto error_return;
++ }
+
+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ digest_size = crypto_shash_digestsize(tfm);