Module Name:    src
Committed By:   tls
Date:           Wed Nov 23 10:47:50 UTC 2011

Modified Files:
        src/distrib/sets/lists/etc: mi
        src/etc/defaults: rc.conf
        src/etc/rc.d: Makefile
        src/sbin/rndctl: rndctl.8 rndctl.c
        src/sys/dev: rnd.c
        src/sys/secmodel/securelevel: secmodel_securelevel.c
        src/sys/secmodel/suser: secmodel_suser.c
        src/sys/sys: kauth.h rnd.h
Added Files:
        src/etc/rc.d: random_seed

Log Message:
Load entropy at system boot (only works at securelevel < 1); save
at system shutdown.  Disable with random_seed=NO in rc.conf if desired.

Goes to some trouble to never load or save to network filesystems.

Entropy should really be loaded by the boot loader but I am still
sorting out how to pass it to the kernel.


To generate a diff of this commit:
cvs rdiff -u -r1.225 -r1.226 src/distrib/sets/lists/etc/mi
cvs rdiff -u -r1.116 -r1.117 src/etc/defaults/rc.conf
cvs rdiff -u -r1.85 -r1.86 src/etc/rc.d/Makefile
cvs rdiff -u -r0 -r1.1 src/etc/rc.d/random_seed
cvs rdiff -u -r1.18 -r1.19 src/sbin/rndctl/rndctl.8
cvs rdiff -u -r1.20 -r1.21 src/sbin/rndctl/rndctl.c
cvs rdiff -u -r1.85 -r1.86 src/sys/dev/rnd.c
cvs rdiff -u -r1.20 -r1.21 \
    src/sys/secmodel/securelevel/secmodel_securelevel.c
cvs rdiff -u -r1.34 -r1.35 src/sys/secmodel/suser/secmodel_suser.c
cvs rdiff -u -r1.64 -r1.65 src/sys/sys/kauth.h
cvs rdiff -u -r1.22 -r1.23 src/sys/sys/rnd.h

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

Modified files:

Index: src/distrib/sets/lists/etc/mi
diff -u src/distrib/sets/lists/etc/mi:1.225 src/distrib/sets/lists/etc/mi:1.226
--- src/distrib/sets/lists/etc/mi:1.225	Tue Sep  6 21:32:30 2011
+++ src/distrib/sets/lists/etc/mi	Wed Nov 23 10:47:49 2011
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.225 2011/09/06 21:32:30 riz Exp $
+# $NetBSD: mi,v 1.226 2011/11/23 10:47:49 tls Exp $
 #
 # Note: end-user configuration files that are moved to another location
 #	should not be marked "obsolete"; they should just be removed from
@@ -254,6 +254,7 @@
 ./etc/rc.d/racoon				etc-net-rc
 ./etc/rc.d/raidframe				etc-sys-rc
 ./etc/rc.d/raidframeparity			etc-sys-rc
+./etc/rc.d/random_seed				etc-sys-rc
 ./etc/rc.d/rarpd				etc-bootserver-rc
 ./etc/rc.d/rbootd				etc-bootserver-rc
 ./etc/rc.d/rndctl				etc-sys-rc

Index: src/etc/defaults/rc.conf
diff -u src/etc/defaults/rc.conf:1.116 src/etc/defaults/rc.conf:1.117
--- src/etc/defaults/rc.conf:1.116	Mon Nov 21 20:56:21 2011
+++ src/etc/defaults/rc.conf	Wed Nov 23 10:47:48 2011
@@ -1,4 +1,4 @@
-#	$NetBSD: rc.conf,v 1.116 2011/11/21 20:56:21 darcy Exp $
+#	$NetBSD: rc.conf,v 1.117 2011/11/23 10:47:48 tls Exp $
 #
 # /etc/defaults/rc.conf --
 #	default configuration of /etc/rc.conf
@@ -362,3 +362,6 @@ veriexec_strict=0
 veriexec_verbose=0
 veriexec_flags="-k"
 
+# Entropy load/save to/from /dev/random at startup/shutdown
+#
+random_seed=YES

