Module Name:    src
Committed By:   tls
Date:           Mon Apr  7 02:20:00 UTC 2014

Modified Files:
        src/sys/kern [tls-earlyentropy]: init_main.c kern_rndq.c kern_sysctl.c
            subr_autoconf.c subr_prf.c
        src/sys/sys [tls-earlyentropy]: kprintf.h

Log Message:
Get more entropy into the system early:

        1) Add device attach timings from autoconf.
        2) Accumulate the output of kernel printf (as well as the times
           when it's called) and add this periodically.  To avoid issues
           with recursion through diagnostic printfs, we use SHA512 to
           accumulate the printf output, then mix in its output.
        3) Add all sysctl settings -- mixes in the hostname and likely a
           bit more.


To generate a diff of this commit:
cvs rdiff -u -r1.454 -r1.454.2.1 src/sys/kern/init_main.c
cvs rdiff -u -r1.23.2.1 -r1.23.2.2 src/sys/kern/kern_rndq.c
cvs rdiff -u -r1.249 -r1.249.2.1 src/sys/kern/kern_sysctl.c
cvs rdiff -u -r1.230 -r1.230.2.1 src/sys/kern/subr_autoconf.c
cvs rdiff -u -r1.153 -r1.153.2.1 src/sys/kern/subr_prf.c
cvs rdiff -u -r1.11 -r1.11.26.1 src/sys/sys/kprintf.h

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

Modified files:

Index: src/sys/kern/init_main.c
diff -u src/sys/kern/init_main.c:1.454 src/sys/kern/init_main.c:1.454.2.1
--- src/sys/kern/init_main.c:1.454	Wed Oct  2 21:38:55 2013
+++ src/sys/kern/init_main.c	Mon Apr  7 02:20:00 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $	*/
+/*	$NetBSD: init_main.c,v 1.454.2.1 2014/04/07 02:20:00 tls Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.454.2.1 2014/04/07 02:20:00 tls Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ipsec.h"
@@ -522,6 +522,9 @@ main(void)
 	/* Enable deferred processing of RNG samples */
 	rnd_init_softint();
 
+	/* Enable periodic injection of console output into entropy pool */
+	kprintf_init_callout();
+
 #ifdef SYSVSHM
 	/* Initialize System V style shared memory. */
 	shminit();

Index: src/sys/kern/kern_rndq.c
diff -u src/sys/kern/kern_rndq.c:1.23.2.1 src/sys/kern/kern_rndq.c:1.23.2.2
--- src/sys/kern/kern_rndq.c:1.23.2.1	Mon Apr  7 02:00:00 2014
+++ src/sys/kern/kern_rndq.c	Mon Apr  7 02:20:00 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_rndq.c,v 1.23.2.1 2014/04/07 02:00:00 tls Exp $	*/
+/*	$NetBSD: kern_rndq.c,v 1.23.2.2 2014/04/07 02:20:00 tls Exp $	*/
 
 /*-
  * Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.23.2.1 2014/04/07 02:00:00 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.23.2.2 2014/04/07 02:20:00 tls Exp $");
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -156,6 +156,8 @@ static krndsource_t rnd_source_anonymous
 	.test = NULL
 };
 
+krndsource_t rnd_printf_source, rnd_autoconf_source;
+
 void *rnd_process, *rnd_wakeup;
 struct callout skew_callout;
 
@@ -608,6 +610,11 @@ rnd_init(void)
 			  RND_TYPE_UNKNOWN,
 			  RND_FLAG_COLLECT_TIME|RND_FLAG_COLLECT_VALUE|
 			  RND_FLAG_ESTIMATE_TIME);
+	rnd_attach_source(&rnd_printf_source, "printf", RND_TYPE_UNKNOWN,
+			  RND_FLAG_NO_ESTIMATE);
+	rnd_attach_source(&rnd_autoconf_source, "autoconf",
+			  RND_TYPE_UNKNOWN,
+			  RND_FLAG_COLLECT_TIME|RND_FLAG_ESTIMATE_TIME);
 	rnd_ready = 1;
 }
 

Index: src/sys/kern/kern_sysctl.c
diff -u src/sys/kern/kern_sysctl.c:1.249 src/sys/kern/kern_sysctl.c:1.249.2.1
--- src/sys/kern/kern_sysctl.c:1.249	Thu Mar 27 21:09:33 2014
+++ src/sys/kern/kern_sysctl.c	Mon Apr  7 02:20:00 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sysctl.c,v 1.249 2014/03/27 21:09:33 christos Exp $	*/
+/*	$NetBSD: kern_sysctl.c,v 1.249.2.1 2014/04/07 02:20:00 tls Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.249 2014/03/27 21:09:33 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.249.2.1 2014/04/07 02:20:00 tls Exp $");
 
 #include "opt_defcorename.h"
 #include "ksyms.h"
@@ -84,6 +84,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_sysctl.
 #include <sys/syscallargs.h>
 #include <sys/kauth.h>
 #include <sys/ktrace.h>
+#include <sys/rnd.h>
 
 #define	MAXDESCLEN	1024
 MALLOC_DEFINE(M_SYSCTLNODE, "sysctlnode", "sysctl node structures");
@@ -1610,6 +1611,7 @@ sysctl_lookup(SYSCTLFN_ARGS)
 		if (newlen != sz)
 			goto bad_size;
 		error = sysctl_copyin(l, newp, d, sz);
+		rnd_add_data(NULL, d, sz, 0);
 		break;
 	case CTLTYPE_STRING: {
 		/*
@@ -1653,8 +1655,10 @@ sysctl_lookup(SYSCTLFN_ARGS)
 		/*
 		 * looks good, so pop it into place and zero the rest.
 		 */
