diff options
Diffstat (limited to 'sys/dev/random')
-rw-r--r-- | sys/dev/random/fenestrasX/fx_pool.c | 15 | ||||
-rw-r--r-- | sys/dev/random/ivy.c | 69 | ||||
-rw-r--r-- | sys/dev/random/random_harvestq.c | 4 | ||||
-rw-r--r-- | sys/dev/random/rdseed.c | 169 |
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 + */ |