All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 0/3] ARMv8.5-RNG support
@ 2020-01-08 19:41 Mark Brown
  2020-01-08 19:41 ` [PATCH v9 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Mark Brown @ 2020-01-08 19:41 UTC (permalink / raw)
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel,
	Ard Biesheuvel

This series is based on Richard Henderson's previous v7, it addresses
review comments from that version by splitting the boot and runtime
interaction with the core random code so that they are completely
separate and adds a new change that uses the v8.5-RNG extension to seed
KASLR when ARCH_RANDOM is enabled.

v9:
 - Make another static inline helper for early feature checks.
 - Add init annotations.
 - Use xor to add RNDR output to seed for KASLR.

Mark Brown (2):
  arm64: random: Add data to pool from setup_arch()
  arm64: Use v8.5-RNG entropy for KASLR seed

Richard Henderson (1):
  arm64: Implement archrandom.h for ARMv8.5-RNG

 Documentation/arm64/cpu-feature-registers.rst |  2 +
 arch/arm64/Kconfig                            | 12 +++
 arch/arm64/include/asm/archrandom.h           | 97 +++++++++++++++++++
 arch/arm64/include/asm/cpucaps.h              |  3 +-
 arch/arm64/include/asm/sysreg.h               |  4 +
 arch/arm64/kernel/cpufeature.c                | 13 +++
 arch/arm64/kernel/kaslr.c                     | 11 +++
 arch/arm64/kernel/setup.c                     |  2 +
 8 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/archrandom.h

-- 
2.20.1


_______________________________________________
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] 6+ messages in thread

* [PATCH v9 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG
  2020-01-08 19:41 [PATCH v9 0/3] ARMv8.5-RNG support Mark Brown
@ 2020-01-08 19:41 ` Mark Brown
  2020-01-08 19:41 ` [PATCH v9 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
  2020-01-08 19:41 ` [PATCH v9 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2020-01-08 19:41 UTC (permalink / raw)
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel,
	Ard Biesheuvel

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

Expose the ID_AA64ISAR0.RNDR field to userspace, as the RNG system
registers are always available at EL0.

Implement arch_get_random_seed_long using RNDR.  Given that the
TRNG is likely to be a shared resource between cores, and VMs,
do not explicitly force re-seeding with RNDRRS.  In order to avoid
code complexity and potential issues with hetrogenous systems only
provide values after cpufeature has finalized the system capabilities.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
[Modified to only function after cpufeature has finalized the system
capabilities and move all the code into the header -- broonie]
Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
---
 Documentation/arm64/cpu-feature-registers.rst |  2 +
 arch/arm64/Kconfig                            | 12 ++++
 arch/arm64/include/asm/archrandom.h           | 67 +++++++++++++++++++
 arch/arm64/include/asm/cpucaps.h              |  3 +-
 arch/arm64/include/asm/sysreg.h               |  4 ++
 arch/arm64/kernel/cpufeature.c                | 13 ++++
 6 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/include/asm/archrandom.h

diff --git a/Documentation/arm64/cpu-feature-registers.rst b/Documentation/arm64/cpu-feature-registers.rst
index b6e44884e3ad..ce320785fb0c 100644
--- a/Documentation/arm64/cpu-feature-registers.rst
+++ b/Documentation/arm64/cpu-feature-registers.rst
@@ -117,6 +117,8 @@ infrastructure:
      +------------------------------+---------+---------+
      | Name                         |  bits   | visible |
      +------------------------------+---------+---------+
+     | RNDR                         | [63-60] |    y    |
+     +------------------------------+---------+---------+
      | TS                           | [55-52] |    y    |
      +------------------------------+---------+---------+
      | FHM                          | [51-48] |    y    |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1b4476ddb83..835f8158220e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1484,6 +1484,18 @@ config ARM64_PTR_AUTH
 
 endmenu
 
+menu "ARMv8.5 architectural features"
+
+config ARCH_RANDOM
+	bool "Enable support for random number generation"
+	default y
+	help
+	  Random number generation (part of the ARMv8.5 Extensions)
+	  provides a high bandwidth, cryptographically secure
+	  hardware random number generator.
+
+endmenu
+
 config ARM64_SVE
 	bool "ARM Scalable Vector Extension support"
 	default y
diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
new file mode 100644
index 000000000000..5ea5a1ce5a5f
--- /dev/null
+++ b/arch/arm64/include/asm/archrandom.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARCHRANDOM_H
+#define _ASM_ARCHRANDOM_H
+
+#ifdef CONFIG_ARCH_RANDOM
+
+#include <linux/random.h>
+#include <asm/cpufeature.h>
+
+static inline bool __arm64_rndr(unsigned long *v)
+{
+	bool ok;
+
+	/*
+	 * Reads of RNDR set PSTATE.NZCV to 0b0000 on success,
+	 * and set PSTATE.NZCV to 0b0100 otherwise.
+	 */
+	asm volatile(
+		__mrs_s("%0", SYS_RNDR_EL0) "\n"
+	"	cset %w1, ne\n"
+	: "=r" (*v), "=r" (ok)
+	:
+	: "cc");
+
+	return ok;
+}
+
+static inline bool __must_check arch_get_random_long(unsigned long *v)
+{
+	return false;
+}
+
+static inline bool __must_check arch_get_random_int(unsigned int *v)
+{
+	return false;
+}
+
+static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
+{
+	/*
+	 * Only support the generic interface after we have detected
+	 * the system wide capability, avoiding complexity with the
+	 * cpufeature code and with potential scheduling between CPUs
+	 * with and without the feature.
+	 */
+	if (!cpus_have_const_cap(ARM64_HAS_RNG))
+		return false;
+
+	return __arm64_rndr(v);
+}
+
+
+static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
+{
+	unsigned long val;
+	bool ok = arch_get_random_seed_long(&val);
+
+	*v = val;
+	return ok;
+}
+
+#else
+
+static inline bool __arm64_rndr(unsigned long *v) { return false; }
+
+#endif /* CONFIG_ARCH_RANDOM */
+#endif /* _ASM_ARCHRANDOM_H */
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index b92683871119..515f4fbcbf91 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -56,7 +56,8 @@
 #define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM	46
 #define ARM64_WORKAROUND_1542419		47
 #define ARM64_WORKAROUND_1319367		48
+#define ARM64_HAS_RNG				49
 
-#define ARM64_NCAPS				49
+#define ARM64_NCAPS				50
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 6e919fafb43d..5e718f279469 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -365,6 +365,9 @@
 #define SYS_CTR_EL0			sys_reg(3, 3, 0, 0, 1)
 #define SYS_DCZID_EL0			sys_reg(3, 3, 0, 0, 7)
 
+#define SYS_RNDR_EL0			sys_reg(3, 3, 2, 4, 0)
+#define SYS_RNDRRS_EL0			sys_reg(3, 3, 2, 4, 1)
+
 #define SYS_PMCR_EL0			sys_reg(3, 3, 9, 12, 0)
 #define SYS_PMCNTENSET_EL0		sys_reg(3, 3, 9, 12, 1)
 #define SYS_PMCNTENCLR_EL0		sys_reg(3, 3, 9, 12, 2)
@@ -539,6 +542,7 @@
 			 ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
 
 /* id_aa64isar0 */
+#define ID_AA64ISAR0_RNDR_SHIFT		60
 #define ID_AA64ISAR0_TS_SHIFT		52
 #define ID_AA64ISAR0_FHM_SHIFT		48
 #define ID_AA64ISAR0_DP_SHIFT		44
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 04cf64e9f0c9..0fea85228956 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -119,6 +119,7 @@ static void cpu_enable_cnp(struct arm64_cpu_capabilities const *cap);
  * sync with the documentation of the CPU feature register ABI.
  */
 static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_RNDR_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_TS_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_FHM_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR0_DP_SHIFT, 4, 0),