-		if (len > 0)
+		if (len > 0) {
 			memcpy(d, newbuf, len);
+			rnd_add_data(NULL, d, len, 0);
+		}
 		if (sz != len)
 			memset((char*)d + len, 0, sz - len);
 		free(newbuf, M_SYSCTLDATA);

Index: src/sys/kern/subr_autoconf.c
diff -u src/sys/kern/subr_autoconf.c:1.230 src/sys/kern/subr_autoconf.c:1.230.2.1
--- src/sys/kern/subr_autoconf.c:1.230	Tue Feb 25 18:30:11 2014
+++ src/sys/kern/subr_autoconf.c	Mon Apr  7 02:20:00 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.230 2014/02/25 18:30:11 pooka Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.230.2.1 2014/04/07 02:20:00 tls Exp $ */
 
 /*
  * Copyright (c) 1996, 2000 Christopher G. Demetriou
@@ -77,7 +77,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.230 2014/02/25 18:30:11 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.230.2.1 2014/04/07 02:20:00 tls Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -110,6 +110,8 @@ __KERNEL_RCSID(0, "$NetBSD: subr_autocon
 
 #include <sys/disk.h>
 
+#include <sys/rnd.h>
+
 #include <machine/limits.h>
 
 /*
@@ -117,6 +119,11 @@ __KERNEL_RCSID(0, "$NetBSD: subr_autocon
  */
 
 /*
+ * Device autoconfiguration timings are mixed into the entropy pool.
+ */
+extern krndsource_t rnd_autoconf_source;
+
+/*
  * ioconf.c exports exactly two names: cfdata and cfroots.  All system
  * devices and drivers are found via these tables.
  */
@@ -1051,6 +1058,14 @@ config_found_sm_loc(device_t parent,
 		aprint_normal("%s", msgs[(*print)(aux, device_xname(parent))]);
 	}
 
+	/*
+	 * This has the effect of mixing in a single timestamp to the
+	 * entropy pool.  Experiments indicate the estimator will almost
+	 * always attribute one bit of entropy to this sample; analysis
+	 * of device attach/detach timestamps on FreeBSD indicates 4
+	 * bits of entropy/sample so this seems appropriately conservative.
+	 */
+	rnd_add_uint32(&rnd_autoconf_source, 0);
 	return NULL;
 }
 

