aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/random
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/random')
-rw-r--r--sys/dev/random/fenestrasX/fx_pool.c15
-rw-r--r--sys/dev/random/ivy.c69
-rw-r--r--sys/dev/random/random_harvestq.c4
-rw-r--r--sys/dev/random/rdseed.c169
4 files changed, 202 insertions, 55 deletions
diff --git a/sys/dev/random/fenestrasX/fx_pool.c b/sys/dev/random/fenestrasX/fx_pool.c
index f4ad1e295d54..858069035572 100644
--- a/sys/dev/random/fenestrasX/fx_pool.c
+++ b/sys/dev/random/fenestrasX/fx_pool.c
@@ -167,9 +167,6 @@ static const struct fxrng_ent_char {
[RANDOM_RANDOMDEV] = {
.entc_cls = &fxrng_lo_push,
},
- [RANDOM_PURE_OCTEON] = {
- .entc_cls = &fxrng_hi_push, /* Could be made pull. */
- },
[RANDOM_PURE_SAFE] = {
.entc_cls = &fxrng_hi_push,
},
@@ -182,6 +179,9 @@ static const struct fxrng_ent_char {
[RANDOM_PURE_RDRAND] = {
.entc_cls = &fxrng_hi_pull,
},
+ [RANDOM_PURE_RDSEED] = {
+ .entc_cls = &fxrng_hi_pull,
+ },
[RANDOM_PURE_NEHEMIAH] = {
.entc_cls = &fxrng_hi_pull,
},
@@ -206,6 +206,15 @@ static const struct fxrng_ent_char {
[RANDOM_PURE_VMGENID] = {
.entc_cls = &fxrng_hi_push,
},
+ [RANDOM_PURE_QUALCOMM] = {
+ .entc_cls = &fxrng_hi_pull,
+ },
+ [RANDOM_PURE_ARMV8] = {
+ .entc_cls = &fxrng_hi_pull,
+ },
+ [RANDOM_PURE_ARM_TRNG] = {
+ .entc_cls = &fxrng_hi_pull,
+ },
};
/* Useful for single-bit-per-source state. */
diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c
index fa1e4831f1b9..3eb0f261e6dc 100644
--- a/sys/dev/random/ivy.c
+++ b/sys/dev/random/ivy.c
@@ -1,6 +1,6 @@
/*-
+ * Copyright (c) 2013, 2025, David E. O'Brien <deo@NUXI.org>
* Copyright (c) 2013 The FreeBSD Foundation
- * Copyright (c) 2013 David E. O'Brien <obrien@NUXI.org>
* Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org>
* All rights reserved.
*
@@ -48,7 +48,6 @@
#define RETRY_COUNT 10
-static bool has_rdrand, has_rdseed;
static u_int random_ivy_read(void *, u_int);
static const struct random_source random_ivy = {
@@ -57,13 +56,7 @@ static const struct random_source random_ivy = {
.rs_read = random_ivy_read
};
-SYSCTL_NODE(_kern_random, OID_AUTO, rdrand, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
- "rdrand (ivy) entropy source");
static bool acquire_independent_seed_samples = false;
-SYSCTL_BOOL(_kern_random_rdrand, OID_AUTO, rdrand_independent_seed,
- CTLFLAG_RWTUN, &acquire_independent_seed_samples, 0,
- "If non-zero, use more expensive and slow, but safer, seeded samples "
- "where RDSEED is not present.");
static bool
x86_rdrand_store(u_long *buf)
@@ -99,45 +92,6 @@ x86_rdrand_store(u_long *buf)
return (true);
}
-static bool
-x86_rdseed_store(u_long *buf)
-{
- u_long rndval;
- int retry;
-
- retry = RETRY_COUNT;
- __asm __volatile(
- "1:\n\t"
- "rdseed %1\n\t" /* read randomness into rndval */
- "jc 2f\n\t" /* CF is set on success, exit retry loop */
- "dec %0\n\t" /* otherwise, retry-- */
- "jne 1b\n\t" /* and loop if retries are not exhausted */
- "2:"
- : "+r" (retry), "=r" (rndval) : : "cc");
- *buf = rndval;
- return (retry != 0);
-}
-
-static bool
-x86_unimpl_store(u_long *buf __unused)
-{
-
- panic("%s called", __func__);
-}
-
-DEFINE_IFUNC(static, bool, x86_rng_store, (u_long *buf))
-{
- has_rdrand = (cpu_feature2 & CPUID2_RDRAND);
- has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED);
-
- if (has_rdseed)
- return (x86_rdseed_store);
- else if (has_rdrand)
- return (x86_rdrand_store);
- else
- return (x86_unimpl_store);
-}
-
/* It is required that buf length is a multiple of sizeof(u_long). */
static u_int
random_ivy_read(void *buf, u_int c)
@@ -148,7 +102,7 @@ random_ivy_read(void *buf, u_int c)
KASSERT(c % sizeof(*b) == 0, ("partial read %d", c));
b = buf;
for (count = c; count > 0; count -= sizeof(*b)) {
- if (!x86_rng_store(&rndval))
+ if (!x86_rdrand_store(&rndval))
break;
*b++ = rndval;
}
@@ -158,18 +112,33 @@ random_ivy_read(void *buf, u_int c)
static int
rdrand_modevent(module_t mod, int type, void *unused)
{
+ struct sysctl_ctx_list ctx;
+ struct sysctl_oid *o;
+ bool has_rdrand, has_rdseed;
int error = 0;
+ has_rdrand = (cpu_feature2 & CPUID2_RDRAND);
+ has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED);
+
switch (type) {
case MOD_LOAD:
- if (has_rdrand || has_rdseed) {
+ if (has_rdrand && !has_rdseed) {
+ sysctl_ctx_init(&ctx);
+ o = SYSCTL_ADD_NODE(&ctx, SYSCTL_STATIC_CHILDREN(_kern_random),
+ OID_AUTO, "rdrand", CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
+ "rdrand (ivy) entropy source");
+ SYSCTL_ADD_BOOL(&ctx, SYSCTL_CHILDREN(o), OID_AUTO,
+ "rdrand_independent_seed", CTLFLAG_RDTUN,
+ &acquire_independent_seed_samples, 0,
+ "If non-zero, use more expensive and slow, but safer, seeded samples "
+ "where RDSEED is not present.");
random_source_register(&random_ivy);
printf("random: fast provider: \"%s\"\n", random_ivy.rs_ident);
}
break;
case MOD_UNLOAD:
- if (has_rdrand || has_rdseed)
+ if (has_rdrand && !has_rdseed)
random_source_deregister(&random_ivy);
break;
diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c
index 2d7af254c52c..e38fd38c310b 100644
--- a/sys/dev/random/random_harvestq.c
+++ b/sys/dev/random/random_harvestq.c
@@ -661,11 +661,11 @@ static const char *random_source_descr[ENTROPYSOURCE] = {
[RANDOM_UMA] = "UMA",
[RANDOM_CALLOUT] = "CALLOUT",
[RANDOM_RANDOMDEV] = "RANDOMDEV", /* ENVIRONMENTAL_END */
- [RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */
- [RANDOM_PURE_SAFE] = "PURE_SAFE",
+ [RANDOM_PURE_SAFE] = "PURE_SAFE", /* PURE_START */
[RANDOM_PURE_GLXSB] = "PURE_GLXSB",
[RANDOM_PURE_HIFN] = "PURE_HIFN",
[RANDOM_PURE_RDRAND] = "PURE_RDRAND",
+ [RANDOM_PURE_RDSEED] = "PURE_RDSEED",
[RANDOM_PURE_NEHEMIAH] = "PURE_NEHEMIAH",
[RANDOM_PURE_RNDTEST] = "PURE_RNDTEST",
[RANDOM_PURE_VIRTIO] = "PURE_VIRTIO",
diff --git a/sys/dev/random/rdseed.c b/sys/dev/random/rdseed.c
new file mode 100644
index 000000000000..af084aab4ed9
--- /dev/null
+++ b/sys/dev/random/rdseed.c
@@ -0,0 +1,169 @@
+/*-
+ * Copyright (c) 2013, 2025, David E. O'Brien <deo@NUXI.org>
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * Copyright (c) 2012 Konstantin Belousov <kib@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/random.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <machine/md_var.h>
+#include <machine/specialreg.h>
+#include <x86/ifunc.h>
+
+#include <dev/random/randomdev.h>
+
+#define RETRY_COUNT 10
+
+static u_int random_rdseed_read(void *, u_int);
+
+static struct random_source random_rdseed = {
+ .rs_ident = "Intel Secure Key Seed",
+ .rs_source = RANDOM_PURE_RDSEED,
+ .rs_read = random_rdseed_read
+};
+
+SYSCTL_NODE(_kern_random, OID_AUTO, rdseed, CTLFLAG_RW, 0,
+ "rdseed (x86) entropy source");
+/* XXX: kern.random.rdseed.enabled=0 also disables RDRAND */
+static bool enabled = true;
+SYSCTL_BOOL(_kern_random_rdseed, OID_AUTO, enabled, CTLFLAG_RDTUN, &enabled, 0,
+ "If zero, disable the use of RDSEED.");
+
+static bool
+x86_rdseed_store(u_long *buf)
+{
+ u_long rndval;
+ int retry;
+
+ retry = RETRY_COUNT;
+ __asm __volatile(
+ "1:\n\t"
+ "rdseed %1\n\t" /* read randomness into rndval */
+ "jc 2f\n\t" /* CF is set on success, exit retry loop */
+ "dec %0\n\t" /* otherwise, retry-- */
+ "jne 1b\n\t" /* and loop if retries are not exhausted */
+ "2:"
+ : "+r" (retry), "=r" (rndval) : : "cc");
+ *buf = rndval;
+ return (retry != 0);
+}
+
+/* It is required that buf length is a multiple of sizeof(u_long). */
+static u_int
+random_rdseed_read(void *buf, u_int c)
+{
+ u_long *b, rndval;
+ u_int count;
+
+ KASSERT(c % sizeof(*b) == 0, ("partial read %d", c));
+ b = buf;
+ for (count = c; count > 0; count -= sizeof(*b)) {
+ if (!x86_rdseed_store(&rndval))
+ break;
+ *b++ = rndval;
+ }
+ return (c - count);
+}
+
+static int
+rdseed_modevent(module_t mod, int type, void *unused)
+{
+ bool has_rdseed;
+ int error = 0;
+
+ has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED);
+
+ switch (type) {
+ case MOD_LOAD:
+ if (has_rdseed && enabled) {
+ random_source_register(&random_rdseed);
+ printf("random: fast provider: \"%s\"\n", random_rdseed.rs_ident);
+ }
+ break;
+
+ case MOD_UNLOAD:
+ if (has_rdseed)
+ random_source_deregister(&random_rdseed);
+ break;
+
+ case MOD_SHUTDOWN:
+ break;
+
+ default:
+ error = EOPNOTSUPP;
+ break;
+
+ }
+
+ return (error);
+}
+
+static moduledata_t rdseed_mod = {
+ "rdseed",
+ rdseed_modevent,
+ 0
+};
+
+DECLARE_MODULE(rdseed, rdseed_mod, SI_SUB_RANDOM, SI_ORDER_FOURTH);
+MODULE_VERSION(rdseed, 1);
+MODULE_DEPEND(rdseed, random_harvestq, 1, 1, 1);
+
+/*
+ * Intel's RDSEED Entropy Assessment Report min-entropy claim is 0.6 Shannons
+ * per bit of data output. Rrefer to the following Entropy Source Validation
+ * (ESV) certificates:
+ *
+ * E#87: Junos OS Physical Entropy Source - Broadwell EP 10-Core Die
+ * Broadwell-EP-10 FCLGA2011 Intel(R) Xeon(R) E5-2620 V4 Processor
+ * https://csrc.nist.gov/projects/cryptographic-module-validation-program/entropy-validations/certificate/87
+ * (URLs below omitted for brevity but follow same format.)
+ *
+ * E#121: Junos OS Physical Entropy Source - Intel Atom C3000 Series
+ * (Denverton) 16 Core Die with FCBGA1310 Package
+ *
+ * E#122: Junos OS Physical Entropy Source - Intel Xeon D-1500 Family
+ * (Broadwell) 8 Core Die with FCBGA1667 Package
+ *
+ * E#123: Junos OS Physical Entropy Source - Intel Xeon D-2100 Series
+ * (Skylake) 18 Core Die with FCBGA2518 Package
+ *
+ * E#141: Junos OS Physical Entropy Source - Intel Xeon D-10 Series
+ * (Ice Lake-D-10) Die with FCBGA2227 Package
+ *
+ * E#169: Junos OS Physical Entropy Source - Intel Xeon AWS-1000 v4 and
+ * E5 v4 (Broadwell EP) 15 Core Die with FCLGA2011 Package
+ */