linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64
@ 2020-02-10 13:00 Mark Rutland
  2020-02-10 13:00 ` [PATCH 1/4] random: split primary/secondary crng init paths Mark Rutland
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Mark Rutland @ 2020-02-10 13:00 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: mark.rutland, tytso, catalin.marinas, richard.henderson, broonie, will

On arm64 systems some CPUs may have RNG instructions while others do
not, and consequently we cannot generally enable the use of RNG
instructions until all CPUs have been booted (as otherwise we'd have
problems with preemption, etc). This prevents us from seeding the
primary CRNG using the RNG, as this occurs before secondary CPUs are
onlined.

These patches rework the core CRNG intialization code so that the arch
code can (optionally) distinguish boot-time usage from runtime usage of
the arch_get_random_*() functions. This allows arm64 to use the boot
CPU's RNG to seed the primary CRNG, regardless of whether secondary CPUs
support the RNG instructions. Other architectures should see no
functional change as a result of this patches.

Thanks,
Mark.

Mark Rutland (3):
  random: split primary/secondary crng init paths
  random: add arch_get_random_*long_early()
  arm64: add credited/trusted RNG support

Richard Henderson (1):
  random: Make RANDOM_TRUST_CPU depend on ARCH_RANDOM

 arch/arm64/include/asm/archrandom.h | 14 ++++++++++
 drivers/char/Kconfig                |  2 +-
 drivers/char/random.c               | 52 ++++++++++++++++++++++++++++---------
 include/linux/random.h              | 22 ++++++++++++++++
 4 files changed, 77 insertions(+), 13 deletions(-)

-- 
2.11.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] random: split primary/secondary crng init paths
  2020-02-10 13:00 [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
@ 2020-02-10 13:00 ` Mark Rutland
  2020-02-10 13:00 ` [PATCH 2/4] random: add arch_get_random_*long_early() Mark Rutland
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Mark Rutland @ 2020-02-10 13:00 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: mark.rutland, tytso, catalin.marinas, richard.henderson, broonie, will

Currently crng_initialize() is used for both the primary CRNG and
secondary CRNGs. While we wish to share common logic, we need to do a
number of additional things for the primary CRNG, and this would be
easier to deal with were these handled in separate functions.

This patch splits crng_initialize() into crng_initialize_primary() and
crng_initialize_secondary(), with common logic factored out into a
crng_init_try_arch() helper.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Theodore Ts'o <tytso@mit.edu>
---
 drivers/char/random.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index c7f9584de2c8..62d32e62f2da 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -781,27 +781,37 @@ static int __init parse_trust_cpu(char *arg)
 }
 early_param("random.trust_cpu", parse_trust_cpu);
 
-static void crng_initialize(struct crng_state *crng)
+static bool crng_init_try_arch(struct crng_state *crng)
 {
 	int		i;
-	int		arch_init = 1;
+	bool		arch_init = true;
 	unsigned long	rv;
 
-	memcpy(&crng->state[0], "expand 32-byte k", 16);
-	if (crng == &primary_crng)
-		_extract_entropy(&input_pool, &crng->state[4],
-				 sizeof(__u32) * 12, 0);
-	else
-		_get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
 	for (i = 4; i < 16; i++) {
 		if (!arch_get_random_seed_long(&rv) &&
 		    !arch_get_random_long(&rv)) {
 			rv = random_get_entropy();
-			arch_init = 0;
+			arch_init = false;
 		}
 		crng->state[i] ^= rv;
 	}
-	if (trust_cpu && arch_init && crng == &primary_crng) {
+
+	return arch_init;
+}
+
+static void crng_initialize_secondary(struct crng_state *crng)
+{
+	memcpy(&crng->state[0], "expand 32-byte k", 16);
+	_get_random_bytes(&crng->state[4], sizeof(__u32) * 12);
+	crng_init_try_arch(crng);
+	crng->init_time = jiffies - CRNG_RESEED_INTERVAL - 1;
+}
+
+static void __init crng_initialize_primary(struct crng_state *crng)
+{
+	memcpy(&crng->state[0], "expand 32-byte k", 16);
+	_extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0);
+	if (crng_init_try_arch(crng) && trust_cpu) {
 		invalidate_batched_entropy();
 		numa_crng_init();
 		crng_init = 2;
@@ -822,7 +832,7 @@ static void do_numa_crng_init(struct work_struct *work)
 		crng = kmalloc_node(sizeof(struct crng_state),
 				    GFP_KERNEL | __GFP_NOFAIL, i);
 		spin_lock_init(&crng->lock);
-		crng_initialize(crng);
+		crng_initialize_secondary(crng);
 		pool[i] = crng;
 	}
 	mb();
@@ -1771,7 +1781,7 @@ static void __init init_std_data(struct entropy_store *r)
 int __init rand_initialize(void)
 {
 	init_std_data(&input_pool);
-	crng_initialize(&primary_crng);
+	crng_initialize_primary(&primary_crng);
 	crng_global_init_time = jiffies;
 	if (ratelimit_disable) {
 		urandom_warning.interval = 0;
-- 
2.11.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] random: add arch_get_random_*long_early()
  2020-02-10 13:00 [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
  2020-02-10 13:00 ` [PATCH 1/4] random: split primary/secondary crng init paths Mark Rutland
