summaryrefslogtreecommitdiffstats
path: root/freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch
diff options
context:
space:
mode:
Diffstat (limited to 'freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch')
-rw-r--r--freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch197
1 files changed, 197 insertions, 0 deletions
diff --git a/freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch b/freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch
new file mode 100644
index 000000000..e3941eeaa
--- /dev/null
+++ b/freed-ora/tags/f27/4.15.9-300.fc27.gnu/Add-an-EFI-signature-blob-parser-and-key-loader.patch
@@ -0,0 +1,197 @@
+From e4c62c12635a371e43bd17e8d33a936668264491 Mon Sep 17 00:00:00 2001
+From: Dave Howells <dhowells@redhat.com>
+Date: Fri, 5 May 2017 08:21:58 +0100
+Subject: [PATCH 2/4] efi: Add an EFI signature blob parser
+
+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
+
+diff --git a/certs/Kconfig b/certs/Kconfig
+index 6ce51ed..630ae09 100644
+--- a/certs/Kconfig
++++ b/certs/Kconfig
+@@ -82,4 +82,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
+diff --git a/certs/Makefile b/certs/Makefile
+index 4119bb3..738151a 100644
+--- a/certs/Makefile
++++ b/certs/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o
+ 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)
+
+diff --git a/certs/efi_parser.c b/certs/efi_parser.c
+new file mode 100644
+index 0000000..4e396f9
+--- /dev/null
++++ b/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;
++}
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 3259ad6..08024c6 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -1055,6 +1055,15 @@ extern int efi_memattr_apply_permissions(struct mm_struct *mm,
+ 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
+--
+2.9.3
+
OpenPOWER on IntegriCloud