Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/x86 Remove callout-based RNG support in VIA crypto ...
details: https://anonhg.NetBSD.org/src/rev/bd94647056a6
branches: trunk
changeset: 343792:bd94647056a6
user: tls <tls%NetBSD.org@localhost>
date: Sat Feb 27 00:54:59 2016 +0000
description:
Remove callout-based RNG support in VIA crypto driver; add VIA RNG backend for cpu_rng.
diffstat:
sys/arch/x86/include/via_padlock.h | 9 +----
sys/arch/x86/x86/cpu_rng.c | 60 +++++++++++++++++++++++++++++++-
sys/arch/x86/x86/via_padlock.c | 70 +------------------------------------
3 files changed, 61 insertions(+), 78 deletions(-)
diffs (245 lines):
diff -r 2addbc4c6fdc -r bd94647056a6 sys/arch/x86/include/via_padlock.h
--- a/sys/arch/x86/include/via_padlock.h Sat Feb 27 00:43:55 2016 +0000
+++ b/sys/arch/x86/include/via_padlock.h Sat Feb 27 00:54:59 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: via_padlock.h,v 1.8 2015/04/13 16:03:51 riastradh Exp $ */
+/* $NetBSD: via_padlock.h,v 1.9 2016/02/27 00:54:59 tls Exp $ */
/*-
* Copyright (c) 2003 Jason Wright
@@ -59,11 +59,6 @@
uint8_t op_iv[16]; /* 128 bit aligned */
void *op_buf;
- int sc_rnd_hz;
- struct callout sc_rnd_co;
- krndsource_t sc_rnd_source;
- bool sc_rnd_attached;
-
/* normal softc stuff */
int32_t sc_cid;
bool sc_cid_attached;
@@ -74,8 +69,6 @@
#define VIAC3_SESSION(sid) ((sid) & 0x0fffffff)
#define VIAC3_SID(crd,ses) (((crd) << 28) | ((ses) & 0x0fffffff))
-#define VIAC3_RNG_BUFSIZ 16
-
#endif /* _KERNEL */
#if defined(_KERNEL) || defined(_KMEMUSER)
diff -r 2addbc4c6fdc -r bd94647056a6 sys/arch/x86/x86/cpu_rng.c
--- a/sys/arch/x86/x86/cpu_rng.c Sat Feb 27 00:43:55 2016 +0000
+++ b/sys/arch/x86/x86/cpu_rng.c Sat Feb 27 00:54:59 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_rng.c,v 1.2 2016/02/27 00:43:55 tls Exp $ */
+/* $NetBSD: cpu_rng.c,v 1.3 2016/02/27 00:54:59 tls Exp $ */
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -29,6 +29,12 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * The VIA RNG code in this file is inspired by Jason Wright and
+ * Theo de Raadt's OpenBSD version but has been rewritten in light of
+ * comments from Henric Jungheim on the tech%openbsd.org@localhost mailing list.
+ */
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/cpu.h>
@@ -42,7 +48,8 @@
static enum {
CPU_RNG_NONE = 0,
CPU_RNG_RDRAND,
- CPU_RNG_RDSEED } cpu_rng_mode __read_mostly = CPU_RNG_NONE;
+ CPU_RNG_RDSEED,
+ CPU_RNG_VIA } cpu_rng_mode __read_mostly = CPU_RNG_NONE;
bool
cpu_rng_init(void)
@@ -56,6 +63,10 @@
cpu_rng_mode = CPU_RNG_RDRAND;
aprint_normal("cpu_rng: RDRAND\n");
return true;
+ } else if (cpu_feature[4] & CPUID_VIA_HAS_RNG) {
+ cpu_rng_mode = CPU_RNG_VIA;
+ aprint_normal("cpu_rng: VIA\n");
+ return true;
}
return false;
}
@@ -121,6 +132,49 @@
return cpu_rng_rdrand(out);
}
+static size_t
+cpu_rng_via(cpu_rng_t *out)
+{
+ uint32_t creg0, rndsts;
+
+ /*
+ * Sadly, we have to monkey with the coprocessor enable and fault
+ * registers, which are really for the FPU, in order to read
+ * from the RNG.
+ *
+ * Don't remove CR0_TS from the call below -- comments in the Linux
+ * driver indicate that the xstorerng instruction can generate
+ * spurious DNA faults though no FPU or SIMD state is changed
+ * even if such a fault is generated.
+ *
+ * XXX can this really happen if we don't use "rep xstorrng"?
+ *
+ */
+ kpreempt_disable();
+ x86_disable_intr();
+ creg0 = rcr0();
+ lcr0(creg0 & ~(CR0_EM|CR0_TS)); /* Permit access to SIMD/FPU path */
+ /*
+ * The VIA RNG has an output queue of 8-byte values. Read one.
+ * This is atomic, so if the FPU were already enabled, we could skip
+ * all the preemption and interrupt frobbing. If we had bread,
+ * we could have a ham sandwich, if we had any ham.
+ */
+ __asm __volatile("xstorerng"
+ : "=a" (rndsts), "+D" (out) : "d" (0) : "memory");
+ /* Put CR0 back how it was */
+ lcr0(creg0);
+ x86_enable_intr();
+ kpreempt_enable();
+
+ /*
+ * The Cryptography Research paper on the VIA RNG estimates
+ * 0.75 bits of entropy per output bit and advises users to
+ * be "even more conservative".
+ */
+ return rndsts & 0xf ? 0 : sizeof(cpu_rng_t) * NBBY / 2;
+}
+
size_t
cpu_rng(cpu_rng_t *out)
{
@@ -131,6 +185,8 @@
return cpu_rng_rdseed(out);
case CPU_RNG_RDRAND:
return cpu_rng_rdrand(out);
+ case CPU_RNG_VIA:
+ return cpu_rng_via(out);
default:
panic("cpu_rng: unknown mode %d", (int)cpu_rng_mode);
}
diff -r 2addbc4c6fdc -r bd94647056a6 sys/arch/x86/x86/via_padlock.c
--- a/sys/arch/x86/x86/via_padlock.c Sat Feb 27 00:43:55 2016 +0000
+++ b/sys/arch/x86/x86/via_padlock.c Sat Feb 27 00:54:59 2016 +0000
@@ -1,5 +1,5 @@
/* $OpenBSD: via.c,v 1.8 2006/11/17 07:47:56 tom Exp $ */
-/* $NetBSD: via_padlock.c,v 1.24 2015/04/13 16:03:51 riastradh Exp $ */
+/* $NetBSD: via_padlock.c,v 1.25 2016/02/27 00:54:59 tls Exp $ */
/*-
* Copyright (c) 2003 Jason Wright
@@ -20,7 +20,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.24 2015/04/13 16:03:51 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.25 2016/02/27 00:54:59 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -28,7 +28,6 @@
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/module.h>
-#include <sys/rndsource.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/cpu.h>
@@ -72,64 +71,6 @@
void *);
static void
-via_c3_rnd(void *arg)
-{
- struct via_padlock_softc *sc = arg;
-
- uint32_t creg0, len = VIAC3_RNG_BUFSIZ;
- uint32_t buffer[VIAC3_RNG_BUFSIZ/4 + 1]; /* CPU goes 3 bytes beyond */
- uint32_t eax, ecx, edi; /* XXX write-only, but necessary it seems */
-
- /*
- * Sadly, we have to monkey with the coprocessor enable and fault
- * registers, which are really for the FPU, in order to read
- * from the RNG.
- *
- * Don't remove CR0_TS from the call below -- comments in the Linux
- * driver indicate that the xstorerng instruction can generate
- * spurious DNA faults though no FPU or SIMD state is changed
- * even if such a fault is generated.
- *
- */
- kpreempt_disable();
- x86_disable_intr();
- creg0 = rcr0();
- lcr0(creg0 & ~(CR0_EM|CR0_TS)); /* Permit access to SIMD/FPU path */
- /*
- * Collect the random data from the C3 RNG into our buffer.
- * We turn on maximum whitening (is this actually desirable
- * if we will feed the data to SHA1?) (%edx[0,1] = "11").
- */
- __asm __volatile("rep xstorerng"
- : "=a" (eax), "=c" (ecx), "=D" (edi)
- : "d" (3), "D" (buffer), "c" (len)
- : "memory", "cc");
- /* Put CR0 back how it was */
- lcr0(creg0);
- x86_enable_intr();
- kpreempt_enable();
- rnd_add_data(&sc->sc_rnd_source, buffer, len, len * NBBY);
- callout_reset(&sc->sc_rnd_co, sc->sc_rnd_hz, via_c3_rnd, sc);
-}
-
-static void
-via_c3_rnd_init(struct via_padlock_softc *sc)
-{
- sc->sc_rnd_attached = true;
-
- if (hz >= 100) {
- sc->sc_rnd_hz = 10 * hz / 100;
- } else {
- sc->sc_rnd_hz = 10;
- }
- rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
- RND_TYPE_RNG, RND_FLAG_COLLECT_VALUE);
- callout_init(&sc->sc_rnd_co, 0);
- /* Call once to prime the pool early and set callout. */
- via_c3_rnd(sc);
-}
-
-static void
via_c3_ace_init(struct via_padlock_softc *sc)
{
/*
@@ -608,7 +549,6 @@
aprint_normal("%s:", device_xname(self));
if (cpu_feature[4] & CPUID_VIA_HAS_RNG) {
- via_c3_rnd_init(sc);
aprint_normal(" RNG");
}
if (cpu_feature[4] & CPUID_VIA_HAS_ACE) {
@@ -623,12 +563,6 @@
{
struct via_padlock_softc *sc = device_private(self);
- if (sc->sc_rnd_attached) {
- callout_halt(&sc->sc_rnd_co, NULL);
- callout_destroy(&sc->sc_rnd_co);
- rnd_detach_source(&sc->sc_rnd_source);
- sc->sc_rnd_attached = false;
- }
if (sc->sc_cid_attached) {
crypto_unregister(sc->sc_cid, CRYPTO_AES_CBC);
crypto_unregister(sc->sc_cid, CRYPTO_MD5_HMAC_96);
Home |
Main Index |
Thread Index |
Old Index