]> asedeno.scripts.mit.edu Git - linux.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)
committerWill Deacon <will@kernel.org>
Fri, 23 Aug 2019 15:39:26 +0000 (16:39 +0100)
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>
drivers/char/Kconfig
drivers/char/random.c
drivers/of/fdt.c
include/linux/random.h

index 3e866885a40513596148b9c5a5a0db5add1c42ff..2794f4b3f62db6f0cd0472ff1d04c708e63e48b3 100644 (file)
@@ -573,3 +573,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 5d5ea4ce144293e3e99cc7b7bcc68250cf12df5b..566922df4b7b551e6abdeda96b727b938696c0c9 100644 (file)
@@ -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
index 9cdf14b9aaabe06a4a0dde1029e8d28425287564..7d97ab6d0e311738fa9c47353b7cfb645a30dd49 100644 (file)
@@ -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;
 }
 
index 1f7dced2bba66b8afe6f0824ee8dba615f0fb8cc..f189c927fdea56314ffbd69803da6c67ac44f2b4 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)