diff mbox series

[v10,2/3] fdt: add support for rng-seed

Message ID 20190823062452.127528-3-hsinyi@chromium.org (mailing list archive)
State Mainlined
Commit 428826f5358c922dc378830a1717b682c0823160
Headers show
Series add support for rng-seed | expand

Commit Message

Hsin-Yi Wang Aug. 23, 2019, 6:24 a.m. UTC
Introducing a chosen node, rng-seed, which is an entropy that can be
passed to kernel called very early to increase initial device
randomness. Bootloader should provide this entropy and the value is
read from /chosen/rng-seed in DT.

Obtain of_fdt_crc32 for CRC check after early_init_dt_scan_nodes(),
since early_init_dt_scan_chosen() would modify fdt to erase rng-seed.

Add a new interface add_bootloader_randomness() for rng-seed use case.
Depends on whether the seed is trustworthy, rng seed would be passed to
add_hwgenerator_randomness(). Otherwise it would be passed to
add_device_randomness(). Decision is controlled by kernel config
RANDOM_TRUST_BOOTLOADER.

Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Reviewed-by: Stephen Boyd <swboyd@chromium.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Change from v9:
* reword kconfig
* use IS_ENABLED for config
---
 drivers/char/Kconfig   |  9 +++++++++
 drivers/char/random.c  | 14 ++++++++++++++
 drivers/of/fdt.c       | 14 ++++++++++++--
 include/linux/random.h |  1 +
 4 files changed, 36 insertions(+), 2 deletions(-)

Comments

Will Deacon Aug. 23, 2019, 3:41 p.m. UTC | #1
On Fri, Aug 23, 2019 at 02:24:51PM +0800, Hsin-Yi Wang wrote:
> Introducing a chosen node, rng-seed, which is an entropy that can be
> passed to kernel called very early to increase initial device
> randomness. Bootloader should provide this entropy and the value is
> read from /chosen/rng-seed in DT.
> 
> Obtain of_fdt_crc32 for CRC check after early_init_dt_scan_nodes(),
> since early_init_dt_scan_chosen() would modify fdt to erase rng-seed.
> 
> Add a new interface add_bootloader_randomness() for rng-seed use case.
> Depends on whether the seed is trustworthy, rng seed would be passed to
> add_hwgenerator_randomness(). Otherwise it would be passed to
> add_device_randomness(). Decision is controlled by kernel config
> RANDOM_TRUST_BOOTLOADER.
> 
> Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
> Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
> Change from v9:
> * reword kconfig
> * use IS_ENABLED for config

Given that these aren't functional changes, I've kept Ted's ack from v9
and I'll queue these via arm64 assuming they pass testing.

Ted -- please shout if you're not happy about that, and I'll drop the
series.

Thanks,

Will
Theodore Ts'o Aug. 23, 2019, 4:06 p.m. UTC | #2
On Fri, Aug 23, 2019 at 04:41:59PM +0100, Will Deacon wrote:
> 
> Given that these aren't functional changes, I've kept Ted's ack from v9
> and I'll queue these via arm64 assuming they pass testing.
> 
> Ted -- please shout if you're not happy about that, and I'll drop the
> series.

That's fine, thanks.  I'm thinking about making some changes to
add_hwgenerator_randomness(), but it's not going to be in the next
merge window, and it's more important that we get the interfaces (the
Kconfig options and add_bootloader_randomness() function prototype)
right for ARM.

Now to shanghai some volunteers to get this functionality working for
x86 (at least for the UEFI and NERF bootloaders).  :-)

Thanks!!

						- Ted
Will Deacon Aug. 23, 2019, 4:31 p.m. UTC | #3
On Fri, Aug 23, 2019 at 12:06:12PM -0400, Theodore Y. Ts'o wrote:
> On Fri, Aug 23, 2019 at 04:41:59PM +0100, Will Deacon wrote:
> > 
> > Given that these aren't functional changes, I've kept Ted's ack from v9
> > and I'll queue these via arm64 assuming they pass testing.
> > 
> > Ted -- please shout if you're not happy about that, and I'll drop the
> > series.
> 
> That's fine, thanks.  I'm thinking about making some changes to
> add_hwgenerator_randomness(), but it's not going to be in the next
> merge window, and it's more important that we get the interfaces (the
> Kconfig options and add_bootloader_randomness() function prototype)
> right for ARM.

