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); /*