Index: src/etc/rc.d/Makefile
diff -u src/etc/rc.d/Makefile:1.85 src/etc/rc.d/Makefile:1.86
--- src/etc/rc.d/Makefile:1.85	Tue Sep  6 21:32:29 2011
+++ src/etc/rc.d/Makefile	Wed Nov 23 10:47:48 2011
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.85 2011/09/06 21:32:29 riz Exp $
+# $NetBSD: Makefile,v 1.86 2011/11/23 10:47:48 tls Exp $
 
 .include <bsd.own.mk>
 
@@ -31,8 +31,9 @@ CONFIGFILES=\
 		named ndbootd network newsyslog nfsd nfslocking npf ntpd ntpdate \
 		perusertmp pf pf_boot pflogd postfix powerd ppp pwcheck \
 		quota \
-		racoon rpcbind raidframe raidframeparity rarpd rbootd rndctl \
-		root route6d routed rtadvd rtclocaltime rtsold rwho \
+		racoon rpcbind raidframe raidframeparity random_seed rarpd \
+		rbootd rndctl root route6d routed rtadvd rtclocaltime \
+		rtsold rwho \
 		savecore screenblank securelevel sshd \
 		staticroute swap1 swap2 sysctl sysdb syslogd \
 		timed tpctl ttys \

Index: src/sbin/rndctl/rndctl.8
diff -u src/sbin/rndctl/rndctl.8:1.18 src/sbin/rndctl/rndctl.8:1.19
--- src/sbin/rndctl/rndctl.8:1.18	Sat Oct  1 02:55:00 2011
+++ src/sbin/rndctl/rndctl.8	Wed Nov 23 10:47:49 2011
@@ -1,4 +1,4 @@
-.\"	$NetBSD: rndctl.8,v 1.18 2011/10/01 02:55:00 pgoyette Exp $
+.\"	$NetBSD: rndctl.8,v 1.19 2011/11/23 10:47:49 tls Exp $
 .\"
 .\" Copyright (c) 1997 Michael Graff
 .\" All rights reserved.
@@ -39,6 +39,10 @@
 .Nm
 .Fl ls
 .Op Fl d Ar devname | Fl t Ar devtype
+.Nm
+.Fl L Ar save-file
+.Nm
+.Fl S Ar save-file
 .Sh DESCRIPTION
 The
 .Nm
@@ -104,6 +108,17 @@ Terminal, mouse, or other user input dev
 .It Ic rng
 Random number generators.
 .El
+.It Fl L
+Load saved entropy from file
+.Ar save-file ,
+which will be overwritten and deleted before the entropy is loaded into
+the kernel.
+.It Fl S
+Save entropy pool to file
+.Ar save-file .
+The file format is specific to
+.Nm
+and includes an estimate of the amount of saved entropy and a checksum.
 .El
 .Sh FILES
 .Bl -tag -width /dev/urandomx -compact