@@ -1566,6 +1567,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
+#endif
+#ifdef CONFIG_ARCH_RANDOM
+	{
+		.desc = "Random Number Generator",
+		.capability = ARM64_HAS_RNG,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_cpuid_feature,
+		.sys_reg = SYS_ID_AA64ISAR0_EL1,
+		.field_pos = ID_AA64ISAR0_RNDR_SHIFT,
+		.sign = FTR_UNSIGNED,
+		.min_field_value = 1,
+	},
 #endif
 	{},
 };
-- 
2.20.1


_______________________________________________
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] 6+ messages in thread

* [PATCH v9 2/3] arm64: random: Add data to pool from setup_arch()
  2020-01-08 19:41 [PATCH v9 0/3] ARMv8.5-RNG support Mark Brown
  2020-01-08 19:41 ` [PATCH v9 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
@ 2020-01-08 19:41 ` Mark Brown
  2020-01-08 21:33   ` Richard Henderson
  2020-01-08 19:41 ` [PATCH v9 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown
  2 siblings, 1 reply; 6+ messages in thread
From: Mark Brown @ 2020-01-08 19:41 UTC (permalink / raw)
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel,
	Ard Biesheuvel

Since the arm64 ARCH_RANDOM implementation is not available until
cpufeature has determined the system capabilities it can't be used by
the generic random code to initialize the entropy pool for early use.
Instead explicitly add some data to the pool from setup_arch() if the
boot CPU supports v8.5-RNG, this is the point recommended by the generic
code.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/include/asm/archrandom.h | 30 +++++++++++++++++++++++++++++
 arch/arm64/kernel/setup.c           |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 5ea5a1ce5a5f..2eb1db1f0bdf 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -59,9 +59,39 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
 	return ok;
 }
 
