linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] efi: add support for seeding the kernel RNG from UEFI
@ 2016-10-06 10:27 Ard Biesheuvel
       [not found] ` <1475749646-10844-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Ard Biesheuvel @ 2016-10-06 10:27 UTC (permalink / raw)
  To: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: mark.rutland-5wv7dgnIgG8, Ard Biesheuvel

This implements generic EFI core kernel code to seed the kernel entropy
pool from a Linux specific UEFI configuration table containing a random seed
supplied by the firmware. (#1)

In addition, it wires it up for ARM and arm64, by invoking the EFI_RNG_PROTOCOL
UEFI protocol from the stub, and populating such a UEFI config table using its
output.

How to wire this up for x86 is left as an exercise for the Intel developer.

Ard Biesheuvel (2):
  efi: add support for seeding the RNG from a UEFI config table
  efi/arm*: libstub: invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table

 drivers/firmware/efi/efi.c              | 26 +++++++++++
 drivers/firmware/efi/libstub/arm-stub.c |  2 +
 drivers/firmware/efi/libstub/efistub.h  |  2 +
 drivers/firmware/efi/libstub/random.c   | 48 ++++++++++++++++++++
 include/linux/efi.h                     |  9 ++++
 5 files changed, 87 insertions(+)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
       [not found] ` <1475749646-10844-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
@ 2016-10-06 10:27   ` Ard Biesheuvel
  2016-10-19 11:02     ` Matt Fleming
  2016-10-19 11:09     ` Mark Rutland
  2016-10-06 10:27   ` [PATCH 2/2] efi/arm*: libstub: invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table Ard Biesheuvel
  1 sibling, 2 replies; 11+ messages in thread
From: Ard Biesheuvel @ 2016-10-06 10:27 UTC (permalink / raw)
  To: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: mark.rutland-5wv7dgnIgG8, Ard Biesheuvel

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.

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-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/firmware/efi/efi.c | 26 ++++++++++++++++++++
 include/linux/efi.h        |  8 ++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 1ac199cd75e7..c8ae40f9b674 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -24,6 +24,7 @@
 #include <linux/of_fdt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/random.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <linux/ucs2_string.h>
@@ -48,6 +49,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);
 
@@ -438,6 +440,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},
 };
 
