diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-12-27 04:31:35 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2015-12-27 04:31:35 +0000 |
commit | 720267282fe64550141b5ceb281072e007c6bd47 (patch) | |
tree | 6a923bad36913111ee9599dab8a014ea79abd666 | |
parent | c96b10aaf03ee1d8d58fa60bfd8cb068070ecfe7 (diff) |
If available prefer the rdseed instruction over rdrand when adding entropy
to the kernel rng. If the rdseed source is empty fallback to rdrand
as suggested by naddy. rdrand output comes from a prng that is
periodically reseeded. rdseed should give us more bits of entropy.
ok naddy@ djm@ deraadt@
-rw-r--r-- | sys/arch/amd64/amd64/autoconf.c | 5 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 24 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/identcpu.c | 6 | ||||
-rw-r--r-- | sys/arch/i386/i386/autoconf.c | 5 | ||||
-rw-r--r-- | sys/arch/i386/i386/cpu.c | 23 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 5 |
6 files changed, 44 insertions, 24 deletions
diff --git a/sys/arch/amd64/amd64/autoconf.c b/sys/arch/amd64/amd64/autoconf.c index 0cb241770c1..5c7566a12c4 100644 --- a/sys/arch/amd64/amd64/autoconf.c +++ b/sys/arch/amd64/amd64/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.44 2015/11/07 01:37:26 naddy Exp $ */ +/* $OpenBSD: autoconf.c,v 1.45 2015/12/27 04:31:34 jsg Exp $ */ /* $NetBSD: autoconf.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -91,6 +91,7 @@ void viac3_rnd(void *); extern struct timeout rdrand_tmo; extern int has_rdrand; +extern int has_rdseed; void rdrand(void *); #ifdef CRYPTO @@ -138,7 +139,7 @@ cpu_configure(void) timeout_set(&viac3_rnd_tmo, viac3_rnd, &viac3_rnd_tmo); viac3_rnd(&viac3_rnd_tmo); } - if (has_rdrand) { + if (has_rdrand || has_rdseed) { timeout_set(&rdrand_tmo, rdrand, &rdrand_tmo); rdrand(&rdrand_tmo); } diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index 9c45df415a7..cd838422e6c 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.93 2015/12/06 03:14:55 dlg Exp $ */ +/* $OpenBSD: cpu.c,v 1.94 2015/12/27 04:31:34 jsg Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -875,23 +875,27 @@ void rdrand(void *v) { struct timeout *tmo = v; - extern int has_rdrand; + extern int has_rdrand, has_rdseed; union { uint64_t u64; uint32_t u32[2]; } r; - uint64_t valid; + uint8_t valid; int i; - if (has_rdrand == 0) + if (has_rdrand == 0 && has_rdseed == 0) return; for (i = 0; i < 2; i++) { - __asm volatile( - "xor %1, %1\n\t" - "rdrand %0\n\t" - "rcl $1, %1\n" - : "=r" (r.u64), "=r" (valid) ); - + if (has_rdseed) + __asm volatile( + "rdseed %0\n\t" + "setc %1\n" + : "=r" (r.u64), "=qm" (valid) ); + if (has_rdseed == 0 || valid == 0) + __asm volatile( + "rdrand %0\n\t" + "setc %1\n" + : "=r" (r.u64), "=qm" (valid) ); if (valid) { add_true_randomness(r.u32[0]); add_true_randomness(r.u32[1]); diff --git a/sys/arch/amd64/amd64/identcpu.c b/sys/arch/amd64/amd64/identcpu.c index f40ab0e1bd1..705270d605a 100644 --- a/sys/arch/amd64/amd64/identcpu.c +++ b/sys/arch/amd64/amd64/identcpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: identcpu.c,v 1.70 2015/12/12 12:33:49 reyk Exp $ */ +/* $OpenBSD: identcpu.c,v 1.71 2015/12/27 04:31:34 jsg Exp $ */ /* $NetBSD: identcpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /* @@ -62,6 +62,7 @@ int amd64_has_pclmul; int amd64_has_aesni; #endif int has_rdrand; +int has_rdseed; #include "pvbus.h" #if NPVBUS > 0 @@ -605,6 +606,9 @@ identifycpu(struct cpu_info *ci) if (cpu_ecxfeature & CPUIDECX_RDRAND) has_rdrand = 1; + if (ci->ci_feature_sefflags_ebx & SEFF0EBX_RDSEED) + has_rdseed = 1; + if (ci->ci_feature_sefflags_ebx & SEFF0EBX_SMAP) replacesmap(); } diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c index e58b77a4248..6660ebb992d 100644 --- a/sys/arch/i386/i386/autoconf.c +++ b/sys/arch/i386/i386/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.94 2015/04/24 19:53:43 mlarkin Exp $ */ +/* $OpenBSD: autoconf.c,v 1.95 2015/12/27 04:31:34 jsg Exp $ */ /* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */ /*- @@ -101,6 +101,7 @@ void viac3_rnd(void *); extern struct timeout rdrand_tmo; extern int has_rdrand; +extern int has_rdseed; void rdrand(void *); #ifdef CRYPTO @@ -176,7 +177,7 @@ cpu_configure(void) timeout_set(&viac3_rnd_tmo, viac3_rnd, &viac3_rnd_tmo); viac3_rnd(&viac3_rnd_tmo); } - if (has_rdrand) { + if (has_rdrand || has_rdseed) { timeout_set(&rdrand_tmo, rdrand, &rdrand_tmo); rdrand(&rdrand_tmo); } diff --git a/sys/arch/i386/i386/cpu.c b/sys/arch/i386/i386/cpu.c index 626e388f0f3..612c958a94c 100644 --- a/sys/arch/i386/i386/cpu.c +++ b/sys/arch/i386/i386/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.69 2015/12/07 06:34:14 jsg Exp $ */ +/* $OpenBSD: cpu.c,v 1.70 2015/12/27 04:31:34 jsg Exp $ */ /* $NetBSD: cpu.c,v 1.1.2.7 2000/06/26 02:04:05 sommerfeld Exp $ */ /*- @@ -445,17 +445,24 @@ rdrand(void *v) { struct timeout *tmo = v; extern int has_rdrand; - uint32_t r, valid; + extern int has_rdseed; + uint32_t r; + uint8_t valid; int i; - if (has_rdrand == 0) + if (has_rdrand == 0 && has_rdseed == 0) return; for (i = 0; i < 4; i++) { - __asm volatile( - "xor %1, %1\n\t" - "rdrand %0\n\t" - "rcl $1, %1\n" - : "=r" (r), "=r" (valid) ); + if (has_rdseed) + __asm volatile( + "rdseed %0\n\t" + "setc %1\n" + : "=r" (r), "=qm" (valid) ); + if (has_rdseed == 0 || valid == 0) + __asm volatile( + "rdrand %0\n\t" + "setc %1\n" + : "=r" (r), "=qm" (valid) ); if (valid) add_true_randomness(r); } diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index bd1fba43bcc..68352e91744 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.578 2015/12/12 12:33:49 reyk Exp $ */ +/* $OpenBSD: machdep.c,v 1.579 2015/12/27 04:31:34 jsg Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -314,6 +314,7 @@ int allowaperture = 0; #endif int has_rdrand; +int has_rdseed; #include "pvbus.h" #if NPVBUS > 0 @@ -2038,6 +2039,8 @@ identifycpu(struct cpu_info *ci) if (ci->ci_flags & CPUF_PRIMARY) { if (cpu_ecxfeature & CPUIDECX_RDRAND) has_rdrand = 1; + if (ci->ci_feature_sefflags_ebx & SEFF0EBX_RDSEED) + has_rdseed = 1; #ifndef SMALL_KERNEL if (ci->ci_feature_sefflags_ebx & SEFF0EBX_SMAP) replacesmap(); |