2014-02-12 01:33:31

by Laura Abbott

[permalink] [raw]
Subject: [RFC/PATCH 0/3] Add devicetree scanning for randomness

Hi,

This is an RFC to seed the random number pool earlier when using devicetree.
The big issue this is trying to solve is the fact that the stack canary for
ARM tends to be the same across bootups of the same device. This is because
the random number pools do not get initialized until after the canary has
been set up. The canary can be moved later, but in general there is still
no way to reliably get random numbers early for other features (e.g. vector
randomization).

The goal here is to allow devices to add to the random pools via
add_device_randomness or some other method of their chosing at FDT time.
I realize that ARCH_RANDOM is already available but this didn't work because
1) ARCH_RANDOM is not multi-platform compatible without added
infrastructure to ARM
2) There is no uniform way to generate the random numbers which
would require an additional framework (same result as #1, different
reasons)
3) Given there is no uniform way to generate the random numbers, it seems
unlikely that 'early' random numbers would work the same as 'non-early'
random number which adds another layer of complexity.

The big reason to skip ARCH_RANDOM though is that the random number generation
we have would be reasonable if only seeded earlier.

Thanks,
Laura


Laura Abbott (3):
of: Add early randomness hooks
arm: Add ARCH_WANT_OF_RANDOMNESS
init: Move stack canary initialization after setup_arch

arch/arm/Kconfig | 3 ++
arch/arm/kernel/vmlinux.lds.S | 1 +
drivers/of/Kconfig | 7 ++++++
drivers/of/Makefile | 1 +
drivers/of/fdt.c | 7 ++++++
drivers/of/of_randomness.c | 43 +++++++++++++++++++++++++++++++++++++
include/asm-generic/vmlinux.lds.h | 5 ++++
include/linux/of_randomness.h | 42 ++++++++++++++++++++++++++++++++++++
init/main.c | 9 +++----
9 files changed, 113 insertions(+), 5 deletions(-)
create mode 100644 drivers/of/of_randomness.c
create mode 100644 include/linux/of_randomness.h

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


2014-02-12 01:33:36

by Laura Abbott

[permalink] [raw]
Subject: [RFC/PATCH 2/3] arm: Add ARCH_WANT_OF_RANDOMNESS

The stack canary for ARM is currently the same across reboots
due to lack of randomness early enough. Add ARCH_WANT_OF_RANDOMNESS
to allow devices to add whatever randomness they need.

Signed-off-by: Laura Abbott <[email protected]>
---
arch/arm/Kconfig | 3 +++
arch/arm/kernel/vmlinux.lds.S | 1 +
2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e254198..7ab0db1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -222,6 +222,9 @@ config NEED_RET_TO_USER
config ARCH_MTD_XIP
bool

+config ARCH_WANT_OF_RANDOMNESS
+ def_bool n
+
config VECTORS_BASE
hex
default 0xffff0000 if MMU || CPU_HIGH_VECTOR
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 7bcee5c..2198258 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -202,6 +202,7 @@ SECTIONS
INIT_SETUP(16)
INIT_CALLS
CON_INITCALL
+ EARLY_RANDOM_FUNCS
SECURITY_INITCALL
INIT_RAM_FS
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

2014-02-12 01:33:34

by Laura Abbott

[permalink] [raw]
Subject: [RFC/PATCH 1/3] of: Add early randomness hooks

Until randomness is added to the kernel's pools, random
numbers returned may not be truly 'random'. Randomness comes
from a variety of sources in the kernel but much of the
randomness comes from device related initialization. This
means that any random numbers that are needed before drivers
are initialized (e.g. stack canary) may not be truely random.
Fix this by build a list of functions that can be used to add
randomness to the kernel's pools very early. The functions are
tied to particular compatible strings of devicetree nodes. The
flattened devicetree is scanned and if the node is present the
function is called. Note that this must happen on the flattened
devicetree to ensure the randomness gets added to the pool
early enough to make a difference.

Signed-off-by: Laura Abbott <[email protected]>
---
drivers/of/Kconfig | 7 ++++++
drivers/of/Makefile | 1 +
drivers/of/fdt.c | 7 ++++++
drivers/of/of_randomness.c | 43 +++++++++++++++++++++++++++++++++++++
include/asm-generic/vmlinux.lds.h | 5 ++++
include/linux/of_randomness.h | 42 ++++++++++++++++++++++++++++++++++++
6 files changed, 105 insertions(+), 0 deletions(-)
create mode 100644 drivers/of/of_randomness.c
create mode 100644 include/linux/of_randomness.h

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index c6973f1..6ae4a38 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -75,4 +75,11 @@ config OF_MTD
depends on MTD
def_bool y

+config OF_RANDOMNESS
+ def_bool n
+ depends on OF_FLATTREE && ARCH_WANT_OF_RANDOMNESS
+ help
+ OpenFirmware hooks to scan for device randomness
+ via flat devicetree
+
endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index efd0510..0ce02d1 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
obj-$(CONFIG_OF_PCI) += of_pci.o
obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
obj-$(CONFIG_OF_MTD) += of_mtd.o
+obj-$(CONFIG_OF_RANDOMNESS) += of_randomness.o
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 758b4f8..c25960e 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_fdt.h>
+#include <linux/of_randomness.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -889,6 +890,12 @@ bool __init early_init_dt_scan(void *params)
/* Setup memory, calling early_init_dt_add_memory_arch */
of_scan_flat_dt(early_init_dt_scan_memory, NULL);

+#ifdef CONFIG_OF_RANDOMNESS
+ /* Add device randomness */
+ of_scan_flat_dt(early_init_dt_scan_early_randomness, NULL);
+#endif
+
+
return true;
}

