summaryrefslogtreecommitdiffstats
path: root/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch')
-rw-r--r--debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch193
1 files changed, 193 insertions, 0 deletions
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