@ 2020-02-10 13:00 ` Mark Rutland
  2020-02-10 13:00 ` [PATCH 3/4] arm64: add credited/trusted RNG support Mark Rutland
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Mark Rutland @ 2020-02-10 13:00 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: mark.rutland, tytso, catalin.marinas, richard.henderson, broonie, will

Some architectures (e.g. arm64) can have heterogeneous CPUs, and the
boot CPU may be able to provide entropy while secondary CPUs cannot. On
such systems, arch_get_random_long() and arch_get_random_seed_long()
will fail unless support for RNG instructions has been detected on all
CPUs. This prevents the boot CPU from being able to provide
(potentially) trusted entropy when seeding the primary CRNG.

To make it possible to seed the primary CRNG from the boot CPU without
adversely affecting the runtime versions of arch_get_random_long() and
arch_get_random_seed_long(), this patch adds new early versions of the
functions used when initializing the primary CRNG.

Default implementations are provided atop of the existing
arch_get_random_long() and arch_get_random_seed_long() so that only
architectures with such constraints need to provide the new helpers.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Theodore Ts'o <tytso@mit.edu>
---
 drivers/char/random.c  | 20 +++++++++++++++++++-
 include/linux/random.h | 22 ++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 62d32e62f2da..02a85b87b993 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -799,6 +799,24 @@ static bool crng_init_try_arch(struct crng_state *crng)
 	return arch_init;
 }
 
