Module Name:    src
Committed By:   tls
Date:           Sat Feb 27 00:54:59 UTC 2016

Modified Files:
        src/sys/arch/x86/include: via_padlock.h
        src/sys/arch/x86/x86: cpu_rng.c via_padlock.c

Log Message:
Remove callout-based RNG support in VIA crypto driver; add VIA RNG backend for 
cpu_rng.


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/x86/include/via_padlock.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/x86/x86/cpu_rng.c
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/x86/x86/via_padlock.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/include/via_padlock.h
diff -u src/sys/arch/x86/include/via_padlock.h:1.8 src/sys/arch/x86/include/via_padlock.h:1.9
--- src/sys/arch/x86/include/via_padlock.h:1.8	Mon Apr 13 16:03:51 2015
+++ src/sys/arch/x86/include/via_padlock.h	Sat Feb 27 00:54:59 2016
@@ -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 @@ struct via_padlock_softc {
 	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 @@ struct via_padlock_softc {
 #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)

Index: src/sys/arch/x86/x86/cpu_rng.c
diff -u src/sys/arch/x86/x86/cpu_rng.c:1.2 src/sys/arch/x86/x86/cpu_rng.c:1.3
--- src/sys/arch/x86/x86/cpu_rng.c:1.2	Sat Feb 27 00:43:55 2016
+++ src/sys/arch/x86/x86/cpu_rng.c	Sat Feb 27 00:54:59 2016
@@ -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 t...@openbsd.org 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_init(void)
 		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 @@ exhausted:
 	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 @@ cpu_rng(cpu_rng_t *out)
 		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);
 	}

Index: src/sys/arch/x86/x86/via_padlock.c
diff -u src/sys/arch/x86/x86/via_padlock.c:1.24 src/sys/arch/x86/x86/via_padlock.c:1.25
--- src/sys/arch/x86/x86/via_padlock.c:1.24	Mon Apr 13 16:03:51 2015
+++ src/sys/arch/x86/x86/via_padlock.c	Sat Feb 27 00:54:59 2016
@@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: via_padlock.
 #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 @@ static	__inline void via_padlock_cbc(voi
 	    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 @@ via_padlock_attach_intr(device_t self)
 
 	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 @@ via_padlock_detach(device_t self, int fl
 {
 	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);

Reply via email to