diff --git a/drivers/of/of_randomness.c b/drivers/of/of_randomness.c
new file mode 100644
index 0000000..9d23624
--- /dev/null
+++ b/drivers/of/of_randomness.c
@@ -0,0 +1,43 @@
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/random.h>
+#include <linux/string.h>
+#include <linux/of_randomness.h>
+#include <linux/of_fdt.h>
+
+int __init early_init_dt_scan_early_randomness(unsigned long node,
+ const char *uname,
+ int depth, void *data)
+{
+ struct early_random_func *f;
+ void *prop;
+ unsigned long len;
+
+ prop = of_get_flat_dt_prop(node, "compatible", &len);
+
+ if (!prop)
+ return 0;
+
+ for (f = __early_random_funcs_start;
+ f < __early_random_funcs_end;
+ f++) {
+ pr_debug("Check compat %s addr %p against %s\n",
+ f->compat_string, f->add_randomness, (char *)prop);
+ if (strcmp(prop, f->compat_string) == 0)
+ f->add_randomness(node);
+ }
+
+ return 0;
+}
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index bc2121f..e5b8be9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -645,6 +645,11 @@
*(.security_initcall.init) \
VMLINUX_SYMBOL(__security_initcall_end) = .;

+#define EARLY_RANDOM_FUNCS \
+ VMLINUX_SYMBOL(__early_random_funcs_start) = .; \
+ *(.earlyrandom.init) \
+ VMLINUX_SYMBOL(__early_random_funcs_end) = .;
+
#ifdef CONFIG_BLK_DEV_INITRD
#define INIT_RAM_FS \
. = ALIGN(4); \
diff --git a/include/linux/of_randomness.h b/include/linux/of_randomness.h
new file mode 100644
index 0000000..b8b4532
--- /dev/null
+++ b/include/linux/of_randomness.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef LINUX_OF_RANDOMNESS_H
+#define LINUX_OF_RANDOMNESS_H
+
+extern int early_init_dt_scan_early_randomness(unsigned long node,
+ const char *uname,
+ int depth, void *data);
+
+#ifdef CONFIG_OF_RANDOMNESS
+
+struct early_random_func {
+ char *compat_string;
+ void (*add_randomness)(unsigned long fdt_node);
+};
+
+extern struct early_random_func __early_random_funcs_start[];
+extern struct early_random_func __early_random_funcs_end[];
+
+#define EARLY_RANDOM_FUNC(c, f) \
+static struct early_random_func __early_rand##f __used \
+ __attribute((__section__(".earlyrandom.init"))) = { \
+ .compat_string = c, \
+ .add_randomness = f\
+ } \
+
+#else
+
+#define EARLY_RANDOM_FUNC(f, e)
+#endif
+
+#endif
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

2014-02-12 01:34:11

by Laura Abbott

[permalink] [raw]
Subject: [RFC/PATCH 3/3] init: Move stack canary initialization after setup_arch

Stack canary intialization involves getting a random number.
Getting this random number may involve accessing caches or other
architectural specific features which are not available until
after the architecture is setup. Move the stack canary initialization
later to accomodate this.

Signed-off-by: Laura Abbott <[email protected]>
---
init/main.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/init/main.c b/init/main.c
index eb03090..63d0596 100644
--- a/init/main.c
+++ b/init/main.c
@@ -489,11 +489,6 @@ asmlinkage void __init start_kernel(void)
smp_setup_processor_id();
debug_objects_early_init();

- /*
- * Set up the the initial canary ASAP:
- */
- boot_init_stack_canary();
-
cgroup_init_early();

local_irq_disable();
@@ -507,6 +502,10 @@ asmlinkage void __init start_kernel(void)
page_address_init();
pr_notice("%s", linux_banner);
setup_arch(&command_line);
+ /*
+ * Set up the the initial canary ASAP:
+ */
+ boot_init_stack_canary();
mm_init_owner(&init_mm, &init_task);
mm_init_cpumask(&init_mm);
setup_command_line(command_line);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

2014-02-12 11:51:42

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wednesday 12 February 2014, Laura Abbott wrote:
> This is an RFC to seed the random number pool earlier when using devicetree.
> The big issue this is trying to solve is the fact that the stack canary for
> ARM tends to be the same across bootups of the same device. This is because
> the random number pools do not get initialized until after the canary has
> been set up. The canary can be moved later, but in general there is still
> no way to reliably get random numbers early for other features (e.g. vector
> randomization).

Implementation-wise this looks reasonable, and it obviously addresses a
very real problem.

> The goal here is to allow devices to add to the random pools via
> add_device_randomness or some other method of their chosing at FDT time.
> I realize that ARCH_RANDOM is already available but this didn't work because
> 1) ARCH_RANDOM is not multi-platform compatible without added
> infrastructure to ARM

That could certainly be done, but I agree that a more generic
approach like you did is nicer. One thing that might be useful
would be to wire up your OF_RANDOM infrastructure as a generic
implementation of ARCH_RANDOM, and merge your header file into
include/asm-generic/archrandom.h, with an added way to call
arch_get_random_long() for the devices you add.

> The big reason to skip ARCH_RANDOM though is that the random number generation
> we have would be reasonable if only seeded earlier.

Yes, makes sense.

I also wonder if we should add a 'trivial' implementation that just
reads a DT property full of random numbers to use as either an initial
seed, or to feed into arch_get_random_long(). This would allow the
boot loader to pass any entropy it has already gathered into the kernel,
but leaves the danger that people might pass static not-so-random data
through a precompiled dtb file ;-). If we get the boot loaders to be
smart enough, doing only this would be a much simpler kernel implementation
than your suggestion, but I'm not sure how far I want to trust boot loaders.

Another possibilitiy is to mix in the any contents of a "local-mac-address"
property into the entropy at early DT probing, which would still be
deterministic for a given machine and should not count as entropty,
but at least give each machine with this property a unique seed in the
absence of any other entropy source.

Arnd

2014-02-12 16:48:01

by Grant Likely

[permalink] [raw]
Subject: Re: [RFC/PATCH 1/3] of: Add early randomness hooks

On Tue, 11 Feb 2014 17:33:23 -0800, Laura Abbott <[email protected]> wrote:
> Until randomness is added to the kernel's pools, random
> numbers returned may not be truly 'random'. Randomness comes
> from a variety of sources in the kernel but much of the
> randomness comes from device related initialization. This
> means that any random numbers that are needed before drivers
> are initialized (e.g. stack canary) may not be truely random.
> Fix this by build a list of functions that can be used to add
> randomness to the kernel's pools very early. The functions are
> tied to particular compatible strings of devicetree nodes. The
> flattened devicetree is scanned and if the node is present the
> function is called. Note that this must happen on the flattened
> devicetree to ensure the randomness gets added to the pool
> early enough to make a difference.
>
> Signed-off-by: Laura Abbott <[email protected]>

