summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authortls <tls@NetBSD.org>2011-11-19 22:51:18 +0000
committertls <tls@NetBSD.org>2011-11-19 22:51:18 +0000
commit8e9334525367ba7642ed9b753a94935c07817c19 (patch)
tree1b53338e20cd060235386b574dbf34d8cf11d50f /sys
parent836ffd606791f7517a3ff458821d8013500d001c (diff)
First step of random number subsystem rework described in
<20111022023242.BA26F14A158@mail.netbsd.org>. This change includes the following: An initial cleanup and minor reorganization of the entropy pool code in sys/dev/rnd.c and sys/dev/rndpool.c. Several bugs are fixed. Some effort is made to accumulate entropy more quickly at boot time. A generic interface, "rndsink", is added, for stream generators to request that they be re-keyed with good quality entropy from the pool as soon as it is available. The arc4random()/arc4randbytes() implementation in libkern is adjusted to use the rndsink interface for rekeying, which helps address the problem of low-quality keys at boot time. An implementation of the FIPS 140-2 statistical tests for random number generator quality is provided (libkern/rngtest.c). This is based on Greg Rose's implementation from Qualcomm. A new random stream generator, nist_ctr_drbg, is provided. It is based on an implementation of the NIST SP800-90 CTR_DRBG by Henric Jungheim. This generator users AES in a modified counter mode to generate a backtracking-resistant random stream. An abstraction layer, "cprng", is provided for in-kernel consumers of randomness. The arc4random/arc4randbytes API is deprecated for in-kernel use. It is replaced by "cprng_strong". The current cprng_fast implementation wraps the existing arc4random implementation. The current cprng_strong implementation wraps the new CTR_DRBG implementation. Both interfaces are rekeyed from the entropy pool automatically at intervals justifiable from best current cryptographic practice. In some quick tests, cprng_fast() is about the same speed as the old arc4randbytes(), and cprng_strong() is about 20% faster than rnd_extract_data(). Performance is expected to improve. The AES code in src/crypto/rijndael is no longer an optional kernel component, as it is required by cprng_strong, which is not an optional kernel component. The entropy pool output is subjected to the rngtest tests at startup time; if it fails, the system will reboot. There is approximately a 3/10000 chance of a false positive from these tests. Entropy pool _input_ from hardware random numbers is subjected to the rngtest tests at attach time, as well as the FIPS continuous-output test, to detect bad or stuck hardware RNGs; if any are detected, they are detached, but the system continues to run. A problem with rndctl(8) is fixed -- datastructures with pointers in arrays are no longer passed to userspace (this was not a security problem, but rather a major issue for compat32). A new kernel will require a new rndctl. The sysctl kern.arandom() and kern.urandom() nodes are hooked up to the new generators, but the /dev/*random pseudodevices are not, yet. Manual pages for the new kernel interfaces are forthcoming.
Diffstat (limited to 'sys')
-rw-r--r--sys/altq/altq_blue.c7
-rw-r--r--sys/altq/altq_cdnr.c7
-rw-r--r--sys/altq/altq_red.c7
-rw-r--r--sys/altq/altq_rmclass.c7
-rw-r--r--sys/arch/acorn26/ioc/arckbd.c6
-rw-r--r--sys/arch/amd64/conf/INSTALL5
-rw-r--r--sys/arch/arm/at91/at91dbguvar.h4
-rw-r--r--sys/arch/arm/at91/at91usartvar.h4
-rw-r--r--sys/arch/arm/ep93xx/epcomvar.h4
-rw-r--r--sys/arch/arm/s3c2xx0/sscom_var.h4
-rw-r--r--sys/arch/arm/sa11x0/sa1111_kbc.c6
-rw-r--r--sys/arch/arm/xscale/ixp425_if_npe.c6
-rw-r--r--sys/arch/emips/ebus/ace_ebus.c8
-rw-r--r--sys/arch/emips/ebus/flash_ebus.c8
-rw-r--r--sys/arch/emips/ebus/if_le_ebus.c6
-rw-r--r--sys/arch/evbarm/dev/plcomvar.h4
-rw-r--r--sys/arch/hp300/dev/rdvar.h4
-rw-r--r--sys/arch/hp700/gsc/harmonyvar.h4
-rw-r--r--sys/arch/i386/pci/glxsb.c10
-rw-r--r--sys/arch/macppc/dev/if_gm.c6
-rw-r--r--sys/arch/mips/alchemy/dev/if_aumac.c6
-rw-r--r--sys/arch/mips/atheros/dev/aevar.h4
-rw-r--r--sys/arch/mips/sibyte/dev/sbscnvar.h4
-rw-r--r--sys/arch/next68k/dev/mb8795var.h4
-rw-r--r--sys/arch/sgimips/hpc/sqvar.h4
-rw-r--r--sys/arch/sgimips/mace/if_mec.c6
-rw-r--r--sys/arch/sun2/dev/if_ec.c6
-rw-r--r--sys/arch/x68k/dev/fd.c6
-rw-r--r--sys/arch/x86/include/via_padlock.h4
-rw-r--r--sys/arch/x86/pci/fwhrng.c6
-rw-r--r--sys/arch/x86/x86/via_padlock.c7
-rw-r--r--sys/arch/xen/include/xbdvar.h4
-rw-r--r--sys/arch/xen/xen/if_xennet_xenbus.c6
-rw-r--r--sys/arch/xen/xen/xbd_xenbus.c6
-rw-r--r--sys/conf/files11
-rw-r--r--sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg3
-rw-r--r--sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h82
-rw-r--r--sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c664
-rw-r--r--sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h106
-rw-r--r--sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h80
-rw-r--r--sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h80
-rw-r--r--sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h72
-rw-r--r--sys/crypto/rijndael/files.rijndael10
-rw-r--r--sys/dev/ata/wdvar.h4
-rw-r--r--sys/dev/gpib/rd.c6
-rw-r--r--sys/dev/ic/comvar.h4
-rw-r--r--sys/dev/ic/cs89x0var.h4
-rw-r--r--sys/dev/ic/dp8390var.h4
-rw-r--r--sys/dev/ic/elink3var.h4
-rw-r--r--sys/dev/ic/elinkxlvar.h4
-rw-r--r--sys/dev/ic/gemvar.h4
-rw-r--r--sys/dev/ic/hmevar.h4
-rw-r--r--sys/dev/ic/i82557var.h4
-rw-r--r--sys/dev/ic/lan9118var.h4
-rw-r--r--sys/dev/ic/lancevar.h4
-rw-r--r--sys/dev/ic/lemacvar.h4
-rw-r--r--sys/dev/ic/mb86950var.h4
-rw-r--r--sys/dev/ic/mb86960var.h4
-rw-r--r--sys/dev/ic/mtd803var.h4
-rw-r--r--sys/dev/ic/pckbc.c6
-rw-r--r--sys/dev/ic/rtl81x9var.h4
-rw-r--r--sys/dev/ic/seeq8005var.h4
-rw-r--r--sys/dev/ic/smc91cxxvar.h4
-rw-r--r--sys/dev/ic/tulipvar.h4
-rw-r--r--sys/dev/isa/fdvar.h4
-rw-r--r--sys/dev/isa/if_eg.c6
-rw-r--r--sys/dev/isa/if_el.c6
-rw-r--r--sys/dev/isa/if_iy.c6
-rw-r--r--sys/dev/ldvar.h4
-rw-r--r--sys/dev/marvell/if_gfevar.h4
-rw-r--r--sys/dev/marvell/if_mvgbe.c6
-rw-r--r--sys/dev/mca/edvar.h4
-rw-r--r--sys/dev/pci/amdpmvar.h4
-rw-r--r--sys/dev/pci/hifn7751.c15
-rw-r--r--sys/dev/pci/hifn7751var.h4
-rw-r--r--sys/dev/pci/if_bce.c6
-rw-r--r--sys/dev/pci/if_bgevar.h4
-rw-r--r--sys/dev/pci/if_casvar.h4
-rw-r--r--sys/dev/pci/if_devar.h4
-rw-r--r--sys/dev/pci/if_dge.c6
-rw-r--r--sys/dev/pci/if_iwi.c8
-rw-r--r--sys/dev/pci/if_jme.c6
-rw-r--r--sys/dev/pci/if_mskvar.h4
-rw-r--r--sys/dev/pci/if_pcn.c6
-rw-r--r--sys/dev/pci/if_sip.c6
-rw-r--r--sys/dev/pci/if_skvar.h4
-rw-r--r--sys/dev/pci/if_tlvar.h4
-rw-r--r--sys/dev/pci/if_vr.c6
-rw-r--r--sys/dev/pci/if_vtevar.h4
-rw-r--r--sys/dev/pci/if_wm.c6
-rw-r--r--sys/dev/pci/ixgbe/ixgbe.c4
-rw-r--r--sys/dev/pci/ubsec.c9
-rw-r--r--sys/dev/pcmcia/if_xivar.h4
-rw-r--r--sys/dev/rnd.c668
-rw-r--r--sys/dev/scsipi/cdvar.h4
-rw-r--r--sys/dev/scsipi/sdvar.h4
-rw-r--r--sys/dev/scsipi/stvar.h4
-rw-r--r--sys/dev/usb/if_auereg.h4
-rw-r--r--sys/dev/usb/if_axereg.h4
-rw-r--r--sys/dev/usb/if_cdcereg.h4
-rw-r--r--sys/dev/usb/if_cuereg.h4
-rw-r--r--sys/dev/usb/if_kuereg.h4
-rw-r--r--sys/dev/usb/if_udavreg.h4
-rw-r--r--sys/dev/usb/if_upl.c6
-rw-r--r--sys/dev/usb/if_urlreg.h4
-rw-r--r--sys/dev/usb/ucom.c6
-rw-r--r--sys/dev/usb/uhidev.h4
-rw-r--r--sys/dist/pf/net/pf.c27
-rw-r--r--sys/dist/pf/netinet/tcp_rndiss.c11
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c6
-rw-r--r--sys/kern/exec_elf.c7
-rw-r--r--sys/kern/init_main.c20
-rw-r--r--sys/kern/init_sysctl.c21
-rw-r--r--sys/kern/kern_exec.c7
-rw-r--r--sys/kern/kern_pax.c9
-rw-r--r--sys/kern/kern_ssp.c7
-rw-r--r--sys/kern/kern_sysctl.c13
-rw-r--r--sys/kern/kern_uuid.c9
-rw-r--r--sys/kern/subr_cprng.c305
-rw-r--r--sys/lib/libkern/Makefile.libkern3
-rw-r--r--sys/lib/libkern/arc4random.c239
-rw-r--r--sys/lib/libkern/rngtest.c281
-rw-r--r--sys/net/if_bridge.c7
-rw-r--r--sys/net/if_spppsubr.c21
-rw-r--r--sys/net/npf/npf_nat.c8
-rw-r--r--sys/net80211/ieee80211_netbsd.c15
-rw-r--r--sys/netinet/in.c8
-rw-r--r--sys/netinet/ip_carp.c9
-rw-r--r--sys/netinet/ip_id.c7
-rw-r--r--sys/netinet/rfc6056.c20
-rw-r--r--sys/netinet/tcp_input.c9
-rw-r--r--sys/netinet/tcp_subr.c28
-rw-r--r--sys/netinet6/files.ipsec6
-rw-r--r--sys/netinet6/in6.c14
-rw-r--r--sys/netinet6/in6_ifattach.c13
-rw-r--r--sys/netinet6/ip6_id.c20
-rw-r--r--sys/netinet6/ip6_input.c7
-rw-r--r--sys/netinet6/mld6.c9
-rw-r--r--sys/netinet6/mld6_var.h4
-rw-r--r--sys/netinet6/nd6.c5
-rw-r--r--sys/netinet6/nd6.h4
-rw-r--r--sys/netinet6/nd6_rtr.c5
-rw-r--r--sys/netkey/key.c24
-rw-r--r--sys/nfs/nfs_subs.c7
-rw-r--r--sys/opencrypto/files.opencrypto4
-rw-r--r--sys/rump/librump/rumpkern/Makefile.rumpkern4
-rw-r--r--sys/rump/librump/rumpkern/cprng_stub.c93
-rw-r--r--sys/rump/librump/rumpkern/rump.c7
-rw-r--r--sys/rump/librump/rumpvfs/rumpblk.c7
-rw-r--r--sys/rump/net/lib/libshmif/if_shmem.c7
-rw-r--r--sys/rump/net/lib/libvirtif/if_virt.c11
-rw-r--r--sys/sys/cprng.h108
-rw-r--r--sys/sys/queue.h6
-rw-r--r--sys/sys/rnd.h71
-rw-r--r--sys/sys/rngtest.h49
-rw-r--r--sys/sys/sysctl.h8
-rw-r--r--sys/ufs/ffs/ffs_appleufs.c9
157 files changed, 3094 insertions, 773 deletions
diff --git a/sys/altq/altq_blue.c b/sys/altq/altq_blue.c
index 5bcf0108842..f5d9c64dee0 100644
--- a/sys/altq/altq_blue.c
+++ b/sys/altq/altq_blue.c
@@ -1,4 +1,4 @@
-/* $NetBSD: altq_blue.c,v 1.22 2007/03/04 05:59:00 christos Exp $ */
+/* $NetBSD: altq_blue.c,v 1.23 2011/11/19 22:51:18 tls Exp $ */
/* $KAME: altq_blue.c,v 1.15 2005/04/13 03:44:24 suz Exp $ */
/*
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_blue.c,v 1.22 2007/03/04 05:59:00 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_blue.c,v 1.23 2011/11/19 22:51:18 tls Exp $");
#ifdef _KERNEL_OPT
#include "opt_altq.h"
@@ -80,6 +80,7 @@ __KERNEL_RCSID(0, "$NetBSD: altq_blue.c,v 1.22 2007/03/04 05:59:00 christos Exp
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/kauth.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -504,7 +505,7 @@ blue_addq(blue_t *rp, class_queue_t *q, struct mbuf *m,
static int
drop_early(blue_t *rp)
{
- if ((arc4random() % rp->blue_max_pmark) < rp->blue_pmark) {
+ if ((cprng_fast32() % rp->blue_max_pmark) < rp->blue_pmark) {
/* drop or mark */
return (1);
}
diff --git a/sys/altq/altq_cdnr.c b/sys/altq/altq_cdnr.c
index 187e3f8f3c4..16db06cb208 100644
--- a/sys/altq/altq_cdnr.c
+++ b/sys/altq/altq_cdnr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: altq_cdnr.c,v 1.19 2007/03/04 05:59:01 christos Exp $ */
+/* $NetBSD: altq_cdnr.c,v 1.20 2011/11/19 22:51:18 tls Exp $ */
/* $KAME: altq_cdnr.c,v 1.15 2005/04/13 03:44:24 suz Exp $ */
/*
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_cdnr.c,v 1.19 2007/03/04 05:59:01 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_cdnr.c,v 1.20 2011/11/19 22:51:18 tls Exp $");
#ifdef _KERNEL_OPT
#include "opt_altq.h"
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: altq_cdnr.c,v 1.19 2007/03/04 05:59:01 christos Exp
#include <sys/kernel.h>
#include <sys/queue.h>
#include <sys/kauth.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -801,7 +802,7 @@ tswtcm_input(struct cdnr_block *cb, struct cdnr_pktinfo *pktinfo)
* marker
*/
if (avg_rate > tsw->cmtd_rate) {
- u_int32_t randval = arc4random() % avg_rate;
+ u_int32_t randval = cprng_fast32() % avg_rate;
if (avg_rate > tsw->peak_rate) {
if (randval < avg_rate - tsw->peak_rate) {
diff --git a/sys/altq/altq_red.c b/sys/altq/altq_red.c
index a611dc5d07f..a01be0781e3 100644
--- a/sys/altq/altq_red.c
+++ b/sys/altq/altq_red.c
@@ -1,4 +1,4 @@
-/* $NetBSD: altq_red.c,v 1.28 2008/06/18 09:06:27 yamt Exp $ */
+/* $NetBSD: altq_red.c,v 1.29 2011/11/19 22:51:18 tls Exp $ */
/* $KAME: altq_red.c,v 1.20 2005/04/13 03:44:25 suz Exp $ */
/*
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_red.c,v 1.28 2008/06/18 09:06:27 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_red.c,v 1.29 2011/11/19 22:51:18 tls Exp $");
#ifdef _KERNEL_OPT
#include "opt_altq.h"
@@ -87,6 +87,7 @@ __KERNEL_RCSID(0, "$NetBSD: altq_red.c,v 1.28 2008/06/18 09:06:27 yamt Exp $");
#include <sys/time.h>
#endif
#endif /* ALTQ3_COMPAT */
+#include <sys/cprng.h>
#include <net/if.h>
@@ -505,7 +506,7 @@ drop_early(int fp_len, int fp_probd, int count)
* drop probability = (avg - TH_MIN) / d
*/
- if ((arc4random() % d) < fp_len) {
+ if ((cprng_fast32() % d) < fp_len) {
/* drop or mark */
return (1);
}
diff --git a/sys/altq/altq_rmclass.c b/sys/altq/altq_rmclass.c
index 7b4cdd9872e..bee3ae75212 100644
--- a/sys/altq/altq_rmclass.c
+++ b/sys/altq/altq_rmclass.c
@@ -1,4 +1,4 @@
-/* $NetBSD: altq_rmclass.c,v 1.21 2008/07/15 16:18:08 christos Exp $ */
+/* $NetBSD: altq_rmclass.c,v 1.22 2011/11/19 22:51:18 tls Exp $ */
/* $KAME: altq_rmclass.c,v 1.19 2005/04/13 03:44:25 suz Exp $ */
/*
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_rmclass.c,v 1.21 2008/07/15 16:18:08 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_rmclass.c,v 1.22 2011/11/19 22:51:18 tls Exp $");
/* #ident "@(#)rm_class.c 1.48 97/12/05 SMI" */
@@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: altq_rmclass.c,v 1.21 2008/07/15 16:18:08 christos E
#ifdef ALTQ3_COMPAT
#include <sys/kernel.h>
#endif
+#include <sys/cprng.h>
#include <net/if.h>
#ifdef ALTQ3_COMPAT
@@ -1777,7 +1778,7 @@ _getq_random(class_queue_t *q)
} else {
struct mbuf *prev = NULL;
- n = arc4random() % qlen(q) + 1;
+ n = cprng_fast32() % qlen(q) + 1;
for (i = 0; i < n; i++) {
prev = m;
m = m->m_nextpkt;
diff --git a/sys/arch/acorn26/ioc/arckbd.c b/sys/arch/acorn26/ioc/arckbd.c
index 7b50084f47d..98c5e867964 100644
--- a/sys/arch/acorn26/ioc/arckbd.c
+++ b/sys/arch/acorn26/ioc/arckbd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: arckbd.c,v 1.20 2011/07/19 16:05:10 dyoung Exp $ */
+/* $NetBSD: arckbd.c,v 1.21 2011/11/19 22:51:18 tls Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 Ben Harris
* All rights reserved.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arckbd.c,v 1.20 2011/07/19 16:05:10 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arckbd.c,v 1.21 2011/11/19 22:51:18 tls Exp $");
#include <sys/param.h>
#include <sys/device.h>
@@ -139,7 +139,7 @@ struct arckbd_softc {
struct irq_handler *sc_rirq;
struct evcnt sc_rev;
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
};
diff --git a/sys/arch/amd64/conf/INSTALL b/sys/arch/amd64/conf/INSTALL
index b82448b5673..44d3038e67b 100644
--- a/sys/arch/amd64/conf/INSTALL
+++ b/sys/arch/amd64/conf/INSTALL
@@ -1,4 +1,4 @@
-# $NetBSD: INSTALL,v 1.87 2011/08/08 16:13:42 jakllsch Exp $
+# $NetBSD: INSTALL,v 1.88 2011/11/19 22:51:19 tls Exp $
#
# INSTALL - Installation kernel.
#
@@ -7,7 +7,8 @@
include "arch/amd64/conf/GENERIC"
-#ident "INSTALL-$Revision: 1.87 $"
+options CONSDEVNAME="\"com\"",CONADDR=0x2f8,CONSPEED=115200
+#ident "INSTALL-$Revision: 1.88 $"
no options MEMORY_DISK_DYNAMIC
options MEMORY_DISK_IS_ROOT # force root on memory disk
diff --git a/sys/arch/arm/at91/at91dbguvar.h b/sys/arch/arm/at91/at91dbguvar.h
index 3c04e3f49b2..5e67c6247cc 100644
--- a/sys/arch/arm/at91/at91dbguvar.h
+++ b/sys/arch/arm/at91/at91dbguvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: at91dbguvar.h,v 1.3 2009/10/23 06:53:13 snj Exp $ */
+/* $NetBSD: at91dbguvar.h,v 1.4 2011/11/19 22:51:19 tls Exp $ */
/*-
* Copyright (c) 2007 Embedtronics Oy
@@ -82,7 +82,7 @@ struct at91dbgu_softc {
int enabled;
#if NRND > 0 && defined(RND_COM)
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/arch/arm/at91/at91usartvar.h b/sys/arch/arm/at91/at91usartvar.h
index 0c5e678675f..b6bb20df69b 100644
--- a/sys/arch/arm/at91/at91usartvar.h
+++ b/sys/arch/arm/at91/at91usartvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: at91usartvar.h,v 1.3 2009/10/23 06:53:13 snj Exp $ */
+/* $NetBSD: at91usartvar.h,v 1.4 2011/11/19 22:51:19 tls Exp $ */
/*-
* Copyright (c) 2007 Embedtronics Oy. All rights reserved.
@@ -86,7 +86,7 @@ struct at91usart_softc {
int enabled;
#if NRND > 0 && defined(RND_COM)
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/arch/arm/ep93xx/epcomvar.h b/sys/arch/arm/ep93xx/epcomvar.h
index 83cb8bd2197..5f628ee8161 100644
--- a/sys/arch/arm/ep93xx/epcomvar.h
+++ b/sys/arch/arm/ep93xx/epcomvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: epcomvar.h,v 1.4 2009/10/23 00:39:30 snj Exp $ */
+/* $NetBSD: epcomvar.h,v 1.5 2011/11/19 22:51:19 tls Exp $ */
/*-
* Copyright (c) 2004 Jesse Off
*
@@ -83,7 +83,7 @@ struct epcom_softc {
int enabled;
#if NRND > 0 && defined(RND_COM)
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/arch/arm/s3c2xx0/sscom_var.h b/sys/arch/arm/s3c2xx0/sscom_var.h
index 85ec04daf13..dcd8c9e3948 100644
--- a/sys/arch/arm/s3c2xx0/sscom_var.h
+++ b/sys/arch/arm/s3c2xx0/sscom_var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sscom_var.h,v 1.8 2011/07/01 20:31:39 dyoung Exp $ */
+/* $NetBSD: sscom_var.h,v 1.9 2011/11/19 22:51:19 tls Exp $ */
/*
* Copyright (c) 2002, 2003 Fujitsu Component Limited
@@ -172,7 +172,7 @@ struct sscom_softc {
#endif
#if NRND > 0 && defined(RND_COM)
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
#if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(SSCOM_MPLOCK)
struct simplelock sc_lock;
diff --git a/sys/arch/arm/sa11x0/sa1111_kbc.c b/sys/arch/arm/sa11x0/sa1111_kbc.c
index b4fc672e5af..c5485d99bef 100644
--- a/sys/arch/arm/sa11x0/sa1111_kbc.c
+++ b/sys/arch/arm/sa11x0/sa1111_kbc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sa1111_kbc.c,v 1.12 2010/03/13 11:13:31 bsh Exp $ */
+/* $NetBSD: sa1111_kbc.c,v 1.13 2011/11/19 22:51:19 tls Exp $ */
/*
* Copyright (c) 2004 Ben Harris.
@@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sa1111_kbc.c,v 1.12 2010/03/13 11:13:31 bsh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sa1111_kbc.c,v 1.13 2011/11/19 22:51:19 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -96,7 +96,7 @@ struct sackbc_softc {
int poll_data; /* status read from intr handler if polling */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
pckbport_tag_t pt;
};
diff --git a/sys/arch/arm/xscale/ixp425_if_npe.c b/sys/arch/arm/xscale/ixp425_if_npe.c
index ca225f1d433..ca98fe99d66 100644
--- a/sys/arch/arm/xscale/ixp425_if_npe.c
+++ b/sys/arch/arm/xscale/ixp425_if_npe.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ixp425_if_npe.c,v 1.20 2011/07/01 20:32:51 dyoung Exp $ */
+/* $NetBSD: ixp425_if_npe.c,v 1.21 2011/11/19 22:51:19 tls Exp $ */
/*-
* Copyright (c) 2006 Sam Leffler. All rights reserved.
@@ -28,7 +28,7 @@
#if 0
__FBSDID("$FreeBSD: src/sys/arm/xscale/ixp425/if_npe.c,v 1.1 2006/11/19 23:55:23 sam Exp $");
#endif
-__KERNEL_RCSID(0, "$NetBSD: ixp425_if_npe.c,v 1.20 2011/07/01 20:32:51 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ixp425_if_npe.c,v 1.21 2011/11/19 22:51:19 tls Exp $");
/*
* Intel XScale NPE Ethernet driver.
@@ -127,7 +127,7 @@ struct npe_softc {
bus_addr_t sc_stats_phys; /* phys addr of sc_stats */
int sc_if_flags; /* keep last if_flags */
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
};
diff --git a/sys/arch/emips/ebus/ace_ebus.c b/sys/arch/emips/ebus/ace_ebus.c
index dfaf891ac5a..c050ce1f4e4 100644
--- a/sys/arch/emips/ebus/ace_ebus.c
+++ b/sys/arch/emips/ebus/ace_ebus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ace_ebus.c,v 1.2 2011/06/18 17:47:20 tsutsui Exp $ */
+/* $NetBSD: ace_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ace_ebus.c,v 1.2 2011/06/18 17:47:20 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ace_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $");
#include "rnd.h"
@@ -193,7 +193,7 @@ struct ace_softc {
int retries; /* number of xfer retry */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
@@ -1467,7 +1467,7 @@ sysace_send_config(struct ace_softc *sc, uint32_t *Data, unsigned int nBytes)
* Rest of code lifted with mods from the dev\ata\wd.c driver
*/
-/* $NetBSD: ace_ebus.c,v 1.2 2011/06/18 17:47:20 tsutsui Exp $ */
+/* $NetBSD: ace_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
diff --git a/sys/arch/emips/ebus/flash_ebus.c b/sys/arch/emips/ebus/flash_ebus.c
index 5591b2bdb11..a6c12c74108 100644
--- a/sys/arch/emips/ebus/flash_ebus.c
+++ b/sys/arch/emips/ebus/flash_ebus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: flash_ebus.c,v 1.2 2011/06/12 03:29:33 tsutsui Exp $ */
+/* $NetBSD: flash_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: flash_ebus.c,v 1.2 2011/06/12 03:29:33 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: flash_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $");
/* Driver for the Intel 28F320/640/128 (J3A150) StrataFlash memory device
* Extended to include the Intel JS28F256P30T95.
@@ -202,7 +202,7 @@ struct eflash_softc {
int retries; /* number of xfer retry */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
/* flash-specific state */
@@ -1306,7 +1306,7 @@ static int eflash_write_at (struct eflash_softc *sc,
/* Rest of code lifted with mods from the dev\ata\wd.c driver
*/
-/* $NetBSD: flash_ebus.c,v 1.2 2011/06/12 03:29:33 tsutsui Exp $ */
+/* $NetBSD: flash_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
diff --git a/sys/arch/emips/ebus/if_le_ebus.c b/sys/arch/emips/ebus/if_le_ebus.c
index 81e5f2f77c0..85b5f5c50ca 100644
--- a/sys/arch/emips/ebus/if_le_ebus.c
+++ b/sys/arch/emips/ebus/if_le_ebus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_le_ebus.c,v 1.2 2011/06/12 14:31:31 tsutsui Exp $ */
+/* $NetBSD: if_le_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_le_ebus.c,v 1.2 2011/06/12 14:31:31 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_le_ebus.c,v 1.3 2011/11/19 22:51:19 tls Exp $");
#include "opt_inet.h"
@@ -115,7 +115,7 @@ struct enic_softc {
uint8_t sc_enaddr[ETHER_ADDR_LEN];
uint8_t sc_pad[2];
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/arch/evbarm/dev/plcomvar.h b/sys/arch/evbarm/dev/plcomvar.h
index 9693ec78d82..30ca4cd5a16 100644
--- a/sys/arch/evbarm/dev/plcomvar.h
+++ b/sys/arch/evbarm/dev/plcomvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: plcomvar.h,v 1.6 2008/01/05 12:40:34 ad Exp $ */
+/* $NetBSD: plcomvar.h,v 1.7 2011/11/19 22:51:19 tls Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@@ -134,7 +134,7 @@ struct plcom_softc {
pps_params_t ppsparam;
#if NRND > 0 && defined(RND_COM)
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
struct simplelock sc_lock;
};
diff --git a/sys/arch/hp300/dev/rdvar.h b/sys/arch/hp300/dev/rdvar.h
index 3d4448a2971..25d5802e824 100644
--- a/sys/arch/hp300/dev/rdvar.h
+++ b/sys/arch/hp300/dev/rdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rdvar.h,v 1.20 2011/02/08 20:20:13 rmind Exp $ */
+/* $NetBSD: rdvar.h,v 1.21 2011/11/19 22:51:19 tls Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -81,7 +81,7 @@ struct rd_softc {
int sc_errcnt;
struct rdstats sc_stats;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/arch/hp700/gsc/harmonyvar.h b/sys/arch/hp700/gsc/harmonyvar.h
index ba492976c03..8a22d349804 100644
--- a/sys/arch/hp700/gsc/harmonyvar.h
+++ b/sys/arch/hp700/gsc/harmonyvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: harmonyvar.h,v 1.4 2008/04/25 08:17:52 mjf Exp $ */
+/* $NetBSD: harmonyvar.h,v 1.5 2011/11/19 22:51:20 tls Exp $ */
/* $OpenBSD: harmonyvar.h,v 1.8 2003/08/15 13:25:53 mickey Exp $ */
@@ -105,7 +105,7 @@ struct harmony_softc {
int sc_teleshare;
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
struct callout sc_acc_tmo;
uint32_t sc_acc, sc_acc_num, sc_acc_cnt;
#endif
diff --git a/sys/arch/i386/pci/glxsb.c b/sys/arch/i386/pci/glxsb.c
index b36c1bfef5d..2ac0cea5331 100644
--- a/sys/arch/i386/pci/glxsb.c
+++ b/sys/arch/i386/pci/glxsb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: glxsb.c,v 1.9 2009/05/16 16:52:03 cegger Exp $ */
+/* $NetBSD: glxsb.c,v 1.10 2011/11/19 22:51:20 tls Exp $ */
/* $OpenBSD: glxsb.c,v 1.7 2007/02/12 14:31:45 tom Exp $ */
/*
@@ -25,7 +25,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: glxsb.c,v 1.9 2009/05/16 16:52:03 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: glxsb.c,v 1.10 2011/11/19 22:51:20 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -34,8 +34,8 @@ __KERNEL_RCSID(0, "$NetBSD: glxsb.c,v 1.9 2009/05/16 16:52:03 cegger Exp $");
#include <sys/mbuf.h>
#include <sys/types.h>
#include <sys/callout.h>
-#include <sys/rnd.h>
#include <sys/bus.h>
+#include <sys/cprng.h>
#include <machine/cpufunc.h>
@@ -165,7 +165,7 @@ struct glxsb_softc {
int sc_nsessions;
struct glxsb_session *sc_sessions;
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
};
int glxsb_match(device_t, cfdata_t, void *);
@@ -343,7 +343,7 @@ glxsb_crypto_newsession(void *aux, uint32_t *sidp, struct cryptoini *cri)
memset(ses, 0, sizeof(*ses));
ses->ses_used = 1;
- arc4randbytes(ses->ses_iv, sizeof(ses->ses_iv));
+ cprng_fast(ses->ses_iv, sizeof(ses->ses_iv));
ses->ses_klen = cri->cri_klen;
/* Copy the key (Geode LX wants the primary key only) */
diff --git a/sys/arch/macppc/dev/if_gm.c b/sys/arch/macppc/dev/if_gm.c
index 6cca16a00fc..a9914ff19ae 100644
--- a/sys/arch/macppc/dev/if_gm.c
+++ b/sys/arch/macppc/dev/if_gm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_gm.c,v 1.39 2011/06/18 08:08:28 matt Exp $ */
+/* $NetBSD: if_gm.c,v 1.40 2011/11/19 22:51:20 tls Exp $ */
/*-
* Copyright (c) 2000 Tsubai Masanari. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gm.c,v 1.39 2011/06/18 08:08:28 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gm.c,v 1.40 2011/11/19 22:51:20 tls Exp $");
#include "opt_inet.h"
#include "rnd.h"
@@ -87,7 +87,7 @@ struct gmac_softc {
char sc_laddr[6];
#if NRND > 0
- rndsource_element_t sc_rnd_source; /* random source */
+ krndsource_t sc_rnd_source; /* random source */
#endif
};
diff --git a/sys/arch/mips/alchemy/dev/if_aumac.c b/sys/arch/mips/alchemy/dev/if_aumac.c
index 1921721e06a..1675188a207 100644
--- a/sys/arch/mips/alchemy/dev/if_aumac.c
+++ b/sys/arch/mips/alchemy/dev/if_aumac.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_aumac.c,v 1.31 2011/07/10 23:13:23 matt Exp $ */
+/* $NetBSD: if_aumac.c,v 1.32 2011/11/19 22:51:20 tls Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_aumac.c,v 1.31 2011/07/10 23:13:23 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_aumac.c,v 1.32 2011/11/19 22:51:20 tls Exp $");
#include "rnd.h"
@@ -143,7 +143,7 @@ struct aumac_softc {
int sc_rxptr; /* next ready Rx descriptor */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
#ifdef AUMAC_EVENT_COUNTERS
diff --git a/sys/arch/mips/atheros/dev/aevar.h b/sys/arch/mips/atheros/dev/aevar.h
index 3c86c70dd23..bf2dd3fb584 100644
--- a/sys/arch/mips/atheros/dev/aevar.h
+++ b/sys/arch/mips/atheros/dev/aevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: aevar.h,v 1.3 2008/04/28 20:23:28 martin Exp $ */
+/* $NetBSD: aevar.h,v 1.4 2011/11/19 22:51:20 tls Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -187,7 +187,7 @@ struct ae_softc {
int sc_rxptr; /* next ready RX descriptor/descsoft */
#if NRND > 0
- rndsource_element_t sc_rnd_source; /* random source */
+ krndsource_t sc_rnd_source; /* random source */
#endif
};
#endif
diff --git a/sys/arch/mips/sibyte/dev/sbscnvar.h b/sys/arch/mips/sibyte/dev/sbscnvar.h
index 209b91bbc40..7d50bb35314 100644
--- a/sys/arch/mips/sibyte/dev/sbscnvar.h
+++ b/sys/arch/mips/sibyte/dev/sbscnvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sbscnvar.h,v 1.4 2011/02/01 03:16:54 matt Exp $ */
+/* $NetBSD: sbscnvar.h,v 1.5 2011/11/19 22:51:20 tls Exp $ */
/*
* Copyright 2000, 2001
@@ -157,7 +157,7 @@ struct sbscn_channel {
u_char ch_o_dtr_pin, ch_o_rts_pin;
#if NRND > 0 && defined(RND_SBSCN)
- rndsource_element_t ch_rnd_source;
+ krndsource_t ch_rnd_source;
#endif
};
diff --git a/sys/arch/next68k/dev/mb8795var.h b/sys/arch/next68k/dev/mb8795var.h
index 058ca35abe6..c53f79b4fb8 100644
--- a/sys/arch/next68k/dev/mb8795var.h
+++ b/sys/arch/next68k/dev/mb8795var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: mb8795var.h,v 1.11 2010/04/24 19:58:13 dbj Exp $ */
+/* $NetBSD: mb8795var.h,v 1.12 2011/11/19 22:51:20 tls Exp $ */
/*
* Copyright (c) 1998 Darrin B. Jewell
* All rights reserved.
@@ -72,7 +72,7 @@ struct mb8795_softc {
struct ifmedia sc_media;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif /* NRND */
};
diff --git a/sys/arch/sgimips/hpc/sqvar.h b/sys/arch/sgimips/hpc/sqvar.h
index 1d758327dee..cef219c5d86 100644
--- a/sys/arch/sgimips/hpc/sqvar.h
+++ b/sys/arch/sgimips/hpc/sqvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sqvar.h,v 1.12 2011/01/25 13:12:39 tsutsui Exp $ */
+/* $NetBSD: sqvar.h,v 1.13 2011/11/19 22:51:20 tls Exp $ */
/*
* Copyright (c) 2001 Rafal K. Boni
@@ -157,7 +157,7 @@ struct sq_softc {
struct evcnt sq_intrcnt; /* count interrupts */
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
struct hpc_values *hpc_regs; /* HPC register definitions */
diff --git a/sys/arch/sgimips/mace/if_mec.c b/sys/arch/sgimips/mace/if_mec.c
index 31191e8b5f8..8775365559a 100644
--- a/sys/arch/sgimips/mace/if_mec.c
+++ b/sys/arch/sgimips/mace/if_mec.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_mec.c,v 1.46 2011/07/01 18:53:47 dyoung Exp $ */
+/* $NetBSD: if_mec.c,v 1.47 2011/11/19 22:51:20 tls Exp $ */
/*-
* Copyright (c) 2004, 2008 Izumi Tsutsui. All rights reserved.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mec.c,v 1.46 2011/07/01 18:53:47 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mec.c,v 1.47 2011/11/19 22:51:20 tls Exp $");
#include "opt_ddb.h"
#include "rnd.h"
@@ -317,7 +317,7 @@ struct mec_softc {
int sc_rxptr; /* next ready RX buffer */
#if NRND > 0
- rndsource_element_t sc_rnd_source; /* random source */
+ krndsource_t sc_rnd_source; /* random source */
#endif
#ifdef MEC_EVENT_COUNTERS
struct evcnt sc_ev_txpkts; /* TX packets queued total */
diff --git a/sys/arch/sun2/dev/if_ec.c b/sys/arch/sun2/dev/if_ec.c
index b2f39a17baf..0237ba2e716 100644
--- a/sys/arch/sun2/dev/if_ec.c
+++ b/sys/arch/sun2/dev/if_ec.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ec.c,v 1.18 2010/04/05 07:19:32 joerg Exp $ */
+/* $NetBSD: if_ec.c,v 1.19 2011/11/19 22:51:21 tls Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ec.c,v 1.18 2010/04/05 07:19:32 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ec.c,v 1.19 2011/11/19 22:51:21 tls Exp $");
#include "opt_inet.h"
#include "opt_ns.h"
@@ -102,7 +102,7 @@ struct ec_softc {
uint32_t sc_backoff_seed; /* seed for the backoff PRNG */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/arch/x68k/dev/fd.c b/sys/arch/x68k/dev/fd.c
index 7126e48551f..5d41b3141e9 100644
--- a/sys/arch/x68k/dev/fd.c
+++ b/sys/arch/x68k/dev/fd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fd.c,v 1.94 2011/04/10 15:23:06 tsutsui Exp $ */
+/* $NetBSD: fd.c,v 1.95 2011/11/19 22:51:21 tls Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.94 2011/04/10 15:23:06 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fd.c,v 1.95 2011/11/19 22:51:21 tls Exp $");
#include "rnd.h"
#include "opt_ddb.h"
@@ -245,7 +245,7 @@ struct fd_softc {
#define SEC_P11 0x03 /* both part */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/arch/x86/include/via_padlock.h b/sys/arch/x86/include/via_padlock.h
index bb653fa12c1..1ed840234d8 100644
--- a/sys/arch/x86/include/via_padlock.h
+++ b/sys/arch/x86/include/via_padlock.h
@@ -1,4 +1,4 @@
-/* $NetBSD: via_padlock.h,v 1.6 2011/02/19 13:52:28 jmcneill Exp $ */
+/* $NetBSD: via_padlock.h,v 1.7 2011/11/19 22:51:21 tls Exp $ */
/*-
* Copyright (c) 2003 Jason Wright
@@ -61,7 +61,7 @@ struct via_padlock_softc {
int sc_rnd_hz;
struct callout sc_rnd_co;
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
bool sc_rnd_attached;
/* normal softc stuff */
diff --git a/sys/arch/x86/pci/fwhrng.c b/sys/arch/x86/pci/fwhrng.c
index f2efa36b797..58169039052 100644
--- a/sys/arch/x86/pci/fwhrng.c
+++ b/sys/arch/x86/pci/fwhrng.c
@@ -1,4 +1,4 @@
-/* $NetBSD: fwhrng.c,v 1.3 2011/07/01 18:22:08 dyoung Exp $ */
+/* $NetBSD: fwhrng.c,v 1.4 2011/11/19 22:51:21 tls Exp $ */
/*
* Copyright (c) 2000 Michael Shalayeff
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fwhrng.c,v 1.3 2011/07/01 18:22:08 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fwhrng.c,v 1.4 2011/11/19 22:51:21 tls Exp $");
#include "rnd.h"
@@ -54,7 +54,7 @@ struct fwhrng_softc {
bus_space_handle_t sc_sh;
struct callout sc_rnd_ch;
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
int sc_rnd_i;
uint32_t sc_rnd_ax;
diff --git a/sys/arch/x86/x86/via_padlock.c b/sys/arch/x86/x86/via_padlock.c
index d0c4ebd8ee5..c30dfa620ee 100644
--- a/sys/arch/x86/x86/via_padlock.c
+++ b/sys/arch/x86/x86/via_padlock.c
@@ -1,5 +1,5 @@
/* $OpenBSD: via.c,v 1.8 2006/11/17 07:47:56 tom Exp $ */
-/* $NetBSD: via_padlock.c,v 1.15 2011/05/24 18:59:21 drochner Exp $ */
+/* $NetBSD: via_padlock.c,v 1.16 2011/11/19 22:51:21 tls Exp $ */
/*-
* Copyright (c) 2003 Jason Wright
@@ -20,7 +20,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.15 2011/05/24 18:59:21 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.16 2011/11/19 22:51:21 tls Exp $");
#ifdef _KERNEL_OPT
# include "rnd.h"
@@ -258,8 +258,7 @@ via_padlock_crypto_newsession(void *arg, uint32_t *sidp, struct cryptoini *cri)
C3_CRYPT_CWLO_KEYGEN_SW |
C3_CRYPT_CWLO_NORMAL;
- rnd_extract_data(ses->ses_iv, sizeof(ses->ses_iv),
- RND_EXTRACT_ANY);
+ arc4randbytes(ses->ses_iv, sizeof(ses->ses_iv));
ses->ses_klen = c->cri_klen;
ses->ses_cw0 = cw0;
diff --git a/sys/arch/xen/include/xbdvar.h b/sys/arch/xen/include/xbdvar.h
index 81c1524a7ff..28fe36e418c 100644
--- a/sys/arch/xen/include/xbdvar.h
+++ b/sys/arch/xen/include/xbdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: xbdvar.h,v 1.12 2009/10/23 02:32:33 snj Exp $ */
+/* $NetBSD: xbdvar.h,v 1.13 2011/11/19 22:51:21 tls Exp $ */
/*
*
@@ -40,7 +40,7 @@ struct xbd_softc {
struct simplelock sc_slock; /* our lock */
int sc_shutdown; /* about to be removed */
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
};
diff --git a/sys/arch/xen/xen/if_xennet_xenbus.c b/sys/arch/xen/xen/if_xennet_xenbus.c
index 84003c6eb38..7c4703f715d 100644
--- a/sys/arch/xen/xen/if_xennet_xenbus.c
+++ b/sys/arch/xen/xen/if_xennet_xenbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_xennet_xenbus.c,v 1.53 2011/09/26 21:44:09 jym Exp $ */
+/* $NetBSD: if_xennet_xenbus.c,v 1.54 2011/11/19 22:51:21 tls Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -85,7 +85,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.53 2011/09/26 21:44:09 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_xennet_xenbus.c,v 1.54 2011/11/19 22:51:21 tls Exp $");
#include "opt_xen.h"
#include "opt_nfs_boot.h"
@@ -203,7 +203,7 @@ struct xennet_xenbus_softc {
#define FEATURE_RX_FLIP 0
#define FEATURE_RX_COPY 1
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
};
#define SC_NLIVEREQ(sc) ((sc)->sc_rx_ring.req_prod_pvt - \
diff --git a/sys/arch/xen/xen/xbd_xenbus.c b/sys/arch/xen/xen/xbd_xenbus.c
index cbe269f198f..3cdfc389cae 100644
--- a/sys/arch/xen/xen/xbd_xenbus.c
+++ b/sys/arch/xen/xen/xbd_xenbus.c
@@ -1,4 +1,4 @@
-/* $NetBSD: xbd_xenbus.c,v 1.48 2011/09/20 00:12:24 jym Exp $ */
+/* $NetBSD: xbd_xenbus.c,v 1.49 2011/11/19 22:51:21 tls Exp $ */
/*
* Copyright (c) 2006 Manuel Bouyer.
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.48 2011/09/20 00:12:24 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.49 2011/11/19 22:51:21 tls Exp $");
#include "opt_xen.h"
#include "rnd.h"
@@ -155,7 +155,7 @@ struct xbd_xenbus_softc {
u_long sc_handle; /* from backend */
int sc_cache_flush; /* backend supports BLKIF_OP_FLUSH_DISKCACHE */
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
};
diff --git a/sys/conf/files b/sys/conf/files
index 612f0d8e028..d7f23618772 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1031 2011/11/15 16:50:43 riz Exp $
+# $NetBSD: files,v 1.1032 2011/11/19 22:51:21 tls Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20100430
@@ -165,10 +165,12 @@ include "crypto/cast128/files.cast128"
include "crypto/rijndael/files.rijndael"
include "crypto/skipjack/files.skipjack"
include "crypto/camellia/files.camellia"
-
# General-purpose crypto processing framework.
include "opencrypto/files.opencrypto"
+# NIST SP800.90 CTR DRBG
+include "crypto/nist_ctr_drbg/files.nist_ctr_drbg"
+
#
# Kernel history/tracing. Old UVMHIST depends upon this.
#
@@ -392,7 +394,7 @@ define hippi
define ieee1394
define token
define sppp
-define wlan: rijndael
+define wlan
define crypto
# devices ARPing IPv4 pull this in:
@@ -1280,7 +1282,7 @@ file dev/ic/dm9000.c dme
defpseudodev vnd: disk
defflag opt_vnd.h VND_COMPRESSION
defpseudo ccd: disk
-defpseudodev cgd: disk, des, blowfish, cast128, rijndael
+defpseudodev cgd: disk, des, blowfish, cast128
defpseudodev md: disk
defpseudodev fss: disk
@@ -1525,6 +1527,7 @@ file kern/subr_autoconf.c
file kern/subr_blist.c vmswap
file kern/subr_bufq.c
file kern/subr_callback.c
+file kern/subr_cprng.c
file kern/subr_cpufreq.c
file kern/subr_copy.c
file kern/subr_debug.c debug
diff --git a/sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg b/sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg
new file mode 100644
index 00000000000..54bc9c995f5
--- /dev/null
+++ b/sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg
@@ -0,0 +1,3 @@
+# $NetBSD: files.nist_ctr_drbg,v 1.1 2011/11/19 22:51:22 tls Exp $
+
+file crypto/nist_ctr_drbg/nist_ctr_drbg.c
diff --git a/sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h b/sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h
new file mode 100644
index 00000000000..80620561967
--- /dev/null
+++ b/sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h
@@ -0,0 +1,82 @@
+/* $NetBSD: nist_ctr_aes_rijndael.h,v 1.1 2011/11/19 22:51:22 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2007 Henric Jungheim <software@henric.info>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Interface adapter for Rijndael implmentation (for use by NIST SP 800-90 CTR_DRBG)
+ */
+
+#ifndef NIST_AES_RIJNDAEL_H
+#define NIST_AES_RIJNDAEL_H
+
+#include <crypto/rijndael/rijndael.h>
+
+#define NIST_AES_MAXKEYBITS 256
+#define NIST_AES_MAXKEYBYTES (NIST_AES_MAXKEYBITS / 8)
+#define NIST_AES_MAXKEYINTS (NIST_AES_MAXKEYBYTES / sizeof(int))
+
+#define NIST_AES_BLOCKSIZEBITS 128
+#define NIST_AES_BLOCKSIZEBYTES (NIST_AES_BLOCKSIZEBITS / 8)
+#define NIST_AES_BLOCKSIZEINTS (NIST_AES_BLOCKSIZEBYTES / sizeof(int))
+
+typedef rijndael_ctx NIST_AES_ENCRYPT_CTX;
+
+static inline void
+NIST_AES_ECB_Encrypt(const NIST_AES_ENCRYPT_CTX *ctx,
+ const void *src, void* dst)
+{
+ rijndael_encrypt(ctx, src, dst);
+}
+
+static inline int
+NIST_AES_Schedule_Encryption(NIST_AES_ENCRYPT_CTX *ctx,
+ const void *key, int bits)
+{
+ rijndael_set_key(ctx, key, bits);
+ return 0;
+}
+
+#endif /* NIST_AES_RIJNDAEL_H */
diff --git a/sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c
new file mode 100644
index 00000000000..9a636975658
--- /dev/null
+++ b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c
@@ -0,0 +1,664 @@
+/* $NetBSD: nist_ctr_drbg.c,v 1.1 2011/11/19 22:51:22 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2007 Henric Jungheim <software@henric.info>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * NIST SP 800-90 CTR_DRBG (Random Number Generator)
+ */
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include <crypto/nist_ctr_drbg/nist_ctr_drbg.h>
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: nist_ctr_drbg.c,v 1.1 2011/11/19 22:51:22 tls Exp $");
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.4.2 Derivation Function Using a Block Cipher Algorithm
+ * Global Constants
+ */
+static NIST_Key nist_cipher_df_ctx;
+static unsigned char nist_cipher_df_encrypted_iv[NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN][NIST_BLOCK_OUTLEN_BYTES];
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2.1.3.2 The Process Steps for Instantiation When a Derivation
+ * Function is Used
+ * Global Constants
+ */
+static NIST_Key nist_cipher_zero_ctx;
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2.1.5.2 The Process Steps for Generating Pseudorandom Bits When a
+ * Derivation Function is Used for the DRBG Implementation
+ * Global Constants
+ */
+static const unsigned int
+ nist_ctr_drgb_generate_null_input[NIST_BLOCK_SEEDLEN_INTS] = { 0 };
+
+/*
+ * Utility
+ */
+/*
+ * nist_increment_block
+ * Increment the output block as a big-endian number.
+ */
+static inline void
+nist_increment_block(unsigned long *V)
+{
+ int i;
+ unsigned long x;
+
+ for (i = NIST_BLOCK_OUTLEN_LONGS - 1; i >= 0; --i) {
+ x = NIST_NTOHL(V[i]) + 1;
+ V[i] = NIST_HTONL(x);
+ if (x) /* There was only a carry if we are zero */
+ return;
+ }
+}
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.4.3 BCC Function
+ */
+static void
+nist_ctr_drbg_bcc_update(const NIST_Key *ctx, const unsigned int *data,
+ int n, unsigned int *chaining_value)
+{
+ int i, j;
+ unsigned int input_block[NIST_BLOCK_OUTLEN_INTS];
+
+ /* [4] for i = 1 to n */
+ for (i = 0; i < n; ++i) {
+
+ /* [4.1] input_block = chaining_value XOR block_i */
+ for (j = 0; j < NIST_BLOCK_OUTLEN_INTS; ++j)
+ input_block[j] = chaining_value[j] ^ *data++;
+
+ /* [4.2] chaining_value = Block_Encrypt(Key, input_block) */
+ Block_Encrypt(ctx, &input_block[0], &chaining_value[0]);
+ }
+
+ /* [5] output_block = chaining_value */
+ /* chaining_value already is output_block, so no copy is required */
+}
+
+static void
+nist_ctr_drbg_bcc(NIST_Key *ctx, const unsigned int *data,
+ int n, unsigned int *output_block)
+{
+ unsigned int *chaining_value = output_block;
+
+ /* [1] chaining_value = 0^outlen */
+ memset(&chaining_value[0], 0, NIST_BLOCK_OUTLEN_BYTES);
+
+ nist_ctr_drbg_bcc_update(ctx, data, n, output_block);
+}
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.4.2 Derivation Function Using a Block Cipher Algorithm
+ */
+
+typedef struct {
+ int index;
+ unsigned char S[NIST_BLOCK_OUTLEN_BYTES];
+} NIST_CTR_DRBG_DF_BCC_CTX;
+
+static inline int
+check_int_alignment(const void *p)
+{
+ intptr_t ip = (const char *)p - (const char *)0;
+
+ if (ip & (sizeof(int) - 1))
+ return 0;
+
+ return 1;
+}
+
+static void
+nist_ctr_drbg_df_bcc_init(NIST_CTR_DRBG_DF_BCC_CTX *ctx, int L, int N)
+{
+ unsigned int *S = (unsigned int *)ctx->S;
+
+ /* [4] S = L || N || input_string || 0x80 */
+ S[0] = NIST_HTONL(L);
+ S[1] = NIST_HTONL(N);
+ ctx->index = 2 * sizeof(S[0]);
+}
+
+static void
+nist_ctr_drbg_df_bcc_update(NIST_CTR_DRBG_DF_BCC_CTX *ctx,
+ const char *input_string,
+ int input_string_length, unsigned int *temp)
+{
+ int i, len;
+ int index = ctx->index;
+ unsigned char *S = ctx->S;
+
+ if (index) {
+ KASSERT(index < NIST_BLOCK_OUTLEN_BYTES);
+ len = NIST_BLOCK_OUTLEN_BYTES - index;
+ if (input_string_length < len)
+ len = input_string_length;
+
+ memcpy(&S[index], input_string, len);
+
+ index += len;
+ input_string += len;
+ input_string_length -= len;
+
+ if (index < NIST_BLOCK_OUTLEN_BYTES) {
+ ctx->index = index;
+
+ return;
+ }
+
+ /* We have a full block in S, so let's process it */
+ /* [9.2] BCC */
+ nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx,
+ (unsigned int *)&S[0], 1, temp);
+ index = 0;
+ }
+
+ /* ctx->S is empty, so let's handle as many input blocks as we can */
+ len = input_string_length / NIST_BLOCK_OUTLEN_BYTES;
+ if (len > 0) {
+ if (check_int_alignment(input_string)) {
+ /* [9.2] BCC */
+ nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx,
+ (const unsigned int *)
+ input_string, len, temp);
+
+ input_string += len * NIST_BLOCK_OUTLEN_BYTES;
+ input_string_length -= len * NIST_BLOCK_OUTLEN_BYTES;
+ } else {
+ for (i = 0; i < len; ++i) {
+ memcpy(&S[0], input_string,
+ NIST_BLOCK_OUTLEN_BYTES);
+
+ /* [9.2] BCC */
+ nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx,
+ (unsigned int *)
+ &S[0], 1, temp);
+
+ input_string += NIST_BLOCK_OUTLEN_BYTES;
+ input_string_length -= NIST_BLOCK_OUTLEN_BYTES;
+ }
+ }
+ }
+
+ KASSERT(input_string_length < NIST_BLOCK_OUTLEN_BYTES);
+
+ if (input_string_length) {
+ memcpy(&S[0], input_string, input_string_length);
+ index = input_string_length;
+ }
+
+ ctx->index = index;
+}
+
+static void
+nist_ctr_drbg_df_bcc_final(NIST_CTR_DRBG_DF_BCC_CTX *ctx, unsigned int *temp)
+{
+ int index;
+ unsigned char* S = ctx->S;
+ static const char endmark[] = { 0x80 };
+
+ nist_ctr_drbg_df_bcc_update(ctx, endmark, sizeof(endmark), temp);
+
+ index = ctx->index;
+ if (index) {
+ memset(&S[index], 0, NIST_BLOCK_OUTLEN_BYTES - index);
+
+ /* [9.2] BCC */
+ nist_ctr_drbg_bcc_update(&nist_cipher_df_ctx,
+ (unsigned int *)&S[0], 1, temp);
+ }
+}
+
+static int
+nist_ctr_drbg_block_cipher_df(const char *input_string[], unsigned int L[],
+ int input_string_count,
+ unsigned char *output_string, unsigned int N)
+{
+ int j, k, blocks, sum_L;
+ unsigned int *temp;
+ unsigned int *X;
+ NIST_Key ctx;
+ NIST_CTR_DRBG_DF_BCC_CTX df_bcc_ctx;
+ unsigned int buffer[NIST_BLOCK_SEEDLEN_INTS];
+ /*
+ * NIST SP 800-90 March 2007 10.4.2 states that 512 bits is
+ * the maximum length for the approved block cipher algorithms.
+ */
+ unsigned int output_buffer[512 / 8 / sizeof(unsigned int)];
+
+ if (N > sizeof(output_buffer) || N < 1)
+ return 0;
+
+ sum_L = 0;
+ for (j = 0; j < input_string_count; ++j)
+ sum_L += L[j];
+
+ /* [6] temp = Null string */
+ temp = buffer;
+
+ /* [9] while len(temp) < keylen + outlen, do */
+ for (j = 0; j < NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN; ++j) {
+ /* [9.2] temp = temp || BCC(K, (IV || S)) */
+
+ /* Since we have precomputed BCC(K, IV), we start with that... */
+ memcpy(&temp[0], &nist_cipher_df_encrypted_iv[j][0],
+ NIST_BLOCK_OUTLEN_BYTES);
+
+ nist_ctr_drbg_df_bcc_init(&df_bcc_ctx, sum_L, N);
+
+ /* Compute the rest of BCC(K, (IV || S)) */
+ for (k = 0; k < input_string_count; ++k)
+ nist_ctr_drbg_df_bcc_update(&df_bcc_ctx,
+ input_string[k],
+ L[k], temp);
+
+ nist_ctr_drbg_df_bcc_final(&df_bcc_ctx, temp);
+
+ temp += NIST_BLOCK_OUTLEN_INTS;
+ }
+
+ nist_zeroize(&df_bcc_ctx, sizeof(df_bcc_ctx));
+
+ /* [6] temp = Null string */
+ temp = buffer;
+
+ /* [10] K = Leftmost keylen bits of temp */
+ Block_Schedule_Encryption(&ctx, &temp[0]);
+
+ /* [11] X = next outlen bits of temp */
+ X = &temp[NIST_BLOCK_KEYLEN_INTS];
+
+ /* [12] temp = Null string */
+ temp = output_buffer;
+
+ /* [13] While len(temp) < number_of_bits_to_return, do */
+ blocks = (int)(N / NIST_BLOCK_OUTLEN_BYTES);
+ if (N & (NIST_BLOCK_OUTLEN_BYTES - 1))
+ ++blocks;
+ for (j = 0; j < blocks; ++j) {
+ /* [13.1] X = Block_Encrypt(K, X) */
+ Block_Encrypt(&ctx, X, temp);
+ X = temp;
+ temp += NIST_BLOCK_OUTLEN_INTS;
+ }
+
+ /* [14] requested_bits = Leftmost number_of_bits_to_return of temp */
+ memcpy(output_string, output_buffer, N);
+
+ nist_zeroize(&ctx, sizeof(ctx));
+
+ return 0;
+}
+
+
+static int
+nist_ctr_drbg_block_cipher_df_initialize(void)
+{
+ int i, err;
+ unsigned char K[NIST_BLOCK_KEYLEN_BYTES];
+ unsigned int IV[NIST_BLOCK_OUTLEN_INTS];
+
+ /* [8] K = Leftmost keylen bits of 0x00010203 ... 1D1E1F */
+ for (i = 0; i < sizeof(K); ++i)
+ K[i] = (unsigned char)i;
+
+ err = Block_Schedule_Encryption(&nist_cipher_df_ctx, K);
+ if (err)
+ return err;
+
+ /*
+ * Precompute the partial BCC result from encrypting the IVs:
+ * nist_cipher_df_encrypted_iv[i] = BCC(K, IV(i))
+ */
+
+ /* [7] i = 0 */
+ /* [9.1] IV = i || 0^(outlen - len(i)) */
+ memset(&IV[0], 0, sizeof(IV));
+
+ /* [9.3] i = i + 1 */
+ for (i = 0; i < NIST_BLOCK_SEEDLEN / NIST_BLOCK_OUTLEN; ++i) {
+
+ /* [9.1] IV = i || 0^(outlen - len(i)) */
+ IV[0] = NIST_HTONL(i);
+
+ /*
+ * [9.2] temp = temp || BCC(K, (IV || S))
+ * (the IV part, at least)
+ */
+ nist_ctr_drbg_bcc(&nist_cipher_df_ctx, &IV[0], 1,
+ (unsigned int *)
+ &nist_cipher_df_encrypted_iv[i][0]);
+ }
+
+ return 0;
+}
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2.1.2 The Update Function
+ */
+static void
+nist_ctr_drbg_update(NIST_CTR_DRBG *drbg, const unsigned int *provided_data)
+{
+ int i;
+ unsigned int temp[NIST_BLOCK_SEEDLEN_INTS];
+ unsigned int* output_block;
+
+ /* 2. while (len(temp) < seedlen) do */
+ for (output_block = temp;
+ output_block < &temp[NIST_BLOCK_SEEDLEN_INTS];
+ output_block += NIST_BLOCK_OUTLEN_INTS) {
+
+ /* 2.1 V = (V + 1) mod 2^outlen */
+ nist_increment_block((unsigned long *)&drbg->V[0]);
+
+ /* 2.2 output_block = Block_Encrypt(K, V) */
+ Block_Encrypt(&drbg->ctx, drbg->V, output_block);
+ }
+
+ /* 3 temp is already of size seedlen (NIST_BLOCK_SEEDLEN_INTS) */
+
+ /* 4 (part 1) temp = temp XOR provided_data */
+ for (i = 0; i < NIST_BLOCK_KEYLEN_INTS; ++i)
+ temp[i] ^= *provided_data++;
+
+ /* 5 Key = leftmost keylen bits of temp */
+ Block_Schedule_Encryption(&drbg->ctx, &temp[0]);
+
+ /* 4 (part 2) combined with 6 V = rightmost outlen bits of temp */
+ for (i = 0; i < NIST_BLOCK_OUTLEN_INTS; ++i)
+ drbg->V[i] =
+ temp[NIST_BLOCK_KEYLEN_INTS + i] ^ *provided_data++;
+}
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2.1.3.2 The Process Steps for Instantiation When a Derivation
+ * Function is Used
+ */
+int
+nist_ctr_drbg_instantiate(NIST_CTR_DRBG* drbg,
+ const void *entropy_input, int entropy_input_length,
+ const void *nonce, int nonce_length,
+ const void *personalization_string, int personalization_string_length)
+{
+ int err, count;
+ unsigned int seed_material[NIST_BLOCK_SEEDLEN_INTS];
+ unsigned int length[3];
+ const char *input_string[3];
+
+ /* [1] seed_material = entropy_input ||
+ * nonce || personalization_string
+ */
+
+ input_string[0] = entropy_input;
+ length[0] = entropy_input_length;
+
+ input_string[1] = nonce;
+ length[1] = nonce_length;
+
+ count = 2;
+ if (personalization_string) {
+ input_string[count] = personalization_string;
+ length[count] = personalization_string_length;
+ ++count;
+ }
+ /* [2] seed_material = Block_Cipher_df(seed_material, seedlen) */
+ err = nist_ctr_drbg_block_cipher_df(input_string, length, count,
+ (unsigned char *)seed_material,
+ sizeof(seed_material));
+ if (err)
+ return err;
+
+ /* [3] Key = 0^keylen */
+ memcpy(&drbg->ctx, &nist_cipher_zero_ctx, sizeof(drbg->ctx));
+
+ /* [4] V = 0^outlen */
+ memset(&drbg->V, 0, sizeof(drbg->V));
+
+ /* [5] (Key, V) = Update(seed_material, Key, V) */
+ nist_ctr_drbg_update(drbg, seed_material);
+
+ /* [6] reseed_counter = 1 */
+ drbg->reseed_counter = 1;
+
+ return 0;
+}
+
+static int
+nist_ctr_drbg_instantiate_initialize(void)
+{
+ int err;
+ unsigned char K[NIST_BLOCK_KEYLEN_BYTES];
+
+ memset(&K[0], 0, sizeof(K));
+
+ err = Block_Schedule_Encryption(&nist_cipher_zero_ctx, &K[0]);
+
+ return err;
+}
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2.1.4.2 The Process Steps for Reseeding When a Derivation
+ * Function is Used
+ */
+int
+nist_ctr_drbg_reseed(NIST_CTR_DRBG *drbg,
+ const void *entropy_input, int entropy_input_length,
+ const void *additional_input,
+ int additional_input_length)
+{
+ int err, count;
+ const char *input_string[2];
+ unsigned int length[2];
+ unsigned int seed_material[NIST_BLOCK_SEEDLEN_INTS];
+
+ /* [1] seed_material = entropy_input || additional_input */
+ input_string[0] = entropy_input;
+ length[0] = entropy_input_length;
+ count = 1;
+
+ if (additional_input) {
+ input_string[count] = additional_input;
+ length[count] = additional_input_length;
+
+ ++count;
+ }
+ /* [2] seed_material = Block_Cipher_df(seed_material, seedlen) */
+ err = nist_ctr_drbg_block_cipher_df(input_string, length, count,
+ (unsigned char *)seed_material,
+ sizeof(seed_material));
+ if (err)
+ return err;
+
+ /* [3] (Key, V) = Update(seed_material, Key, V) */
+ nist_ctr_drbg_update(drbg, seed_material);
+
+ /* [4] reseed_counter = 1 */
+ drbg->reseed_counter = 1;
+
+ return 0;
+}
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2.1.5.2 The Process Steps for Generating Pseudorandom Bits When a
+ * Derivation Function is Used for the DRBG Implementation
+ */
+static void
+nist_ctr_drbg_generate_block(NIST_CTR_DRBG *drbg, unsigned int *output_block)
+{
+
+ /* [4.1] V = (V + 1) mod 2^outlen */
+ nist_increment_block((unsigned long *)&drbg->V[0]);
+
+ /* [4.2] output_block = Block_Encrypt(Key, V) */
+ Block_Encrypt(&drbg->ctx, &drbg->V[0], output_block);
+
+}
+
+int
+nist_ctr_drbg_generate(NIST_CTR_DRBG * drbg,
+ void *output_string, int output_string_length,
+ const void *additional_input,
+ int additional_input_length)
+{
+ int i, len, err;
+ int blocks = output_string_length / NIST_BLOCK_OUTLEN_BYTES;
+ unsigned char* p;
+ unsigned int* temp;
+ const char *input_string[1];
+ unsigned int length[1];
+ unsigned int buffer[NIST_BLOCK_OUTLEN_BYTES];
+ unsigned int additional_input_buffer[NIST_BLOCK_SEEDLEN_INTS];
+ int ret = 0;
+
+ if (output_string_length < 1)
+ return 1;
+
+ /* [1] If reseed_counter > reseed_interval ... */
+ if (drbg->reseed_counter >= NIST_CTR_DRBG_RESEED_INTERVAL) {
+ ret = 1;
+ goto out;
+ }
+
+ /* [2] If (addional_input != Null), then */
+ if (additional_input) {
+ input_string[0] = additional_input;
+ length[0] = additional_input_length;
+ /*
+ * [2.1] additional_input =
+ * Block_Cipher_df(additional_input, seedlen)
+ */
+ err = nist_ctr_drbg_block_cipher_df(input_string, length, 1,
+ (unsigned char *)additional_input_buffer,
+ sizeof(additional_input_buffer));
+ if (err) {
+ ret = err;
+ goto out;
+ }
+
+ /* [2.2] (Key, V) = Update(additional_input, Key, V) */
+ nist_ctr_drbg_update(drbg, additional_input_buffer);
+ }
+
+ if (blocks && check_int_alignment(output_string)) {
+ /* [3] temp = Null */
+ temp = (unsigned int *)output_string;
+ for (i = 0; i < blocks; ++i) {
+ nist_ctr_drbg_generate_block(drbg, temp);
+
+ temp += NIST_BLOCK_OUTLEN_INTS;
+ output_string_length -= NIST_BLOCK_OUTLEN_BYTES;
+ }
+
+ output_string = (unsigned char *)temp;
+ }
+
+ /* [3] temp = Null */
+ temp = buffer;
+
+ len = NIST_BLOCK_OUTLEN_BYTES;
+
+ /* [4] While (len(temp) < requested_number_of_bits) do: */
+ p = output_string;
+ while (output_string_length > 0) {
+ nist_ctr_drbg_generate_block(drbg, temp);
+
+ if (output_string_length < NIST_BLOCK_OUTLEN_BYTES)
+ len = output_string_length;
+
+ memcpy(p, temp, len);
+
+ p += len;
+ output_string_length -= len;
+ }
+
+ /* [6] (Key, V) = Update(additional_input, Key, V) */
+ nist_ctr_drbg_update(drbg, additional_input ?
+ &additional_input_buffer[0] :
+ &nist_ctr_drgb_generate_null_input[0]);
+
+ /* [7] reseed_counter = reseed_counter + 1 */
+ ++drbg->reseed_counter;
+
+out:
+ return ret;
+}
+
+int
+nist_ctr_initialize(void)
+{
+ int err;
+
+ err = nist_ctr_drbg_instantiate_initialize();
+ if (err)
+ return err;
+ err = nist_ctr_drbg_block_cipher_df_initialize();
+ if (err)
+ return err;
+
+ return 0;
+}
+
+int
+nist_ctr_drbg_destroy(NIST_CTR_DRBG* drbg)
+{
+ nist_zeroize(drbg, sizeof(*drbg));
+ drbg->reseed_counter = ~0U;
+ return 1;
+}
diff --git a/sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h
new file mode 100644
index 00000000000..65e44a3a1ac
--- /dev/null
+++ b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h
@@ -0,0 +1,106 @@
+/* $NetBSD: nist_ctr_drbg.h,v 1.1 2011/11/19 22:51:22 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2007 Henric Jungheim <software@henric.info>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * NIST SP 800-90 CTR_DRBG (Random Number Generator)
+ */
+
+#ifndef NIST_CTR_DRBG_H
+#define NIST_CTR_DRBG_H
+
+#include <crypto/nist_ctr_drbg/nist_ctr_drbg_config.h>
+
+#define NIST_BLOCK_SEEDLEN (NIST_BLOCK_KEYLEN + NIST_BLOCK_OUTLEN)
+#define NIST_BLOCK_SEEDLEN_BYTES (NIST_BLOCK_SEEDLEN / 8)
+#define NIST_BLOCK_SEEDLEN_INTS (NIST_BLOCK_SEEDLEN_BYTES / sizeof(int))
+
+typedef struct {
+ unsigned int reseed_counter;
+ NIST_Key ctx;
+ unsigned int V[NIST_BLOCK_OUTLEN_INTS];
+} NIST_CTR_DRBG;
+
+int nist_ctr_initialize(void);
+int nist_ctr_drbg_generate(NIST_CTR_DRBG *, void *, int, const void *, int);
+int nist_ctr_drbg_reseed(NIST_CTR_DRBG *, const void *, int,
+ const void *, int);
+int nist_ctr_drbg_instantiate(NIST_CTR_DRBG *, const void *, int,
+ const void *, int, const void *, int);
+int nist_ctr_drbg_destroy(NIST_CTR_DRBG *);
+
+#ifdef NIST_ZEROIZE
+#define nist_zeroize(p, s) memset(p, 0, s)
+#else
+#define nist_zeroize(p, s) do { } while(0)
+#endif
+
+#ifdef NIST_IS_LITTLE_ENDIAN /* Faster, as secure, won't pass KAT */
+#define NIST_HTONL(x) (x)
+#define NIST_NTOHL(x) (x)
+#else
+static inline unsigned long
+NIST_HTONL(unsigned long x)
+{
+ switch(sizeof(long)) {
+ case 4:
+ return be32toh(x);
+ default:
+ return be64toh(x);
+ {
+}
+static inline unsigned long
+NIST_NTOHL(unsigned long x)
+{
+ switch(sizeof(long)) {
+ case 4:
+ return htobe32(x);
+ default:
+ return htobe64(x);
+}
+#endif
+
+#endif /* NIST_CTR_DRBG_H */
diff --git a/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h
new file mode 100644
index 00000000000..805524b084d
--- /dev/null
+++ b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h
@@ -0,0 +1,80 @@
+/* $NetBSD: nist_ctr_drbg_aes128.h,v 1.1 2011/11/19 22:51:22 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2007 Henric Jungheim <software@henric.info>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * NIST SP 800-90 CTR_DRBG (Random Number Generator)
+ */
+
+#ifndef NIST_CTR_DRBG_AES128_H
+#define NIST_CTR_DRBG_AES128_H
+
+/* Choose AES-128 as the underlying block cipher */
+#define NIST_BLOCK_KEYLEN (128)
+#define NIST_BLOCK_KEYLEN_BYTES (NIST_BLOCK_KEYLEN / 8)
+#define NIST_BLOCK_KEYLEN_INTS (NIST_BLOCK_KEYLEN_BYTES / sizeof(int))
+
+#define NIST_BLOCK_OUTLEN (NIST_AES_BLOCKSIZEBITS)
+#define NIST_BLOCK_OUTLEN_BYTES (NIST_BLOCK_OUTLEN / 8)
+#define NIST_BLOCK_OUTLEN_INTS (NIST_BLOCK_OUTLEN_BYTES / sizeof(int))
+#define NIST_BLOCK_OUTLEN_LONGS (NIST_BLOCK_OUTLEN_BYTES / sizeof(long))
+
+typedef NIST_AES_ENCRYPT_CTX NIST_Key;
+
+#define Block_Encrypt(ctx, src, dst) NIST_AES_ECB_Encrypt(ctx, src, dst)
+#define Block_Schedule_Encryption(ctx, key) \
+ NIST_AES_Schedule_Encryption(ctx, key, NIST_BLOCK_KEYLEN)
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2 DRBG Mechanism Based on Block Ciphers
+ *
+ * Table 3 specifies the reseed interval as
+ * <= 2^48. We use 2^32 so we can always be sure it'll fit in an int.
+ */
+#define NIST_CTR_DRBG_RESEED_INTERVAL (0xffffffffU)
+
+#endif /* NIST_CTR_DRBG_AES128_H */
diff --git a/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h
new file mode 100644
index 00000000000..0cb75fb688a
--- /dev/null
+++ b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h
@@ -0,0 +1,80 @@
+/* $NetBSD: nist_ctr_drbg_aes256.h,v 1.1 2011/11/19 22:51:22 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2007 Henric Jungheim <software@henric.info>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * NIST SP 800-90 CTR_DRBG (Random Number Generator)
+ */
+
+#ifndef NIST_CTR_DRBG_AES256_H
+#define NIST_CTR_DRBG_AES256_H
+
+/* Choose AES-256 as the underlying block cipher */
+#define NIST_BLOCK_KEYLEN (256)
+#define NIST_BLOCK_KEYLEN_BYTES (NIST_BLOCK_KEYLEN / 8)
+#define NIST_BLOCK_KEYLEN_INTS (NIST_BLOCK_KEYLEN_BYTES / sizeof(int))
+
+#define NIST_BLOCK_OUTLEN (NIST_AES_BLOCKSIZEBITS)
+#define NIST_BLOCK_OUTLEN_BYTES (NIST_BLOCK_OUTLEN / 8)
+#define NIST_BLOCK_OUTLEN_INTS (NIST_BLOCK_OUTLEN_BYTES / sizeof(int))
+#define NIST_BLOCK_OUTLEN_LONGS (NIST_BLOCK_OUTLEN_BYTES / sizeof(long))
+
+typedef NIST_AES_ENCRYPT_CTX NIST_Key;
+
+#define Block_Encrypt(ctx, src, dst) NIST_AES_ECB_Encrypt(ctx, src, dst)
+#define Block_Schedule_Encryption(ctx, key) \
+ NIST_AES_Schedule_Encryption(ctx, key, NIST_BLOCK_KEYLEN)
+
+/*
+ * NIST SP 800-90 March 2007
+ * 10.2 DRBG Mechanism Based on Block Ciphers
+ *
+ * Table 3 specifies the reseed interval as
+ * <= 2^48. We use 2^32 so we can always be sure it'll fit in an int.
+ */
+#define NIST_CTR_DRBG_RESEED_INTERVAL (0xffffffffU)
+
+#endif /* NIST_CTR_DRBG_AES256_H */
diff --git a/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h
new file mode 100644
index 00000000000..9695001d11c
--- /dev/null
+++ b/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h
@@ -0,0 +1,72 @@
+/* $NetBSD: nist_ctr_drbg_config.h,v 1.1 2011/11/19 22:51:22 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2007 Henric Jungheim <software@henric.info>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * NIST SP 800-90 Configuration (Random Number Generator)
+ */
+
+#ifndef NIST_CTR_DRBG_CONFIG_H
+#define NIST_CTR_DRBG_CONFIG_H
+
+/*
+ * The test vectors will indicate failure if the
+ * byte ordering is set incorrectly.
+ * Pretending to be little endian will improve performance
+ * slightly but should not have an impact on
+ * security (a byte-swapped nonce is still a nonce).
+ */
+#define NIST_IS_LITTLE_ENDIAN 1
+
+/* Without NIST_ZEROIZE, we leave some intermediaries on the stack. */
+#define NIST_ZEROIZE 1
+
+#include <crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h>
+
+/* Use AES-128 as the block cipher */
+#include <crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h>
+
+#endif /* NIST_CTR_DRBG_CONFIG_H */
diff --git a/sys/crypto/rijndael/files.rijndael b/sys/crypto/rijndael/files.rijndael
index 82d0ae5946c..8ffbae8e2f3 100644
--- a/sys/crypto/rijndael/files.rijndael
+++ b/sys/crypto/rijndael/files.rijndael
@@ -1,7 +1,5 @@
-# $NetBSD: files.rijndael,v 1.5 2005/12/11 12:20:52 christos Exp $
+# $NetBSD: files.rijndael,v 1.6 2011/11/19 22:51:22 tls Exp $
-define rijndael
-
-file crypto/rijndael/rijndael-alg-fst.c rijndael
-file crypto/rijndael/rijndael-api-fst.c rijndael
-file crypto/rijndael/rijndael.c rijndael
+file crypto/rijndael/rijndael-alg-fst.c
+file crypto/rijndael/rijndael-api-fst.c
+file crypto/rijndael/rijndael.c
diff --git a/sys/dev/ata/wdvar.h b/sys/dev/ata/wdvar.h
index 1a89f05d8a8..fea02e9ffdd 100644
--- a/sys/dev/ata/wdvar.h
+++ b/sys/dev/ata/wdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wdvar.h,v 1.38 2009/12/17 21:03:10 bouyer Exp $ */
+/* $NetBSD: wdvar.h,v 1.39 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -67,7 +67,7 @@ struct wd_softc {
u_int sc_bscount;
#endif
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/gpib/rd.c b/sys/dev/gpib/rd.c
index 3bd348a0eed..069179d9b81 100644
--- a/sys/dev/gpib/rd.c
+++ b/sys/dev/gpib/rd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rd.c,v 1.28 2011/02/08 20:20:27 rmind Exp $ */
+/* $NetBSD: rd.c,v 1.29 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.28 2011/02/08 20:20:27 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rd.c,v 1.29 2011/11/19 22:51:22 tls Exp $");
#include "rnd.h"
@@ -143,7 +143,7 @@ struct rd_softc {
struct callout sc_restart_ch;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h
index 867be2ac84c..52e804dbe74 100644
--- a/sys/dev/ic/comvar.h
+++ b/sys/dev/ic/comvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: comvar.h,v 1.71 2010/11/13 15:35:50 uebayasi Exp $ */
+/* $NetBSD: comvar.h,v 1.72 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@@ -228,7 +228,7 @@ struct com_softc {
struct pps_state sc_pps_state; /* pps state */
#if NRND > 0 && defined(RND_COM)
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
kmutex_t sc_lock;
};
diff --git a/sys/dev/ic/cs89x0var.h b/sys/dev/ic/cs89x0var.h
index b1a740b7ce7..6d433d83530 100644
--- a/sys/dev/ic/cs89x0var.h
+++ b/sys/dev/ic/cs89x0var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: cs89x0var.h,v 1.14 2009/09/22 14:55:19 tsutsui Exp $ */
+/* $NetBSD: cs89x0var.h,v 1.15 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright 1997
@@ -105,7 +105,7 @@ struct cs_softc {
u_int16_t *eeprom_data; /* copy of the eeprom data */
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
/* power management */
diff --git a/sys/dev/ic/dp8390var.h b/sys/dev/ic/dp8390var.h
index ca927d5b6c8..daf23afd520 100644
--- a/sys/dev/ic/dp8390var.h
+++ b/sys/dev/ic/dp8390var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: dp8390var.h,v 1.30 2009/05/12 14:25:17 cegger Exp $ */
+/* $NetBSD: dp8390var.h,v 1.31 2011/11/19 22:51:22 tls Exp $ */
/*
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
@@ -72,7 +72,7 @@ struct dp8390_softc {
int sc_enabled; /* boolean; power enabled on interface */
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
int (*test_mem)(struct dp8390_softc *);
diff --git a/sys/dev/ic/elink3var.h b/sys/dev/ic/elink3var.h
index 226c7959254..bef646843f0 100644
--- a/sys/dev/ic/elink3var.h
+++ b/sys/dev/ic/elink3var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: elink3var.h,v 1.36 2009/09/05 12:30:59 tsutsui Exp $ */
+/* $NetBSD: elink3var.h,v 1.37 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 1994 Herb Peyerl <hpeyerl@beer.org>
@@ -102,7 +102,7 @@ struct ep_softc {
int ep_pktlenshift; /* scale factor for pkt lengths */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
/* power management hooks */
diff --git a/sys/dev/ic/elinkxlvar.h b/sys/dev/ic/elinkxlvar.h
index ed33fdfa396..b327dfa9302 100644
--- a/sys/dev/ic/elinkxlvar.h
+++ b/sys/dev/ic/elinkxlvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: elinkxlvar.h,v 1.22 2010/03/22 23:03:30 dyoung Exp $ */
+/* $NetBSD: elinkxlvar.h,v 1.23 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -110,7 +110,7 @@ struct ex_softc {
#define EX_FLAGS_ATTACHED 0x4000 /* attach has succeeded */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
/* power management hooks */
diff --git a/sys/dev/ic/gemvar.h b/sys/dev/ic/gemvar.h
index bfef0f25da0..cdf5b5b1406 100644
--- a/sys/dev/ic/gemvar.h
+++ b/sys/dev/ic/gemvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: gemvar.h,v 1.21 2010/02/24 22:37:58 dyoung Exp $ */
+/* $NetBSD: gemvar.h,v 1.22 2011/11/19 22:51:22 tls Exp $ */
/*
*
@@ -217,7 +217,7 @@ struct gem_softc {
void (*sc_hwinit)(struct gem_softc *);
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
struct evcnt sc_ev_intr;
diff --git a/sys/dev/ic/hmevar.h b/sys/dev/ic/hmevar.h
index 32fb983f100..ed24b11d4f1 100644
--- a/sys/dev/ic/hmevar.h
+++ b/sys/dev/ic/hmevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hmevar.h,v 1.21 2009/09/18 12:40:15 tsutsui Exp $ */
+/* $NetBSD: hmevar.h,v 1.22 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -95,7 +95,7 @@ struct hme_softc {
void (*sc_hwinit)(struct hme_softc *);
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ic/i82557var.h b/sys/dev/ic/i82557var.h
index 4d9be3ba861..792913ef555 100644
--- a/sys/dev/ic/i82557var.h
+++ b/sys/dev/ic/i82557var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: i82557var.h,v 1.48 2010/02/25 23:40:39 dyoung Exp $ */
+/* $NetBSD: i82557var.h,v 1.49 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999, 2001 The NetBSD Foundation, Inc.
@@ -242,7 +242,7 @@ struct fxp_softc {
int sc_eeprom_size; /* log2 size of EEPROM */
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
};
diff --git a/sys/dev/ic/lan9118var.h b/sys/dev/ic/lan9118var.h
index 2cb8bb61227..7a4fc836550 100644
--- a/sys/dev/ic/lan9118var.h
+++ b/sys/dev/ic/lan9118var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lan9118var.h,v 1.2 2009/11/28 08:44:00 kiyohara Exp $ */
+/* $NetBSD: lan9118var.h,v 1.3 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 2008 KIYOHARA Takashi
* All rights reserved.
@@ -76,7 +76,7 @@ struct lan9118_softc {
#define LAN9118_FLAGS_NO_EEPROM 0x00000002
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ic/lancevar.h b/sys/dev/ic/lancevar.h
index 482adbab542..ed8d5a53b5d 100644
--- a/sys/dev/ic/lancevar.h
+++ b/sys/dev/ic/lancevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lancevar.h,v 1.13 2009/09/04 16:21:24 tsutsui Exp $ */
+/* $NetBSD: lancevar.h,v 1.14 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -116,7 +116,7 @@ struct lance_softc {
uint8_t sc_enaddr[ETHER_ADDR_LEN];
uint8_t sc_pad[2];
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
void (*sc_meminit)(struct lance_softc *);
diff --git a/sys/dev/ic/lemacvar.h b/sys/dev/ic/lemacvar.h
index 0300026c5c1..6b1cf6c5e7d 100644
--- a/sys/dev/ic/lemacvar.h
+++ b/sys/dev/ic/lemacvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lemacvar.h,v 1.9 2005/12/11 12:21:27 christos Exp $ */
+/* $NetBSD: lemacvar.h,v 1.10 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 1997 Matt Thomas <matt@3am-software.com>
@@ -80,7 +80,7 @@ typedef struct {
char sc_prodname[LEMAC_EEP_PRDNMSZ+1]; /* product name DE20x-xx */
u_int8_t sc_eeprom[LEMAC_EEP_SIZE]; /* local copy eeprom */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
} lemac_softc_t;
diff --git a/sys/dev/ic/mb86950var.h b/sys/dev/ic/mb86950var.h
index 01242496bb4..b4e2aafbb4c 100644
--- a/sys/dev/ic/mb86950var.h
+++ b/sys/dev/ic/mb86950var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: mb86950var.h,v 1.5 2009/05/12 14:25:17 cegger Exp $ */
+/* $NetBSD: mb86950var.h,v 1.6 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 1995 Mika Kortelainen
@@ -60,7 +60,7 @@ struct mb86950_softc {
u_int8_t sc_enaddr[ETHER_ADDR_LEN];
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
u_int32_t sc_stat; /* driver status */
diff --git a/sys/dev/ic/mb86960var.h b/sys/dev/ic/mb86960var.h
index 45468ec3ccc..dc703308ebf 100644
--- a/sys/dev/ic/mb86960var.h
+++ b/sys/dev/ic/mb86960var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: mb86960var.h,v 1.37 2009/05/12 14:25:17 cegger Exp $ */
+/* $NetBSD: mb86960var.h,v 1.38 2011/11/19 22:51:22 tls Exp $ */
/*
* All Rights Reserved, Copyright (C) Fujitsu Limited 1995
@@ -162,7 +162,7 @@ struct mb86960_softc {
uint8_t sc_enaddr[ETHER_ADDR_LEN];
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
uint32_t sc_stat; /* driver status */
diff --git a/sys/dev/ic/mtd803var.h b/sys/dev/ic/mtd803var.h
index 0ab54c4fb13..bb4f95f7c51 100644
--- a/sys/dev/ic/mtd803var.h
+++ b/sys/dev/ic/mtd803var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: mtd803var.h,v 1.6 2008/04/28 20:23:50 martin Exp $ */
+/* $NetBSD: mtd803var.h,v 1.7 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@ struct mtd_softc {
bus_dmamap_t buf_dma_map;
#if NRND > 0
- rndsource_element_t rnd_src;
+ krndsource_t rnd_src;
#endif
};
diff --git a/sys/dev/ic/pckbc.c b/sys/dev/ic/pckbc.c
index 5795126a308..ca567b5b144 100644
--- a/sys/dev/ic/pckbc.c
+++ b/sys/dev/ic/pckbc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pckbc.c,v 1.51 2010/08/08 09:33:05 isaki Exp $ */
+/* $NetBSD: pckbc.c,v 1.52 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 2004 Ben Harris.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pckbc.c,v 1.51 2010/08/08 09:33:05 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pckbc.c,v 1.52 2011/11/19 22:51:22 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -59,7 +59,7 @@ struct pckbc_slotdata {
int poll_data; /* data read from inr handler if polling */
int poll_stat; /* status read from inr handler if polling */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ic/rtl81x9var.h b/sys/dev/ic/rtl81x9var.h
index e944695471c..467a049b232 100644
--- a/sys/dev/ic/rtl81x9var.h
+++ b/sys/dev/ic/rtl81x9var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rtl81x9var.h,v 1.50 2010/07/27 21:02:00 jakllsch Exp $ */
+/* $NetBSD: rtl81x9var.h,v 1.51 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 1997, 1998
@@ -226,7 +226,7 @@ struct rtk_softc {
int (*sc_enable) (struct rtk_softc *);
void (*sc_disable) (struct rtk_softc *);
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ic/seeq8005var.h b/sys/dev/ic/seeq8005var.h
index e0d7c3b9234..3585f92117b 100644
--- a/sys/dev/ic/seeq8005var.h
+++ b/sys/dev/ic/seeq8005var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: seeq8005var.h,v 1.5 2001/11/07 20:01:58 bjh21 Exp $ */
+/* $NetBSD: seeq8005var.h,v 1.6 2011/11/19 22:51:22 tls Exp $ */
/*
* Copyright (c) 2000 Ben Harris
@@ -86,7 +86,7 @@ struct seeq8005_softc {
int sc_flags;
#define SF_8BIT 0x01
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ic/smc91cxxvar.h b/sys/dev/ic/smc91cxxvar.h
index 4c9c1052298..fb5a1b8b8ad 100644
--- a/sys/dev/ic/smc91cxxvar.h
+++ b/sys/dev/ic/smc91cxxvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: smc91cxxvar.h,v 1.16 2009/05/12 14:25:18 cegger Exp $ */
+/* $NetBSD: smc91cxxvar.h,v 1.17 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@ struct smc91cxx_softc {
uint8_t sc_intmask;
uint8_t sc_txpacketno; /* cached packetno */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ic/tulipvar.h b/sys/dev/ic/tulipvar.h
index c74264a03d0..72e2e6b2363 100644
--- a/sys/dev/ic/tulipvar.h
+++ b/sys/dev/ic/tulipvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: tulipvar.h,v 1.65 2011/07/09 23:18:05 christos Exp $ */
+/* $NetBSD: tulipvar.h,v 1.66 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
@@ -448,7 +448,7 @@ struct tulip_softc {
int sc_rxptr; /* next ready RX descriptor/descsoft */
#if NRND > 0
- rndsource_element_t sc_rnd_source; /* random source */
+ krndsource_t sc_rnd_source; /* random source */
#endif
};
#endif
diff --git a/sys/dev/isa/fdvar.h b/sys/dev/isa/fdvar.h
index 9ff1204d2f4..eb35a97b631 100644
--- a/sys/dev/isa/fdvar.h
+++ b/sys/dev/isa/fdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: fdvar.h,v 1.6 2008/04/28 20:23:52 martin Exp $ */
+/* $NetBSD: fdvar.h,v 1.7 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -91,6 +91,6 @@ struct fd_softc {
int sc_active; /* number of active I/O operations */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/isa/if_eg.c b/sys/dev/isa/if_eg.c
index b4fe0a2207e..4f0a6455310 100644
--- a/sys/dev/isa/if_eg.c
+++ b/sys/dev/isa/if_eg.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_eg.c,v 1.82 2010/04/05 07:20:24 joerg Exp $ */
+/* $NetBSD: if_eg.c,v 1.83 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 1993 Dean Huxley <dean@fsa.ca>
@@ -40,7 +40,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_eg.c,v 1.82 2010/04/05 07:20:24 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_eg.c,v 1.83 2011/11/19 22:51:23 tls Exp $");
#include "opt_inet.h"
#include "rnd.h"
@@ -114,7 +114,7 @@ struct eg_softc {
void * eg_outbuf; /* Outgoing packet buffer */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/isa/if_el.c b/sys/dev/isa/if_el.c
index 9ea4e8c51ce..beb042d365b 100644
--- a/sys/dev/isa/if_el.c
+++ b/sys/dev/isa/if_el.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_el.c,v 1.86 2010/04/05 07:20:24 joerg Exp $ */
+/* $NetBSD: if_el.c,v 1.87 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 1994, Matthew E. Kimmel. Permission is hereby granted
@@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_el.c,v 1.86 2010/04/05 07:20:24 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_el.c,v 1.87 2011/11/19 22:51:23 tls Exp $");
#include "opt_inet.h"
#include "rnd.h"
@@ -80,7 +80,7 @@ struct el_softc {
bus_space_handle_t sc_ioh; /* i/o handle */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/isa/if_iy.c b/sys/dev/isa/if_iy.c
index fed9a014d44..37d4c0cf873 100644
--- a/sys/dev/isa/if_iy.c
+++ b/sys/dev/isa/if_iy.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_iy.c,v 1.88 2010/04/05 07:20:24 joerg Exp $ */
+/* $NetBSD: if_iy.c,v 1.89 2011/11/19 22:51:23 tls Exp $ */
/* #define IYDEBUG */
/* #define IYMEMDEBUG */
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iy.c,v 1.88 2010/04/05 07:20:24 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iy.c,v 1.89 2011/11/19 22:51:23 tls Exp $");
#include "opt_inet.h"
#include "rnd.h"
@@ -129,7 +129,7 @@ struct iy_softc {
#endif
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/ldvar.h b/sys/dev/ldvar.h
index e8913f0e949..dccadae861b 100644
--- a/sys/dev/ldvar.h
+++ b/sys/dev/ldvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: ldvar.h,v 1.18 2010/09/20 06:54:06 kiyohara Exp $ */
+/* $NetBSD: ldvar.h,v 1.19 2011/11/19 22:51:22 tls Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@ struct ld_softc {
struct bufq_state *sc_bufq;
kmutex_t sc_mutex;
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
int sc_queuecnt; /* current h/w queue depth */
int sc_ncylinders; /* # cylinders */
diff --git a/sys/dev/marvell/if_gfevar.h b/sys/dev/marvell/if_gfevar.h
index db0f2065d7e..f3e1478515e 100644
--- a/sys/dev/marvell/if_gfevar.h
+++ b/sys/dev/marvell/if_gfevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_gfevar.h,v 1.10 2010/04/28 13:51:56 kiyohara Exp $ */
+/* $NetBSD: if_gfevar.h,v 1.11 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
@@ -168,7 +168,7 @@ struct gfe_softc {
struct gfe_rxqueue sc_rxq[4]; /* Hi/MedHi/MedLo/Lo receive queues */
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
};
#endif /* _IF_GFEVAR_H_ */
diff --git a/sys/dev/marvell/if_mvgbe.c b/sys/dev/marvell/if_mvgbe.c
index 2bb2a640237..0679be5661d 100644
--- a/sys/dev/marvell/if_mvgbe.c
+++ b/sys/dev/marvell/if_mvgbe.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_mvgbe.c,v 1.14 2011/11/19 17:01:38 jakllsch Exp $ */
+/* $NetBSD: if_mvgbe.c,v 1.15 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2007, 2008 KIYOHARA Takashi
* All rights reserved.
@@ -25,7 +25,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.14 2011/11/19 17:01:38 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mvgbe.c,v 1.15 2011/11/19 22:51:23 tls Exp $");
#include "rnd.h"
@@ -216,7 +216,7 @@ struct mvgbe_softc {
SIMPLEQ_HEAD(__mvgbe_txmaphead, mvgbe_txmap_entry) sc_txmap_head;
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
};
diff --git a/sys/dev/mca/edvar.h b/sys/dev/mca/edvar.h
index 8cf6ef1fe0b..b7262dfb13f 100644
--- a/sys/dev/mca/edvar.h
+++ b/sys/dev/mca/edvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: edvar.h,v 1.13 2008/05/04 13:11:14 martin Exp $ */
+/* $NetBSD: edvar.h,v 1.14 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -61,6 +61,6 @@ struct ed_softc {
u_int32_t rba; /* # of RBAs */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/pci/amdpmvar.h b/sys/dev/pci/amdpmvar.h
index af186f22355..25fc789770e 100644
--- a/sys/dev/pci/amdpmvar.h
+++ b/sys/dev/pci/amdpmvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: amdpmvar.h,v 1.6 2008/04/28 20:23:54 martin Exp $ */
+/* $NetBSD: amdpmvar.h,v 1.7 2011/11/19 22:51:23 tls Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@@ -52,7 +52,7 @@ struct amdpm_softc {
void *sc_ih;
struct callout sc_rnd_ch;
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#ifdef AMDPM_RND_COUNTERS
struct evcnt sc_rnd_hits;
struct evcnt sc_rnd_miss;
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c
index 9cd187bddac..4cdd258bfd9 100644
--- a/sys/dev/pci/hifn7751.c
+++ b/sys/dev/pci/hifn7751.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hifn7751.c,v 1.46 2010/11/13 13:52:05 uebayasi Exp $ */
+/* $NetBSD: hifn7751.c,v 1.47 2011/11/19 22:51:23 tls Exp $ */
/* $FreeBSD: hifn7751.c,v 1.5.2.7 2003/10/08 23:52:00 sam Exp $ */
/* $OpenBSD: hifn7751.c,v 1.140 2003/08/01 17:55:54 deraadt Exp $ */
@@ -48,14 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.46 2010/11/13 13:52:05 uebayasi Exp $");
-
-#include "rnd.h"
-
-#if NRND == 0
-#error hifn7751 requires rnd pseudo-devices
-#endif
-
+__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.47 2011/11/19 22:51:23 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -71,7 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.46 2010/11/13 13:52:05 uebayasi Exp $
#include <dev/rndvar.h>
#else
#include <opencrypto/cryptodev.h>
-#include <sys/rnd.h>
+#include <sys/cprng.h>
#endif
#include <dev/pci/pcireg.h>
@@ -2077,7 +2070,7 @@ hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
to generate IVs has been FIPS140-2
certified by several labs. */
#ifdef __NetBSD__
- arc4randbytes(sc->sc_sessions[i].hs_iv,
+ cprng_fast(sc->sc_sessions[i].hs_iv,
c->cri_alg == CRYPTO_AES_CBC ?
HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
#else /* FreeBSD and OpenBSD have get_random_bytes */
diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h
index d3ed8ede489..edfa62a112d 100644
--- a/sys/dev/pci/hifn7751var.h
+++ b/sys/dev/pci/hifn7751var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hifn7751var.h,v 1.7 2005/12/11 12:22:49 christos Exp $ */
+/* $NetBSD: hifn7751var.h,v 1.8 2011/11/19 22:51:23 tls Exp $ */
/* $OpenBSD: hifn7751var.h,v 1.18 2000/06/02 22:36:45 deraadt Exp $ */
/*
@@ -168,7 +168,7 @@ struct hifn_softc {
struct callout sc_rngto; /* rng timeout */
struct callout sc_tickto; /* led-clear timeout */
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
int sc_rngfirst;
int sc_rnghz;
int sc_c_busy; /* command ring busy */
diff --git a/sys/dev/pci/if_bce.c b/sys/dev/pci/if_bce.c
index b492e23bb88..ff3b7dd5ccd 100644
--- a/sys/dev/pci/if_bce.c
+++ b/sys/dev/pci/if_bce.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bce.c,v 1.33 2010/11/13 13:52:05 uebayasi Exp $ */
+/* $NetBSD: if_bce.c,v 1.34 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2003 Clifford Wright. All rights reserved.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bce.c,v 1.33 2010/11/13 13:52:05 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bce.c,v 1.34 2011/11/19 22:51:23 tls Exp $");
#include "vlan.h"
#include "rnd.h"
@@ -139,7 +139,7 @@ struct bce_softc {
int bce_txsnext; /* next available tx slot */
callout_t bce_timeout;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/pci/if_bgevar.h b/sys/dev/pci/if_bgevar.h
index a87d92aefa3..db681571ea6 100644
--- a/sys/dev/pci/if_bgevar.h
+++ b/sys/dev/pci/if_bgevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bgevar.h,v 1.7 2011/05/18 01:02:43 dyoung Exp $ */
+/* $NetBSD: if_bgevar.h,v 1.8 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2001 Wind River Systems
* Copyright (c) 1997, 1998, 1999, 2001
@@ -290,7 +290,7 @@ struct bge_softc {
struct sysctllog *bge_log;
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
};
diff --git a/sys/dev/pci/if_casvar.h b/sys/dev/pci/if_casvar.h
index 4d4c5b3b912..04ed095caaf 100644
--- a/sys/dev/pci/if_casvar.h
+++ b/sys/dev/pci/if_casvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_casvar.h,v 1.2 2010/01/18 18:09:22 jdc Exp $ */
+/* $NetBSD: if_casvar.h,v 1.3 2011/11/19 22:51:23 tls Exp $ */
/* $OpenBSD: if_casvar.h,v 1.6 2009/06/13 12:18:58 kettenis Exp $ */
/*
@@ -195,7 +195,7 @@ struct cas_softc {
void *sc_sh; /* shutdownhook cookie */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
struct evcnt sc_ev_intr;
diff --git a/sys/dev/pci/if_devar.h b/sys/dev/pci/if_devar.h
index 9c85d36cbf5..ae292477be3 100644
--- a/sys/dev/pci/if_devar.h
+++ b/sys/dev/pci/if_devar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_devar.h,v 1.55 2010/04/05 07:20:25 joerg Exp $ */
+/* $NetBSD: if_devar.h,v 1.56 2011/11/19 22:51:23 tls Exp $ */
/*-
* Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
@@ -695,7 +695,7 @@ struct _tulip_softc_t {
tulip_desc_t *tulip_rxdescs;
tulip_desc_t *tulip_txdescs;
#if defined(__NetBSD__) && NRND > 0
- rndsource_element_t tulip_rndsource;
+ krndsource_t tulip_rndsource;
#endif
};
diff --git a/sys/dev/pci/if_dge.c b/sys/dev/pci/if_dge.c
index 0a869b9618b..b269af890c2 100644
--- a/sys/dev/pci/if_dge.c
+++ b/sys/dev/pci/if_dge.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_dge.c,v 1.31 2010/11/13 13:52:06 uebayasi Exp $ */
+/* $NetBSD: if_dge.c,v 1.32 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2004, SUNET, Swedish University Computer Network.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_dge.c,v 1.31 2010/11/13 13:52:06 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_dge.c,v 1.32 2011/11/19 22:51:23 tls Exp $");
#include "rnd.h"
@@ -334,7 +334,7 @@ struct dge_softc {
uint16_t sc_eeprom[EEPROM_SIZE];
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
#ifdef DGE_OFFBYONE_RXBUG
void *sc_bugbuf;
diff --git a/sys/dev/pci/if_iwi.c b/sys/dev/pci/if_iwi.c
index 64e73687878..b5b74307f10 100644
--- a/sys/dev/pci/if_iwi.c
+++ b/sys/dev/pci/if_iwi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_iwi.c,v 1.87 2011/05/23 15:37:36 drochner Exp $ */
+/* $NetBSD: if_iwi.c,v 1.88 2011/11/19 22:51:23 tls Exp $ */
/* $OpenBSD: if_iwi.c,v 1.111 2010/11/15 19:11:57 damien Exp $ */
/*-
@@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.87 2011/05/23 15:37:36 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.88 2011/11/19 22:51:23 tls Exp $");
/*-
* Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_iwi.c,v 1.87 2011/05/23 15:37:36 drochner Exp $")
#include <sys/conf.h>
#include <sys/kauth.h>
#include <sys/proc.h>
+#include <sys/cprng.h>
#include <sys/bus.h>
#include <machine/endian.h>
@@ -2386,7 +2387,8 @@ iwi_config(struct iwi_softc *sc)
return error;
}
- data = htole32(arc4random());
+ cprng_fast(&data, sizeof(data));
+ data = htole32(data);
DPRINTF(("Setting initialization vector to %u\n", le32toh(data)));
error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data, 0);
if (error != 0)
diff --git a/sys/dev/pci/if_jme.c b/sys/dev/pci/if_jme.c
index 05d10bd64a8..153327c5a91 100644
--- a/sys/dev/pci/if_jme.c
+++ b/sys/dev/pci/if_jme.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_jme.c,v 1.17 2011/03/30 18:11:37 bouyer Exp $ */
+/* $NetBSD: if_jme.c,v 1.18 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2008 Manuel Bouyer. All rights reserved.
@@ -58,7 +58,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.17 2011/03/30 18:11:37 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_jme.c,v 1.18 2011/11/19 22:51:23 tls Exp $");
#include <sys/param.h>
@@ -168,7 +168,7 @@ struct jme_softc {
uint32_t jme_txcsr; /* TX config register */
uint32_t jme_rxcsr; /* RX config register */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
/* interrupt coalition parameters */
struct sysctllog *jme_clog;
diff --git a/sys/dev/pci/if_mskvar.h b/sys/dev/pci/if_mskvar.h
index 1fb3299e7d9..01ac7e2df75 100644
--- a/sys/dev/pci/if_mskvar.h
+++ b/sys/dev/pci/if_mskvar.h
@@ -1,5 +1,5 @@
/* $OpenBSD: if_mskvar.h,v 1.3 2006/12/28 16:34:42 kettenis Exp $ */
-/* $NetBSD: if_mskvar.h,v 1.8 2009/12/24 18:27:32 christos Exp $ */
+/* $NetBSD: if_mskvar.h,v 1.9 2011/11/19 22:51:23 tls Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -210,7 +210,7 @@ struct sk_softc {
int sk_status_idx;
int sk_status_own_idx;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/pci/if_pcn.c b/sys/dev/pci/if_pcn.c
index 15035e4ee84..d49408332ef 100644
--- a/sys/dev/pci/if_pcn.c
+++ b/sys/dev/pci/if_pcn.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_pcn.c,v 1.52 2010/11/13 13:52:06 uebayasi Exp $ */
+/* $NetBSD: if_pcn.c,v 1.53 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pcn.c,v 1.52 2010/11/13 13:52:06 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pcn.c,v 1.53 2011/11/19 22:51:23 tls Exp $");
#include "rnd.h"
@@ -313,7 +313,7 @@ struct pcn_softc {
uint32_t sc_mode; /* prototype MODE register */
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
};
diff --git a/sys/dev/pci/if_sip.c b/sys/dev/pci/if_sip.c
index bcf9e4282a9..eb9c8293561 100644
--- a/sys/dev/pci/if_sip.c
+++ b/sys/dev/pci/if_sip.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_sip.c,v 1.150 2011/10/15 19:50:20 dholland Exp $ */
+/* $NetBSD: if_sip.c,v 1.151 2011/11/19 22:51:23 tls Exp $ */
/*-
* Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.150 2011/10/15 19:50:20 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_sip.c,v 1.151 2011/11/19 22:51:23 tls Exp $");
#include "rnd.h"
@@ -355,7 +355,7 @@ struct sip_softc {
void (*sc_rxintr)(struct sip_softc *);
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
};
diff --git a/sys/dev/pci/if_skvar.h b/sys/dev/pci/if_skvar.h
index d66022ccd4b..79b3479f900 100644
--- a/sys/dev/pci/if_skvar.h
+++ b/sys/dev/pci/if_skvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_skvar.h,v 1.15 2008/09/08 21:20:03 christos Exp $ */
+/* $NetBSD: if_skvar.h,v 1.16 2011/11/19 22:51:23 tls Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -205,7 +205,7 @@ struct sk_softc {
bus_dma_tag_t sc_dmatag;
struct sk_if_softc *sk_if[2];
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/pci/if_tlvar.h b/sys/dev/pci/if_tlvar.h
index fc254659442..ad34eda5450 100644
--- a/sys/dev/pci/if_tlvar.h
+++ b/sys/dev/pci/if_tlvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_tlvar.h,v 1.14 2009/10/19 18:41:15 bouyer Exp $ */
+/* $NetBSD: if_tlvar.h,v 1.15 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
@@ -85,7 +85,7 @@ struct tl_softc {
int oerr_mcopy;
#endif
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
#define tl_if tl_ec.ec_if
diff --git a/sys/dev/pci/if_vr.c b/sys/dev/pci/if_vr.c
index badd3839c19..95bb018d4f5 100644
--- a/sys/dev/pci/if_vr.c
+++ b/sys/dev/pci/if_vr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vr.c,v 1.107 2010/12/16 17:07:44 jakllsch Exp $ */
+/* $NetBSD: if_vr.c,v 1.108 2011/11/19 22:51:23 tls Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.107 2010/12/16 17:07:44 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_vr.c,v 1.108 2011/11/19 22:51:23 tls Exp $");
#include "rnd.h"
@@ -234,7 +234,7 @@ struct vr_softc {
uint32_t vr_save_irq;
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
};
diff --git a/sys/dev/pci/if_vtevar.h b/sys/dev/pci/if_vtevar.h
index 3b7d3aaaa82..9abc8928ee5 100644
--- a/sys/dev/pci/if_vtevar.h
+++ b/sys/dev/pci/if_vtevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_vtevar.h,v 1.1 2011/01/26 18:48:13 bouyer Exp $ */
+/* $NetBSD: if_vtevar.h,v 1.2 2011/11/19 22:51:23 tls Exp $ */
/*-
* Copyright (c) 2010, Pyun YongHyeon <yongari@FreeBSD.org>
@@ -139,7 +139,7 @@ struct vte_softc {
int vte_int_tx_mod;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/pci/if_wm.c b/sys/dev/pci/if_wm.c
index 4919c455444..97ff118eef6 100644
--- a/sys/dev/pci/if_wm.c
+++ b/sys/dev/pci/if_wm.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.223 2011/07/01 07:45:39 matt Exp $ */
+/* $NetBSD: if_wm.c,v 1.224 2011/11/19 22:51:23 tls Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.223 2011/07/01 07:45:39 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.224 2011/11/19 22:51:23 tls Exp $");
#include "rnd.h"
@@ -379,7 +379,7 @@ struct wm_softc {
int sc_mchash_type; /* multicast filter offset */
#if NRND > 0
- rndsource_element_t rnd_source; /* random source */
+ krndsource_t rnd_source; /* random source */
#endif
};
diff --git a/sys/dev/pci/ixgbe/ixgbe.c b/sys/dev/pci/ixgbe/ixgbe.c
index 7a05c96d8e7..475047aa3ec 100644
--- a/sys/dev/pci/ixgbe/ixgbe.c
+++ b/sys/dev/pci/ixgbe/ixgbe.c
@@ -59,7 +59,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/*$FreeBSD: src/sys/dev/ixgbe/ixgbe.c,v 1.51 2011/04/25 23:34:21 jfv Exp $*/
-/*$NetBSD: ixgbe.c,v 1.1 2011/08/12 21:55:29 dyoung Exp $*/
+/*$NetBSD: ixgbe.c,v 1.2 2011/11/19 22:51:24 tls Exp $*/
#include "opt_inet.h"
@@ -4160,7 +4160,7 @@ ixgbe_initialize_receive_units(struct adapter *adapter)
reta = 0;
/* set up random bits */
- arc4randbytes(&r, sizeof(r));
+ cprng_fast(&r, sizeof(r));
/* Set up the redirection table */
for (i = 0, j = 0; i < 128; i++, j++) {
diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c
index 69edacd7c39..28755e95d1d 100644
--- a/sys/dev/pci/ubsec.c
+++ b/sys/dev/pci/ubsec.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ubsec.c,v 1.25 2010/11/13 13:52:09 uebayasi Exp $ */
+/* $NetBSD: ubsec.c,v 1.26 2011/11/19 22:51:24 tls Exp $ */
/* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */
/* $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $ */
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.25 2010/11/13 13:52:09 uebayasi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.26 2011/11/19 22:51:24 tls Exp $");
#undef UBSEC_DEBUG
@@ -65,7 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.25 2010/11/13 13:52:09 uebayasi Exp $");
#include <dev/rndvar.h>
#include <sys/md5k.h>
#else
- #include <sys/rnd.h>
+ #include <sys/cprng.h>
#include <sys/md5.h>
#endif
#include <sys/sha1.h>
@@ -808,8 +808,7 @@ ubsec_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
if (encini) {
/* get an IV, network byte order */
#ifdef __NetBSD__
- rnd_extract_data(ses->ses_iv,
- sizeof(ses->ses_iv), RND_EXTRACT_ANY);
+ cprng_fast(ses->ses_iv, sizeof(ses->ses_iv));
#else
get_random_bytes(ses->ses_iv, sizeof(ses->ses_iv));
#endif
diff --git a/sys/dev/pcmcia/if_xivar.h b/sys/dev/pcmcia/if_xivar.h
index 8a5c458cd45..2b493881546 100644
--- a/sys/dev/pcmcia/if_xivar.h
+++ b/sys/dev/pcmcia/if_xivar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_xivar.h,v 1.6 2009/12/06 23:05:39 dyoung Exp $ */
+/* $NetBSD: if_xivar.h,v 1.7 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 2004 Charles M. Hannum. All rights reserved.
@@ -45,7 +45,7 @@ struct xi_softc {
u_int8_t sc_rev; /* Chip revision */
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
};
diff --git a/sys/dev/rnd.c b/sys/dev/rnd.c
index 0f0960a6e16..54445b4c676 100644
--- a/sys/dev/rnd.c
+++ b/sys/dev/rnd.c
@@ -1,12 +1,13 @@
-/* $NetBSD: rnd.c,v 1.82 2011/10/11 23:55:30 yamt Exp $ */
+/* $NetBSD: rnd.c,v 1.83 2011/11/19 22:51:22 tls Exp $ */
/*-
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
- * by Michael Graff <explorer@flame.org>. This code uses ideas and
- * algorithms from the Linux driver written by Ted Ts'o.
+ * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon.
+ * This code uses ideas and algorithms from the Linux driver written by
+ * Ted Ts'o.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.82 2011/10/11 23:55:30 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.83 2011/11/19 22:51:22 tls Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -50,6 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.82 2011/10/11 23:55:30 yamt Exp $");
#include <sys/pool.h>
#include <sys/kauth.h>
#include <sys/once.h>
+#include <sys/rngtest.h>
#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */
#include <machine/cpu_counter.h>
@@ -89,7 +91,7 @@ int rnd_debug = 0;
#define RND_SAMPLE_COUNT 64 /* collect N samples, then compress */
typedef struct _rnd_sample_t {
SIMPLEQ_ENTRY(_rnd_sample_t) next;
- rndsource_t *source;
+ krndsource_t *source;
int cursor;
int entropy;
u_int32_t ts[RND_SAMPLE_COUNT];
@@ -105,6 +107,14 @@ SIMPLEQ_HEAD(, _rnd_sample_t) rnd_samples;
kmutex_t rnd_mtx;
/*
+ * Entropy sinks: usually other generators waiting to be rekeyed.
+ *
+ * A sink's callback MUST NOT re-add the sink to the list, or
+ * list corruption will occur.
+ */
+TAILQ_HEAD(, rndsink) rnd_sinks;
+
+/*
* our select/poll queue
*/
struct selinfo rnd_selq;
@@ -130,12 +140,18 @@ kcondvar_t rndpool_cv;
* This source is used to easily "remove" queue entries when the source
* which actually generated the events is going away.
*/
-static rndsource_t rnd_source_no_collect = {
- { 'N', 'o', 'C', 'o', 'l', 'l', 'e', 'c', 't', 0, 0, 0, 0, 0, 0, 0 },
- 0, 0, 0, 0,
- RND_TYPE_UNKNOWN,
- (RND_FLAG_NO_COLLECT | RND_FLAG_NO_ESTIMATE | RND_TYPE_UNKNOWN),
- NULL
+static krndsource_t rnd_source_no_collect = {
+ /* LIST_ENTRY list */
+ .name = { 'N', 'o', 'C', 'o', 'l', 'l', 'e', 'c', 't',
+ 0, 0, 0, 0, 0, 0, 0 },
+ .last_time = 0, .last_delta = 0, .last_delta2 = 0, .total = 0,
+ .type = RND_TYPE_UNKNOWN,
+ .flags = (RND_FLAG_NO_COLLECT |
+ RND_FLAG_NO_ESTIMATE |
+ RND_TYPE_UNKNOWN),
+ .state = NULL,
+ .test_cnt = 0,
+ .test = NULL
};
struct callout rnd_callout;
@@ -155,15 +171,17 @@ const struct cdevsw rnd_cdevsw = {
};
static inline void rnd_wakeup_readers(void);
-static inline u_int32_t rnd_estimate_entropy(rndsource_t *, u_int32_t);
+static inline u_int32_t rnd_estimate_entropy(krndsource_t *, u_int32_t);
static inline u_int32_t rnd_counter(void);
static void rnd_timeout(void *);
+static void rnd_process_events(void *);
static u_int32_t rnd_extract_data_locked(void *, u_int32_t, u_int32_t);
static int rnd_ready = 0;
static int rnd_have_entropy = 0;
+static int rnd_tested = 0;
-LIST_HEAD(, __rndsource_element) rnd_sources;
+LIST_HEAD(, krndsource) rnd_sources;
/*
* Generate a 32-bit counter. This should be more machine dependent,
@@ -192,24 +210,67 @@ rnd_counter(void)
static inline void
rnd_wakeup_readers(void)
{
+ rndsink_t *sink, *tsink;
+ TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk);
+ mutex_spin_enter(&rndpool_mtx);
+ if (rndpool_get_entropy_count(&rnd_pool) < RND_ENTROPY_THRESHOLD * 8) {
+ mutex_spin_exit(&rndpool_mtx);
+ return;
+ }
+
+ /*
+ * First, take care of in-kernel consumers needing rekeying.
+ */
+ TAILQ_FOREACH_SAFE(sink, &rnd_sinks, tailq, tsink) {
+ if ((sink->len + RND_ENTROPY_THRESHOLD) * 8 <
+ rndpool_get_entropy_count(&rnd_pool)) {
+ /* We have enough entropy to sink some here. */
+ if (rndpool_extract_data(&rnd_pool, sink->data,
+ sink->len, RND_EXTRACT_GOOD)
+ != sink->len) {
+ panic("could not extract estimated "
+ "entropy from pool");
+ }
+ /* Move this sink to the list of pending callbacks */
+ TAILQ_REMOVE(&rnd_sinks, sink, tailq);
+ TAILQ_INSERT_HEAD(&sunk, sink, tailq);
+ }
+ }
+
/*
- * If we have added new bits, and now have enough to do something,
- * wake up sleeping readers.
+ * If we still have enough new bits to do something, feed userspace.
*/
- mutex_enter(&rndpool_mtx);
if (rndpool_get_entropy_count(&rnd_pool) > RND_ENTROPY_THRESHOLD * 8) {
- cv_broadcast(&rndpool_cv);
- selnotify(&rnd_selq, 0, 0);
-
#ifdef RND_VERBOSE
if (!rnd_have_entropy)
printf("rnd: have initial entropy (%u)\n",
rndpool_get_entropy_count(&rnd_pool));
#endif
rnd_have_entropy = 1;
+ cv_broadcast(&rndpool_cv);
+ mutex_spin_exit(&rndpool_mtx);
+ selnotify(&rnd_selq, 0, 0);
+ } else {
+ mutex_spin_exit(&rndpool_mtx);
+ }
+
+ /*
+ * Now that we have dropped the mutex, we can run sinks' callbacks.
+ * Since we have reused the "tailq" member of the sink structure for
+ * this temporary on-stack queue, the callback must NEVER re-add
+ * the sink to the main queue, or our on-stack queue will become
+ * corrupt.
+ */
+ while ((sink = TAILQ_FIRST(&sunk))) {
+#ifdef RND_VERBOSE
+ printf("supplying %d bytes to entropy sink \"%s\""
+ " (cb %p, arg %p).\n",
+ (int)sink->len, sink->name, sink->cb, sink->arg);
+#endif
+ sink->cb(sink->arg);
+ TAILQ_REMOVE(&sunk, sink, tailq);
}
- mutex_exit(&rndpool_mtx);
}
/*
@@ -218,7 +279,7 @@ rnd_wakeup_readers(void)
* non-zero. If any of these are zero, return zero.
*/
static inline u_int32_t
-rnd_estimate_entropy(rndsource_t *rs, u_int32_t t)
+rnd_estimate_entropy(krndsource_t *rs, u_int32_t t)
{
int32_t delta, delta2, delta3;
@@ -287,7 +348,9 @@ rndattach(int num)
/* mix in another counter */
c = rnd_counter();
+ mutex_spin_enter(&rndpool_mtx);
rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
+ mutex_spin_exit(&rndpool_mtx);
}
/*
@@ -306,6 +369,7 @@ rnd_init(void)
mutex_init(&rnd_mtx, MUTEX_DEFAULT, IPL_VM);
callout_init(&rnd_callout, CALLOUT_MPSAFE);
+ callout_setfunc(&rnd_callout, rnd_timeout, NULL);
/*
* take a counter early, hoping that there's some variance in
@@ -315,10 +379,11 @@ rnd_init(void)
LIST_INIT(&rnd_sources);
SIMPLEQ_INIT(&rnd_samples);
+ TAILQ_INIT(&rnd_sinks);
selinit(&rnd_selq);
rndpool_init(&rnd_pool);
- mutex_init(&rndpool_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
+ mutex_init(&rndpool_mtx, MUTEX_DEFAULT, IPL_VM);
cv_init(&rndpool_cv, "rndread");
/* Mix *something*, *anything* into the pool to help it get started.
@@ -327,9 +392,11 @@ rnd_init(void)
* XXX more things to add would be nice.
*/
if (c) {
- rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
+ mutex_spin_enter(&rndpool_mtx);
+ rndpool_add_data(&rnd_pool, &c, sizeof(c), 1);
c = rnd_counter();
- rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
+ rndpool_add_data(&rnd_pool, &c, sizeof(c), 1);
+ mutex_spin_exit(&rndpool_mtx);
}
rnd_ready = 1;
@@ -393,7 +460,7 @@ rndread(dev_t dev, struct uio *uio, int ioflag)
*
* If not requesting strong randomness, we can always read.
*/
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
if (mode != RND_EXTRACT_ANY) {
for (;;) {
/*
@@ -408,19 +475,19 @@ rndread(dev_t dev, struct uio *uio, int ioflag)
* Data is not available.
*/
if (ioflag & IO_NDELAY) {
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
ret = EWOULDBLOCK;
goto out;
}
ret = cv_wait_sig(&rndpool_cv, &rndpool_mtx);
if (ret) {
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
goto out;
}
}
}
nread = rnd_extract_data_locked(bf, n, mode);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
/*
* Copy (possibly partial) data to the user.
@@ -460,9 +527,9 @@ rndwrite(dev_t dev, struct uio *uio, int ioflag)
/*
* Mix in the bytes.
*/
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
rndpool_add_data(&rnd_pool, bf, n, 0);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
DPRINTF(RND_DEBUG_WRITE, ("Random: Copied in %d bytes\n", n));
}
@@ -470,11 +537,21 @@ rndwrite(dev_t dev, struct uio *uio, int ioflag)
return (ret);
}
+static void
+krndsource_to_rndsource(krndsource_t *kr, rndsource_t *r)
+{
+ memset(r, 0, sizeof(*r));
+ strlcpy(r->name, kr->name, sizeof(r->name));
+ r->total = kr->total;
+ r->type = kr->type;
+ r->flags = kr->flags;
+}
+
int
rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
struct lwp *l)
{
- rndsource_element_t *rse;
+ krndsource_t *kr;
rndstat_t *rst;
rndstat_name_t *rstnm;
rndctl_t *rctl;
@@ -528,15 +605,15 @@ rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
break;
case RNDGETENTCNT:
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
*(u_int32_t *)addr = rndpool_get_entropy_count(&rnd_pool);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
break;
case RNDGETPOOLSTAT:
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
rndpool_get_stats(&rnd_pool, addr, sizeof(rndpoolstat_t));
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
break;
case RNDGETSRCNUM:
@@ -552,10 +629,10 @@ rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
* Find the starting source by running through the
* list of sources.
*/
- rse = rnd_sources.lh_first;
+ kr = rnd_sources.lh_first;
start = rst->start;
- while (rse != NULL && start >= 1) {
- rse = rse->list.le_next;
+ while (kr != NULL && start >= 1) {
+ kr = kr->list.le_next;
start--;
}
@@ -564,15 +641,9 @@ rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
* for. If we run out of sources, a count of zero
* will be returned, without an error.
*/
- for (count = 0; count < rst->count && rse != NULL; count++) {
- memcpy(&rst->source[count], &rse->data,
- sizeof(rndsource_t));
- /* Zero out information which may leak */
- rst->source[count].last_time = 0;
- rst->source[count].last_delta = 0;
- rst->source[count].last_delta2 = 0;
- rst->source[count].state = 0;
- rse = rse->list.le_next;
+ for (count = 0; count < rst->count && kr != NULL; count++) {
+ krndsource_to_rndsource(kr, &rst->source[count]);
+ kr = kr->list.le_next;
}
rst->count = count;
@@ -584,15 +655,15 @@ rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
* Scan through the list, trying to find the name.
*/
rstnm = (rndstat_name_t *)addr;
- rse = rnd_sources.lh_first;
- while (rse != NULL) {
- if (strncmp(rse->data.name, rstnm->name, 16) == 0) {
- memcpy(&rstnm->source, &rse->data,
- sizeof(rndsource_t));
-
+ kr = rnd_sources.lh_first;
+ while (kr != NULL) {
+ if (strncmp(kr->name, rstnm->name,
+ MIN(sizeof(kr->name),
+ sizeof(*rstnm))) == 0) {
+ krndsource_to_rndsource(kr, &rstnm->source);
return (0);
}
- rse = rse->list.le_next;
+ kr = kr->list.le_next;
}
ret = ENOENT; /* name not found */
@@ -605,19 +676,19 @@ rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
* collection.
*/
rctl = (rndctl_t *)addr;
- rse = rnd_sources.lh_first;
+ kr = rnd_sources.lh_first;
/*
* Flags set apply to all sources of this type.
*/
if (rctl->type != 0xff) {
- while (rse != NULL) {
- if (rse->data.type == rctl->type) {
- rse->data.flags &= ~rctl->mask;
- rse->data.flags |=
+ while (kr != NULL) {
+ if (kr->type == rctl->type) {
+ kr->flags &= ~rctl->mask;
+ kr->flags |=
(rctl->flags & rctl->mask);
}
- rse = rse->list.le_next;
+ kr = kr->list.le_next;
}
return (0);
@@ -626,14 +697,16 @@ rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
/*
* scan through the list, trying to find the name
*/
- while (rse != NULL) {
- if (strncmp(rse->data.name, rctl->name, 16) == 0) {
- rse->data.flags &= ~rctl->mask;
- rse->data.flags |= (rctl->flags & rctl->mask);
+ while (kr != NULL) {
+ if (strncmp(kr->name, rctl->name,
+ MIN(sizeof(kr->name),
+ sizeof(rctl->name))) == 0) {
+ kr->flags &= ~rctl->mask;
+ kr->flags |= (rctl->flags & rctl->mask);
return (0);
}
- rse = rse->list.le_next;
+ kr = kr->list.le_next;
}
ret = ENOENT; /* name not found */
@@ -646,10 +719,10 @@ rndioctl(dev_t dev, u_long cmd, void *addr, int flag,
if (rnddata->len > sizeof(rnddata->data))
return EINVAL;
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
rndpool_add_data(&rnd_pool, rnddata->data, rnddata->len,
rnddata->entropy);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
rnd_wakeup_readers();
@@ -690,13 +763,13 @@ rndpoll(dev_t dev, int events, struct lwp *l)
/*
* Make certain we have enough entropy to be readable.
*/
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
entcnt = rndpool_get_entropy_count(&rnd_pool);
+ mutex_spin_exit(&rndpool_mtx);
if (entcnt >= RND_ENTROPY_THRESHOLD * 8)
revents |= events & (POLLIN | POLLRDNORM);
else
selrecord(l, &rnd_selq);
- mutex_exit(&rndpool_mtx);
return (revents);
}
@@ -704,9 +777,9 @@ rndpoll(dev_t dev, int events, struct lwp *l)
static void
filt_rnddetach(struct knote *kn)
{
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
SLIST_REMOVE(&rnd_selq.sel_klist, kn, knote, kn_selnext);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
}
static int
@@ -714,9 +787,9 @@ filt_rndread(struct knote *kn, long hint)
{
uint32_t entcnt;
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
entcnt = rndpool_get_entropy_count(&rnd_pool);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
if (entcnt >= RND_ENTROPY_THRESHOLD * 8) {
kn->kn_data = RND_TEMP_BUFFER_SIZE;
return (1);
@@ -755,15 +828,15 @@ rndkqfilter(dev_t dev, struct knote *kn)
kn->kn_hook = NULL;
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
SLIST_INSERT_HEAD(klist, kn, kn_selnext);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
return (0);
}
static rnd_sample_t *
-rnd_sample_allocate(rndsource_t *source)
+rnd_sample_allocate(krndsource_t *source)
{
rnd_sample_t *c;
@@ -782,7 +855,7 @@ rnd_sample_allocate(rndsource_t *source)
* Don't wait on allocation. To be used in an interrupt context.
*/
static rnd_sample_t *
-rnd_sample_allocate_isr(rndsource_t *source)
+rnd_sample_allocate_isr(krndsource_t *source)
{
rnd_sample_t *c;
@@ -800,7 +873,7 @@ rnd_sample_allocate_isr(rndsource_t *source)
static void
rnd_sample_free(rnd_sample_t *c)
{
- memset(c, 0, sizeof(rnd_sample_t));
+ memset(c, 0, sizeof(*c));
pool_put(&rnd_mempool, c);
}
@@ -808,7 +881,7 @@ rnd_sample_free(rnd_sample_t *c)
* Add a source to our list of sources.
*/
void
-rnd_attach_source(rndsource_element_t *rs, const char *name, u_int32_t type,
+rnd_attach_source(krndsource_t *rs, const char *name, u_int32_t type,
u_int32_t flags)
{
u_int32_t ts;
@@ -817,11 +890,11 @@ rnd_attach_source(rndsource_element_t *rs, const char *name, u_int32_t type,
ts = rnd_counter();
- strlcpy(rs->data.name, name, sizeof(rs->data.name));
- rs->data.last_time = ts;
- rs->data.last_delta = 0;
- rs->data.last_delta2 = 0;
- rs->data.total = 0;
+ strlcpy(rs->name, name, sizeof(rs->name));
+ rs->last_time = ts;
+ rs->last_delta = 0;
+ rs->last_delta2 = 0;
+ rs->total = 0;
/*
* Force network devices to not collect any entropy by
@@ -830,15 +903,27 @@ rnd_attach_source(rndsource_element_t *rs, const char *name, u_int32_t type,
if (type == RND_TYPE_NET)
flags |= (RND_FLAG_NO_COLLECT | RND_FLAG_NO_ESTIMATE);
- rs->data.type = type;
- rs->data.flags = flags;
+ /*
+ * Hardware RNGs get extra space for statistical testing.
+ */
+ if (type == RND_TYPE_RNG) {
+ rs->test = kmem_alloc(sizeof(rngtest_t), KM_NOSLEEP);
+ rs->test_cnt = 0;
+ } else {
+ rs->test = NULL;
+ rs->test_cnt = -1;
+ }
+
+ rs->type = type;
+ rs->flags = flags;
- rs->data.state = rnd_sample_allocate(&rs->data);
+ rs->state = rnd_sample_allocate(rs);
+ mutex_spin_enter(&rndpool_mtx);
LIST_INSERT_HEAD(&rnd_sources, rs, list);
#ifdef RND_VERBOSE
- printf("rnd: %s attached as an entropy source (", rs->data.name);
+ printf("rnd: %s attached as an entropy source (", rs->name);
if (!(flags & RND_FLAG_NO_COLLECT)) {
printf("collecting");
if (flags & RND_FLAG_NO_ESTIMATE)
@@ -854,28 +939,30 @@ rnd_attach_source(rndsource_element_t *rs, const char *name, u_int32_t type,
* XXX Bogus, but harder to guess than zeros.
*/
rndpool_add_data(&rnd_pool, &ts, sizeof(u_int32_t), 1);
+ mutex_spin_exit(&rndpool_mtx);
}
/*
* Remove a source from our list of sources.
*/
void
-rnd_detach_source(rndsource_element_t *rs)
+rnd_detach_source(krndsource_t *source)
{
rnd_sample_t *sample;
- rndsource_t *source;
-
- mutex_enter(&rnd_mtx);
- LIST_REMOVE(rs, list);
+ mutex_spin_enter(&rnd_mtx);
- source = &rs->data;
+ LIST_REMOVE(source, list);
if (source->state) {
rnd_sample_free(source->state);
source->state = NULL;
}
+ if (source->test) {
+ kmem_free(source->test, sizeof(rngtest_t));
+ }
+
/*
* If there are samples queued up "remove" them from the sample queue
* by setting the source to the no-collect pseudosource.
@@ -888,9 +975,9 @@ rnd_detach_source(rndsource_element_t *rs)
sample = SIMPLEQ_NEXT(sample, next);
}
- mutex_exit(&rnd_mtx);
+ mutex_spin_exit(&rnd_mtx);
#ifdef RND_VERBOSE
- printf("rnd: %s detached as an entropy source\n", rs->data.name);
+ printf("rnd: %s detached as an entropy source\n", source->name);
#endif
}
@@ -899,16 +986,12 @@ rnd_detach_source(rndsource_element_t *rs)
* source-specific source structure.
*/
void
-rnd_add_uint32(rndsource_element_t *rs, u_int32_t val)
+rnd_add_uint32(krndsource_t *rs, u_int32_t val)
{
- rndsource_t *rst;
- rnd_sample_t *state;
u_int32_t ts;
+ u_int32_t entropy = 0;
-
- rst = &rs->data;
-
- if (rst->flags & RND_FLAG_NO_COLLECT)
+ if (rs->flags & RND_FLAG_NO_COLLECT)
return;
/*
@@ -918,134 +1001,264 @@ rnd_add_uint32(rndsource_element_t *rs, u_int32_t val)
ts = rnd_counter();
/*
- * If the sample buffer is NULL, try to allocate one here. If this
- * fails, drop this sample.
- */
- state = rst->state;
- if (state == NULL) {
- state = rnd_sample_allocate_isr(rst);
- if (state == NULL)
- return;
- rst->state = state;
- }
-
- /*
* If we are estimating entropy on this source,
* calculate differentials.
*/
- if ((rst->flags & RND_FLAG_NO_ESTIMATE) == 0)
- state->entropy += rnd_estimate_entropy(rst, ts);
+ if ((rs->flags & RND_FLAG_NO_ESTIMATE) == 0) {
+ entropy = rnd_estimate_entropy(rs, ts);
+ }
+
+ rnd_add_data(rs, &val, sizeof(val), entropy);
+}
- state->ts[state->cursor] = ts;
- state->values[state->cursor] = val;
- state->cursor++;
+void
+rnd_add_data(krndsource_t *rs, const void *const data, u_int32_t len,
+ u_int32_t entropy)
+{
+ rnd_sample_t *state = NULL;
+ uint32_t ts;
+ const uint32_t *dint = data;
+ int todo, done, filled = 0;
+ SIMPLEQ_HEAD(, _rnd_sample_t) tmp_samples =
+ SIMPLEQ_HEAD_INITIALIZER(tmp_samples);
+
+ if (rs->flags & RND_FLAG_NO_COLLECT) {
+ return;
+ }
+
+ /*
+ * Sample the counter as soon as possible to avoid entropy
+ * overestimation.
+ */
+ ts = rnd_counter();
/*
- * If the state arrays are not full, we're done.
+ * Loop over data packaging it into sample buffers.
+ * If a sample buffer allocation fails, drop all data.
*/
- if (state->cursor < RND_SAMPLE_COUNT)
+ todo = len / sizeof(*dint);
+ for (done = 0; done < todo ; done++) {
+ state = rs->state;
+ if (state == NULL) {
+ state = rnd_sample_allocate_isr(rs);
+ if (__predict_false(state == NULL)) {
+ break;
+ }
+ rs->state = state;
+ }
+
+ state->ts[state->cursor] = ts;
+ state->values[state->cursor] = dint[done];
+ state->cursor++;
+
+ if (state->cursor == RND_SAMPLE_COUNT) {
+ SIMPLEQ_INSERT_HEAD(&tmp_samples, state, next);
+ filled++;
+ rs->state = NULL;
+ }
+ }
+
+ if (__predict_false(state == NULL)) {
+ while ((state = SIMPLEQ_FIRST(&tmp_samples))) {
+ SIMPLEQ_REMOVE_HEAD(&tmp_samples, next);
+ rnd_sample_free(state);
+ }
return;
+ }
/*
- * State arrays are full. Queue this chunk on the processing queue.
+ * Claim all the entropy on the last one we send to
+ * the pool, so we don't rely on it being evenly distributed
+ * in the supplied data.
+ *
+ * XXX The rndpool code must accept samples with more
+ * XXX claimed entropy than bits for this to work right.
*/
- mutex_enter(&rnd_mtx);
- SIMPLEQ_INSERT_HEAD(&rnd_samples, state, next);
- rst->state = NULL;
+ state->entropy += entropy;
+ rs->total += entropy;
/*
- * If the timeout isn't pending, have it run in the near future.
+ * If we didn't finish any sample buffers, we're done.
*/
- if (rnd_timeout_pending == 0) {
- rnd_timeout_pending = 1;
- callout_reset(&rnd_callout, 1, rnd_timeout, NULL);
+ if (!filled) {
+ return;
+ }
+
+ mutex_spin_enter(&rnd_mtx);
+ while ((state = SIMPLEQ_FIRST(&tmp_samples))) {
+ SIMPLEQ_REMOVE_HEAD(&tmp_samples, next);
+ SIMPLEQ_INSERT_HEAD(&rnd_samples, state, next);
}
- mutex_exit(&rnd_mtx);
/*
- * To get here we have to have queued the state up, and therefore
- * we need a new state buffer. If we can, allocate one now;
- * if we don't get it, it doesn't matter; we'll try again on
- * the next random event.
+ * If we are still starting up, cause immediate processing of
+ * the queued samples. Otherwise, if the timeout isn't
+ * pending, have it run in the near future.
*/
- rst->state = rnd_sample_allocate_isr(rst);
+ if (__predict_false(cold)) {
+#ifdef RND_VERBOSE
+ printf("rnd: directly processing boot-time events.\n");
+#endif
+ rnd_process_events(NULL); /* Drops lock! */
+ return;
+ }
+ if (rnd_timeout_pending == 0) {
+ rnd_timeout_pending = 1;
+ mutex_spin_exit(&rnd_mtx);
+ callout_schedule(&rnd_callout, 1);
+ return;
+ }
+ mutex_spin_exit(&rnd_mtx);
}
-void
-rnd_add_data(rndsource_element_t *rs, void *data, u_int32_t len,
- u_int32_t entropy)
+static int
+rnd_hwrng_test(rnd_sample_t *sample)
{
- rndsource_t *rst;
+ krndsource_t *source = sample->source;
+ size_t cmplen;
+ uint8_t *v1, *v2;
+ size_t resid, totest;
- /* Mix in the random data directly into the pool. */
- rndpool_add_data(&rnd_pool, data, len, entropy);
+ KASSERT(source->type = RND_TYPE_RNG);
- if (rs != NULL) {
- rst = &rs->data;
- rst->total += entropy;
-
- if ((rst->flags & RND_FLAG_NO_ESTIMATE) == 0)
- /* Estimate entropy using timing information */
- rnd_add_uint32(rs, *(u_int8_t *)data);
+ /*
+ * Continuous-output test: compare two halves of the
+ * sample buffer to each other. The sample buffer (64 ints,
+ * so either 256 or 512 bytes on any modern machine) should be
+ * much larger than a typical hardware RNG output, so this seems
+ * a reasonable way to do it without retaining extra data.
+ */
+ cmplen = sizeof(sample->values) / 2;
+ v1 = (uint8_t *)sample->values;
+ v2 = (uint8_t *)sample->values + cmplen;
+
+ if (__predict_false(memcmp(v1, v2, cmplen))) {
+ printf("rnd: source \"%s\" failed continuous-output test.",
+ source->name);
+ return 1;
}
- /* Wake up any potential readers since we've just added some data. */
- rnd_wakeup_readers();
+ /*
+ * FIPS 140 statistical RNG test. We must accumulate 20,000 bits.
+ */
+ if (__predict_true(source->test_cnt == -1)) {
+ /* already passed the test */
+ return 0;
+ }
+ resid = FIPS140_RNG_TEST_BYTES - source->test_cnt;
+ totest = MIN(RND_SAMPLE_COUNT * 4, resid);
+ memcpy(source->test->rt_b + source->test_cnt, sample->values, totest);
+ resid -= totest;
+ source->test_cnt += totest;
+ if (resid == 0) {
+ strlcpy(source->test->rt_name, source->name,
+ sizeof(source->test->rt_name));
+ if (rngtest(source->test)) {
+ printf("rnd: source \"%s\" failed statistical test.",
+ source->name);
+ return 1;
+ }
+ source->test_cnt = -1;
+ memset(source->test, 0, sizeof(*source->test));
+ }
+ return 0;
}
/*
- * Timeout, run to process the events in the ring buffer.
+ * Process the events in the ring buffer. Called by rnd_timeout or
+ * by the add routines directly if the callout has never fired (that
+ * is, if we are "cold" -- just booted).
+ *
+ * Call with rnd_mtx held -- WILL RELEASE IT.
*/
static void
-rnd_timeout(void *arg)
+rnd_process_events(void *arg)
{
rnd_sample_t *sample;
- rndsource_t *source;
+ krndsource_t *source, *badsource = NULL;
u_int32_t entropy;
+ SIMPLEQ_HEAD(, _rnd_sample_t) dq_samples =
+ SIMPLEQ_HEAD_INITIALIZER(dq_samples);
+ SIMPLEQ_HEAD(, _rnd_sample_t) df_samples =
+ SIMPLEQ_HEAD_INITIALIZER(df_samples);
+ TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk);
/*
- * Sample queue is protected by rnd_mtx, take it briefly to dequeue.
+ * Sample queue is protected by rnd_mtx, drain to onstack queue
+ * and drop lock.
*/
- mutex_enter(&rnd_mtx);
- rnd_timeout_pending = 0;
- sample = SIMPLEQ_FIRST(&rnd_samples);
- while (sample != NULL) {
+ while ((sample = SIMPLEQ_FIRST(&rnd_samples))) {
SIMPLEQ_REMOVE_HEAD(&rnd_samples, next);
- mutex_exit(&rnd_mtx);
+ /*
+ * We repeat this check here, since it is possible
+ * the source was disabled before we were called, but
+ * after the entry was queued.
+ */
+ if (__predict_false(sample->source->flags
+ & RND_FLAG_NO_COLLECT)) {
+ SIMPLEQ_INSERT_TAIL(&df_samples, sample, next);
+ } else {
+ SIMPLEQ_INSERT_TAIL(&dq_samples, sample, next);
+ }
+ }
+ mutex_spin_exit(&rnd_mtx);
+ /* Don't thrash the rndpool mtx either. Hold, add all samples. */
+ mutex_spin_enter(&rndpool_mtx);
+ while ((sample = SIMPLEQ_FIRST(&dq_samples))) {
+ SIMPLEQ_REMOVE_HEAD(&dq_samples, next);
source = sample->source;
+ entropy = sample->entropy;
+ if (source->flags & RND_FLAG_NO_ESTIMATE)
+ entropy = 0;
/*
- * We repeat this check here, since it is possible the source
- * was disabled before we were called, but after the entry
- * was queued.
+ * Hardware generators are great but sometimes they
+ * have...hardware issues. Don't use any data from
+ * them unless it passes some tests.
*/
- if ((source->flags & RND_FLAG_NO_COLLECT) == 0) {
- entropy = sample->entropy;
- if (source->flags & RND_FLAG_NO_ESTIMATE)
- entropy = 0;
+ if (source->type == RND_TYPE_RNG) {
+ if (__predict_false(rnd_hwrng_test(sample))) {
+ /*
+ * Detach the bad source. See below.
+ */
+ badsource = source;
+ printf("rnd: detaching source \"%s\".",
+ badsource->name);
+ break;
+ }
+ }
+ rndpool_add_data(&rnd_pool, sample->values,
+ RND_SAMPLE_COUNT * 4, 0);
- mutex_enter(&rndpool_mtx);
- rndpool_add_data(&rnd_pool, sample->values,
- RND_SAMPLE_COUNT * 4, 0);
+ rndpool_add_data(&rnd_pool, sample->ts,
+ RND_SAMPLE_COUNT * 4, entropy);
- rndpool_add_data(&rnd_pool, sample->ts,
- RND_SAMPLE_COUNT * 4,
- entropy);
- mutex_exit(&rndpool_mtx);
+ source->total += sample->entropy;
+ SIMPLEQ_INSERT_TAIL(&df_samples, sample, next);
+ }
+ mutex_spin_exit(&rndpool_mtx);
- source->total += sample->entropy;
+ /* Now we hold no locks: clean up. */
+ if (__predict_false(badsource)) {
+ /*
+ * The detach routine frees any samples we have not
+ * dequeued ourselves. For sanity's sake, we simply
+ * free (without using) all dequeued samples from the
+ * point at which we detected a problem onwards.
+ */
+ rnd_detach_source(badsource);
+ while ((sample = SIMPLEQ_FIRST(&dq_samples))) {
+ SIMPLEQ_REMOVE_HEAD(&dq_samples, next);
+ rnd_sample_free(sample);
}
-
+ }
+ while ((sample = SIMPLEQ_FIRST(&df_samples))) {
+ SIMPLEQ_REMOVE_HEAD(&df_samples, next);
rnd_sample_free(sample);
-
- /* Get mtx back to dequeue the next one.. */
- mutex_enter(&rnd_mtx);
- sample = SIMPLEQ_FIRST(&rnd_samples);
}
- mutex_exit(&rnd_mtx);
/*
* Wake up any potential readers waiting.
@@ -1053,6 +1266,17 @@ rnd_timeout(void *arg)
rnd_wakeup_readers();
}
+/*
+ * Timeout, run to process the events in the ring buffer.
+ */
+static void
+rnd_timeout(void *arg)
+{
+ mutex_spin_enter(&rnd_mtx);
+ rnd_timeout_pending = 0;
+ rnd_process_events(arg);
+}
+
static u_int32_t
rnd_extract_data_locked(void *p, u_int32_t len, u_int32_t flags)
{
@@ -1069,6 +1293,48 @@ rnd_extract_data_locked(void *p, u_int32_t len, u_int32_t flags)
c = rnd_counter();
rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
}
+ if (!rnd_tested) {
+ rngtest_t rt;
+ uint8_t testbits[sizeof(rt.rt_b)];
+ int entropy_count;
+
+ entropy_count = rndpool_get_entropy_count(&rnd_pool);
+#ifdef RND_VERBOSE
+ printf("rnd: starting statistical RNG test, entropy = %d.\n",
+ entropy_count);
+#endif
+ if (rndpool_extract_data(&rnd_pool, rt.rt_b,
+ sizeof(rt.rt_b), RND_EXTRACT_ANY) != sizeof(rt.rt_b)) {
+ panic("rnd: could not get bits for statistical test");
+ }
+ /*
+ * Stash the tested bits so we can put them back in the
+ * pool, restoring the entropy count. DO NOT rely on
+ * rngtest to maintain the bits pristine -- we could end
+ * up adding back non-random data claiming it were pure
+ * entropy.
+ */
+ memcpy(testbits, rt.rt_b, sizeof(rt.rt_b));
+ strlcpy(rt.rt_name, "entropy pool", sizeof(rt.rt_name));
+ if (rngtest(&rt)) {
+ /*
+ * The probabiliity of a Type I error is 3/10000,
+ * but note this can only happen at boot time.
+ * The relevant standard says to reset the module,
+ * so that's what we do.
+ */
+ panic("rnd: entropy pool failed statistical test");
+ }
+ memset(&rt, 0, sizeof(rt));
+ rndpool_add_data(&rnd_pool, testbits, sizeof(testbits),
+ entropy_count);
+ memset(testbits, 0, sizeof(testbits));
+#ifdef RND_VERBOSE
+ printf("rnd: statistical RNG test done, entropy = %d.\n",
+ rndpool_get_entropy_count(&rnd_pool));
+#endif
+ rnd_tested++;
+ }
return rndpool_extract_data(&rnd_pool, p, len, flags);
}
@@ -1077,8 +1343,42 @@ rnd_extract_data(void *p, u_int32_t len, u_int32_t flags)
{
uint32_t retval;
- mutex_enter(&rndpool_mtx);
+ mutex_spin_enter(&rndpool_mtx);
retval = rnd_extract_data_locked(p, len, flags);
- mutex_exit(&rndpool_mtx);
+ mutex_spin_exit(&rndpool_mtx);
return retval;
}
+
+void
+rndsink_attach(rndsink_t *rs)
+{
+#ifdef RND_VERBOSE
+ printf("rnd: entropy sink \"%s\" wants %d bytes of data.\n",
+ rs->name, (int)rs->len);
+#endif
+ mutex_spin_enter(&rndpool_mtx);
+ TAILQ_INSERT_TAIL(&rnd_sinks, rs, tailq);
+ mutex_spin_exit(&rndpool_mtx);
+ mutex_spin_enter(&rnd_mtx);
+ if (rnd_timeout_pending == 0) {
+ rnd_timeout_pending = 1;
+ callout_schedule(&rnd_callout, 1);
+ }
+ mutex_spin_exit(&rnd_mtx);
+}
+
+void
+rndsink_detach(rndsink_t *rs)
+{
+ rndsink_t *sink, *tsink;
+#ifdef RND_VERBOSE
+ printf("rnd: entropy sink \"%s\" no longer wants data.\n", rs->name);
+#endif
+ mutex_spin_enter(&rndpool_mtx);
+ TAILQ_FOREACH_SAFE(sink, &rnd_sinks, tailq, tsink) {
+ if (sink == rs) {
+ TAILQ_REMOVE(&rnd_sinks, rs, tailq);
+ }
+ }
+ mutex_spin_exit(&rndpool_mtx);
+}
diff --git a/sys/dev/scsipi/cdvar.h b/sys/dev/scsipi/cdvar.h
index 5187e018373..5f48abdbe5f 100644
--- a/sys/dev/scsipi/cdvar.h
+++ b/sys/dev/scsipi/cdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: cdvar.h,v 1.29 2009/10/19 18:41:16 bouyer Exp $ */
+/* $NetBSD: cdvar.h,v 1.30 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
@@ -48,6 +48,6 @@ struct cd_softc {
struct callout sc_callout;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/scsipi/sdvar.h b/sys/dev/scsipi/sdvar.h
index 93f46c28604..11646e20434 100644
--- a/sys/dev/scsipi/sdvar.h
+++ b/sys/dev/scsipi/sdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sdvar.h,v 1.32 2009/04/10 17:36:42 dyoung Exp $ */
+/* $NetBSD: sdvar.h,v 1.33 2011/11/19 22:51:24 tls Exp $ */
/*-
* Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -92,7 +92,7 @@ struct sd_softc {
char name[16]; /* product name, for default disklabel */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/scsipi/stvar.h b/sys/dev/scsipi/stvar.h
index 88a2cbc1a1f..45e32e29468 100644
--- a/sys/dev/scsipi/stvar.h
+++ b/sys/dev/scsipi/stvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: stvar.h,v 1.21 2009/12/06 22:48:17 dyoung Exp $ */
+/* $NetBSD: stvar.h,v 1.22 2011/11/19 22:51:24 tls Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -147,7 +147,7 @@ struct st_softc {
struct io_stats *stats; /* statistics for the drive */
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dev/usb/if_auereg.h b/sys/dev/usb/if_auereg.h
index 6d1bfb86571..56f9839f8df 100644
--- a/sys/dev/usb/if_auereg.h
+++ b/sys/dev/usb/if_auereg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_auereg.h,v 1.23 2009/09/04 18:10:08 dyoung Exp $ */
+/* $NetBSD: if_auereg.h,v 1.24 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
@@ -229,7 +229,7 @@ struct aue_softc {
struct ethercom aue_ec;
struct mii_data aue_mii;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
struct lwp *aue_thread;
int aue_closing;
diff --git a/sys/dev/usb/if_axereg.h b/sys/dev/usb/if_axereg.h
index 6b0ede7a731..cb3d55fd0d4 100644
--- a/sys/dev/usb/if_axereg.h
+++ b/sys/dev/usb/if_axereg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_axereg.h,v 1.12 2010/08/14 10:47:57 tsutsui Exp $ */
+/* $NetBSD: if_axereg.h,v 1.13 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000-2003
@@ -200,7 +200,7 @@ struct axe_softc {
struct ethercom axe_ec;
struct mii_data axe_mii;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
usbd_device_handle axe_udev;
usbd_interface_handle axe_iface;
diff --git a/sys/dev/usb/if_cdcereg.h b/sys/dev/usb/if_cdcereg.h
index 533d9a0022c..90f2da7be4e 100644
--- a/sys/dev/usb/if_cdcereg.h
+++ b/sys/dev/usb/if_cdcereg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_cdcereg.h,v 1.5 2009/09/04 18:10:08 dyoung Exp $ */
+/* $NetBSD: if_cdcereg.h,v 1.6 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com>
@@ -69,7 +69,7 @@ struct cdce_softc {
device_t cdce_dev;
struct ethercom cdce_ec;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
#define GET_IFP(sc) (&(sc)->cdce_ec.ec_if)
usbd_device_handle cdce_udev;
diff --git a/sys/dev/usb/if_cuereg.h b/sys/dev/usb/if_cuereg.h
index d3ffc3e3802..f5d53b894d4 100644
--- a/sys/dev/usb/if_cuereg.h
+++ b/sys/dev/usb/if_cuereg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_cuereg.h,v 1.16 2009/09/04 18:10:08 dyoung Exp $ */
+/* $NetBSD: if_cuereg.h,v 1.17 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
@@ -169,7 +169,7 @@ struct cue_softc {
struct ethercom cue_ec;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
#define GET_IFP(sc) (&(sc)->cue_ec.ec_if)
diff --git a/sys/dev/usb/if_kuereg.h b/sys/dev/usb/if_kuereg.h
index 4746832e27c..5920c98e4b1 100644
--- a/sys/dev/usb/if_kuereg.h
+++ b/sys/dev/usb/if_kuereg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_kuereg.h,v 1.16 2010/11/03 22:30:50 dyoung Exp $ */
+/* $NetBSD: if_kuereg.h,v 1.17 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2000
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
@@ -163,7 +163,7 @@ struct kue_softc {
struct ethercom kue_ec;
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
#define GET_IFP(sc) (&(sc)->kue_ec.ec_if)
diff --git a/sys/dev/usb/if_udavreg.h b/sys/dev/usb/if_udavreg.h
index 4aea9f9c791..9aa6f1b2513 100644
--- a/sys/dev/usb/if_udavreg.h
+++ b/sys/dev/usb/if_udavreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_udavreg.h,v 1.6 2010/11/03 22:30:50 dyoung Exp $ */
+/* $NetBSD: if_udavreg.h,v 1.7 2011/11/19 22:51:24 tls Exp $ */
/* $nabe: if_udavreg.h,v 1.2 2003/08/21 16:26:40 nabe Exp $ */
/*
* Copyright (c) 2003
@@ -190,7 +190,7 @@ struct udav_softc {
int sc_link;
#define sc_media udav_mii.mii_media
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
struct udav_cdata sc_cdata;
diff --git a/sys/dev/usb/if_upl.c b/sys/dev/usb/if_upl.c
index d263f4e235a..336c8e70bd2 100644
--- a/sys/dev/usb/if_upl.c
+++ b/sys/dev/usb/if_upl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_upl.c,v 1.38 2010/11/03 22:28:31 dyoung Exp $ */
+/* $NetBSD: if_upl.c,v 1.39 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.38 2010/11/03 22:28:31 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.39 2011/11/19 22:51:24 tls Exp $");
#include "opt_inet.h"
#include "rnd.h"
@@ -135,7 +135,7 @@ struct upl_softc {
struct ifnet sc_if;
#if NRND > 0
- rndsource_element_t sc_rnd_source;
+ krndsource_t sc_rnd_source;
#endif
struct callout sc_stat_ch;
diff --git a/sys/dev/usb/if_urlreg.h b/sys/dev/usb/if_urlreg.h
index 86a3af5ad80..8a0ed59fb0d 100644
--- a/sys/dev/usb/if_urlreg.h
+++ b/sys/dev/usb/if_urlreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_urlreg.h,v 1.6 2010/11/03 22:30:50 dyoung Exp $ */
+/* $NetBSD: if_urlreg.h,v 1.7 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 2001, 2002
* Shingo WATANABE <nabe@nabechan.org>. All rights reserved.
@@ -176,7 +176,7 @@ struct url_softc {
int sc_link;
#define sc_media url_mii.mii_media
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
struct url_cdata sc_cdata;
diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c
index 548e503652f..5dd961925c6 100644
--- a/sys/dev/usb/ucom.c
+++ b/sys/dev/usb/ucom.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ucom.c,v 1.87 2011/04/24 16:27:01 rmind Exp $ */
+/* $NetBSD: ucom.c,v 1.88 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.87 2011/04/24 16:27:01 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.88 2011/11/19 22:51:24 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -147,7 +147,7 @@ struct ucom_softc {
u_char sc_dying; /* disconnecting */
#if defined(__NetBSD__) && NRND > 0
- rndsource_element_t sc_rndsource; /* random source */
+ krndsource_t sc_rndsource; /* random source */
#endif
};
diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h
index b3d44267060..425189f0eec 100644
--- a/sys/dev/usb/uhidev.h
+++ b/sys/dev/usb/uhidev.h
@@ -1,4 +1,4 @@
-/* $NetBSD: uhidev.h,v 1.10 2010/11/03 22:34:24 dyoung Exp $ */
+/* $NetBSD: uhidev.h,v 1.11 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@ struct uhidev {
#define UHIDEV_OPEN 0x01 /* device is open */
void (*sc_intr)(struct uhidev *, void *, u_int);
#if NRND > 0
- rndsource_element_t rnd_source;
+ krndsource_t rnd_source;
#endif
};
diff --git a/sys/dist/pf/net/pf.c b/sys/dist/pf/net/pf.c
index 996b50248c7..2d0dc54d39a 100644
--- a/sys/dist/pf/net/pf.c
+++ b/sys/dist/pf/net/pf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pf.c,v 1.66 2011/08/29 09:50:04 jmcneill Exp $ */
+/* $NetBSD: pf.c,v 1.67 2011/11/19 22:51:24 tls Exp $ */
/* $OpenBSD: pf.c,v 1.552.2.1 2007/11/27 16:37:57 henning Exp $ */
/*
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.66 2011/08/29 09:50:04 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.67 2011/11/19 22:51:24 tls Exp $");
#include "pflog.h"
@@ -93,7 +93,7 @@ __KERNEL_RCSID(0, "$NetBSD: pf.c,v 1.66 2011/08/29 09:50:04 jmcneill Exp $");
#ifndef __NetBSD__
#include <dev/rndvar.h>
#else
-#include <sys/rnd.h>
+#include <sys/cprng.h>
#endif /* __NetBSD__ */
#include <net/pfvar.h>
@@ -2321,29 +2321,30 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, const struct pf_addr *saddr,
switch (af) {
#ifdef INET
case AF_INET:
- rpool->counter.addr32[0] = htonl(arc4random());
+ rpool->counter.addr32[0] =
+ htonl(cprng_fast32());
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
if (rmask->addr32[3] != 0xffffffff)
rpool->counter.addr32[3] =
- htonl(arc4random());
+ htonl(cprng_fast32());
else
break;
if (rmask->addr32[2] != 0xffffffff)
rpool->counter.addr32[2] =
- htonl(arc4random());
+ htonl(cprng_fast32());
else
break;
if (rmask->addr32[1] != 0xffffffff)
rpool->counter.addr32[1] =
- htonl(arc4random());
+ htonl(cprng_fast32());
else
break;
if (rmask->addr32[0] != 0xffffffff)
rpool->counter.addr32[0] =
- htonl(arc4random());
+ htonl(cprng_fast32());
break;
#endif /* INET6 */
}
@@ -2476,7 +2477,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
high = tmp;
}
/* low < high */
- cut = htonl(arc4random()) % (1 + high - low) + low;
+ cut = htonl(cprng_fast32()) % (1 + high - low) + low;
/* low <= cut <= high */
for (tmp = cut; tmp <= high; ++(tmp)) {
key.gwy.port = htons(tmp);
@@ -3305,7 +3306,7 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
!pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
pd->lookup.gid))
r = TAILQ_NEXT(r, entries);
- else if (r->prob && r->prob <= arc4random())
+ else if (r->prob && r->prob <= cprng_fast32())
r = TAILQ_NEXT(r, entries);
else if (r->match_tag && !pf_match_tag(m, r, &tag))
r = TAILQ_NEXT(r, entries);
@@ -3710,7 +3711,7 @@ cleanup:
sport = th->th_dport;
}
}
- s->src.seqhi = htonl(arc4random());
+ s->src.seqhi = htonl(cprng_fast32());
/* Find mss option */
mss = pf_get_mss(m, off, th->th_off, af);
mss = pf_calc_mss(saddr, af, mss);
@@ -3767,7 +3768,7 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
r->flagset || r->type || r->code ||
r->os_fingerprint != PF_OSFP_ANY)
r = TAILQ_NEXT(r, entries);
- else if (r->prob && r->prob <= arc4random())
+ else if (r->prob && r->prob <= cprng_fast32())
r = TAILQ_NEXT(r, entries);
else if (r->match_tag && !pf_match_tag(m, r, &tag))
r = TAILQ_NEXT(r, entries);
@@ -3895,7 +3896,7 @@ pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
}
(*state)->src.max_win = MAX(ntohs(th->th_win), 1);
if ((*state)->dst.seqhi == 1)
- (*state)->dst.seqhi = htonl(arc4random());
+ (*state)->dst.seqhi = htonl(cprng_fast32());
pf_send_tcp((*state)->rule.ptr, pd->af, &psrc->addr,
&pdst->addr, psrc->port, pdst->port,
(*state)->dst.seqhi, 0, TH_SYN, 0,
diff --git a/sys/dist/pf/netinet/tcp_rndiss.c b/sys/dist/pf/netinet/tcp_rndiss.c
index c9e8049ee83..de7fd2bdd71 100644
--- a/sys/dist/pf/netinet/tcp_rndiss.c
+++ b/sys/dist/pf/netinet/tcp_rndiss.c
@@ -1,5 +1,5 @@
/* $OpenBSD: tcp_subr.c,v 1.98 2007/06/25 12:17:43 markus Exp $ */
-/* $NetBSD: tcp_rndiss.c,v 1.2 2008/06/18 09:06:27 yamt Exp $ */
+/* $NetBSD: tcp_rndiss.c,v 1.3 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 1982, 1986, 1988, 1990, 1993
@@ -69,10 +69,10 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_rndiss.c,v 1.2 2008/06/18 09:06:27 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_rndiss.c,v 1.3 2011/11/19 22:51:24 tls Exp $");
#include <sys/param.h>
-#include <sys/rnd.h>
+#include <sys/cprng.h>
#include <netinet/tcp.h>
#include <netinet/tcp_seq.h>
@@ -104,8 +104,7 @@ tcp_rndiss_encrypt(u_int16_t val)
void
tcp_rndiss_init(void)
{
- rnd_extract_data(tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox),
- RND_EXTRACT_ANY);
+ cprng_strong(kern_cprng, tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox));
tcp_rndiss_reseed = time_second + TCP_RNDISS_OUT;
tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
@@ -121,5 +120,5 @@ tcp_rndiss_next(void)
/* (arc4random() & 0x7fff) ensures a 32768 byte gap between ISS */
return ((tcp_rndiss_encrypt(tcp_rndiss_cnt++) | tcp_rndiss_msb) <<16) |
- (arc4random() & 0x7fff);
+ (cprng_fast32() & 0x7fff);
}
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 5bc60141685..007d1429394 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tmpfs_subr.c,v 1.77 2011/08/27 15:32:28 hannken Exp $ */
+/* $NetBSD: tmpfs_subr.c,v 1.78 2011/11/19 22:51:24 tls Exp $ */
/*
* Copyright (c) 2005-2011 The NetBSD Foundation, Inc.
@@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.77 2011/08/27 15:32:28 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tmpfs_subr.c,v 1.78 2011/11/19 22:51:24 tls Exp $");
#include <sys/param.h>
#include <sys/dirent.h>
@@ -124,7 +124,7 @@ tmpfs_alloc_node(tmpfs_mount_t *tmp, enum vtype type, uid_t uid, gid_t gid,
* for applications that do not understand 64-bit ino_t.
*/
nnode->tn_id = (ino_t)((uintptr_t)nnode / sizeof(*nnode));
- nnode->tn_gen = TMPFS_NODE_GEN_MASK & arc4random();
+ nnode->tn_gen = TMPFS_NODE_GEN_MASK & random();
/* Generic initialization. */
nnode->tn_type = type;
diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c
index 9ea2048415a..69db721a62c 100644
--- a/sys/kern/exec_elf.c
+++ b/sys/kern/exec_elf.c
@@ -1,4 +1,4 @@
-/* $NetBSD: exec_elf.c,v 1.32 2011/08/27 17:53:21 reinoud Exp $ */
+/* $NetBSD: exec_elf.c,v 1.33 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.32 2011/08/27 17:53:21 reinoud Exp $");
+__KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.33 2011/11/19 22:51:25 tls Exp $");
#ifdef _KERNEL_OPT
#include "opt_pax.h"
@@ -77,6 +77,7 @@ __KERNEL_RCSID(1, "$NetBSD: exec_elf.c,v 1.32 2011/08/27 17:53:21 reinoud Exp $"
#include <sys/stat.h>
#include <sys/kauth.h>
#include <sys/bitops.h>
+#include <sys/cprng.h>
#include <sys/cpu.h>
#include <machine/reg.h>
@@ -134,7 +135,7 @@ elf_placedynexec(struct lwp *l, struct exec_package *epp, Elf_Ehdr *eh,
pax_align = align;
- r = arc4random();
+ r = cprng_fast32();
if (pax_align == 0)
pax_align = PGSHIFT;
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 5d8e7b36992..6a612417471 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: init_main.c,v 1.436 2011/09/28 15:52:47 jruoho Exp $ */
+/* $NetBSD: init_main.c,v 1.437 2011/11/19 22:51:25 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.436 2011/09/28 15:52:47 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.437 2011/11/19 22:51:25 tls Exp $");
#include "opt_ddb.h"
#include "opt_ipsec.h"
@@ -186,9 +186,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.436 2011/09/28 15:52:47 jruoho Exp $
#endif
#include <sys/domain.h>
#include <sys/namei.h>
-#if NRND > 0
#include <sys/rnd.h>
-#endif
#include <sys/pipe.h>
#if NVERIEXEC > 0
#include <sys/verified_exec.h>
@@ -204,6 +202,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.436 2011/09/28 15:52:47 jruoho Exp $
#ifdef PTRACE
#include <sys/ptrace.h>
#endif /* PTRACE */
+#include <sys/cprng.h>
#include <sys/syscall.h>
#include <sys/syscallargs.h>
@@ -260,6 +259,8 @@ struct timespec boottime; /* time at system startup - will only follow s
int start_init_exec; /* semaphore for start_init() */
+cprng_strong_t *kern_cprng;
+
static void check_console(struct lwp *l);
static void start_init(void *);
static void configure(void);
@@ -375,9 +376,9 @@ main(void)
/*
* The following things must be done before autoconfiguration.
*/
-#if NRND > 0
- rnd_init(); /* initialize random number generator */
-#endif
+ rnd_init(); /* initialize entropy pool */
+
+ cprng_init(); /* initialize cryptographic PRNG */
/* Initialize process and pgrp structures. */
#ifdef KERN_SA
@@ -501,6 +502,10 @@ main(void)
/* Initialize the disk wedge subsystem. */
dkwedge_init();
+ /* Initialize the kernel strong PRNG. */
+ kern_cprng = cprng_strong_create("kernel", IPL_VM,
+ CPRNG_INIT_ANY|CPRNG_REKEY_ANY);
+
/* Initialize interfaces. */
ifinit1();
@@ -509,7 +514,6 @@ main(void)
/* Initialize sockets thread(s) */
soinit1();
-
/* Configure the system hardware. This will enable interrupts. */
configure();
diff --git a/sys/kern/init_sysctl.c b/sys/kern/init_sysctl.c
index 427caadfb88..94beb3ec0da 100644
--- a/sys/kern/init_sysctl.c
+++ b/sys/kern/init_sysctl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: init_sysctl.c,v 1.183 2011/08/30 12:39:59 bouyer Exp $ */
+/* $NetBSD: init_sysctl.c,v 1.184 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.183 2011/08/30 12:39:59 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.184 2011/11/19 22:51:25 tls Exp $");
#include "opt_sysv.h"
#include "opt_compat_netbsd.h"
@@ -38,7 +38,6 @@ __KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.183 2011/08/30 12:39:59 bouyer Exp
#include "opt_sa.h"
#include "opt_posix.h"
#include "pty.h"
-#include "rnd.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -49,7 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.183 2011/08/30 12:39:59 bouyer Exp
#include <sys/kernel.h>
#include <sys/unistd.h>
#include <sys/disklabel.h>
-#include <sys/rnd.h>
+#include <sys/cprng.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/namei.h>
@@ -1395,12 +1394,9 @@ sysctl_kern_sbmax(SYSCTLFN_ARGS)
static int
sysctl_kern_urnd(SYSCTLFN_ARGS)
{
-#if NRND > 0
int v, rv;
- KERNEL_LOCK(1, NULL);
- rv = rnd_extract_data(&v, sizeof(v), RND_EXTRACT_ANY);
- KERNEL_UNLOCK_ONE(NULL);
+ rv = cprng_strong(sysctl_prng, &v, sizeof(v));
if (rv == sizeof(v)) {
struct sysctlnode node = *rnode;
node.sysctl_data = &v;
@@ -1408,9 +1404,6 @@ sysctl_kern_urnd(SYSCTLFN_ARGS)
}
else
return (EIO); /*XXX*/
-#else
- return (EOPNOTSUPP);
-#endif
}
/*
@@ -1420,7 +1413,6 @@ sysctl_kern_urnd(SYSCTLFN_ARGS)
static int
sysctl_kern_arnd(SYSCTLFN_ARGS)
{
-#if NRND > 0
int error;
void *v;
struct sysctlnode node = *rnode;
@@ -1431,15 +1423,12 @@ sysctl_kern_arnd(SYSCTLFN_ARGS)
return E2BIG;
v = kmem_alloc(*oldlenp, KM_SLEEP);
- arc4randbytes(v, *oldlenp);
+ cprng_fast(v, *oldlenp);
node.sysctl_data = v;
node.sysctl_size = *oldlenp;
error = sysctl_lookup(SYSCTLFN_CALL(&node));
kmem_free(v, *oldlenp);
return error;
-#else
- return (EOPNOTSUPP);
-#endif
}
/*
* sysctl helper routine to do kern.lwp.* work.
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index b32552d1f92..a6544c75b45 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_exec.c,v 1.329 2011/09/16 21:02:28 reinoud Exp $ */
+/* $NetBSD: kern_exec.c,v 1.330 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.329 2011/09/16 21:02:28 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.330 2011/11/19 22:51:25 tls Exp $");
#include "opt_exec.h"
#include "opt_ktrace.h"
@@ -103,6 +103,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.329 2011/09/16 21:02:28 reinoud Exp
#include <sys/verified_exec.h>
#endif /* NVERIEXEC > 0 */
#include <sys/sdt.h>
+#include <sys/cprng.h>
#include <uvm/uvm_extern.h>
@@ -780,7 +781,7 @@ execve1(struct lwp *l, const char *path, char * const *args,
#ifdef PAX_ASLR
if (pax_aslr_active(l))
- len += (arc4random() % PAGE_SIZE);
+ len += (cprng_fast32() % PAGE_SIZE);
#endif /* PAX_ASLR */
#ifdef STACKALIGN /* arm, etc. */
diff --git a/sys/kern/kern_pax.c b/sys/kern/kern_pax.c
index 51494747409..076231301f7 100644
--- a/sys/kern/kern_pax.c
+++ b/sys/kern/kern_pax.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_pax.c,v 1.25 2011/04/24 18:46:22 rmind Exp $ */
+/* $NetBSD: kern_pax.c,v 1.26 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.25 2011/04/24 18:46:22 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.26 2011/11/19 22:51:25 tls Exp $");
#include "opt_pax.h"
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_pax.c,v 1.25 2011/04/24 18:46:22 rmind Exp $");
#include <sys/vnode.h>
#include <sys/queue.h>
#include <sys/kauth.h>
+#include <sys/cprng.h>
#ifdef PAX_ASLR
#include <sys/mman.h>
@@ -310,7 +311,7 @@ pax_aslr_init(struct lwp *l, struct vmspace *vm)
if (!pax_aslr_active(l))
return;
- vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(arc4random(),
+ vm->vm_aslr_delta_mmap = PAX_ASLR_DELTA(cprng_fast32(),
PAX_ASLR_DELTA_MMAP_LSB, PAX_ASLR_DELTA_MMAP_LEN);
}
@@ -344,7 +345,7 @@ void
pax_aslr_stack(struct lwp *l, struct exec_package *epp, u_long *max_stack_size)
{
if (pax_aslr_active(l)) {
- u_long d = PAX_ASLR_DELTA(arc4random(),
+ u_long d = PAX_ASLR_DELTA(cprng_fast32(),
PAX_ASLR_DELTA_STACK_LSB,
PAX_ASLR_DELTA_STACK_LEN);
#ifdef PAX_ASLR_DEBUG
diff --git a/sys/kern/kern_ssp.c b/sys/kern/kern_ssp.c
index 6e78988b2a1..a4bbe6b37ae 100644
--- a/sys/kern/kern_ssp.c
+++ b/sys/kern/kern_ssp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_ssp.c,v 1.5 2010/02/01 16:14:58 njoly Exp $ */
+/* $NetBSD: kern_ssp.c,v 1.6 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -27,11 +27,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ssp.c,v 1.5 2010/02/01 16:14:58 njoly Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ssp.c,v 1.6 2011/11/19 22:51:25 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/intr.h>
+#include <sys/cprng.h>
#if defined(__SSP__) || defined(__SSP_ALL__)
long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -57,7 +58,7 @@ ssp_init(void)
size_t i;
long guard[__arraycount(__stack_chk_guard)];
- arc4randbytes(guard, sizeof(guard));
+ cprng_fast(guard, sizeof(guard));
s = splhigh();
for (i = 0; i < __arraycount(guard); i++)
__stack_chk_guard[i] = guard[i];
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 90e45235582..3b0707047f3 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sysctl.c,v 1.232 2011/10/05 13:24:09 apb Exp $ */
+/* $NetBSD: kern_sysctl.c,v 1.233 2011/11/19 22:51:25 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.232 2011/10/05 13:24:09 apb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.233 2011/11/19 22:51:25 tls Exp $");
#include "opt_defcorename.h"
#include "ksyms.h"
@@ -84,6 +84,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.232 2011/10/05 13:24:09 apb Exp $"
#include <sys/syscallargs.h>
#include <sys/kauth.h>
#include <sys/ktrace.h>
+#include <sys/cprng.h>
#define MAXDESCLEN 1024
MALLOC_DEFINE(M_SYSCTLNODE, "sysctlnode", "sysctl node structures");
@@ -158,6 +159,8 @@ long hostid;
#endif
char defcorename[MAXPATHLEN] = DEFCORENAME;
+cprng_strong_t *sysctl_prng;
+
/*
* ********************************************************************
* Section 0: Some simple glue
@@ -245,12 +248,16 @@ sysctl_init(void)
* trees that claim to be readonly at the root now are, and if
* the main tree is readonly, *everything* is.
*
+ * Also starts up the PRNG used for the "random" sysctl: it's
+ * better to start it later than sooner.
+ *
* Call this at the end of kernel init.
*/
void
sysctl_finalize(void)
{
-
+ sysctl_prng = cprng_strong_create("sysctl", IPL_NONE,
+ CPRNG_INIT_ANY|CPRNG_REKEY_ANY);
sysctl_root.sysctl_flags |= CTLFLAG_PERMANENT;
}
diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c
index ecc41db9327..8c6f57e094b 100644
--- a/sys/kern/kern_uuid.c
+++ b/sys/kern/kern_uuid.c
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_uuid.c,v 1.17 2010/05/04 19:23:56 kardel Exp $ */
+/* $NetBSD: kern_uuid.c,v 1.18 2011/11/19 22:51:25 tls Exp $ */
/*
* Copyright (c) 2002 Marcel Moolenaar
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.17 2010/05/04 19:23:56 kardel Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.18 2011/11/19 22:51:25 tls Exp $");
#include <sys/param.h>
#include <sys/endian.h>
@@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.17 2010/05/04 19:23:56 kardel Exp $"
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/uio.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -126,7 +127,7 @@ uuid_node(uint16_t *node)
splx(s);
for (i = 0; i < (UUID_NODE_LEN>>1); i++)
- node[i] = (uint16_t)arc4random();
+ node[i] = (uint16_t)cprng_fast32();
*((uint8_t*)node) |= 0x01;
}
@@ -165,7 +166,7 @@ uuid_generate(struct uuid_private *uuid, uint64_t *timep, int count)
if (uuid_last.time.ll == 0LL || uuid_last.node[0] != uuid->node[0] ||
uuid_last.node[1] != uuid->node[1] ||
uuid_last.node[2] != uuid->node[2])
- uuid->seq = (uint16_t)arc4random() & 0x3fff;
+ uuid->seq = (uint16_t)cprng_fast32() & 0x3fff;
else if (uuid_last.time.ll >= xtime)
uuid->seq = (uuid_last.seq + 1) & 0x3fff;
else
diff --git a/sys/kern/subr_cprng.c b/sys/kern/subr_cprng.c
new file mode 100644
index 00000000000..bbf3ba57f46
--- /dev/null
+++ b/sys/kern/subr_cprng.c
@@ -0,0 +1,305 @@
+/* $NetBSD: subr_cprng.c,v 1.1 2011/11/19 22:51:25 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/rngtest.h>
+#include <sys/rnd.h>
+
+#include <machine/cpu_counter.h>
+
+#include <sys/cprng.h>
+
+__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.1 2011/11/19 22:51:25 tls Exp $");
+
+void
+cprng_init(void)
+{
+ nist_ctr_initialize();
+}
+
+static inline uint32_t
+cprng_counter(void)
+{
+ struct timeval tv;
+
+#if defined(__HAVE_CPU_COUNTER)
+ if (cpu_hascounter())
+ return cpu_counter32();
+#endif
+ if (__predict_false(cold)) {
+ /* microtime unsafe if clock not running yet */
+ return 0;
+ }
+ microtime(&tv);
+ return (tv.tv_sec * 1000000 + tv.tv_usec);
+}
+
+static void
+cprng_strong_reseed(void *const arg)
+{
+ cprng_strong_t *c = arg;
+ uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
+ uint32_t cc = cprng_counter();
+
+ mutex_enter(&c->mtx);
+ if (c->reseed.len != sizeof(key)) {
+ panic("cprng_strong_reseed: bad entropy length %d "
+ " (expected %d)", (int)c->reseed.len, (int)sizeof(key));
+ }
+ if (nist_ctr_drbg_reseed(&c->drbg, c->reseed.data, c->reseed.len,
+ &cc, sizeof(cc))) {
+ panic("cprng %s: nist_ctr_drbg_reseed failed.", c->name);
+ }
+ c->reseed_pending = 0;
+ if (c->flags & CPRNG_USE_CV) {
+ cv_broadcast(&c->cv);
+ }
+ mutex_exit(&c->mtx);
+}
+
+cprng_strong_t *
+cprng_strong_create(const char *const name, int ipl, int flags)
+{
+ cprng_strong_t *c;
+ uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
+ int r, getmore = 0;;
+ uint32_t cc;
+
+ c = kmem_alloc(sizeof(*c), KM_NOSLEEP);
+ if (c == NULL) {
+ return NULL;
+ }
+ c->flags = flags;
+ strlcpy(c->name, name, sizeof(c->name));
+ c->reseed_pending = 0;
+ c->reseed.cb = cprng_strong_reseed;
+ c->reseed.arg = c;
+ strlcpy(c->reseed.name, name, sizeof(c->reseed.name));
+
+ mutex_init(&c->mtx, MUTEX_DEFAULT, ipl);
+
+ if (c->flags & CPRNG_USE_CV) {
+ cv_init(&c->cv, name);
+ }
+
+ r = rnd_extract_data(key, sizeof(key), RND_EXTRACT_GOOD);
+ if (r != sizeof(key)) {
+ if (c->flags & CPRNG_INIT_ANY) {
+ printf("cprng %s: WARNING insufficient "
+ "entropy at creation.\n", name);
+ rnd_extract_data(key + r, sizeof(key - r),
+ RND_EXTRACT_ANY);
+ } else {
+ return NULL;
+ }
+ getmore++;
+ }
+
+ if (nist_ctr_drbg_instantiate(&c->drbg, key, sizeof(key),
+ &cc, sizeof(cc), name, strlen(name))) {
+ panic("cprng %s: instantiation failed.", name);
+ }
+
+ if (getmore) {
+ int wr = 0;
+
+ /* Ask for more. */
+ c->reseed_pending = 1;
+ c->reseed.len = sizeof(key);
+ rndsink_attach(&c->reseed);
+ if (c->flags & CPRNG_USE_CV) {
+ mutex_enter(&c->mtx);
+ do {
+ wr = cv_wait_sig(&c->cv, &c->mtx);
+ if (__predict_true(wr == 0)) {
+ break;
+ }
+ if (wr == ERESTART) {
+ continue;
+ } else {
+ cv_destroy(&c->cv);
+ mutex_exit(&c->mtx);
+ mutex_destroy(&c->mtx);
+ kmem_free(c, sizeof(c));
+ return NULL;
+ }
+ } while (1);
+ mutex_exit(&c->mtx);
+ }
+ }
+ return c;
+}
+
+size_t
+cprng_strong(cprng_strong_t *const c, void *const p, size_t len)
+{
+ uint32_t cc = cprng_counter();
+
+ if (len > CPRNG_MAX_LEN) { /* XXX should we loop? */
+ len = CPRNG_MAX_LEN; /* let the caller loop if desired */
+ }
+
+ mutex_enter(&c->mtx);
+again:
+ if (nist_ctr_drbg_generate(&c->drbg, p, len, &cc, sizeof(cc))) {
+ /* A generator failure really means we hit the hard limit. */
+ if (c->flags & CPRNG_REKEY_ANY) {
+ uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
+
+ printf("cprng %s: WARNING pseudorandom rekeying.\n",
+ c->name);
+ rnd_extract_data(key, sizeof(key), RND_EXTRACT_ANY);
+ cc = cprng_counter();
+ if (nist_ctr_drbg_reseed(&c->drbg, key, sizeof(key),
+ &cc, sizeof(cc))) {
+ panic("cprng %s: nist_ctr_drbg_reseed "
+ "failed.", c->name);
+ }
+ if (c->flags & CPRNG_USE_CV) {
+ cv_broadcast(&c->cv); /* XXX unnecessary? */
+ }
+ } else {
+ if (c->flags & CPRNG_USE_CV) {
+ int wr;
+
+ do {
+ wr = cv_wait_sig(&c->cv, &c->mtx);
+ if (wr == EINTR) {
+ mutex_exit(&c->mtx);
+ return 0;
+ }
+ } while (nist_ctr_drbg_generate(&c->drbg, p,
+ len, &cc,
+ sizeof(cc)));
+ } else {
+ mutex_exit(&c->mtx);
+ return 0;
+ }
+ }
+ }
+
+#ifdef DIAGNOSTIC
+ /*
+ * If the generator has just been keyed, perform
+ * the statistical RNG test.
+ */
+ if (__predict_false(c->drbg.reseed_counter == 1)) {
+ rngtest_t rt;
+
+ strncpy(rt.rt_name, c->name, sizeof(rt.rt_name));
+
+ if (nist_ctr_drbg_generate(&c->drbg, rt.rt_b,
+ sizeof(rt.rt_b), NULL, 0)) {
+ panic("cprng %s: nist_ctr_drbg_generate failed!",
+ c->name);
+
+ }
+ if (rngtest(&rt)) {
+ printf("cprng %s: failed statistical RNG test.\n",
+ c->name);
+ c->drbg.reseed_counter =
+ NIST_CTR_DRBG_RESEED_INTERVAL + 1;
+ }
+
+ memset(&rt, 0, sizeof(rt));
+ }
+#endif
+ if (__predict_false(c->drbg.reseed_counter >
+ (NIST_CTR_DRBG_RESEED_INTERVAL / 2))) {
+ if (!(c->reseed_pending)) {
+ c->reseed_pending = 1;
+ c->reseed.len = NIST_BLOCK_KEYLEN_BYTES;
+ rndsink_attach(&c->reseed);
+ }
+ if (__predict_false(c->drbg.reseed_counter >
+ NIST_CTR_DRBG_RESEED_INTERVAL)) {
+ goto again; /* statistical test failure */
+ }
+ }
+
+ mutex_exit(&c->mtx);
+ return len;
+}
+
+void
+cprng_strong_destroy(cprng_strong_t *c)
+{
+ KASSERT(!mutex_owned(&c->mtx));
+ if (c->flags & CPRNG_USE_CV) {
+ KASSERT(!cv_has_waiters(&c->cv));
+ cv_destroy(&c->cv);
+ }
+
+ mutex_destroy(&c->mtx);
+ if (c->reseed_pending) {
+ rndsink_detach(&c->reseed);
+ }
+ nist_ctr_drbg_destroy(&c->drbg);
+ memset(c, 0, sizeof(*c));
+ kmem_free(c, sizeof(*c));
+}
+
+int
+cprng_strong_getflags(cprng_strong_t *const c)
+{
+ KASSERT(mutex_owned(&c->mtx));
+ return c->flags;
+}
+
+void
+cprng_strong_setflags(cprng_strong_t *const c, int flags)
+{
+ KASSERT(mutex_owned(&c->mtx));
+ if (flags & CPRNG_USE_CV) {
+ if (!(c->flags & CPRNG_USE_CV)) {
+ cv_init(&c->cv, (const char *)c->name);
+ }
+ } else {
+ if (c->flags & CPRNG_USE_CV) {
+ KASSERT(!cv_has_waiters(&c->cv));
+ cv_destroy(&c->cv);
+ }
+ }
+ if (flags & CPRNG_REKEY_ANY) {
+ if (!(c->flags & CPRNG_REKEY_ANY)) {
+ if (c->flags & CPRNG_USE_CV) {
+ cv_broadcast(&c->cv);
+ }
+ }
+ }
+ c->flags = flags;
+}
diff --git a/sys/lib/libkern/Makefile.libkern b/sys/lib/libkern/Makefile.libkern
index cc5adacff32..e15c16ca870 100644
--- a/sys/lib/libkern/Makefile.libkern
+++ b/sys/lib/libkern/Makefile.libkern
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.libkern,v 1.14 2011/08/26 21:22:10 dyoung Exp $
+# $NetBSD: Makefile.libkern,v 1.15 2011/11/19 22:51:25 tls Exp $
#
# Variable definitions for libkern.
@@ -82,6 +82,7 @@ SRCS+= strtoul.c strtoll.c strtoull.c strtoumax.c
SRCS+= scanc.c skpc.c
SRCS+= random.c
+SRCS+= rngtest.c
SRCS+= memchr.c
SRCS+= strcat.c strcmp.c strcpy.c strlen.c
diff --git a/sys/lib/libkern/arc4random.c b/sys/lib/libkern/arc4random.c
index 5a0b846a9f3..566befabd14 100644
--- a/sys/lib/libkern/arc4random.c
+++ b/sys/lib/libkern/arc4random.c
@@ -1,7 +1,7 @@
-/* $NetBSD: arc4random.c,v 1.21 2010/01/18 20:54:54 joerg Exp $ */
+/* $NetBSD: arc4random.c,v 1.22 2011/11/19 22:51:25 tls Exp $ */
/*-
- * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 2002, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -57,15 +57,44 @@
#endif
#include <sys/systm.h>
+#ifdef _KERNEL
+#include <sys/mutex.h>
+#include <sys/rngtest.h>
+#else
+#define mutex_spin_enter(x) ;
+#define mutex_spin_exit(x) ;
+#define mutex_init(x, y, z) ;
+#endif
+
#include <lib/libkern/libkern.h>
#if NRND > 0
#include <sys/rnd.h>
+
+rndsink_t rs;
+
#endif
-#define ARC4_MAXRUNS 16384
-#define ARC4_RESEED_SECONDS 300
-#define ARC4_KEYBYTES 32 /* 256 bit key */
+/*
+ * The best known attack that distinguishes RC4 output from a random
+ * bitstream requires 2^25 bytes. (see Paul and Preneel, Analysis of
+ * Non-fortuitous Predictive States of the RC4 Keystream Generator.
+ * INDOCRYPT 2003, pp52 – 67).
+ *
+ * However, we discard the first 1024 bytes of output, avoiding the
+ * biases detected in this paper. The best current attack that
+ * can distinguish this "RC4[drop]" output seems to be Fleuhrer &
+ * McGrew's attack which requires 2^30.6 bytes of output:
+ * Fluhrer and McGrew, Statistical Analysis of the Alleged RC4
+ * Keystream Generator. FSE 2000, pp19 – 30
+ *
+ * We begin trying to rekey at 2^24 bytes, and forcibly rekey at 2^29 bytes
+ * even if the resulting key cannot be guaranteed to have full entropy.
+ */
+#define ARC4_MAXBYTES (16 * 1024 * 1024)
+#define ARC4_HARDMAX (512 * 1024 * 1024)
+#define ARC4_RESEED_SECONDS 300
+#define ARC4_KEYBYTES 16 /* 128 bit key */
#ifdef _STANDALONE
#define time_uptime 1 /* XXX ugly! */
@@ -73,11 +102,17 @@
static u_int8_t arc4_i, arc4_j;
static int arc4_initialized = 0;
-static int arc4_numruns = 0;
+static int arc4_numbytes = 0;
static u_int8_t arc4_sbox[256];
static time_t arc4_nextreseed;
+#ifdef _KERNEL
+kmutex_t arc4_mtx;
+#endif
+
static inline u_int8_t arc4_randbyte(void);
+static inline void arc4randbytes_unlocked(void *, size_t);
+
static inline void
arc4_swap(u_int8_t *a, u_int8_t *b)
@@ -93,62 +128,119 @@ arc4_swap(u_int8_t *a, u_int8_t *b)
* Stir our S-box.
*/
static void
-arc4_randrekey(void)
+arc4_randrekey(void *arg)
{
u_int8_t key[256];
- static int cur_keybytes;
- int n, byteswanted;
+ int n, ask_for_more = 0;
+#ifdef _KERNEL
+ rngtest_t rt;
+#endif
#if NRND > 0
+ static int callback_pending;
int r;
#endif
- if(!arc4_initialized)
- /* The first time through, we must take what we can get */
- byteswanted = 0;
- else
- /* Don't rekey with less entropy than we already have */
- byteswanted = cur_keybytes;
-
+ /*
+ * The first time through, we must take what we can get,
+ * so schedule ourselves for callback no matter what.
+ */
+ if (__predict_true(arc4_initialized)) {
+ mutex_spin_enter(&arc4_mtx);
+ }
#if NRND > 0 /* XXX without rnd, we will key from the stack, ouch! */
- r = rnd_extract_data(key, ARC4_KEYBYTES, RND_EXTRACT_GOOD);
-
- if (r < ARC4_KEYBYTES) {
- if (r >= byteswanted) {
- (void)rnd_extract_data(key + r,
- ARC4_KEYBYTES - r,
- RND_EXTRACT_ANY);
- } else {
- /* don't replace a good key with a bad one! */
- arc4_nextreseed = time_uptime + ARC4_RESEED_SECONDS;
- arc4_numruns = 0;
- /* we should just ask rnd(4) to rekey us when
- it can, but for now, we'll just try later. */
- return;
- }
+ else {
+ ask_for_more = 1;
+ r = rnd_extract_data(key, ARC4_KEYBYTES, RND_EXTRACT_ANY);
+ goto got_entropy;
}
- cur_keybytes = r;
-
- for (n = ARC4_KEYBYTES; n < sizeof(key); n++)
- key[n] = key[n % ARC4_KEYBYTES];
-#endif
- for (n = 0; n < 256; n++) {
- arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256;
- arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);
+ if (arg == NULL) {
+ if (callback_pending) {
+ if (arc4_numbytes > ARC4_HARDMAX) {
+ printf("arc4random: WARNING, hit 2^29 bytes, "
+ "forcibly rekeying.\n");
+ r = rnd_extract_data(key, ARC4_KEYBYTES,
+ RND_EXTRACT_ANY);
+ rndsink_detach(&rs);
+ callback_pending = 0;
+ goto got_entropy;
+ } else {
+ mutex_spin_exit(&arc4_mtx);
+ return;
+ }
+ }
+ r = rnd_extract_data(key, ARC4_KEYBYTES, RND_EXTRACT_GOOD);
+ if (r < ARC4_KEYBYTES) {
+ ask_for_more = 1;
+ }
+ } else {
+ ask_for_more = 0;
+ callback_pending = 0;
+ if (rs.len != ARC4_KEYBYTES) {
+ panic("arc4_randrekey: rekey callback bad length");
+ }
+ memcpy(key, rs.data, rs.len);
+ memset(rs.data, 0, rs.len);
}
- arc4_i = arc4_j;
-
- /* Reset for next reseed cycle. */
- arc4_nextreseed = time_uptime + ARC4_RESEED_SECONDS;
- arc4_numruns = 0;
+got_entropy:
+
+ if (!ask_for_more) {
+ callback_pending = 0;
+ } else if (!callback_pending) {
+ callback_pending = 1;
+ strlcpy(rs.name, "arc4random", sizeof(rs.name));
+ rs.cb = arc4_randrekey;
+ rs.arg = &rs;
+ rs.len = ARC4_KEYBYTES;
+ rndsink_attach(&rs);
+ }
+#endif
/*
- * Throw away the first N words of output, as suggested in the
- * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
- * by Fluher, Mantin, and Shamir. (N = 256 in our case.)
+ * If it's the first time, or we got a good key, actually rekey.
*/
- for (n = 0; n < 256 * 4; n++)
- arc4_randbyte();
+ if (!ask_for_more || !arc4_initialized) {
+ for (n = ARC4_KEYBYTES; n < sizeof(key); n++)
+ key[n] = key[n % ARC4_KEYBYTES];
+
+ for (n = 0; n < 256; n++) {
+ arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256;
+ arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);
+ }
+ arc4_i = arc4_j;
+
+ memset(key, 0, sizeof(key));
+ /*
+ * Throw away the first N words of output, as suggested in the
+ * paper "Weaknesses in the Key Scheduling Algorithm of RC4"
+ * by Fluher, Mantin, and Shamir. (N = 256 in our case.)
+ */
+ for (n = 0; n < 256 * 4; n++)
+ arc4_randbyte();
+
+ /* Reset for next reseed cycle. */
+ arc4_nextreseed = time_uptime + ARC4_RESEED_SECONDS;
+ arc4_numbytes = 0;
+#ifdef _KERNEL
+#ifdef DIAGNOSTIC
+ /*
+ * Perform the FIPS 140-2 statistical RNG test; warn if our
+ * output has such poor quality as to fail the test.
+ */
+ arc4randbytes_unlocked(rt.rt_b, sizeof(rt.rt_b));
+ strlcpy(rt.rt_name, "arc4random", sizeof(rt.rt_name));
+ if (rngtest(&rt)) {
+ /* rngtest will scream to the console. */
+ arc4_nextreseed = time_uptime;
+ arc4_numbytes = ARC4_MAXBYTES;
+ /* XXX should keep old context around, *NOT* use new */
+ }
+#endif
+#endif
+ }
+ if (__predict_true(arc4_initialized)) {
+ mutex_spin_exit(&arc4_mtx);
+ }
}
/*
@@ -159,11 +251,12 @@ arc4_init(void)
{
int n;
+ mutex_init(&arc4_mtx, MUTEX_DEFAULT, IPL_VM);
arc4_i = arc4_j = 0;
for (n = 0; n < 256; n++)
arc4_sbox[n] = (u_int8_t) n;
- arc4_randrekey();
+ arc4_randrekey(NULL);
arc4_initialized = 1;
}
@@ -187,40 +280,40 @@ arc4_randbyte(void)
u_int32_t
arc4random(void)
{
- u_int32_t ret;
- int i;
+ int ret;
+ u_int8_t *retc;
- /* Initialize array if needed. */
- if (!arc4_initialized)
- arc4_init();
+ retc = (u_int8_t *)&ret;
- if ((++arc4_numruns > ARC4_MAXRUNS) ||
- (time_uptime > arc4_nextreseed)) {
- arc4_randrekey();
- }
+ arc4randbytes(retc, sizeof(u_int32_t));
+ return ret;
+}
- for (i = 0, ret = 0; i <= 24; ret |= arc4_randbyte() << i, i += 8)
+static inline void
+arc4randbytes_unlocked(void *p, size_t len)
+{
+ u_int8_t *buf = (u_int8_t *)p;
+ size_t i;
+
+ for (i = 0; i < len; buf[i] = arc4_randbyte(), i++)
continue;
- return ret;
}
void
arc4randbytes(void *p, size_t len)
{
- u_int8_t *buf;
- size_t i;
-
/* Initialize array if needed. */
- if (!arc4_initialized)
+ if (!arc4_initialized) {
arc4_init();
-
- buf = (u_int8_t *)p;
-
- for (i = 0; i < len; buf[i] = arc4_randbyte(), i++)
- continue;
- arc4_numruns += len / sizeof(u_int32_t);
- if ((arc4_numruns > ARC4_MAXRUNS) ||
+ /* avoid conditionalizing locking */
+ return arc4randbytes_unlocked(p, len);
+ }
+ mutex_spin_enter(&arc4_mtx);
+ arc4randbytes_unlocked(p, len);
+ arc4_numbytes += len;
+ mutex_spin_exit(&arc4_mtx);
+ if ((arc4_numbytes > ARC4_MAXBYTES) ||
(time_uptime > arc4_nextreseed)) {
- arc4_randrekey();
+ arc4_randrekey(NULL);
}
}
diff --git a/sys/lib/libkern/rngtest.c b/sys/lib/libkern/rngtest.c
new file mode 100644
index 00000000000..d423d40e39b
--- /dev/null
+++ b/sys/lib/libkern/rngtest.c
@@ -0,0 +1,281 @@
+/* $NetBSD: rngtest.c,v 1.1 2011/11/19 22:51:25 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* fips140.c 1.5 (Qualcomm) 02/09/02 */
+/*
+This software is free for commercial and non-commercial use
+subject to the following conditions.
+
+Copyright remains vested in QUALCOMM Incorporated, and Copyright
+notices in the code are not to be removed. If this package is used in
+a product, QUALCOMM should be given attribution as the author this
+software. This can be in the form of a textual message at program
+startup or in documentation (online or textual) provided with the
+package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the copyright notice,
+ this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the
+ distribution.
+
+3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgement: This product
+ includes software developed by QUALCOMM Incorporated.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+The license and distribution terms for any publically available version
+or derivative of this code cannot be changed, that is, this code cannot
+simply be copied and put under another distribution license including
+the GNU Public License.
+*/
+
+/* Run FIPS 140 statistical tests on a file */
+
+/* written by Greg Rose, Copyright C 2000 QUALCOMM Incorporated */
+
+/*
+ * Modified for in-kernel use (API adjustments, conversion from
+ * floating to fixed-point chi-sq computation) by Thor Lancelot
+ * Simon.
+ *
+ * A comment on appropriate use of this test and the infamous FIPS 140
+ * "continuous output test" (COT): Both tests are very appropriate for
+ * software interfaces to hardware implementations, and will quickly tell
+ * you if any number of very bad things have happened to your RNG: perhaps
+ * it has come disconnected from the rest of the system, somehow, and you
+ * are getting only unconditioned bus noise (read: clock edges from the
+ * loudest thing in your system). Perhaps it has ceased to latch a shift
+ * register and is feeding you the same data over and over again. Perhaps
+ * it is not really random at all but was sold to you as such. Perhaps it
+ * is not actually *there* (Intel chipset RNG anyone?) but claims to be,
+ * and is feeding you 01010101 on every register read.
+ *
+ * However, when applied to software RNGs, the situation is quite different.
+ * Most software RNGs use a modern hash function or cipher as an output
+ * stage. The resulting bitstream assuredly *should* pass both the
+ * "continuous output" (no two consecutive samples identical) and
+ * statistical tests: if it does not, the cryptographic primitive or its
+ * implementation is terribly broken.
+ *
+ * There is still value to this test: it will tell you if you inadvertently
+ * terribly break your implementation of the software RNG. Which is a thing
+ * that has in fact happened from time to time, even to the careful (or
+ * paranoid). But it will not tell you if there is a problem with the
+ * _input_ to that final cryptographic primitive -- the bits that are hashed
+ * or the key to the cipher -- and if an adversary can find one, you're
+ * still toast.
+ *
+ * The situation is -- sadly -- similar with hardware RNGs that are
+ * certified to one of the standards such as X9.31 or SP800-90. In these
+ * cases the hardware vendor has hidden the actual random bitstream behind
+ * a hardware cipher/hash implementation that should, indeed, produce good
+ * quality random numbers that pass will pass this test -- whether the
+ * underlying bitstream is trustworthy or not.
+ *
+ * However, this test (and the COT) will still probably tell you if the
+ * thing fell off the bus, etc. Which is a thing that has in fact
+ * happened from time to time, even to the fully certified...
+ *
+ * This module does not (yet?) implement the Continuous Output Test. When
+ * I call that test "infamous", it's because it obviously reduces the
+ * backtracking resistance of any implementation that includes it -- the
+ * implementation has to store the entire previous RNG output in order to
+ * perform the required comparison; not just periodically but all the time
+ * when operating at all. Nonetheless, it has obvious value for
+ * hardware implementations where it will quickly and surely detect a
+ * severe failure; but as of this writing several of the latest comments
+ * on SP800-90 recommend removing any requirement for the COT and my
+ * personal tendency is to agree. It's easy to add if you really need it.
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/rngtest.h>
+
+#include <lib/libkern/libkern.h>
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: rngtest.c,v 1.1 2011/11/19 22:51:25 tls Exp $");
+
+#ifndef _KERNEL
+static inline int
+printf(const char *restrict format, ...)
+{
+ return 0; /* XXX no standard way to do output in libkern? */
+}
+#endif
+
+int bitnum = 0;
+
+const int minrun[7] = {0, 2315, 1114, 527, 240, 103, 103};
+const int maxrun[7] = {0, 2685, 1386, 723, 384, 209, 209};
+#define LONGRUN 26
+#define MINONES 9725
+#define MAXONES 10275
+#define MINPOKE 2.16
+#define MAXPOKE 46.17
+#define PRECISION 100000
+
+const int longrun = LONGRUN;
+const int minones = MINONES;
+const int maxones = MAXONES;
+const long long minpoke = (MINPOKE * PRECISION);
+const long long maxpoke = (MAXPOKE * PRECISION);
+
+/* Population count of 1's in a byte */
+const unsigned char Popcount[] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
+
+/* end of run */
+static void
+endrun(rngtest_t *const rc, const int last, int run)
+{
+ if (run >= longrun) {
+ printf("Kernel RNG \"%s\" long run test FAILURE: "
+ "Run of %d %ds found\n", rc->rt_name, run, last);
+ ++rc->rt_nerrs;
+ }
+ if (run > 6)
+ run = 6;
+ ++rc->rt_runs[last][run];
+}
+
+int
+rngtest(rngtest_t *const rc)
+{
+ int i;
+ uint8_t *p;
+ int c;
+ long long X;
+ int last;
+ int run;
+
+ /* Enforce sanity for most members of the context */
+ memset(rc->rt_poker, 0, sizeof(rc->rt_poker));
+ memset(rc->rt_runs, 0, sizeof(rc->rt_runs));
+ rc->rt_nerrs = 0;
+ rc->rt_name[sizeof(rc->rt_name) - 1] = '\0';
+
+ /* monobit test */
+ for (p = rc->rt_b, c = 0; p < &rc->rt_b[sizeof rc->rt_b]; ++p)
+ c += Popcount[*p];
+ if (c <= minones || maxones <= c) {
+ printf("Kernel RNG \"%s\" monobit test FAILURE: %d ones\n",
+ rc->rt_name, c);
+ ++rc->rt_nerrs;
+ }
+ /* poker test */
+ for (p = rc->rt_b; p < &rc->rt_b[sizeof rc->rt_b]; ++p) {
+ ++rc->rt_poker[*p & 0xF];
+ ++rc->rt_poker[(*p >> 4) & 0xF];
+ }
+ for (X = i = 0; i < 16; ++i) {
+ X += rc->rt_poker[i] * rc->rt_poker[i];
+ }
+ X *= PRECISION;
+ X = 16 * X / 5000 - 5000 * PRECISION;
+ if (X <= minpoke || maxpoke <= X) {
+ printf("Kernel RNG \"%s\" poker test failure: "
+ "parameter X = %lld.%lld\n", rc->rt_name,
+ (X / PRECISION), (X % PRECISION));
+ ++rc->rt_nerrs;
+ }
+ /* runs test */
+ last = (rc->rt_b[0] >> 7) & 1;
+ run = 0;
+ for (p = rc->rt_b; p < &rc->rt_b[sizeof rc->rt_b]; ++p) {
+ c = *p;
+ for (i = 7; i >= 0; --i) {
+ if (((c >> i) & 1) != last) {
+ endrun(rc, last, run);
+ run = 0;
+ last = (c >> i) & 1;
+ }
+ ++run;
+ }
+ }
+ endrun(rc, last, run);
+
+ for (run = 1; run <= 6; ++run) {
+ for (last = 0; last <= 1; ++last) {
+ if (rc->rt_runs[last][run] <= minrun[run]) {
+ printf("Kernel RNG \"%s\" runs test FAILURE: "
+ "too few runs of %d %ds (%d < %d)\n",
+ rc->rt_name, run, last,
+ rc->rt_runs[last][run], minrun[run]);
+ ++rc->rt_nerrs;
+ } else if (rc->rt_runs[last][run] >= maxrun[run]) {
+ printf("Kernel RNG \"%s\" runs test FAILURE: "
+ "too many runs of %d %ds (%d > %d)\n",
+ rc->rt_name, run, last,
+ rc->rt_runs[last][run], maxrun[run]);
+ ++rc->rt_nerrs;
+ }
+ }
+ }
+ memset(rc->rt_b, 0, sizeof(rc->rt_b));
+ return rc->rt_nerrs;
+}
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index d3b4b09ab43..429d36fc6eb 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bridge.c,v 1.73 2011/05/23 21:52:54 joerg Exp $ */
+/* $NetBSD: if_bridge.c,v 1.74 2011/11/19 22:51:25 tls Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.73 2011/05/23 21:52:54 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.74 2011/11/19 22:51:25 tls Exp $");
#ifdef _KERNEL_OPT
#include "opt_bridge_ipf.h"
@@ -100,6 +100,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.73 2011/05/23 21:52:54 joerg Exp $")
#include <sys/pool.h>
#include <sys/kauth.h>
#include <sys/cpu.h>
+#include <sys/cprng.h>
#include <net/bpf.h>
#include <net/if.h>
@@ -1848,7 +1849,7 @@ bridge_rtable_init(struct bridge_softc *sc)
for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
LIST_INIT(&sc->sc_rthash[i]);
- sc->sc_rthash_key = arc4random();
+ sc->sc_rthash_key = cprng_fast32();
LIST_INIT(&sc->sc_rtlist);
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c
index a421fb182a2..fcb7749bf68 100644
--- a/sys/net/if_spppsubr.c
+++ b/sys/net/if_spppsubr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_spppsubr.c,v 1.123 2011/10/28 22:08:14 dyoung Exp $ */
+/* $NetBSD: if_spppsubr.c,v 1.124 2011/11/19 22:51:25 tls Exp $ */
/*
* Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.123 2011/10/28 22:08:14 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.124 2011/11/19 22:51:25 tls Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -66,6 +66,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.123 2011/10/28 22:08:14 dyoung Exp
#include <sys/md5.h>
#include <sys/inttypes.h>
#include <sys/kauth.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/netisr.h>
@@ -1202,7 +1203,7 @@ sppp_cisco_input(struct sppp *sp, struct mbuf *m)
++sp->pp_loopcnt;
/* Generate new local sequence number */
- sp->pp_seq[IDX_LCP] = arc4random();
+ sp->pp_seq[IDX_LCP] = cprng_fast32();
break;
}
sp->pp_loopcnt = 0;
@@ -2481,7 +2482,7 @@ sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len)
if (magic == ~sp->lcp.magic) {
if (debug)
addlog(" magic glitch");
- sp->lcp.magic = arc4random();
+ sp->lcp.magic = cprng_fast32();
} else {
sp->lcp.magic = magic;
if (debug)
@@ -2665,7 +2666,7 @@ sppp_lcp_scr(struct sppp *sp)
if (sp->lcp.opts & (1 << LCP_OPT_MAGIC)) {
if (! sp->lcp.magic)
- sp->lcp.magic = arc4random();
+ sp->lcp.magic = cprng_fast32();
opt[i++] = LCP_OPT_MAGIC;
opt[i++] = 6;
opt[i++] = sp->lcp.magic >> 24;
@@ -4229,7 +4230,7 @@ sppp_chap_tlu(struct sppp *sp)
* Compute the re-challenge timeout. This will yield
* a number between 300 and 810 seconds.
*/
- i = 300 + ((unsigned)(arc4random() & 0xff00) >> 7);
+ i = 300 + ((unsigned)(cprng_fast32() & 0xff00) >> 7);
callout_reset(&sp->ch[IDX_CHAP], i * hz, chap.TO, sp);
}
@@ -4286,7 +4287,7 @@ static void
sppp_chap_scr(struct sppp *sp)
{
uint32_t *ch;
- u_char clen;
+ u_char clen = 4 * sizeof(uint32_t);
if (sp->myauth.name == NULL) {
/* can't do anything useful */
@@ -4297,11 +4298,7 @@ sppp_chap_scr(struct sppp *sp)
/* Compute random challenge. */
ch = (uint32_t *)sp->myauth.challenge;
- ch[0] = arc4random();
- ch[1] = arc4random();
- ch[2] = arc4random();
- ch[3] = arc4random();
- clen = 16; /* 4 * sizeof(uint32_t) */
+ cprng_strong(kern_cprng, ch, clen);
sp->confid[IDX_CHAP] = ++sp->pp_seq[IDX_CHAP];
diff --git a/sys/net/npf/npf_nat.c b/sys/net/npf/npf_nat.c
index 93c62546ac7..e3fec80e060 100644
--- a/sys/net/npf/npf_nat.c
+++ b/sys/net/npf/npf_nat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_nat.c,v 1.7 2011/11/04 01:00:27 zoltan Exp $ */
+/* $NetBSD: npf_nat.c,v 1.8 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.7 2011/11/04 01:00:27 zoltan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.8 2011/11/19 22:51:25 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -87,6 +87,8 @@ __KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.7 2011/11/04 01:00:27 zoltan Exp $");
#include <sys/kmem.h>
#include <sys/mutex.h>
#include <sys/pool.h>
+#include <sys/cprng.h>
+
#include <net/pfil.h>
#include <netinet/in.h>
@@ -319,7 +321,7 @@ npf_nat_getport(npf_natpolicy_t *np)
u_int n = PORTMAP_SIZE, idx, bit;
uint32_t map, nmap;
- idx = arc4random() % PORTMAP_SIZE;
+ idx = cprng_fast32() % PORTMAP_SIZE;
for (;;) {
KASSERT(idx < PORTMAP_SIZE);
map = pm->p_bitmap[idx];
diff --git a/sys/net80211/ieee80211_netbsd.c b/sys/net80211/ieee80211_netbsd.c
index f6e59c719a1..5db11cf60e1 100644
--- a/sys/net80211/ieee80211_netbsd.c
+++ b/sys/net80211/ieee80211_netbsd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ieee80211_netbsd.c,v 1.19 2011/10/07 16:51:45 dyoung Exp $ */
+/* $NetBSD: ieee80211_netbsd.c,v 1.20 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 2003-2005 Sam Leffler, Errno Consulting
* All rights reserved.
@@ -30,7 +30,7 @@
#ifdef __FreeBSD__
__FBSDID("$FreeBSD: src/sys/net80211/ieee80211_freebsd.c,v 1.8 2005/08/08 18:46:35 sam Exp $");
#else
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.19 2011/10/07 16:51:45 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.20 2011/11/19 22:51:25 tls Exp $");
#endif
/*
@@ -46,6 +46,8 @@ __KERNEL_RCSID(0, "$NetBSD: ieee80211_netbsd.c,v 1.19 2011/10/07 16:51:45 dyoung
#include <sys/socket.h>
+#include <sys/cprng.h>
+
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_ether.h>
@@ -640,14 +642,7 @@ ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen)
void
get_random_bytes(void *p, size_t n)
{
- u_int8_t *dp = p;
-
- while (n > 0) {
- u_int32_t v = arc4random();
- size_t nb = n > sizeof(u_int32_t) ? sizeof(u_int32_t) : n;
- (void)memcpy(dp, &v, nb);
- dp += sizeof(u_int32_t), n -= nb;
- }
+ cprng_fast(p, n);
}
void
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 07aea7195ff..edd5cda6e2a 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in.c,v 1.140 2011/10/28 22:23:54 dyoung Exp $ */
+/* $NetBSD: in.c,v 1.141 2011/11/19 22:51:25 tls Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.140 2011/10/28 22:23:54 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.141 2011/11/19 22:51:25 tls Exp $");
#include "opt_inet.h"
#include "opt_inet_conf.h"
@@ -110,6 +110,8 @@ __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.140 2011/10/28 22:23:54 dyoung Exp $");
#include <sys/syslog.h>
#include <sys/kauth.h>
+#include <sys/cprng.h>
+
#include <net/if.h>
#include <net/route.h>
@@ -401,7 +403,7 @@ in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp,
ia->ia_broadaddr.sin_family = AF_INET;
}
ia->ia_ifp = ifp;
- ia->ia_idsalt = arc4random() % 65535;
+ ia->ia_idsalt = cprng_fast32() % 65535;
LIST_INIT(&ia->ia_multiaddrs);
newifaddr = 1;
}
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 1c5b6a5496b..1432f532a98 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_carp.c,v 1.46 2011/10/19 01:52:22 dyoung Exp $ */
+/* $NetBSD: ip_carp.c,v 1.47 2011/11/19 22:51:25 tls Exp $ */
/* $OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $ */
/*
@@ -30,7 +30,7 @@
#include "opt_inet.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.46 2011/10/19 01:52:22 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.47 2011/11/19 22:51:25 tls Exp $");
/*
* TODO:
@@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.46 2011/10/19 01:52:22 dyoung Exp $");
#include <sys/ucred.h>
#include <sys/syslog.h>
#include <sys/acct.h>
+#include <sys/cprng.h>
#include <sys/cpu.h>
@@ -877,9 +878,7 @@ carp_prepare_ad(struct mbuf *m, struct carp_softc *sc,
{
if (sc->sc_init_counter) {
/* this could also be seconds since unix epoch */
- sc->sc_counter = arc4random();
- sc->sc_counter = sc->sc_counter << 32;
- sc->sc_counter += arc4random();
+ sc->sc_counter = cprng_fast64();
} else
sc->sc_counter++;
diff --git a/sys/netinet/ip_id.c b/sys/netinet/ip_id.c
index 3df99561073..2a56a96c812 100644
--- a/sys/netinet/ip_id.c
+++ b/sys/netinet/ip_id.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_id.c,v 1.14 2010/11/05 01:35:57 rmind Exp $ */
+/* $NetBSD: ip_id.c,v 1.15 2011/11/19 22:51:25 tls Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -30,11 +30,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_id.c,v 1.14 2010/11/05 01:35:57 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_id.c,v 1.15 2011/11/19 22:51:25 tls Exp $");
#include <sys/param.h>
#include <sys/kmem.h>
#include <sys/mutex.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -54,7 +55,7 @@ struct ipid_state {
static inline uint32_t
ipid_random(void)
{
- return arc4random();
+ return cprng_fast32();
}
/*
diff --git a/sys/netinet/rfc6056.c b/sys/netinet/rfc6056.c
index bac5f4c5bce..529e51b7143 100644
--- a/sys/netinet/rfc6056.c
+++ b/sys/netinet/rfc6056.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rfc6056.c,v 1.3 2011/09/25 11:54:28 mrg Exp $ */
+/* $NetBSD: rfc6056.c,v 1.4 2011/11/19 22:51:25 tls Exp $ */
/*
* Copyright 2011 Vlad Balan
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfc6056.c,v 1.3 2011/09/25 11:54:28 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfc6056.c,v 1.4 2011/11/19 22:51:25 tls Exp $");
#include "opt_inet.h"
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: rfc6056.c,v 1.3 2011/09/25 11:54:28 mrg Exp $");
#include <sys/uidinfo.h>
#include <sys/domain.h>
#include <sys/md5.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/route.h>
@@ -427,7 +428,7 @@ algo_random_start(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr,
DPRINTF("num_ephemeral: %u\n", num_ephemeral);
- *next_ephemeral = mymin + (arc4random() % num_ephemeral);
+ *next_ephemeral = mymin + (cprng_fast32() % num_ephemeral);
DPRINTF("next_ephemeral initially: %u\n", *next_ephemeral);
@@ -480,7 +481,7 @@ algo_random_pick(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr,
num_ephemeral = mymax - mymin + 1;
DPRINTF("num_ephemeral: %u\n", num_ephemeral);
- *next_ephemeral = mymin + (arc4random() % num_ephemeral);
+ *next_ephemeral = mymin + (cprng_fast32() % num_ephemeral);
DPRINTF("next_ephemeral initially: %u\n", *next_ephemeral);
@@ -493,7 +494,7 @@ algo_random_pick(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr,
return 0;
}
*next_ephemeral = mymin +
- (arc4random() % num_ephemeral);
+ (cprng_fast32() % num_ephemeral);
count--;
@@ -516,10 +517,7 @@ Fhash(const struct inpcb_hdr *inp_hdr)
uint32_t offset;
uint16_t soffset[2];
- secret_f[0] = arc4random();
- secret_f[1] = arc4random();
- secret_f[2] = arc4random();
- secret_f[3] = arc4random();
+ cprng_fast(secret_f, sizeof(secret_f));
MD5Init(&f_ctx);
switch (inp_hdr->inph_af) {
@@ -732,7 +730,7 @@ algo_randinc(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr,
return error;
if (*next_ephemeral == 0)
- *next_ephemeral = arc4random() & 0xffff;
+ *next_ephemeral = cprng_fast32() & 0xffff;
/* Ephemeral port selection function */
num_ephemeral = mymax - mymin + 1;
@@ -740,7 +738,7 @@ algo_randinc(int algo, uint16_t *port, struct inpcb_hdr *inp_hdr,
count = num_ephemeral;
do {
*next_ephemeral = *next_ephemeral +
- (arc4random() % N) + 1;
+ (cprng_fast32() % N) + 1;
myport = mymin +
(*next_ephemeral % num_ephemeral);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 11256c58278..d7ea712c3c8 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tcp_input.c,v 1.317 2011/10/31 13:01:42 yamt Exp $ */
+/* $NetBSD: tcp_input.c,v 1.318 2011/11/19 22:51:25 tls Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -148,7 +148,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.317 2011/10/31 13:01:42 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.318 2011/11/19 22:51:25 tls Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@@ -171,6 +171,7 @@ __KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.317 2011/10/31 13:01:42 yamt Exp $")
#include <sys/md5.h>
#endif
#include <sys/lwp.h> /* for lwp0 */
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/route.h>
@@ -3710,8 +3711,8 @@ syn_cache_insert(struct syn_cache *sc, struct tcpcb *tp)
* the hash secrets.
*/
if (syn_cache_count == 0) {
- syn_hash1 = arc4random();
- syn_hash2 = arc4random();
+ syn_hash1 = cprng_fast32();
+ syn_hash2 = cprng_fast32();
}
SYN_HASHALL(sc->sc_hash, &sc->sc_src.sa, &sc->sc_dst.sa);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 2405bfa876d..6db1c3e3b68 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tcp_subr.c,v 1.242 2011/10/31 12:56:45 yamt Exp $ */
+/* $NetBSD: tcp_subr.c,v 1.243 2011/11/19 22:51:26 tls Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,14 +91,13 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.242 2011/10/31 12:56:45 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.243 2011/11/19 22:51:26 tls Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_tcp_compat_42.h"
#include "opt_inet_csum.h"
#include "opt_mbuftrace.h"
-#include "rnd.h"
#include <sys/param.h>
#include <sys/proc.h>
@@ -111,10 +110,8 @@ __KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.242 2011/10/31 12:56:45 yamt Exp $");
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/pool.h>
-#if NRND > 0
#include <sys/md5.h>
-#include <sys/rnd.h>
-#endif
+#include <sys/cprng.h>
#include <net/route.h>
#include <net/if.h>
@@ -174,9 +171,7 @@ int tcp_mssdflt = TCP_MSS;
int tcp_minmss = TCP_MINMSS;
int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
int tcp_do_rfc1323 = 1; /* window scaling / timestamps (obsolete) */
-#if NRND > 0
int tcp_do_rfc1948 = 0; /* ISS by cryptographic hash */
-#endif
int tcp_do_sack = 1; /* selective acknowledgement */
int tcp_do_win_scale = 1; /* RFC1323 window scaling */
int tcp_do_timestamps = 1; /* RFC1323 timestamps */
@@ -2179,9 +2174,7 @@ tcp_rmx_rtt(struct tcpcb *tp)
}
tcp_seq tcp_iss_seq = 0; /* tcp initial seq # */
-#if NRND > 0
u_int8_t tcp_iss_secret[16]; /* 128 bits; should be plenty */
-#endif
/*
* Get a new sequence value given a tcp control block
@@ -2219,7 +2212,6 @@ tcp_new_iss1(void *laddr, void *faddr, u_int16_t lport, u_int16_t fport,
{
tcp_seq tcp_iss;
-#if NRND > 0
static bool tcp_iss_gotten_secret;
/*
@@ -2227,8 +2219,8 @@ tcp_new_iss1(void *laddr, void *faddr, u_int16_t lport, u_int16_t fport,
* hash secret.
*/
if (tcp_iss_gotten_secret == false) {
- rnd_extract_data(tcp_iss_secret, sizeof(tcp_iss_secret),
- RND_EXTRACT_ANY);
+ cprng_strong(kern_cprng,
+ tcp_iss_secret, sizeof(tcp_iss_secret));
tcp_iss_gotten_secret = true;
}
@@ -2269,17 +2261,11 @@ tcp_new_iss1(void *laddr, void *faddr, u_int16_t lport, u_int16_t fport,
#ifdef TCPISS_DEBUG
printf("new ISS 0x%08x\n", tcp_iss);
#endif
- } else
-#endif /* NRND > 0 */
- {
+ } else {
/*
* Randomize.
*/
-#if NRND > 0
- rnd_extract_data(&tcp_iss, sizeof(tcp_iss), RND_EXTRACT_ANY);
-#else
- tcp_iss = arc4random();
-#endif
+ tcp_iss = cprng_fast32();
/*
* If we were asked to add some amount to a known value,
diff --git a/sys/netinet6/files.ipsec b/sys/netinet6/files.ipsec
index 4bdb5a01061..9b2557f0fd3 100644
--- a/sys/netinet6/files.ipsec
+++ b/sys/netinet6/files.ipsec
@@ -1,7 +1,7 @@
-# $NetBSD: files.ipsec,v 1.5 2006/10/27 21:20:48 christos Exp $
+# $NetBSD: files.ipsec,v 1.6 2011/11/19 22:51:26 tls Exp $
-defflag opt_ipsec.h IPSEC: rijndael
-defflag opt_ipsec.h IPSEC_ESP: des, blowfish, cast128, rijndael
+defflag opt_ipsec.h IPSEC
+defflag opt_ipsec.h IPSEC_ESP: des, blowfish, cast128
defflag opt_ipsec.h IPSEC_NAT_T
file netinet6/ah_aesxcbcmac.c ipsec
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index fe979abf837..dc8987b869f 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in6.c,v 1.158 2011/10/19 01:53:07 dyoung Exp $ */
+/* $NetBSD: in6.c,v 1.159 2011/11/19 22:51:26 tls Exp $ */
/* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.158 2011/10/19 01:53:07 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.159 2011/11/19 22:51:26 tls Exp $");
#include "opt_inet.h"
#include "opt_pfil_hooks.h"
@@ -81,6 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.158 2011/10/19 01:53:07 dyoung Exp $");
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <sys/kauth.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -1119,7 +1120,7 @@ in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra,
* avoid report collision.
* [draft-ietf-ipv6-rfc2462bis-02.txt]
*/
- dad_delay = arc4random() %
+ dad_delay = cprng_fast32() %
(MAX_RTR_SOLICITATION_DELAY * hz);
}
@@ -1210,7 +1211,7 @@ in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra,
* The spec doesn't say anything about delay for this
* group, but the same logic should apply.
*/
- dad_delay = arc4random() %
+ dad_delay = cprng_fast32() %
(MAX_RTR_SOLICITATION_DELAY * hz);
}
if (in6_nigroup(ifp, hostname, hostnamelen, &mltaddr) != 0)
@@ -1318,7 +1319,7 @@ in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra,
dad_delay = 0;
else {
dad_delay =
- (arc4random() % (maxdelay - mindelay)) +
+ (cprng_fast32() % (maxdelay - mindelay)) +
mindelay;
}
}
@@ -2157,7 +2158,8 @@ in6_if_up(struct ifnet *ifp)
* case, but we impose delays just in case.
*/
nd6_dad_start(ifa,
- arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz));
+ cprng_fast32() %
+ (MAX_RTR_SOLICITATION_DELAY * hz));
}
}
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 06bc9030c9b..0b966bec16e 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -1,4 +1,4 @@
-/* $NetBSD: in6_ifattach.c,v 1.85 2009/09/19 13:11:02 christos Exp $ */
+/* $NetBSD: in6_ifattach.c,v 1.86 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.85 2009/09/19 13:11:02 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.86 2011/11/19 22:51:29 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.85 2009/09/19 13:11:02 christos E
#include <sys/syslog.h>
#include <sys/md5.h>
#include <sys/socketvar.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_dl.h>
@@ -177,7 +178,6 @@ generate_tmp_ifid(u_int8_t *seed0, const u_int8_t *seed1, u_int8_t *ret)
{
MD5_CTX ctxt;
u_int8_t seed[16], digest[16], nullbuf[8];
- u_int32_t val32;
/*
* interface ID for subnet anycast addresses.
* XXX: we assume the unicast address range that requires IDs
@@ -191,12 +191,7 @@ generate_tmp_ifid(u_int8_t *seed0, const u_int8_t *seed1, u_int8_t *ret)
/* If there's no hisotry, start with a random seed. */
memset(nullbuf, 0, sizeof(nullbuf));
if (memcmp(nullbuf, seed0, sizeof(nullbuf)) == 0) {
- int i;
-
- for (i = 0; i < 2; i++) {
- val32 = arc4random();
- memcpy(seed + sizeof(val32) * i, &val32, sizeof(val32));
- }
+ cprng_fast(seed, sizeof(seed));
} else
memcpy(seed, seed0, 8);
diff --git a/sys/netinet6/ip6_id.c b/sys/netinet6/ip6_id.c
index 6d688348a26..f789cf097be 100644
--- a/sys/netinet6/ip6_id.c
+++ b/sys/netinet6/ip6_id.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_id.c,v 1.16 2006/08/30 17:11:53 christos Exp $ */
+/* $NetBSD: ip6_id.c,v 1.17 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: ip6_id.c,v 1.8 2003/09/06 13:41:06 itojun Exp $ */
/* $OpenBSD: ip_id.c,v 1.6 2002/03/15 18:19:52 millert Exp $ */
@@ -82,9 +82,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_id.c,v 1.16 2006/08/30 17:11:53 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_id.c,v 1.17 2011/11/19 22:51:29 tls Exp $");
#include <sys/param.h>
+#include <sys/cprng.h>
+
#include <lib/libkern/libkern.h>
#include <net/if.h>
@@ -175,20 +177,20 @@ initid(struct randomtab *p)
u_int32_t j, i;
int noprime = 1;
- p->ru_x = arc4random() % p->ru_m;
+ p->ru_x = cprng_fast32() % p->ru_m;
/* (bits - 1) bits of random seed */
- p->ru_seed = arc4random() & (~0U >> (32 - p->ru_bits + 1));
- p->ru_seed2 = arc4random() & (~0U >> (32 - p->ru_bits + 1));
+ p->ru_seed = cprng_fast32() & (~0U >> (32 - p->ru_bits + 1));
+ p->ru_seed2 = cprng_fast32() & (~0U >> (32 - p->ru_bits + 1));
/* Determine the LCG we use */
- p->ru_b = (arc4random() & (~0U >> (32 - p->ru_bits))) | 1;
+ p->ru_b = (cprng_fast32() & (~0U >> (32 - p->ru_bits))) | 1;
p->ru_a = pmod(p->ru_agen,
- (arc4random() & (~0U >> (32 - p->ru_bits))) & (~1U), p->ru_m);
+ (cprng_fast32() & (~0U >> (32 - p->ru_bits))) & (~1U), p->ru_m);
while (p->ru_b % 3 == 0)
p->ru_b += 2;
- j = arc4random() % p->ru_n;
+ j = cprng_fast32() % p->ru_n;
/*
* Do a fast gcd(j, RU_N - 1), so we can find a j with
@@ -222,7 +224,7 @@ randomid(struct randomtab *p)
initid(p);
/* Skip a random number of ids */
- n = arc4random() & 0x3;
+ n = cprng_fast32() & 0x3;
if (p->ru_counter + n >= p->ru_max)
initid(p);
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 6a2589f35e3..f67888688cd 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ip6_input.c,v 1.132 2011/06/01 22:59:44 dyoung Exp $ */
+/* $NetBSD: ip6_input.c,v 1.133 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.132 2011/06/01 22:59:44 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.133 2011/11/19 22:51:29 tls Exp $");
#include "opt_gateway.h"
#include "opt_inet.h"
@@ -85,6 +85,7 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.132 2011/06/01 22:59:44 dyoung Exp $
#include <sys/syslog.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -190,7 +191,7 @@ ip6_init(void)
addrsel_policy_init();
nd6_init();
frag6_init();
- ip6_desync_factor = arc4random() % MAX_TEMP_DESYNC_FACTOR;
+ ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR;
ip6_init2((void *)0);
#ifdef GATEWAY
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index 6487d134dc2..861f076fb7a 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -1,4 +1,4 @@
-/* $NetBSD: mld6.c,v 1.54 2011/10/19 01:53:07 dyoung Exp $ */
+/* $NetBSD: mld6.c,v 1.55 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */
/*
@@ -102,7 +102,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.54 2011/10/19 01:53:07 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.55 2011/11/19 22:51:29 tls Exp $");
#include "opt_inet.h"
@@ -116,6 +116,7 @@ __KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.54 2011/10/19 01:53:07 dyoung Exp $");
#include <sys/sysctl.h>
#include <sys/kernel.h>
#include <sys/callout.h>
+#include <sys/cprng.h>
#include <net/if.h>
@@ -289,7 +290,7 @@ mld_start_listening(struct in6_multi *in6m)
in6m->in6m_state = MLD_OTHERLISTENER;
} else {
mld_sendpkt(in6m, MLD_LISTENER_REPORT, NULL);
- in6m->in6m_timer = arc4random() %
+ in6m->in6m_timer = cprng_fast32() %
(MLD_UNSOLICITED_REPORT_INTERVAL * hz);
in6m->in6m_state = MLD_IREPORTEDLAST;
@@ -443,7 +444,7 @@ mld_input(struct mbuf *m, int off)
} else if (in6m->in6m_timer == IN6M_TIMER_UNDEF ||
mld_timerresid(in6m) > timer) {
in6m->in6m_timer =
- 1 + (arc4random() % timer) * hz / 1000;
+ 1 + (cprng_fast32() % timer) * hz / 1000;
mld_starttimer(in6m);
}
}
diff --git a/sys/netinet6/mld6_var.h b/sys/netinet6/mld6_var.h
index 577411880cc..6129ef11665 100644
--- a/sys/netinet6/mld6_var.h
+++ b/sys/netinet6/mld6_var.h
@@ -1,4 +1,4 @@
-/* $NetBSD: mld6_var.h,v 1.9 2007/11/01 20:33:58 dyoung Exp $ */
+/* $NetBSD: mld6_var.h,v 1.10 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: mld6_var.h,v 1.4 2000/03/25 07:23:54 sumikawa Exp $ */
/*
@@ -35,7 +35,7 @@
#ifdef _KERNEL
-#define MLD_RANDOM_DELAY(X) (arc4random() % (X) + 1)
+#define MLD_RANDOM_DELAY(X) (cprng_fast32() % (X) + 1)
/*
* States for MLD stop-listening processing
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 8cc8cb0b93b..13587854909 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6.c,v 1.137 2011/11/10 17:10:00 seanb Exp $ */
+/* $NetBSD: nd6.c,v 1.138 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.137 2011/11/10 17:10:00 seanb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.138 2011/11/19 22:51:29 tls Exp $");
#include "opt_ipsec.h"
@@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.137 2011/11/10 17:10:00 seanb Exp $");
#include <sys/ioctl.h>
#include <sys/syslog.h>
#include <sys/queue.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_dl.h>
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index 54a5d534816..6f7b042bba6 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6.h,v 1.55 2011/11/11 15:09:33 gdt Exp $ */
+/* $NetBSD: nd6.h,v 1.56 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */
/*
@@ -255,7 +255,7 @@ struct in6_ndifreq {
#define TEMPADDR_REGEN_ADVANCE 5 /* sec */
#define MAX_TEMP_DESYNC_FACTOR 600 /* 10 min */
#define ND_COMPUTE_RTIME(x) \
- (((MIN_RANDOM_FACTOR * (x >> 10)) + (arc4random() & \
+ (((MIN_RANDOM_FACTOR * (x >> 10)) + (cprng_fast32() & \
((MAX_RANDOM_FACTOR - MIN_RANDOM_FACTOR) * (x >> 10)))) /1000)
TAILQ_HEAD(nd_drhead, nd_defrouter);
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index ce968014c40..644308fd897 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6_rtr.c,v 1.81 2011/05/24 18:07:11 spz Exp $ */
+/* $NetBSD: nd6_rtr.c,v 1.82 2011/11/19 22:51:29 tls Exp $ */
/* $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $ */
/*
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.81 2011/05/24 18:07:11 spz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.82 2011/11/19 22:51:29 tls Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -44,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.81 2011/05/24 18:07:11 spz Exp $");
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <sys/syslog.h>
+#include <sys/cprng.h>
#include <net/if.h>
#include <net/if_types.h>
diff --git a/sys/netkey/key.c b/sys/netkey/key.c
index 3f10e80e936..cae5fc5d99c 100644
--- a/sys/netkey/key.c
+++ b/sys/netkey/key.c
@@ -1,4 +1,4 @@
-/* $NetBSD: key.c,v 1.179 2011/07/17 20:54:54 joerg Exp $ */
+/* $NetBSD: key.c,v 1.180 2011/11/19 22:51:30 tls Exp $ */
/* $KAME: key.c,v 1.310 2003/09/08 02:23:44 itojun Exp $ */
/*
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.179 2011/07/17 20:54:54 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.180 2011/11/19 22:51:30 tls Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@@ -96,10 +96,7 @@ __KERNEL_RCSID(0, "$NetBSD: key.c,v 1.179 2011/07/17 20:54:54 joerg Exp $");
#include <miscfs/kernfs/kernfs.h>
-#include "rnd.h"
-#if NRND > 0
-#include <sys/rnd.h>
-#endif
+#include <sys/cprng.h>
#include <net/net_osdep.h>
@@ -4975,20 +4972,7 @@ key_random(void)
void
key_randomfill(void *p, size_t l)
{
-#if NRND == 0
- static int warn = 1;
-#endif
-
- arc4randbytes(p, l);
-
-#if NRND == 0
- /* the arc4 generator is keyed with junk. */
- if (warn) {
- printf("WARNING: pseudo-random number generator "
- "used for IPsec processing\n");
- warn = 0;
- }
-#endif
+ cprng_fast(p, l);
}
/*
diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c
index c926803314d..b2718837581 100644
--- a/sys/nfs/nfs_subs.c
+++ b/sys/nfs/nfs_subs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_subs.c,v 1.221 2011/06/12 03:35:59 rmind Exp $ */
+/* $NetBSD: nfs_subs.c,v 1.222 2011/11/19 22:51:30 tls Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.221 2011/06/12 03:35:59 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.222 2011/11/19 22:51:30 tls Exp $");
#ifdef _KERNEL_OPT
#include "opt_nfs.h"
@@ -98,6 +98,7 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.221 2011/06/12 03:35:59 rmind Exp $")
#include <sys/once.h>
#include <sys/kauth.h>
#include <sys/atomic.h>
+#include <sys/cprng.h>
#include <uvm/uvm.h>
@@ -1488,7 +1489,7 @@ nfs_init0(void)
nfs_ticks = (hz * NFS_TICKINTVL + 500) / 1000;
if (nfs_ticks < 1)
nfs_ticks = 1;
- nfs_xid = arc4random();
+ nfs_xid = cprng_fast32();
nfsdreq_init();
/*
diff --git a/sys/opencrypto/files.opencrypto b/sys/opencrypto/files.opencrypto
index e2b0a352869..010285cc149 100644
--- a/sys/opencrypto/files.opencrypto
+++ b/sys/opencrypto/files.opencrypto
@@ -1,4 +1,4 @@
-# $NetBSD: files.opencrypto,v 1.24 2011/05/26 21:50:03 drochner Exp $
+# $NetBSD: files.opencrypto,v 1.25 2011/11/19 22:51:30 tls Exp $
#
#
@@ -15,7 +15,7 @@ file opencrypto/crypto.c opencrypto
# Pseudo-device that provides software implementations of various cryptographic
# algorithms.
defpseudo swcrypto: opencrypto,
- blowfish, des, cast128, rijndael, skipjack, camellia
+ blowfish, des, cast128, skipjack, camellia
file opencrypto/cryptosoft.c swcrypto
file opencrypto/deflate.c swcrypto # wrapper around zlib
file opencrypto/aesxcbcmac.c swcrypto
diff --git a/sys/rump/librump/rumpkern/Makefile.rumpkern b/sys/rump/librump/rumpkern/Makefile.rumpkern
index 5a8e52d7a78..abe7845b56d 100644
--- a/sys/rump/librump/rumpkern/Makefile.rumpkern
+++ b/sys/rump/librump/rumpkern/Makefile.rumpkern
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.rumpkern,v 1.110 2011/06/12 06:36:38 mrg Exp $
+# $NetBSD: Makefile.rumpkern,v 1.111 2011/11/19 22:51:30 tls Exp $
#
.include "${RUMPTOP}/Makefile.rump"
@@ -20,7 +20,7 @@ LIB= rump
#
SRCS= rump.c rumpcopy.c emul.c intr.c lwproc.c klock.c \
kobj_rename.c ltsleep.c memalloc.c scheduler.c \
- signals.c sleepq.c threads.c vm.c
+ signals.c sleepq.c threads.c vm.c cprng_stub.c
# Multiprocessor or uniprocessor locking. TODO: select right
# locking at runtime.
diff --git a/sys/rump/librump/rumpkern/cprng_stub.c b/sys/rump/librump/rumpkern/cprng_stub.c
new file mode 100644
index 00000000000..7c0861d3322
--- /dev/null
+++ b/sys/rump/librump/rumpkern/cprng_stub.c
@@ -0,0 +1,93 @@
+/* $NetBSD: cprng_stub.c,v 1.1 2011/11/19 22:51:30 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/rngtest.h>
+
+#include <machine/cpu_counter.h>
+
+#include <sys/cprng.h>
+
+/*
+ * This is all stubbed out because of rump build dependency issues I
+ * cannot fix. One is more-or-less caused by the longstanding bogosity
+ * that sys/dev/rnd.c implements *both* the in-kernel interface *and*
+ * the pseudodevice. The other, by the fact that I am not smart enough
+ * to understand how to deal with code in rumpkern that depends on code
+ * that lives in sys/crypto. Sigh.
+ */
+
+cprng_strong_t *kern_cprng = NULL;
+
+void
+cprng_init(void)
+{
+ return;
+}
+
+cprng_strong_t *cprng_strong_create(const char *const name, int ipl, int flags)
+{
+ cprng_strong_t *c;
+
+ c = kmem_alloc(sizeof(*c), KM_NOSLEEP);
+ if (c == NULL) {
+ return NULL;
+ }
+ strlcpy(c->name, name, sizeof(c->name));
+ mutex_init(&c->mtx, MUTEX_DEFAULT, ipl);
+ if (c->flags & CPRNG_USE_CV) {
+ cv_init(&c->cv, name);
+ }
+ return c;
+}
+
+
+size_t cprng_strong(cprng_strong_t *c, void *p, size_t len)
+{
+ mutex_enter(&c->mtx);
+ cprng_fast(p, len); /* XXX! */
+ mutex_exit(&c->mtx);
+ return len;
+}
+
+void cprng_strong_destroy(cprng_strong_t *c)
+{
+ mutex_destroy(&c->mtx);
+ cv_destroy(&c->cv);
+ memset(c, 0, sizeof(*c));
+ kmem_free(c, sizeof(*c));
+}
diff --git a/sys/rump/librump/rumpkern/rump.c b/sys/rump/librump/rumpkern/rump.c
index 1564a25fb94..c04c504d10d 100644
--- a/sys/rump/librump/rumpkern/rump.c
+++ b/sys/rump/librump/rumpkern/rump.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rump.c,v 1.234 2011/03/22 15:16:23 pooka Exp $ */
+/* $NetBSD: rump.c,v 1.235 2011/11/19 22:51:30 tls Exp $ */
/*
* Copyright (c) 2007-2011 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.234 2011/03/22 15:16:23 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.235 2011/11/19 22:51:30 tls Exp $");
#include <sys/systm.h>
#define ELFSIZE ARCH_ELFSIZE
@@ -69,6 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: rump.c,v 1.234 2011/03/22 15:16:23 pooka Exp $");
#include <sys/vmem.h>
#include <sys/xcall.h>
#include <sys/simplelock.h>
+#include <sys/cprng.h>
#include <rump/rumpuser.h>
@@ -288,7 +289,7 @@ rump__init(int rump_version)
* implementation.
*/
messthestack();
- arc4random();
+ cprng_fast32();
if (rump_version != RUMP_VERSION) {
printf("rump version mismatch, %d vs. %d\n",
diff --git a/sys/rump/librump/rumpvfs/rumpblk.c b/sys/rump/librump/rumpvfs/rumpblk.c
index 65660039cf3..63a74833820 100644
--- a/sys/rump/librump/rumpvfs/rumpblk.c
+++ b/sys/rump/librump/rumpvfs/rumpblk.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rumpblk.c,v 1.46 2011/02/03 22:16:11 pooka Exp $ */
+/* $NetBSD: rumpblk.c,v 1.47 2011/11/19 22:51:31 tls Exp $ */
/*
* Copyright (c) 2009 Antti Kantee. All Rights Reserved.
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.46 2011/02/03 22:16:11 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.47 2011/11/19 22:51:31 tls Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -65,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: rumpblk.c,v 1.46 2011/02/03 22:16:11 pooka Exp $");
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/stat.h>
+#include <sys/cprng.h>
#include <rump/rumpuser.h>
@@ -326,7 +327,7 @@ rumpblk_init(void)
&error) == 0) {
randstate = strtoul(buf, NULL, 10);
} else {
- randstate = arc4random();
+ randstate = cprng_fast32();
}
printf("rumpblk: FAULT INJECTION ACTIVE! fail %d/%d. "
"seed %u\n", blkfail, BLKFAIL_MAX, randstate);
diff --git a/sys/rump/net/lib/libshmif/if_shmem.c b/sys/rump/net/lib/libshmif/if_shmem.c
index ad954f42287..64f24651e4b 100644
--- a/sys/rump/net/lib/libshmif/if_shmem.c
+++ b/sys/rump/net/lib/libshmif/if_shmem.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_shmem.c,v 1.43 2011/09/02 22:25:08 dyoung Exp $ */
+/* $NetBSD: if_shmem.c,v 1.44 2011/11/19 22:51:31 tls Exp $ */
/*
* Copyright (c) 2009, 2010 Antti Kantee. All Rights Reserved.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.43 2011/09/02 22:25:08 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.44 2011/11/19 22:51:31 tls Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.43 2011/09/02 22:25:08 dyoung Exp $")
#include <sys/kthread.h>
#include <sys/lock.h>
#include <sys/vmem.h>
+#include <sys/cprng.h>
#include <net/bpf.h>
#include <net/if.h>
@@ -152,7 +153,7 @@ allocif(int unit, struct shmif_sc **scp)
uint32_t randnum;
int error;
- randnum = arc4random();
+ randnum = cprng_fast32();
memcpy(&enaddr[2], &randnum, sizeof(randnum));
sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
diff --git a/sys/rump/net/lib/libvirtif/if_virt.c b/sys/rump/net/lib/libvirtif/if_virt.c
index 8cbc8a8ce1c..0fd7abec4bd 100644
--- a/sys/rump/net/lib/libvirtif/if_virt.c
+++ b/sys/rump/net/lib/libvirtif/if_virt.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_virt.c,v 1.25 2011/10/31 13:25:21 yamt Exp $ */
+/* $NetBSD: if_virt.c,v 1.26 2011/11/19 22:51:31 tls Exp $ */
/*
* Copyright (c) 2008 Antti Kantee. All Rights Reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.25 2011/10/31 13:25:21 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.26 2011/11/19 22:51:31 tls Exp $");
#include <sys/param.h>
#include <sys/condvar.h>
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_virt.c,v 1.25 2011/10/31 13:25:21 yamt Exp $");
#include <sys/poll.h>
#include <sys/sockio.h>
#include <sys/socketvar.h>
+#include <sys/cprng.h>
#include <net/bpf.h>
#include <net/if.h>
@@ -102,7 +103,7 @@ rump_virtif_create(int num)
num, error);
return error;
}
- enaddr[2] = arc4random() & 0xff;
+ enaddr[2] = cprng_fast32() & 0xff;
enaddr[5] = num;
sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
@@ -370,8 +371,8 @@ rump_dummyif_create()
struct ethercom *ec;
uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0x0a, 0x00, 0x0b, 0x0e, 0x01 };
- enaddr[2] = arc4random() & 0xff;
- enaddr[5] = arc4random() & 0xff;
+ enaddr[2] = cprng_fast32() & 0xff;
+ enaddr[5] = cprng_fast32() & 0xff;
ec = kmem_zalloc(sizeof(*ec), KM_SLEEP);
diff --git a/sys/sys/cprng.h b/sys/sys/cprng.h
new file mode 100644
index 00000000000..148803247d8
--- /dev/null
+++ b/sys/sys/cprng.h
@@ -0,0 +1,108 @@
+/* $NetBSD: cprng.h,v 1.1 2011/11/19 22:51:31 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _CPRNG_H
+#define _CPRNG_H
+
+#include <sys/types.h>
+#include <lib/libkern/libkern.h>
+#include <sys/rnd.h>
+#include <crypto/nist_ctr_drbg/nist_ctr_drbg.h>
+#include <sys/condvar.h>
+
+/*
+ * NIST SP800-90 says 2^19 bytes per request for the CTR_DRBG.
+ */
+#define CPRNG_MAX_LEN 524288
+
+static inline size_t
+cprng_fast(void *p, size_t len)
+{
+ arc4randbytes(p, len);
+ return len;
+}
+
+static inline uint32_t
+cprng_fast32(void)
+{
+ return arc4random();
+}
+
+static inline uint64_t
+cprng_fast64(void)
+{
+ uint64_t r;
+ arc4randbytes(&r, sizeof(r));
+ return r;
+}
+
+typedef struct _cprng_strong {
+ kmutex_t mtx;
+ kcondvar_t cv;
+ NIST_CTR_DRBG drbg;
+ int flags;
+ char name[16];
+ int reseed_pending;
+ rndsink_t reseed;
+} cprng_strong_t;
+
+#define CPRNG_INIT_ANY 0x00000001
+#define CPRNG_REKEY_ANY 0x00000002
+#define CPRNG_USE_CV 0x00000004
+
+cprng_strong_t *cprng_strong_create(const char *const, int, int);
+
+size_t cprng_strong(cprng_strong_t *const, void *const, size_t);
+
+void cprng_strong_destroy(cprng_strong_t *);
+
+extern cprng_strong_t * kern_cprng;
+
+static inline uint32_t
+cprng_strong32(void)
+{
+ uint32_t r;
+ cprng_strong(kern_cprng, &r, sizeof(r));
+ return r;
+}
+
+static inline uint64_t
+cprng_strong64(void)
+{
+ uint64_t r;
+ cprng_strong(kern_cprng, &r, sizeof(r));
+ return r;
+}
+
+void cprng_init(void);
+int cprng_strong_getflags(cprng_strong_t *const);
+void cprng_strong_setflags(cprng_strong_t *const, int);
+
+#endif
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index 4c72a39dd2a..368830b4e6a 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -1,4 +1,4 @@
-/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
+/* $NetBSD: queue.h,v 1.53 2011/11/19 22:51:31 tls Exp $ */
/*
* Copyright (c) 1991, 1993
@@ -166,6 +166,10 @@ struct { \
(var); \
(var) = ((var)->field.le_next))
+#define LIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = LIST_FIRST((head)); \
+ (var) && ((tvar) = LIST_NEXT((var), field), 1); \
+ (var) = (tvar))
/*
* List access methods.
*/
diff --git a/sys/sys/rnd.h b/sys/sys/rnd.h
index e04cdda1afb..c38d2153085 100644
--- a/sys/sys/rnd.h
+++ b/sys/sys/rnd.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rnd.h,v 1.21 2008/04/28 20:24:11 martin Exp $ */
+/* $NetBSD: rnd.h,v 1.22 2011/11/19 22:51:31 tls Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -43,6 +43,10 @@
#include <sys/queue.h>
#endif
+#ifdef _KERNEL
+#include <sys/rngtest.h>
+#endif
+
#define RND_DEV_RANDOM 0 /* minor devices for random and kinda random */
#define RND_DEV_URANDOM 1
@@ -82,26 +86,14 @@ typedef struct
uint32_t generated;
} rndpoolstat_t;
-
-typedef struct {
- uint32_t cursor; /* current add point in the pool */
- uint32_t rotate; /* how many bits to rotate by */
- rndpoolstat_t stats; /* current statistics */
- uint32_t pool[RND_POOLWORDS]; /* random pool data */
-} rndpool_t;
-
+/* Sanitized random source view for userspace */
typedef struct {
char name[16]; /* device name */
- uint32_t last_time; /* last time recorded */
- uint32_t last_delta; /* last delta value */
- uint32_t last_delta2; /* last delta2 value */
uint32_t total; /* entropy from this source */
uint32_t type; /* type */
uint32_t flags; /* flags */
- void *state; /* state informaiton */
} rndsource_t;
-
/*
* Flags to control the source. Low byte is type, upper bits are flags.
*/
@@ -118,12 +110,36 @@ typedef struct {
#define RND_TYPE_MAX 5 /* last type id used */
#ifdef _KERNEL
-typedef struct __rndsource_element rndsource_element_t;
-struct __rndsource_element {
- LIST_ENTRY(__rndsource_element) list; /* the linked list */
- rndsource_t data; /* the actual data */
-};
+typedef struct krndsource {
+ LIST_ENTRY(krndsource) list; /* the linked list */
+ char name[16]; /* device name */
+ uint32_t last_time; /* last time recorded */
+ uint32_t last_delta; /* last delta value */
+ uint32_t last_delta2; /* last delta2 value */
+ uint32_t total; /* entropy from this source */
+ uint32_t type; /* type */
+ uint32_t flags; /* flags */
+ void *state; /* state informaiton */
+ size_t test_cnt; /* how much test data accumulated? */
+ rngtest_t *test; /* test data for RNG type sources */
+} krndsource_t;
+
+typedef struct rndsink {
+ TAILQ_ENTRY(rndsink) tailq; /* the queue */
+ void (*cb)(void *); /* callback function when ready */
+ void *arg; /* callback function argument */
+ char name[16]; /* sink name */
+ size_t len; /* how many bytes wanted/supplied */
+ uint8_t data[64]; /* random data returned here */
+} rndsink_t;
+
+typedef struct {
+ uint32_t cursor; /* current add point in the pool */
+ uint32_t rotate; /* how many bits to rotate by */
+ rndpoolstat_t stats; /* current statistics */
+ uint32_t pool[RND_POOLWORDS]; /* random pool data */
+} rndpool_t;
/*
* Used by rnd_extract_data() and rndpool_extract_data() to describe how
@@ -134,7 +150,7 @@ struct __rndsource_element {
(short read ok) */
#define RND_ENABLED(rp) \
- (((rp)->data.flags & RND_FLAG_NO_COLLECT) == 0)
+ (((rp)->flags & RND_FLAG_NO_COLLECT) == 0)
void rndpool_init(rndpool_t *);
void rndpool_init_global(void);
@@ -144,17 +160,18 @@ void rndpool_increment_entropy_count(rndpool_t *, uint32_t);
uint32_t *rndpool_get_pool(rndpool_t *);
uint32_t rndpool_get_poolsize(void);
void rndpool_add_data(rndpool_t *, void *, uint32_t, uint32_t);
-uint32_t rndpool_extract_data(rndpool_t *, void *, uint32_t,
- uint32_t);
-
+uint32_t rndpool_extract_data(rndpool_t *, void *, uint32_t, uint32_t);
void rnd_init(void);
-void rnd_add_uint32(rndsource_element_t *, uint32_t);
-void rnd_add_data(rndsource_element_t *, void *, uint32_t,
+void rnd_add_uint32(krndsource_t *, uint32_t);
+void rnd_add_data(krndsource_t *, const void *const, uint32_t,
uint32_t);
uint32_t rnd_extract_data(void *, uint32_t, uint32_t);
-void rnd_attach_source(rndsource_element_t *, const char *,
+void rnd_attach_source(krndsource_t *, const char *,
uint32_t, uint32_t);
-void rnd_detach_source(rndsource_element_t *);
+void rnd_detach_source(krndsource_t *);
+
+void rndsink_attach(rndsink_t *);
+void rndsink_detach(rndsink_t *);
#endif /* _KERNEL */
diff --git a/sys/sys/rngtest.h b/sys/sys/rngtest.h
new file mode 100644
index 00000000000..1fa70fc05c8
--- /dev/null
+++ b/sys/sys/rngtest.h
@@ -0,0 +1,49 @@
+/* $NetBSD: rngtest.h,v 1.1 2011/11/19 22:51:31 tls Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Thor Lancelot Simon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _RNGTEST_H
+#define _RNGTEST_H
+
+#include <sys/types.h>
+
+#define FIPS140_RNG_TEST_BITS 20000
+#define FIPS140_RNG_TEST_BYTES (FIPS140_RNG_TEST_BITS / NBBY)
+
+typedef struct {
+ uint8_t rt_b[FIPS140_RNG_TEST_BYTES];
+ int rt_poker[16];
+ int rt_runs[2][7];
+ int rt_nerrs;
+ char rt_name[16];
+} rngtest_t;
+
+int rngtest(rngtest_t *const);
+
+#endif
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 7f7bd7d0313..b31c6b08f26 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sysctl.h,v 1.197 2011/10/21 02:07:07 christos Exp $ */
+/* $NetBSD: sysctl.h,v 1.198 2011/11/19 22:51:31 tls Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -56,6 +56,10 @@
#include <stdbool.h>
#endif
+#ifdef _KERNEL
+#include <sys/cprng.h>
+#endif
+
/*
* Definitions for sysctl call. The sysctl call uses a hierarchical name
* for objects that can be examined or modified. The name is expressed as
@@ -1208,6 +1212,8 @@ MALLOC_DECLARE(M_SYSCTLDATA);
extern const u_int sysctl_lwpflagmap[];
+extern cprng_strong_t *sysctl_prng;
+
#else /* !_KERNEL */
#include <sys/cdefs.h>
diff --git a/sys/ufs/ffs/ffs_appleufs.c b/sys/ufs/ffs/ffs_appleufs.c
index af4feb4e7c9..0067d40e9a9 100644
--- a/sys/ufs/ffs/ffs_appleufs.c
+++ b/sys/ufs/ffs/ffs_appleufs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_appleufs.c,v 1.11 2011/06/22 04:01:33 mrg Exp $ */
+/* $NetBSD: ffs_appleufs.c,v 1.12 2011/11/19 22:51:31 tls Exp $ */
/*
* Copyright (c) 2002 Darrin B. Jewell
@@ -26,13 +26,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_appleufs.c,v 1.11 2011/06/22 04:01:33 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_appleufs.c,v 1.12 2011/11/19 22:51:31 tls Exp $");
#include <sys/param.h>
#include <sys/time.h>
#if defined(_KERNEL)
#include <sys/kernel.h>
#include <sys/systm.h>
+#include <sys/cprng.h>
#endif
#include <ufs/ufs/dinode.h>
@@ -136,9 +137,7 @@ ffs_appleufs_set(struct appleufslabel *appleufs, const char *name, time_t t,
}
if (uuid == 0) {
#if defined(_KERNEL) && !defined(STANDALONE)
- uuid = arc4random();
- uuid <<= 32;
- uuid |= arc4random();
+ uuid = cprng_fast64();
#endif
}
namelen = strlen(name);