+static inline bool __init __early_cpu_has_rndr(void)
+{
+	/* Open code as we run prior to the first call to cpufeature. */
+	unsigned long ftr = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
+	return (ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf;
+}
+
+/*
+ * Our ARCH_RANDOM implementation does not function until relatively
+ * late in the boot when cpufeature has detertmined system
+ * capabilities so the core code can't use arch_get_random*() to
+ * initialize, instead we call this function to inject data from
+ * setup_arch() if the boot CPU supports v8.5-RNG.
+ */
+static inline void __init arm64_add_early_rndr_entropy(void)
+{
+	unsigned long val;
+	int i;
+
+	if (!__early_cpu_has_rndr())
+		return;
+
+	/* Add multiple values to mirror the generic code. */
+	for (i = 0; i < 16; i++)
+		if (__arm64_rndr(&val))
+			add_device_randomness(&val, sizeof(val));
+}
+
 #else
 
 static inline bool __arm64_rndr(unsigned long *v) { return false; }
+static inline bool __init __early_cpu_has_rndr(void) { return false; }
+static inline void __init arm64_add_early_rndr_entropy(void) { }
 
 #endif /* CONFIG_ARCH_RANDOM */
 #endif /* _ASM_ARCHRANDOM_H */
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 56f664561754..170842965a32 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -344,6 +344,8 @@ void __init setup_arch(char **cmdline_p)
 	/* Init percpu seeds for random tags after cpus are set up. */
 	kasan_init_tags();
 
+	arm64_add_early_rndr_entropy();
+
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
 	/*
 	 * Make sure init_thread_info.ttbr0 always generates translation
-- 
2.20.1


_______________________________________________
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] 6+ messages in thread

* [PATCH v9 3/3] arm64: Use v8.5-RNG entropy for KASLR seed
  2020-01-08 19:41 [PATCH v9 0/3] ARMv8.5-RNG support Mark Brown
  2020-01-08 19:41 ` [PATCH v9 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
  2020-01-08 19:41 ` [PATCH v9 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
@ 2020-01-08 19:41 ` Mark Brown
  2 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2020-01-08 19:41 UTC (permalink / raw)
  To: Will Deacon, Catalin Marinas
  Cc: Mark Rutland, Mark Brown, Richard Henderson, linux-arm-kernel,
	Ard Biesheuvel

When seeding KALSR on a system where we have architecture level random
number generation make use of that entropy, mixing it in with the seed
passed by the bootloader. Since this is run very early in init before
feature detection is complete we open code rather than use archrandom.h.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 arch/arm64/kernel/kaslr.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c
index 2a11a962e571..53b8a4ee64ff 100644
--- a/arch/arm64/kernel/kaslr.c
+++ b/arch/arm64/kernel/kaslr.c
@@ -120,6 +120,17 @@ u64 __init kaslr_early_init(u64 dt_phys)
 		return 0;
 	}
 
+	/*
+	 * Mix in any entropy obtainable architecturally, open coded
+	 * since this runs extremely early.
+	 */
+	if (__early_cpu_has_rndr()) {
+		unsigned long raw;
+
+		if (__arm64_rndr(&raw))
+			seed ^= raw;
+	}
+
 	if (!seed) {
 		kaslr_status = KASLR_DISABLED_NO_SEED;
 		return 0;
-- 
2.20.1


_______________________________________________
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] 6+ messages in thread

* Re: [PATCH v9 2/3] arm64: random: Add data to pool from setup_arch()
  2020-01-08 19:41 ` [PATCH v9 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
@ 2020-01-08 21:33   ` Richard Henderson
  2020-01-09 16:18     ` Mark Brown
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Henderson @ 2020-01-08 21:33 UTC (permalink / raw)
  To: Mark Brown, Will Deacon, Catalin Marinas
  Cc: Mark Rutland, linux-arm-kernel, Ard Biesheuvel

On 1/9/20 6:41 AM, Mark Brown wrote:
> +/*
> + * Our ARCH_RANDOM implementation does not function until relatively
> + * late in the boot when cpufeature has detertmined system
> + * capabilities so the core code can't use arch_get_random*() to
> + * initialize, instead we call this function to inject data from
> + * setup_arch() if the boot CPU supports v8.5-RNG.
> + */
> +static inline void __init arm64_add_early_rndr_entropy(void)
> +{
> +	unsigned long val;
> +	int i;
> +
> +	if (!__early_cpu_has_rndr())
> +		return;
> +
> +	/* Add multiple values to mirror the generic code. */
> +	for (i = 0; i < 16; i++)
> +		if (__arm64_rndr(&val))
> +			add_device_randomness(&val, sizeof(val));
> +}

This is not nearly the same thing as what crng_initialize does.  In particular,
it's not going to advance crng_init at all.

You could use add_hwgenerator_randomness, but you have no way to honor the
random.trust_cpu command-line parameter that way.

The only thing I can imagine that would satisfy MarkR's constraints is to have
a new archrandom.h interface, arch_get_random_boot_long().


r~

_______________________________________________
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] 6+ messages in thread

* Re: [PATCH v9 2/3] arm64: random: Add data to pool from setup_arch()
  2020-01-08 21:33   ` Richard Henderson
@ 2020-01-09 16:18     ` Mark Brown
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2020-01-09 16:18 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Mark Rutland, Catalin Marinas, Will Deacon, linux-arm-kernel,
	Ard Biesheuvel


[-- Attachment #1.1: Type: text/plain, Size: 2213 bytes --]

On Thu, Jan 09, 2020 at 08:33:25AM +1100, Richard Henderson wrote:
> On 1/9/20 6:41 AM, Mark Brown wrote:

> > +	for (i = 0; i < 16; i++)
> > +		if (__arm64_rndr(&val))
> > +			add_device_randomness(&val, sizeof(val));
> > +}

> This is not nearly the same thing as what crng_initialize does.  In particular,
> it's not going to advance crng_init at all.

That's right, but I think that's good enough to get us going here.  It
will add data into the pool so we're mitigating against a lack of per
device entropy which seems clearly better than doing nothing at all and
has no issues with integration with the decision about trusting the RNG
to provide entropy so it's safe.  The commit message does say we add
data rather than entropy, though I agree that on reflection the callback
isn't clearly named there and people not familiar with the random
subsystem will likely not notice the difference.

We could definitely improve the commit message a bit here or even drop
the patch but I think we're better off with this than without it, and
exposing the feature to userspace, allowing in kernel usage after init
and using it for KASAN are clear wins regardless of what we do with the
pool.  If we can do something that credits the entropy at boot that'd be
even better of course but I don't think that needs to block everything
else.

> You could use add_hwgenerator_randomness, but you have no way to honor the
> random.trust_cpu command-line parameter that way.

Right, that'd definitely be the wrong thing to do here.

> The only thing I can imagine that would satisfy MarkR's constraints is to have

The main issue he had was as far as I can tell with adding complexity to
the main runtime path which we now avoid, we now don't have anything
that needs to disable preemption or anything like that.

> a new archrandom.h interface, arch_get_random_boot_long().

An equivalent of device_add_randomness() that credits entropy would also
do the trick for adding entropy, it'd definitely be more hassle to
implement and quite possibly more trouble than it's worth compared to a
simple call like you suggest but it does have the advantage that you
know the core can't try to call it once we've got multiple CPUs up.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
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] 6+ messages in thread

end of thread, other threads:[~2020-01-09 16:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-08 19:41 [PATCH v9 0/3] ARMv8.5-RNG support Mark Brown
2020-01-08 19:41 ` [PATCH v9 1/3] arm64: Implement archrandom.h for ARMv8.5-RNG Mark Brown
2020-01-08 19:41 ` [PATCH v9 2/3] arm64: random: Add data to pool from setup_arch() Mark Brown
2020-01-08 21:33   ` Richard Henderson
2020-01-09 16:18     ` Mark Brown
2020-01-08 19:41 ` [PATCH v9 3/3] arm64: Use v8.5-RNG entropy for KASLR seed Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.