Index: src/sbin/rndctl/rndctl.c
diff -u src/sbin/rndctl/rndctl.c:1.20 src/sbin/rndctl/rndctl.c:1.21
--- src/sbin/rndctl/rndctl.c:1.20	Sat Aug 27 18:48:59 2011
+++ src/sbin/rndctl/rndctl.c	Wed Nov 23 10:47:49 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: rndctl.c,v 1.20 2011/08/27 18:48:59 joerg Exp $	*/
+/*	$NetBSD: rndctl.c,v 1.21 2011/11/23 10:47:49 tls Exp $	*/
 
 /*-
  * Copyright (c) 1997 Michael Graff.
@@ -29,14 +29,17 @@
  * SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sha1.h>
 
 #ifndef lint
-__RCSID("$NetBSD: rndctl.c,v 1.20 2011/08/27 18:48:59 joerg Exp $");
+__RCSID("$NetBSD: rndctl.c,v 1.21 2011/11/23 10:47:49 tls Exp $");
 #endif
 
 
 #include <sys/types.h>
 #include <sys/ioctl.h>
+#include <sys/param.h>
 #include <sys/rnd.h>
 
 #include <stdio.h>
@@ -48,6 +51,12 @@ __RCSID("$NetBSD: rndctl.c,v 1.20 2011/0
 #include <string.h>
 
 typedef struct {
+	uint32_t entropy;
+	uint8_t data[RND_POOLWORDS * sizeof(uint32_t)];
+	uint8_t digest[SHA1_DIGEST_LENGTH];
+} rndsave_t;
+
+typedef struct {
 	const char *a_name;
 	u_int32_t a_type;
 } arg_t;
@@ -78,6 +87,7 @@ usage(void)
 	    getprogname());
 	fprintf(stderr, "       %s -ls [-d devname | -t devtype]\n",
 	    getprogname());
+	fprintf(stderr, "	%s -[L|S] save-file\n", getprogname());
 	exit(1);
 }
 
@@ -116,6 +126,114 @@ find_name(u_int32_t type)
 }
 
 static void
+do_save(const char *const filename)
+{
+	int est1, est2;
+	rndpoolstat_t rp;
+	rndsave_t rs;
+	SHA1_CTX s;
+
+	int fd;
+
+	fd = open("/dev/urandom", O_RDONLY, 0644);
+	if (fd < 0) {
+		err(1, "device open");
+	}
+	
+	if (ioctl(fd, RNDGETPOOLSTAT, &rp) < 0) {
+		err(1, "ioctl(RNDGETPOOLSTAT)");
+	}
+
+	est1 = rp.curentropy;
+
+	if (read(fd, rs.data, sizeof(rs.data)) != sizeof(rs.data)) {
+		err(1, "entropy read");
+	}
+
+	if (ioctl(fd, RNDGETPOOLSTAT, &rp) < 0) {
+		err(1, "ioctl(RNDGETPOOLSTAT)");
+	}
+
+	est2 = rp.curentropy;
+
+	if (est1 - est2 < 0) {
+		rs.entropy = 0;
+	} else {
+		rs.entropy = est1 - est2;
+	}
+
+	SHA1Init(&s);
+	SHA1Update(&s, (uint8_t *)&rs.entropy, sizeof(rs.entropy));
+	SHA1Update(&s, rs.data, sizeof(rs.data));
+	SHA1Final(rs.digest, &s);
+
+	close(fd);
+	unlink(filename);
+	fd = open(filename, O_CREAT|O_EXCL|O_WRONLY, 0600);
+	if (fd < 0) {
+		err(1, "output open");
+	}
+	
+	if (write(fd, &rs, sizeof(rs)) != sizeof(rs)) {
+		unlink(filename);
+		fsync_range(fd, FDATASYNC|FDISKSYNC, (off_t)0, (off_t)0);
+		err(1, "write");
+	}
+	fsync_range(fd, FDATASYNC|FDISKSYNC, (off_t)0, (off_t)0);
+	close(fd);
+}
+
+static void
+do_load(const char *const filename)
+{
+	int fd;
+	rndsave_t rs;
+	rnddata_t rd;
+	SHA1_CTX s;
+	uint8_t digest[SHA1_DIGEST_LENGTH];
+
+	fd = open(filename, O_RDWR, 0600);
+	if (fd < 0) {
+		err(1, "input open");
+	}
+
+	unlink(filename);
+
+	if (read(fd, &rs, sizeof(rs)) != sizeof(rs)) {
+		err(1, "read");
+	}
+
+	if (write(fd, &rs, sizeof(rs) != sizeof(rs))) {
+		err(1, "overwrite");
+	}
+	fsync_range(fd, FDATASYNC|FDISKSYNC, (off_t)0, (off_t)0);
+	close(fd);
+
+	SHA1Init(&s);
+	SHA1Update(&s, (uint8_t *)&rs.entropy, sizeof(rs.entropy));
+	SHA1Update(&s, rs.data, sizeof(rs.data));
+	SHA1Final(digest, &s);
+
+	if (memcmp(digest, rs.digest, sizeof(digest))) {
+		errx(1, "bad digest");
+	}
+
+	rd.len = MIN(sizeof(rd.data), sizeof(rs.data));
+	rd.entropy = rs.entropy;
+	memcpy(rd.data, rs.data, MIN(sizeof(rd.data), sizeof(rs.data)));
+
+	fd = open("/dev/urandom", O_RDWR, 0644);
+	if (fd < 0) {
+		err(1, "device open");
+	}
+
+	if (ioctl(fd, RNDADDDATA, &rd) < 0) {
+		err(1, "ioctl");
+	}
+	close(fd);
+}
+
+static void
 do_ioctl(rndctl_t *rctl)
 {
 	int fd;
@@ -247,6 +365,7 @@ main(int argc, char **argv)
 	int ch, cmd, lflag, mflag, sflag;
 	u_int32_t type;
 	char name[16];
+	const char *filename = NULL;
 
 	rctl.mask = 0;
 	rctl.flags = 0;
@@ -257,7 +376,7 @@ main(int argc, char **argv)
 	sflag = 0;
 	type = 0xff;
 
-	while ((ch = getopt(argc, argv, "CEcelt:d:s")) != -1) {
+	while ((ch = getopt(argc, argv, "CES:L:celt:d:s")) != -1) {
 		switch (ch) {
 		case 'C':
 			rctl.flags |= RND_FLAG_NO_COLLECT;
@@ -269,6 +388,18 @@ main(int argc, char **argv)
 			rctl.mask |= RND_FLAG_NO_ESTIMATE;
 			mflag++;
 			break;
+		case 'L':
+			if (cmd != 0)
+				usage();
+			cmd = 'L';
+			filename = optarg;
+			break;
+		case 'S':
+			if (cmd != 0)
+				usage();
+			cmd = 'S';
+			filename = optarg;
+			break;
 		case 'c':
 			rctl.flags &= ~RND_FLAG_NO_COLLECT;
 			rctl.mask |= RND_FLAG_NO_COLLECT;
@@ -315,6 +446,22 @@ main(int argc, char **argv)
 		usage();
 
 	/*
+	 * Save.
+	 */
+	if (cmd == 'S') {
+		do_save(filename);
+		exit(0);
+	}
+
+	/*
+	 * Load.
+	 */
+	if (cmd == 'L') {
+		do_load(filename);
+		exit(0);
+	}
+
+	/*
 	 * Cannot list and modify at the same time.
 	 */
 	if ((lflag != 0 || sflag != 0) && mflag != 0)