Well, on the off-chance that you do need it, I've stuck the series on its
own branch anyway so you can pull in elsewhere if necessary:

https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/rng

> Now to shanghai some volunteers to get this functionality working for
> x86 (at least for the UEFI and NERF bootloaders).  :-)

Hehe, good luck!

Will
Geert Uytterhoeven Aug. 27, 2019, 9:17 a.m. UTC | #4
Hi Will, Hsin-Yi,

On Fri, Aug 23, 2019 at 5:42 PM Will Deacon <will@kernel.org> wrote:
> On Fri, Aug 23, 2019 at 02:24:51PM +0800, Hsin-Yi Wang wrote:
> > Introducing a chosen node, rng-seed, which is an entropy that can be
> > passed to kernel called very early to increase initial device
> > randomness. Bootloader should provide this entropy and the value is
> > read from /chosen/rng-seed in DT.
> >
> > Obtain of_fdt_crc32 for CRC check after early_init_dt_scan_nodes(),
> > since early_init_dt_scan_chosen() would modify fdt to erase rng-seed.
> >
> > Add a new interface add_bootloader_randomness() for rng-seed use case.
> > Depends on whether the seed is trustworthy, rng seed would be passed to
> > add_hwgenerator_randomness(). Otherwise it would be passed to
> > add_device_randomness(). Decision is controlled by kernel config
> > RANDOM_TRUST_BOOTLOADER.
> >
> > Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
> > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > ---
> > Change from v9:
> > * reword kconfig
> > * use IS_ENABLED for config
>
> Given that these aren't functional changes, I've kept Ted's ack from v9
> and I'll queue these via arm64 assuming they pass testing.

This is now commit 428826f5358c922d ("fdt: add support for rng-seed")
in arm64/for-next/core, and causes the following regression on arm32
(e.g. r8a7791/koelsch, and sh73a0/kzm9g):

    OF: fdt: not creating '/sys/firmware/fdt': CRC check failed

Seems to work fine on arm64 (r8a7795/h3-salvator-xs), though.

Gr{oetje,eeting}s,

                        Geert
Hsin-Yi Wang Aug. 27, 2019, 9:42 a.m. UTC | #5
I probably shouldn't move of_fdt_crc32 from early_init_dt_verify() to
early_init_dt_scan() after early_init_dt_scan_nodes().
Since arm doesn't call early_init_dt_scan(). It calls
early_init_dt_verify() and early_init_dt_scan_nodes(). While arm64
calls early_init_dt_scan().
Sorry for not checking on arm.

Since it's early_init_dt_scan_nodes() that would modify DT, I'll still
leave of_fdt_crc32 be in early_init_dt_verify() and update it in
early_init_dt_scan_chosen() if rng-seed is wiped from dt.


On Tue, Aug 27, 2019 at 5:18 PM Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>
> Hi Will, Hsin-Yi,
>
> On Fri, Aug 23, 2019 at 5:42 PM Will Deacon <will@kernel.org> wrote:
> > On Fri, Aug 23, 2019 at 02:24:51PM +0800, Hsin-Yi Wang wrote:
> > > Introducing a chosen node, rng-seed, which is an entropy that can be
> > > passed to kernel called very early to increase initial device
> > > randomness. Bootloader should provide this entropy and the value is
> > > read from /chosen/rng-seed in DT.
> > >
> > > Obtain of_fdt_crc32 for CRC check after early_init_dt_scan_nodes(),
> > > since early_init_dt_scan_chosen() would modify fdt to erase rng-seed.
> > >
> > > Add a new interface add_bootloader_randomness() for rng-seed use case.
> > > Depends on whether the seed is trustworthy, rng seed would be passed to
> > > add_hwgenerator_randomness(). Otherwise it would be passed to
> > > add_device_randomness(). Decision is controlled by kernel config
> > > RANDOM_TRUST_BOOTLOADER.
> > >
> > > Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
> > > Reviewed-by: Stephen Boyd <swboyd@chromium.org>
> > > Reviewed-by: Rob Herring <robh@kernel.org>
> > > ---
> > > Change from v9:
> > > * reword kconfig
> > > * use IS_ENABLED for config
> >
> > Given that these aren't functional changes, I've kept Ted's ack from v9
> > and I'll queue these via arm64 assuming they pass testing.
>
> This is now commit 428826f5358c922d ("fdt: add support for rng-seed")
> in arm64/for-next/core, and causes the following regression on arm32
> (e.g. r8a7791/koelsch, and sh73a0/kzm9g):
>
>     OF: fdt: not creating '/sys/firmware/fdt': CRC check failed
>
> Seems to work fine on arm64 (r8a7795/h3-salvator-xs), though.
>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> 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
diff mbox series