Index: src/sys/kern/subr_prf.c
diff -u src/sys/kern/subr_prf.c:1.153 src/sys/kern/subr_prf.c:1.153.2.1
--- src/sys/kern/subr_prf.c:1.153	Wed Mar 26 18:03:47 2014
+++ src/sys/kern/subr_prf.c	Mon Apr  7 02:20:00 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_prf.c,v 1.153 2014/03/26 18:03:47 christos Exp $	*/
+/*	$NetBSD: subr_prf.c,v 1.153.2.1 2014/04/07 02:20:00 tls Exp $	*/
 
 /*-
  * Copyright (c) 1986, 1988, 1991, 1993
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.153 2014/03/26 18:03:47 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v 1.153.2.1 2014/04/07 02:20:00 tls Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ipkdb.h"
@@ -63,6 +63,8 @@ __KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v
 #include <sys/atomic.h>
 #include <sys/kernel.h>
 #include <sys/cpu.h>
+#include <sys/sha2.h>
+#include <sys/rnd.h>
 
 #include <dev/cons.h>
 
@@ -73,7 +75,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_prf.c,v
 #endif
 
 static kmutex_t kprintf_mtx;
-static bool kprintf_inited = false;
+static bool kprintf_inited = false, kprintf_inited_callout = false;
 
 #ifdef KGDB
 #include <sys/kgdb.h>
@@ -103,6 +105,7 @@ static void	 putchar(int, int, struct tt
 
 extern	struct tty *constty;	/* pointer to console "window" tty */
 extern	int log_open;	/* subr_log: is /dev/klog open? */
+extern	krndsource_t	rnd_printf_source;
 const	char *panicstr; /* arg to first call to panic (used as a flag
 			   to indicate that panic has already been called). */
 struct cpu_info *paniccpu;	/* cpu that first paniced */
@@ -110,6 +113,12 @@ long	panicstart, panicend;	/* position i
 				   end of the formatted panicstr. */
 int	doing_shutdown;	/* set to indicate shutdown in progress */
 
+static SHA512_CTX kprnd_sha;
+static uint8_t kprnd_accum[SHA512_DIGEST_LENGTH];
+static int kprnd_added;
+
+static struct callout kprnd_callout;
+
 #ifndef	DUMP_ON_PANIC
 #define	DUMP_ON_PANIC	1
 #endif
@@ -133,6 +142,30 @@ const char HEXDIGITS[] = "0123456789ABCD
  * functions
  */
 
+static void kprintf_rnd_get(size_t bytes, void *priv)
+{
+	if (mutex_tryenter(&kprintf_mtx)) {
+		if (kprnd_added) {
+			SHA512_Final(kprnd_accum, &kprnd_sha);
+			rnd_add_data(&rnd_printf_source,
+				     kprnd_accum, sizeof(kprnd_accum), 0);
+			kprnd_added = 0;
+			/* This, we must do, since we called _Final. */
+			SHA512_Init(&kprnd_sha);
+			/* This is optional but seems useful. */
+			SHA512_Update(&kprnd_sha, kprnd_accum,
+				      sizeof(kprnd_accum));
+		}
+		mutex_exit(&kprintf_mtx);
+	}
+}
+
+static void kprintf_rnd_callout(void *arg)
+{
+	kprintf_rnd_get(0, NULL);
+	callout_schedule(&kprnd_callout, hz);
+}
+
 /*
  * Locking is inited fairly early in MI bootstrap.  Before that
  * prints are done unlocked.  But that doesn't really matter,
@@ -143,11 +176,22 @@ kprintf_init(void)
 {
 
 	KASSERT(!kprintf_inited && cold); /* not foolproof, but ... */
+	SHA512_Init(&kprnd_sha);
 	mutex_init(&kprintf_mtx, MUTEX_DEFAULT, IPL_HIGH);
 	kprintf_inited = true;
 }
 
 void