Intriguing solution. Looks good to me, but some comments below...

> ---
> drivers/of/Kconfig | 7 ++++++
> drivers/of/Makefile | 1 +
> drivers/of/fdt.c | 7 ++++++
> drivers/of/of_randomness.c | 43 +++++++++++++++++++++++++++++++++++++
> include/asm-generic/vmlinux.lds.h | 5 ++++
> include/linux/of_randomness.h | 42 ++++++++++++++++++++++++++++++++++++
> 6 files changed, 105 insertions(+), 0 deletions(-)
> create mode 100644 drivers/of/of_randomness.c
> create mode 100644 include/linux/of_randomness.h
>
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index c6973f1..6ae4a38 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -75,4 +75,11 @@ config OF_MTD
> depends on MTD
> def_bool y
>
> +config OF_RANDOMNESS
> + def_bool n

There should be the option to turn this off, particularly if it turns
out to be expensive in terms of boot time.

> + depends on OF_FLATTREE && ARCH_WANT_OF_RANDOMNESS
> + help
> + OpenFirmware hooks to scan for device randomness
> + via flat devicetree

Inconsistent whitespace

> +
> endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index efd0510..0ce02d1 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
> obj-$(CONFIG_OF_PCI) += of_pci.o
> obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
> obj-$(CONFIG_OF_MTD) += of_mtd.o
> +obj-$(CONFIG_OF_RANDOMNESS) += of_randomness.o
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 758b4f8..c25960e 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -15,6 +15,7 @@
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/of_fdt.h>
> +#include <linux/of_randomness.h>
> #include <linux/string.h>
> #include <linux/errno.h>
> #include <linux/slab.h>
> @@ -889,6 +890,12 @@ bool __init early_init_dt_scan(void *params)
> /* Setup memory, calling early_init_dt_add_memory_arch */
> of_scan_flat_dt(early_init_dt_scan_memory, NULL);
>
> +#ifdef CONFIG_OF_RANDOMNESS
> + /* Add device randomness */
> + of_scan_flat_dt(early_init_dt_scan_early_randomness, NULL);
> +#endif

Drop the #ifdef in fdt.c and use static inlines in the header file. One
that does the of_scan_flat_dt() call, and one empty stub for the
!CONFIG_OF_RANDOMNESS case.

I would also bypass the of_scan_flat_dt call entirely if the
__early_random_funcs list is empty.

> +
> +
> return true;
> }
>
> diff --git a/drivers/of/of_randomness.c b/drivers/of/of_randomness.c
> new file mode 100644
> index 0000000..9d23624
> --- /dev/null
> +++ b/drivers/of/of_randomness.c
> @@ -0,0 +1,43 @@
> +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/random.h>
> +#include <linux/string.h>
> +#include <linux/of_randomness.h>
> +#include <linux/of_fdt.h>
> +
> +int __init early_init_dt_scan_early_randomness(unsigned long node,
> + const char *uname,
> + int depth, void *data)
> +{
> + struct early_random_func *f;
> + void *prop;
> + unsigned long len;
> +
> + prop = of_get_flat_dt_prop(node, "compatible", &len);
> +
> + if (!prop)
> + return 0;
> +
> + for (f = __early_random_funcs_start;
> + f < __early_random_funcs_end;
> + f++) {
> + pr_debug("Check compat %s addr %p against %s\n",
> + f->compat_string, f->add_randomness, (char *)prop);
> + if (strcmp(prop, f->compat_string) == 0)
> + f->add_randomness(node);
> + }
> +
> + return 0;
> +}
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index bc2121f..e5b8be9 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -645,6 +645,11 @@
> *(.security_initcall.init) \
> VMLINUX_SYMBOL(__security_initcall_end) = .;
>
> +#define EARLY_RANDOM_FUNCS \
> + VMLINUX_SYMBOL(__early_random_funcs_start) = .; \
> + *(.earlyrandom.init) \
> + VMLINUX_SYMBOL(__early_random_funcs_end) = .;
> +
> #ifdef CONFIG_BLK_DEV_INITRD
> #define INIT_RAM_FS \
> . = ALIGN(4); \
> diff --git a/include/linux/of_randomness.h b/include/linux/of_randomness.h
> new file mode 100644
> index 0000000..b8b4532
> --- /dev/null
> +++ b/include/linux/of_randomness.h
> @@ -0,0 +1,42 @@
> +/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +#ifndef LINUX_OF_RANDOMNESS_H
> +#define LINUX_OF_RANDOMNESS_H
> +
> +extern int early_init_dt_scan_early_randomness(unsigned long node,
> + const char *uname,
> + int depth, void *data);
> +
> +#ifdef CONFIG_OF_RANDOMNESS
> +
> +struct early_random_func {
> + char *compat_string;
> + void (*add_randomness)(unsigned long fdt_node);
> +};
> +
> +extern struct early_random_func __early_random_funcs_start[];
> +extern struct early_random_func __early_random_funcs_end[];
> +
> +#define EARLY_RANDOM_FUNC(c, f) \
> +static struct early_random_func __early_rand##f __used \
> + __attribute((__section__(".earlyrandom.init"))) = { \
> + .compat_string = c, \
> + .add_randomness = f\
> + } \
> +
> +#else
> +
> +#define EARLY_RANDOM_FUNC(f, e)
> +#endif
> +
> +#endif
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
>

2014-02-12 16:49:14

by Grant Likely

[permalink] [raw]
Subject: Re: [RFC/PATCH 2/3] arm: Add ARCH_WANT_OF_RANDOMNESS

On Tue, 11 Feb 2014 17:33:24 -0800, Laura Abbott <[email protected]> wrote:
> The stack canary for ARM is currently the same across reboots
> due to lack of randomness early enough. Add ARCH_WANT_OF_RANDOMNESS
> to allow devices to add whatever randomness they need.
>
> Signed-off-by: Laura Abbott <[email protected]>

Do you have a draft patch for a user of this yet?

g.