@@ -499,6 +502,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;
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 2d089487d2da..85e28b138cdd 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 */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/2] efi/arm*: libstub: invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table
       [not found] ` <1475749646-10844-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
  2016-10-06 10:27   ` [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table Ard Biesheuvel
@ 2016-10-06 10:27   ` Ard Biesheuvel
  1 sibling, 0 replies; 11+ messages in thread
From: Ard Biesheuvel @ 2016-10-06 10:27 UTC (permalink / raw)
  To: linux-efi-u79uwXL29TY76Z2rM5mHXA,
	matt-mF/unelCI9GS6iBeEJttW/XRex20P6io,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: mark.rutland-5wv7dgnIgG8, Ard Biesheuvel

Invoke the EFI_RNG_PROTOCOL protocol in the context of the stub and
install the Linux-specific RNG seed UEFI config table. This will be
picked up by the EFI routines in the core kernel to seed the kernel
entropy pool.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/firmware/efi/libstub/arm-stub.c |  2 +
 drivers/firmware/efi/libstub/efistub.h  |  2 +
 drivers/firmware/efi/libstub/random.c   | 48 ++++++++++++++++++++
 include/linux/efi.h                     |  1 +
 4 files changed, 53 insertions(+)

diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 993aa56755f6..b4f7d78f9e8b 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -340,6 +340,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
 	if (status != EFI_SUCCESS)
 		pr_efi_err(sys_table, "Failed initrd from command line!\n");
 
+	efi_random_get_seed(sys_table);
+
 	new_fdt_addr = fdt_addr;
 	status = allocate_new_fdt_and_exit_boot(sys_table, handle,
 				&new_fdt_addr, dram_base + MAX_FDT_OFFSET,
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index ee49cd23ee63..1c57715286a7 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -62,4 +62,6 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
 
 efi_status_t check_platform_features(efi_system_table_t *sys_table_arg);
 
+efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg);
+
 #endif
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
index 0c9f58c5ba50..0109bc3a1f3f 100644
--- a/drivers/firmware/efi/libstub/random.c
+++ b/drivers/firmware/efi/libstub/random.c
@@ -141,3 +141,51 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
 
 	return status;
 }
+
+#define RANDOM_SEED_SIZE	32
+
+efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
+{
+	efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
+	efi_guid_t rng_algo_raw = EFI_RNG_ALGORITHM_RAW;
+	efi_guid_t rng_table_guid = LINUX_EFI_RANDOM_SEED_TABLE_GUID;
+	struct efi_rng_protocol *rng;
+	struct linux_efi_random_seed *seed;
+	efi_status_t status;
+
+	status = efi_call_early(locate_protocol, &rng_proto, NULL,
+				(void **)&rng);
+	if (status != EFI_SUCCESS)
+		return status;
+
+	status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
+				sizeof(*seed) + RANDOM_SEED_SIZE,
+				(void **)&seed);
+	if (status != EFI_SUCCESS)
+		return status;
+
+	status = rng->get_rng(rng, &rng_algo_raw, RANDOM_SEED_SIZE,
+			      seed->bits);
+	if (status == EFI_UNSUPPORTED)
+		/*
+		 * Use whatever algorithm we have available if the raw algorithm
+		 * is not implemented.
+		 */
+		status = rng->get_rng(rng, NULL, RANDOM_SEED_SIZE,
+				      seed->bits);
+
+	if (status != EFI_SUCCESS)
+		goto err_freepool;
+
+	seed->size = RANDOM_SEED_SIZE;
+	status = efi_call_early(install_configuration_table, &rng_table_guid,
+				seed);
+	if (status != EFI_SUCCESS)
+		goto err_freepool;
+
+	return EFI_SUCCESS;
+
+err_freepool:
+	efi_call_early(free_pool, seed);
+	return status;
+}
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 85e28b138cdd..f5a821d9b90c 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -589,6 +589,7 @@ void efi_native_runtime_setup(void);
 #define DEVICE_TREE_GUID			EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5,  0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
 #define EFI_PROPERTIES_TABLE_GUID		EFI_GUID(0x880aaca3, 0x4adc, 0x4a04,  0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5)
 #define EFI_RNG_PROTOCOL_GUID			EFI_GUID(0x3152bca5, 0xeade, 0x433d,  0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
+#define EFI_RNG_ALGORITHM_RAW			EFI_GUID(0xe43176d7, 0xb6e8, 0x4827,  0xb7, 0x84, 0x7f, 0xfd, 0xc4, 0xb6, 0x85, 0x61)
 #define EFI_MEMORY_ATTRIBUTES_TABLE_GUID	EFI_GUID(0xdcfa911d, 0x26eb, 0x469f,  0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
 #define EFI_CONSOLE_OUT_DEVICE_GUID		EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4,  0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
  2016-10-06 10:27   ` [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table Ard Biesheuvel
@ 2016-10-19 11:02     ` Matt Fleming
  2016-10-19 11:09     ` Mark Rutland
  1 sibling, 0 replies; 11+ messages in thread
From: Matt Fleming @ 2016-10-19 11:02 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: mark.rutland, linux-efi, Theodore Ts'o, Kees Cook, linux-arm-kernel

(CC'ing other potentially interested randomness folks)

On Thu, 06 Oct, at 11:27:25AM, Ard Biesheuvel wrote:
> 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.
> 
> 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>
> ---
>  drivers/firmware/efi/efi.c | 26 ++++++++++++++++++++
>  include/linux/efi.h        |  8 ++++++
>  2 files changed, 34 insertions(+)
 
This series looks fine to me. I'm leaving the patch below for the
benefit of the Ted and Kees.

> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 1ac199cd75e7..c8ae40f9b674 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -24,6 +24,7 @@
>  #include <linux/of_fdt.h>
>  #include <linux/io.h>
>  #include <linux/platform_device.h>
> +#include <linux/random.h>
>  #include <linux/slab.h>
>  #include <linux/acpi.h>
>  #include <linux/ucs2_string.h>
> @@ -48,6 +49,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);
>  
> @@ -438,6 +440,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},
>  };
>  
> @@ -499,6 +502,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;
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 2d089487d2da..85e28b138cdd 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 */
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
  2016-10-06 10:27   ` [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table Ard Biesheuvel
  2016-10-19 11:02     ` Matt Fleming