Patch

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 96156c729a31..df0fc997dc3e 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -551,3 +551,12 @@  config RANDOM_TRUST_CPU
 	has not installed a hidden back door to compromise the CPU's
 	random number generation facilities. This can also be configured
 	at boot with "random.trust_cpu=on/off".
+
+config RANDOM_TRUST_BOOTLOADER
+	bool "Trust the bootloader to initialize Linux's CRNG"
+	help
+	Some bootloaders can provide entropy to increase the kernel's initial
+	device randomness. Say Y here to assume the entropy provided by the
+	booloader is trustworthy so it will be added to the kernel's entropy
+	pool. Otherwise, say N here so it will be regarded as device input that
+	only mixes the entropy pool.
\ No newline at end of file
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 5d5ea4ce1442..566922df4b7b 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -2445,3 +2445,17 @@  void add_hwgenerator_randomness(const char *buffer, size_t count,
 	credit_entropy_bits(poolp, entropy);
 }
 EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
+
+/* Handle random seed passed by bootloader.
+ * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
+ * it would be regarded as device data.
+ * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
+ */
+void add_bootloader_randomness(const void *buf, unsigned int size)
+{
+	if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
+		add_hwgenerator_randomness(buf, size, size * 8);
+	else
+		add_device_randomness(buf, size);
+}
+EXPORT_SYMBOL_GPL(add_bootloader_randomness);
\ No newline at end of file
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 9cdf14b9aaab..7d97ab6d0e31 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -24,6 +24,7 @@ 
 #include <linux/debugfs.h>
 #include <linux/serial_core.h>
 #include <linux/sysfs.h>
+#include <linux/random.h>
 
 #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
 #include <asm/page.h>
@@ -1044,6 +1045,7 @@  int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 {
 	int l;
 	const char *p;
+	const void *rng_seed;
 
 	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 
@@ -1078,6 +1080,14 @@  int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 
 	pr_debug("Command line is: %s\n", (char*)data);
 
+	rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
+	if (rng_seed && l > 0) {
+		add_bootloader_randomness(rng_seed, l);
+
+		/* try to clear seed so it won't be found. */
+		fdt_nop_property(initial_boot_params, node, "rng-seed");
+	}
+
 	/* break now */
 	return 1;
 }
@@ -1166,8 +1176,6 @@  bool __init early_init_dt_verify(void *params)
 
 	/* Setup flat device-tree pointer */
 	initial_boot_params = params;
-	of_fdt_crc32 = crc32_be(~0, initial_boot_params,
-				fdt_totalsize(initial_boot_params));
 	return true;
 }
 
@@ -1197,6 +1205,8 @@  bool __init early_init_dt_scan(void *params)
 		return false;
 
 	early_init_dt_scan_nodes();
+	of_fdt_crc32 = crc32_be(~0, initial_boot_params,
+				fdt_totalsize(initial_boot_params));
 	return true;
 }
 
diff --git a/include/linux/random.h b/include/linux/random.h
index 1f7dced2bba6..f189c927fdea 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -19,6 +19,7 @@  struct random_ready_callback {
 };
 
 extern void add_device_randomness(const void *, unsigned int);
+extern void add_bootloader_randomness(const void *, unsigned int);
 
 #if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
 static inline void add_latent_entropy(void)