diff options
| author | tls <tls@NetBSD.org> | 2011-11-19 22:51:18 +0000 |
|---|---|---|
| committer | tls <tls@NetBSD.org> | 2011-11-19 22:51:18 +0000 |
| commit | 8e9334525367ba7642ed9b753a94935c07817c19 (patch) | |
| tree | 1b53338e20cd060235386b574dbf34d8cf11d50f /sys | |
| parent | 836ffd606791f7517a3ff458821d8013500d001c (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')
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); |