@ 2016-10-19 11:09     ` Mark Rutland
  2016-10-19 11:13       ` Ard Biesheuvel
  1 sibling, 1 reply; 11+ messages in thread
From: Mark Rutland @ 2016-10-19 11:09 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: matt, linux-efi, linux-arm-kernel

Hi Ard,

On Thu, Oct 06, 2016 at 11:27:25AM +0100, Ard Biesheuvel wrote:
> 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.
> 
> 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)

What does this mean for kexec? Won't each successive kernel look for the
table and find the same seed?

I think to some extent this mush be treated as an ABI, given cases like
kexec.

Thanks,
Mark.

> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  drivers/firmware/efi/efi.c | 26 ++++++++++++++++++++
>  include/linux/efi.h        |  8 ++++++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
> index 1ac199cd75e7..c8ae40f9b674 100644
> --- a/drivers/firmware/efi/efi.c
> +++ b/drivers/firmware/efi/efi.c
> @@ -24,6 +24,7 @@
>  #include <linux/of_fdt.h>
>  #include <linux/io.h>
>  #include <linux/platform_device.h>
> +#include <linux/random.h>
>  #include <linux/slab.h>
>  #include <linux/acpi.h>
>  #include <linux/ucs2_string.h>
> @@ -48,6 +49,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);
>  
> @@ -438,6 +440,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},
>  };
>  
> @@ -499,6 +502,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;
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 2d089487d2da..85e28b138cdd 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 */
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-efi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
  2016-10-19 11:09     ` Mark Rutland
@ 2016-10-19 11:13       ` Ard Biesheuvel
  2016-10-19 11:22         ` Matt Fleming
  0 siblings, 1 reply; 11+ messages in thread
From: Ard Biesheuvel @ 2016-10-19 11:13 UTC (permalink / raw)
  To: Mark Rutland; +Cc: Matt Fleming, linux-efi, linux-arm-kernel

On 19 October 2016 at 12:09, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi Ard,
>
> On Thu, Oct 06, 2016 at 11:27:25AM +0100, Ard Biesheuvel wrote:
>> 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.
>>
>> 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)
>
> What does this mean for kexec? Won't each successive kernel look for the
> table and find the same seed?
>

Yes. Whether this is a problem or not is context dependent: for things
like kdump, I don't think anyone cares. For other cases, having some
seed may still be better than having no seed at all.

It does mean, however, that we have to preserve the memory this table
points to for kexec boots.

> I think to some extent this mush be treated as an ABI, given cases like
> kexec.
>

Perhaps, yes. That would also allow GRUB or other EFI aware
bootloaders to generate the seed.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
  2016-10-19 11:13       ` Ard Biesheuvel
@ 2016-10-19 11:22         ` Matt Fleming
       [not found]           ` <20161019112243.GD31476-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Matt Fleming @ 2016-10-19 11:22 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: Mark Rutland, linux-efi, linux-arm-kernel

On Wed, 19 Oct, at 12:13:55PM, Ard Biesheuvel wrote:
> On 19 October 2016 at 12:09, Mark Rutland <mark.rutland@arm.com> wrote:
>
> > I think to some extent this mush be treated as an ABI, given cases like
> > kexec.
> >
> 
> Perhaps, yes. That would also allow GRUB or other EFI aware
> bootloaders to generate the seed.