> ---
> arch/arm/Kconfig | 3 +++
> arch/arm/kernel/vmlinux.lds.S | 1 +
> 2 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index e254198..7ab0db1 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -222,6 +222,9 @@ config NEED_RET_TO_USER
> config ARCH_MTD_XIP
> bool
>
> +config ARCH_WANT_OF_RANDOMNESS
> + def_bool n
> +
> config VECTORS_BASE
> hex
> default 0xffff0000 if MMU || CPU_HIGH_VECTOR
> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index 7bcee5c..2198258 100644
> --- a/arch/arm/kernel/vmlinux.lds.S
> +++ b/arch/arm/kernel/vmlinux.lds.S
> @@ -202,6 +202,7 @@ SECTIONS
> INIT_SETUP(16)
> INIT_CALLS
> CON_INITCALL
> + EARLY_RANDOM_FUNCS
> SECURITY_INITCALL
> INIT_RAM_FS
> }
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
>

2014-02-12 17:46:11

by Jason Cooper

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

Laura,

Sorry to hijack the thread (sort of). :)

+ Kees Cook

On Wed, Feb 12, 2014 at 12:51:05PM +0100, Arnd Bergmann wrote:
> On Wednesday 12 February 2014, Laura Abbott wrote:
> > This is an RFC to seed the random number pool earlier when using devicetree.
> > The big issue this is trying to solve is the fact that the stack canary for
> > ARM tends to be the same across bootups of the same device. This is because
> > the random number pools do not get initialized until after the canary has
> > been set up. The canary can be moved later, but in general there is still
> > no way to reliably get random numbers early for other features (e.g. vector
> > randomization).
>
> Implementation-wise this looks reasonable, and it obviously addresses a
> very real problem.
>
> > The goal here is to allow devices to add to the random pools via
> > add_device_randomness or some other method of their chosing at FDT time.
> > I realize that ARCH_RANDOM is already available but this didn't work because
> > 1) ARCH_RANDOM is not multi-platform compatible without added
> > infrastructure to ARM
>
> That could certainly be done, but I agree that a more generic
> approach like you did is nicer. One thing that might be useful
> would be to wire up your OF_RANDOM infrastructure as a generic
> implementation of ARCH_RANDOM, and merge your header file into
> include/asm-generic/archrandom.h, with an added way to call
> arch_get_random_long() for the devices you add.
>
> > The big reason to skip ARCH_RANDOM though is that the random number generation
> > we have would be reasonable if only seeded earlier.
>
> Yes, makes sense.
>
> I also wonder if we should add a 'trivial' implementation that just
> reads a DT property full of random numbers to use as either an initial
> seed, or to feed into arch_get_random_long(). This would allow the
> boot loader to pass any entropy it has already gathered into the kernel,
> but leaves the danger that people might pass static not-so-random data
> through a precompiled dtb file ;-). If we get the boot loaders to be
> smart enough, doing only this would be a much simpler kernel implementation
> than your suggestion, but I'm not sure how far I want to trust boot loaders.

I brought this up at last weeks devicetree irc meeting. My goal is to
provide early randomness for kaslr on ARM. Currently, my idea is modify
the init script to save an additional random seed from /dev/urandom to
/boot/random-seed.

The bootloader would then load this file into ram, and pass the
address/size to the kernel either via dt, or commandline. kaslr (run in
the decompressor) would consume some of this randomness, and then
random.c would consume the rest in a non-crediting initialization.

While not ideal, it works in absence of an HRNG, and is no worse than
the current situation of storing the seed in /var/lib/misc/random-seed.
It also doesn't require modification of the bootloaders. Just an
updated kernel, and update the bootloader environment to load the
seed.

Unfortunately, it's an idea so far. I have one project to get off of my
plate, then this is next :)

thx,

Jason.

2014-02-12 18:14:03

by Olof Johansson

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 9:45 AM, Jason Cooper <[email protected]> wrote:

> I brought this up at last weeks devicetree irc meeting. My goal is to
> provide early randomness for kaslr on ARM. Currently, my idea is modify
> the init script to save an additional random seed from /dev/urandom to
> /boot/random-seed.
>
> The bootloader would then load this file into ram, and pass the
> address/size to the kernel either via dt, or commandline. kaslr (run in
> the decompressor) would consume some of this randomness, and then
> random.c would consume the rest in a non-crediting initialization.
>
> While not ideal, it works in absence of an HRNG, and is no worse than
> the current situation of storing the seed in /var/lib/misc/random-seed.
> It also doesn't require modification of the bootloaders. Just an
> updated kernel, and update the bootloader environment to load the
> seed.

Hmm. There are some drawbacks with this -- it assumes you can "just
update the bootloader environment" which in general isn't easy to do.
Also, you can't assume that /boot is writable or exists on all
embedded systems.

In general, taking both runtime and system-dependend data and using
that to see entropy is a good idea. For example, device trees that
contain serial numbers and mac addresses for the individual system. I
think x86 feeds the DMI table in for similar purposes.

If that can be amended on some systems with a runtime seed (from
/boot), that's good but we can't rely on it.


-Olof

2014-02-12 18:18:16

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wednesday 12 February 2014 12:45:54 Jason Cooper wrote:
> I brought this up at last weeks devicetree irc meeting. My goal is to
> provide early randomness for kaslr on ARM. Currently, my idea is modify
> the init script to save an additional random seed from /dev/urandom to
> /boot/random-seed.
>
> The bootloader would then load this file into ram, and pass the
> address/size to the kernel either via dt, or commandline. kaslr (run in
> the decompressor) would consume some of this randomness, and then
> random.c would consume the rest in a non-crediting initialization.

I like the idea, but wouldn't it be easier to pass actual random data
using DT, rather than the address/size? That way we could even
use the same DT binding for passing randomness from the bootloader,
whereever it may have found that.

If the bootloader has internet connectivity, it could even mix in
some data from http://www.random.org/cgi-bin/randbyte?nbytes=256&format=f
;-)

Arnd

2014-02-12 18:20:09

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 12:45:54PM -0500, Jason Cooper wrote:

> The bootloader would then load this file into ram, and pass the
> address/size to the kernel either via dt, or commandline. kaslr (run in
> the decompressor) would consume some of this randomness, and then
> random.c would consume the rest in a non-crediting initialization.

Sure is a neat idea, but I think in general it would probably be smart
to include the entire FDT blob in the early random pool, that way you
get MACs and other machine unique data too.

