Source-Changes-HG archive

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

[src/trunk]: src Add support for passing saved entropy (random seed file) to ...



details:   https://anonhg.NetBSD.org/src/rev/92234ff5713b
branches:  trunk
changeset: 771675:92234ff5713b
user:      tls <tls%NetBSD.org@localhost>
date:      Mon Nov 28 07:56:53 2011 +0000

description:
Add support for passing saved entropy (random seed file) to the kernel
from the bootloader.  This can fix the problem of poor quality keys
for other kernel modules which call arc4random() early in kernel startup
(NFS startup, in particular, causes this).

We continue to rely on the etc/rc.d/random_seed script to save entropy
to the seed file at shutdown and erase the seed file at startup.

Boot loader support implemented only for i386 and amd64 ports for now but
it should be easy for other ports to do the same or similar.

diffstat:

 share/man/man5/boot.cfg.5         |   11 +++-
 sys/arch/i386/stand/boot/boot2.c  |    4 +-
 sys/arch/i386/stand/lib/bootmod.h |    3 +-
 sys/arch/i386/stand/lib/exec.c    |   23 ++++++-
 sys/arch/i386/stand/lib/libi386.h |    3 +-
 sys/arch/x86/include/bootinfo.h   |    3 +-
 sys/arch/x86/x86/x86_machdep.c    |   13 +++-
 sys/dev/rnd.c                     |  121 ++++++++++++++++++++++++++++++-------
 8 files changed, 146 insertions(+), 35 deletions(-)

diffs (truncated from 349 to 300 lines):

diff -r cea6e31699b7 -r 92234ff5713b share/man/man5/boot.cfg.5
--- a/share/man/man5/boot.cfg.5 Mon Nov 28 06:36:14 2011 +0000
+++ b/share/man/man5/boot.cfg.5 Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: boot.cfg.5,v 1.22 2011/05/26 04:25:26 uebayasi Exp $
+.\"    $NetBSD: boot.cfg.5,v 1.23 2011/11/28 07:56:53 tls Exp $
 .\"
 .\" Copyright (c) 2007 Stephen Borrill
 .\" All rights reserved.
@@ -147,6 +147,15 @@
 Passes a
 .Xr userconf 4
 command to the kernel at boot time .
+.It Sy rndseed
+Takes the path to a random-seed file as written by the -S flag to
+.Xr rndctl 8
+as an argument.  This file is used to seed the
+kernel entropy pool
+.Xr rnd 9
+very early in kernel startup, so that high quality randomness is
+available to all kernel modules.  This argument should be supplied
+before any "load" commands that may load executable modules.
 .El
 .Sh EXAMPLES
 Here is an example
diff -r cea6e31699b7 -r 92234ff5713b sys/arch/i386/stand/boot/boot2.c
--- a/sys/arch/i386/stand/boot/boot2.c  Mon Nov 28 06:36:14 2011 +0000
+++ b/sys/arch/i386/stand/boot/boot2.c  Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: boot2.c,v 1.55 2011/06/23 12:07:00 mrg Exp $   */
+/*     $NetBSD: boot2.c,v 1.56 2011/11/28 07:56:54 tls Exp $   */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -136,6 +136,7 @@
        { "multiboot",  command_multiboot },
        { "vesa",       command_vesa },
        { "splash",     splash_add },
+       { "rndseed",    rnd_add },
        { "userconf",   userconf_add },
        { NULL,         NULL },
 };
@@ -397,6 +398,7 @@
               "load {path_to_module}\n"
               "multiboot [xdNx:][filename] [<args>]\n"
               "userconf {command}\n"
+              "rndseed {path_to_rndseed_file}\n"
               "help|?\n"
               "quit\n");
 }
diff -r cea6e31699b7 -r 92234ff5713b sys/arch/i386/stand/lib/bootmod.h
--- a/sys/arch/i386/stand/lib/bootmod.h Mon Nov 28 06:36:14 2011 +0000
+++ b/sys/arch/i386/stand/lib/bootmod.h Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bootmod.h,v 1.4 2011/02/06 23:16:05 jmcneill Exp $     */
+/*     $NetBSD: bootmod.h,v 1.5 2011/11/28 07:56:54 tls Exp $  */
 
 /*-
  * Copyright (c) 2008 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -35,6 +35,7 @@
        uint8_t                 bm_type;
 #define        BM_TYPE_KMOD            0x00
 #define        BM_TYPE_IMAGE           0x01
+#define BM_TYPE_RND            0x02
        struct boot_module      *bm_next;
 } boot_module_t;
 
diff -r cea6e31699b7 -r 92234ff5713b sys/arch/i386/stand/lib/exec.c
--- a/sys/arch/i386/stand/lib/exec.c    Mon Nov 28 06:36:14 2011 +0000
+++ b/sys/arch/i386/stand/lib/exec.c    Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec.c,v 1.48 2011/07/17 20:54:41 joerg Exp $   */
+/*     $NetBSD: exec.c,v 1.49 2011/11/28 07:56:54 tls Exp $     */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -171,6 +171,12 @@
        return module_add_common(name, BM_TYPE_IMAGE);
 }
 