If we're going to go down this route, we should try and get the GUID
into the UEFI spec.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
       [not found]           ` <20161019112243.GD31476-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
@ 2016-10-19 20:14             ` Kees Cook
       [not found]               ` <CAGXu5jJ-KTVJLwAp6iZ-tp5AKnAzSHz80yZkg4dh3uYDz3MsJw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Kees Cook @ 2016-10-19 20:14 UTC (permalink / raw)
  To: Matt Fleming
  Cc: Ard Biesheuvel, Mark Rutland, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Oct 19, 2016 at 4:22 AM, Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org> wrote:
> On Wed, 19 Oct, at 12:13:55PM, Ard Biesheuvel wrote:
>> On 19 October 2016 at 12:09, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
>>
>> > I think to some extent this mush be treated as an ABI, given cases like
>> > kexec.
>> >
>>
>> Perhaps, yes. That would also allow GRUB or other EFI aware
>> bootloaders to generate the seed.
>
> If we're going to go down this route, we should try and get the GUID
> into the UEFI spec.

It seems like maybe under UEFI, both this table (which sounds like
it'll not be rotated regularly) could be mixed with calls to
EFI_PROTOCOL_RNG by the kernel? (Similar to how kaslr is seeded?)

-Kees

-- 
Kees Cook
Nexus Security

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
       [not found]               ` <CAGXu5jJ-KTVJLwAp6iZ-tp5AKnAzSHz80yZkg4dh3uYDz3MsJw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-10-19 20:18                 ` Ard Biesheuvel
       [not found]                   ` <CAKv+Gu92dC6BK7Adb2xLvPwNXv=z15A0zhss_XVNfd+r0NA0SA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Ard Biesheuvel @ 2016-10-19 20:18 UTC (permalink / raw)
  To: Kees Cook
  Cc: Matt Fleming, Mark Rutland, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 19 October 2016 at 21:14, Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