+kprintf_init_callout(void)
+{
+	KASSERT(!kprintf_inited_callout);
+	callout_init(&kprnd_callout, CALLOUT_MPSAFE);
+	callout_setfunc(&kprnd_callout, kprintf_rnd_callout, NULL);
+	callout_schedule(&kprnd_callout, hz);
+	kprintf_inited_callout = true;
+}
+
+void
 kprintf_lock(void)
 {
 
@@ -405,6 +449,8 @@ addlog(const char *fmt, ...)
 static void
 putchar(int c, int flags, struct tty *tp)
 {
+	uint8_t rbuf[SHA512_BLOCK_LENGTH];
+	static int cursor;
 
 	if (panicstr)
 		constty = NULL;
@@ -422,9 +468,20 @@ putchar(int c, int flags, struct tty *tp
 	if ((flags & TOCONS) && constty == NULL && c != '\0')
 		(*v_putc)(c);
 #ifdef DDB
-	if (flags & TODDB)
+	if (flags & TODDB) {
 		db_putchar(c);
+		return;
+	}
 #endif
+
+	rbuf[cursor] = c;
+	if (cursor == sizeof(rbuf) - 1) {
+		SHA512_Update(&kprnd_sha, rbuf, sizeof(rbuf));
+		kprnd_added++;
+		cursor = 0;
+	} else {
+		cursor++;
+	}
 }
 
 /*
@@ -773,7 +830,6 @@ aprint_error_ifnet(struct ifnet *ifp, co
 static void
 aprint_naive_internal(const char *prefix, const char *fmt, va_list ap)
 {
-
 	if ((boothowto & (AB_QUIET|AB_SILENT|AB_VERBOSE)) != AB_QUIET)
 		return;
 
@@ -876,7 +932,6 @@ aprint_verbose_ifnet(struct ifnet *ifp, 
 static void
 aprint_debug_internal(const char *prefix, const char *fmt, va_list ap)
 {
-
 	if ((boothowto & AB_DEBUG) == 0)
 		return;
 
@@ -927,7 +982,7 @@ printf_tolog(const char *fmt, ...)
 	kprintf_lock();
 
 	va_start(ap, fmt);
-	(void)kprintf(fmt, TOLOG, NULL, NULL, ap);
+	kprintf(fmt, TOLOG, NULL, NULL, ap);
 	va_end(ap);
 
 	kprintf_unlock();
@@ -983,7 +1038,6 @@ printf(const char *fmt, ...)
 void
 vprintf(const char *fmt, va_list ap)
 {
-
 	kprintf_lock();
 
 	kprintf(fmt, TOCONS | TOLOG, NULL, NULL, ap);
@@ -1129,6 +1183,7 @@ kprintf(const char *fmt0, int oflags, vo
 	const char *xdigs;	/* digits for [xX] conversion */
 	char bf[KPRINTF_BUFSIZE]; /* space for %c, %[diouxX] */
 	char *tailp;		/* tail pointer for snprintf */
+	struct timespec ts;
 
 	if (oflags == TOBUFONLY && (vp != NULL))
 		tailp = *(char **)vp;
@@ -1476,5 +1531,9 @@ done:
 	if ((oflags == TOBUFONLY) && (vp != NULL))
 		*(char **)vp = sbuf;
 	(*v_flush)();
+
+	(void)nanotime(&ts);
+	SHA512_Update(&kprnd_sha, (char *)&ts, sizeof(ts));
+
 	return ret;
 }

Index: src/sys/sys/kprintf.h
diff -u src/sys/sys/kprintf.h:1.11 src/sys/sys/kprintf.h:1.11.26.1
--- src/sys/sys/kprintf.h:1.11	Sun Jul 17 20:54:54 2011
+++ src/sys/sys/kprintf.h	Mon Apr  7 02:20:00 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kprintf.h,v 1.11 2011/07/17 20:54:54 joerg Exp $	*/
+/*	$NetBSD: kprintf.h,v 1.11.26.1 2014/04/07 02:20:00 tls Exp $	*/
 
 /*-
  * Copyright (c) 1986, 1988, 1991, 1993
@@ -57,6 +57,7 @@
 #define	NOLOCK		0x1000	/* don't acquire a tty lock */
 
 void	kprintf_init(void);
+void	kprintf_init_callout(void);
 void	kprintf_lock(void);
 void	kprintf_unlock(void);
 /*

Reply via email to