diff options
Diffstat (limited to 'sys/dev/random')
| -rw-r--r-- | sys/dev/random/fenestrasX/fx_pool.c | 18 | ||||
| -rw-r--r-- | sys/dev/random/ivy.c | 69 | ||||
| -rw-r--r-- | sys/dev/random/random_harvestq.c | 5 | ||||
| -rw-r--r-- | sys/dev/random/rdseed.c | 169 | 
4 files changed, 202 insertions, 59 deletions
| diff --git a/sys/dev/random/fenestrasX/fx_pool.c b/sys/dev/random/fenestrasX/fx_pool.c index f4ad1e295d54..8e63b345a1bd 100644 --- a/sys/dev/random/fenestrasX/fx_pool.c +++ b/sys/dev/random/fenestrasX/fx_pool.c @@ -167,21 +167,18 @@ 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,  	},  	[RANDOM_PURE_GLXSB] = {  		.entc_cls = &fxrng_hi_push,  	}, -	[RANDOM_PURE_HIFN] = { -		.entc_cls = &fxrng_hi_push, -	},  	[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 +203,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..643dbac1fc8b 100644 --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -661,11 +661,10 @@ 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 + */ | 