+void
+rnd_add(char *name)
+{
+       return module_add_common(name, BM_TYPE_RND);
+}
+
 static void
 module_add_common(char *name, uint8_t type)
 {
@@ -579,8 +585,19 @@
                        strncpy(bi->path, bm->bm_path, sizeof(bi->path) - 1);
                        bi->base = image_end;
                        bi->len = len;
-                       bi->type = bm->bm_type == BM_TYPE_KMOD ?
-                           BI_MODULE_ELF : BI_MODULE_IMAGE;
+                       switch (bm->bm_type) {
+                           case BM_TYPE_KMOD:
+                               bi->type = BI_MODULE_ELF;
+                               break;
+                           case BM_TYPE_IMAGE:
+                               bi->type = BI_MODULE_IMAGE;
+                               break;
+                           case BM_TYPE_RND:
+                           default:
+                               /* safest -- rnd checks the sha1 */
+                               bi->type = BI_MODULE_RND;
+                               break;
+                       }
                        if ((howto & AB_SILENT) == 0)
                                printf(" \n");
                }
diff -r cea6e31699b7 -r 92234ff5713b sys/arch/i386/stand/lib/libi386.h
--- a/sys/arch/i386/stand/lib/libi386.h Mon Nov 28 06:36:14 2011 +0000
+++ b/sys/arch/i386/stand/lib/libi386.h Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: libi386.h,v 1.37 2011/06/16 13:27:59 joerg Exp $       */
+/*     $NetBSD: libi386.h,v 1.38 2011/11/28 07:56:54 tls Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -138,6 +138,7 @@
 
 void module_add(char *);
 void splash_add(char *);
+void rnd_add(char *);
 void userconf_add(char *);
 
 struct btinfo_framebuffer;
diff -r cea6e31699b7 -r 92234ff5713b sys/arch/x86/include/bootinfo.h
--- a/sys/arch/x86/include/bootinfo.h   Mon Nov 28 06:36:14 2011 +0000
+++ b/sys/arch/x86/include/bootinfo.h   Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bootinfo.h,v 1.18 2011/05/26 04:25:28 uebayasi Exp $   */
+/*     $NetBSD: bootinfo.h,v 1.19 2011/11/28 07:56:54 tls Exp $        */
 
 /*
  * Copyright (c) 1997
@@ -175,6 +175,7 @@
 #define        BI_MODULE_NONE          0x00
 #define        BI_MODULE_ELF           0x01
 #define        BI_MODULE_IMAGE         0x02
+#define BI_MODULE_RND          0x03
 
 struct btinfo_modulelist {
        struct btinfo_common common;
diff -r cea6e31699b7 -r 92234ff5713b sys/arch/x86/x86/x86_machdep.c
--- a/sys/arch/x86/x86/x86_machdep.c    Mon Nov 28 06:36:14 2011 +0000
+++ b/sys/arch/x86/x86/x86_machdep.c    Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: x86_machdep.c,v 1.56 2011/08/13 21:04:05 christos Exp $        */
+/*     $NetBSD: x86_machdep.c,v 1.57 2011/11/28 07:56:54 tls Exp $     */
 
 /*-
  * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.56 2011/08/13 21:04:05 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.57 2011/11/28 07:56:54 tls Exp $");
 
 #include "opt_modular.h"
 #include "opt_physmem.h"
@@ -50,6 +50,7 @@
 #include <sys/module.h>
 #include <sys/sysctl.h>
 #include <sys/extent.h>
+#include <sys/rnd.h>
 
 #include <x86/cpuvar.h>
 #include <x86/cputypes.h>
@@ -173,6 +174,14 @@
                            (void *)((uintptr_t)bi->base + KERNBASE), bi->len);
 #endif
                        break;
+               case BI_MODULE_RND:
+                       aprint_debug("Random seed data path=%s len=%d pa=%x\n",
+                                    bi->path, bi->len, bi->base);
+                       KASSERT(trunc_page(bi->base) == bi->base);
+                       rnd_seed(
+                           (void *)((uintptr_t)bi->base + KERNBASE),
+                            bi->len);
+                       break;
                default:
                        aprint_debug("Skipping non-ELF module\n");
                        break;
diff -r cea6e31699b7 -r 92234ff5713b sys/dev/rnd.c
--- a/sys/dev/rnd.c     Mon Nov 28 06:36:14 2011 +0000
+++ b/sys/dev/rnd.c     Mon Nov 28 07:56:53 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rnd.c,v 1.86 2011/11/23 10:47:48 tls Exp $     */
+/*     $NetBSD: rnd.c,v 1.87 2011/11/28 07:56:54 tls Exp $     */
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.86 2011/11/23 10:47:48 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.87 2011/11/28 07:56:54 tls Exp $");
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -184,6 +184,7 @@
 
 LIST_HEAD(, krndsource)        rnd_sources;
 