>From there it is a small step to encourage bootloaders to include
boot-time-variable data in the DT like like 'boot time of day', 'cycle
counter', 'random blob', etc.

Then you just need the bootloader to dump the random-seed file into a
DT property.

Or have the bootloader fetch randomness from any HWRNG it has a driver
for. (eg a TPM)

Jason

2014-02-12 18:32:41

by Jason Cooper

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 10:13:59AM -0800, Olof Johansson wrote:
> On Wed, Feb 12, 2014 at 9:45 AM, Jason Cooper <[email protected]> wrote:
>
> > I brought this up at last weeks devicetree irc meeting. My goal is to
> > provide early randomness for kaslr on ARM. Currently, my idea is modify
> > the init script to save an additional random seed from /dev/urandom to
> > /boot/random-seed.
> >
> > The bootloader would then load this file into ram, and pass the
> > address/size to the kernel either via dt, or commandline. kaslr (run in
> > the decompressor) would consume some of this randomness, and then
> > random.c would consume the rest in a non-crediting initialization.
> >
> > While not ideal, it works in absence of an HRNG, and is no worse than
> > the current situation of storing the seed in /var/lib/misc/random-seed.
> > It also doesn't require modification of the bootloaders. Just an
> > updated kernel, and update the bootloader environment to load the
> > seed.
>
> Hmm. There are some drawbacks with this -- it assumes you can "just
> update the bootloader environment" which in general isn't easy to do.

true, the scope of my experience is consumer grade NASs, routers and
APs. At the very least, it's much easier than upgrading the bootloader.

Also, my pov is as a hobbyist modifying devices post-sale. The idea is
something I could add to my existing boxes without having to upgrade the
bootloaders.

> Also, you can't assume that /boot is writable or exists on all
> embedded systems.

In systems missing this capability, they often have the ability to
update the kernel. All that's needed is one block of flash. Current
random-seed size is 512 bytes. I'm not saying it's easy or desirable.
But for folks who feel it's necessary to have kaslr on embedded devices,
it would facilitate better random numbers. "Better" meaning much harder
for an attacker to guess.

> In general, taking both runtime and system-dependend data and using
> that to see entropy is a good idea.

Of course, I wasn't arguing for one or the other. As you said later, in
situations where you can't feed in a seed file, MAC addresses and serial
numbers are better than nothing.

thx,

Jason.

2014-02-12 18:45:30

by Jason Cooper

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 07:17:41PM +0100, Arnd Bergmann wrote:
> On Wednesday 12 February 2014 12:45:54 Jason Cooper wrote:
> > I brought this up at last weeks devicetree irc meeting. My goal is to
> > provide early randomness for kaslr on ARM. Currently, my idea is modify
> > the init script to save an additional random seed from /dev/urandom to
> > /boot/random-seed.
> >
> > The bootloader would then load this file into ram, and pass the
> > address/size to the kernel either via dt, or commandline. kaslr (run in
> > the decompressor) would consume some of this randomness, and then
> > random.c would consume the rest in a non-crediting initialization.
>
> I like the idea, but wouldn't it be easier to pass actual random data
> using DT, rather than the address/size?

I thought about that at first, but that requires either that the
bootloader be upgraded to insert the data, or that userspace is
modifying the dtb at least twice per boot.

I chose address/size to facilitate modifying existing/fielded devices.
The user could modify the dtb once, and modify the bootloader
environment to load X amount to Y address. As a fallback, it could be
expressed on the commandline for non-DT bootloaders.

So I'm not against the idea of random-seed,{start,size} and a
random-seed,blob. I would just like the former to be available for
folks interested in the capability on existing hardware w/o upgrading
the bootloader.

> That way we could even use the same DT binding for passing randomness
> from the bootloader, whereever it may have found that.

The problem lies in defining "whereever" ;)

> If the bootloader has internet connectivity, it could even mix in
> some data from http://www.random.org/cgi-bin/randbyte?nbytes=256&format=f
> ;-)

Gah! Arnd, you just about gave me a heart attack. And http no less.

thx,

Jason.

2014-02-12 18:52:14

by Jason Cooper

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 11:20:00AM -0700, Jason Gunthorpe wrote:
> On Wed, Feb 12, 2014 at 12:45:54PM -0500, Jason Cooper wrote:
>
> > The bootloader would then load this file into ram, and pass the
> > address/size to the kernel either via dt, or commandline. kaslr (run in
> > the decompressor) would consume some of this randomness, and then
> > random.c would consume the rest in a non-crediting initialization.
>
> Sure is a neat idea, but I think in general it would probably be smart
> to include the entire FDT blob in the early random pool, that way you
> get MACs and other machine unique data too.

Sure.

> From there it is a small step to encourage bootloaders to include
> boot-time-variable data in the DT like like 'boot time of day', 'cycle
> counter', 'random blob', etc.

I like it.

> Then you just need the bootloader to dump the random-seed file into a
> DT property.

Yes, see my response to Arnd re the binding. I'm also interested in
making it easier for devices already in the field. iow, without
upgrading the bootloader.

> Or have the bootloader fetch randomness from any HWRNG it has a driver
> for. (eg a TPM)

Depends on who you're protecting against. I'd prefer to have that
called out as a separate blob in the DT so the kernel could decide
whether to trust it explicitly, or mix it like random.c already does
with RDRAND.

thx,

Jason.

2014-02-12 19:12:34

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wednesday 12 February 2014 13:45:21 Jason Cooper wrote:
> On Wed, Feb 12, 2014 at 07:17:41PM +0100, Arnd Bergmann wrote:
> > On Wednesday 12 February 2014 12:45:54 Jason Cooper wrote:
> > > I brought this up at last weeks devicetree irc meeting. My goal is to
> > > provide early randomness for kaslr on ARM. Currently, my idea is modify
> > > the init script to save an additional random seed from /dev/urandom to
> > > /boot/random-seed.
> > >
> > > The bootloader would then load this file into ram, and pass the
> > > address/size to the kernel either via dt, or commandline. kaslr (run in
> > > the decompressor) would consume some of this randomness, and then
> > > random.c would consume the rest in a non-crediting initialization.
> >
> > I like the idea, but wouldn't it be easier to pass actual random data
> > using DT, rather than the address/size?
>
> I thought about that at first, but that requires either that the
> bootloader be upgraded to insert the data, or that userspace is
> modifying the dtb at least twice per boot.
>
> I chose address/size to facilitate modifying existing/fielded devices.
> The user could modify the dtb once, and modify the bootloader
> environment to load X amount to Y address. As a fallback, it could be
> expressed on the commandline for non-DT bootloaders.