+static bool __init crng_init_try_arch_early(struct crng_state *crng)
+{
+	int		i;
+	bool		arch_init = true;
+	unsigned long	rv;
+
+	for (i = 4; i < 16; i++) {
+		if (!arch_get_random_seed_long_early(&rv) &&
+		    !arch_get_random_long_early(&rv)) {
+			rv = random_get_entropy();
+			arch_init = false;
+		}
+		crng->state[i] ^= rv;
+	}
+
+	return arch_init;
+}
+
 static void crng_initialize_secondary(struct crng_state *crng)
 {
 	memcpy(&crng->state[0], "expand 32-byte k", 16);
@@ -811,7 +829,7 @@ static void __init crng_initialize_primary(struct crng_state *crng)
 {
 	memcpy(&crng->state[0], "expand 32-byte k", 16);
 	_extract_entropy(&input_pool, &crng->state[4], sizeof(__u32) * 12, 0);
-	if (crng_init_try_arch(crng) && trust_cpu) {
+	if (crng_init_try_arch_early(crng) && trust_cpu) {
 		invalidate_batched_entropy();
 		numa_crng_init();
 		crng_init = 2;
diff --git a/include/linux/random.h b/include/linux/random.h
index d319f9a1e429..45e1f8fa742b 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -7,6 +7,8 @@
 #ifndef _LINUX_RANDOM_H
 #define _LINUX_RANDOM_H
 
+#include <linux/bug.h>
+#include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/once.h>
 
@@ -185,6 +187,26 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
 }
 #endif
 
+/*
+ * Called from the boot CPU during startup; not valid to call once
+ * secondary CPUs are up and preemption is possible.
+ */
+#ifndef arch_get_random_seed_long_early
+static inline bool __init arch_get_random_seed_long_early(unsigned long *v)
+{
+	WARN_ON(system_state != SYSTEM_BOOTING);
+	return arch_get_random_seed_long(v);
+}
+#endif
+
+#ifndef arch_get_random_long_early
+static inline bool __init arch_get_random_long_early(unsigned long *v)
+{
+	WARN_ON(system_state != SYSTEM_BOOTING);
+	return arch_get_random_long(v);
+}
+#endif
+
 /* Pseudo random number generator from numerical recipes. */
 static inline u32 next_pseudo_random32(u32 seed)
 {
-- 
2.11.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] arm64: add credited/trusted RNG support
  2020-02-10 13:00 [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
  2020-02-10 13:00 ` [PATCH 1/4] random: split primary/secondary crng init paths Mark Rutland
  2020-02-10 13:00 ` [PATCH 2/4] random: add arch_get_random_*long_early() Mark Rutland
@ 2020-02-10 13:00 ` Mark Rutland
  2020-02-10 13:00 ` [PATCH 4/4] random: Make RANDOM_TRUST_CPU depend on ARCH_RANDOM Mark Rutland
  2020-02-26 10:24 ` [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
  4 siblings, 0 replies; 7+ messages in thread
From: Mark Rutland @ 2020-02-10 13:00 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: mark.rutland, tytso, catalin.marinas, richard.henderson, broonie, will

Currently arm64 doesn't initialize the primary CRNG in a (potentially)
trusted manner as we only detect the presence of the RNG once secondary
CPUs are up.

Now that the core RNG code distinguishes the early initialization of the
primary CRNG, we can implement arch_get_random_seed_long_early() to
support this.

This patch does so.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Theodore Ts'o <tytso@mit.edu>
Cc: Will Deacon <will@kernel.org>
---
 arch/arm64/include/asm/archrandom.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 3fe02da70004..fc1594a0710e 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -4,6 +4,8 @@
 
 #ifdef CONFIG_ARCH_RANDOM
 
+#include <linux/bug.h>
+#include <linux/kernel.h>
 #include <linux/random.h>
 #include <asm/cpufeature.h>
 
@@ -66,6 +68,18 @@ static inline bool __init __early_cpu_has_rndr(void)
 	return (ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf;
 }
 
+static inline bool __init __must_check
+arch_get_random_seed_long_early(unsigned long *v)
+{
+	WARN_ON(system_state != SYSTEM_BOOTING);
+
+	if (!__early_cpu_has_rndr())
+		return false;
+
+	return __arm64_rndr(v);
+}
+#define arch_get_random_seed_long_early arch_get_random_seed_long_early
+
 #else
 
 static inline bool __arm64_rndr(unsigned long *v) { return false; }
-- 
2.11.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] random: Make RANDOM_TRUST_CPU depend on ARCH_RANDOM
  2020-02-10 13:00 [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
                   ` (2 preceding siblings ...)
  2020-02-10 13:00 ` [PATCH 3/4] arm64: add credited/trusted RNG support Mark Rutland
@ 2020-02-10 13:00 ` Mark Rutland
  2020-02-26 10:24 ` [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
  4 siblings, 0 replies; 7+ messages in thread
From: Mark Rutland @ 2020-02-10 13:00 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel
  Cc: mark.rutland, tytso, catalin.marinas, richard.henderson, broonie, will

From: Richard Henderson <richard.henderson@linaro.org>

Listing the set of host architectures does not scale.
Depend instead on the existence of the architecture rng.

This will allow RANDOM_TRUST_CPU to be selected on arm64. Today
ARCH_RANDOM is only selected by x86, s390, and powerpc, so this does not
adversely affect other architectures.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/char/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 26956c006987..84207d5a9bb0 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -539,7 +539,7 @@ endmenu
 
 config RANDOM_TRUST_CPU
 	bool "Trust the CPU manufacturer to initialize Linux's CRNG"
-	depends on X86 || S390 || PPC
+	depends on ARCH_RANDOM
 	default n
 	help
 	Assume that CPU manufacturer (e.g., Intel or AMD for RDSEED or
-- 
2.11.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64
  2020-02-10 13:00 [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
                   ` (3 preceding siblings ...)
  2020-02-10 13:00 ` [PATCH 4/4] random: Make RANDOM_TRUST_CPU depend on ARCH_RANDOM Mark Rutland
@ 2020-02-26 10:24 ` Mark Rutland
  2020-02-28  4:22   ` Theodore Y. Ts'o
  4 siblings, 1 reply; 7+ messages in thread
From: Mark Rutland @ 2020-02-26 10:24 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, tytso
  Cc: catalin.marinas, broonie, richard.henderson, will

Ted, sorry to ping, but do you have any thoughts on this series?

I'm happy to rework this, or drop it if you think it's completely wrong,
but if you're not too concerned it would be nice to be able to queue
this soon.

Thanks,
Mark.

On Mon, Feb 10, 2020 at 01:00:11PM +0000, Mark Rutland wrote:
> On arm64 systems some CPUs may have RNG instructions while others do
> not, and consequently we cannot generally enable the use of RNG
> instructions until all CPUs have been booted (as otherwise we'd have
> problems with preemption, etc). This prevents us from seeding the
> primary CRNG using the RNG, as this occurs before secondary CPUs are
> onlined.
> 
> These patches rework the core CRNG intialization code so that the arch
> code can (optionally) distinguish boot-time usage from runtime usage of
> the arch_get_random_*() functions. This allows arm64 to use the boot
> CPU's RNG to seed the primary CRNG, regardless of whether secondary CPUs
> support the RNG instructions. Other architectures should see no
> functional change as a result of this patches.
> 
> Thanks,
> Mark.
> 
> Mark Rutland (3):
>   random: split primary/secondary crng init paths
>   random: add arch_get_random_*long_early()
>   arm64: add credited/trusted RNG support
> 
> Richard Henderson (1):
>   random: Make RANDOM_TRUST_CPU depend on ARCH_RANDOM
> 
>  arch/arm64/include/asm/archrandom.h | 14 ++++++++++
>  drivers/char/Kconfig                |  2 +-
>  drivers/char/random.c               | 52 ++++++++++++++++++++++++++++---------
>  include/linux/random.h              | 22 ++++++++++++++++
>  4 files changed, 77 insertions(+), 13 deletions(-)
> 
> -- 
> 2.11.0
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64
  2020-02-26 10:24 ` [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
@ 2020-02-28  4:22   ` Theodore Y. Ts'o
  0 siblings, 0 replies; 7+ messages in thread
From: Theodore Y. Ts'o @ 2020-02-28  4:22 UTC (permalink / raw)
  To: Mark Rutland
  Cc: catalin.marinas, richard.henderson, linux-kernel, broonie, will,
	linux-arm-kernel

On Wed, Feb 26, 2020 at 10:24:22AM +0000, Mark Rutland wrote:
> Ted, sorry to ping, but do you have any thoughts on this series?
> 
> I'm happy to rework this, or drop it if you think it's completely wrong,
> but if you're not too concerned it would be nice to be able to queue
> this soon.

Thanks, I've applied it to the random git tree.

						- Ted

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-02-28  4:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-10 13:00 [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
2020-02-10 13:00 ` [PATCH 1/4] random: split primary/secondary crng init paths Mark Rutland
2020-02-10 13:00 ` [PATCH 2/4] random: add arch_get_random_*long_early() Mark Rutland
2020-02-10 13:00 ` [PATCH 3/4] arm64: add credited/trusted RNG support Mark Rutland
2020-02-10 13:00 ` [PATCH 4/4] random: Make RANDOM_TRUST_CPU depend on ARCH_RANDOM Mark Rutland
2020-02-26 10:24 ` [PATCH 0/4] random/arm64: enable RANDOM_TRUST_CPU for arm64 Mark Rutland
2020-02-28  4:22   ` Theodore Y. Ts'o

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).