aa224e7
From 39a8883a2b989d1d21bd8dd99f5557f0c5e89694 Mon Sep 17 00:00:00 2001
aa224e7
From: Theodore Ts'o <tytso@mit.edu>
aa224e7
Date: Tue, 17 Jul 2018 18:24:27 -0400
aa224e7
Subject: [PATCH] random: add a config option to trust the CPU's hwrng
aa224e7
aa224e7
This gives the user building their own kernel (or a Linux
aa224e7
distribution) the option of deciding whether or not to trust the CPU's
aa224e7
hardware random number generator (e.g., RDRAND for x86 CPU's) as being
aa224e7
correctly implemented and not having a back door introduced (perhaps
aa224e7
courtesy of a Nation State's law enforcement or intelligence
aa224e7
agencies).
aa224e7
aa224e7
This will prevent getrandom(2) from blocking, if there is a
aa224e7
willingness to trust the CPU manufacturer.
aa224e7
aa224e7
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
aa224e7
---
aa224e7
 drivers/char/Kconfig  | 14 ++++++++++++++
aa224e7
 drivers/char/random.c | 11 ++++++++++-
aa224e7
 2 files changed, 24 insertions(+), 1 deletion(-)
aa224e7
aa224e7
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
aa224e7
index 212f447938ae..ce277ee0a28a 100644
aa224e7
--- a/drivers/char/Kconfig
aa224e7
+++ b/drivers/char/Kconfig
aa224e7
@@ -554,3 +554,17 @@ config ADI
aa224e7
 
aa224e7
 endmenu
aa224e7
 
aa224e7
+config RANDOM_TRUST_CPU
aa224e7
+	bool "Trust the CPU manufacturer to initialize Linux's CRNG"
aa224e7
+	depends on X86 || S390 || PPC
aa224e7
+	default n
aa224e7
+	help
aa224e7
+	Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or
aa224e7
+	RDRAND, IBM for the S390 and Power PC architectures) is trustworthy
aa224e7
+	for the purposes of initializing Linux's CRNG.  Since this is not
aa224e7
+	something that can be independently audited, this amounts to trusting
aa224e7
+	that CPU manufacturer (perhaps with the insistence or mandate
aa224e7
+	of a Nation State's intelligence or law enforcement agencies)
aa224e7
+	has not installed a hidden back door to compromise the CPU's
aa224e7
+	random number generation facilities.
aa224e7
+
aa224e7
diff --git a/drivers/char/random.c b/drivers/char/random.c
aa224e7
index 34ddfd57419b..f4013b8a711b 100644
aa224e7
--- a/drivers/char/random.c
aa224e7
+++ b/drivers/char/random.c
aa224e7
@@ -782,6 +782,7 @@ static void invalidate_batched_entropy(void);
aa224e7
 static void crng_initialize(struct crng_state *crng)
aa224e7
 {
aa224e7
 	int		i;
aa224e7
+	int		arch_init = 1;
aa224e7
 	unsigned long	rv;
aa224e7
 
aa224e7
 	memcpy(&crng->state[0], "expand 32-byte k", 16);
aa224e7
@@ -792,10 +793,18 @@ static void crng_initialize(struct crng_state *crng)
aa224e7
 		_get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
aa224e7
 	for (i = 4; i < 16; i++) {
aa224e7
 		if (!arch_get_random_seed_long(&rv) &&
aa224e7
-		    !arch_get_random_long(&rv))
aa224e7
+		    !arch_get_random_long(&rv)) {
aa224e7
 			rv = random_get_entropy();
aa224e7
+			arch_init = 0;
aa224e7
+		}
aa224e7
 		crng->state[i] ^= rv;
aa224e7
 	}
aa224e7
+#ifdef CONFIG_RANDOM_TRUST_CPU
aa224e7
+	if (arch_init) {
aa224e7
+		crng_init = 2;
aa224e7
+		pr_notice("random: crng done (trusting CPU's manufacturer)\n");
aa224e7
+	}
aa224e7
+#endif
aa224e7
 	crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
aa224e7
 }
aa224e7
 
aa224e7
-- 
aa224e7
2.17.1
aa224e7