Ah, so you are interested in boot loaders that can be scripted to do
what you had in mind but cannot be scripted to add or modify a DT
property. I hadn't considered that, but you are probably right that
this is at least 90% of the systems you'd find in the wild today.

Thinking this a bit further, I wonder if (at least upstream) u-boot
has a way to modify DT properties in a scripted way that would allow
the direct property. It sounds like a generally useful feature not
just for randomness, so if that doesn't already work, maybe someone
can implement it. In the simplest case, you'd only need to find the
address of an existing property in the dtb and load a file to
that location.

Arnd

2014-02-12 19:44:00

by Jason Cooper

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 08:12:23PM +0100, Arnd Bergmann wrote:
> On Wednesday 12 February 2014 13:45:21 Jason Cooper wrote:
> > On Wed, Feb 12, 2014 at 07:17:41PM +0100, Arnd Bergmann wrote:
> > > On Wednesday 12 February 2014 12:45:54 Jason Cooper wrote:
> > > > I brought this up at last weeks devicetree irc meeting. My goal is to
> > > > provide early randomness for kaslr on ARM. Currently, my idea is modify
> > > > the init script to save an additional random seed from /dev/urandom to
> > > > /boot/random-seed.
> > > >
> > > > The bootloader would then load this file into ram, and pass the
> > > > address/size to the kernel either via dt, or commandline. kaslr (run in
> > > > the decompressor) would consume some of this randomness, and then
> > > > random.c would consume the rest in a non-crediting initialization.
> > >
> > > I like the idea, but wouldn't it be easier to pass actual random data
> > > using DT, rather than the address/size?
> >
> > I thought about that at first, but that requires either that the
> > bootloader be upgraded to insert the data, or that userspace is
> > modifying the dtb at least twice per boot.
> >
> > I chose address/size to facilitate modifying existing/fielded devices.
> > The user could modify the dtb once, and modify the bootloader
> > environment to load X amount to Y address. As a fallback, it could be
> > expressed on the commandline for non-DT bootloaders.
>
> Ah, so you are interested in boot loaders that can be scripted to do
> what you had in mind but cannot be scripted to add or modify a DT
> property. I hadn't considered that, but you are probably right that
> this is at least 90% of the systems you'd find in the wild today.

Yes, exactly.

> Thinking this a bit further, I wonder if (at least upstream) u-boot
> has a way to modify DT properties in a scripted way that would allow
> the direct property. It sounds like a generally useful feature not
> just for randomness, so if that doesn't already work, maybe someone
> can implement it. In the simplest case, you'd only need to find the
> address of an existing property in the dtb and load a file to
> that location.

Like fdtget from dtc? The thing is, this address would only need to be
setup once per board. Hypothetically, debian's flash-kernel could set
the address in the dtb, then set it in the u-boot environment. From
then on, only the normal initscript writing to random-seed would be
needed.

thx,

Jason.

2014-02-12 21:35:57

by Kees Cook

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 9:45 AM, Jason Cooper <[email protected]> wrote:
> I brought this up at last weeks devicetree irc meeting. My goal is to
> provide early randomness for kaslr on ARM. Currently, my idea is modify
> the init script to save an additional random seed from /dev/urandom to
> /boot/random-seed.

I'm all for a good entropy source for early boot. :)

I need to figure out what's needed for relocation support first
though, before we can really tackle kernel base-address randomization
on ARM. I haven't had a chance to look around too closely yet, but it
seems like only x86 and ppc do this currently? Has anyone looked in
detail and what would be needed on ARM for CONFIG_RELOCATABLE
behavior?

-Kees

--
Kees Cook
Chrome OS Security

2014-02-12 23:55:12

by Rob Herring

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, Feb 12, 2014 at 1:12 PM, Arnd Bergmann <[email protected]> wrote:
> On Wednesday 12 February 2014 13:45:21 Jason Cooper wrote:
>> On Wed, Feb 12, 2014 at 07:17:41PM +0100, Arnd Bergmann wrote:
>> > On Wednesday 12 February 2014 12:45:54 Jason Cooper wrote:
>> > > I brought this up at last weeks devicetree irc meeting. My goal is to
>> > > provide early randomness for kaslr on ARM. Currently, my idea is modify
>> > > the init script to save an additional random seed from /dev/urandom to
>> > > /boot/random-seed.
>> > >
>> > > The bootloader would then load this file into ram, and pass the
>> > > address/size to the kernel either via dt, or commandline. kaslr (run in
>> > > the decompressor) would consume some of this randomness, and then
>> > > random.c would consume the rest in a non-crediting initialization.
>> >
>> > I like the idea, but wouldn't it be easier to pass actual random data
>> > using DT, rather than the address/size?
>>
>> I thought about that at first, but that requires either that the
>> bootloader be upgraded to insert the data, or that userspace is
>> modifying the dtb at least twice per boot.
>>
>> I chose address/size to facilitate modifying existing/fielded devices.
>> The user could modify the dtb once, and modify the bootloader
>> environment to load X amount to Y address. As a fallback, it could be
>> expressed on the commandline for non-DT bootloaders.
>
> Ah, so you are interested in boot loaders that can be scripted to do
> what you had in mind but cannot be scripted to add or modify a DT
> property. I hadn't considered that, but you are probably right that
> this is at least 90% of the systems you'd find in the wild today.
>
> Thinking this a bit further, I wonder if (at least upstream) u-boot
> has a way to modify DT properties in a scripted way that would allow
> the direct property. It sounds like a generally useful feature not
> just for randomness, so if that doesn't already work, maybe someone
> can implement it. In the simplest case, you'd only need to find the
> address of an existing property in the dtb and load a file to
> that location.

You would be referring to the u-boot fdt command which can read and
set properties. Of course, like all u-boot commands, that may or may
not be enabled by a vendor's u-boot. :(

Rob

2014-02-13 00:07:01

