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