Index: sys/altq/altq_blue.c =================================================================== RCS file: /cvsroot/src/sys/altq/altq_blue.c,v retrieving revision 1.22 diff -u -b -r1.22 altq_blue.c --- sys/altq/altq_blue.c 4 Mar 2007 05:59:00 -0000 1.22 +++ sys/altq/altq_blue.c 21 Oct 2011 20:31:02 -0000 @@ -80,6 +80,7 @@ #include #include #include +#include #include #include @@ -504,7 +505,7 @@ 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); } Index: sys/altq/altq_cdnr.c =================================================================== RCS file: /cvsroot/src/sys/altq/altq_cdnr.c,v retrieving revision 1.19 diff -u -b -r1.19 altq_cdnr.c --- sys/altq/altq_cdnr.c 4 Mar 2007 05:59:01 -0000 1.19 +++ sys/altq/altq_cdnr.c 21 Oct 2011 20:31:02 -0000 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -801,7 +802,7 @@ * 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) { Index: sys/altq/altq_red.c =================================================================== RCS file: /cvsroot/src/sys/altq/altq_red.c,v retrieving revision 1.28 diff -u -b -r1.28 altq_red.c --- sys/altq/altq_red.c 18 Jun 2008 09:06:27 -0000 1.28 +++ sys/altq/altq_red.c 21 Oct 2011 20:31:02 -0000 @@ -87,6 +87,7 @@ #include #endif #endif /* ALTQ3_COMPAT */ +#include #include @@ -505,7 +506,7 @@ * drop probability = (avg - TH_MIN) / d */ - if ((arc4random() % d) < fp_len) { + if ((cprng_fast32() % d) < fp_len) { /* drop or mark */ return (1); } Index: sys/altq/altq_rmclass.c =================================================================== RCS file: /cvsroot/src/sys/altq/altq_rmclass.c,v retrieving revision 1.21 diff -u -b -r1.21 altq_rmclass.c --- sys/altq/altq_rmclass.c 15 Jul 2008 16:18:08 -0000 1.21 +++ sys/altq/altq_rmclass.c 21 Oct 2011 20:31:03 -0000 @@ -59,6 +59,7 @@ #ifdef ALTQ3_COMPAT #include #endif +#include #include #ifdef ALTQ3_COMPAT @@ -1777,7 +1778,7 @@ } 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; Index: sys/arch/acorn26/ioc/arckbd.c =================================================================== RCS file: /cvsroot/src/sys/arch/acorn26/ioc/arckbd.c,v retrieving revision 1.20 diff -u -b -r1.20 arckbd.c --- sys/arch/acorn26/ioc/arckbd.c 19 Jul 2011 16:05:10 -0000 1.20 +++ sys/arch/acorn26/ioc/arckbd.c 21 Oct 2011 20:31:03 -0000 @@ -139,7 +139,7 @@ struct irq_handler *sc_rirq; struct evcnt sc_rev; #if NRND > 0 - rndsource_element_t sc_rnd_source; + krndsource_t sc_rnd_source; #endif }; Index: sys/arch/arm/at91/at91dbguvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/at91/at91dbguvar.h,v retrieving revision 1.3 diff -u -b -r1.3 at91dbguvar.h --- sys/arch/arm/at91/at91dbguvar.h 23 Oct 2009 06:53:13 -0000 1.3 +++ sys/arch/arm/at91/at91dbguvar.h 21 Oct 2011 20:31:03 -0000 @@ -82,7 +82,7 @@ int enabled; #if NRND > 0 && defined(RND_COM) - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/arch/arm/at91/at91usartvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/at91/at91usartvar.h,v retrieving revision 1.3 diff -u -b -r1.3 at91usartvar.h --- sys/arch/arm/at91/at91usartvar.h 23 Oct 2009 06:53:13 -0000 1.3 +++ sys/arch/arm/at91/at91usartvar.h 21 Oct 2011 20:31:03 -0000 @@ -86,7 +86,7 @@ int enabled; #if NRND > 0 && defined(RND_COM) - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/arch/arm/ep93xx/epcomvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/ep93xx/epcomvar.h,v retrieving revision 1.4 diff -u -b -r1.4 epcomvar.h --- sys/arch/arm/ep93xx/epcomvar.h 23 Oct 2009 00:39:30 -0000 1.4 +++ sys/arch/arm/ep93xx/epcomvar.h 21 Oct 2011 20:31:03 -0000 @@ -83,7 +83,7 @@ int enabled; #if NRND > 0 && defined(RND_COM) - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/arch/arm/s3c2xx0/sscom_var.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/s3c2xx0/sscom_var.h,v retrieving revision 1.8 diff -u -b -r1.8 sscom_var.h --- sys/arch/arm/s3c2xx0/sscom_var.h 1 Jul 2011 20:31:39 -0000 1.8 +++ sys/arch/arm/s3c2xx0/sscom_var.h 21 Oct 2011 20:31:03 -0000 @@ -172,7 +172,7 @@ #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; Index: sys/arch/arm/sa11x0/sa1111_kbc.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/sa11x0/sa1111_kbc.c,v retrieving revision 1.12 diff -u -b -r1.12 sa1111_kbc.c --- sys/arch/arm/sa11x0/sa1111_kbc.c 13 Mar 2010 11:13:31 -0000 1.12 +++ sys/arch/arm/sa11x0/sa1111_kbc.c 21 Oct 2011 20:31:03 -0000 @@ -96,7 +96,7 @@ 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; }; Index: sys/arch/arm/xscale/ixp425_if_npe.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/xscale/ixp425_if_npe.c,v retrieving revision 1.20 diff -u -b -r1.20 ixp425_if_npe.c --- sys/arch/arm/xscale/ixp425_if_npe.c 1 Jul 2011 20:32:51 -0000 1.20 +++ sys/arch/arm/xscale/ixp425_if_npe.c 21 Oct 2011 20:31:04 -0000 @@ -127,7 +127,7 @@ 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 }; Index: sys/arch/emips/ebus/ace_ebus.c =================================================================== RCS file: /cvsroot/src/sys/arch/emips/ebus/ace_ebus.c,v retrieving revision 1.2 diff -u -b -r1.2 ace_ebus.c --- sys/arch/emips/ebus/ace_ebus.c 18 Jun 2011 17:47:20 -0000 1.2 +++ sys/arch/emips/ebus/ace_ebus.c 21 Oct 2011 20:31:04 -0000 @@ -193,7 +193,7 @@ int retries; /* number of xfer retry */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/arch/emips/ebus/flash_ebus.c =================================================================== RCS file: /cvsroot/src/sys/arch/emips/ebus/flash_ebus.c,v retrieving revision 1.2 diff -u -b -r1.2 flash_ebus.c --- sys/arch/emips/ebus/flash_ebus.c 12 Jun 2011 03:29:33 -0000 1.2 +++ sys/arch/emips/ebus/flash_ebus.c 21 Oct 2011 20:31:05 -0000 @@ -202,7 +202,7 @@ int retries; /* number of xfer retry */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif /* flash-specific state */ Index: sys/arch/emips/ebus/if_le_ebus.c =================================================================== RCS file: /cvsroot/src/sys/arch/emips/ebus/if_le_ebus.c,v retrieving revision 1.2 diff -u -b -r1.2 if_le_ebus.c --- sys/arch/emips/ebus/if_le_ebus.c 12 Jun 2011 14:31:31 -0000 1.2 +++ sys/arch/emips/ebus/if_le_ebus.c 21 Oct 2011 20:31:05 -0000 @@ -115,7 +115,7 @@ 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 }; Index: sys/arch/evbarm/dev/plcomvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/dev/plcomvar.h,v retrieving revision 1.6 diff -u -b -r1.6 plcomvar.h --- sys/arch/evbarm/dev/plcomvar.h 5 Jan 2008 12:40:34 -0000 1.6 +++ sys/arch/evbarm/dev/plcomvar.h 21 Oct 2011 20:31:05 -0000 @@ -134,7 +134,7 @@ pps_params_t ppsparam; #if NRND > 0 && defined(RND_COM) - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif struct simplelock sc_lock; }; Index: sys/arch/hp300/dev/rdvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp300/dev/rdvar.h,v retrieving revision 1.20 diff -u -b -r1.20 rdvar.h --- sys/arch/hp300/dev/rdvar.h 8 Feb 2011 20:20:13 -0000 1.20 +++ sys/arch/hp300/dev/rdvar.h 21 Oct 2011 20:31:06 -0000 @@ -81,7 +81,7 @@ int sc_errcnt; struct rdstats sc_stats; #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/arch/hp700/gsc/harmonyvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/hp700/gsc/harmonyvar.h,v retrieving revision 1.4 diff -u -b -r1.4 harmonyvar.h --- sys/arch/hp700/gsc/harmonyvar.h 25 Apr 2008 08:17:52 -0000 1.4 +++ sys/arch/hp700/gsc/harmonyvar.h 21 Oct 2011 20:31:06 -0000 @@ -105,7 +105,7 @@ 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 Index: sys/arch/i386/pci/glxsb.c =================================================================== RCS file: /cvsroot/src/sys/arch/i386/pci/glxsb.c,v retrieving revision 1.9 diff -u -b -r1.9 glxsb.c --- sys/arch/i386/pci/glxsb.c 16 May 2009 16:52:03 -0000 1.9 +++ sys/arch/i386/pci/glxsb.c 21 Oct 2011 20:31:06 -0000 @@ -34,8 +34,8 @@ #include #include #include -#include #include +#include #include @@ -165,7 +165,7 @@ 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 @@ 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) */ Index: sys/arch/macppc/dev/if_gm.c =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/dev/if_gm.c,v retrieving revision 1.39 diff -u -b -r1.39 if_gm.c --- sys/arch/macppc/dev/if_gm.c 18 Jun 2011 08:08:28 -0000 1.39 +++ sys/arch/macppc/dev/if_gm.c 21 Oct 2011 20:31:06 -0000 @@ -87,7 +87,7 @@ char sc_laddr[6]; #if NRND > 0 - rndsource_element_t sc_rnd_source; /* random source */ + krndsource_t sc_rnd_source; /* random source */ #endif }; Index: sys/arch/mips/alchemy/dev/if_aumac.c =================================================================== RCS file: /cvsroot/src/sys/arch/mips/alchemy/dev/if_aumac.c,v retrieving revision 1.31 diff -u -b -r1.31 if_aumac.c --- sys/arch/mips/alchemy/dev/if_aumac.c 10 Jul 2011 23:13:23 -0000 1.31 +++ sys/arch/mips/alchemy/dev/if_aumac.c 21 Oct 2011 20:31:07 -0000 @@ -143,7 +143,7 @@ int sc_rxptr; /* next ready Rx descriptor */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif #ifdef AUMAC_EVENT_COUNTERS Index: sys/arch/mips/atheros/dev/aevar.h =================================================================== RCS file: /cvsroot/src/sys/arch/mips/atheros/dev/aevar.h,v retrieving revision 1.3 diff -u -b -r1.3 aevar.h --- sys/arch/mips/atheros/dev/aevar.h 28 Apr 2008 20:23:28 -0000 1.3 +++ sys/arch/mips/atheros/dev/aevar.h 21 Oct 2011 20:31:07 -0000 @@ -187,7 +187,7 @@ 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 Index: sys/arch/mips/sibyte/dev/sbscnvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/mips/sibyte/dev/sbscnvar.h,v retrieving revision 1.4 diff -u -b -r1.4 sbscnvar.h --- sys/arch/mips/sibyte/dev/sbscnvar.h 1 Feb 2011 03:16:54 -0000 1.4 +++ sys/arch/mips/sibyte/dev/sbscnvar.h 21 Oct 2011 20:31:08 -0000 @@ -157,7 +157,7 @@ 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 }; Index: sys/arch/next68k/dev/mb8795var.h =================================================================== RCS file: /cvsroot/src/sys/arch/next68k/dev/mb8795var.h,v retrieving revision 1.11 diff -u -b -r1.11 mb8795var.h --- sys/arch/next68k/dev/mb8795var.h 24 Apr 2010 19:58:13 -0000 1.11 +++ sys/arch/next68k/dev/mb8795var.h 21 Oct 2011 20:31:08 -0000 @@ -72,7 +72,7 @@ struct ifmedia sc_media; #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif /* NRND */ }; Index: sys/arch/sgimips/hpc/sqvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/sgimips/hpc/sqvar.h,v retrieving revision 1.12 diff -u -b -r1.12 sqvar.h --- sys/arch/sgimips/hpc/sqvar.h 25 Jan 2011 13:12:39 -0000 1.12 +++ sys/arch/sgimips/hpc/sqvar.h 21 Oct 2011 20:31:08 -0000 @@ -157,7 +157,7 @@ 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 */ Index: sys/arch/sgimips/mace/if_mec.c =================================================================== RCS file: /cvsroot/src/sys/arch/sgimips/mace/if_mec.c,v retrieving revision 1.46 diff -u -b -r1.46 if_mec.c --- sys/arch/sgimips/mace/if_mec.c 1 Jul 2011 18:53:47 -0000 1.46 +++ sys/arch/sgimips/mace/if_mec.c 21 Oct 2011 20:31:08 -0000 @@ -317,7 +317,7 @@ 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 */ Index: sys/arch/sun2/dev/if_ec.c =================================================================== RCS file: /cvsroot/src/sys/arch/sun2/dev/if_ec.c,v retrieving revision 1.18 diff -u -b -r1.18 if_ec.c --- sys/arch/sun2/dev/if_ec.c 5 Apr 2010 07:19:32 -0000 1.18 +++ sys/arch/sun2/dev/if_ec.c 21 Oct 2011 20:31:09 -0000 @@ -102,7 +102,7 @@ uint32_t sc_backoff_seed; /* seed for the backoff PRNG */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/arch/x68k/dev/fd.c =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/dev/fd.c,v retrieving revision 1.94 diff -u -b -r1.94 fd.c --- sys/arch/x68k/dev/fd.c 10 Apr 2011 15:23:06 -0000 1.94 +++ sys/arch/x68k/dev/fd.c 21 Oct 2011 20:31:09 -0000 @@ -245,7 +245,7 @@ #define SEC_P11 0x03 /* both part */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/arch/x86/include/via_padlock.h =================================================================== RCS file: /cvsroot/src/sys/arch/x86/include/via_padlock.h,v retrieving revision 1.6 diff -u -b -r1.6 via_padlock.h --- sys/arch/x86/include/via_padlock.h 19 Feb 2011 13:52:28 -0000 1.6 +++ sys/arch/x86/include/via_padlock.h 21 Oct 2011 20:31:09 -0000 @@ -61,7 +61,7 @@ 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 */ Index: sys/arch/x86/pci/fwhrng.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/pci/fwhrng.c,v retrieving revision 1.3 diff -u -b -r1.3 fwhrng.c --- sys/arch/x86/pci/fwhrng.c 1 Jul 2011 18:22:08 -0000 1.3 +++ sys/arch/x86/pci/fwhrng.c 21 Oct 2011 20:31:09 -0000 @@ -54,7 +54,7 @@ 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; Index: sys/arch/x86/x86/via_padlock.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/via_padlock.c,v retrieving revision 1.15 diff -u -b -r1.15 via_padlock.c --- sys/arch/x86/x86/via_padlock.c 24 May 2011 18:59:21 -0000 1.15 +++ sys/arch/x86/x86/via_padlock.c 21 Oct 2011 20:31:09 -0000 @@ -258,8 +258,7 @@ 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; Index: sys/arch/xen/include/xbdvar.h =================================================================== RCS file: /cvsroot/src/sys/arch/xen/include/xbdvar.h,v retrieving revision 1.12 diff -u -b -r1.12 xbdvar.h --- sys/arch/xen/include/xbdvar.h 23 Oct 2009 02:32:33 -0000 1.12 +++ sys/arch/xen/include/xbdvar.h 21 Oct 2011 20:31:09 -0000 @@ -40,7 +40,7 @@ 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 }; Index: sys/arch/xen/xen/if_xennet_xenbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/if_xennet_xenbus.c,v retrieving revision 1.53 diff -u -b -r1.53 if_xennet_xenbus.c --- sys/arch/xen/xen/if_xennet_xenbus.c 26 Sep 2011 21:44:09 -0000 1.53 +++ sys/arch/xen/xen/if_xennet_xenbus.c 21 Oct 2011 20:31:10 -0000 @@ -203,7 +203,7 @@ #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 - \ Index: sys/arch/xen/xen/xbd_xenbus.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/xbd_xenbus.c,v retrieving revision 1.48 diff -u -b -r1.48 xbd_xenbus.c --- sys/arch/xen/xen/xbd_xenbus.c 20 Sep 2011 00:12:24 -0000 1.48 +++ sys/arch/xen/xen/xbd_xenbus.c 21 Oct 2011 20:31:10 -0000 @@ -155,7 +155,7 @@ 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 }; Index: sys/conf/files =================================================================== RCS file: /cvsroot/src/sys/conf/files,v retrieving revision 1.1029 diff -u -b -r1.1029 files --- sys/conf/files 15 Oct 2011 00:23:08 -0000 1.1029 +++ sys/conf/files 21 Oct 2011 20:31:10 -0000 @@ -165,10 +165,12 @@ 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 ieee1394 define token define sppp -define wlan: rijndael +define wlan define crypto # devices ARPing IPv4 pull this in: @@ -1280,7 +1282,7 @@ 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 @@ -1521,10 +1523,12 @@ file kern/kgdb_stub.c kgdb file kern/sched_4bsd.c sched_4bsd file kern/sched_m2.c sched_m2 +file kern/subr_rngtest.c 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 Index: sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg =================================================================== RCS file: sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg diff -N sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/nist_ctr_drbg/files.nist_ctr_drbg 21 Oct 2011 20:31:10 -0000 @@ -0,0 +1,3 @@ +# $NetBSD: files.rijndael,v 1.5 2005/12/11 12:20:52 christos Exp $ + +file crypto/nist_ctr_drbg/nist_ctr_drbg.c Index: sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h =================================================================== RCS file: sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h diff -N sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/nist_ctr_drbg/nist_ctr_aes_rijndael.h 21 Oct 2011 20:31:10 -0000 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2007 Henric Jungheim + * + * 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 + +#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 */ Index: sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c =================================================================== RCS file: sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c diff -N sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/nist_ctr_drbg/nist_ctr_drbg.c 21 Oct 2011 20:31:10 -0000 @@ -0,0 +1,598 @@ +/* + * Copyright (c) 2007 Henric Jungheim + * + * 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 +#include + +#include + +/* + * 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 void +nist_increment_block(unsigned int* V) +{ + int i; + unsigned int x; + + for (i = NIST_BLOCK_OUTLEN_INTS - 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(&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(&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; +} Index: sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h =================================================================== RCS file: sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h diff -N sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/nist_ctr_drbg/nist_ctr_drbg.h 21 Oct 2011 20:31:10 -0000 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2007 Henric Jungheim + * + * 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 + +#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* drbg, + void* output_string, int output_string_length, + const void* additional_input, int additional_input_length); + +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 +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 +nist_ctr_drbg_destroy(NIST_CTR_DRBG* ); + +void +nist_dump_simple_hex(const void* data, int length); + +void +nist_dump_hex(const void* data, int length); + +void +nist_dump_named_hex(const char* name, const void* data, int length); + +void +nist_dump_ctr_drbg(const NIST_CTR_DRBG* drbg); + +void +nist_dump_block_ctx(const NIST_Key* ctx); + + +#ifdef NIST_ZEROIZE +#define nist_zeroize(p, s) memset(p, 0, s) +#else +#define nist_zeroize(p, s) do { } while(0) +#endif + +#define NIST_HTONL(x) htonl(x) +#define NIST_NTOHL(x) ntohl(x) + +#endif /* NIST_CTR_DRBG_H */ Index: sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h =================================================================== RCS file: sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h diff -N sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h 21 Oct 2011 20:31:10 -0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2007 Henric Jungheim + * + * 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)) + +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 are only using a 32-bit counter, + * so we set the reseed interval a bit lower. + */ +#define NIST_CTR_DRBG_RESEED_INTERVAL (100000) + +#endif /* NIST_CTR_DRBG_AES128_H */ Index: sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h =================================================================== RCS file: sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h diff -N sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h 21 Oct 2011 20:31:10 -0000 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2007 Henric Jungheim + * + * 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)) + +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 are only using a 32-bit counter, + * so we set the reseed interval a bit lower. + */ +#define NIST_CTR_DRBG_RESEED_INTERVAL (100000) + +#endif /* NIST_CTR_DRBG_AES256_H */ Index: sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h =================================================================== RCS file: sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h diff -N sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/crypto/nist_ctr_drbg/nist_ctr_drbg_config.h 21 Oct 2011 20:31:10 -0000 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2007 Henric Jungheim + * + * 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 + +/* #define NIST_ZEROIZE 1 */ + +#include + +/* Use AES-128 as the block cipher */ +#include + +#endif /* NIST_CTR_DRBG_CONFIG_H */ Index: sys/crypto/rijndael/files.rijndael =================================================================== RCS file: /cvsroot/src/sys/crypto/rijndael/files.rijndael,v retrieving revision 1.5 diff -u -b -r1.5 files.rijndael --- sys/crypto/rijndael/files.rijndael 11 Dec 2005 12:20:52 -0000 1.5 +++ sys/crypto/rijndael/files.rijndael 21 Oct 2011 20:31:10 -0000 @@ -1,7 +1,5 @@ # $NetBSD: files.rijndael,v 1.5 2005/12/11 12:20:52 christos 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 Index: sys/dev/ldvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ldvar.h,v retrieving revision 1.18 diff -u -b -r1.18 ldvar.h --- sys/dev/ldvar.h 20 Sep 2010 06:54:06 -0000 1.18 +++ sys/dev/ldvar.h 21 Oct 2011 20:31:10 -0000 @@ -46,7 +46,7 @@ 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 */ Index: sys/dev/rnd.c =================================================================== RCS file: /cvsroot/src/sys/dev/rnd.c,v retrieving revision 1.82 diff -u -b -r1.82 rnd.c --- sys/dev/rnd.c 11 Oct 2011 23:55:30 -0000 1.82 +++ sys/dev/rnd.c 21 Oct 2011 20:31:10 -0000 @@ -50,6 +50,7 @@ #include #include #include +#include #if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */ #include @@ -89,7 +90,7 @@ #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 +106,13 @@ kmutex_t rnd_mtx; /* + * Entropy sinks: usually other generators waiting to be rekeyed. + * The list is protected by the rndpool_mtx. 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 +138,18 @@ * 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 +169,17 @@ }; 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,12 +208,37 @@ static inline void rnd_wakeup_readers(void) { + rndsink_t *sink, *tsink; + TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk); + + mutex_enter(&rndpool_mtx); + if (rndpool_get_entropy_count(&rnd_pool) < RND_ENTROPY_THRESHOLD * 8) { + mutex_exit(&rndpool_mtx); + return; + } /* - * If we have added new bits, and now have enough to do something, - * wake up sleeping readers. + * 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 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); @@ -210,6 +251,22 @@ rnd_have_entropy = 1; } mutex_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\".\n", + (int)sink->len, sink->name); +#endif + sink->cb(sink->arg); + TAILQ_REMOVE(&sunk, sink, tailq); + } } /* @@ -218,7 +275,7 @@ * 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; @@ -315,6 +372,7 @@ LIST_INIT(&rnd_sources); SIMPLEQ_INIT(&rnd_samples); + TAILQ_INIT(&rnd_sinks); selinit(&rnd_selq); rndpool_init(&rnd_pool); @@ -470,11 +528,21 @@ 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; @@ -552,10 +620,10 @@ * 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 +632,9 @@ * 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 +646,13 @@ * 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, 16) == 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 +665,19 @@ * 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 +686,14 @@ /* * 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, 16) == 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 */ @@ -763,7 +823,7 @@ } static rnd_sample_t * -rnd_sample_allocate(rndsource_t *source) +rnd_sample_allocate(krndsource_t *source) { rnd_sample_t *c; @@ -782,7 +842,7 @@ * 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; @@ -808,7 +868,7 @@ * 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 +877,11 @@ 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 +890,26 @@ 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); 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) @@ -860,22 +931,23 @@ * 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 +960,9 @@ 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 +971,12 @@ * 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; - - rst = &rs->data; - - if (rst->flags & RND_FLAG_NO_COLLECT) + if (rs->flags & RND_FLAG_NO_COLLECT) return; /* @@ -921,12 +989,12 @@ * If the sample buffer is NULL, try to allocate one here. If this * fails, drop this sample. */ - state = rst->state; + state = rs->state; if (state == NULL) { - state = rnd_sample_allocate_isr(rst); + state = rnd_sample_allocate_isr(rs); if (state == NULL) return; - rst->state = state; + rs->state = state; } /* @@ -934,8 +1002,8 @@ * 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) + state->entropy += rnd_estimate_entropy(rs, ts); state->ts[state->cursor] = ts; state->values[state->cursor] = val; @@ -950,18 +1018,27 @@ /* * State arrays are full. Queue this chunk on the processing queue. */ - mutex_enter(&rnd_mtx); + mutex_spin_enter(&rnd_mtx); SIMPLEQ_INSERT_HEAD(&rnd_samples, state, next); - rst->state = NULL; + rs->state = NULL; /* - * If the timeout isn't pending, have it run in the near future. + * 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. */ + if (__predict_false(cold)) { +#ifdef RND_VERBOSE + printf("rnd: directly processing boot-time events.\n"); +#endif + rnd_process_events(NULL); /* Drops lock! */ + } else { if (rnd_timeout_pending == 0) { rnd_timeout_pending = 1; callout_reset(&rnd_callout, 1, rnd_timeout, NULL); } - mutex_exit(&rnd_mtx); + mutex_spin_exit(&rnd_mtx); + } /* * To get here we have to have queued the state up, and therefore @@ -969,23 +1046,21 @@ * if we don't get it, it doesn't matter; we'll try again on * the next random event. */ - rst->state = rnd_sample_allocate_isr(rst); + rs->state = rnd_sample_allocate_isr(rs); } void -rnd_add_data(rndsource_element_t *rs, void *data, u_int32_t len, +rnd_add_data(krndsource_t *rs, void *data, u_int32_t len, u_int32_t entropy) { - rndsource_t *rst; /* Mix in the random data directly into the pool. */ rndpool_add_data(&rnd_pool, data, len, entropy); if (rs != NULL) { - rst = &rs->data; - rst->total += entropy; + rs->total += entropy; - if ((rst->flags & RND_FLAG_NO_ESTIMATE) == 0) + if ((rs->flags & RND_FLAG_NO_ESTIMATE) == 0) /* Estimate entropy using timing information */ rnd_add_uint32(rs, *(u_int8_t *)data); } @@ -994,58 +1069,152 @@ rnd_wakeup_readers(); } +static int +rnd_hwrng_test(rnd_sample_t *sample) +{ + krndsource_t *source = sample->source; + size_t cmplen; + uint8_t *v1, *v2; + size_t resid, totest; + + KASSERT(source->type = RND_TYPE_RNG); + + /* + * 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; + } + + /* + * 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); /* - * 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); - - source = sample->source; - /* - * We repeat this check here, since it is possible the source - * was disabled before we were called, but after the entry - * was queued. + * We repeat this check here, since it is possible + * the source was disabled before we were called, but + * after the entry was queued. */ - if ((source->flags & RND_FLAG_NO_COLLECT) == 0) { + 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_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; - mutex_enter(&rndpool_mtx); + /* + * Hardware generators are great but sometimes they + * have...hardware issues. Don't use any data from + * them unless it passes some tests. + */ + 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); rndpool_add_data(&rnd_pool, sample->ts, - RND_SAMPLE_COUNT * 4, - entropy); - mutex_exit(&rndpool_mtx); + RND_SAMPLE_COUNT * 4, entropy); source->total += sample->entropy; + SIMPLEQ_INSERT_TAIL(&df_samples, sample, next); } + mutex_exit(&rndpool_mtx); + /* 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 +1222,17 @@ 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 +1249,42 @@ 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)) { + 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); } @@ -1082,3 +1298,26 @@ mutex_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_enter(&rndpool_mtx); + TAILQ_INSERT_TAIL(&rnd_sinks, rs, tailq); + mutex_exit(&rndpool_mtx); +} + +void +rndsink_detach(rndsink_t *rs) +{ +#ifdef RND_VERBOSE + printf("rnd: entropy sink \"%s\" no longer wants data.\n", rs->name); +#endif + mutex_enter(&rndpool_mtx); + TAILQ_REMOVE(&rnd_sinks, rs, tailq); + mutex_exit(&rndpool_mtx); +} Index: sys/dev/ata/wdvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ata/wdvar.h,v retrieving revision 1.38 diff -u -b -r1.38 wdvar.h --- sys/dev/ata/wdvar.h 17 Dec 2009 21:03:10 -0000 1.38 +++ sys/dev/ata/wdvar.h 21 Oct 2011 20:31:11 -0000 @@ -67,7 +67,7 @@ u_int sc_bscount; #endif #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/gpib/rd.c =================================================================== RCS file: /cvsroot/src/sys/dev/gpib/rd.c,v retrieving revision 1.28 diff -u -b -r1.28 rd.c --- sys/dev/gpib/rd.c 8 Feb 2011 20:20:27 -0000 1.28 +++ sys/dev/gpib/rd.c 21 Oct 2011 20:31:11 -0000 @@ -143,7 +143,7 @@ struct callout sc_restart_ch; #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/ic/comvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/comvar.h,v retrieving revision 1.71 diff -u -b -r1.71 comvar.h --- sys/dev/ic/comvar.h 13 Nov 2010 15:35:50 -0000 1.71 +++ sys/dev/ic/comvar.h 21 Oct 2011 20:31:11 -0000 @@ -228,7 +228,7 @@ 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; }; Index: sys/dev/ic/cs89x0var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/cs89x0var.h,v retrieving revision 1.14 diff -u -b -r1.14 cs89x0var.h --- sys/dev/ic/cs89x0var.h 22 Sep 2009 14:55:19 -0000 1.14 +++ sys/dev/ic/cs89x0var.h 21 Oct 2011 20:31:11 -0000 @@ -105,7 +105,7 @@ 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 */ Index: sys/dev/ic/dp8390var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/dp8390var.h,v retrieving revision 1.30 diff -u -b -r1.30 dp8390var.h --- sys/dev/ic/dp8390var.h 12 May 2009 14:25:17 -0000 1.30 +++ sys/dev/ic/dp8390var.h 21 Oct 2011 20:31:11 -0000 @@ -72,7 +72,7 @@ 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 *); Index: sys/dev/ic/elink3var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/elink3var.h,v retrieving revision 1.36 diff -u -b -r1.36 elink3var.h --- sys/dev/ic/elink3var.h 5 Sep 2009 12:30:59 -0000 1.36 +++ sys/dev/ic/elink3var.h 21 Oct 2011 20:31:11 -0000 @@ -102,7 +102,7 @@ int ep_pktlenshift; /* scale factor for pkt lengths */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif /* power management hooks */ Index: sys/dev/ic/elinkxlvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/elinkxlvar.h,v retrieving revision 1.22 diff -u -b -r1.22 elinkxlvar.h --- sys/dev/ic/elinkxlvar.h 22 Mar 2010 23:03:30 -0000 1.22 +++ sys/dev/ic/elinkxlvar.h 21 Oct 2011 20:31:11 -0000 @@ -110,7 +110,7 @@ #define EX_FLAGS_ATTACHED 0x4000 /* attach has succeeded */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif /* power management hooks */ Index: sys/dev/ic/gemvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/gemvar.h,v retrieving revision 1.21 diff -u -b -r1.21 gemvar.h --- sys/dev/ic/gemvar.h 24 Feb 2010 22:37:58 -0000 1.21 +++ sys/dev/ic/gemvar.h 21 Oct 2011 20:31:11 -0000 @@ -217,7 +217,7 @@ void (*sc_hwinit)(struct gem_softc *); #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif struct evcnt sc_ev_intr; Index: sys/dev/ic/hmevar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/hmevar.h,v retrieving revision 1.21 diff -u -b -r1.21 hmevar.h --- sys/dev/ic/hmevar.h 18 Sep 2009 12:40:15 -0000 1.21 +++ sys/dev/ic/hmevar.h 21 Oct 2011 20:31:11 -0000 @@ -95,7 +95,7 @@ void (*sc_hwinit)(struct hme_softc *); #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/ic/i82557var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/i82557var.h,v retrieving revision 1.48 diff -u -b -r1.48 i82557var.h --- sys/dev/ic/i82557var.h 25 Feb 2010 23:40:39 -0000 1.48 +++ sys/dev/ic/i82557var.h 21 Oct 2011 20:31:11 -0000 @@ -242,7 +242,7 @@ 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 }; Index: sys/dev/ic/lan9118var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/lan9118var.h,v retrieving revision 1.2 diff -u -b -r1.2 lan9118var.h --- sys/dev/ic/lan9118var.h 28 Nov 2009 08:44:00 -0000 1.2 +++ sys/dev/ic/lan9118var.h 21 Oct 2011 20:31:11 -0000 @@ -76,7 +76,7 @@ #define LAN9118_FLAGS_NO_EEPROM 0x00000002 #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/ic/lancevar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/lancevar.h,v retrieving revision 1.13 diff -u -b -r1.13 lancevar.h --- sys/dev/ic/lancevar.h 4 Sep 2009 16:21:24 -0000 1.13 +++ sys/dev/ic/lancevar.h 21 Oct 2011 20:31:11 -0000 @@ -116,7 +116,7 @@ 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 *); Index: sys/dev/ic/lemacvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/lemacvar.h,v retrieving revision 1.9 diff -u -b -r1.9 lemacvar.h --- sys/dev/ic/lemacvar.h 11 Dec 2005 12:21:27 -0000 1.9 +++ sys/dev/ic/lemacvar.h 21 Oct 2011 20:31:11 -0000 @@ -80,7 +80,7 @@ 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; Index: sys/dev/ic/mb86950var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/mb86950var.h,v retrieving revision 1.5 diff -u -b -r1.5 mb86950var.h --- sys/dev/ic/mb86950var.h 12 May 2009 14:25:17 -0000 1.5 +++ sys/dev/ic/mb86950var.h 21 Oct 2011 20:31:11 -0000 @@ -60,7 +60,7 @@ 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 */ Index: sys/dev/ic/mb86960var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/mb86960var.h,v retrieving revision 1.37 diff -u -b -r1.37 mb86960var.h --- sys/dev/ic/mb86960var.h 12 May 2009 14:25:17 -0000 1.37 +++ sys/dev/ic/mb86960var.h 21 Oct 2011 20:31:11 -0000 @@ -162,7 +162,7 @@ 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 */ Index: sys/dev/ic/mtd803var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/mtd803var.h,v retrieving revision 1.6 diff -u -b -r1.6 mtd803var.h --- sys/dev/ic/mtd803var.h 28 Apr 2008 20:23:50 -0000 1.6 +++ sys/dev/ic/mtd803var.h 21 Oct 2011 20:31:11 -0000 @@ -75,7 +75,7 @@ bus_dmamap_t buf_dma_map; #if NRND > 0 - rndsource_element_t rnd_src; + krndsource_t rnd_src; #endif }; Index: sys/dev/ic/pckbc.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/pckbc.c,v retrieving revision 1.51 diff -u -b -r1.51 pckbc.c --- sys/dev/ic/pckbc.c 8 Aug 2010 09:33:05 -0000 1.51 +++ sys/dev/ic/pckbc.c 21 Oct 2011 20:31:12 -0000 @@ -59,7 +59,7 @@ 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 }; Index: sys/dev/ic/rtl81x9var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/rtl81x9var.h,v retrieving revision 1.50 diff -u -b -r1.50 rtl81x9var.h --- sys/dev/ic/rtl81x9var.h 27 Jul 2010 21:02:00 -0000 1.50 +++ sys/dev/ic/rtl81x9var.h 21 Oct 2011 20:31:12 -0000 @@ -226,7 +226,7 @@ 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 }; Index: sys/dev/ic/seeq8005var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/seeq8005var.h,v retrieving revision 1.5 diff -u -b -r1.5 seeq8005var.h --- sys/dev/ic/seeq8005var.h 7 Nov 2001 20:01:58 -0000 1.5 +++ sys/dev/ic/seeq8005var.h 21 Oct 2011 20:31:12 -0000 @@ -86,7 +86,7 @@ int sc_flags; #define SF_8BIT 0x01 #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/ic/smc91cxxvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/smc91cxxvar.h,v retrieving revision 1.16 diff -u -b -r1.16 smc91cxxvar.h --- sys/dev/ic/smc91cxxvar.h 12 May 2009 14:25:18 -0000 1.16 +++ sys/dev/ic/smc91cxxvar.h 21 Oct 2011 20:31:12 -0000 @@ -61,7 +61,7 @@ uint8_t sc_intmask; uint8_t sc_txpacketno; /* cached packetno */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/ic/tulipvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/tulipvar.h,v retrieving revision 1.65 diff -u -b -r1.65 tulipvar.h --- sys/dev/ic/tulipvar.h 9 Jul 2011 23:18:05 -0000 1.65 +++ sys/dev/ic/tulipvar.h 21 Oct 2011 20:31:12 -0000 @@ -448,7 +448,7 @@ 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 Index: sys/dev/isa/fdvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/isa/fdvar.h,v retrieving revision 1.6 diff -u -b -r1.6 fdvar.h --- sys/dev/isa/fdvar.h 28 Apr 2008 20:23:52 -0000 1.6 +++ sys/dev/isa/fdvar.h 21 Oct 2011 20:31:12 -0000 @@ -91,6 +91,6 @@ int sc_active; /* number of active I/O operations */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/isa/if_eg.c =================================================================== RCS file: /cvsroot/src/sys/dev/isa/if_eg.c,v retrieving revision 1.82 diff -u -b -r1.82 if_eg.c --- sys/dev/isa/if_eg.c 5 Apr 2010 07:20:24 -0000 1.82 +++ sys/dev/isa/if_eg.c 21 Oct 2011 20:31:12 -0000 @@ -114,7 +114,7 @@ void * eg_outbuf; /* Outgoing packet buffer */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/isa/if_el.c =================================================================== RCS file: /cvsroot/src/sys/dev/isa/if_el.c,v retrieving revision 1.86 diff -u -b -r1.86 if_el.c --- sys/dev/isa/if_el.c 5 Apr 2010 07:20:24 -0000 1.86 +++ sys/dev/isa/if_el.c 21 Oct 2011 20:31:12 -0000 @@ -80,7 +80,7 @@ bus_space_handle_t sc_ioh; /* i/o handle */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/isa/if_iy.c =================================================================== RCS file: /cvsroot/src/sys/dev/isa/if_iy.c,v retrieving revision 1.88 diff -u -b -r1.88 if_iy.c --- sys/dev/isa/if_iy.c 5 Apr 2010 07:20:24 -0000 1.88 +++ sys/dev/isa/if_iy.c 21 Oct 2011 20:31:12 -0000 @@ -129,7 +129,7 @@ #endif #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/marvell/if_gfevar.h =================================================================== RCS file: /cvsroot/src/sys/dev/marvell/if_gfevar.h,v retrieving revision 1.10 diff -u -b -r1.10 if_gfevar.h --- sys/dev/marvell/if_gfevar.h 28 Apr 2010 13:51:56 -0000 1.10 +++ sys/dev/marvell/if_gfevar.h 21 Oct 2011 20:31:12 -0000 @@ -168,7 +168,7 @@ 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_ */ Index: sys/dev/marvell/if_mvgbe.c =================================================================== RCS file: /cvsroot/src/sys/dev/marvell/if_mvgbe.c,v retrieving revision 1.13 diff -u -b -r1.13 if_mvgbe.c --- sys/dev/marvell/if_mvgbe.c 6 Sep 2011 19:38:23 -0000 1.13 +++ sys/dev/marvell/if_mvgbe.c 21 Oct 2011 20:31:12 -0000 @@ -216,7 +216,7 @@ 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 }; Index: sys/dev/mca/edvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/mca/edvar.h,v retrieving revision 1.13 diff -u -b -r1.13 edvar.h --- sys/dev/mca/edvar.h 4 May 2008 13:11:14 -0000 1.13 +++ sys/dev/mca/edvar.h 21 Oct 2011 20:31:12 -0000 @@ -61,6 +61,6 @@ u_int32_t rba; /* # of RBAs */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/pci/amdpmvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/amdpmvar.h,v retrieving revision 1.6 diff -u -b -r1.6 amdpmvar.h --- sys/dev/pci/amdpmvar.h 28 Apr 2008 20:23:54 -0000 1.6 +++ sys/dev/pci/amdpmvar.h 21 Oct 2011 20:31:12 -0000 @@ -52,7 +52,7 @@ 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; Index: sys/dev/pci/hifn7751.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/hifn7751.c,v retrieving revision 1.46 diff -u -b -r1.46 hifn7751.c --- sys/dev/pci/hifn7751.c 13 Nov 2010 13:52:05 -0000 1.46 +++ sys/dev/pci/hifn7751.c 21 Oct 2011 20:31:13 -0000 @@ -50,13 +50,6 @@ #include __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 - - #include #include #include @@ -71,7 +64,7 @@ #include #else #include -#include +#include #endif #include @@ -2077,7 +2070,7 @@ 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 */ Index: sys/dev/pci/hifn7751var.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/hifn7751var.h,v retrieving revision 1.7 diff -u -b -r1.7 hifn7751var.h --- sys/dev/pci/hifn7751var.h 11 Dec 2005 12:22:49 -0000 1.7 +++ sys/dev/pci/hifn7751var.h 21 Oct 2011 20:31:13 -0000 @@ -168,7 +168,7 @@ 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 */ Index: sys/dev/pci/if_bce.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_bce.c,v retrieving revision 1.33 diff -u -b -r1.33 if_bce.c --- sys/dev/pci/if_bce.c 13 Nov 2010 13:52:05 -0000 1.33 +++ sys/dev/pci/if_bce.c 21 Oct 2011 20:31:13 -0000 @@ -139,7 +139,7 @@ int bce_txsnext; /* next available tx slot */ callout_t bce_timeout; #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/pci/if_bgevar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_bgevar.h,v retrieving revision 1.7 diff -u -b -r1.7 if_bgevar.h --- sys/dev/pci/if_bgevar.h 18 May 2011 01:02:43 -0000 1.7 +++ sys/dev/pci/if_bgevar.h 21 Oct 2011 20:31:13 -0000 @@ -290,7 +290,7 @@ struct sysctllog *bge_log; #if NRND > 0 - rndsource_element_t rnd_source; /* random source */ + krndsource_t rnd_source; /* random source */ #endif }; Index: sys/dev/pci/if_casvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_casvar.h,v retrieving revision 1.2 diff -u -b -r1.2 if_casvar.h --- sys/dev/pci/if_casvar.h 18 Jan 2010 18:09:22 -0000 1.2 +++ sys/dev/pci/if_casvar.h 21 Oct 2011 20:31:13 -0000 @@ -195,7 +195,7 @@ void *sc_sh; /* shutdownhook cookie */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif struct evcnt sc_ev_intr; Index: sys/dev/pci/if_devar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_devar.h,v retrieving revision 1.55 diff -u -b -r1.55 if_devar.h --- sys/dev/pci/if_devar.h 5 Apr 2010 07:20:25 -0000 1.55 +++ sys/dev/pci/if_devar.h 21 Oct 2011 20:31:13 -0000 @@ -695,7 +695,7 @@ 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 }; Index: sys/dev/pci/if_dge.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_dge.c,v retrieving revision 1.31 diff -u -b -r1.31 if_dge.c --- sys/dev/pci/if_dge.c 13 Nov 2010 13:52:06 -0000 1.31 +++ sys/dev/pci/if_dge.c 21 Oct 2011 20:31:14 -0000 @@ -334,7 +334,7 @@ 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; Index: sys/dev/pci/if_iwi.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_iwi.c,v retrieving revision 1.87 diff -u -b -r1.87 if_iwi.c --- sys/dev/pci/if_iwi.c 23 May 2011 15:37:36 -0000 1.87 +++ sys/dev/pci/if_iwi.c 21 Oct 2011 20:31:14 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -2386,7 +2387,8 @@ 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) Index: sys/dev/pci/if_jme.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_jme.c,v retrieving revision 1.17 diff -u -b -r1.17 if_jme.c --- sys/dev/pci/if_jme.c 30 Mar 2011 18:11:37 -0000 1.17 +++ sys/dev/pci/if_jme.c 21 Oct 2011 20:31:15 -0000 @@ -168,7 +168,7 @@ 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; Index: sys/dev/pci/if_mskvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_mskvar.h,v retrieving revision 1.8 diff -u -b -r1.8 if_mskvar.h --- sys/dev/pci/if_mskvar.h 24 Dec 2009 18:27:32 -0000 1.8 +++ sys/dev/pci/if_mskvar.h 21 Oct 2011 20:31:15 -0000 @@ -210,7 +210,7 @@ int sk_status_idx; int sk_status_own_idx; #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/pci/if_pcn.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_pcn.c,v retrieving revision 1.52 diff -u -b -r1.52 if_pcn.c --- sys/dev/pci/if_pcn.c 13 Nov 2010 13:52:06 -0000 1.52 +++ sys/dev/pci/if_pcn.c 21 Oct 2011 20:31:15 -0000 @@ -313,7 +313,7 @@ uint32_t sc_mode; /* prototype MODE register */ #if NRND > 0 - rndsource_element_t rnd_source; /* random source */ + krndsource_t rnd_source; /* random source */ #endif }; Index: sys/dev/pci/if_sip.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_sip.c,v retrieving revision 1.150 diff -u -b -r1.150 if_sip.c --- sys/dev/pci/if_sip.c 15 Oct 2011 19:50:20 -0000 1.150 +++ sys/dev/pci/if_sip.c 21 Oct 2011 20:31:15 -0000 @@ -355,7 +355,7 @@ void (*sc_rxintr)(struct sip_softc *); #if NRND > 0 - rndsource_element_t rnd_source; /* random source */ + krndsource_t rnd_source; /* random source */ #endif }; Index: sys/dev/pci/if_skvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_skvar.h,v retrieving revision 1.15 diff -u -b -r1.15 if_skvar.h --- sys/dev/pci/if_skvar.h 8 Sep 2008 21:20:03 -0000 1.15 +++ sys/dev/pci/if_skvar.h 21 Oct 2011 20:31:15 -0000 @@ -205,7 +205,7 @@ 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 }; Index: sys/dev/pci/if_tlvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_tlvar.h,v retrieving revision 1.14 diff -u -b -r1.14 if_tlvar.h --- sys/dev/pci/if_tlvar.h 19 Oct 2009 18:41:15 -0000 1.14 +++ sys/dev/pci/if_tlvar.h 21 Oct 2011 20:31:15 -0000 @@ -85,7 +85,7 @@ int oerr_mcopy; #endif #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; #define tl_if tl_ec.ec_if Index: sys/dev/pci/if_vr.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_vr.c,v retrieving revision 1.107 diff -u -b -r1.107 if_vr.c --- sys/dev/pci/if_vr.c 16 Dec 2010 17:07:44 -0000 1.107 +++ sys/dev/pci/if_vr.c 21 Oct 2011 20:31:16 -0000 @@ -234,7 +234,7 @@ uint32_t vr_save_irq; #if NRND > 0 - rndsource_element_t rnd_source; /* random source */ + krndsource_t rnd_source; /* random source */ #endif }; Index: sys/dev/pci/if_vtevar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_vtevar.h,v retrieving revision 1.1 diff -u -b -r1.1 if_vtevar.h --- sys/dev/pci/if_vtevar.h 26 Jan 2011 18:48:13 -0000 1.1 +++ sys/dev/pci/if_vtevar.h 21 Oct 2011 20:31:16 -0000 @@ -139,7 +139,7 @@ int vte_int_tx_mod; #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/pci/if_wm.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/if_wm.c,v retrieving revision 1.223 diff -u -b -r1.223 if_wm.c --- sys/dev/pci/if_wm.c 1 Jul 2011 07:45:39 -0000 1.223 +++ sys/dev/pci/if_wm.c 21 Oct 2011 20:31:17 -0000 @@ -379,7 +379,7 @@ int sc_mchash_type; /* multicast filter offset */ #if NRND > 0 - rndsource_element_t rnd_source; /* random source */ + krndsource_t rnd_source; /* random source */ #endif }; Index: sys/dev/pci/ubsec.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/ubsec.c,v retrieving revision 1.25 diff -u -b -r1.25 ubsec.c --- sys/dev/pci/ubsec.c 13 Nov 2010 13:52:09 -0000 1.25 +++ sys/dev/pci/ubsec.c 21 Oct 2011 20:31:17 -0000 @@ -65,7 +65,7 @@ #include #include #else - #include + #include #include #endif #include @@ -808,8 +808,7 @@ 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 Index: sys/dev/pci/ixgbe/ixgbe.c =================================================================== RCS file: /cvsroot/src/sys/dev/pci/ixgbe/ixgbe.c,v retrieving revision 1.1 diff -u -b -r1.1 ixgbe.c --- sys/dev/pci/ixgbe/ixgbe.c 12 Aug 2011 21:55:29 -0000 1.1 +++ sys/dev/pci/ixgbe/ixgbe.c 21 Oct 2011 20:31:18 -0000 @@ -4160,7 +4160,7 @@ 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++) { Index: sys/dev/pcmcia/if_xivar.h =================================================================== RCS file: /cvsroot/src/sys/dev/pcmcia/if_xivar.h,v retrieving revision 1.6 diff -u -b -r1.6 if_xivar.h --- sys/dev/pcmcia/if_xivar.h 6 Dec 2009 23:05:39 -0000 1.6 +++ sys/dev/pcmcia/if_xivar.h 21 Oct 2011 20:31:18 -0000 @@ -45,7 +45,7 @@ u_int8_t sc_rev; /* Chip revision */ #if NRND > 0 - rndsource_element_t sc_rnd_source; + krndsource_t sc_rnd_source; #endif }; Index: sys/dev/scsipi/cdvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/scsipi/cdvar.h,v retrieving revision 1.29 diff -u -b -r1.29 cdvar.h --- sys/dev/scsipi/cdvar.h 19 Oct 2009 18:41:16 -0000 1.29 +++ sys/dev/scsipi/cdvar.h 21 Oct 2011 20:31:18 -0000 @@ -48,6 +48,6 @@ struct callout sc_callout; #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/scsipi/sdvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/scsipi/sdvar.h,v retrieving revision 1.32 diff -u -b -r1.32 sdvar.h --- sys/dev/scsipi/sdvar.h 10 Apr 2009 17:36:42 -0000 1.32 +++ sys/dev/scsipi/sdvar.h 21 Oct 2011 20:31:18 -0000 @@ -92,7 +92,7 @@ char name[16]; /* product name, for default disklabel */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/scsipi/stvar.h =================================================================== RCS file: /cvsroot/src/sys/dev/scsipi/stvar.h,v retrieving revision 1.21 diff -u -b -r1.21 stvar.h --- sys/dev/scsipi/stvar.h 6 Dec 2009 22:48:17 -0000 1.21 +++ sys/dev/scsipi/stvar.h 21 Oct 2011 20:31:18 -0000 @@ -147,7 +147,7 @@ struct io_stats *stats; /* statistics for the drive */ #if NRND > 0 - rndsource_element_t rnd_source; + krndsource_t rnd_source; #endif }; Index: sys/dev/usb/if_auereg.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_auereg.h,v retrieving revision 1.23 diff -u -b -r1.23 if_auereg.h --- sys/dev/usb/if_auereg.h 4 Sep 2009 18:10:08 -0000 1.23 +++ sys/dev/usb/if_auereg.h 21 Oct 2011 20:31:18 -0000 @@ -229,7 +229,7 @@ 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; Index: sys/dev/usb/if_axereg.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_axereg.h,v retrieving revision 1.12 diff -u -b -r1.12 if_axereg.h --- sys/dev/usb/if_axereg.h 14 Aug 2010 10:47:57 -0000 1.12 +++ sys/dev/usb/if_axereg.h 21 Oct 2011 20:31:18 -0000 @@ -200,7 +200,7 @@ 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; Index: sys/dev/usb/if_cdcereg.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_cdcereg.h,v retrieving revision 1.5 diff -u -b -r1.5 if_cdcereg.h --- sys/dev/usb/if_cdcereg.h 4 Sep 2009 18:10:08 -0000 1.5 +++ sys/dev/usb/if_cdcereg.h 21 Oct 2011 20:31:18 -0000 @@ -69,7 +69,7 @@ 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; Index: sys/dev/usb/if_cuereg.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_cuereg.h,v retrieving revision 1.16 diff -u -b -r1.16 if_cuereg.h --- sys/dev/usb/if_cuereg.h 4 Sep 2009 18:10:08 -0000 1.16 +++ sys/dev/usb/if_cuereg.h 21 Oct 2011 20:31:18 -0000 @@ -169,7 +169,7 @@ 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) Index: sys/dev/usb/if_kuereg.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_kuereg.h,v retrieving revision 1.16 diff -u -b -r1.16 if_kuereg.h --- sys/dev/usb/if_kuereg.h 3 Nov 2010 22:30:50 -0000 1.16 +++ sys/dev/usb/if_kuereg.h 21 Oct 2011 20:31:18 -0000 @@ -163,7 +163,7 @@ 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) Index: sys/dev/usb/if_udavreg.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_udavreg.h,v retrieving revision 1.6 diff -u -b -r1.6 if_udavreg.h --- sys/dev/usb/if_udavreg.h 3 Nov 2010 22:30:50 -0000 1.6 +++ sys/dev/usb/if_udavreg.h 21 Oct 2011 20:31:18 -0000 @@ -190,7 +190,7 @@ 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; Index: sys/dev/usb/if_upl.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_upl.c,v retrieving revision 1.38 diff -u -b -r1.38 if_upl.c --- sys/dev/usb/if_upl.c 3 Nov 2010 22:28:31 -0000 1.38 +++ sys/dev/usb/if_upl.c 21 Oct 2011 20:31:18 -0000 @@ -135,7 +135,7 @@ struct ifnet sc_if; #if NRND > 0 - rndsource_element_t sc_rnd_source; + krndsource_t sc_rnd_source; #endif struct callout sc_stat_ch; Index: sys/dev/usb/if_urlreg.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/if_urlreg.h,v retrieving revision 1.6 diff -u -b -r1.6 if_urlreg.h --- sys/dev/usb/if_urlreg.h 3 Nov 2010 22:30:50 -0000 1.6 +++ sys/dev/usb/if_urlreg.h 21 Oct 2011 20:31:18 -0000 @@ -176,7 +176,7 @@ 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; Index: sys/dev/usb/ucom.c =================================================================== RCS file: /cvsroot/src/sys/dev/usb/ucom.c,v retrieving revision 1.87 diff -u -b -r1.87 ucom.c --- sys/dev/usb/ucom.c 24 Apr 2011 16:27:01 -0000 1.87 +++ sys/dev/usb/ucom.c 21 Oct 2011 20:31:19 -0000 @@ -147,7 +147,7 @@ u_char sc_dying; /* disconnecting */ #if defined(__NetBSD__) && NRND > 0 - rndsource_element_t sc_rndsource; /* random source */ + krndsource_t sc_rndsource; /* random source */ #endif }; Index: sys/dev/usb/uhidev.h =================================================================== RCS file: /cvsroot/src/sys/dev/usb/uhidev.h,v retrieving revision 1.10 diff -u -b -r1.10 uhidev.h --- sys/dev/usb/uhidev.h 3 Nov 2010 22:34:24 -0000 1.10 +++ sys/dev/usb/uhidev.h 21 Oct 2011 20:31:19 -0000 @@ -68,7 +68,7 @@ #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 }; Index: sys/dist/pf/net/pf.c =================================================================== RCS file: /cvsroot/src/sys/dist/pf/net/pf.c,v retrieving revision 1.66 diff -u -b -r1.66 pf.c --- sys/dist/pf/net/pf.c 29 Aug 2011 09:50:04 -0000 1.66 +++ sys/dist/pf/net/pf.c 21 Oct 2011 20:31:20 -0000 @@ -93,7 +93,7 @@ #ifndef __NetBSD__ #include #else -#include +#include #endif /* __NetBSD__ */ #include @@ -2321,29 +2321,30 @@ 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 @@ 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_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 @@ 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 @@ 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 @@ } (*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, Index: sys/dist/pf/netinet/tcp_rndiss.c =================================================================== RCS file: /cvsroot/src/sys/dist/pf/netinet/tcp_rndiss.c,v retrieving revision 1.2 diff -u -b -r1.2 tcp_rndiss.c --- sys/dist/pf/netinet/tcp_rndiss.c 18 Jun 2008 09:06:27 -0000 1.2 +++ sys/dist/pf/netinet/tcp_rndiss.c 21 Oct 2011 20:31:20 -0000 @@ -72,7 +72,7 @@ __KERNEL_RCSID(0, "$NetBSD: tcp_rndiss.c,v 1.2 2008/06/18 09:06:27 yamt Exp $"); #include -#include +#include #include #include @@ -104,8 +104,7 @@ 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 @@ /* (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); } Index: sys/fs/tmpfs/tmpfs_subr.c =================================================================== RCS file: /cvsroot/src/sys/fs/tmpfs/tmpfs_subr.c,v retrieving revision 1.77 diff -u -b -r1.77 tmpfs_subr.c --- sys/fs/tmpfs/tmpfs_subr.c 27 Aug 2011 15:32:28 -0000 1.77 +++ sys/fs/tmpfs/tmpfs_subr.c 21 Oct 2011 20:31:20 -0000 @@ -124,7 +124,7 @@ * 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; Index: sys/kern/exec_elf.c =================================================================== RCS file: /cvsroot/src/sys/kern/exec_elf.c,v retrieving revision 1.32 diff -u -b -r1.32 exec_elf.c --- sys/kern/exec_elf.c 27 Aug 2011 17:53:21 -0000 1.32 +++ sys/kern/exec_elf.c 21 Oct 2011 20:31:21 -0000 @@ -77,6 +77,7 @@ #include #include #include +#include #include #include @@ -134,7 +135,7 @@ pax_align = align; - r = arc4random(); + r = cprng_fast32(); if (pax_align == 0) pax_align = PGSHIFT; Index: sys/kern/init_main.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_main.c,v retrieving revision 1.436 diff -u -b -r1.436 init_main.c --- sys/kern/init_main.c 28 Sep 2011 15:52:47 -0000 1.436 +++ sys/kern/init_main.c 21 Oct 2011 20:31:21 -0000 @@ -186,9 +186,7 @@ #endif #include #include -#if NRND > 0 #include -#endif #include #if NVERIEXEC > 0 #include @@ -204,6 +202,7 @@ #ifdef PTRACE #include #endif /* PTRACE */ +#include #include #include @@ -260,6 +259,8 @@ 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 @@ /* * 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,9 @@ /* Initialize the disk wedge subsystem. */ dkwedge_init(); + /* Initialize the kernel strong PRNG. */ + kern_cprng = cprng_strong_create("kernel_cprng", IPL_VM); + /* Initialize interfaces. */ ifinit1(); @@ -509,7 +513,6 @@ /* Initialize sockets thread(s) */ soinit1(); - /* Configure the system hardware. This will enable interrupts. */ configure(); Index: sys/kern/init_sysctl.c =================================================================== RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v retrieving revision 1.183 diff -u -b -r1.183 init_sysctl.c --- sys/kern/init_sysctl.c 30 Aug 2011 12:39:59 -0000 1.183 +++ sys/kern/init_sysctl.c 21 Oct 2011 20:31:21 -0000 @@ -38,7 +38,6 @@ #include "opt_sa.h" #include "opt_posix.h" #include "pty.h" -#include "rnd.h" #include #include @@ -49,7 +48,7 @@ #include #include #include -#include +#include #include #include #include @@ -1395,12 +1394,9 @@ 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 @@ } else return (EIO); /*XXX*/ -#else - return (EOPNOTSUPP); -#endif } /* @@ -1420,7 +1413,6 @@ static int sysctl_kern_arnd(SYSCTLFN_ARGS) { -#if NRND > 0 int error; void *v; struct sysctlnode node = *rnode; @@ -1431,15 +1423,12 @@ 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. Index: sys/kern/kern_exec.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exec.c,v retrieving revision 1.329 diff -u -b -r1.329 kern_exec.c --- sys/kern/kern_exec.c 16 Sep 2011 21:02:28 -0000 1.329 +++ sys/kern/kern_exec.c 21 Oct 2011 20:31:21 -0000 @@ -103,6 +103,7 @@ #include #endif /* NVERIEXEC > 0 */ #include +#include #include @@ -780,7 +781,7 @@ #ifdef PAX_ASLR if (pax_aslr_active(l)) - len += (arc4random() % PAGE_SIZE); + len += (cprng_fast32() % PAGE_SIZE); #endif /* PAX_ASLR */ #ifdef STACKALIGN /* arm, etc. */ Index: sys/kern/kern_pax.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_pax.c,v retrieving revision 1.25 diff -u -b -r1.25 kern_pax.c --- sys/kern/kern_pax.c 24 Apr 2011 18:46:22 -0000 1.25 +++ sys/kern/kern_pax.c 21 Oct 2011 20:31:21 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #ifdef PAX_ASLR #include @@ -310,7 +311,7 @@ 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 @@ 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 Index: sys/kern/kern_ssp.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_ssp.c,v retrieving revision 1.5 diff -u -b -r1.5 kern_ssp.c --- sys/kern/kern_ssp.c 1 Feb 2010 16:14:58 -0000 1.5 +++ sys/kern/kern_ssp.c 21 Oct 2011 20:31:21 -0000 @@ -32,6 +32,7 @@ #include #include #include +#include #if defined(__SSP__) || defined(__SSP_ALL__) long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -57,7 +58,7 @@ 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]; Index: sys/kern/kern_sysctl.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sysctl.c,v retrieving revision 1.232 diff -u -b -r1.232 kern_sysctl.c --- sys/kern/kern_sysctl.c 5 Oct 2011 13:24:09 -0000 1.232 +++ sys/kern/kern_sysctl.c 21 Oct 2011 20:31:22 -0000 @@ -84,6 +84,7 @@ #include #include #include +#include #define MAXDESCLEN 1024 MALLOC_DEFINE(M_SYSCTLNODE, "sysctlnode", "sysctl node structures"); @@ -158,6 +159,8 @@ #endif char defcorename[MAXPATHLEN] = DEFCORENAME; +cprng_strong_t *sysctl_prng; + /* * ******************************************************************** * Section 0: Some simple glue @@ -245,12 +248,15 @@ * 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_VM); sysctl_root.sysctl_flags |= CTLFLAG_PERMANENT; } Index: sys/kern/kern_uuid.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_uuid.c,v retrieving revision 1.17 diff -u -b -r1.17 kern_uuid.c --- sys/kern/kern_uuid.c 4 May 2010 19:23:56 -0000 1.17 +++ sys/kern/kern_uuid.c 21 Oct 2011 20:31:22 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -126,7 +127,7 @@ 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 @@ 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 Index: sys/kern/subr_cprng.c =================================================================== RCS file: sys/kern/subr_cprng.c diff -N sys/kern/subr_cprng.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/kern/subr_cprng.c 21 Oct 2011 20:31:22 -0000 @@ -0,0 +1,178 @@ +/* $NetBSD: $ */ + +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +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; + } + return (tv.tv_sec * 1000000 + tv.tv_usec); +} + +static void cprng_strong_reseed(void *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; + mutex_exit(&c->mtx); +} + +cprng_strong_t *cprng_strong_create(const char *const name, int ipl) +{ + cprng_strong_t *c; + uint8_t key[NIST_BLOCK_KEYLEN_BYTES]; + int r; + uint32_t cc; + + c = kmem_alloc(sizeof(*c), KM_NOSLEEP); + if (c == NULL) { + return NULL; + } + strlcpy(c->name, name, sizeof(c->name)); + 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); + mutex_enter(&c->mtx); + r = rnd_extract_data(key, sizeof(key), RND_EXTRACT_GOOD); + if (r != sizeof(key)) { + printf("cprng %s: WARNING insufficient " + "entropy at creation.\n", name); + rnd_extract_data(key + r, sizeof(key - r), RND_EXTRACT_ANY); + + /* Ask for more. */ + c->reseed.len = sizeof(key); + rndsink_attach(&c->reseed); + } + + if (nist_ctr_drbg_instantiate(&c->drbg, key, sizeof(key), + &cc, sizeof(cc), name, strlen(name))) { + panic("cprng %s: instantiation failed.", name); + } + mutex_exit(&c->mtx); + return c; +} + + +size_t cprng_strong(cprng_strong_t *c, void *p, size_t len) +{ + uint32_t cc = cprng_counter(); + + mutex_enter(&c->mtx); + + if (nist_ctr_drbg_generate(&c->drbg, p, len, &cc, sizeof(cc))) { + panic("cprng %s: nist_ctr_drbg_generate failed!", c->name); + } + + /* + * If the generator has just been keyed, perform + * the statistical RNG test. + */ + if (__predict_false(c->drbg.reseed_counter = 1)) { + rngtest_t rt; + + 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)) { + panic("cprng %s: failed statistical RNG test.", + c->name); + } + + memset(&rt, 0, sizeof(rt)); + } + + if (__predict_false(c->drbg.reseed_counter > + (NIST_CTR_DRBG_RESEED_INTERVAL / 2))) { + if (!(c->reseed_pending)) { + c->reseed.len = NIST_BLOCK_KEYLEN_BYTES; + rndsink_attach(&c->reseed); + } + } + + mutex_exit(&c->mtx); + return len; +} + +void cprng_strong_destroy(cprng_strong_t *c) +{ + mutex_enter(&c->mtx); + if (c->reseed_pending) { + rndsink_detach(&c->reseed); + } + mutex_exit(&c->mtx); + mutex_destroy(&c->mtx); + nist_ctr_drbg_destroy(&c->drbg); + memset(c, 0, sizeof(*c)); + kmem_free(c, sizeof(*c)); +} Index: sys/kern/subr_rngtest.c =================================================================== RCS file: sys/kern/subr_rngtest.c diff -N sys/kern/subr_rngtest.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/kern/subr_rngtest.c 21 Oct 2011 20:31:22 -0000 @@ -0,0 +1,269 @@ +/* $NetBSD: $ */ + +/*- + * 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 +#include +#include + +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; +} Index: sys/lib/libkern/arc4random.c =================================================================== RCS file: /cvsroot/src/sys/lib/libkern/arc4random.c,v retrieving revision 1.21 diff -u -b -r1.21 arc4random.c --- sys/lib/libkern/arc4random.c 18 Jan 2010 20:54:54 -0000 1.21 +++ sys/lib/libkern/arc4random.c 21 Oct 2011 20:31:22 -0000 @@ -1,7 +1,7 @@ /* $NetBSD: arc4random.c,v 1.21 2010/01/18 20:54:54 joerg 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,42 @@ #endif #include +#ifdef _KERNEL +#include +#include +#else +#define mutex_spin_enter(x) ; +#define mutex_spin_exit(x) ; +#define mutex_init(x, y, z) ; +#endif + #include #if NRND > 0 #include + +rndsink_t rs; + #endif -#define ARC4_MAXRUNS 16384 +/* + * 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 rekey at 2^24 bytes. + */ +#define ARC4_MAXBYTES (16 * 1024 * 1024) #define ARC4_RESEED_SECONDS 300 -#define ARC4_KEYBYTES 32 /* 256 bit key */ +#define ARC4_KEYBYTES 16 /* 128 bit key */ #ifdef _STANDALONE #define time_uptime 1 /* XXX ugly! */ @@ -73,11 +100,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,55 +126,70 @@ * 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; - + 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 (!arc4_initialized) { + KASSERT(arg == NULL); + /* + * The first time through, we must take what we can get, + * so schedule ourselves for callback no matter what. + */ + r = rnd_extract_data(key, ARC4_KEYBYTES, RND_EXTRACT_ANY); + ask_for_more = 1; + goto got_entropy; + } + KASSERT(arg == NULL || (arg == &rs && callback_pending == 1)); + if (arg == NULL) { + 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); + ask_for_more = 1; + } } 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; + callback_pending = 0; + ask_for_more = 0; + if (rs.len != ARC4_KEYBYTES) { + panic("arc4_randrekey: rekey callback bad length"); } + memcpy(key, rs.data, rs.len); } - cur_keybytes = r; - +got_entropy: + if (ask_for_more) { + KASSERT(!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 + /* + * If it's the first time, or we got a good key, actually rekey. + */ + if (!ask_for_more || !arc4_initialized) { 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]); } arc4_i = arc4_j; - /* Reset for next reseed cycle. */ - arc4_nextreseed = time_uptime + ARC4_RESEED_SECONDS; - arc4_numruns = 0; - /* * Throw away the first N words of output, as suggested in the * paper "Weaknesses in the Key Scheduling Algorithm of RC4" @@ -149,6 +197,26 @@ */ 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 + /* + * 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 + } + mutex_spin_exit(&arc4_mtx); } /* @@ -159,11 +227,12 @@ { 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 +256,40 @@ 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; +} + +static inline void +arc4randbytes_unlocked(void *p, size_t len) +{ + u_int8_t *buf = (u_int8_t *)p; + size_t i; - for (i = 0, ret = 0; i <= 24; ret |= arc4_randbyte() << i, i += 8) + 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); } } Index: sys/net/if_bridge.c =================================================================== RCS file: /cvsroot/src/sys/net/if_bridge.c,v retrieving revision 1.73 diff -u -b -r1.73 if_bridge.c --- sys/net/if_bridge.c 23 May 2011 21:52:54 -0000 1.73 +++ sys/net/if_bridge.c 21 Oct 2011 20:31:22 -0000 @@ -100,6 +100,7 @@ #include #include #include +#include #include #include @@ -1848,7 +1849,7 @@ 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); Index: sys/net/if_spppsubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_spppsubr.c,v retrieving revision 1.122 diff -u -b -r1.122 if_spppsubr.c --- sys/net/if_spppsubr.c 5 Sep 2011 12:19:09 -0000 1.122 +++ sys/net/if_spppsubr.c 21 Oct 2011 20:31:23 -0000 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -1203,7 +1204,7 @@ ++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; @@ -2482,7 +2483,7 @@ 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) @@ -2666,7 +2667,7 @@ 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; @@ -4230,7 +4231,7 @@ * 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); } @@ -4287,7 +4288,7 @@ 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 */ @@ -4298,11 +4299,7 @@ /* 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]; Index: sys/net/npf/npf_nat.c =================================================================== RCS file: /cvsroot/src/sys/net/npf/npf_nat.c,v retrieving revision 1.6 diff -u -b -r1.6 npf_nat.c --- sys/net/npf/npf_nat.c 2 Feb 2011 02:20:25 -0000 1.6 +++ sys/net/npf/npf_nat.c 21 Oct 2011 20:31:23 -0000 @@ -87,6 +87,8 @@ #include #include #include +#include + #include #include @@ -319,7 +321,7 @@ 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]; Index: sys/net80211/ieee80211_netbsd.c =================================================================== RCS file: /cvsroot/src/sys/net80211/ieee80211_netbsd.c,v retrieving revision 1.19 diff -u -b -r1.19 ieee80211_netbsd.c --- sys/net80211/ieee80211_netbsd.c 7 Oct 2011 16:51:45 -0000 1.19 +++ sys/net80211/ieee80211_netbsd.c 21 Oct 2011 20:31:23 -0000 @@ -46,6 +46,8 @@ #include +#include + #include #include #include @@ -640,14 +642,7 @@ 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 Index: sys/netinet/in.c =================================================================== RCS file: /cvsroot/src/sys/netinet/in.c,v retrieving revision 1.139 diff -u -b -r1.139 in.c --- sys/netinet/in.c 19 Oct 2011 01:52:22 -0000 1.139 +++ sys/netinet/in.c 21 Oct 2011 20:31:23 -0000 @@ -110,6 +110,8 @@ #include #include +#include + #include #include @@ -403,7 +405,7 @@ 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; } Index: sys/netinet/ip_carp.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_carp.c,v retrieving revision 1.46 diff -u -b -r1.46 ip_carp.c --- sys/netinet/ip_carp.c 19 Oct 2011 01:52:22 -0000 1.46 +++ sys/netinet/ip_carp.c 21 Oct 2011 20:31:23 -0000 @@ -55,6 +55,7 @@ #include #include #include +#include #include @@ -877,9 +878,7 @@ { 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++; Index: sys/netinet/ip_id.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_id.c,v retrieving revision 1.14 diff -u -b -r1.14 ip_id.c --- sys/netinet/ip_id.c 5 Nov 2010 01:35:57 -0000 1.14 +++ sys/netinet/ip_id.c 21 Oct 2011 20:31:24 -0000 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -54,7 +55,7 @@ static inline uint32_t ipid_random(void) { - return arc4random(); + return cprng_fast32(); } /* Index: sys/netinet/rfc6056.c =================================================================== RCS file: /cvsroot/src/sys/netinet/rfc6056.c,v retrieving revision 1.3 diff -u -b -r1.3 rfc6056.c --- sys/netinet/rfc6056.c 25 Sep 2011 11:54:28 -0000 1.3 +++ sys/netinet/rfc6056.c 21 Oct 2011 20:31:24 -0000 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -427,7 +428,7 @@ 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 @@ 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 @@ return 0; } *next_ephemeral = mymin + - (arc4random() % num_ephemeral); + (cprng_fast32() % num_ephemeral); count--; @@ -516,10 +517,7 @@ 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 @@ 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 @@ count = num_ephemeral; do { *next_ephemeral = *next_ephemeral + - (arc4random() % N) + 1; + (cprng_fast32() % N) + 1; myport = mymin + (*next_ephemeral % num_ephemeral); Index: sys/netinet/tcp_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_input.c,v retrieving revision 1.316 diff -u -b -r1.316 tcp_input.c --- sys/netinet/tcp_input.c 31 Aug 2011 18:31:03 -0000 1.316 +++ sys/netinet/tcp_input.c 21 Oct 2011 20:31:24 -0000 @@ -171,6 +171,7 @@ #include #endif #include /* for lwp0 */ +#include #include #include @@ -3711,8 +3712,8 @@ * 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); Index: sys/netinet/tcp_subr.c =================================================================== RCS file: /cvsroot/src/sys/netinet/tcp_subr.c,v retrieving revision 1.241 diff -u -b -r1.241 tcp_subr.c --- sys/netinet/tcp_subr.c 3 May 2011 18:28:45 -0000 1.241 +++ sys/netinet/tcp_subr.c 21 Oct 2011 20:31:25 -0000 @@ -98,7 +98,6 @@ #include "opt_tcp_compat_42.h" #include "opt_inet_csum.h" #include "opt_mbuftrace.h" -#include "rnd.h" #include #include @@ -111,10 +110,8 @@ #include #include #include -#if NRND > 0 #include -#include -#endif +#include #include #include @@ -174,9 +171,7 @@ 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 */ @@ -2178,9 +2173,7 @@ } 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 @@ -2218,7 +2211,6 @@ { tcp_seq tcp_iss; -#if NRND > 0 static bool tcp_iss_gotten_secret; /* @@ -2226,8 +2218,8 @@ * 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; } @@ -2268,17 +2260,11 @@ #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, Index: sys/netinet6/files.ipsec =================================================================== RCS file: /cvsroot/src/sys/netinet6/files.ipsec,v retrieving revision 1.5 diff -u -b -r1.5 files.ipsec --- sys/netinet6/files.ipsec 27 Oct 2006 21:20:48 -0000 1.5 +++ sys/netinet6/files.ipsec 21 Oct 2011 20:31:25 -0000 @@ -1,7 +1,7 @@ # $NetBSD: files.ipsec,v 1.5 2006/10/27 21:20:48 christos 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 Index: sys/netinet6/in6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6.c,v retrieving revision 1.158 diff -u -b -r1.158 in6.c --- sys/netinet6/in6.c 19 Oct 2011 01:53:07 -0000 1.158 +++ sys/netinet6/in6.c 21 Oct 2011 20:31:25 -0000 @@ -81,6 +81,7 @@ #include #include #include +#include #include #include @@ -1119,7 +1120,7 @@ * 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 @@ * 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 @@ dad_delay = 0; else { dad_delay = - (arc4random() % (maxdelay - mindelay)) + + (cprng_fast32() % (maxdelay - mindelay)) + mindelay; } } @@ -2157,7 +2158,8 @@ * 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)); } } Index: sys/netinet6/in6_ifattach.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6_ifattach.c,v retrieving revision 1.85 diff -u -b -r1.85 in6_ifattach.c --- sys/netinet6/in6_ifattach.c 19 Sep 2009 13:11:02 -0000 1.85 +++ sys/netinet6/in6_ifattach.c 21 Oct 2011 20:31:25 -0000 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -194,7 +195,7 @@ int i; for (i = 0; i < 2; i++) { - val32 = arc4random(); + val32 = cprng_fast32(); memcpy(seed + sizeof(val32) * i, &val32, sizeof(val32)); } } else Index: sys/netinet6/ip6_id.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ip6_id.c,v retrieving revision 1.16 diff -u -b -r1.16 ip6_id.c --- sys/netinet6/ip6_id.c 30 Aug 2006 17:11:53 -0000 1.16 +++ sys/netinet6/ip6_id.c 21 Oct 2011 20:31:25 -0000 @@ -85,6 +85,8 @@ __KERNEL_RCSID(0, "$NetBSD: ip6_id.c,v 1.16 2006/08/30 17:11:53 christos Exp $"); #include +#include + #include #include @@ -175,20 +177,20 @@ 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 @@ 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); Index: sys/netinet6/ip6_input.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ip6_input.c,v retrieving revision 1.132 diff -u -b -r1.132 ip6_input.c --- sys/netinet6/ip6_input.c 1 Jun 2011 22:59:44 -0000 1.132 +++ sys/netinet6/ip6_input.c 21 Oct 2011 20:31:25 -0000 @@ -85,6 +85,7 @@ #include #include #include +#include #include #include @@ -190,7 +191,7 @@ 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 Index: sys/netinet6/mld6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/mld6.c,v retrieving revision 1.54 diff -u -b -r1.54 mld6.c --- sys/netinet6/mld6.c 19 Oct 2011 01:53:07 -0000 1.54 +++ sys/netinet6/mld6.c 21 Oct 2011 20:31:26 -0000 @@ -116,6 +116,7 @@ #include #include #include +#include #include @@ -289,7 +290,7 @@ 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 @@ } 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); } } Index: sys/netinet6/mld6_var.h =================================================================== RCS file: /cvsroot/src/sys/netinet6/mld6_var.h,v retrieving revision 1.9 diff -u -b -r1.9 mld6_var.h --- sys/netinet6/mld6_var.h 1 Nov 2007 20:33:58 -0000 1.9 +++ sys/netinet6/mld6_var.h 21 Oct 2011 20:31:26 -0000 @@ -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 Index: sys/netinet6/nd6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/nd6.c,v retrieving revision 1.136 diff -u -b -r1.136 nd6.c --- sys/netinet6/nd6.c 15 Jul 2010 19:15:30 -0000 1.136 +++ sys/netinet6/nd6.c 21 Oct 2011 20:31:26 -0000 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include Index: sys/netinet6/nd6.h =================================================================== RCS file: /cvsroot/src/sys/netinet6/nd6.h,v retrieving revision 1.54 diff -u -b -r1.54 nd6.h --- sys/netinet6/nd6.h 24 May 2011 18:07:11 -0000 1.54 +++ sys/netinet6/nd6.h 21 Oct 2011 20:31:26 -0000 @@ -260,7 +260,7 @@ #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); Index: sys/netinet6/nd6_rtr.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/nd6_rtr.c,v retrieving revision 1.81 diff -u -b -r1.81 nd6_rtr.c --- sys/netinet6/nd6_rtr.c 24 May 2011 18:07:11 -0000 1.81 +++ sys/netinet6/nd6_rtr.c 21 Oct 2011 20:31:27 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include Index: sys/netkey/key.c =================================================================== RCS file: /cvsroot/src/sys/netkey/key.c,v retrieving revision 1.179 diff -u -b -r1.179 key.c --- sys/netkey/key.c 17 Jul 2011 20:54:54 -0000 1.179 +++ sys/netkey/key.c 21 Oct 2011 20:31:27 -0000 @@ -96,10 +96,7 @@ #include -#include "rnd.h" -#if NRND > 0 -#include -#endif +#include #include @@ -4975,20 +4972,7 @@ 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); } /* Index: sys/nfs/nfs_subs.c =================================================================== RCS file: /cvsroot/src/sys/nfs/nfs_subs.c,v retrieving revision 1.221 diff -u -b -r1.221 nfs_subs.c --- sys/nfs/nfs_subs.c 12 Jun 2011 03:35:59 -0000 1.221 +++ sys/nfs/nfs_subs.c 21 Oct 2011 20:31:28 -0000 @@ -98,6 +98,7 @@ #include #include #include +#include #include @@ -1488,7 +1489,7 @@ nfs_ticks = (hz * NFS_TICKINTVL + 500) / 1000; if (nfs_ticks < 1) nfs_ticks = 1; - nfs_xid = arc4random(); + nfs_xid = cprng_fast32(); nfsdreq_init(); /* Index: sys/opencrypto/files.opencrypto =================================================================== RCS file: /cvsroot/src/sys/opencrypto/files.opencrypto,v retrieving revision 1.24 diff -u -b -r1.24 files.opencrypto --- sys/opencrypto/files.opencrypto 26 May 2011 21:50:03 -0000 1.24 +++ sys/opencrypto/files.opencrypto 21 Oct 2011 20:31:28 -0000 @@ -15,7 +15,7 @@ # 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 Index: sys/rump/dev/lib/librnd/Makefile =================================================================== RCS file: /cvsroot/src/sys/rump/dev/lib/librnd/Makefile,v retrieving revision 1.2 diff -u -b -r1.2 Makefile --- sys/rump/dev/lib/librnd/Makefile 16 Feb 2010 20:42:45 -0000 1.2 +++ sys/rump/dev/lib/librnd/Makefile 21 Oct 2011 20:31:28 -0000 @@ -5,7 +5,7 @@ LIB= rumpdev_rnd -SRCS= rnd.c rndpool.c +#SRCS= rnd.c rndpool.c SRCS+= component.c Index: sys/rump/librump/rumpkern/Makefile.rumpkern =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpkern/Makefile.rumpkern,v retrieving revision 1.110 diff -u -b -r1.110 Makefile.rumpkern --- sys/rump/librump/rumpkern/Makefile.rumpkern 12 Jun 2011 06:36:38 -0000 1.110 +++ sys/rump/librump/rumpkern/Makefile.rumpkern 21 Oct 2011 20:31:28 -0000 @@ -20,7 +20,7 @@ # 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. @@ -94,6 +94,7 @@ subr_lwp_specificdata.c \ subr_once.c \ subr_prf.c \ + subr_rngtest.c \ subr_specificdata.c \ subr_time.c \ subr_workqueue.c \ Index: sys/rump/librump/rumpkern/cprng_stub.c =================================================================== RCS file: sys/rump/librump/rumpkern/cprng_stub.c diff -N sys/rump/librump/rumpkern/cprng_stub.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/rump/librump/rumpkern/cprng_stub.c 21 Oct 2011 20:31:28 -0000 @@ -0,0 +1,89 @@ +/* $NetBSD: $ */ + +/*- + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +/* + * 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) +{ + 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); + 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); + memset(c, 0, sizeof(*c)); + kmem_free(c, sizeof(*c)); +} Index: sys/rump/librump/rumpkern/rump.c =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpkern/rump.c,v retrieving revision 1.234 diff -u -b -r1.234 rump.c --- sys/rump/librump/rumpkern/rump.c 22 Mar 2011 15:16:23 -0000 1.234 +++ sys/rump/librump/rumpkern/rump.c 21 Oct 2011 20:31:28 -0000 @@ -69,6 +69,7 @@ #include #include #include +#include #include @@ -288,7 +289,7 @@ * implementation. */ messthestack(); - arc4random(); + cprng_fast32(); if (rump_version != RUMP_VERSION) { printf("rump version mismatch, %d vs. %d\n", Index: sys/rump/librump/rumpvfs/rumpblk.c =================================================================== RCS file: /cvsroot/src/sys/rump/librump/rumpvfs/rumpblk.c,v retrieving revision 1.46 diff -u -b -r1.46 rumpblk.c --- sys/rump/librump/rumpvfs/rumpblk.c 3 Feb 2011 22:16:11 -0000 1.46 +++ sys/rump/librump/rumpvfs/rumpblk.c 21 Oct 2011 20:31:28 -0000 @@ -65,6 +65,7 @@ #include #include #include +#include #include @@ -326,7 +327,7 @@ &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); Index: sys/rump/net/lib/libshmif/if_shmem.c =================================================================== RCS file: /cvsroot/src/sys/rump/net/lib/libshmif/if_shmem.c,v retrieving revision 1.43 diff -u -b -r1.43 if_shmem.c --- sys/rump/net/lib/libshmif/if_shmem.c 2 Sep 2011 22:25:08 -0000 1.43 +++ sys/rump/net/lib/libshmif/if_shmem.c 21 Oct 2011 20:31:28 -0000 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -152,7 +153,7 @@ uint32_t randnum; int error; - randnum = arc4random(); + randnum = cprng_fast32(); memcpy(&enaddr[2], &randnum, sizeof(randnum)); sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); Index: sys/rump/net/lib/libvirtif/if_virt.c =================================================================== RCS file: /cvsroot/src/sys/rump/net/lib/libvirtif/if_virt.c,v retrieving revision 1.24 diff -u -b -r1.24 if_virt.c --- sys/rump/net/lib/libvirtif/if_virt.c 7 Aug 2011 14:03:16 -0000 1.24 +++ sys/rump/net/lib/libvirtif/if_virt.c 21 Oct 2011 20:31:28 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -102,7 +103,7 @@ 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 @@ 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); Index: sys/sys/cprng.h =================================================================== RCS file: sys/sys/cprng.h diff -N sys/sys/cprng.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/cprng.h 21 Oct 2011 20:31:28 -0000 @@ -0,0 +1,94 @@ +/* $NetBSD: $ */ + +/*- + * 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 +#include +#include +#include + +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; + NIST_CTR_DRBG drbg; + char name[16]; + int reseed_pending; + rndsink_t reseed; +} cprng_strong_t; + +cprng_strong_t *cprng_strong_create(const char *const, int); + +size_t cprng_strong(cprng_strong_t *, void *, 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); + +#endif Index: sys/sys/queue.h =================================================================== RCS file: /cvsroot/src/sys/sys/queue.h,v retrieving revision 1.52 diff -u -b -r1.52 queue.h --- sys/sys/queue.h 20 Apr 2009 09:56:08 -0000 1.52 +++ sys/sys/queue.h 21 Oct 2011 20:31:28 -0000 @@ -166,6 +166,10 @@ (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. */ Index: sys/sys/rnd.h =================================================================== RCS file: /cvsroot/src/sys/sys/rnd.h,v retrieving revision 1.21 diff -u -b -r1.21 rnd.h --- sys/sys/rnd.h 28 Apr 2008 20:24:11 -0000 1.21 +++ sys/sys/rnd.h 21 Oct 2011 20:31:28 -0000 @@ -43,6 +43,10 @@ #include #endif +#ifdef _KERNEL +#include +#endif + #define RND_DEV_RANDOM 0 /* minor devices for random and kinda random */ #define RND_DEV_URANDOM 1 @@ -82,26 +86,14 @@ 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 @@ #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 @@ (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); @@ -148,13 +164,16 @@ 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 *, void *, 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 */ Index: sys/sys/rngtest.h =================================================================== RCS file: sys/sys/rngtest.h diff -N sys/sys/rngtest.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/rngtest.h 21 Oct 2011 20:31:28 -0000 @@ -0,0 +1,49 @@ +/* $NetBSD: $ */ + +/*- + * 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 + +#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 Index: sys/sys/sysctl.h =================================================================== RCS file: /cvsroot/src/sys/sys/sysctl.h,v retrieving revision 1.196 diff -u -b -r1.196 sysctl.h --- sys/sys/sysctl.h 12 Oct 2011 23:04:22 -0000 1.196 +++ sys/sys/sysctl.h 21 Oct 2011 20:31:29 -0000 @@ -56,6 +56,10 @@ #include #endif +#ifdef _KERNEL +#include +#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 @@ extern const u_int sysctl_lwpflagmap[]; +extern cprng_strong_t *sysctl_prng; + #else /* !_KERNEL */ #include Index: sys/ufs/ffs/ffs_appleufs.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_appleufs.c,v retrieving revision 1.11 diff -u -b -r1.11 ffs_appleufs.c --- sys/ufs/ffs/ffs_appleufs.c 22 Jun 2011 04:01:33 -0000 1.11 +++ sys/ufs/ffs/ffs_appleufs.c 21 Oct 2011 20:31:30 -0000 @@ -33,6 +33,7 @@ #if defined(_KERNEL) #include #include +#include #endif #include @@ -136,9 +137,7 @@ } if (uuid == 0) { #if defined(_KERNEL) && !defined(STANDALONE) - uuid = arc4random(); - uuid <<= 32; - uuid |= arc4random(); + uuid = cprng_fast64(); #endif } namelen = strlen(name);