by Laura Abbott

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On 2/12/2014 3:51 AM, Arnd Bergmann wrote:
> On Wednesday 12 February 2014, Laura Abbott wrote:
>> This is an RFC to seed the random number pool earlier when using devicetree.
>> The big issue this is trying to solve is the fact that the stack canary for
>> ARM tends to be the same across bootups of the same device. This is because
>> the random number pools do not get initialized until after the canary has
>> been set up. The canary can be moved later, but in general there is still
>> no way to reliably get random numbers early for other features (e.g. vector
>> randomization).
>
> Implementation-wise this looks reasonable, and it obviously addresses a
> very real problem.
>
>> The goal here is to allow devices to add to the random pools via
>> add_device_randomness or some other method of their chosing at FDT time.
>> I realize that ARCH_RANDOM is already available but this didn't work because
>> 1) ARCH_RANDOM is not multi-platform compatible without added
>> infrastructure to ARM
>
> That could certainly be done, but I agree that a more generic
> approach like you did is nicer. One thing that might be useful
> would be to wire up your OF_RANDOM infrastructure as a generic
> implementation of ARCH_RANDOM, and merge your header file into
> include/asm-generic/archrandom.h, with an added way to call
> arch_get_random_long() for the devices you add.
>

I originally tried that approach but ran into some hiccups related to
mapping for access to the HWRNG. early_ioremap would be needed to access
hardware registers but on ARM early_ioremap does not persist across
paging init. I couldn't come up with a sufficiently not terrible way to
unmap the early mapping and re-map with a proper ioremap.

>> The big reason to skip ARCH_RANDOM though is that the random number generation
>> we have would be reasonable if only seeded earlier.
>
> Yes, makes sense.
>
> I also wonder if we should add a 'trivial' implementation that just
> reads a DT property full of random numbers to use as either an initial
> seed, or to feed into arch_get_random_long(). This would allow the
> boot loader to pass any entropy it has already gathered into the kernel,
> but leaves the danger that people might pass static not-so-random data
> through a precompiled dtb file ;-). If we get the boot loaders to be
> smart enough, doing only this would be a much simpler kernel implementation
> than your suggestion, but I'm not sure how far I want to trust boot loaders.
>

This was similar to an option discussed internally (passing a seed on
the command line). Ultimately, it was concluded that relying on the
bootloader to do this would be too much overhead vs. doing all the work
in the kernel.

> Another possibilitiy is to mix in the any contents of a "local-mac-address"
> property into the entropy at early DT probing, which would still be
> deterministic for a given machine and should not count as entropty,
> but at least give each machine with this property a unique seed in the
> absence of any other entropy source.

Is this typically updated by the bootloader as well? I'm looking at the
tree and most of the instances of local-mac-address I see are all zero.

>
> Arnd

Thanks,
Laura


--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

2014-02-13 00:54:09

by Laura Abbott

[permalink] [raw]
Subject: Re: [RFC/PATCH 2/3] arm: Add ARCH_WANT_OF_RANDOMNESS

On 2/12/2014 8:49 AM, Grant Likely wrote:
> On Tue, 11 Feb 2014 17:33:24 -0800, Laura Abbott <[email protected]> wrote:
>> The stack canary for ARM is currently the same across reboots
>> due to lack of randomness early enough. Add ARCH_WANT_OF_RANDOMNESS
>> to allow devices to add whatever randomness they need.
>>
>> Signed-off-by: Laura Abbott <[email protected]>
>
> Do you have a draft patch for a user of this yet?
>

I had a particular patch in mind but I need to re-work it to work with
the upstream tree. I wanted to at least send out the infrastructure to
see how open people were to the idea. After reading the comments, I have
a couple more ideas of users as well. I'll see if I can work that in for v2.

> g.
>

Thanks,
Laura


--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

2014-02-17 15:54:29

by Grant Likely

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Wed, 12 Feb 2014 11:20:00 -0700, Jason Gunthorpe <[email protected]> wrote:
> On Wed, Feb 12, 2014 at 12:45:54PM -0500, Jason Cooper wrote:
>
> > The bootloader would then load this file into ram, and pass the
> > address/size to the kernel either via dt, or commandline. kaslr (run in
> > the decompressor) would consume some of this randomness, and then
> > random.c would consume the rest in a non-crediting initialization.
>
> Sure is a neat idea, but I think in general it would probably be smart
> to include the entire FDT blob in the early random pool, that way you
> get MACs and other machine unique data too.

I applied a patch that did exactly that (109b623629), and then reverted
it (b920ecc82) shortly thereafter because add_device_randomness() is
a rather slow function and FDTs can get large. I'd like to see someone
do a reasonable analysis on the cost of using an FDT for randomness
before I reapply a patch doing something similar. An awful lot of the
FDT data is not very random, but there are certainly portions of it that
are appropriate for the random pool.

g.

2014-02-17 16:13:45

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Monday 17 February 2014 15:54:19 Grant Likely wrote:
> On Wed, 12 Feb 2014 11:20:00 -0700, Jason Gunthorpe <[email protected]> wrote:
> > On Wed, Feb 12, 2014 at 12:45:54PM -0500, Jason Cooper wrote:
> >
> > > The bootloader would then load this file into ram, and pass the
> > > address/size to the kernel either via dt, or commandline. kaslr (run in
> > > the decompressor) would consume some of this randomness, and then
> > > random.c would consume the rest in a non-crediting initialization.
> >
> > Sure is a neat idea, but I think in general it would probably be smart
> > to include the entire FDT blob in the early random pool, that way you
> > get MACs and other machine unique data too.
>
> I applied a patch that did exactly that (109b623629), and then reverted
> it (b920ecc82) shortly thereafter because add_device_randomness() is
> a rather slow function and FDTs can get large. I'd like to see someone
> do a reasonable analysis on the cost of using an FDT for randomness
> before I reapply a patch doing something similar. An awful lot of the
> FDT data is not very random, but there are certainly portions of it that
> are appropriate for the random pool.

Could we use a faster hash function that scans the entire device tree and
then just feed the output of that into add_device_randomness? We probably
can't expect that there is a lot of entropy in the DT blob, so the
result wouldn't be all that different in terms of quality of the random
seed.

Arnd

2014-02-17 18:23:30

