linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: tip-bot for Ard Biesheuvel <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, mingo@kernel.org,
	torvalds@linux-foundation.org, peterz@infradead.org,
	keescook@chromium.org, matt@codeblueprint.co.uk,
	ard.biesheuvel@linaro.org, tglx@linutronix.de, hpa@zytor.com
Subject: [tip:efi/core] efi: Add support for seeding the RNG from a UEFI config table
Date: Sun, 13 Nov 2016 01:05:23 -0800	[thread overview]
Message-ID: <tip-636259880a7e7d3446a707dddebc799da94bdd0b@git.kernel.org> (raw)
In-Reply-To: <20161112213237.8804-4-matt@codeblueprint.co.uk>

Commit-ID:  636259880a7e7d3446a707dddebc799da94bdd0b
Gitweb:     http://git.kernel.org/tip/636259880a7e7d3446a707dddebc799da94bdd0b
Author:     Ard Biesheuvel <ard.biesheuvel@linaro.org>
AuthorDate: Sat, 12 Nov 2016 21:32:31 +0000
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Sun, 13 Nov 2016 08:23:14 +0100

efi: Add support for seeding the RNG from a UEFI config table

Specify a Linux specific UEFI configuration table that carries some
random bits, and use the contents during early boot to seed the kernel's
random number generator. This allows much strong random numbers to be
generated early on.

The entropy is fed to the kernel using add_device_randomness(), which is
documented as being appropriate for being called very early.

Since UEFI configuration tables may also be consumed by kexec'd kernels,
register a reboot notifier that updates the seed in the table.

Note that the config table could be generated by the EFI stub or by any
other UEFI driver or application (e.g., GRUB), but the random seed table
GUID and the associated functionality should be considered an internal
kernel interface (unless it is promoted to ABI later on)

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Kees Cook <keescook@chromium.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20161112213237.8804-4-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/firmware/efi/efi.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/efi.h        |  8 ++++++
 2 files changed, 80 insertions(+)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index a4944e2..9291480 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -23,7 +23,10 @@
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/io.h>
+#include <linux/kexec.h>
 #include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/ucs2_string.h>
@@ -48,6 +51,7 @@ struct efi __read_mostly efi = {
 	.esrt			= EFI_INVALID_TABLE_ADDR,
 	.properties_table	= EFI_INVALID_TABLE_ADDR,
 	.mem_attr_table		= EFI_INVALID_TABLE_ADDR,
+	.rng_seed		= EFI_INVALID_TABLE_ADDR,
 };
 EXPORT_SYMBOL(efi);
 
@@ -440,6 +444,7 @@ static __initdata efi_config_table_type_t common_tables[] = {
 	{EFI_SYSTEM_RESOURCE_TABLE_GUID, "ESRT", &efi.esrt},
 	{EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table},
 	{EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table},
+	{LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed},
 	{NULL_GUID, NULL, NULL},
 };
 
@@ -501,6 +506,29 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
 	pr_cont("\n");
 	set_bit(EFI_CONFIG_TABLES, &efi.flags);
 
+	if (efi.rng_seed != EFI_INVALID_TABLE_ADDR) {
+		struct linux_efi_random_seed *seed;
+		u32 size = 0;
+
+		seed = early_memremap(efi.rng_seed, sizeof(*seed));
+		if (seed != NULL) {
+			size = seed->size;
+			early_memunmap(seed, sizeof(*seed));
+		} else {
+			pr_err("Could not map UEFI random seed!\n");
+		}
+		if (size > 0) {
+			seed = early_memremap(efi.rng_seed,
+					      sizeof(*seed) + size);
+			if (seed != NULL) {
+				add_device_randomness(seed->bits, seed->size);
+				early_memunmap(seed, sizeof(*seed) + size);
+			} else {
+				pr_err("Could not map UEFI random seed!\n");
+			}
+		}
+	}
+
 	/* Parse the EFI Properties table if it exists */
 	if (efi.properties_table != EFI_INVALID_TABLE_ADDR) {
 		efi_properties_table_t *tbl;
@@ -824,3 +852,47 @@ int efi_status_to_err(efi_status_t status)
 
 	return err;
 }
