summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2015-12-27 04:31:35 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2015-12-27 04:31:35 +0000
commit720267282fe64550141b5ceb281072e007c6bd47 (patch)
tree6a923bad36913111ee9599dab8a014ea79abd666
parentc96b10aaf03ee1d8d58fa60bfd8cb068070ecfe7 (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.c5
-rw-r--r--sys/arch/amd64/amd64/cpu.c24
-rw-r--r--sys/arch/amd64/amd64/identcpu.c6
-rw-r--r--sys/arch/i386/i386/autoconf.c5
-rw-r--r--sys/arch/i386/i386/cpu.c23
-rw-r--r--sys/arch/i386/i386/machdep.c5
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();