Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/tls-earlyentropy]: src/sys Get more entropy into the system early:



details:   https://anonhg.NetBSD.org/src/rev/3dd895d768e3
branches:  tls-earlyentropy
changeset: 795264:3dd895d768e3
user:      tls <tls%NetBSD.org@localhost>
date:      Mon Apr 07 02:20:00 2014 +0000

description:
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.

diffstat:

 sys/kern/init_main.c     |   7 +++-
 sys/kern/kern_rndq.c     |  11 +++++-
 sys/kern/kern_sysctl.c   |  10 ++++-
 sys/kern/subr_autoconf.c |  19 ++++++++++-
 sys/kern/subr_prf.c      |  75 ++++++++++++++++++++++++++++++++++++++++++-----
 sys/sys/kprintf.h        |   3 +-
 6 files changed, 107 insertions(+), 18 deletions(-)

diffs (truncated from 377 to 300 lines):

diff -r b5d812aa0bac -r 3dd895d768e3 sys/kern/init_main.c
--- a/sys/kern/init_main.c      Mon Apr 07 02:00:00 2014 +0000
+++ b/sys/kern/init_main.c      Mon Apr 07 02:20:00 2014 +0000
@@ -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 @@
        /* 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();
diff -r b5d812aa0bac -r 3dd895d768e3 sys/kern/kern_rndq.c
--- a/sys/kern/kern_rndq.c      Mon Apr 07 02:00:00 2014 +0000
+++ b/sys/kern/kern_rndq.c      Mon Apr 07 02:20:00 2014 +0000
@@ -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 @@
        .test = NULL
 };
 
+krndsource_t rnd_printf_source, rnd_autoconf_source;
+
 void *rnd_process, *rnd_wakeup;
 struct callout skew_callout;
 
@@ -608,6 +610,11 @@
                          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;
 }
 
diff -r b5d812aa0bac -r 3dd895d768e3 sys/kern/kern_sysctl.c
--- a/sys/kern/kern_sysctl.c    Mon Apr 07 02:00:00 2014 +0000
+++ b/sys/kern/kern_sysctl.c    Mon Apr 07 02:20:00 2014 +0000
@@ -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 @@
 #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 @@
                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 @@
                /*
                 * 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);
diff -r b5d812aa0bac -r 3dd895d768e3 sys/kern/subr_autoconf.c
--- a/sys/kern/subr_autoconf.c  Mon Apr 07 02:00:00 2014 +0000
+++ b/sys/kern/subr_autoconf.c  Mon Apr 07 02:20:00 2014 +0000
@@ -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 @@
 
 #include <sys/disk.h>
 
+#include <sys/rnd.h>
+
 #include <machine/limits.h>
 
 /*
@@ -117,6 +119,11 @@
  */
 
 /*
+ * 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 @@
                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;
 }
 
diff -r b5d812aa0bac -r 3dd895d768e3 sys/kern/subr_prf.c
--- a/sys/kern/subr_prf.c       Mon Apr 07 02:00:00 2014 +0000
+++ b/sys/kern/subr_prf.c       Mon Apr 07 02:20:00 2014 +0000
@@ -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 @@
 #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 @@
 #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 @@
 
 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 @@
                                   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 @@
  * 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 @@
 {
 
        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 @@
 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 @@
        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) {



Home | Main Index | Thread Index | Old Index