+
+#ifdef CONFIG_KEXEC
+static int update_efi_random_seed(struct notifier_block *nb,
+				  unsigned long code, void *unused)
+{
+	struct linux_efi_random_seed *seed;
+	u32 size = 0;
+
+	if (!kexec_in_progress)
+		return NOTIFY_DONE;
+
+	seed = memremap(efi.rng_seed, sizeof(*seed), MEMREMAP_WB);
+	if (seed != NULL) {
+		size = min(seed->size, 32U);
+		memunmap(seed);
+	} else {
+		pr_err("Could not map UEFI random seed!\n");
+	}
+	if (size > 0) {
+		seed = memremap(efi.rng_seed, sizeof(*seed) + size,
+				MEMREMAP_WB);
+		if (seed != NULL) {
+			seed->size = size;
+			get_random_bytes(seed->bits, seed->size);
+			memunmap(seed);
+		} else {
+			pr_err("Could not map UEFI random seed!\n");
+		}
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block efi_random_seed_nb = {
+	.notifier_call = update_efi_random_seed,
+};
+
+static int register_update_efi_random_seed(void)
+{
+	if (efi.rng_seed == EFI_INVALID_TABLE_ADDR)
+		return 0;
+	return register_reboot_notifier(&efi_random_seed_nb);
+}
+late_initcall(register_update_efi_random_seed);
+#endif
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 2d08948..85e28b1 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -599,6 +599,7 @@ void efi_native_runtime_setup(void);
  */
 #define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID	EFI_GUID(0xe03fc20a, 0x85dc, 0x406e,  0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95)
 #define LINUX_EFI_LOADER_ENTRY_GUID		EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf,  0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
+#define LINUX_EFI_RANDOM_SEED_TABLE_GUID	EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2,  0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b)
 
 typedef struct {
 	efi_guid_t guid;
@@ -872,6 +873,7 @@ extern struct efi {
 	unsigned long esrt;		/* ESRT table */
 	unsigned long properties_table;	/* properties table */
 	unsigned long mem_attr_table;	/* memory attributes table */
+	unsigned long rng_seed;		/* UEFI firmware random seed */
 	efi_get_time_t *get_time;
 	efi_set_time_t *set_time;
 	efi_get_wakeup_time_t *get_wakeup_time;
@@ -1493,4 +1495,10 @@ efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table,
 				    struct efi_boot_memmap *map,
 				    void *priv,
 				    efi_exit_boot_map_processing priv_func);
+
+struct linux_efi_random_seed {
+	u32	size;
+	u8	bits[];
+};
+
 #endif /* _LINUX_EFI_H */

  reply	other threads:[~2016-11-13  9:06 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-12 21:32 [GIT PULL 0/9] EFI changes for v4.10 Matt Fleming
2016-11-12 21:32 ` [PATCH 1/9] efi/libstub: Fix allocation size calculations Matt Fleming
2016-11-13  9:04   ` [tip:efi/core] " tip-bot for Roy Franz
2016-11-12 21:32 ` [PATCH 2/9] MAINTAINERS: Add ARM and arm64 EFI specific files to EFI subsystem Matt Fleming
2016-11-13  9:04   ` [tip:efi/core] " tip-bot for Ard Biesheuvel
2016-11-12 21:32 ` [PATCH 3/9] efi: Add support for seeding the RNG from a UEFI config table Matt Fleming
2016-11-13  9:05   ` tip-bot for Ard Biesheuvel [this message]
2016-11-12 21:32 ` [PATCH 4/9] efi/libstub: Add random.c to ARM build Matt Fleming
2016-11-13  9:05   ` [tip:efi/core] " tip-bot for Ard Biesheuvel
2016-11-12 21:32 ` [PATCH 5/9] efi/arm*: libstub: Invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table Matt Fleming
2016-11-13  7:19   ` Ingo Molnar
2016-11-13  8:59     ` Ingo Molnar
2016-11-14 13:27       ` Matt Fleming
2016-11-14 15:10         ` Lukas Wunner
2016-11-15 10:50           ` [tip:efi/core] thunderbolt, efi: Fix Kconfig dependencies tip-bot for Lukas Wunner
2016-11-14 13:23     ` [PATCH 5/9] efi/arm*: libstub: Invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table Matt Fleming
2016-11-14 13:55       ` Ingo Molnar
2016-11-14 14:01         ` Matt Fleming
2016-11-13  9:06   ` [tip:efi/core] efi/arm*/libstub: " tip-bot for Ard Biesheuvel
2016-11-12 21:32 ` [PATCH 6/9] efi: Add device path parser Matt Fleming
2016-11-13  9:07   ` [tip:efi/core] " tip-bot for Lukas Wunner
2016-11-12 21:32 ` [PATCH 7/9] efi: Allow bitness-agnostic protocol calls Matt Fleming
2016-11-13  9:07   ` [tip:efi/core] " tip-bot for Lukas Wunner
2016-11-12 21:32 ` [PATCH 8/9] x86/efi: Retrieve and assign Apple device properties Matt Fleming
2016-11-13  9:08   ` [tip:efi/core] " tip-bot for Lukas Wunner
2016-11-12 21:32 ` [PATCH 9/9] thunderbolt: Use Device ROM retrieved from EFI Matt Fleming
2016-11-13  9:08   ` [tip:efi/core] " tip-bot for Lukas Wunner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-636259880a7e7d3446a707dddebc799da94bdd0b@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=hpa@zytor.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=matt@codeblueprint.co.uk \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).