]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fdt: add support for rng-seed
authorHsin-Yi Wang <hsinyi@chromium.org>
Fri, 23 Aug 2019 06:24:51 +0000 (14:24 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 25 Jun 2022 09:48:58 +0000 (11:48 +0200)
commit 428826f5358c922dc378830a1717b682c0823160 upstream.

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>
Reviewed-by: Theodore Ts'o <tytso@mit.edu> # drivers/char/random.c
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/Kconfig
drivers/char/random.c
drivers/of/fdt.c
include/linux/random.h

index 1df9cb8e659e2d9693a1300af93a1cb648900a07..3bc53a8c93fec159b3bdac300fbb1712d33eaa86 100644 (file)
@@ -568,3 +568,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
index de8da6e0b9a8bdab87841f6fcfd5b06b0f4b1811..60a1f3928706c7504829513ae916afb3560ed24a 100644 (file)
@@ -2503,3 +2503,17 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
        }
 }
 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
index 1eb6af6439ad625d3ee294cfa2e51fc3fb88bac9..2e9ea7f1e719bbf7b97a58b09be9f3b30a71da15 100644 (file)
@@ -25,6 +25,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>
@@ -1077,6 +1078,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);
 
@@ -1111,6 +1113,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;
 }
@@ -1213,8 +1223,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;
 }
 
@@ -1240,6 +1248,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;
 }
 
index 2f902463c40859b6ed8c6c1afb2430d77c5ad190..5b3ec7d2791f8811cd7959ebd062849bcd46525d 100644 (file)
@@ -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)