Index: src/sys/dev/rnd.c
diff -u src/sys/dev/rnd.c:1.85 src/sys/dev/rnd.c:1.86
--- src/sys/dev/rnd.c:1.85	Sun Nov 20 00:45:15 2011
+++ src/sys/dev/rnd.c	Wed Nov 23 10:47:48 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: rnd.c,v 1.85 2011/11/20 00:45:15 tls Exp $	*/
+/*	$NetBSD: rnd.c,v 1.86 2011/11/23 10:47:48 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.85 2011/11/20 00:45:15 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.86 2011/11/23 10:47:48 tls Exp $");
 
 #include <sys/param.h>
 #include <sys/ioctl.h>
@@ -509,7 +509,15 @@ int
 rndwrite(dev_t dev, struct uio *uio, int ioflag)
 {
 	u_int8_t *bf;
-	int n, ret;
+	int n, ret = 0, estimate_ok = 0, estimate = 0, added = 0;
+
+	ret = kauth_authorize_device(curlwp->l_cred,
+	    KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL);
+	if (ret) {
+		return (ret);
+	}
+	estimate_ok = !kauth_authorize_device(curlwp->l_cred,
+	    KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL);
 
 	DPRINTF(RND_DEBUG_WRITE,
 	    ("Random: Write of %zu requested\n", uio->uio_resid));
@@ -519,19 +527,43 @@ rndwrite(dev_t dev, struct uio *uio, int
 	ret = 0;
 	bf = kmem_alloc(RND_TEMP_BUFFER_SIZE, KM_SLEEP);
 	while (uio->uio_resid > 0) {
+		/*
+		 * Don't flood the pool.
+		 */
+		if (added > RND_POOLWORDS * sizeof(int)) {
+			printf("rnd: added %d already, adding no more.\n",
+			       added);
+			break;
+		}
 		n = min(RND_TEMP_BUFFER_SIZE, uio->uio_resid);
 
 		ret = uiomove((void *)bf, n, uio);
 		if (ret != 0)
 			break;
 
+		if (estimate_ok) {
+			/*
+			 * Don't cause samples to be discarded by taking
+			 * the pool's entropy estimate to the max.
+			 */
+			if (added > RND_POOLWORDS / 2)
+				estimate = 0;
+			else
+				estimate = n * NBBY / 2;
+			printf("rnd: adding on write, %d bytes, estimate %d\n",
+			       n, estimate);
+		} else {
+			printf("rnd: kauth says no entropy.\n");
+		}
+
 		/*
 		 * Mix in the bytes.
 		 */
 		mutex_spin_enter(&rndpool_mtx);
-		rndpool_add_data(&rnd_pool, bf, n, 0);
+		rndpool_add_data(&rnd_pool, bf, n, estimate);
 		mutex_spin_exit(&rndpool_mtx);
 