by Jason Cooper

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Mon, Feb 17, 2014 at 05:13:07PM +0100, Arnd Bergmann wrote:
> On Monday 17 February 2014 15:54:19 Grant Likely wrote:
> > On Wed, 12 Feb 2014 11:20:00 -0700, Jason Gunthorpe <[email protected]> wrote:
> > > On Wed, Feb 12, 2014 at 12:45:54PM -0500, Jason Cooper wrote:
> > >
> > > > The bootloader would then load this file into ram, and pass the
> > > > address/size to the kernel either via dt, or commandline. kaslr (run in
> > > > the decompressor) would consume some of this randomness, and then
> > > > random.c would consume the rest in a non-crediting initialization.
> > >
> > > Sure is a neat idea, but I think in general it would probably be smart
> > > to include the entire FDT blob in the early random pool, that way you
> > > get MACs and other machine unique data too.
> >
> > I applied a patch that did exactly that (109b623629), and then reverted
> > it (b920ecc82) shortly thereafter because add_device_randomness() is
> > a rather slow function and FDTs can get large. I'd like to see someone
> > do a reasonable analysis on the cost of using an FDT for randomness
> > before I reapply a patch doing something similar. An awful lot of the
> > FDT data is not very random, but there are certainly portions of it that
> > are appropriate for the random pool.
>
> Could we use a faster hash function that scans the entire device tree and
> then just feed the output of that into add_device_randomness? We probably
> can't expect that there is a lot of entropy in the DT blob, so the
> result wouldn't be all that different in terms of quality of the random
> seed.

I think it would be easier to identify the few attributes that differ
from board to board (mac address, serial number, etc), and differ from
boot to boot (random-seed, timestamp) and just extract and feed those
in.

We already have the fdt parsing code in the decompressor...

thx,

Jason.

2014-02-17 21:07:53

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Mon, Feb 17, 2014 at 7:23 PM, Jason Cooper <[email protected]> wrote:
>> Could we use a faster hash function that scans the entire device tree and
>> then just feed the output of that into add_device_randomness? We probably
>> can't expect that there is a lot of entropy in the DT blob, so the
>> result wouldn't be all that different in terms of quality of the random
>> seed.
>
> I think it would be easier to identify the few attributes that differ
> from board to board (mac address, serial number, etc), and differ from
> boot to boot (random-seed, timestamp) and just extract and feed those
> in.

Isn't identifying those (mostly) a manual process?
Calculating a fast hash is fully automatic.

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds

2014-02-18 09:39:52

by Grant Likely

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Mon, 17 Feb 2014 17:13:07 +0100, Arnd Bergmann <[email protected]> wrote:
> On Monday 17 February 2014 15:54:19 Grant Likely wrote:
> > On Wed, 12 Feb 2014 11:20:00 -0700, Jason Gunthorpe <[email protected]> wrote:
> > > On Wed, Feb 12, 2014 at 12:45:54PM -0500, Jason Cooper wrote:
> > >
> > > > The bootloader would then load this file into ram, and pass the
> > > > address/size to the kernel either via dt, or commandline. kaslr (run in
> > > > the decompressor) would consume some of this randomness, and then
> > > > random.c would consume the rest in a non-crediting initialization.
> > >
> > > Sure is a neat idea, but I think in general it would probably be smart
> > > to include the entire FDT blob in the early random pool, that way you
> > > get MACs and other machine unique data too.
> >
> > I applied a patch that did exactly that (109b623629), and then reverted
> > it (b920ecc82) shortly thereafter because add_device_randomness() is
> > a rather slow function and FDTs can get large. I'd like to see someone
> > do a reasonable analysis on the cost of using an FDT for randomness
> > before I reapply a patch doing something similar. An awful lot of the
> > FDT data is not very random, but there are certainly portions of it that
> > are appropriate for the random pool.
>
> Could we use a faster hash function that scans the entire device tree and
> then just feed the output of that into add_device_randomness? We probably
> can't expect that there is a lot of entropy in the DT blob, so the
> result wouldn't be all that different in terms of quality of the random
> seed.
>
> Arnd

Yes, I think that is a good solution.

g.

2014-02-18 17:56:45

by Jason Cooper

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Mon, Feb 17, 2014 at 10:07:50PM +0100, Geert Uytterhoeven wrote:
> On Mon, Feb 17, 2014 at 7:23 PM, Jason Cooper <[email protected]> wrote:
> >> Could we use a faster hash function that scans the entire device tree and
> >> then just feed the output of that into add_device_randomness? We probably
> >> can't expect that there is a lot of entropy in the DT blob, so the
> >> result wouldn't be all that different in terms of quality of the random
> >> seed.
> >
> > I think it would be easier to identify the few attributes that differ
> > from board to board (mac address, serial number, etc), and differ from
> > boot to boot (random-seed, timestamp) and just extract and feed those
> > in.
>
> Isn't identifying those (mostly) a manual process?
> Calculating a fast hash is fully automatic.

The list would be pretty short, and once created wouldn't likely change
too often. But it really depends on the 'fast hash'. if the two
methods have comparable speed, I'd definitely prefer the hash. Easier
to maintain.

thx,

Jason.

2014-02-18 18:19:34

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: [RFC/PATCH 0/3] Add devicetree scanning for randomness

On Mon, Feb 17, 2014 at 03:54:19PM +0000, Grant Likely wrote:

> I applied a patch that did exactly that (109b623629), and then reverted
> it (b920ecc82) shortly thereafter because add_device_randomness() is
> a rather slow function and FDTs can get large. I'd like to see someone
> do a reasonable analysis on the cost of using an FDT for randomness
> before I reapply a patch doing something similar. An awful lot of the
> FDT data is not very random, but there are certainly portions of it that
> are appropriate for the random pool.

I read through the original thread from Tim Bird and FWIW I agree with
the assessment that passing the FDT through MD5 first is a good
approach.

Thinking into the future, I'd expect to see similar variable data in
DT on servers as we see in DMI, including:
- Vendor serial number for the HW, manufacturing date, model number,
and HW UUID
- Serial numbers and vendor part numbers for DIMMS
- MAC addresses for all the ethernet
- OEM specific data

At worst a 'choosen/linux,no-dt-random = 1' value in the DT to disable
it would solve the problem for those in embedded that care about
microseconds during booting.

Regards,
Jason