> On Wed, Oct 19, 2016 at 4:22 AM, Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org> wrote:
>> On Wed, 19 Oct, at 12:13:55PM, Ard Biesheuvel wrote:
>>> On 19 October 2016 at 12:09, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
>>>
>>> > I think to some extent this mush be treated as an ABI, given cases like
>>> > kexec.
>>> >
>>>
>>> Perhaps, yes. That would also allow GRUB or other EFI aware
>>> bootloaders to generate the seed.
>>
>> If we're going to go down this route, we should try and get the GUID
>> into the UEFI spec.
>
> It seems like maybe under UEFI, both this table (which sounds like
> it'll not be rotated regularly)

What do you mean 'rotated'? It is generated at boot. My 2/2 patch
generates it from the stub using the EFI_RNG_PROTOCOL on ARM/arm64

> could be mixed with calls to
> EFI_PROTOCOL_RNG by the kernel? (Similar to how kaslr is seeded?)
>

That is kind of the point. KASLR is different because we need the
entropy before even jumping to C code, but for all other uses of early
entropy, this seemed like a useful approach

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
       [not found]                   ` <CAKv+Gu92dC6BK7Adb2xLvPwNXv=z15A0zhss_XVNfd+r0NA0SA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-10-19 20:20                     ` Kees Cook
       [not found]                       ` <CAGXu5jKx5cvZsBwC1AJZ3Q4CCn-nxD3Jejs5irQLRan+j305Cw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Kees Cook @ 2016-10-19 20:20 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Matt Fleming, Mark Rutland, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Oct 19, 2016 at 1:18 PM, Ard Biesheuvel
<ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On 19 October 2016 at 21:14, Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
>> On Wed, Oct 19, 2016 at 4:22 AM, Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org> wrote:
>>> On Wed, 19 Oct, at 12:13:55PM, Ard Biesheuvel wrote:
>>>> On 19 October 2016 at 12:09, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
>>>>
>>>> > I think to some extent this mush be treated as an ABI, given cases like
>>>> > kexec.
>>>> >
>>>>
>>>> Perhaps, yes. That would also allow GRUB or other EFI aware
>>>> bootloaders to generate the seed.
>>>
>>> If we're going to go down this route, we should try and get the GUID
>>> into the UEFI spec.
>>
>> It seems like maybe under UEFI, both this table (which sounds like
>> it'll not be rotated regularly)
>
> What do you mean 'rotated'? It is generated at boot. My 2/2 patch
> generates it from the stub using the EFI_RNG_PROTOCOL on ARM/arm64

Oh! I entirely misunderstood. I thought doing regular writes to EFI
variables was discouraged (since they may be stored in NVRAM that
would "wear out").

>> could be mixed with calls to
>> EFI_PROTOCOL_RNG by the kernel? (Similar to how kaslr is seeded?)
>>
>
> That is kind of the point. KASLR is different because we need the
> entropy before even jumping to C code, but for all other uses of early
> entropy, this seemed like a useful approach

Yup, cool. If the table changes per boot, yeah, my suggestion is pointless. :)

-Kees

-- 
Kees Cook
Nexus Security

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table
       [not found]                       ` <CAGXu5jKx5cvZsBwC1AJZ3Q4CCn-nxD3Jejs5irQLRan+j305Cw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-10-19 20:35                         ` Ard Biesheuvel
  0 siblings, 0 replies; 11+ messages in thread
From: Ard Biesheuvel @ 2016-10-19 20:35 UTC (permalink / raw)
  To: Kees Cook
  Cc: Matt Fleming, Mark Rutland, linux-efi-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r


> On 19 Oct 2016, at 21:20, Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
> 
> On Wed, Oct 19, 2016 at 1:18 PM, Ard Biesheuvel
> <ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
>> On 19 October 2016 at 21:14, Kees Cook <keescook-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> wrote:
>>>> On Wed, Oct 19, 2016 at 4:22 AM, Matt Fleming <matt-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org> wrote:
>>>>> On Wed, 19 Oct, at 12:13:55PM, Ard Biesheuvel wrote:
>>>>>> On 19 October 2016 at 12:09, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
>>>>>> 
>>>>>> I think to some extent this mush be treated as an ABI, given cases like
>>>>>> kexec.
>>>>>> 
>>>>> 
>>>>> Perhaps, yes. That would also allow GRUB or other EFI aware
>>>>> bootloaders to generate the seed.
>>>> 
>>>> If we're going to go down this route, we should try and get the GUID
>>>> into the UEFI spec.
>>> 
>>> It seems like maybe under UEFI, both this table (which sounds like
>>> it'll not be rotated regularly)
>> 
>> What do you mean 'rotated'? It is generated at boot. My 2/2 patch
>> generates it from the stub using the EFI_RNG_PROTOCOL on ARM/arm64
> 
> Oh! I entirely misunderstood. I thought doing regular writes to EFI
> variables was discouraged (since they may be stored in NVRAM that
> would "wear out")

Uefi config tables only live in memory. They are used to provide the os with data that the firmware generates at boot, e.g., smbios and acpi tables etc

>>> could be mixed with calls to
>>> EFI_PROTOCOL_RNG by the kernel? (Similar to how kaslr is seeded?)
>>> 
>> 
>> That is kind of the point. KASLR is different because we need the
>> entropy before even jumping to C code, but for all other uses of early
>> entropy, this seemed like a useful approach
> 
> Yup, cool. If the table changes per boot, yeah, my suggestion is pointless. :)
> 

Yes, but as Mark pointed out, we need to decide how to handle kexec, which does not go through the stub

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-10-19 20:35 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-06 10:27 [PATCH 0/2] efi: add support for seeding the kernel RNG from UEFI Ard Biesheuvel
     [not found] ` <1475749646-10844-1-git-send-email-ard.biesheuvel-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2016-10-06 10:27   ` [PATCH 1/2] efi: add support for seeding the RNG from a UEFI config table Ard Biesheuvel
2016-10-19 11:02     ` Matt Fleming
2016-10-19 11:09     ` Mark Rutland
2016-10-19 11:13       ` Ard Biesheuvel
2016-10-19 11:22         ` Matt Fleming
     [not found]           ` <20161019112243.GD31476-mF/unelCI9GS6iBeEJttW/XRex20P6io@public.gmane.org>
2016-10-19 20:14             ` Kees Cook
     [not found]               ` <CAGXu5jJ-KTVJLwAp6iZ-tp5AKnAzSHz80yZkg4dh3uYDz3MsJw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-10-19 20:18                 ` Ard Biesheuvel
     [not found]                   ` <CAKv+Gu92dC6BK7Adb2xLvPwNXv=z15A0zhss_XVNfd+r0NA0SA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-10-19 20:20                     ` Kees Cook
     [not found]                       ` <CAGXu5jKx5cvZsBwC1AJZ3Q4CCn-nxD3Jejs5irQLRan+j305Cw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-10-19 20:35                         ` Ard Biesheuvel
2016-10-06 10:27   ` [PATCH 2/2] efi/arm*: libstub: invoke EFI_RNG_PROTOCOL to seed the UEFI RNG table Ard Biesheuvel

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).