+		added += n;
 		DPRINTF(RND_DEBUG_WRITE, ("Random: Copied in %d bytes\n", n));
 	}
 	kmem_free(bf, RND_TEMP_BUFFER_SIZE);
@@ -558,9 +590,8 @@ rndioctl(dev_t dev, u_long cmd, void *ad
 	rndctl_t *rctl;
 	rnddata_t *rnddata;
 	u_int32_t count, start;
-	int ret;
-
-	ret = 0;
+	int ret = 0;
+	int estimate_ok = 0, estimate = 0;
 
 	switch (cmd) {
 	case FIONBIO:
@@ -589,6 +620,8 @@ rndioctl(dev_t dev, u_long cmd, void *ad
 		    KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL);
 		if (ret)
 			return (ret);
+		estimate_ok = !kauth_authorize_device(l->l_cred,
+		    KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL);
 		break;
 
 	default:
@@ -720,9 +753,23 @@ rndioctl(dev_t dev, u_long cmd, void *ad
 		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;
+		}
+
 		mutex_spin_enter(&rndpool_mtx);
 		rndpool_add_data(&rnd_pool, rnddata->data, rnddata->len,
-		    rnddata->entropy);
+				 estimate);
 		mutex_spin_exit(&rndpool_mtx);
 
 		rnd_wakeup_readers();

Index: src/sys/secmodel/securelevel/secmodel_securelevel.c
diff -u src/sys/secmodel/securelevel/secmodel_securelevel.c:1.20 src/sys/secmodel/securelevel/secmodel_securelevel.c:1.21
--- src/sys/secmodel/securelevel/secmodel_securelevel.c:1.20	Wed Oct  7 01:06:57 2009
+++ src/sys/secmodel/securelevel/secmodel_securelevel.c	Wed Nov 23 10:47:48 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: secmodel_securelevel.c,v 1.20 2009/10/07 01:06:57 elad Exp $ */
+/* $NetBSD: secmodel_securelevel.c,v 1.21 2011/11/23 10:47:48 tls Exp $ */
 /*-
  * Copyright (c) 2006 Elad Efrat <[email protected]>
  * All rights reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.20 2009/10/07 01:06:57 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: secmodel_securelevel.c,v 1.21 2011/11/23 10:47:48 tls Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_insecure.h"
@@ -553,6 +553,11 @@ secmodel_securelevel_device_cb(kauth_cre
 			result = KAUTH_RESULT_DENY;
 		break;
 
+	case KAUTH_DEVICE_RND_ADDDATA_ESTIMATE:
+		if (securelevel > 0)
+			result = KAUTH_RESULT_DENY;
+		break;
+
 	default:
 		break;
 	}

Index: src/sys/secmodel/suser/secmodel_suser.c
diff -u src/sys/secmodel/suser/secmodel_suser.c:1.34 src/sys/secmodel/suser/secmodel_suser.c:1.35
--- src/sys/secmodel/suser/secmodel_suser.c:1.34	Tue Dec 29 04:25:30 2009
+++ src/sys/secmodel/suser/secmodel_suser.c	Wed Nov 23 10:47:49 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: secmodel_suser.c,v 1.34 2009/12/29 04:25:30 elad Exp $ */
+/* $NetBSD: secmodel_suser.c,v 1.35 2011/11/23 10:47:49 tls Exp $ */
 /*-
  * Copyright (c) 2006 Elad Efrat <[email protected]>
  * All rights reserved.
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.34 2009/12/29 04:25:30 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.35 2011/11/23 10:47:49 tls Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -838,6 +838,7 @@ secmodel_suser_device_cb(kauth_cred_t cr
 	case KAUTH_DEVICE_TTY_PRIVSET:
 	case KAUTH_DEVICE_TTY_STI:
 	case KAUTH_DEVICE_RND_ADDDATA:
+	case KAUTH_DEVICE_RND_ADDDATA_ESTIMATE:
 	case KAUTH_DEVICE_RND_GETPRIV:
 	case KAUTH_DEVICE_RND_SETPRIV:
 		if (isroot)

Index: src/sys/sys/kauth.h
diff -u src/sys/sys/kauth.h:1.64 src/sys/sys/kauth.h:1.65
--- src/sys/sys/kauth.h:1.64	Thu Dec 24 19:02:07 2009
+++ src/sys/sys/kauth.h	Wed Nov 23 10:47:49 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: kauth.h,v 1.64 2009/12/24 19:02:07 elad Exp $ */
+/* $NetBSD: kauth.h,v 1.65 2011/11/23 10:47:49 tls Exp $ */
 
 /*-
  * Copyright (c) 2005, 2006 Elad Efrat <[email protected]>  
@@ -255,6 +255,7 @@ enum {
 	KAUTH_DEVICE_RAWIO_PASSTHRU,
 	KAUTH_DEVICE_BLUETOOTH_SETPRIV,
 	KAUTH_DEVICE_RND_ADDDATA,
+	KAUTH_DEVICE_RND_ADDDATA_ESTIMATE,
 	KAUTH_DEVICE_RND_GETPRIV,
 	KAUTH_DEVICE_RND_SETPRIV,
 	KAUTH_DEVICE_BLUETOOTH_BCSP,

Index: src/sys/sys/rnd.h
diff -u src/sys/sys/rnd.h:1.22 src/sys/sys/rnd.h:1.23
--- src/sys/sys/rnd.h:1.22	Sat Nov 19 22:51:31 2011
+++ src/sys/sys/rnd.h	Wed Nov 23 10:47:49 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: rnd.h,v 1.22 2011/11/19 22:51:31 tls Exp $	*/
+/*	$NetBSD: rnd.h,v 1.23 2011/11/23 10:47:49 tls Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -209,7 +209,7 @@ typedef struct {
 typedef struct {
 	uint32_t	len;
 	uint32_t	entropy;
-	u_char		data[RND_POOLWORDS * 4];
+	u_char		data[RND_POOLWORDS * sizeof(uint32_t)];
 } rnddata_t;
 
 #define	RNDGETENTCNT	_IOR('R',  101, uint32_t) /* get entropy count */

Added files:

Index: src/etc/rc.d/random_seed
diff -u /dev/null src/etc/rc.d/random_seed:1.1
--- /dev/null	Wed Nov 23 10:47:50 2011
+++ src/etc/rc.d/random_seed	Wed Nov 23 10:47:48 2011
@@ -0,0 +1,91 @@
+#!/bin/sh
+#
+# $NetBSD: random_seed,v 1.1 2011/11/23 10:47:48 tls Exp $
+#
+
+# PROVIDE: random_seed
+# REQUIRE: mountcritlocal
+# BEFORE: securelevel
+# KEYWORD: shutdown
+
+$_rc_subr_loaded . /etc/rc.subr
+
+name="random_seed"
+rcvar=$name
+start_cmd="random_load"
+stop_cmd="random_save"
+
+random_file=${random_file:-/var/db/entropy-file}
+
+fs_safe()
+{
+	#
+	# Enforce that the file's on a local filesystem.
+	# Include only the types we can actually write.
+	#
+	fstype=$(df -G $1 | awk '$2 == "fstype" {print $1}')
+	case $fstype in
+	    ffs)
+		return 0
+		;;
+	    lfs)
+		return 0
+		;;
+	    ext2fs)
+		return 0;
+		;;
+	    msdosfs)
+		return 0;
+		;;
+	    v7fs)
+		return 0;
+		;;
+	 esac
+	 return 1
+}
+
+random_load()
+{
+	if [ -f $random_file ]; then
+
+		if ! fs_safe $(dirname ${random_file}); then
+			return 1
+		fi
+
+		eval $(stat -s ${random_file})
+
+		# The file must be owned by root,
+		if [ "$st_uid" != "0" ]; then
+			return 1
+		fi
+		# and root read/write only.
+		if [ "$(echo $st_mode | tail -c4)" != "600" ]; then
+			return 1
+		fi
+
+		if rndctl -L ${random_file}; then
+			echo "Loaded entropy from disk."
+		fi
+		
+	fi
+}
+
+random_save()
+{
+	oum=$(umask)
+	umask 077
+
+	rm -Pf ${random_file}
+
+	if ! fs_safe $(dirname ${random_file}); then
+		return 1
+	fi
+
+	if rndctl -S ${random_file}; then
+		echo "Saved entropy to disk."
+	fi
+}
+
+
+load_rc_config $name
+run_rc_command "$1"

Reply via email to