+static rndsave_t       *boot_rsp;
 /*
  * Generate a 32-bit counter.  This should be more machine dependent,
  * using cycle counters and the like when possible.
@@ -406,6 +407,23 @@
        printf("rnd: initialised (%u)%s", RND_POOLBITS,
               c ? " with counter\n" : "\n");
 #endif
+       if (boot_rsp != NULL) {
+               mutex_spin_enter(&rndpool_mtx);
+                       rndpool_add_data(&rnd_pool, boot_rsp->data,
+                                        sizeof(boot_rsp->data),
+                                        MIN(boot_rsp->entropy,
+                                            RND_POOLBITS / 2));
+               if (rndpool_get_entropy_count(&rnd_pool) >
+                   RND_ENTROPY_THRESHOLD * 8) {
+                       rnd_have_entropy = 1;
+               }
+                mutex_spin_exit(&rndpool_mtx);
+#ifdef RND_VERBOSE
+               printf("rnd: seeded with %d bits\n",
+                      MIN(boot_rsp->entropy, RND_POOLBITS / 2));
+#endif
+               memset(boot_rsp, 0, sizeof(*boot_rsp));
+       }
 }
 
 int
@@ -748,32 +766,41 @@
                break;
 
        case RNDADDDATA:
-               rnddata = (rnddata_t *)addr;
+               /*
+                * Don't seed twice if our bootloader has
+                * seed loading support.
+                */
+               if (!boot_rsp) {
+                       rnddata = (rnddata_t *)addr;
 
-               if (rnddata->len > sizeof(rnddata->data))
-                       return EINVAL;
+                       if (rnddata->len > sizeof(rnddata->data))
+                               return EINVAL;
 
-               if (estimate_ok) {
-                       /*
-                        * Do not accept absurd entropy estimates, and
-                        * do not flood the pool with entropy such that
-                        * new samples are discarded henceforth.
-                        */
-                       estimate = MIN((rnddata->len * NBBY) / 2,
-                                      MIN(rnddata->entropy,
-                                          RND_POOLWORDS * sizeof(int) *
-                                          NBBY / 2));
-               } else {
-                       estimate = 0;
+                       if (estimate_ok) {
+                               /*
+                                * Do not accept absurd entropy estimates, and
+                                * do not flood the pool with entropy such that
+                                * new samples are discarded henceforth.
+                                */
+                               estimate = MIN((rnddata->len * NBBY) / 2,
+                                              MIN(rnddata->entropy,
+                                                  RND_POOLBITS / 2));
+                       } else {
+                               estimate = 0;
+                       }
+
+                       mutex_spin_enter(&rndpool_mtx);
+                       rndpool_add_data(&rnd_pool, rnddata->data,
+                                        rnddata->len, estimate);
+                       mutex_spin_exit(&rndpool_mtx);
+
+                       rnd_wakeup_readers();
                }
-
-               mutex_spin_enter(&rndpool_mtx);
-               rndpool_add_data(&rnd_pool, rnddata->data, rnddata->len,
-                                estimate);
-               mutex_spin_exit(&rndpool_mtx);
-
-               rnd_wakeup_readers();
-
+#ifdef RND_VERBOSE
+               else {
+                       printf("rnd: already seeded by boot loader\n");
+               }
+#endif
                break;
 



Home | Main Index | Thread Index | Old Index