Sat Dec 17 20:05:40 2011 UTC ()
Separate /dev/random pseudodevice implemenation from kernel entropy pool
implementation.  Rewrite pseudodevice code to use cprng_strong(9).

The new pseudodevice is cloning, so each caller gets bits from a stream
generated with its own key.  Users of /dev/urandom get their generators
keyed on a "best effort" basis -- the kernel will rekey generators
whenever the entropy pool hits the high water mark -- while users of
/dev/random get their generators rekeyed every time key-length bits
are output.

The underlying cprng_strong API can use AES-256 or AES-128, but we use
AES-128 because of concerns about related-key attacks on AES-256.  This
improves performance (and reduces entropy pool depletion) significantly
for users of /dev/urandom but does cause users of /dev/random to rekey
twice as often.

Also fixes various bugs (including some missing locking and a reseed-counter
overflow in the CTR_DRBG code) found while testing this.

For long reads, this generator is approximately 20 times as fast as the
old generator (dd with bs=64K yields 53MB/sec on 2Ghz Core2 instead of
2.5MB/sec) and also uses a separate mutex per instance so concurrency
is greatly improved.  For reads of typical key sizes for modern
cryptosystems (16-32 bytes) performance is about the same as the old
code: a little better for 32 bytes, a little worse for 16 bytes.


(tls)
diff -r1.16 -r1.17 src/share/man/man4/rnd.4
diff -r1.3 -r1.4 src/share/man/man9/cprng.9
diff -r1.18 -r1.19 src/share/man/man9/rnd.9
diff -r1.1032 -r1.1033 src/sys/conf/files
diff -r1.1 -r1.2 src/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes128.h
diff -r1.1 -r1.2 src/sys/crypto/nist_ctr_drbg/nist_ctr_drbg_aes256.h
diff -r1.88 -r1.89 src/sys/dev/rnd.c
diff -r1.21 -r1.22 src/sys/dev/rndpool.c
diff -r0 -r1.1 src/sys/dev/rndpseudo.c
diff -r1.2 -r1.3 src/sys/dev/iscsi/iscsi_text.c
diff -r1.3 -r1.4 src/sys/dist/pf/netinet/tcp_rndiss.c
diff -r1.185 -r1.186 src/sys/kern/init_sysctl.c
diff -r1.4 -r1.5 src/sys/kern/subr_cprng.c
diff -r1.124 -r1.125 src/sys/net/if_spppsubr.c
diff -r1.243 -r1.244 src/sys/netinet/tcp_subr.c
diff -r1.2 -r1.3 src/sys/rump/dev/lib/librnd/Makefile
diff -r1.3 -r1.4 src/sys/rump/librump/rumpkern/cprng_stub.c
diff -r1.3 -r1.4 src/sys/sys/cprng.h
diff -r1.397 -r1.398 src/sys/sys/param.h
diff -r1.27 -r1.28 src/sys/sys/rnd.h

cvs diff -r1.16 -r1.17 src/share/man/man4/rnd.4 (expand / switch to unified diff)

--- src/share/man/man4/rnd.4 2010/03/22 18:58:31 1.16
+++ src/share/man/man4/rnd.4 2011/12/17 20:05:38 1.17
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: rnd.4,v 1.16 2010/03/22 18:58:31 joerg Exp $ 1.\" $NetBSD: rnd.4,v 1.17 2011/12/17 20:05:38 tls Exp $
2.\" 2.\"
3.\" Copyright (c) 1997 Michael Graff 3.\" Copyright (c) 1997 Michael Graff
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" Redistribution and use in source and binary forms, with or without 6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions 7.\" modification, are permitted provided that the following conditions
8.\" are met: 8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright 9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer. 10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the 12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution. 13.\" documentation and/or other materials provided with the distribution.
14.\" 3. The name of the author may not be used to endorse or promote products 14.\" 3. The name of the author may not be used to endorse or promote products
@@ -27,113 +27,153 @@ @@ -27,113 +27,153 @@
27.\" SUCH DAMAGE. 27.\" SUCH DAMAGE.
28.\" 28.\"
29.Dd February 22, 2009 29.Dd February 22, 2009
30.Dt RND 4 30.Dt RND 4
31.Os 31.Os
32.Sh NAME 32.Sh NAME
33.Nm rnd 33.Nm rnd
34.Nd in kernel entropy collection and random number generation 34.Nd in kernel entropy collection and random number generation
35.Sh SYNOPSIS 35.Sh SYNOPSIS
36.Cd pseudo-device rnd 36.Cd pseudo-device rnd
37.Sh DESCRIPTION 37.Sh DESCRIPTION
38The 38The
39.Nm 39.Nm
40pseudo-device uses event timing information collected from many 40pseudo-device has three purposes. On read, it returns cryptographically
41devices, and mixes this into an entropy pool. 41strong random data from a generator keyed from the kernel entropy pool.
42This pool is stirred with a cryptographically strong hash function 42On write, data may be added to the entropy pool. By ioctl, the behavior
43when data is extracted from the pool. 43of the entropy pool (which sources are used; how their entropy is
44.Sh INTERNAL ENTROPY POOL MANAGEMENT 44estimated, etc.) may be controlled.
45When a hardware event occurs (such as completion of a hard drive 45.Pp
46transfer or an interrupt from a network device) a timestamp is 46The kernel uses event timing information collected from many
47generated. 47devices, and mixes this into an entropy pool. This pool is used to
48This timestamp is compared to the previous timestamp 48key a stream generator (the CTR_DRBG generator specified by NIST
49recorded for the device, and the first, second, and third order 49SP 800-90) which is used to generate values returned to userspace when
50differentials are calculated. 50the pseudo-device is read.
51.Pp 51.Pp
52If any of these differentials is zero, no entropy is assumed to 52The pseudodevice is cloning, which means that each time it is opened,
53have been gathered. 53a new instance of the stream generator is created. Interposing a stream
54If all are non-zero, one bit is assumed. 54generator between the entropy pool and readers in this manner protects
55Next, data is mixed into the entropy pool using an LFSR (linear 55readers from each other (each reader's random stream is generated from a
56feedback shift register). 56unique key) and protects all users of the entropy pool from any attack
57.Pp 57which might correlate its successive outputs to each other, such as
58To extract data from the entropy pool, a cryptographically strong hash 58iterative guessing attacks.
59function is used. 59.Pp
60The output of this hash is mixed back into the pool using the LFSR, 
61and then folded in half before being returned to the caller. 
62.Pp 
63Mixing the actual hash into the pool causes the next extraction to 
64return a different value, even if no timing events were added to the 
65pool. 
66Folding the data in half prevents the caller to derive the 
67actual hash of the pool, preventing some attacks. 
68.Sh USER ACCESS 60.Sh USER ACCESS
69User code can obtain random values from the kernel in two ways. 61User code can obtain random values from the kernel in two ways.
70.Pp 62.Pp
71Reading from 63Reading from
72.Pa /dev/random 64.Pa /dev/random
73will only return values while sufficient entropy exists in the 65provides information-theoretic properties desirable for some callers:
74internal pool. 66it will guarantee that the stream generator never outputs more bits
75When sufficient entropy does not exist, 67than the length of its key, which may in some sense mean that all the
 68entropy provided to it by the entropy pool is "preserved" in its output.
 69.Pp
 70Reading from
 71.Pa /dev/random
 72may return
76.Er EAGAIN 73.Er EAGAIN
77is returned for non-blocking reads, or the read will block for 74(for non-blocking reads), block, or return less data than requested, if
78blocking reads. 75the pool does not have sufficient entropy
 76to provide a new key for the stream generator when sufficient bits have
 77been read to require rekeying.
79.Pp 78.Pp
80Reading from 79Reading from
81.Pa /dev/urandom 80.Pa /dev/urandom
82will return as many values as requested, even when the entropy pool is 81will return as many values as requested. The stream generator may be
83empty. 82initially keyed from the entropy pool even if the pool's estimate of
84This data is not as good as reading from 83its own entropy is less than the number of bits in the stream generator's
 84key. If this occurs, the generator will be rekeyed with fresh entropy
 85from the pool as soon as sufficient entropy becomes available. The
 86generator will also be rekeyed whenever the pool's entropy estimate
 87exceeds the size of the pool's internal state (when the pool "is full").
 88.Pp
 89In some sense, this data is not as good as reading from
 90.Pa /dev/random ,
 91for at least two reasons. First, the generator may initially be keyed
 92from a pool that has never had as many bits of entropy mixed into it as
 93there are bits in the generator's key. Second, the generator may produce
 94many more bits of output than are contained in its own key, though it
 95will never produce more output on one key than is allowed by the
 96CTR_DRBG specification.
 97.Pp
 98However, reading large amounts of data from a single opened instance of
 99.Pa /dev/urandom
 100will
 101.Em
 102not
 103deplete the kernel entropy pool, as it would with some other
 104implementations. This preserves entropy for other callers and will
 105produce a more fair distribution of the available entropy over many
 106potential readers on the same system.
 107.Pp
 108Users of these interfaces must carefully consider their application's
 109actual security requirements and the characteristics of the system
 110on which they are reading from the pseudodevice. For many applications,
 111the depletion of the entropy pool caused by the
85.Pa /dev/random 112.Pa /dev/random
86since when the pool is empty, data is still returned, degenerating to a 113pseudodevice's continual rekeying of the stream generator will cause
87pseudo-random generator. 114application behavior (or, perhaps more precisely, nonbehavior) which
 115is less secure than relying on the
 116.Pa /dev/urandom
 117interface, which is guaranteed to rekey the stream generator as often
 118as it can.
88.Pp 119.Pp
89Writing to either device will mix the data written into the pool using 120Excessive use of
90the LFSR as above, without modifying the entropy estimation for the 121.Pa /dev/random
91pool. 122can deplete the entropy pool (or, at least, its estimate of how many
92.Sh RANDOM SOURCE STRUCTURE 123bits of entropy it "contains") and reduce security for other consumers
93Each source has a state structure which the kernel uses to hold the 124of randomness both in userspace
94timing information and other state for that source. 125.Em and within the kernel.
 126Some system administrators may wish therefore to remove the /dev/random
 127device node and replace it with a second copy of the node for the
 128nonblocking /dev/urandom device.
 129.Pp
 130In any event, as the Linux manual page notes, one should
 131be very suspicious of any application which attempts to read more than
 13232 bytes (256 bits) from the blocking
 133.Pa /dev/random
 134pseudodevice, since no practical cryptographic algorithm in current
 135use is believed to have a security strength greater than 256 bits.
 136.Pp
 137Writing to either device node will mix the data written into the
 138entropy pool, but will have no effect on the pool's entropy estimate.
 139The
 140.Xr ioctl 2
 141interface to the device may be used -- once only, and only when the
 142system is in insecure mode at security level 0 or lower -- to add
 143data with an explicit entropy estimate.
 144.Sh IOCTL INTERFACE
 145Various
 146.Xr ioctl 2
 147functions are available to control device behavior, gather statistics,
 148and add data to the entropy pool.
 149These are all defined in the
 150.In sys/rnd.h
 151file, along with the data types and constants. The structures and
 152ioctl functions are also listed below.
 153.Sh DATA TYPES
 154Each source has a state structure which summarizes the kernel's state
 155for that entropy source.
95.Bd -literal -offset indent 156.Bd -literal -offset indent
96typedef struct { 157typedef struct {
97 char name[16]; 158 char name[16];
98 uint32_t last_time; 159 uint32_t total;
99 uint32_t last_delta; 160 uint32_t type;
100 uint32_t last_delta2; 
101 uint32_t total; 
102 uint32_t type; 
103 uint32_t flags; 161 uint32_t flags;
104} rndsource_t; 162} rndsource_t;
105.Ed 163.Ed
106.Pp 
107This structure holds the internal representation of a device's timing 
108state. 
109The 164The
110.Va name 165.Va name
111field holes the device name, as known to the kernel. 166field holds the device name, as known to the kernel.
112The 
113.Va last_time 
114entry is the timestamp of the last time this device generated an 
115event. 
116It is for internal use only, and not in any specific representation. 
117The 
118.Va last_delta 
119and 
120.Va last_delta2 
121fields hold the last first- and second-order deltas. 
122The 
123.Va total 
124field holds a count of how many bits this device has potentially 
125generated. 
126This is not the same as how many bits were used from it. 
127The 167The
128.Va type 168.Va type
129field holds the device type. 169field holds the device type.
130.Pp 170.Pp
131Currently, these types are defined: 171Currently, these types are defined:
132.Bl -tag -width RND_TYPE_DISK 172.Bl -tag -width RND_TYPE_DISK
133.It Dv RND_TYPE_DISK 173.It Dv RND_TYPE_DISK
134The device is a physical hard drive. 174The device is a physical hard drive.
135.It Dv RND_TYPE_NET 175.It Dv RND_TYPE_NET
136The device is a network interface. 176The device is a network interface.
137By default, timing information is 177By default, timing information is
138collected from this source type, but entropy is not estimated. 178collected from this source type, but entropy is not estimated.
139.It Dv RND_TYPE_TAPE 179.It Dv RND_TYPE_TAPE
@@ -142,34 +182,26 @@ The device is a tape device. @@ -142,34 +182,26 @@ The device is a tape device.
142The device is a terminal, mouse, or other user input device. 182The device is a terminal, mouse, or other user input device.
143.It Dv RND_TYPE_RNG 183.It Dv RND_TYPE_RNG
144The device is a random number generator. 184The device is a random number generator.
145.El 185.El
146.Pp 186.Pp
147.Va flags 187.Va flags
148is a bitfield. 188is a bitfield.
149.Bl -tag -width RND_FLAG_NO_ESTIMATE 189.Bl -tag -width RND_FLAG_NO_ESTIMATE
150.It Dv RND_FLAG_NO_ESTIMATE 190.It Dv RND_FLAG_NO_ESTIMATE
151Do not assume any entropy is in the timing information. 191Do not assume any entropy is in the timing information.
152.It Dv RND_FLAG_NO_COLLECT 192.It Dv RND_FLAG_NO_COLLECT
153Do not even add timing information to the pool. 193Do not even add timing information to the pool.
154.El 194.El
155.Sh IOCTL 
156Various 
157.Xr ioctl 2 
158functions are available to control device behavior, gather statistics, 
159and add data to the entropy pool. 
160These are all defined in the 
161.In sys/rnd.h 
162file, along with the data types and constants. 
163.Pp 195.Pp
164.Bl -tag -width RNDADDTOENTCNT 196.Bl -tag -width RNDADDTOENTCNT
165.It Dv RNDGETENTCNT 197.It Dv RNDGETENTCNT
166.Pq Li "uint32_t" 198.Pq Li "uint32_t"
167Return the current entropy count (in bits). 199Return the current entropy count (in bits).
168.It Dv RNDGETPOOLSTAT 200.It Dv RNDGETPOOLSTAT
169.Pq Li "rndpoolstat_t" 201.Pq Li "rndpoolstat_t"
170.Bd -literal -offset indent 202.Bd -literal -offset indent
171typedef struct 203typedef struct
172{ 204{
173 uint32_t poolsize; 205 uint32_t poolsize;
174 uint32_t threshold; 206 uint32_t threshold;
175 uint32_t maxentropy; 207 uint32_t maxentropy;
@@ -238,36 +270,36 @@ The @@ -238,36 +270,36 @@ The
238.Va flags 270.Va flags
239and 271and
240.Va mask 272.Va mask
241work together to change flag bits. 273work together to change flag bits.
242The 274The
243.Va mask 275.Va mask
244field specifies which bits in 276field specifies which bits in
245.Va flags 277.Va flags
246are to be set or cleared. 278are to be set or cleared.
247.It Dv RNDADDDATA 279.It Dv RNDADDDATA
248.Pq Li "rnddata_t" 280.Pq Li "rnddata_t"
249.Bd -literal -offset indent 281.Bd -literal -offset indent
250typedef struct { 282typedef struct {
251 uint32_t len; 283 uint32_t len;
252 uint32_t entropy; 284 uint32_t entropy;
253 u_char data[RND_POOLWORDS * 4]; 285 u_char data[RND_SAVEWORDS * sizeof(uint32_t)];
254} rnddata_t; 286} rnddata_t;
255.Ed 287.Ed
256.El 288.El
257.Sh FILES 289.Sh FILES
258.Bl -tag -width /dev/urandomx -compact 290.Bl -tag -width /dev/urandomx -compact
259.It Pa /dev/random 291.It Pa /dev/random
260Returns ``good'' values only 292Returns ``good'' values only
261.It Pa /dev/urandom 293.It Pa /dev/urandom
262Always returns data, degenerates to a pseudo-random generator 294Always returns data.
263.El 295.El
264.Sh SEE ALSO 296.Sh SEE ALSO
265.Xr rndctl 8 , 297.Xr rndctl 8 ,
266.Xr rnd 9 298.Xr rnd 9
267.Sh HISTORY 299.Sh HISTORY
268The random device was first made available in 300The random device was first made available in
269.Nx 1.3 . 301.Nx 1.3 .
270.Sh AUTHORS 302.Sh AUTHORS
271This implementation was written by Michael Graff \*[Lt]explorer@flame.org\*[Gt] 303This implementation was written by Thor Lancelot Simon. It retains
272using ideas and algorithms gathered from many sources, including 304some code (particularly for the ioctl interface) from the earlier
273the driver written by Ted Ts'o. 305implementation by Michael Graff \*[Lt]explorer@flame.org\*[Gt].

cvs diff -r1.3 -r1.4 src/share/man/man9/cprng.9 (expand / switch to unified diff)

--- src/share/man/man9/cprng.9 2011/11/28 23:29:45 1.3
+++ src/share/man/man9/cprng.9 2011/12/17 20:05:38 1.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: cprng.9,v 1.3 2011/11/28 23:29:45 wiz Exp $ 1.\" $NetBSD: cprng.9,v 1.4 2011/12/17 20:05:38 tls Exp $
2.\" 2.\"
3.\" Copyright (c) 2011 The NetBSD Foundation, Inc. 3.\" Copyright (c) 2011 The NetBSD Foundation, Inc.
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation 6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Thor Lancelot Simon. 7.\" by Thor Lancelot Simon.
8.\" 8.\"
9.\" Redistribution and use in source and binary forms, with or without 9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions 10.\" modification, are permitted provided that the following conditions
11.\" are met: 11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright 12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer. 13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
@@ -28,64 +28,66 @@ @@ -28,64 +28,66 @@
28.\" POSSIBILITY OF SUCH DAMAGE. 28.\" POSSIBILITY OF SUCH DAMAGE.
29.\" 29.\"
30.Dd November 28, 2011 30.Dd November 28, 2011
31.Dt CPRNG 9 31.Dt CPRNG 9
32.Os 32.Os
33.Sh NAME 33.Sh NAME
34.Nm cprng , 34.Nm cprng ,
35.Nm cprng_strong_create , 35.Nm cprng_strong_create ,
36.Nm cprng_strong , 36.Nm cprng_strong ,
37.Nm cprng_strong32 , 37.Nm cprng_strong32 ,
38.Nm cprng_strong64 , 38.Nm cprng_strong64 ,
39.Nm cprng_strong_getflags , 39.Nm cprng_strong_getflags ,
40.Nm cprng_strong_setflags , 40.Nm cprng_strong_setflags ,
 41.Nm cprng_strong_ready ,
41.Nm cprng_strong_destroy , 42.Nm cprng_strong_destroy ,
42.Nm cprng_fast , 43.Nm cprng_fast ,
43.Nm cprng_fast32 , 44.Nm cprng_fast32 ,
44.Nm cprng_fast64 , 45.Nm cprng_fast64 ,
45.Nd cryptographic pseudo-random number generators 46.Nd cryptographic pseudo-random number generators
46.Sh SYNOPSIS 47.Sh SYNOPSIS
47.In sys/cprng.h 48.In sys/cprng.h
48.Ft cprng_strong_t 49.Ft cprng_strong_t
49.Fn cprng_strong_create "const char *const name" "int ipl" "int flags" 50.Fn cprng_strong_create "const char *const name" "int ipl" "int flags"
50.Ft void 51.Ft void
51.Fn cprng_strong_destroy "cprng_strong_t *cprng" 52.Fn cprng_strong_destroy "cprng_strong_t *cprng"
52.Ft size_t 53.Ft size_t
53.Fn cprng_strong "cprng_strong_t *const cprng" "void *buf" "size_t len" 54.Fn cprng_strong "cprng_strong_t *const cprng" "void *buf" "size_t len" "int blocking"
54.Ft size_t 55.Ft size_t
55.Fn cprng_fast "void *buf" "size_t len" 56.Fn cprng_fast "void *buf" "size_t len"
56.Ft uint32_t 57.Ft uint32_t
57.Fn cprng_strong32 "void" 58.Fn cprng_strong32 "void"
58.Ft uint64_t 59.Ft uint64_t
59.Fn cprng_strong64 "void" 60.Fn cprng_strong64 "void"
60.Ft uint32_t 61.Ft uint32_t
61.Fn cprng_fast32 "void" 62.Fn cprng_fast32 "void"
62.Ft uint32_t 63.Ft uint32_t
63.Fn cprng_fast64 "void" 64.Fn cprng_fast64 "void"
64.Ft int 65.Ft int
65.Fn cprng_strong_getflags "cprng_strong_t *const cprng" 66.Fn cprng_strong_getflags "cprng_strong_t *const cprng"
66.Ft void 67.Ft void
67.Fn cprng_strong_setflags "cprng_strong_t *const cprng" "int flags" 68.Fn cprng_strong_setflags "cprng_strong_t *const cprng" "int flags"
68.Bd -literal 69.Bd -literal
69#define CPRNG_MAX_LEN 524288 70#define CPRNG_MAX_LEN 524288
70 71
71typedef struct _cprng_strong { 72typedef struct _cprng_strong {
72 kmutex_t mtx; 73 kmutex_t mtx;
73 kcondvar_t cv; 74 kcondvar_t cv;
74 NIST_CTR_DRBG drbg; 75 struct selinfo selq;
75 int flags; 76 NIST_CTR_DRBG drbg;
76 char name[16]; 77 int flags;
77 int reseed_pending; 78 char name[16];
78 rndsink_t reseed; 79 int reseed_pending;
 80 rndsink_t reseed;
79} cprng_strong_t; 81} cprng_strong_t;
80.Ed 82.Ed
81.Sh DESCRIPTION 83.Sh DESCRIPTION
82The 84The
83.Nm 85.Nm
84family of functions supply randomness to callers within the 86family of functions supply randomness to callers within the
85.Nx 87.Nx
86kernel. 88kernel.
87They replace the 89They replace the
88.Xr arc4random 9 90.Xr arc4random 9
89and 91and
90.Xr rnd_extract_data 9 92.Xr rnd_extract_data 9
91functions for this purpose. 93functions for this purpose.
@@ -160,46 +162,52 @@ argument controls the behavior of the ge @@ -160,46 +162,52 @@ argument controls the behavior of the ge
160.It Dv CPRNG_INIT_ANY 162.It Dv CPRNG_INIT_ANY
161Perform initial keying of the generator from the entropy pool even if 163Perform initial keying of the generator from the entropy pool even if
162the current estimate of entropy in the pool is less than the required 164the current estimate of entropy in the pool is less than the required
163number of key bits for the generator. 165number of key bits for the generator.
164.It Dv CPRNG_REKEY_ANY 166.It Dv CPRNG_REKEY_ANY
165When rekeying of the generator is required, key the generator from the 167When rekeying of the generator is required, key the generator from the
166entropy pool even if the current estimate of entropy in the pool is less 168entropy pool even if the current estimate of entropy in the pool is less
167than the required number of key bits for the generator. 169than the required number of key bits for the generator.
168.It Dv CPRNG_USE_CV 170.It Dv CPRNG_USE_CV
169Perform a 171Perform a
170.Xr cv_broadcast 9 172.Xr cv_broadcast 9
171operation on the "cv" member of the returned cprng_strong_t each time 173operation on the "cv" member of the returned cprng_strong_t each time
172the generator is successfully rekeyed. 174the generator is successfully rekeyed.
 175.Em If this flag is set, the generator will sleep when rekeying is needed,
 176.Em and will therefore always return the requested number of bytes.
173.El 177.El
174.Pp 178.Pp
175Creation will succeed even if key material for the generator is not 179Creation will succeed even if key material for the generator is not
176available. 180available.
177In this case, the first request to read from the generator 181In this case, the first request to read from the generator
178may cause rekeying. 182may cause rekeying.
179.It Fn cprng_strong_destroy "cprng" 183.It Fn cprng_strong_destroy "cprng"
180.Pp 184.Pp
181Destroy an instance of the cprng_strong generator. 185Destroy an instance of the cprng_strong generator.
182.It Fn cprng_strong "cprng" "buf" "len" 186.It Fn cprng_strong "cprng" "buf" "len" "blocking"
183.Pp 187.Pp
184Fill memory location 188Fill memory location
185.Fa buf 189.Fa buf
186with 190with
187.Fa len 191.Fa len
188bytes from the generator 192bytes from the generator
189.Fa cprng . 193.Fa cprng .
190If less than 194The
 195.Fa blocking
 196argument controls the blocking/non-blocking behavior of the
 197generator: if it is set to FNONBLOCK, the generator may return
 198less than
191.Fa len 199.Fa len
192bytes are returned, the generator requires rekeying. 200bytes if it requires rekeying.
193If the 201If the
194.Dv CPRNG_USE_CV 202.Dv CPRNG_USE_CV
195flag is set on the generator, the caller can wait on 203flag is set on the generator, the caller can wait on
196.Dv cprng->cv 204.Dv cprng->cv
197for notification that the generator can again supply bytes. 205for notification that the generator can again supply bytes.
198A maximum of 206A maximum of
199.Dv CPRNG_MAX_LEN 207.Dv CPRNG_MAX_LEN
200bytes may be requested at once; this is a restriction of the 208bytes may be requested at once; this is a restriction of the
201CTR_DRBG specification. 209CTR_DRBG specification.
202.It Fn cprng_strong32 "cprng" 210.It Fn cprng_strong32 "cprng"
203.Pp 211.Pp
204Generate 32 bits using cprng_strong generator 212Generate 32 bits using cprng_strong generator
205.Fa cprng . 213.Fa cprng .

cvs diff -r1.18 -r1.19 src/share/man/man9/rnd.9 (expand / switch to unified diff)

--- src/share/man/man9/rnd.9 2011/11/28 20:19:28 1.18
+++ src/share/man/man9/rnd.9 2011/12/17 20:05:38 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1.\" $NetBSD: rnd.9,v 1.18 2011/11/28 20:19:28 tls Exp $ 1.\" $NetBSD: rnd.9,v 1.19 2011/12/17 20:05:38 tls Exp $
2.\" 2.\"
3.\" Copyright (c) 1997 The NetBSD Foundation, Inc. 3.\" Copyright (c) 1997 The NetBSD Foundation, Inc.
4.\" All rights reserved. 4.\" All rights reserved.
5.\" 5.\"
6.\" This documentation is derived from text contributed to The NetBSD 6.\" This documentation is derived from text contributed to The NetBSD
7.\" Foundation by S.P.Zeidler (aka stargazer). 7.\" Foundation by S.P.Zeidler (aka stargazer).
8.\" 8.\"
9.\" Redistribution and use in source and binary forms, with or without 9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions 10.\" modification, are permitted provided that the following conditions
11.\" are met: 11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright 12.\" 1. Redistributions of source code must retain the above copyright
13.\" notice, this list of conditions and the following disclaimer. 13.\" notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright 14.\" 2. Redistributions in binary form must reproduce the above copyright
@@ -41,32 +41,36 @@ @@ -41,32 +41,36 @@
41.In sys/rnd.h 41.In sys/rnd.h
42.Ft void 42.Ft void
43.Fn rnd_attach_source "rndsource_element_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags" 43.Fn rnd_attach_source "rndsource_element_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags"
44.Ft void 44.Ft void
45.Fn rnd_detach_source "rndsource_element_t *rnd_source" 45.Fn rnd_detach_source "rndsource_element_t *rnd_source"
46.Ft void 46.Ft void
47.Fn rnd_add_data "rndsource_element_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy" 47.Fn rnd_add_data "rndsource_element_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy"
48.Ft void 48.Ft void
49.Fn rnd_add_uint32 "rndsource_element_t *rnd_source" "uint32_t datum" 49.Fn rnd_add_uint32 "rndsource_element_t *rnd_source" "uint32_t datum"
50.Sh DESCRIPTION 50.Sh DESCRIPTION
51These 51These
52.Nm 52.Nm
53functions make a device available for entropy collection for 53functions make a device available for entropy collection for
54.Pa /dev/random . 54the kernel entropy pool, which provides key material for the
 55.Xr cprng 9
 56and
 57.Xr rnd 4
 58.Pa (/dev/random) interfaces.
55.Pp 59.Pp
56Ideally the first argument 60Ideally the first argument
57.Fa rnd_source 61.Fa rnd_source
58of these functions gets included in the devices' entity struct, 62of these functions gets included in the devices' entity struct,
59but any means to permanently (static) attach one such argument 63but any means to permanently (statically) attach one such argument
60to one incarnation of the device is ok. 64to one incarnation of the device is ok.
61Do not share 65Do not share
62.Fa rnd_source 66.Fa rnd_source
63structures between two devices. 67structures between two devices.
64.Pp 68.Pp
65.Bl -tag -width 8n 69.Bl -tag -width 8n
66.It Fn rnd_attach_source "rndsource_element_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags" 70.It Fn rnd_attach_source "rndsource_element_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags"
67This function announces the availability of a device for entropy collection. 71This function announces the availability of a device for entropy collection.
68It must be called before the source struct pointed to by 72It must be called before the source struct pointed to by
69.Fa rnd_source 73.Fa rnd_source
70is used in any of the following functions. 74is used in any of the following functions.
71.Pp 75.Pp
72.Fa devname 76.Fa devname
@@ -157,26 +161,61 @@ is the number of bits in @@ -157,26 +161,61 @@ is the number of bits in
157.Pp 161.Pp
158Timing information is also used to add entropy into the system, using 162Timing information is also used to add entropy into the system, using
159inter-event timings. 163inter-event timings.
160.Pp 164.Pp
161If it is desired to mix in the 165If it is desired to mix in the
162.Va data 166.Va data
163and to add in a timestamp, but not to actually estimate entropy from a source 167and to add in a timestamp, but not to actually estimate entropy from a source
164of randomness, passing 168of randomness, passing
165.Dv NULL 169.Dv NULL
166for 170for
167.Va rnd_source 171.Va rnd_source
168is permitted, and the device does not need to be attached. 172is permitted, and the device does not need to be attached.
169.El 173.El
 174.Sh INTERNAL ENTROPY POOL MANAGEMENT
 175When a hardware event occurs (such as completion of a hard drive
 176transfer or an interrupt from a network device) a timestamp is
 177generated.
 178This timestamp is compared to the previous timestamp
 179recorded for the device, and the first, second, and third order
 180differentials are calculated.
 181.Pp
 182If any of these differentials is zero, no entropy is assumed to
 183have been gathered.
 184If all are non-zero, one bit is assumed.
 185Next, data is mixed into the entropy pool using an LFSR (linear
 186feedback shift register).
 187.Pp
 188To extract data from the entropy pool, a cryptographically strong hash
 189function is used.
 190The output of this hash is mixed back into the pool using the LFSR,
 191and then folded in half before being returned to the caller.
 192.Pp
 193Mixing the actual hash into the pool causes the next extraction to
 194return a different value, even if no timing events were added to the
 195pool.
 196Folding the data in half prevents the caller to derive the
 197actual hash of the pool, preventing some attacks.
 198.Pp
 199.Pp
 200In the NetBSD kernel, values should be extracted from the entropy
 201pool
 202.Em only
 203via the
 204.Xr cprng 9
 205interface. Direct access to the entropy pool is unsupported and
 206may be dangerous. There is no supported API for direct access to
 207the output of the entropy pool.
 208.Pp
170.\" .Sh ERRORS 209.\" .Sh ERRORS
171.Sh FILES 210.Sh FILES
172These functions are declared in src/sys/sys/rnd.h and defined in 211These functions are declared in src/sys/sys/rnd.h and defined in
173src/sys/dev/rnd.c. 212src/sys/dev/rnd.c.
174.Sh SEE ALSO 213.Sh SEE ALSO
175.Xr rnd 4 , 214.Xr rnd 4 ,
176.Xr rndctl 8 , 215.Xr rndctl 8 ,
177.Xr cprng 9 216.Xr cprng 9
178.Sh HISTORY 217.Sh HISTORY
179The random device was introduced in 218The random device was introduced in
180.Nx 1.3 . 219.Nx 1.3 .
181.Sh AUTHORS 220.Sh AUTHORS
182This implementation was written by Michael Graff \*[Lt]explorer@flame.org\*[Gt] 221This implementation was written by Michael Graff \*[Lt]explorer@flame.org\*[Gt]

cvs diff -r1.1032 -r1.1033 src/sys/conf/files (expand / switch to unified diff)

--- src/sys/conf/files 2011/11/19 22:51:21 1.1032
+++ src/sys/conf/files 2011/12/17 20:05:38 1.1033
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: files,v 1.1032 2011/11/19 22:51:21 tls Exp $ 1# $NetBSD: files,v 1.1033 2011/12/17 20:05:38 tls Exp $
2# @(#)files.newconf 7.5 (Berkeley) 5/10/93 2# @(#)files.newconf 7.5 (Berkeley) 5/10/93
3 3
4version 20100430 4version 20100430
5 5
6# 6#
7# device classes 7# device classes
8# 8#
9devclass disk 9devclass disk
10devclass tape 10devclass tape
11devclass ifnet 11devclass ifnet
12devclass tty 12devclass tty
13devclass audiodev 13devclass audiodev
14devclass displaydev 14devclass displaydev
@@ -1429,28 +1429,29 @@ file dev/dkwedge/dkwedge_gpt.c dkwedge_m @@ -1429,28 +1429,29 @@ file dev/dkwedge/dkwedge_gpt.c dkwedge_m
1429file dev/dkwedge/dkwedge_mbr.c dkwedge_method_mbr 1429file dev/dkwedge/dkwedge_mbr.c dkwedge_method_mbr
1430file dev/firmload.c firmload 1430file dev/firmload.c firmload
1431file dev/fss.c fss 1431file dev/fss.c fss
1432file dev/keylock.c keylock 1432file dev/keylock.c keylock
1433file dev/lockstat.c lockstat needs-flag 1433file dev/lockstat.c lockstat needs-flag
1434file dev/md.c md 1434file dev/md.c md
1435file dev/midi.c midi | midibus needs-flag 1435file dev/midi.c midi | midibus needs-flag
1436file dev/midictl.c midisyn 1436file dev/midictl.c midisyn
1437file dev/midisyn.c midisyn 1437file dev/midisyn.c midisyn
1438file dev/mm.c 1438file dev/mm.c
1439file dev/mulaw.c mulaw needs-flag 1439file dev/mulaw.c mulaw needs-flag
1440file dev/nullcons_subr.c nullcons needs-flag 1440file dev/nullcons_subr.c nullcons needs-flag
1441file dev/radio.c radio needs-flag 1441file dev/radio.c radio needs-flag
1442file dev/rnd.c rnd needs-flag 1442file dev/rnd.c
1443file dev/rndpool.c rnd needs-flag 1443file dev/rndpool.c
 1444file dev/rndpseudo.c rnd needs-flag
1444file dev/sequencer.c sequencer needs-flag 1445file dev/sequencer.c sequencer needs-flag
1445file dev/video.c video needs-flag 1446file dev/video.c video needs-flag
1446file dev/vnd.c vnd needs-flag 1447file dev/vnd.c vnd needs-flag
1447file kern/bufq_disksort.c bufq_disksort 1448file kern/bufq_disksort.c bufq_disksort
1448file kern/bufq_fcfs.c bufq_fcfs 1449file kern/bufq_fcfs.c bufq_fcfs
1449file kern/bufq_priocscan.c bufq_priocscan 1450file kern/bufq_priocscan.c bufq_priocscan
1450file kern/bufq_readprio.c bufq_readprio | new_bufq_strategy 1451file kern/bufq_readprio.c bufq_readprio | new_bufq_strategy
1451file kern/core_elf32.c exec_elf32 1452file kern/core_elf32.c exec_elf32
1452file kern/core_elf64.c exec_elf64 1453file kern/core_elf64.c exec_elf64
1453file kern/core_netbsd.c exec_aout | exec_coff | exec_ecoff 1454file kern/core_netbsd.c exec_aout | exec_coff | exec_ecoff
1454file kern/cnmagic.c 1455file kern/cnmagic.c
1455file kern/exec_aout.c exec_aout 1456file kern/exec_aout.c exec_aout
1456file kern/exec_ecoff.c exec_ecoff 1457file kern/exec_ecoff.c exec_ecoff

cvs diff -r1.1 -r1.2 src/sys/crypto/nist_ctr_drbg/Attic/nist_ctr_drbg_aes128.h (expand / switch to unified diff)

--- src/sys/crypto/nist_ctr_drbg/Attic/nist_ctr_drbg_aes128.h 2011/11/19 22:51:22 1.1
+++ src/sys/crypto/nist_ctr_drbg/Attic/nist_ctr_drbg_aes128.h 2011/12/17 20:05:38 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nist_ctr_drbg_aes128.h,v 1.1 2011/11/19 22:51:22 tls Exp $ */ 1/* $NetBSD: nist_ctr_drbg_aes128.h,v 1.2 2011/12/17 20:05:38 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Thor Lancelot Simon. 8 * by Thor Lancelot Simon.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -63,18 +63,18 @@ @@ -63,18 +63,18 @@
63#define NIST_BLOCK_OUTLEN_LONGS (NIST_BLOCK_OUTLEN_BYTES / sizeof(long)) 63#define NIST_BLOCK_OUTLEN_LONGS (NIST_BLOCK_OUTLEN_BYTES / sizeof(long))
64 64
65typedef NIST_AES_ENCRYPT_CTX NIST_Key; 65typedef NIST_AES_ENCRYPT_CTX NIST_Key;
66 66
67#define Block_Encrypt(ctx, src, dst) NIST_AES_ECB_Encrypt(ctx, src, dst) 67#define Block_Encrypt(ctx, src, dst) NIST_AES_ECB_Encrypt(ctx, src, dst)
68#define Block_Schedule_Encryption(ctx, key) \ 68#define Block_Schedule_Encryption(ctx, key) \
69 NIST_AES_Schedule_Encryption(ctx, key, NIST_BLOCK_KEYLEN) 69 NIST_AES_Schedule_Encryption(ctx, key, NIST_BLOCK_KEYLEN)
70 70
71/* 71/*
72 * NIST SP 800-90 March 2007 72 * NIST SP 800-90 March 2007
73 * 10.2 DRBG Mechanism Based on Block Ciphers 73 * 10.2 DRBG Mechanism Based on Block Ciphers
74 * 74 *
75 * Table 3 specifies the reseed interval as 75 * Table 3 specifies the reseed interval as
76 * <= 2^48. We use 2^32 so we can always be sure it'll fit in an int. 76 * <= 2^48. We use 2^31 so we can always be sure it'll fit in an int.
77 */ 77 */
78#define NIST_CTR_DRBG_RESEED_INTERVAL (0xffffffffU) 78#define NIST_CTR_DRBG_RESEED_INTERVAL (0x7fffffffU)
79 79
80#endif /* NIST_CTR_DRBG_AES128_H */ 80#endif /* NIST_CTR_DRBG_AES128_H */

cvs diff -r1.1 -r1.2 src/sys/crypto/nist_ctr_drbg/Attic/nist_ctr_drbg_aes256.h (expand / switch to unified diff)

--- src/sys/crypto/nist_ctr_drbg/Attic/nist_ctr_drbg_aes256.h 2011/11/19 22:51:22 1.1
+++ src/sys/crypto/nist_ctr_drbg/Attic/nist_ctr_drbg_aes256.h 2011/12/17 20:05:38 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: nist_ctr_drbg_aes256.h,v 1.1 2011/11/19 22:51:22 tls Exp $ */ 1/* $NetBSD: nist_ctr_drbg_aes256.h,v 1.2 2011/12/17 20:05:38 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Thor Lancelot Simon. 8 * by Thor Lancelot Simon.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -63,18 +63,18 @@ @@ -63,18 +63,18 @@
63#define NIST_BLOCK_OUTLEN_LONGS (NIST_BLOCK_OUTLEN_BYTES / sizeof(long)) 63#define NIST_BLOCK_OUTLEN_LONGS (NIST_BLOCK_OUTLEN_BYTES / sizeof(long))
64 64
65typedef NIST_AES_ENCRYPT_CTX NIST_Key; 65typedef NIST_AES_ENCRYPT_CTX NIST_Key;
66 66
67#define Block_Encrypt(ctx, src, dst) NIST_AES_ECB_Encrypt(ctx, src, dst) 67#define Block_Encrypt(ctx, src, dst) NIST_AES_ECB_Encrypt(ctx, src, dst)
68#define Block_Schedule_Encryption(ctx, key) \ 68#define Block_Schedule_Encryption(ctx, key) \
69 NIST_AES_Schedule_Encryption(ctx, key, NIST_BLOCK_KEYLEN) 69 NIST_AES_Schedule_Encryption(ctx, key, NIST_BLOCK_KEYLEN)
70 70
71/* 71/*
72 * NIST SP 800-90 March 2007 72 * NIST SP 800-90 March 2007
73 * 10.2 DRBG Mechanism Based on Block Ciphers 73 * 10.2 DRBG Mechanism Based on Block Ciphers
74 * 74 *
75 * Table 3 specifies the reseed interval as 75 * Table 3 specifies the reseed interval as
76 * <= 2^48. We use 2^32 so we can always be sure it'll fit in an int. 76 * <= 2^48. We use 2^31 so we can always be sure it'll fit in an int.
77 */ 77 */
78#define NIST_CTR_DRBG_RESEED_INTERVAL (0xffffffffU) 78#define NIST_CTR_DRBG_RESEED_INTERVAL (0x7fffffffU)
79 79
80#endif /* NIST_CTR_DRBG_AES256_H */ 80#endif /* NIST_CTR_DRBG_AES256_H */

cvs diff -r1.88 -r1.89 src/sys/dev/Attic/rnd.c (expand / switch to unified diff)

--- src/sys/dev/Attic/rnd.c 2011/11/29 03:50:31 1.88
+++ src/sys/dev/Attic/rnd.c 2011/12/17 20:05:38 1.89
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rnd.c,v 1.88 2011/11/29 03:50:31 tls Exp $ */ 1/* $NetBSD: rnd.c,v 1.89 2011/12/17 20:05:38 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon. 8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon.
9 * This code uses ideas and algorithms from the Linux driver written by 9 * This code uses ideas and algorithms from the Linux driver written by
10 * Ted Ts'o. 10 * Ted Ts'o.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.88 2011/11/29 03:50:31 tls Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: rnd.c,v 1.89 2011/12/17 20:05:38 tls Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/ioctl.h> 38#include <sys/ioctl.h>
39#include <sys/fcntl.h> 39#include <sys/fcntl.h>
40#include <sys/select.h> 40#include <sys/select.h>
41#include <sys/poll.h> 41#include <sys/poll.h>
42#include <sys/kmem.h> 42#include <sys/kmem.h>
43#include <sys/mutex.h> 43#include <sys/mutex.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/conf.h> 46#include <sys/conf.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/callout.h> 48#include <sys/callout.h>
@@ -108,34 +108,29 @@ typedef struct _rnd_sample_t { @@ -108,34 +108,29 @@ typedef struct _rnd_sample_t {
108volatile int rnd_timeout_pending; 108volatile int rnd_timeout_pending;
109SIMPLEQ_HEAD(, _rnd_sample_t) rnd_samples; 109SIMPLEQ_HEAD(, _rnd_sample_t) rnd_samples;
110kmutex_t rnd_mtx; 110kmutex_t rnd_mtx;
111 111
112/* 112/*
113 * Entropy sinks: usually other generators waiting to be rekeyed. 113 * Entropy sinks: usually other generators waiting to be rekeyed.
114 * 114 *
115 * A sink's callback MUST NOT re-add the sink to the list, or 115 * A sink's callback MUST NOT re-add the sink to the list, or
116 * list corruption will occur. 116 * list corruption will occur.
117 */ 117 */
118TAILQ_HEAD(, rndsink) rnd_sinks; 118TAILQ_HEAD(, rndsink) rnd_sinks;
119 119
120/* 120/*
121 * our select/poll queue 
122 */ 
123struct selinfo rnd_selq; 
124 
125/* 
126 * Memory pool for sample buffers 121 * Memory pool for sample buffers
127 */ 122 */
128static struct pool rnd_mempool; 123static pool_cache_t rnd_mempc;
129 124
130/* 125/*
131 * Our random pool. This is defined here rather than using the general 126 * Our random pool. This is defined here rather than using the general
132 * purpose one defined in rndpool.c. 127 * purpose one defined in rndpool.c.
133 * 128 *
134 * Samples are collected and queued into a separate mutex-protected queue 129 * Samples are collected and queued into a separate mutex-protected queue
135 * (rnd_samples, see above), and processed in a timeout routine; therefore, 130 * (rnd_samples, see above), and processed in a timeout routine; therefore,
136 * the mutex protecting the random pool is at IPL_SOFTCLOCK() as well. 131 * the mutex protecting the random pool is at IPL_SOFTCLOCK() as well.
137 */ 132 */
138rndpool_t rnd_pool; 133rndpool_t rnd_pool;
139kmutex_t rndpool_mtx; 134kmutex_t rndpool_mtx;
140kcondvar_t rndpool_cv; 135kcondvar_t rndpool_cv;
141 136
@@ -149,79 +144,70 @@ static krndsource_t rnd_source_no_collec @@ -149,79 +144,70 @@ static krndsource_t rnd_source_no_collec
149 0, 0, 0, 0, 0, 0, 0 }, 144 0, 0, 0, 0, 0, 0, 0 },
150 .last_time = 0, .last_delta = 0, .last_delta2 = 0, .total = 0, 145 .last_time = 0, .last_delta = 0, .last_delta2 = 0, .total = 0,
151 .type = RND_TYPE_UNKNOWN, 146 .type = RND_TYPE_UNKNOWN,
152 .flags = (RND_FLAG_NO_COLLECT | 147 .flags = (RND_FLAG_NO_COLLECT |
153 RND_FLAG_NO_ESTIMATE | 148 RND_FLAG_NO_ESTIMATE |
154 RND_TYPE_UNKNOWN), 149 RND_TYPE_UNKNOWN),
155 .state = NULL, 150 .state = NULL,
156 .test_cnt = 0, 151 .test_cnt = 0,
157 .test = NULL 152 .test = NULL
158}; 153};
159 154
160struct callout rnd_callout; 155struct callout rnd_callout;
161 156
162void rndattach(int); 157void rnd_wakeup_readers(void);
163 
164dev_type_open(rndopen); 
165dev_type_read(rndread); 
166dev_type_write(rndwrite); 
167dev_type_ioctl(rndioctl); 
168dev_type_poll(rndpoll); 
169dev_type_kqfilter(rndkqfilter); 
170 
171const struct cdevsw rnd_cdevsw = { 
172 rndopen, nullclose, rndread, rndwrite, rndioctl, 
173 nostop, notty, rndpoll, nommap, rndkqfilter, D_OTHER|D_MPSAFE, 
174}; 
175 
176static inline void rnd_wakeup_readers(void); 
177static inline u_int32_t rnd_estimate_entropy(krndsource_t *, u_int32_t); 158static inline u_int32_t rnd_estimate_entropy(krndsource_t *, u_int32_t);
178static inline u_int32_t rnd_counter(void); 159static inline u_int32_t rnd_counter(void);
179static void rnd_timeout(void *); 160static void rnd_timeout(void *);
180static void rnd_process_events(void *); 161static void rnd_process_events(void *);
181static u_int32_t rnd_extract_data_locked(void *, u_int32_t, u_int32_t); 162u_int32_t rnd_extract_data_locked(void *, u_int32_t, u_int32_t); /* XXX */
182 163
183static int rnd_ready = 0; 164int rnd_ready = 0;
184static int rnd_have_entropy = 0; 165static int rnd_have_entropy = 0;
 166
 167#ifdef DIAGNOSTIC
185static int rnd_tested = 0; 168static int rnd_tested = 0;
 169static rngtest_t rnd_rt;
 170static uint8_t rnd_testbits[sizeof(rnd_rt.rt_b)];
 171#endif
186 172
187LIST_HEAD(, krndsource) rnd_sources; 173LIST_HEAD(, krndsource) rnd_sources;
188 174
189static rndsave_t *boot_rsp; 175rndsave_t *boot_rsp;
190/* 176/*
191 * Generate a 32-bit counter. This should be more machine dependent, 177 * Generate a 32-bit counter. This should be more machine dependent,
192 * using cycle counters and the like when possible. 178 * using cycle counters and the like when possible.
193 */ 179 */
194static inline u_int32_t 180static inline u_int32_t
195rnd_counter(void) 181rnd_counter(void)
196{ 182{
197 struct timeval tv; 183 struct timeval tv;
198 184
199#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */ 185#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */
200 if (cpu_hascounter()) 186 if (cpu_hascounter())
201 return (cpu_counter32()); 187 return (cpu_counter32());
202#endif 188#endif
203 if (rnd_ready) { 189 if (rnd_ready) {
204 microtime(&tv); 190 microtime(&tv);
205 return (tv.tv_sec * 1000000 + tv.tv_usec); 191 return (tv.tv_sec * 1000000 + tv.tv_usec);
206 } 192 }
207 /* when called from rnd_init, its too early to call microtime safely */ 193 /* when called from rnd_init, its too early to call microtime safely */
208 return (0); 194 return (0);
209} 195}
210 196
211/* 197/*
212 * Check to see if there are readers waiting on us. If so, kick them. 198 * Check to see if there are readers waiting on us. If so, kick them.
213 */ 199 */
214static inline void 200void
215rnd_wakeup_readers(void) 201rnd_wakeup_readers(void)
216{ 202{
217 rndsink_t *sink, *tsink; 203 rndsink_t *sink, *tsink;
218 TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk); 204 TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk);
219 205
220 mutex_spin_enter(&rndpool_mtx); 206 mutex_spin_enter(&rndpool_mtx);
221 if (rndpool_get_entropy_count(&rnd_pool) < RND_ENTROPY_THRESHOLD * 8) { 207 if (rndpool_get_entropy_count(&rnd_pool) < RND_ENTROPY_THRESHOLD * 8) {
222 mutex_spin_exit(&rndpool_mtx); 208 mutex_spin_exit(&rndpool_mtx);
223 return; 209 return;
224 } 210 }
225 211
226 /* 212 /*
227 * First, take care of in-kernel consumers needing rekeying. 213 * First, take care of in-kernel consumers needing rekeying.
@@ -242,29 +228,27 @@ rnd_wakeup_readers(void) @@ -242,29 +228,27 @@ rnd_wakeup_readers(void)
242 } 228 }
243 } 229 }
244  230
245 /* 231 /*
246 * If we still have enough new bits to do something, feed userspace. 232 * If we still have enough new bits to do something, feed userspace.
247 */ 233 */
248 if (rndpool_get_entropy_count(&rnd_pool) > RND_ENTROPY_THRESHOLD * 8) { 234 if (rndpool_get_entropy_count(&rnd_pool) > RND_ENTROPY_THRESHOLD * 8) {
249#ifdef RND_VERBOSE 235#ifdef RND_VERBOSE
250 if (!rnd_have_entropy) 236 if (!rnd_have_entropy)
251 printf("rnd: have initial entropy (%u)\n", 237 printf("rnd: have initial entropy (%u)\n",
252 rndpool_get_entropy_count(&rnd_pool)); 238 rndpool_get_entropy_count(&rnd_pool));
253#endif 239#endif
254 rnd_have_entropy = 1; 240 rnd_have_entropy = 1;
255 cv_broadcast(&rndpool_cv); 
256 mutex_spin_exit(&rndpool_mtx); 241 mutex_spin_exit(&rndpool_mtx);
257 selnotify(&rnd_selq, 0, 0); 
258 } else { 242 } else {
259 mutex_spin_exit(&rndpool_mtx); 243 mutex_spin_exit(&rndpool_mtx);
260 } 244 }
261 245
262 /* 246 /*
263 * Now that we have dropped the mutex, we can run sinks' callbacks. 247 * Now that we have dropped the mutex, we can run sinks' callbacks.
264 * Since we have reused the "tailq" member of the sink structure for 248 * Since we have reused the "tailq" member of the sink structure for
265 * this temporary on-stack queue, the callback must NEVER re-add 249 * this temporary on-stack queue, the callback must NEVER re-add
266 * the sink to the main queue, or our on-stack queue will become 250 * the sink to the main queue, or our on-stack queue will become
267 * corrupt. 251 * corrupt.
268 */ 252 */
269 while ((sink = TAILQ_FIRST(&sunk))) { 253 while ((sink = TAILQ_FIRST(&sunk))) {
270#ifdef RND_VERBOSE 254#ifdef RND_VERBOSE
@@ -314,59 +298,26 @@ rnd_estimate_entropy(krndsource_t *rs, u @@ -314,59 +298,26 @@ rnd_estimate_entropy(krndsource_t *rs, u
314 rs->last_delta = delta; 298 rs->last_delta = delta;
315 rs->last_delta2 = delta2; 299 rs->last_delta2 = delta2;
316 300
317 /* 301 /*
318 * If any delta is 0, we got no entropy. If all are non-zero, we 302 * If any delta is 0, we got no entropy. If all are non-zero, we
319 * might have something. 303 * might have something.
320 */ 304 */
321 if (delta == 0 || delta2 == 0 || delta3 == 0) 305 if (delta == 0 || delta2 == 0 || delta3 == 0)
322 return (0); 306 return (0);
323 307
324 return (1); 308 return (1);
325} 309}
326 310
327static int 
328rnd_mempool_init(void) 
329{ 
330 
331 pool_init(&rnd_mempool, sizeof(rnd_sample_t), 0, 0, 0, "rndsample", 
332 NULL, IPL_VM); 
333 return 0; 
334} 
335static ONCE_DECL(rnd_mempoolinit_ctrl); 
336 
337/* 
338 * "Attach" the random device. This is an (almost) empty stub, since 
339 * pseudo-devices don't get attached until after config, after the 
340 * entropy sources will attach. We just use the timing of this event 
341 * as another potential source of initial entropy. 
342 */ 
343void 
344rndattach(int num) 
345{ 
346 u_int32_t c; 
347 
348 RUN_ONCE(&rnd_mempoolinit_ctrl, rnd_mempool_init); 
349 
350 /* Trap unwary players who don't call rnd_init() early */ 
351 KASSERT(rnd_ready); 
352 
353 /* mix in another counter */ 
354 c = rnd_counter(); 
355 mutex_spin_enter(&rndpool_mtx); 
356 rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1); 
357 mutex_spin_exit(&rndpool_mtx); 
358} 
359 
360/* 311/*
361 * initialize the global random pool for our use. 312 * initialize the global random pool for our use.
362 * rnd_init() must be called very early on in the boot process, so 313 * rnd_init() must be called very early on in the boot process, so
363 * the pool is ready for other devices to attach as sources. 314 * the pool is ready for other devices to attach as sources.
364 */ 315 */
365void 316void
366rnd_init(void) 317rnd_init(void)
367{ 318{
368 u_int32_t c; 319 u_int32_t c;
369 320
370 if (rnd_ready) 321 if (rnd_ready)
371 return; 322 return;
372 323
@@ -374,32 +325,34 @@ rnd_init(void) @@ -374,32 +325,34 @@ rnd_init(void)
374 325
375 callout_init(&rnd_callout, CALLOUT_MPSAFE); 326 callout_init(&rnd_callout, CALLOUT_MPSAFE);
376 callout_setfunc(&rnd_callout, rnd_timeout, NULL); 327 callout_setfunc(&rnd_callout, rnd_timeout, NULL);
377 328
378 /* 329 /*
379 * take a counter early, hoping that there's some variance in 330 * take a counter early, hoping that there's some variance in
380 * the following operations 331 * the following operations
381 */ 332 */
382 c = rnd_counter(); 333 c = rnd_counter();
383 334
384 LIST_INIT(&rnd_sources); 335 LIST_INIT(&rnd_sources);
385 SIMPLEQ_INIT(&rnd_samples); 336 SIMPLEQ_INIT(&rnd_samples);
386 TAILQ_INIT(&rnd_sinks); 337 TAILQ_INIT(&rnd_sinks);
387 selinit(&rnd_selq); 
388 338
389 rndpool_init(&rnd_pool); 339 rndpool_init(&rnd_pool);
390 mutex_init(&rndpool_mtx, MUTEX_DEFAULT, IPL_VM); 340 mutex_init(&rndpool_mtx, MUTEX_DEFAULT, IPL_VM);
391 cv_init(&rndpool_cv, "rndread"); 341 cv_init(&rndpool_cv, "rndread");
392 342
 343 rnd_mempc = pool_cache_init(sizeof(rnd_sample_t), 0, 0, 0,
 344 "rndsample", NULL, IPL_VM,
 345 NULL, NULL, NULL);
393 /* Mix *something*, *anything* into the pool to help it get started. 346 /* Mix *something*, *anything* into the pool to help it get started.
394 * However, it's not safe for rnd_counter() to call microtime() yet, 347 * However, it's not safe for rnd_counter() to call microtime() yet,
395 * so on some platforms we might just end up with zeros anyway. 348 * so on some platforms we might just end up with zeros anyway.
396 * XXX more things to add would be nice. 349 * XXX more things to add would be nice.
397 */ 350 */
398 if (c) { 351 if (c) {
399 mutex_spin_enter(&rndpool_mtx); 352 mutex_spin_enter(&rndpool_mtx);
400 rndpool_add_data(&rnd_pool, &c, sizeof(c), 1); 353 rndpool_add_data(&rnd_pool, &c, sizeof(c), 1);
401 c = rnd_counter(); 354 c = rnd_counter();
402 rndpool_add_data(&rnd_pool, &c, sizeof(c), 1); 355 rndpool_add_data(&rnd_pool, &c, sizeof(c), 1);
403 mutex_spin_exit(&rndpool_mtx); 356 mutex_spin_exit(&rndpool_mtx);
404 } 357 }
405 358
@@ -418,563 +371,77 @@ rnd_init(void) @@ -418,563 +371,77 @@ rnd_init(void)
418 if (rndpool_get_entropy_count(&rnd_pool) > 371 if (rndpool_get_entropy_count(&rnd_pool) >
419 RND_ENTROPY_THRESHOLD * 8) { 372 RND_ENTROPY_THRESHOLD * 8) {
420 rnd_have_entropy = 1; 373 rnd_have_entropy = 1;
421 } 374 }
422 mutex_spin_exit(&rndpool_mtx); 375 mutex_spin_exit(&rndpool_mtx);
423#ifdef RND_VERBOSE 376#ifdef RND_VERBOSE
424 printf("rnd: seeded with %d bits\n", 377 printf("rnd: seeded with %d bits\n",
425 MIN(boot_rsp->entropy, RND_POOLBITS / 2)); 378 MIN(boot_rsp->entropy, RND_POOLBITS / 2));
426#endif 379#endif
427 memset(boot_rsp, 0, sizeof(*boot_rsp)); 380 memset(boot_rsp, 0, sizeof(*boot_rsp));
428 } 381 }
429} 382}
430 383
431int 
432rndopen(dev_t dev, int flags, int ifmt, 
433 struct lwp *l) 
434{ 
435 
436 if (rnd_ready == 0) 
437 return (ENXIO); 
438 
439 if (minor(dev) == RND_DEV_URANDOM || minor(dev) == RND_DEV_RANDOM) 
440 return (0); 
441 
442 return (ENXIO); 
443} 
444 
445int 
446rndread(dev_t dev, struct uio *uio, int ioflag) 
447{ 
448 u_int8_t *bf; 
449 u_int32_t entcnt, mode, n, nread; 
450 int ret; 
451 
452 DPRINTF(RND_DEBUG_READ, 
453 ("Random: Read of %zu requested, flags 0x%08x\n", 
454 uio->uio_resid, ioflag)); 
455 
456 if (uio->uio_resid == 0) 
457 return (0); 
458 
459 switch (minor(dev)) { 
460 case RND_DEV_RANDOM: 
461 mode = RND_EXTRACT_GOOD; 
462 break; 
463 case RND_DEV_URANDOM: 
464 mode = RND_EXTRACT_ANY; 
465 break; 
466 default: 
467 /* Can't happen, but this is cheap */ 
468 return (ENXIO); 
469 } 
470 
471 ret = 0; 
472 bf = kmem_alloc(RND_TEMP_BUFFER_SIZE, KM_SLEEP); 
473 while (uio->uio_resid > 0) { 
474 n = min(RND_TEMP_BUFFER_SIZE, uio->uio_resid); 
475 
476 /* 
477 * Make certain there is data available. If there 
478 * is, do the I/O even if it is partial. If not, 
479 * sleep unless the user has requested non-blocking 
480 * I/O. 
481 * 
482 * If not requesting strong randomness, we can always read. 
483 */ 
484 mutex_spin_enter(&rndpool_mtx); 
485 if (mode != RND_EXTRACT_ANY) { 
486 for (;;) { 
487 /* 
488 * How much entropy do we have? 
489 * If it is enough for one hash, we can read. 
490 */ 
491 entcnt = rndpool_get_entropy_count(&rnd_pool); 
492 if (entcnt >= RND_ENTROPY_THRESHOLD * 8) 
493 break; 
494 
495 /* 
496 * Data is not available. 
497 */ 
498 if (ioflag & IO_NDELAY) { 
499 mutex_spin_exit(&rndpool_mtx); 
500 ret = EWOULDBLOCK; 
501 goto out; 
502 } 
503 ret = cv_wait_sig(&rndpool_cv, &rndpool_mtx); 
504 if (ret) { 
505 mutex_spin_exit(&rndpool_mtx); 
506 goto out; 
507 } 
508 } 
509 } 
510 nread = rnd_extract_data_locked(bf, n, mode); 
511 mutex_spin_exit(&rndpool_mtx); 
512 
513 /* 
514 * Copy (possibly partial) data to the user. 
515 * If an error occurs, or this is a partial 
516 * read, bail out. 
517 */ 
518 ret = uiomove((void *)bf, nread, uio); 
519 if (ret != 0 || nread != n) 
520 goto out; 
521 } 
522 
523out: 
524 kmem_free(bf, RND_TEMP_BUFFER_SIZE); 
525 return (ret); 
526} 
527 
528int 
529rndwrite(dev_t dev, struct uio *uio, int ioflag) 
530{ 
531 u_int8_t *bf; 
532 int n, ret = 0, estimate_ok = 0, estimate = 0, added = 0; 
533 
534 ret = kauth_authorize_device(curlwp->l_cred, 
535 KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL); 
536 if (ret) { 
537 return (ret); 
538 } 
539 estimate_ok = !kauth_authorize_device(curlwp->l_cred, 
540 KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL); 
541 
542 DPRINTF(RND_DEBUG_WRITE, 
543 ("Random: Write of %zu requested\n", uio->uio_resid)); 
544 
545 if (uio->uio_resid == 0) 
546 return (0); 
547 ret = 0; 
548 bf = kmem_alloc(RND_TEMP_BUFFER_SIZE, KM_SLEEP); 
549 while (uio->uio_resid > 0) { 
550 /* 
551 * Don't flood the pool. 
552 */ 
553 if (added > RND_POOLWORDS * sizeof(int)) { 
554 printf("rnd: added %d already, adding no more.\n", 
555 added); 
556 break; 
557 } 
558 n = min(RND_TEMP_BUFFER_SIZE, uio->uio_resid); 
559 
560 ret = uiomove((void *)bf, n, uio); 
561 if (ret != 0) 
562 break; 
563 
564 if (estimate_ok) { 
565 /* 
566 * Don't cause samples to be discarded by taking 
567 * the pool's entropy estimate to the max. 
568 */ 
569 if (added > RND_POOLWORDS / 2) 
570 estimate = 0; 
571 else 
572 estimate = n * NBBY / 2; 
573 printf("rnd: adding on write, %d bytes, estimate %d\n", 
574 n, estimate); 
575 } else { 
576 printf("rnd: kauth says no entropy.\n"); 
577 } 
578 
579 /* 
580 * Mix in the bytes. 
581 */ 
582 mutex_spin_enter(&rndpool_mtx); 
583 rndpool_add_data(&rnd_pool, bf, n, estimate); 
584 mutex_spin_exit(&rndpool_mtx); 
585 
586 added += n; 
587 DPRINTF(RND_DEBUG_WRITE, ("Random: Copied in %d bytes\n", n)); 
588 } 
589 kmem_free(bf, RND_TEMP_BUFFER_SIZE); 
590 return (ret); 
591} 
592 
593static void 
594krndsource_to_rndsource(krndsource_t *kr, rndsource_t *r) 
595{ 
596 memset(r, 0, sizeof(*r)); 
597 strlcpy(r->name, kr->name, sizeof(r->name)); 
598 r->total = kr->total; 
599 r->type = kr->type; 
600 r->flags = kr->flags; 
601} 
602 
603int 
604rndioctl(dev_t dev, u_long cmd, void *addr, int flag, 
605 struct lwp *l) 
606{ 
607 krndsource_t *kr; 
608 rndstat_t *rst; 
609 rndstat_name_t *rstnm; 
610 rndctl_t *rctl; 
611 rnddata_t *rnddata; 
612 u_int32_t count, start; 
613 int ret = 0; 
614 int estimate_ok = 0, estimate = 0; 
615 
616 switch (cmd) { 
617 case FIONBIO: 
618 case FIOASYNC: 
619 case RNDGETENTCNT: 
620 break; 
621 
622 case RNDGETPOOLSTAT: 
623 case RNDGETSRCNUM: 
624 case RNDGETSRCNAME: 
625 ret = kauth_authorize_device(l->l_cred, 
626 KAUTH_DEVICE_RND_GETPRIV, NULL, NULL, NULL, NULL); 
627 if (ret) 
628 return (ret); 
629 break; 
630 
631 case RNDCTL: 
632 ret = kauth_authorize_device(l->l_cred, 
633 KAUTH_DEVICE_RND_SETPRIV, NULL, NULL, NULL, NULL); 
634 if (ret) 
635 return (ret); 
636 break; 
637 
638 case RNDADDDATA: 
639 ret = kauth_authorize_device(l->l_cred, 
640 KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL); 
641 if (ret) 
642 return (ret); 
643 estimate_ok = !kauth_authorize_device(l->l_cred, 
644 KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL); 
645 break; 
646 
647 default: 
648 return (EINVAL); 
649 } 
650 
651 switch (cmd) { 
652 
653 /* 
654 * Handled in upper layer really, but we have to return zero 
655 * for it to be accepted by the upper layer. 
656 */ 
657 case FIONBIO: 
658 case FIOASYNC: 
659 break; 
660 
661 case RNDGETENTCNT: 
662 mutex_spin_enter(&rndpool_mtx); 
663 *(u_int32_t *)addr = rndpool_get_entropy_count(&rnd_pool); 
664 mutex_spin_exit(&rndpool_mtx); 
665 break; 
666 
667 case RNDGETPOOLSTAT: 
668 mutex_spin_enter(&rndpool_mtx); 
669 rndpool_get_stats(&rnd_pool, addr, sizeof(rndpoolstat_t)); 
670 mutex_spin_exit(&rndpool_mtx); 
671 break; 
672 
673 case RNDGETSRCNUM: 
674 rst = (rndstat_t *)addr; 
675 
676 if (rst->count == 0) 
677 break; 
678 
679 if (rst->count > RND_MAXSTATCOUNT) 
680 return (EINVAL); 
681 
682 /* 
683 * Find the starting source by running through the 
684 * list of sources. 
685 */ 
686 kr = rnd_sources.lh_first; 
687 start = rst->start; 
688 while (kr != NULL && start >= 1) { 
689 kr = kr->list.le_next; 
690 start--; 
691 } 
692 
693 /* 
694 * Return up to as many structures as the user asked 
695 * for. If we run out of sources, a count of zero 
696 * will be returned, without an error. 
697 */ 
698 for (count = 0; count < rst->count && kr != NULL; count++) { 
699 krndsource_to_rndsource(kr, &rst->source[count]); 
700 kr = kr->list.le_next; 
701 } 
702 
703 rst->count = count; 
704 
705 break; 
706 
707 case RNDGETSRCNAME: 
708 /* 
709 * Scan through the list, trying to find the name. 
710 */ 
711 rstnm = (rndstat_name_t *)addr; 
712 kr = rnd_sources.lh_first; 
713 while (kr != NULL) { 
714 if (strncmp(kr->name, rstnm->name, 
715 MIN(sizeof(kr->name), 
716 sizeof(*rstnm))) == 0) { 
717 krndsource_to_rndsource(kr, &rstnm->source); 
718 return (0); 
719 } 
720 kr = kr->list.le_next; 
721 } 
722 
723 ret = ENOENT; /* name not found */ 
724 
725 break; 
726 
727 case RNDCTL: 
728 /* 
729 * Set flags to enable/disable entropy counting and/or 
730 * collection. 
731 */ 
732 rctl = (rndctl_t *)addr; 
733 kr = rnd_sources.lh_first; 
734 
735 /* 
736 * Flags set apply to all sources of this type. 
737 */ 
738 if (rctl->type != 0xff) { 
739 while (kr != NULL) { 
740 if (kr->type == rctl->type) { 
741 kr->flags &= ~rctl->mask; 
742 kr->flags |= 
743 (rctl->flags & rctl->mask); 
744 } 
745 kr = kr->list.le_next; 
746 } 
747 
748 return (0); 
749 } 
750 
751 /* 
752 * scan through the list, trying to find the name 
753 */ 
754 while (kr != NULL) { 
755 if (strncmp(kr->name, rctl->name, 
756 MIN(sizeof(kr->name), 
757 sizeof(rctl->name))) == 0) { 
758 kr->flags &= ~rctl->mask; 
759 kr->flags |= (rctl->flags & rctl->mask); 
760 
761 return (0); 
762 } 
763 kr = kr->list.le_next; 
764 } 
765 
766 ret = ENOENT; /* name not found */ 
767 
768 break; 
769 
770 case RNDADDDATA: 
771 /* 
772 * Don't seed twice if our bootloader has 
773 * seed loading support. 
774 */ 
775 if (!boot_rsp) { 
776 rnddata = (rnddata_t *)addr; 
777 
778 if (rnddata->len > sizeof(rnddata->data)) 
779 return EINVAL; 
780 
781 if (estimate_ok) { 
782 /* 
783 * Do not accept absurd entropy estimates, and 
784 * do not flood the pool with entropy such that 
785 * new samples are discarded henceforth. 
786 */ 
787 estimate = MIN((rnddata->len * NBBY) / 2, 
788 MIN(rnddata->entropy, 
789 RND_POOLBITS / 2)); 
790 } else { 
791 estimate = 0; 
792 } 
793 
794 mutex_spin_enter(&rndpool_mtx); 
795 rndpool_add_data(&rnd_pool, rnddata->data, 
796 rnddata->len, estimate); 
797 mutex_spin_exit(&rndpool_mtx); 
798 
799 rnd_wakeup_readers(); 
800 } 
801#ifdef RND_VERBOSE 
802 else { 
803 printf("rnd: already seeded by boot loader\n"); 
804 } 
805#endif 
806 break; 
807 
808 default: 
809 return (EINVAL); 
810 } 
811 
812 return (ret); 
813} 
814 
815int 
816rndpoll(dev_t dev, int events, struct lwp *l) 
817{ 
818 u_int32_t entcnt; 
819 int revents; 
820 
821 /* 
822 * We are always writable. 
823 */ 
824 revents = events & (POLLOUT | POLLWRNORM); 
825 
826 /* 
827 * Save some work if not checking for reads. 
828 */ 
829 if ((events & (POLLIN | POLLRDNORM)) == 0) 
830 return (revents); 
831 
832 /* 
833 * If the minor device is not /dev/random, we are always readable. 
834 */ 
835 if (minor(dev) != RND_DEV_RANDOM) { 
836 revents |= events & (POLLIN | POLLRDNORM); 
837 return (revents); 
838 } 
839 
840 /* 
841 * Make certain we have enough entropy to be readable. 
842 */ 
843 mutex_spin_enter(&rndpool_mtx); 
844 entcnt = rndpool_get_entropy_count(&rnd_pool); 
845 mutex_spin_exit(&rndpool_mtx); 
846 if (entcnt >= RND_ENTROPY_THRESHOLD * 8) 
847 revents |= events & (POLLIN | POLLRDNORM); 
848 else 
849 selrecord(l, &rnd_selq); 
850 
851 return (revents); 
852} 
853 
854static void 
855filt_rnddetach(struct knote *kn) 
856{ 
857 mutex_spin_enter(&rndpool_mtx); 
858 SLIST_REMOVE(&rnd_selq.sel_klist, kn, knote, kn_selnext); 
859 mutex_spin_exit(&rndpool_mtx); 
860} 
861 
862static int 
863filt_rndread(struct knote *kn, long hint) 
864{ 
865 uint32_t entcnt; 
866 
867 mutex_spin_enter(&rndpool_mtx); 
868 entcnt = rndpool_get_entropy_count(&rnd_pool); 
869 mutex_spin_exit(&rndpool_mtx); 
870 if (entcnt >= RND_ENTROPY_THRESHOLD * 8) { 
871 kn->kn_data = RND_TEMP_BUFFER_SIZE; 
872 return (1); 
873 } 
874 return (0); 
875} 
876 
877static const struct filterops rnd_seltrue_filtops = 
878 { 1, NULL, filt_rnddetach, filt_seltrue }; 
879 
880static const struct filterops rndread_filtops = 
881 { 1, NULL, filt_rnddetach, filt_rndread }; 
882 
883int 
884rndkqfilter(dev_t dev, struct knote *kn) 
885{ 
886 struct klist *klist; 
887 
888 switch (kn->kn_filter) { 
889 case EVFILT_READ: 
890 klist = &rnd_selq.sel_klist; 
891 if (minor(dev) == RND_DEV_URANDOM) 
892 kn->kn_fop = &rnd_seltrue_filtops; 
893 else 
894 kn->kn_fop = &rndread_filtops; 
895 break; 
896 
897 case EVFILT_WRITE: 
898 klist = &rnd_selq.sel_klist; 
899 kn->kn_fop = &rnd_seltrue_filtops; 
900 break; 
901 
902 default: 
903 return (EINVAL); 
904 } 
905 
906 kn->kn_hook = NULL; 
907 
908 mutex_spin_enter(&rndpool_mtx); 
909 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 
910 mutex_spin_exit(&rndpool_mtx); 
911 
912 return (0); 
913} 
914 
915static rnd_sample_t * 384static rnd_sample_t *
916rnd_sample_allocate(krndsource_t *source) 385rnd_sample_allocate(krndsource_t *source)
917{ 386{
918 rnd_sample_t *c; 387 rnd_sample_t *c;
919 388
920 c = pool_get(&rnd_mempool, PR_WAITOK); 389 c = pool_cache_get(rnd_mempc, PR_WAITOK);
921 if (c == NULL) 390 if (c == NULL)
922 return (NULL); 391 return (NULL);
923 392
924 c->source = source; 393 c->source = source;
925 c->cursor = 0; 394 c->cursor = 0;
926 c->entropy = 0; 395 c->entropy = 0;
927 396
928 return (c); 397 return (c);
929} 398}
930 399
931/* 400/*
932 * Don't wait on allocation. To be used in an interrupt context. 401 * Don't wait on allocation. To be used in an interrupt context.
933 */ 402 */
934static rnd_sample_t * 403static rnd_sample_t *
935rnd_sample_allocate_isr(krndsource_t *source) 404rnd_sample_allocate_isr(krndsource_t *source)
936{ 405{
937 rnd_sample_t *c; 406 rnd_sample_t *c;
938 407
939 c = pool_get(&rnd_mempool, PR_NOWAIT); 408 c = pool_cache_get(rnd_mempc, PR_NOWAIT);
940 if (c == NULL) 409 if (c == NULL)
941 return (NULL); 410 return (NULL);
942 411
943 c->source = source; 412 c->source = source;
944 c->cursor = 0; 413 c->cursor = 0;
945 c->entropy = 0; 414 c->entropy = 0;
946 415
947 return (c); 416 return (c);
948} 417}
949 418
950static void 419static void
951rnd_sample_free(rnd_sample_t *c) 420rnd_sample_free(rnd_sample_t *c)
952{ 421{
953 memset(c, 0, sizeof(*c)); 422 memset(c, 0, sizeof(*c));
954 pool_put(&rnd_mempool, c); 423 pool_cache_put(rnd_mempc, c);
955} 424}
956 425
957/* 426/*
958 * Add a source to our list of sources. 427 * Add a source to our list of sources.
959 */ 428 */
960void 429void
961rnd_attach_source(krndsource_t *rs, const char *name, u_int32_t type, 430rnd_attach_source(krndsource_t *rs, const char *name, u_int32_t type,
962 u_int32_t flags) 431 u_int32_t flags)
963{ 432{
964 u_int32_t ts; 433 u_int32_t ts;
965 434
966 RUN_ONCE(&rnd_mempoolinit_ctrl, rnd_mempool_init); 
967 
968 ts = rnd_counter(); 435 ts = rnd_counter();
969 436
970 strlcpy(rs->name, name, sizeof(rs->name)); 437 strlcpy(rs->name, name, sizeof(rs->name));
971 rs->last_time = ts; 438 rs->last_time = ts;
972 rs->last_delta = 0; 439 rs->last_delta = 0;
973 rs->last_delta2 = 0; 440 rs->last_delta2 = 0;
974 rs->total = 0; 441 rs->total = 0;
975 442
976 /* 443 /*
977 * Force network devices to not collect any entropy by 444 * Force network devices to not collect any entropy by
978 * default. 445 * default.
979 */ 446 */
980 if (type == RND_TYPE_NET) 447 if (type == RND_TYPE_NET)
@@ -1204,36 +671,28 @@ rnd_hwrng_test(rnd_sample_t *sample) @@ -1204,36 +671,28 @@ rnd_hwrng_test(rnd_sample_t *sample)
1204 671
1205 /* 672 /*
1206 * Continuous-output test: compare two halves of the 673 * Continuous-output test: compare two halves of the
1207 * sample buffer to each other. The sample buffer (64 ints, 674 * sample buffer to each other. The sample buffer (64 ints,
1208 * so either 256 or 512 bytes on any modern machine) should be 675 * so either 256 or 512 bytes on any modern machine) should be
1209 * much larger than a typical hardware RNG output, so this seems 676 * much larger than a typical hardware RNG output, so this seems
1210 * a reasonable way to do it without retaining extra data. 677 * a reasonable way to do it without retaining extra data.
1211 */ 678 */
1212 cmplen = sizeof(sample->values) / 2; 679 cmplen = sizeof(sample->values) / 2;
1213 v1 = (uint8_t *)sample->values; 680 v1 = (uint8_t *)sample->values;
1214 v2 = (uint8_t *)sample->values + cmplen; 681 v2 = (uint8_t *)sample->values + cmplen;
1215 682
1216 if (__predict_false(!memcmp(v1, v2, cmplen))) { 683 if (__predict_false(!memcmp(v1, v2, cmplen))) {
1217 int *dump; 
1218 printf("rnd: source \"%s\" failed continuous-output test.\n", 684 printf("rnd: source \"%s\" failed continuous-output test.\n",
1219 source->name); 685 source->name);
1220 printf("rnd: bad buffer: "); 
1221 for (dump = (int *)sample->values; 
1222 dump < (int *)((uint8_t *)sample->values + 
1223 sizeof(sample->values)); dump += sizeof(int)) { 
1224 printf("%x ", *dump); 
1225 } 
1226 printf("\n"); 
1227 return 1; 686 return 1;
1228 } 687 }
1229 688
1230 /* 689 /*
1231 * FIPS 140 statistical RNG test. We must accumulate 20,000 bits. 690 * FIPS 140 statistical RNG test. We must accumulate 20,000 bits.
1232 */ 691 */
1233 if (__predict_true(source->test_cnt == -1)) { 692 if (__predict_true(source->test_cnt == -1)) {
1234 /* already passed the test */ 693 /* already passed the test */
1235 return 0; 694 return 0;
1236 } 695 }
1237 resid = FIPS140_RNG_TEST_BYTES - source->test_cnt; 696 resid = FIPS140_RNG_TEST_BYTES - source->test_cnt;
1238 totest = MIN(RND_SAMPLE_COUNT * 4, resid); 697 totest = MIN(RND_SAMPLE_COUNT * 4, resid);
1239 memcpy(source->test->rt_b + source->test_cnt, sample->values, totest); 698 memcpy(source->test->rt_b + source->test_cnt, sample->values, totest);
@@ -1355,84 +814,88 @@ rnd_process_events(void *arg) @@ -1355,84 +814,88 @@ rnd_process_events(void *arg)
1355} 814}
1356 815
1357/* 816/*
1358 * Timeout, run to process the events in the ring buffer. 817 * Timeout, run to process the events in the ring buffer.
1359 */ 818 */
1360static void 819static void
1361rnd_timeout(void *arg) 820rnd_timeout(void *arg)
1362{ 821{
1363 mutex_spin_enter(&rnd_mtx); 822 mutex_spin_enter(&rnd_mtx);
1364 rnd_timeout_pending = 0; 823 rnd_timeout_pending = 0;
1365 rnd_process_events(arg); 824 rnd_process_events(arg);
1366} 825}
1367 826
1368static u_int32_t 827u_int32_t
1369rnd_extract_data_locked(void *p, u_int32_t len, u_int32_t flags) 828rnd_extract_data_locked(void *p, u_int32_t len, u_int32_t flags)
1370{ 829{
1371 830
1372 KASSERT(mutex_owned(&rndpool_mtx)); 831 KASSERT(mutex_owned(&rndpool_mtx));
1373 if (!rnd_have_entropy) { 832 if (!rnd_have_entropy) {
1374 u_int32_t c; 833 u_int32_t c;
1375 834
1376#ifdef RND_VERBOSE 835#ifdef RND_VERBOSE
1377 printf("rnd: WARNING! initial entropy low (%u).\n", 836 printf("rnd: WARNING! initial entropy low (%u).\n",
1378 rndpool_get_entropy_count(&rnd_pool)); 837 rndpool_get_entropy_count(&rnd_pool));
1379#endif 838#endif
1380 /* Try once again to put something in the pool */ 839 /* Try once again to put something in the pool */
1381 c = rnd_counter(); 840 c = rnd_counter();
1382 rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1); 841 rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
1383 } 842 }
1384 if (!rnd_tested) { 843
1385 rngtest_t rt; 844#ifdef DIAGNOSTIC
1386 uint8_t testbits[sizeof(rt.rt_b)]; 845 while (!rnd_tested) {
1387 int entropy_count; 846 int entropy_count;
1388 847
1389 entropy_count = rndpool_get_entropy_count(&rnd_pool); 848 entropy_count = rndpool_get_entropy_count(&rnd_pool);
1390#ifdef RND_VERBOSE 849#ifdef RND_VERBOSE
1391 printf("rnd: starting statistical RNG test, entropy = %d.\n", 850 printf("rnd: starting statistical RNG test, entropy = %d.\n",
1392 entropy_count); 851 entropy_count);
1393#endif 852#endif
1394 if (rndpool_extract_data(&rnd_pool, rt.rt_b, 853 if (rndpool_extract_data(&rnd_pool, rnd_rt.rt_b,
1395 sizeof(rt.rt_b), RND_EXTRACT_ANY) != sizeof(rt.rt_b)) { 854 sizeof(rnd_rt.rt_b), RND_EXTRACT_ANY)
 855 != sizeof(rnd_rt.rt_b)) {
1396 panic("rnd: could not get bits for statistical test"); 856 panic("rnd: could not get bits for statistical test");
1397 } 857 }
1398 /* 858 /*
1399 * Stash the tested bits so we can put them back in the 859 * Stash the tested bits so we can put them back in the
1400 * pool, restoring the entropy count. DO NOT rely on 860 * pool, restoring the entropy count. DO NOT rely on
1401 * rngtest to maintain the bits pristine -- we could end 861 * rngtest to maintain the bits pristine -- we could end
1402 * up adding back non-random data claiming it were pure 862 * up adding back non-random data claiming it were pure
1403 * entropy. 863 * entropy.
1404 */ 864 */
1405 memcpy(testbits, rt.rt_b, sizeof(rt.rt_b)); 865 memcpy(rnd_testbits, rnd_rt.rt_b, sizeof(rnd_rt.rt_b));
1406 strlcpy(rt.rt_name, "entropy pool", sizeof(rt.rt_name)); 866 strlcpy(rnd_rt.rt_name, "entropy pool", sizeof(rnd_rt.rt_name));
1407 if (rngtest(&rt)) { 867 if (rngtest(&rnd_rt)) {
1408 /* 868 /*
1409 * The probabiliity of a Type I error is 3/10000, 869 * The probabiliity of a Type I error is 3/10000,
1410 * but note this can only happen at boot time. 870 * but note this can only happen at boot time.
1411 * The relevant standard says to reset the module, 871 * The relevant standard says to reset the module,
1412 * so that's what we do. 872 * but developers objected...
1413 */ 873 */
1414 panic("rnd: entropy pool failed statistical test"); 874 printf("rnd: WARNING, ENTROPY POOL FAILED "
 875 "STATISTICAL TEST!\n");
 876 continue;
1415 } 877 }
1416 memset(&rt, 0, sizeof(rt)); 878 memset(&rnd_rt, 0, sizeof(rnd_rt));
1417 rndpool_add_data(&rnd_pool, testbits, sizeof(testbits), 879 rndpool_add_data(&rnd_pool, rnd_testbits, sizeof(rnd_testbits),
1418 entropy_count); 880 entropy_count);
1419 memset(testbits, 0, sizeof(testbits)); 881 memset(rnd_testbits, 0, sizeof(rnd_testbits));
1420#ifdef RND_VERBOSE 882#ifdef RND_VERBOSE
1421 printf("rnd: statistical RNG test done, entropy = %d.\n", 883 printf("rnd: statistical RNG test done, entropy = %d.\n",
1422 rndpool_get_entropy_count(&rnd_pool)); 884 rndpool_get_entropy_count(&rnd_pool));
1423#endif 885#endif
1424 rnd_tested++; 886 rnd_tested++;
1425 } 887 }
 888#endif
1426 return rndpool_extract_data(&rnd_pool, p, len, flags); 889 return rndpool_extract_data(&rnd_pool, p, len, flags);
1427} 890}
1428 891
1429u_int32_t 892u_int32_t
1430rnd_extract_data(void *p, u_int32_t len, u_int32_t flags) 893rnd_extract_data(void *p, u_int32_t len, u_int32_t flags)
1431{ 894{
1432 uint32_t retval; 895 uint32_t retval;
1433 896
1434 mutex_spin_enter(&rndpool_mtx); 897 mutex_spin_enter(&rndpool_mtx);
1435 retval = rnd_extract_data_locked(p, len, flags); 898 retval = rnd_extract_data_locked(p, len, flags);
1436 mutex_spin_exit(&rndpool_mtx); 899 mutex_spin_exit(&rndpool_mtx);
1437 return retval; 900 return retval;
1438} 901}

cvs diff -r1.21 -r1.22 src/sys/dev/Attic/rndpool.c (expand / switch to unified diff)

--- src/sys/dev/Attic/rndpool.c 2011/11/29 03:50:31 1.21
+++ src/sys/dev/Attic/rndpool.c 2011/12/17 20:05:38 1.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rndpool.c,v 1.21 2011/11/29 03:50:31 tls Exp $ */ 1/* $NetBSD: rndpool.c,v 1.22 2011/12/17 20:05:38 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org>. This code uses ideas and 8 * by Michael Graff <explorer@flame.org>. This code uses ideas and
9 * algorithms from the Linux driver written by Ted Ts'o. 9 * algorithms from the Linux driver written by Ted Ts'o.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -21,44 +21,49 @@ @@ -21,44 +21,49 @@
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: rndpool.c,v 1.21 2011/11/29 03:50:31 tls Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: rndpool.c,v 1.22 2011/12/17 20:05:38 tls Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/sha1.h> 38#include <sys/sha1.h>
39 39
40#include <sys/rnd.h> 40#include <sys/rnd.h>
41#include <dev/rnd_private.h> 41#include <dev/rnd_private.h>
42 42
43/* 43/*
44 * The random pool "taps" 44 * The random pool "taps"
45 */ 45 */
46#define TAP1 99 46#define TAP1 99
47#define TAP2 59 47#define TAP2 59
48#define TAP3 31 48#define TAP3 31
49#define TAP4 9 49#define TAP4 9
50#define TAP5 7 50#define TAP5 7
51 51
 52/*
 53 * Let others know: the pool is full.
 54 */
 55int rnd_full;
 56
52static inline void rndpool_add_one_word(rndpool_t *, u_int32_t); 57static inline void rndpool_add_one_word(rndpool_t *, u_int32_t);
53 58
54void 59void
55rndpool_init(rndpool_t *rp) 60rndpool_init(rndpool_t *rp)
56{ 61{
57 62
58 rp->cursor = 0; 63 rp->cursor = 0;
59 rp->rotate = 1; 64 rp->rotate = 1;
60 65
61 memset(&rp->stats, 0, sizeof(rp->stats)); 66 memset(&rp->stats, 0, sizeof(rp->stats));
62 67
63 rp->stats.curentropy = 0; 68 rp->stats.curentropy = 0;
64 rp->stats.poolsize = RND_POOLWORDS; 69 rp->stats.poolsize = RND_POOLWORDS;
@@ -163,45 +168,26 @@ rndpool_add_one_word(rndpool_t *rp, u_in @@ -163,45 +168,26 @@ rndpool_add_one_word(rndpool_t *rp, u_in
163 rp->pool[rp->cursor++] ^= val; 168 rp->pool[rp->cursor++] ^= val;
164 169
165 /* 170 /*
166 * If we have looped around the pool, increment the rotate 171 * If we have looped around the pool, increment the rotate
167 * variable so the next value will get xored in rotated to 172 * variable so the next value will get xored in rotated to
168 * a different position. 173 * a different position.
169 */ 174 */
170 if (rp->cursor == RND_POOLWORDS) { 175 if (rp->cursor == RND_POOLWORDS) {
171 rp->cursor = 0; 176 rp->cursor = 0;
172 rp->rotate = (rp->rotate + 7) & 31; 177 rp->rotate = (rp->rotate + 7) & 31;
173 } 178 }
174} 179}
175 180
176#if 0 
177/* 
178 * Stir a 32-bit value (with possibly less entropy than that) into the pool. 
179 * Update entropy estimate. 
180 */ 
181void 
182rndpool_add_uint32(rndpool_t *rp, u_int32_t val, u_int32_t entropy) 
183{ 
184 rndpool_add_one_word(rp, val); 
185 
186 rp->entropy += entropy; 
187 rp->stats.added += entropy; 
188 if (rp->entropy > RND_POOLBITS) { 
189 rp->stats.discarded += (rp->entropy - RND_POOLBITS); 
190 rp->entropy = RND_POOLBITS; 
191 } 
192} 
193#endif 
194 
195/* 181/*
196 * Add a buffer's worth of data to the pool. 182 * Add a buffer's worth of data to the pool.
197 */ 183 */
198void 184void
199rndpool_add_data(rndpool_t *rp, void *p, u_int32_t len, u_int32_t entropy) 185rndpool_add_data(rndpool_t *rp, void *p, u_int32_t len, u_int32_t entropy)
200{ 186{
201 u_int32_t val; 187 u_int32_t val;
202 u_int8_t *buf; 188 u_int8_t *buf;
203 189
204 buf = p; 190 buf = p;
205 191
206 for (; len > 3; len -= 4) { 192 for (; len > 3; len -= 4) {
207 val = *((u_int32_t *)buf); 193 val = *((u_int32_t *)buf);
@@ -220,26 +206,27 @@ rndpool_add_data(rndpool_t *rp, void *p, @@ -220,26 +206,27 @@ rndpool_add_data(rndpool_t *rp, void *p,
220 case 1: 206 case 1:
221 val = val << 8 | *buf++; 207 val = val << 8 | *buf++;
222 } 208 }
223 209
224 rndpool_add_one_word(rp, val); 210 rndpool_add_one_word(rp, val);
225 } 211 }
226 212
227 rp->stats.curentropy += entropy; 213 rp->stats.curentropy += entropy;
228 rp->stats.added += entropy; 214 rp->stats.added += entropy;
229 215
230 if (rp->stats.curentropy > RND_POOLBITS) { 216 if (rp->stats.curentropy > RND_POOLBITS) {
231 rp->stats.discarded += (rp->stats.curentropy - RND_POOLBITS); 217 rp->stats.discarded += (rp->stats.curentropy - RND_POOLBITS);
232 rp->stats.curentropy = RND_POOLBITS; 218 rp->stats.curentropy = RND_POOLBITS;
 219 rnd_full = 1;
233 } 220 }
234} 221}
235 222
236/* 223/*
237 * Extract some number of bytes from the random pool, decreasing the 224 * Extract some number of bytes from the random pool, decreasing the
238 * estimate of randomness as each byte is extracted. 225 * estimate of randomness as each byte is extracted.
239 * 226 *
240 * Do this by hashing the pool and returning a part of the hash as 227 * Do this by hashing the pool and returning a part of the hash as
241 * randomness. Stir the hash back into the pool. Note that no 228 * randomness. Stir the hash back into the pool. Note that no
242 * secrets going back into the pool are given away here since parts of 229 * secrets going back into the pool are given away here since parts of
243 * the hash are xored together before being returned. 230 * the hash are xored together before being returned.
244 * 231 *
245 * Honor the request from the caller to only return good data, any data, 232 * Honor the request from the caller to only return good data, any data,
@@ -249,26 +236,28 @@ rndpool_add_data(rndpool_t *rp, void *p, @@ -249,26 +236,28 @@ rndpool_add_data(rndpool_t *rp, void *p,
249u_int32_t 236u_int32_t
250rndpool_extract_data(rndpool_t *rp, void *p, u_int32_t len, u_int32_t mode) 237rndpool_extract_data(rndpool_t *rp, void *p, u_int32_t len, u_int32_t mode)
251{ 238{
252 u_int i; 239 u_int i;
253 SHA1_CTX hash; 240 SHA1_CTX hash;
254 u_char digest[SHA1_DIGEST_LENGTH]; 241 u_char digest[SHA1_DIGEST_LENGTH];
255 u_int32_t remain, deltae, count; 242 u_int32_t remain, deltae, count;
256 u_int8_t *buf; 243 u_int8_t *buf;
257 int good; 244 int good;
258 245
259 buf = p; 246 buf = p;
260 remain = len; 247 remain = len;
261 248
 249 rnd_full = 0;
 250
262 if (mode == RND_EXTRACT_ANY) 251 if (mode == RND_EXTRACT_ANY)
263 good = 1; 252 good = 1;
264 else 253 else
265 good = (rp->stats.curentropy >= (8 * RND_ENTROPY_THRESHOLD)); 254 good = (rp->stats.curentropy >= (8 * RND_ENTROPY_THRESHOLD));
266 255
267 KASSERT(RND_ENTROPY_THRESHOLD * 2 <= sizeof(digest)); 256 KASSERT(RND_ENTROPY_THRESHOLD * 2 <= sizeof(digest));
268 257
269 while (good && (remain != 0)) { 258 while (good && (remain != 0)) {
270 /* 259 /*
271 * While bytes are requested, compute the hash of the pool, 260 * While bytes are requested, compute the hash of the pool,
272 * and then "fold" the hash in half with XOR, keeping the 261 * and then "fold" the hash in half with XOR, keeping the
273 * exact hash value secret, as it will be stirred back into 262 * exact hash value secret, as it will be stirred back into
274 * the pool. 263 * the pool.

File Added: src/sys/dev/Attic/rndpseudo.c
/*	$NetBSD: rndpseudo.c,v 1.1 2011/12/17 20:05:39 tls Exp $	*/

/*-
 * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.1 2011/12/17 20:05:39 tls Exp $");

#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/select.h>
#include <sys/poll.h>
#include <sys/kmem.h>
#include <sys/atomic.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/rnd.h>
#include <sys/vnode.h>
#include <sys/pool.h>
#include <sys/kauth.h>
#include <sys/cprng.h>
#include <sys/stat.h>

#include <dev/rnd_private.h>

#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */
#include <machine/cpu_counter.h>
#endif

#ifdef RND_DEBUG
#define	DPRINTF(l,x)      if (rnd_debug & (l)) printf x
int	rnd_debug = 0;
#else
#define	DPRINTF(l,x)
#endif

#define	RND_DEBUG_WRITE		0x0001
#define	RND_DEBUG_READ		0x0002
#define	RND_DEBUG_IOCTL		0x0004
#define	RND_DEBUG_SNOOZE	0x0008

/*
 * list devices attached
 */
#if 0
#define	RND_VERBOSE
#endif

/*
 * The size of a temporary buffer, kmem_alloc()ed when needed, and used for
 * reading and writing data.
 */
#define	RND_TEMP_BUFFER_SIZE	512

static pool_cache_t rp_pc;
static pool_cache_t rp_cpc;

/*
 * A context.  cprng plus a smidge.
 */
typedef struct {
	cprng_strong_t	*cprng;
	int		hard;
	int		bytesonkey;
	kmutex_t	interlock;
} rp_ctx_t;

/*
 * Our random pool.  This is defined here rather than using the general
 * purpose one defined in rndpool.c.
 *
 * Samples are collected and queued into a separate mutex-protected queue
 * (rnd_samples, see above), and processed in a timeout routine; therefore,
 * the mutex protecting the random pool is at IPL_SOFTCLOCK() as well.
 */
extern rndpool_t rnd_pool;
extern kmutex_t  rndpool_mtx;

void	rndattach(int);

dev_type_open(rndopen);

const struct cdevsw rnd_cdevsw = {
	rndopen, noclose, noread, nowrite, noioctl, nostop,
	notty, nopoll, nommap, nokqfilter, D_OTHER|D_MPSAFE
};

static int rnd_read(struct file *, off_t *, struct uio *, kauth_cred_t, int);
static int rnd_write(struct file *, off_t *, struct uio *, kauth_cred_t, int);
static int rnd_ioctl(struct file *, u_long, void *);
static int rnd_poll(struct file *, int);
static int rnd_stat(struct file *, struct stat *);
static int rnd_close(struct file *);
static int rnd_kqfilter(struct file *, struct knote *);

const struct fileops rnd_fileops = {
	.fo_read = rnd_read,
	.fo_write = rnd_write,
	.fo_ioctl = rnd_ioctl,
	.fo_fcntl = fnullop_fcntl,
	.fo_poll = rnd_poll,
	.fo_stat = rnd_stat,
	.fo_close = rnd_close,
	.fo_kqfilter = rnd_kqfilter,
	.fo_restart = fnullop_restart
};

void			rnd_wakeup_readers(void);	/* XXX */
extern int		rnd_ready;		/* XXX */
extern rndsave_t	*boot_rsp;		/* XXX */
extern LIST_HEAD(, krndsource) rnd_sources;	/* XXX */

/*
 * Generate a 32-bit counter.  This should be more machine dependent,
 * using cycle counters and the like when possible.
 */
static inline u_int32_t
rndpseudo_counter(void)
{
	struct timeval tv;

#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */
	if (cpu_hascounter())
		return (cpu_counter32());
#endif
	microtime(&tv);
	return (tv.tv_sec * 1000000 + tv.tv_usec);
}

/*
 * "Attach" the random device. This is an (almost) empty stub, since
 * pseudo-devices don't get attached until after config, after the
 * entropy sources will attach. We just use the timing of this event
 * as another potential source of initial entropy.
 */
void
rndattach(int num)
{
	u_int32_t c;

	/* Trap unwary players who don't call rnd_init() early */
	KASSERT(rnd_ready);

	rp_pc = pool_cache_init(RND_TEMP_BUFFER_SIZE, 0, 0, 0,
				"rndtemp", NULL, IPL_NONE,
				NULL, NULL, NULL);
	rp_cpc = pool_cache_init(sizeof(rp_ctx_t), 0, 0, 0,
				 "rndctx", NULL, IPL_NONE,
				 NULL, NULL, NULL);

	/* mix in another counter */
	c = rndpseudo_counter();
	mutex_spin_enter(&rndpool_mtx);
	rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
	mutex_spin_exit(&rndpool_mtx);
}

int
rndopen(dev_t dev, int flag, int ifmt,
    struct lwp *l)
{
	rp_ctx_t *ctx;
	file_t *fp;
	int fd, hard, error = 0;

	switch (minor(dev)) {
	    case RND_DEV_URANDOM:
		hard = 0;
		break;
	    case RND_DEV_RANDOM:
		hard = 1;
		break;
	    default:
		return ENXIO;
	}
	ctx = pool_cache_get(rp_cpc, PR_WAITOK);
	ctx->cprng = NULL;
	ctx->hard = hard;
	mutex_init(&ctx->interlock, MUTEX_DEFAULT, IPL_NONE);
	
	if ((error = fd_allocfile(&fp, &fd)) != 0) {
	    pool_cache_put(rp_cpc, ctx);
	    return error;
	}

	return fd_clone(fp, fd, flag, &rnd_fileops, ctx);
}

static void
rnd_alloc_cprng(rp_ctx_t *ctx)
{
	char personalization_buf[64];
	struct lwp *l = curlwp;
	int cflags = ctx->hard ? CPRNG_USE_CV :
				 CPRNG_INIT_ANY|CPRNG_REKEY_ANY;

	mutex_enter(&ctx->interlock);
	if (__predict_true(ctx->cprng == NULL)) {
		snprintf(personalization_buf,
			 sizeof(personalization_buf),
	 		 "%d%llud%d", l->l_proc->p_pid,
	 		 (unsigned long long int)l->l_ncsw, l->l_cpticks);
		ctx->cprng = cprng_strong_create(personalization_buf,
						 IPL_NONE, cflags);
	}
	membar_sync();
	mutex_exit(&ctx->interlock);
}

static int
rnd_read(struct file * fp, off_t *offp, struct uio *uio,
	  kauth_cred_t cred, int flags)
{
	rp_ctx_t *ctx = fp->f_data;
	u_int8_t *bf;
	int strength, ret;

	DPRINTF(RND_DEBUG_READ,
	    ("Random:  Read of %zu requested, flags 0x%08x\n",
	    uio->uio_resid, ioflag));

	if (uio->uio_resid == 0)
		return (0);

	if (ctx->cprng == NULL) {
		rnd_alloc_cprng(ctx);
		if (__predict_false(ctx->cprng == NULL)) {
			return EIO;
		}
        }

	strength = cprng_strong_strength(ctx->cprng);
	ret = 0;
	bf = pool_cache_get(rp_pc, PR_WAITOK);
	while (uio->uio_resid > 0) {
		int n, nread, want;

		want = MIN(RND_TEMP_BUFFER_SIZE, uio->uio_resid);

		/* XXX is this _really_ what's wanted? */
		if (ctx->hard) {
			n = MIN(want, strength - ctx->bytesonkey);
			ctx->bytesonkey += n;
		} else {
			n = want;
		}

		nread = cprng_strong(ctx->cprng, bf, n,
				     (fp->f_flag & FNONBLOCK) ? FNONBLOCK : 0);
		if (nread != n) {
			if (fp->f_flag & FNONBLOCK) {
				ret = EWOULDBLOCK;
			} else {
				ret = EINTR;
			}
			goto out;
		}
		ret = uiomove((void *)bf, nread, uio);
		if (ret != 0 || n < want) {
			goto out;
		}
	}
out:
	if (ctx->bytesonkey >= strength) {
		/* Force reseed of underlying DRBG (prediction resistance) */
		cprng_strong_deplete(ctx->cprng);
		ctx->bytesonkey = 0;
	}
	pool_cache_put(rp_pc, bf);
	return (ret);
}

static int
rnd_write(struct file *fp, off_t *offp, struct uio *uio,
	   kauth_cred_t cred, int flags)
{
	u_int8_t *bf;
	int n, ret = 0, estimate_ok = 0, estimate = 0, added = 0;

	ret = kauth_authorize_device(cred,
	    KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL);
	if (ret) {
		return (ret);
	}
	estimate_ok = !kauth_authorize_device(cred,
	    KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL);

	DPRINTF(RND_DEBUG_WRITE,
	    ("Random: Write of %zu requested\n", uio->uio_resid));

	if (uio->uio_resid == 0)
		return (0);
	ret = 0;
	bf = pool_cache_get(rp_pc, PR_WAITOK);
	while (uio->uio_resid > 0) {
		/*
		 * Don't flood the pool.
		 */
		if (added > RND_POOLWORDS * sizeof(int)) {
#ifdef RND_VERBOSE
			printf("rnd: added %d already, adding no more.\n",
			       added);
#endif
			break;
		}
		n = min(RND_TEMP_BUFFER_SIZE, uio->uio_resid);

		ret = uiomove((void *)bf, n, uio);
		if (ret != 0)
			break;

		if (estimate_ok) {
			/*
			 * Don't cause samples to be discarded by taking
			 * the pool's entropy estimate to the max.
			 */
			if (added > RND_POOLWORDS / 2)
				estimate = 0;
			else
				estimate = n * NBBY / 2;
#ifdef RND_VERBOSE
			printf("rnd: adding on write, %d bytes, estimate %d\n",
			       n, estimate);
#endif
		} else {
#ifdef RND_VERBOSE
			printf("rnd: kauth says no entropy.\n");
#endif
		}

		/*
		 * Mix in the bytes.
		 */
		mutex_spin_enter(&rndpool_mtx);
		rndpool_add_data(&rnd_pool, bf, n, estimate);
		mutex_spin_exit(&rndpool_mtx);

		added += n;
		DPRINTF(RND_DEBUG_WRITE, ("Random: Copied in %d bytes\n", n));
	}
	pool_cache_put(rp_pc, bf);
	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
rnd_ioctl(struct file *fp, u_long cmd, void *addr)
{
	krndsource_t *kr;
	rndstat_t *rst;
	rndstat_name_t *rstnm;
	rndctl_t *rctl;
	rnddata_t *rnddata;
	u_int32_t count, start;
	int ret = 0;
	int estimate_ok = 0, estimate = 0;

	switch (cmd) {
	case FIONBIO:
	case FIOASYNC:
	case RNDGETENTCNT:
		break;

	case RNDGETPOOLSTAT:
	case RNDGETSRCNUM:
	case RNDGETSRCNAME:
		ret = kauth_authorize_device(curlwp->l_cred,
		    KAUTH_DEVICE_RND_GETPRIV, NULL, NULL, NULL, NULL);
		if (ret)
			return (ret);
		break;

	case RNDCTL:
		ret = kauth_authorize_device(curlwp->l_cred,
		    KAUTH_DEVICE_RND_SETPRIV, NULL, NULL, NULL, NULL);
		if (ret)
			return (ret);
		break;

	case RNDADDDATA:
		ret = kauth_authorize_device(curlwp->l_cred,
		    KAUTH_DEVICE_RND_ADDDATA, NULL, NULL, NULL, NULL);
		if (ret)
			return (ret);
		estimate_ok = !kauth_authorize_device(curlwp->l_cred,
		    KAUTH_DEVICE_RND_ADDDATA_ESTIMATE, NULL, NULL, NULL, NULL);
		break;

	default:
		return (EINVAL);
	}

	switch (cmd) {

	/*
	 * Handled in upper layer really, but we have to return zero
	 * for it to be accepted by the upper layer.
	 */
	case FIONBIO:
	case FIOASYNC:
		break;

	case RNDGETENTCNT:
		mutex_spin_enter(&rndpool_mtx);
		*(u_int32_t *)addr = rndpool_get_entropy_count(&rnd_pool);
		mutex_spin_exit(&rndpool_mtx);
		break;

	case RNDGETPOOLSTAT:
		mutex_spin_enter(&rndpool_mtx);
		rndpool_get_stats(&rnd_pool, addr, sizeof(rndpoolstat_t));
		mutex_spin_exit(&rndpool_mtx);
		break;

	case RNDGETSRCNUM:
		rst = (rndstat_t *)addr;

		if (rst->count == 0)
			break;

		if (rst->count > RND_MAXSTATCOUNT)
			return (EINVAL);

		mutex_spin_enter(&rndpool_mtx);
		/*
		 * Find the starting source by running through the
		 * list of sources.
		 */
		kr = rnd_sources.lh_first;
		start = rst->start;
		while (kr != NULL && start >= 1) {
			kr = kr->list.le_next;
			start--;
		}

		/*
		 * Return up to as many structures as the user asked
		 * for.  If we run out of sources, a count of zero
		 * will be returned, without an error.
		 */
		for (count = 0; count < rst->count && kr != NULL; count++) {
			krndsource_to_rndsource(kr, &rst->source[count]);
			kr = kr->list.le_next;
		}

		rst->count = count;

		mutex_spin_exit(&rndpool_mtx);
		break;

	case RNDGETSRCNAME:
		/*
		 * Scan through the list, trying to find the name.
		 */
		mutex_spin_enter(&rndpool_mtx);
		rstnm = (rndstat_name_t *)addr;
		kr = rnd_sources.lh_first;
		while (kr != NULL) {
			if (strncmp(kr->name, rstnm->name,
				    MIN(sizeof(kr->name),
					sizeof(*rstnm))) == 0) {
				krndsource_to_rndsource(kr, &rstnm->source);
				mutex_spin_exit(&rndpool_mtx);
				return (0);
			}
			kr = kr->list.le_next;
		}
		mutex_spin_exit(&rndpool_mtx);

		ret = ENOENT;		/* name not found */

		break;

	case RNDCTL:
		/*
		 * Set flags to enable/disable entropy counting and/or
		 * collection.
		 */
		mutex_spin_enter(&rndpool_mtx);
		rctl = (rndctl_t *)addr;
		kr = rnd_sources.lh_first;

		/*
		 * Flags set apply to all sources of this type.
		 */
		if (rctl->type != 0xff) {
			while (kr != NULL) {
				if (kr->type == rctl->type) {
					kr->flags &= ~rctl->mask;
					kr->flags |=
					    (rctl->flags & rctl->mask);
				}
				kr = kr->list.le_next;
			}
			mutex_spin_exit(&rndpool_mtx);
			return (0);
		}

		/*
		 * scan through the list, trying to find the name
		 */
		while (kr != NULL) {
			if (strncmp(kr->name, rctl->name,
				    MIN(sizeof(kr->name),
                                        sizeof(rctl->name))) == 0) {
				kr->flags &= ~rctl->mask;
				kr->flags |= (rctl->flags & rctl->mask);
				
				mutex_spin_exit(&rndpool_mtx);
				return (0);
			}
			kr = kr->list.le_next;
		}

		mutex_spin_exit(&rndpool_mtx);
		ret = ENOENT;		/* name not found */
		
		break;

	case RNDADDDATA:
		/*
		 * Don't seed twice if our bootloader has
		 * seed loading support.
		 */
		if (!boot_rsp) {
			rnddata = (rnddata_t *)addr;

			if (rnddata->len > sizeof(rnddata->data))
				return EINVAL;

			if (estimate_ok) {
				/*
				 * Do not accept absurd entropy estimates, and
				 * do not flood the pool with entropy such that
				 * new samples are discarded henceforth.
				 */
				estimate = MIN((rnddata->len * NBBY) / 2,
					       MIN(rnddata->entropy,
						   RND_POOLBITS / 2));
			} else {
				estimate = 0;
			}

			mutex_spin_enter(&rndpool_mtx);
			rndpool_add_data(&rnd_pool, rnddata->data,
					 rnddata->len, estimate);
			mutex_spin_exit(&rndpool_mtx);

			rnd_wakeup_readers();
		}
#ifdef RND_VERBOSE
		else {
			printf("rnd: already seeded by boot loader\n");
		}
#endif
		break;

	default:
		return (EINVAL);
	}

	return (ret);
}

static int
rnd_poll(struct file *fp, int events)
{
	int revents;
	rp_ctx_t *ctx = fp->f_data;

	/*
	 * We are always writable.
	 */
	revents = events & (POLLOUT | POLLWRNORM);

	/*
	 * Save some work if not checking for reads.
	 */
	if ((events & (POLLIN | POLLRDNORM)) == 0)
		return (revents);

	if (ctx->cprng == NULL) {
		rnd_alloc_cprng(ctx);
		if (__predict_false(ctx->cprng == NULL)) {
			return EIO;
		}       
	}

	if (cprng_strong_ready(ctx->cprng)) {
		revents |= events & (POLLIN | POLLRDNORM);
	} else {
		mutex_enter(&ctx->cprng->mtx);
		selrecord(curlwp, &ctx->cprng->selq);
		mutex_exit(&ctx->cprng->mtx);
	}

	return (revents);
}

static int
rnd_stat(struct file *fp, struct stat *st)
{
	rp_ctx_t *ctx = fp->f_data;

	/* XXX lock, if cprng allocated?  why? */
	memset(st, 0, sizeof(*st));
	st->st_dev = makedev(cdevsw_lookup_major(&rnd_cdevsw),
						 ctx->hard ? RND_DEV_RANDOM :
						 RND_DEV_URANDOM);
	/* XXX leave atimespect, mtimespec, ctimespec = 0? */

	st->st_uid = kauth_cred_geteuid(fp->f_cred);
	st->st_gid = kauth_cred_getegid(fp->f_cred);
	st->st_mode = S_IFCHR;
	return 0;
}

static int
rnd_close(struct file *fp)
{
	rp_ctx_t *ctx = fp->f_data;

	if (ctx->cprng) {
		cprng_strong_destroy(ctx->cprng);
	}
	fp->f_data = NULL;
	mutex_destroy(&ctx->interlock);
	pool_cache_put(rp_cpc, ctx);

	return 0;
}

static void
filt_rnddetach(struct knote *kn)
{
	cprng_strong_t *c = kn->kn_hook;

	mutex_enter(&c->mtx);
	SLIST_REMOVE(&c->selq.sel_klist, kn, knote, kn_selnext);
	mutex_exit(&c->mtx);
}

static int
filt_rndread(struct knote *kn, long hint)
{
	cprng_strong_t *c = kn->kn_hook;

	if (cprng_strong_ready(c)) {
		kn->kn_data = RND_TEMP_BUFFER_SIZE;
		return 1;
	}
	return 0;
}

static const struct filterops rnd_seltrue_filtops =
	{ 1, NULL, filt_rnddetach, filt_seltrue };

static const struct filterops rndread_filtops =
	{ 1, NULL, filt_rnddetach, filt_rndread };

static int
rnd_kqfilter(struct file *fp, struct knote *kn)
{
	rp_ctx_t *ctx = fp->f_data;
	struct klist *klist;

	if (ctx->cprng == NULL) {
		rnd_alloc_cprng(ctx);
		if (__predict_false(ctx->cprng == NULL)) {
			return EIO;
		}
	}

	mutex_enter(&ctx->cprng->mtx);
	switch (kn->kn_filter) {
	case EVFILT_READ:
		klist = &ctx->cprng->selq.sel_klist;
		kn->kn_fop = &rndread_filtops;
		break;

	case EVFILT_WRITE:
		klist = &ctx->cprng->selq.sel_klist;
		kn->kn_fop = &rnd_seltrue_filtops;
		break;

	default:
		mutex_exit(&ctx->cprng->mtx);
		return EINVAL;
	}

	kn->kn_hook = ctx->cprng;

	SLIST_INSERT_HEAD(klist, kn, kn_selnext);

	mutex_exit(&ctx->cprng->mtx);
	return (0);
}

cvs diff -r1.2 -r1.3 src/sys/dev/iscsi/iscsi_text.c (expand / switch to unified diff)

--- src/sys/dev/iscsi/iscsi_text.c 2011/11/29 03:50:31 1.2
+++ src/sys/dev/iscsi/iscsi_text.c 2011/12/17 20:05:39 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: iscsi_text.c,v 1.2 2011/11/29 03:50:31 tls Exp $ */ 1/* $NetBSD: iscsi_text.c,v 1.3 2011/12/17 20:05:39 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc. 8 * by Wasabi Systems, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -1449,27 +1449,27 @@ assemble_security_parameters(connection_ @@ -1449,27 +1449,27 @@ assemble_security_parameters(connection_
1449 1449
1450 cpar = set_key_s(state, K_Auth_CHAP_Response, state->temp_buf); 1450 cpar = set_key_s(state, K_Auth_CHAP_Response, state->temp_buf);
1451 if (cpar != NULL) 1451 if (cpar != NULL)
1452 cpar->list_num = CHAP_MD5_SIZE; 1452 cpar->list_num = CHAP_MD5_SIZE;
1453 1453
1454 if (par->auth_info.mutual_auth) { 1454 if (par->auth_info.mutual_auth) {
1455 if (!state->target_password[0]) { 1455 if (!state->target_password[0]) {
1456 DEBOUT(("No target password with mutual authentication!\n")); 1456 DEBOUT(("No target password with mutual authentication!\n"));
1457 return ISCSI_STATUS_PARAMETER_MISSING; 1457 return ISCSI_STATUS_PARAMETER_MISSING;
1458 } 1458 }
1459 1459
1460 cprng_strong(kern_cprng, 1460 cprng_strong(kern_cprng,
1461 &state->temp_buf[CHAP_MD5_SIZE], 1461 &state->temp_buf[CHAP_MD5_SIZE],
1462 CHAP_CHALLENGE_LEN + 1); 1462 CHAP_CHALLENGE_LEN + 1, 0);
1463 set_key_n(state, K_Auth_CHAP_Identifier, 1463 set_key_n(state, K_Auth_CHAP_Identifier,
1464 state->temp_buf[CHAP_MD5_SIZE]); 1464 state->temp_buf[CHAP_MD5_SIZE]);
1465 cpar = set_key_s(state, K_Auth_CHAP_Challenge, 1465 cpar = set_key_s(state, K_Auth_CHAP_Challenge,
1466 &state->temp_buf[CHAP_MD5_SIZE + 1]); 1466 &state->temp_buf[CHAP_MD5_SIZE + 1]);
1467 if (cpar != NULL) 1467 if (cpar != NULL)
1468 cpar->list_num = CHAP_CHALLENGE_LEN; 1468 cpar->list_num = CHAP_CHALLENGE_LEN;
1469 next = -1; 1469 next = -1;
1470 } 1470 }
1471 state->auth_state = AUTH_CHAP_RSP_SENT; 1471 state->auth_state = AUTH_CHAP_RSP_SENT;
1472 break; 1472 break;
1473 1473
1474 case AUTH_CHAP_RSP_SENT: 1474 case AUTH_CHAP_RSP_SENT:
1475 /* we can only be here for mutual authentication */ 1475 /* we can only be here for mutual authentication */

cvs diff -r1.3 -r1.4 src/sys/dist/pf/netinet/tcp_rndiss.c (expand / switch to unified diff)

--- src/sys/dist/pf/netinet/tcp_rndiss.c 2011/11/19 22:51:24 1.3
+++ src/sys/dist/pf/netinet/tcp_rndiss.c 2011/12/17 20:05:39 1.4
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1/* $OpenBSD: tcp_subr.c,v 1.98 2007/06/25 12:17:43 markus Exp $ */ 1/* $OpenBSD: tcp_subr.c,v 1.98 2007/06/25 12:17:43 markus Exp $ */
2/* $NetBSD: tcp_rndiss.c,v 1.3 2011/11/19 22:51:24 tls Exp $ */ 2/* $NetBSD: tcp_rndiss.c,v 1.4 2011/12/17 20:05:39 tls Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1982, 1986, 1988, 1990, 1993 5 * Copyright (c) 1982, 1986, 1988, 1990, 1993
6 * The Regents of the University of California. All rights reserved. 6 * The Regents of the University of California. All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
@@ -59,27 +59,27 @@ @@ -59,27 +59,27 @@
59 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 59 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 60 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 61 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 62 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 * 64 *
65 * The views and conclusions contained in the software and documentation 65 * The views and conclusions contained in the software and documentation
66 * are those of the authors and should not be interpreted as representing 66 * are those of the authors and should not be interpreted as representing
67 * official policies, either expressed or implied, of the US Naval 67 * official policies, either expressed or implied, of the US Naval
68 * Research Laboratory (NRL). 68 * Research Laboratory (NRL).
69 */ 69 */
70 70
71#include <sys/cdefs.h> 71#include <sys/cdefs.h>
72__KERNEL_RCSID(0, "$NetBSD: tcp_rndiss.c,v 1.3 2011/11/19 22:51:24 tls Exp $"); 72__KERNEL_RCSID(0, "$NetBSD: tcp_rndiss.c,v 1.4 2011/12/17 20:05:39 tls Exp $");
73 73
74#include <sys/param.h> 74#include <sys/param.h>
75#include <sys/cprng.h> 75#include <sys/cprng.h>
76 76
77#include <netinet/tcp.h> 77#include <netinet/tcp.h>
78#include <netinet/tcp_seq.h> 78#include <netinet/tcp_seq.h>
79#include <netinet/tcp_rndiss.h> 79#include <netinet/tcp_rndiss.h>
80 80
81#define TCP_RNDISS_ROUNDS 16 81#define TCP_RNDISS_ROUNDS 16
82#define TCP_RNDISS_OUT 7200 82#define TCP_RNDISS_OUT 7200
83#define TCP_RNDISS_MAX 30000 83#define TCP_RNDISS_MAX 30000
84 84
85u_int8_t tcp_rndiss_sbox[128]; 85u_int8_t tcp_rndiss_sbox[128];
@@ -94,27 +94,27 @@ tcp_rndiss_encrypt(u_int16_t val) @@ -94,27 +94,27 @@ tcp_rndiss_encrypt(u_int16_t val)
94 94
95 for (i = 0; i < TCP_RNDISS_ROUNDS; i++) { 95 for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
96 sum += 0x79b9; 96 sum += 0x79b9;
97 val ^= ((u_int16_t)tcp_rndiss_sbox[(val^sum) & 0x7f]) << 7; 97 val ^= ((u_int16_t)tcp_rndiss_sbox[(val^sum) & 0x7f]) << 7;
98 val = ((val & 0xff) << 7) | (val >> 8); 98 val = ((val & 0xff) << 7) | (val >> 8);
99 } 99 }
100 100
101 return val; 101 return val;
102} 102}
103 103
104void 104void
105tcp_rndiss_init(void) 105tcp_rndiss_init(void)
106{ 106{
107 cprng_strong(kern_cprng, tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox)); 107 cprng_strong(kern_cprng, tcp_rndiss_sbox, sizeof(tcp_rndiss_sbox), 0);
108 108
109 tcp_rndiss_reseed = time_second + TCP_RNDISS_OUT; 109 tcp_rndiss_reseed = time_second + TCP_RNDISS_OUT;
110 tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000; 110 tcp_rndiss_msb = tcp_rndiss_msb == 0x8000 ? 0 : 0x8000;
111 tcp_rndiss_cnt = 0; 111 tcp_rndiss_cnt = 0;
112} 112}
113 113
114tcp_seq 114tcp_seq
115tcp_rndiss_next(void) 115tcp_rndiss_next(void)
116{ 116{
117 if (tcp_rndiss_cnt >= TCP_RNDISS_MAX || 117 if (tcp_rndiss_cnt >= TCP_RNDISS_MAX ||
118 time_second > tcp_rndiss_reseed) 118 time_second > tcp_rndiss_reseed)
119 tcp_rndiss_init(); 119 tcp_rndiss_init();
120 120

cvs diff -r1.185 -r1.186 src/sys/kern/init_sysctl.c (expand / switch to unified diff)

--- src/sys/kern/init_sysctl.c 2011/11/20 01:09:14 1.185
+++ src/sys/kern/init_sysctl.c 2011/12/17 20:05:39 1.186
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: init_sysctl.c,v 1.185 2011/11/20 01:09:14 tls Exp $ */ 1/* $NetBSD: init_sysctl.c,v 1.186 2011/12/17 20:05:39 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Brown, and by Andrew Doran. 8 * by Andrew Brown, and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.185 2011/11/20 01:09:14 tls Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.186 2011/12/17 20:05:39 tls Exp $");
34 34
35#include "opt_sysv.h" 35#include "opt_sysv.h"
36#include "opt_compat_netbsd.h" 36#include "opt_compat_netbsd.h"
37#include "opt_modular.h" 37#include "opt_modular.h"
38#include "opt_sa.h" 38#include "opt_sa.h"
39#include "opt_posix.h" 39#include "opt_posix.h"
40#include "pty.h" 40#include "pty.h"
41 41
42#include <sys/types.h> 42#include <sys/types.h>
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/sysctl.h> 44#include <sys/sysctl.h>
45#include <sys/cpu.h> 45#include <sys/cpu.h>
46#include <sys/errno.h> 46#include <sys/errno.h>
@@ -1386,27 +1386,27 @@ sysctl_kern_sbmax(SYSCTLFN_ARGS) @@ -1386,27 +1386,27 @@ sysctl_kern_sbmax(SYSCTLFN_ARGS)
1386 1386
1387 return (error); 1387 return (error);
1388} 1388}
1389 1389
1390/* 1390/*
1391 * sysctl helper routine for kern.urandom node. Picks a random number 1391 * sysctl helper routine for kern.urandom node. Picks a random number
1392 * for you. 1392 * for you.
1393 */ 1393 */
1394static int 1394static int
1395sysctl_kern_urnd(SYSCTLFN_ARGS) 1395sysctl_kern_urnd(SYSCTLFN_ARGS)
1396{ 1396{
1397 int v, rv; 1397 int v, rv;
1398 1398
1399 rv = cprng_strong(sysctl_prng, &v, sizeof(v)); 1399 rv = cprng_strong(sysctl_prng, &v, sizeof(v), 0);
1400 if (rv == sizeof(v)) { 1400 if (rv == sizeof(v)) {
1401 struct sysctlnode node = *rnode; 1401 struct sysctlnode node = *rnode;
1402 node.sysctl_data = &v; 1402 node.sysctl_data = &v;
1403 return (sysctl_lookup(SYSCTLFN_CALL(&node))); 1403 return (sysctl_lookup(SYSCTLFN_CALL(&node)));
1404 } 1404 }
1405 else 1405 else
1406 return (EIO); /*XXX*/ 1406 return (EIO); /*XXX*/
1407} 1407}
1408 1408
1409/* 1409/*
1410 * sysctl helper routine for kern.arandom node. Picks a random number 1410 * sysctl helper routine for kern.arandom node. Picks a random number
1411 * for you. 1411 * for you.
1412 */ 1412 */

cvs diff -r1.4 -r1.5 src/sys/kern/subr_cprng.c (expand / switch to unified diff)

--- src/sys/kern/subr_cprng.c 2011/11/29 21:48:22 1.4
+++ src/sys/kern/subr_cprng.c 2011/12/17 20:05:39 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: subr_cprng.c,v 1.4 2011/11/29 21:48:22 njoly Exp $ */ 1/* $NetBSD: subr_cprng.c,v 1.5 2011/12/17 20:05:39 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Thor Lancelot Simon. 8 * by Thor Lancelot Simon.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -36,252 +36,262 @@ @@ -36,252 +36,262 @@
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kmem.h> 37#include <sys/kmem.h>
38#include <sys/mutex.h> 38#include <sys/mutex.h>
39#include <sys/rngtest.h> 39#include <sys/rngtest.h>
40#include <sys/rnd.h> 40#include <sys/rnd.h>
41#include <dev/rnd_private.h> 41#include <dev/rnd_private.h>
42 42
43#if defined(__HAVE_CPU_COUNTER) 43#if defined(__HAVE_CPU_COUNTER)
44#include <machine/cpu_counter.h> 44#include <machine/cpu_counter.h>
45#endif 45#endif
46 46
47#include <sys/cprng.h> 47#include <sys/cprng.h>
48 48
49__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.4 2011/11/29 21:48:22 njoly Exp $"); 49__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.5 2011/12/17 20:05:39 tls Exp $");
50 50
51void 51void
52cprng_init(void) 52cprng_init(void)
53{ 53{
54 nist_ctr_initialize(); 54 nist_ctr_initialize();
55} 55}
56 56
57static inline uint32_t 57static inline uint32_t
58cprng_counter(void) 58cprng_counter(void)
59{ 59{
60 struct timeval tv; 60 struct timeval tv;
61 61
62#if defined(__HAVE_CPU_COUNTER) 62#if defined(__HAVE_CPU_COUNTER)
63 if (cpu_hascounter()) 63 if (cpu_hascounter())
64 return cpu_counter32(); 64 return cpu_counter32();
65#endif 65#endif
66 if (__predict_false(cold)) { 66 if (__predict_false(cold)) {
67 /* microtime unsafe if clock not running yet */ 67 /* microtime unsafe if clock not running yet */
68 return 0; 68 return 0;
69 } 69 }
70 microtime(&tv); 70 microtime(&tv);
71 return (tv.tv_sec * 1000000 + tv.tv_usec); 71 return (tv.tv_sec * 1000000 + tv.tv_usec);
72} 72}
73 73
74static void 74static void
 75cprng_strong_sched_reseed(cprng_strong_t *const c)
 76{
 77 KASSERT(mutex_owned(&c->mtx));
 78 if (!(c->reseed_pending)) {
 79 c->reseed_pending = 1;
 80 c->reseed.len = NIST_BLOCK_KEYLEN_BYTES;
 81 rndsink_attach(&c->reseed);
 82 }
 83}
 84
 85static void
75cprng_strong_reseed(void *const arg) 86cprng_strong_reseed(void *const arg)
76{ 87{
77 cprng_strong_t *c = arg; 88 cprng_strong_t *c = arg;
78 uint8_t key[NIST_BLOCK_KEYLEN_BYTES]; 89 uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
79 uint32_t cc = cprng_counter(); 90 uint32_t cc = cprng_counter();
80 91
81 mutex_enter(&c->mtx); 92 mutex_enter(&c->mtx);
82 if (c->reseed.len != sizeof(key)) { 93 if (c->reseed.len != sizeof(key)) {
83 panic("cprng_strong_reseed: bad entropy length %d " 94 panic("cprng_strong_reseed: bad entropy length %d "
84 " (expected %d)", (int)c->reseed.len, (int)sizeof(key)); 95 " (expected %d)", (int)c->reseed.len, (int)sizeof(key));
85 } 96 }
86 if (nist_ctr_drbg_reseed(&c->drbg, c->reseed.data, c->reseed.len, 97 if (nist_ctr_drbg_reseed(&c->drbg, c->reseed.data, c->reseed.len,
87 &cc, sizeof(cc))) { 98 &cc, sizeof(cc))) {
88 panic("cprng %s: nist_ctr_drbg_reseed failed.", c->name); 99 panic("cprng %s: nist_ctr_drbg_reseed failed.", c->name);
89 } 100 }
90 c->reseed_pending = 0; 101 c->reseed_pending = 0;
91 if (c->flags & CPRNG_USE_CV) { 102 if (c->flags & CPRNG_USE_CV) {
92 cv_broadcast(&c->cv); 103 cv_broadcast(&c->cv);
93 } 104 }
 105 selnotify(&c->selq, 0, 0);
94 mutex_exit(&c->mtx); 106 mutex_exit(&c->mtx);
95} 107}
96 108
97cprng_strong_t * 109cprng_strong_t *
98cprng_strong_create(const char *const name, int ipl, int flags) 110cprng_strong_create(const char *const name, int ipl, int flags)
99{ 111{
100 cprng_strong_t *c; 112 cprng_strong_t *c;
101 uint8_t key[NIST_BLOCK_KEYLEN_BYTES]; 113 uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
102 int r, getmore = 0; 114 int r, getmore = 0, hard = 0;
103 uint32_t cc; 115 uint32_t cc;
104 116
105 c = kmem_alloc(sizeof(*c), KM_NOSLEEP); 117 c = kmem_alloc(sizeof(*c), KM_NOSLEEP);
106 if (c == NULL) { 118 if (c == NULL) {
107 return NULL; 119 return NULL;
108 } 120 }
109 c->flags = flags; 121 c->flags = flags;
110 strlcpy(c->name, name, sizeof(c->name)); 122 strlcpy(c->name, name, sizeof(c->name));
111 c->reseed_pending = 0; 123 c->reseed_pending = 0;
112 c->reseed.cb = cprng_strong_reseed; 124 c->reseed.cb = cprng_strong_reseed;
113 c->reseed.arg = c; 125 c->reseed.arg = c;
114 strlcpy(c->reseed.name, name, sizeof(c->reseed.name)); 126 strlcpy(c->reseed.name, name, sizeof(c->reseed.name));
115 127
116 mutex_init(&c->mtx, MUTEX_DEFAULT, ipl); 128 mutex_init(&c->mtx, MUTEX_DEFAULT, ipl);
117 129
118 if (c->flags & CPRNG_USE_CV) { 130 if (c->flags & CPRNG_USE_CV) {
119 cv_init(&c->cv, name); 131 cv_init(&c->cv, name);
120 } 132 }
121 133
 134 selinit(&c->selq);
 135
122 r = rnd_extract_data(key, sizeof(key), RND_EXTRACT_GOOD); 136 r = rnd_extract_data(key, sizeof(key), RND_EXTRACT_GOOD);
123 if (r != sizeof(key)) { 137 if (r != sizeof(key)) {
124 if (c->flags & CPRNG_INIT_ANY) { 138 if (c->flags & CPRNG_INIT_ANY) {
 139#ifdef DEBUG
125 printf("cprng %s: WARNING insufficient " 140 printf("cprng %s: WARNING insufficient "
126 "entropy at creation.\n", name); 141 "entropy at creation.\n", name);
 142#endif
127 rnd_extract_data(key + r, sizeof(key - r), 143 rnd_extract_data(key + r, sizeof(key - r),
128 RND_EXTRACT_ANY); 144 RND_EXTRACT_ANY);
129 } else { 145 } else {
130 return NULL; 146 hard++;
131 } 147 }
132 getmore++; 148 getmore++;
133 } 149 }
134  150
135 if (nist_ctr_drbg_instantiate(&c->drbg, key, sizeof(key), 151 if (nist_ctr_drbg_instantiate(&c->drbg, key, sizeof(key),
136 &cc, sizeof(cc), name, strlen(name))) { 152 &cc, sizeof(cc), name, strlen(name))) {
137 panic("cprng %s: instantiation failed.", name); 153 panic("cprng %s: instantiation failed.", name);
138 } 154 }
139 155
140 if (getmore) { 156 if (getmore) {
141 int wr = 0; 157 /* Cause readers to wait for rekeying. */
142 158 if (hard) {
143 /* Ask for more. */ 159 c->drbg.reseed_counter =
144 c->reseed_pending = 1; 160 NIST_CTR_DRBG_RESEED_INTERVAL + 1;
145 c->reseed.len = sizeof(key); 161 } else {
146 rndsink_attach(&c->reseed); 162 c->drbg.reseed_counter =
147 if (c->flags & CPRNG_USE_CV) { 163 (NIST_CTR_DRBG_RESEED_INTERVAL / 2) + 1;
148 mutex_enter(&c->mtx); 
149 do { 
150 wr = cv_wait_sig(&c->cv, &c->mtx); 
151 if (__predict_true(wr == 0)) { 
152 break; 
153 } 
154 if (wr == ERESTART) { 
155 continue; 
156 } else { 
157 cv_destroy(&c->cv); 
158 mutex_exit(&c->mtx); 
159 mutex_destroy(&c->mtx); 
160 kmem_free(c, sizeof(c)); 
161 return NULL; 
162 } 
163 } while (1); 
164 mutex_exit(&c->mtx); 
165 } 164 }
166 } 165 }
167 return c; 166 return c;
168} 167}
169 168
170size_t 169size_t
171cprng_strong(cprng_strong_t *const c, void *const p, size_t len) 170cprng_strong(cprng_strong_t *const c, void *const p, size_t len, int flags)
172{ 171{
173 uint32_t cc = cprng_counter(); 172 uint32_t cc = cprng_counter();
174 173#ifdef DEBUG
 174 int testfail = 0;
 175#endif
175 if (len > CPRNG_MAX_LEN) { /* XXX should we loop? */ 176 if (len > CPRNG_MAX_LEN) { /* XXX should we loop? */
176 len = CPRNG_MAX_LEN; /* let the caller loop if desired */ 177 len = CPRNG_MAX_LEN; /* let the caller loop if desired */
177 } 178 }
178 
179 mutex_enter(&c->mtx); 179 mutex_enter(&c->mtx);
180again: 180
181 if (nist_ctr_drbg_generate(&c->drbg, p, len, &cc, sizeof(cc))) { 181 if (nist_ctr_drbg_generate(&c->drbg, p, len, &cc, sizeof(cc))) {
182 /* A generator failure really means we hit the hard limit. */ 182 /* A generator failure really means we hit the hard limit. */
183 if (c->flags & CPRNG_REKEY_ANY) { 183 if (c->flags & CPRNG_REKEY_ANY) {
184 uint8_t key[NIST_BLOCK_KEYLEN_BYTES]; 184 uint8_t key[NIST_BLOCK_KEYLEN_BYTES];
185 185
186 printf("cprng %s: WARNING pseudorandom rekeying.\n", 186 printf("cprng %s: WARNING pseudorandom rekeying.\n",
187 c->name); 187 c->name);
188 rnd_extract_data(key, sizeof(key), RND_EXTRACT_ANY); 188 rnd_extract_data(key, sizeof(key), RND_EXTRACT_ANY);
189 cc = cprng_counter(); 189 cc = cprng_counter();
190 if (nist_ctr_drbg_reseed(&c->drbg, key, sizeof(key), 190 if (nist_ctr_drbg_reseed(&c->drbg, key, sizeof(key),
191 &cc, sizeof(cc))) { 191 &cc, sizeof(cc))) {
192 panic("cprng %s: nist_ctr_drbg_reseed " 192 panic("cprng %s: nist_ctr_drbg_reseed "
193 "failed.", c->name); 193 "failed.", c->name);
194 } 194 }
195 if (c->flags & CPRNG_USE_CV) { 
196 cv_broadcast(&c->cv); /* XXX unnecessary? */ 
197 } 
198 } else { 195 } else {
199 if (c->flags & CPRNG_USE_CV) { 196 if (!(flags & FNONBLOCK) &&
 197 (c->flags & CPRNG_USE_CV)) {
200 int wr; 198 int wr;
201 199
 200 cprng_strong_sched_reseed(c);
202 do { 201 do {
203 wr = cv_wait_sig(&c->cv, &c->mtx);  202 wr = cv_wait_sig(&c->cv, &c->mtx);
204 if (wr == EINTR) { 203 if (wr == ERESTART) {
205 mutex_exit(&c->mtx); 204 mutex_exit(&c->mtx);
206 return 0; 205 return 0;
207 } 206 }
208 } while (nist_ctr_drbg_generate(&c->drbg, p, 207 } while (nist_ctr_drbg_generate(&c->drbg, p,
209 len, &cc, 208 len, &cc,
210 sizeof(cc))); 209 sizeof(cc)));
211 } else { 210 } else {
212 mutex_exit(&c->mtx); 211 len = 0;
213 return 0; 
214 } 212 }
215 } 213 }
216 } 214 }
217 215
218#ifdef DIAGNOSTIC 216#ifdef DEBUG
219 /* 217 /*
220 * If the generator has just been keyed, perform 218 * If the generator has just been keyed, perform
221 * the statistical RNG test. 219 * the statistical RNG test.
222 */ 220 */
223 if (__predict_false(c->drbg.reseed_counter == 1)) { 221 if (__predict_false(c->drbg.reseed_counter == 1)) {
224 rngtest_t rt; 222 rngtest_t *rt = kmem_alloc(sizeof(*rt), KM_NOSLEEP);
225 223
226 strncpy(rt.rt_name, c->name, sizeof(rt.rt_name)); 224 if (rt) {
227 225
228 if (nist_ctr_drbg_generate(&c->drbg, rt.rt_b, 226 strncpy(rt->rt_name, c->name, sizeof(rt->rt_name));
229 sizeof(rt.rt_b), NULL, 0)) { 227
230 panic("cprng %s: nist_ctr_drbg_generate failed!", 228 if (nist_ctr_drbg_generate(&c->drbg, rt->rt_b,
231 c->name); 229 sizeof(rt->rt_b), NULL, 0)) {
 230 panic("cprng %s: nist_ctr_drbg_generate "
 231 "failed!", c->name);
232  232
233 } 233 }
234 if (rngtest(&rt)) { 234 testfail = rngtest(rt);
235 printf("cprng %s: failed statistical RNG test.\n", 
236 c->name); 
237 c->drbg.reseed_counter = 
238 NIST_CTR_DRBG_RESEED_INTERVAL + 1; 
239 } 
240 235
241 memset(&rt, 0, sizeof(rt)); 236 if (testfail) {
 237 printf("cprng %s: failed statistical RNG "
 238 "test.\n", c->name);
 239 c->drbg.reseed_counter =
 240 NIST_CTR_DRBG_RESEED_INTERVAL + 1;
 241 len = 0;
 242 }
 243 memset(rt, 0, sizeof(*rt));
 244 kmem_free(rt, sizeof(*rt));
 245 }
242 } 246 }
243#endif 247#endif
244 if (__predict_false(c->drbg.reseed_counter > 248 if (__predict_false(c->drbg.reseed_counter >
245 (NIST_CTR_DRBG_RESEED_INTERVAL / 2))) { 249 (NIST_CTR_DRBG_RESEED_INTERVAL / 2))) {
246 if (!(c->reseed_pending)) { 250 cprng_strong_sched_reseed(c);
247 c->reseed_pending = 1; 251 }
248 c->reseed.len = NIST_BLOCK_KEYLEN_BYTES; 252
249 rndsink_attach(&c->reseed); 253 if (rnd_full) {
250 } 254 if (!c->rekeyed_on_full) {
251 if (__predict_false(c->drbg.reseed_counter > 255 c->rekeyed_on_full++;
252 NIST_CTR_DRBG_RESEED_INTERVAL)) { 256 cprng_strong_sched_reseed(c);
253 goto again; /* statistical test failure */ 
254 } 257 }
 258 } else {
 259 c->rekeyed_on_full = 0;
255 } 260 }
256 261
257 mutex_exit(&c->mtx); 262 mutex_exit(&c->mtx);
258 return len; 263 return len;
259} 264}
260 265
261void 266void
262cprng_strong_destroy(cprng_strong_t *c) 267cprng_strong_destroy(cprng_strong_t *c)
263{ 268{
264 KASSERT(!mutex_owned(&c->mtx)); 269 mutex_enter(&c->mtx);
 270
265 if (c->flags & CPRNG_USE_CV) { 271 if (c->flags & CPRNG_USE_CV) {
266 KASSERT(!cv_has_waiters(&c->cv)); 272 KASSERT(!cv_has_waiters(&c->cv));
267 cv_destroy(&c->cv); 273 cv_destroy(&c->cv);
268 } 274 }
 275 seldestroy(&c->selq);
269 276
270 mutex_destroy(&c->mtx); 
271 if (c->reseed_pending) { 277 if (c->reseed_pending) {
272 rndsink_detach(&c->reseed); 278 rndsink_detach(&c->reseed);
273 } 279 }
274 nist_ctr_drbg_destroy(&c->drbg); 280 nist_ctr_drbg_destroy(&c->drbg);
 281
 282 mutex_exit(&c->mtx);
 283 mutex_destroy(&c->mtx);
 284
275 memset(c, 0, sizeof(*c)); 285 memset(c, 0, sizeof(*c));
276 kmem_free(c, sizeof(*c)); 286 kmem_free(c, sizeof(*c));
277} 287}
278 288
279int 289int
280cprng_strong_getflags(cprng_strong_t *const c) 290cprng_strong_getflags(cprng_strong_t *const c)
281{ 291{
282 KASSERT(mutex_owned(&c->mtx)); 292 KASSERT(mutex_owned(&c->mtx));
283 return c->flags; 293 return c->flags;
284} 294}
285 295
286void 296void
287cprng_strong_setflags(cprng_strong_t *const c, int flags) 297cprng_strong_setflags(cprng_strong_t *const c, int flags)
@@ -292,17 +302,18 @@ cprng_strong_setflags(cprng_strong_t *co @@ -292,17 +302,18 @@ cprng_strong_setflags(cprng_strong_t *co
292 cv_init(&c->cv, (const char *)c->name); 302 cv_init(&c->cv, (const char *)c->name);
293 } 303 }
294 } else { 304 } else {
295 if (c->flags & CPRNG_USE_CV) { 305 if (c->flags & CPRNG_USE_CV) {
296 KASSERT(!cv_has_waiters(&c->cv)); 306 KASSERT(!cv_has_waiters(&c->cv));
297 cv_destroy(&c->cv); 307 cv_destroy(&c->cv);
298 } 308 }
299 } 309 }
300 if (flags & CPRNG_REKEY_ANY) { 310 if (flags & CPRNG_REKEY_ANY) {
301 if (!(c->flags & CPRNG_REKEY_ANY)) { 311 if (!(c->flags & CPRNG_REKEY_ANY)) {
302 if (c->flags & CPRNG_USE_CV) { 312 if (c->flags & CPRNG_USE_CV) {
303 cv_broadcast(&c->cv); 313 cv_broadcast(&c->cv);
304 } 314 }
 315 selnotify(&c->selq, 0, 0);
305 } 316 }
306 } 317 }
307 c->flags = flags; 318 c->flags = flags;
308} 319}

cvs diff -r1.124 -r1.125 src/sys/net/if_spppsubr.c (expand / switch to unified diff)

--- src/sys/net/if_spppsubr.c 2011/11/19 22:51:25 1.124
+++ src/sys/net/if_spppsubr.c 2011/12/17 20:05:39 1.125
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_spppsubr.c,v 1.124 2011/11/19 22:51:25 tls Exp $ */ 1/* $NetBSD: if_spppsubr.c,v 1.125 2011/12/17 20:05:39 tls Exp $ */
2 2
3/* 3/*
4 * Synchronous PPP/Cisco link level subroutines. 4 * Synchronous PPP/Cisco link level subroutines.
5 * Keepalive protocol implemented in both Cisco and PPP modes. 5 * Keepalive protocol implemented in both Cisco and PPP modes.
6 * 6 *
7 * Copyright (C) 1994-1996 Cronyx Engineering Ltd. 7 * Copyright (C) 1994-1996 Cronyx Engineering Ltd.
8 * Author: Serge Vakulenko, <vak@cronyx.ru> 8 * Author: Serge Vakulenko, <vak@cronyx.ru>
9 * 9 *
10 * Heavily revamped to conform to RFC 1661. 10 * Heavily revamped to conform to RFC 1661.
11 * Copyright (C) 1997, Joerg Wunsch. 11 * Copyright (C) 1997, Joerg Wunsch.
12 * 12 *
13 * RFC2472 IPv6CP support. 13 * RFC2472 IPv6CP support.
14 * Copyright (C) 2000, Jun-ichiro itojun Hagino <itojun@iijlab.net>. 14 * Copyright (C) 2000, Jun-ichiro itojun Hagino <itojun@iijlab.net>.
@@ -31,27 +31,27 @@ @@ -31,27 +31,27 @@
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 * 35 *
36 * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997 36 * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997
37 * 37 *
38 * From: if_spppsubr.c,v 1.39 1998/04/04 13:26:03 phk Exp 38 * From: if_spppsubr.c,v 1.39 1998/04/04 13:26:03 phk Exp
39 * 39 *
40 * From: Id: if_spppsubr.c,v 1.23 1999/02/23 14:47:50 hm Exp 40 * From: Id: if_spppsubr.c,v 1.23 1999/02/23 14:47:50 hm Exp
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.124 2011/11/19 22:51:25 tls Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.125 2011/12/17 20:05:39 tls Exp $");
45 45
46#if defined(_KERNEL_OPT) 46#if defined(_KERNEL_OPT)
47#include "opt_inet.h" 47#include "opt_inet.h"
48#include "opt_ipx.h" 48#include "opt_ipx.h"
49#include "opt_iso.h" 49#include "opt_iso.h"
50#include "opt_pfil_hooks.h" 50#include "opt_pfil_hooks.h"
51#include "opt_modular.h" 51#include "opt_modular.h"
52#include "opt_compat_netbsd.h" 52#include "opt_compat_netbsd.h"
53#endif 53#endif
54 54
55 55
56#include <sys/param.h> 56#include <sys/param.h>
57#include <sys/proc.h> 57#include <sys/proc.h>
@@ -4288,27 +4288,27 @@ sppp_chap_scr(struct sppp *sp) @@ -4288,27 +4288,27 @@ sppp_chap_scr(struct sppp *sp)
4288{ 4288{
4289 uint32_t *ch; 4289 uint32_t *ch;
4290 u_char clen = 4 * sizeof(uint32_t); 4290 u_char clen = 4 * sizeof(uint32_t);
4291 4291
4292 if (sp->myauth.name == NULL) { 4292 if (sp->myauth.name == NULL) {
4293 /* can't do anything useful */ 4293 /* can't do anything useful */
4294 printf("%s: chap starting without my name being set\n", 4294 printf("%s: chap starting without my name being set\n",
4295 sp->pp_if.if_xname); 4295 sp->pp_if.if_xname);
4296 return; 4296 return;
4297 } 4297 }
4298 4298
4299 /* Compute random challenge. */ 4299 /* Compute random challenge. */
4300 ch = (uint32_t *)sp->myauth.challenge; 4300 ch = (uint32_t *)sp->myauth.challenge;
4301 cprng_strong(kern_cprng, ch, clen); 4301 cprng_strong(kern_cprng, ch, clen, 0);
4302 4302
4303 sp->confid[IDX_CHAP] = ++sp->pp_seq[IDX_CHAP]; 4303 sp->confid[IDX_CHAP] = ++sp->pp_seq[IDX_CHAP];
4304 4304
4305 sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP], 4305 sppp_auth_send(&chap, sp, CHAP_CHALLENGE, sp->confid[IDX_CHAP],
4306 sizeof clen, (const char *)&clen, 4306 sizeof clen, (const char *)&clen,
4307 sizeof(sp->myauth.challenge), sp->myauth.challenge, 4307 sizeof(sp->myauth.challenge), sp->myauth.challenge,
4308 sp->myauth.name_len, 4308 sp->myauth.name_len,
4309 sp->myauth.name, 4309 sp->myauth.name,
4310 0); 4310 0);
4311} 4311}
4312 4312
4313/* 4313/*
4314 *--------------------------------------------------------------------------* 4314 *--------------------------------------------------------------------------*

cvs diff -r1.243 -r1.244 src/sys/netinet/tcp_subr.c (expand / switch to unified diff)

--- src/sys/netinet/tcp_subr.c 2011/11/19 22:51:26 1.243
+++ src/sys/netinet/tcp_subr.c 2011/12/17 20:05:39 1.244
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tcp_subr.c,v 1.243 2011/11/19 22:51:26 tls Exp $ */ 1/* $NetBSD: tcp_subr.c,v 1.244 2011/12/17 20:05:39 tls Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -81,27 +81,27 @@ @@ -81,27 +81,27 @@
81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88 * SUCH DAMAGE. 88 * SUCH DAMAGE.
89 * 89 *
90 * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95 90 * @(#)tcp_subr.c 8.2 (Berkeley) 5/24/95
91 */ 91 */
92 92
93#include <sys/cdefs.h> 93#include <sys/cdefs.h>
94__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.243 2011/11/19 22:51:26 tls Exp $"); 94__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.244 2011/12/17 20:05:39 tls Exp $");
95 95
96#include "opt_inet.h" 96#include "opt_inet.h"
97#include "opt_ipsec.h" 97#include "opt_ipsec.h"
98#include "opt_tcp_compat_42.h" 98#include "opt_tcp_compat_42.h"
99#include "opt_inet_csum.h" 99#include "opt_inet_csum.h"
100#include "opt_mbuftrace.h" 100#include "opt_mbuftrace.h"
101 101
102#include <sys/param.h> 102#include <sys/param.h>
103#include <sys/proc.h> 103#include <sys/proc.h>
104#include <sys/systm.h> 104#include <sys/systm.h>
105#include <sys/malloc.h> 105#include <sys/malloc.h>
106#include <sys/mbuf.h> 106#include <sys/mbuf.h>
107#include <sys/socket.h> 107#include <sys/socket.h>
@@ -2210,27 +2210,27 @@ tcp_seq @@ -2210,27 +2210,27 @@ tcp_seq
2210tcp_new_iss1(void *laddr, void *faddr, u_int16_t lport, u_int16_t fport, 2210tcp_new_iss1(void *laddr, void *faddr, u_int16_t lport, u_int16_t fport,
2211 size_t addrsz, tcp_seq addin) 2211 size_t addrsz, tcp_seq addin)
2212{ 2212{
2213 tcp_seq tcp_iss; 2213 tcp_seq tcp_iss;
2214 2214
2215 static bool tcp_iss_gotten_secret; 2215 static bool tcp_iss_gotten_secret;
2216 2216
2217 /* 2217 /*
2218 * If we haven't been here before, initialize our cryptographic 2218 * If we haven't been here before, initialize our cryptographic
2219 * hash secret. 2219 * hash secret.
2220 */ 2220 */
2221 if (tcp_iss_gotten_secret == false) { 2221 if (tcp_iss_gotten_secret == false) {
2222 cprng_strong(kern_cprng, 2222 cprng_strong(kern_cprng,
2223 tcp_iss_secret, sizeof(tcp_iss_secret)); 2223 tcp_iss_secret, sizeof(tcp_iss_secret), 0);
2224 tcp_iss_gotten_secret = true; 2224 tcp_iss_gotten_secret = true;
2225 } 2225 }
2226 2226
2227 if (tcp_do_rfc1948) { 2227 if (tcp_do_rfc1948) {
2228 MD5_CTX ctx; 2228 MD5_CTX ctx;
2229 u_int8_t hash[16]; /* XXX MD5 knowledge */ 2229 u_int8_t hash[16]; /* XXX MD5 knowledge */
2230 2230
2231 /* 2231 /*
2232 * Compute the base value of the ISS. It is a hash 2232 * Compute the base value of the ISS. It is a hash
2233 * of (saddr, sport, daddr, dport, secret). 2233 * of (saddr, sport, daddr, dport, secret).
2234 */ 2234 */
2235 MD5Init(&ctx); 2235 MD5Init(&ctx);
2236 2236

cvs diff -r1.2 -r1.3 src/sys/rump/dev/lib/librnd/Makefile (expand / switch to unified diff)

--- src/sys/rump/dev/lib/librnd/Makefile 2010/02/16 20:42:45 1.2
+++ src/sys/rump/dev/lib/librnd/Makefile 2011/12/17 20:05:39 1.3
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1# $NetBSD: Makefile,v 1.2 2010/02/16 20:42:45 pooka Exp $ 1# $NetBSD: Makefile,v 1.3 2011/12/17 20:05:39 tls Exp $
2# 2#
3 3
4.PATH: ${.CURDIR}/../../../../dev 4.PATH: ${.CURDIR}/../../../../dev
5 5
6LIB= rumpdev_rnd 6LIB= rumpdev_rnd
7 7
8SRCS= rnd.c rndpool.c 8SRCS= rnd.c rndpseudo.c rndpool.c
9 9
10SRCS+= component.c 10SRCS+= component.c
11 11
12CPPFLAGS+= -I${RUMPTOP}/librump/rumpvfs 12CPPFLAGS+= -I${RUMPTOP}/librump/rumpvfs
13 13
14.include <bsd.lib.mk> 14.include <bsd.lib.mk>
15.include <bsd.klinks.mk> 15.include <bsd.klinks.mk>

cvs diff -r1.3 -r1.4 src/sys/rump/librump/rumpkern/Attic/cprng_stub.c (expand / switch to unified diff)

--- src/sys/rump/librump/rumpkern/Attic/cprng_stub.c 2011/11/28 08:05:07 1.3
+++ src/sys/rump/librump/rumpkern/Attic/cprng_stub.c 2011/12/17 20:05:40 1.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cprng_stub.c,v 1.3 2011/11/28 08:05:07 tls Exp $ */ 1/* $NetBSD: cprng_stub.c,v 1.4 2011/12/17 20:05:40 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Thor Lancelot Simon. 8 * by Thor Lancelot Simon.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -49,52 +49,57 @@ @@ -49,52 +49,57 @@
49 * the pseudodevice. The other, by the fact that I am not smart enough 49 * the pseudodevice. The other, by the fact that I am not smart enough
50 * to understand how to deal with code in rumpkern that depends on code 50 * to understand how to deal with code in rumpkern that depends on code
51 * that lives in sys/crypto. Sigh. 51 * that lives in sys/crypto. Sigh.
52 */ 52 */
53 53
54cprng_strong_t *kern_cprng = NULL; 54cprng_strong_t *kern_cprng = NULL;
55 55
56void 56void
57cprng_init(void) 57cprng_init(void)
58{ 58{
59 return; 59 return;
60} 60}
61 61
62cprng_strong_t *cprng_strong_create(const char *const name, int ipl, int flags) 62cprng_strong_t *
 63cprng_strong_create(const char *const name, int ipl, int flags)
63{ 64{
64 cprng_strong_t *c; 65 cprng_strong_t *c;
65 66
66 c = kmem_alloc(sizeof(*c), KM_NOSLEEP); 67 /* zero struct to zero counters we won't ever set with no DRBG */
 68 c = kmem_zalloc(sizeof(*c), KM_NOSLEEP);
67 if (c == NULL) { 69 if (c == NULL) {
68 return NULL; 70 return NULL;
69 } 71 }
70 strlcpy(c->name, name, sizeof(c->name)); 72 strlcpy(c->name, name, sizeof(c->name));
71 mutex_init(&c->mtx, MUTEX_DEFAULT, ipl); 73 mutex_init(&c->mtx, MUTEX_DEFAULT, ipl);
72 if (c->flags & CPRNG_USE_CV) { 74 if (c->flags & CPRNG_USE_CV) {
73 cv_init(&c->cv, name); 75 cv_init(&c->cv, name);
74 } 76 }
 77 selinit(&c->selq);
75 return c; 78 return c;
76} 79}
77 80
78 81
79size_t cprng_strong(cprng_strong_t *c, void *p, size_t len) 82size_t
 83cprng_strong(cprng_strong_t *c, void *p, size_t len, int blocking)
80{ 84{
81 mutex_enter(&c->mtx); 85 mutex_enter(&c->mtx);
82 cprng_fast(p, len); /* XXX! */ 86 cprng_fast(p, len); /* XXX! */
83 mutex_exit(&c->mtx); 87 mutex_exit(&c->mtx);
84 return len; 88 return len;
85} 89}
86 90
87void cprng_strong_destroy(cprng_strong_t *c) 91void
 92cprng_strong_destroy(cprng_strong_t *c)
88{ 93{
89 mutex_destroy(&c->mtx); 94 mutex_destroy(&c->mtx);
90 cv_destroy(&c->cv); 95 cv_destroy(&c->cv);
91 memset(c, 0, sizeof(*c)); 96 memset(c, 0, sizeof(*c));
92 kmem_free(c, sizeof(*c)); 97 kmem_free(c, sizeof(*c));
93} 98}
94 99
95size_t 100size_t
96cprng_fast(void *p, size_t len) 101cprng_fast(void *p, size_t len)
97{ 102{
98 uint8_t *resp, *pchar = (uint8_t *)p; 103 uint8_t *resp, *pchar = (uint8_t *)p;
99 uint32_t res; 104 uint32_t res;
100 size_t i; 105 size_t i;

cvs diff -r1.3 -r1.4 src/sys/sys/cprng.h (expand / switch to unified diff)

--- src/sys/sys/cprng.h 2011/12/13 08:00:36 1.3
+++ src/sys/sys/cprng.h 2011/12/17 20:05:40 1.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cprng.h,v 1.3 2011/12/13 08:00:36 mlelstv Exp $ */ 1/* $NetBSD: cprng.h,v 1.4 2011/12/17 20:05:40 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Thor Lancelot Simon. 8 * by Thor Lancelot Simon.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -22,30 +22,32 @@ @@ -22,30 +22,32 @@
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#ifndef _CPRNG_H 31#ifndef _CPRNG_H
32#define _CPRNG_H 32#define _CPRNG_H
33 33
34#include <sys/types.h> 34#include <sys/types.h>
 35#include <sys/fcntl.h>
35#include <lib/libkern/libkern.h> 36#include <lib/libkern/libkern.h>
36#include <sys/rnd.h> 37#include <sys/rnd.h>
37#include <crypto/nist_ctr_drbg/nist_ctr_drbg.h> 38#include <crypto/nist_ctr_drbg/nist_ctr_drbg.h>
38#include <sys/condvar.h> 39#include <sys/condvar.h>
 40#include <sys/select.h>
39 41
40/* 42/*
41 * NIST SP800-90 says 2^19 bytes per request for the CTR_DRBG. 43 * NIST SP800-90 says 2^19 bytes per request for the CTR_DRBG.
42 */ 44 */
43#define CPRNG_MAX_LEN 524288 45#define CPRNG_MAX_LEN 524288
44 46
45#if !defined(_RUMPKERNEL) && !defined(_RUMP_NATIVE_ABI) 47#if !defined(_RUMPKERNEL) && !defined(_RUMP_NATIVE_ABI)
46/* 48/*
47 * We do not want an arc4random() prototype available to anyone. 49 * We do not want an arc4random() prototype available to anyone.
48 */ 50 */
49void _arc4randbytes(void *, size_t); 51void _arc4randbytes(void *, size_t);
50uint32_t _arc4random(void); 52uint32_t _arc4random(void);
51 53
@@ -66,55 +68,84 @@ static inline uint64_t @@ -66,55 +68,84 @@ static inline uint64_t
66cprng_fast64(void) 68cprng_fast64(void)
67{ 69{
68 uint64_t r; 70 uint64_t r;
69 _arc4randbytes(&r, sizeof(r)); 71 _arc4randbytes(&r, sizeof(r));
70 return r; 72 return r;
71} 73}
72#else 74#else
73size_t cprng_fast(void *, size_t); 75size_t cprng_fast(void *, size_t);
74uint32_t cprng_fast32(void); 76uint32_t cprng_fast32(void);
75uint64_t cprng_fast64(void); 77uint64_t cprng_fast64(void);
76#endif 78#endif
77 79
78typedef struct _cprng_strong { 80typedef struct _cprng_strong {
79 kmutex_t mtx; 81 kmutex_t mtx;
80 kcondvar_t cv; 82 kcondvar_t cv;
81 NIST_CTR_DRBG drbg; 83 struct selinfo selq;
82 int flags; 84 NIST_CTR_DRBG drbg;
83 char name[16]; 85 int flags;
84 int reseed_pending; 86 char name[16];
85 rndsink_t reseed; 87 int reseed_pending;
 88 int rekeyed_on_full;
 89 rndsink_t reseed;
86} cprng_strong_t; 90} cprng_strong_t;
87 91
88#define CPRNG_INIT_ANY 0x00000001 92#define CPRNG_INIT_ANY 0x00000001
89#define CPRNG_REKEY_ANY 0x00000002 93#define CPRNG_REKEY_ANY 0x00000002
90#define CPRNG_USE_CV 0x00000004 94#define CPRNG_USE_CV 0x00000004
91 95
92cprng_strong_t *cprng_strong_create(const char *const, int, int); 96cprng_strong_t *cprng_strong_create(const char *const, int, int);
93 97
94size_t cprng_strong(cprng_strong_t *const, void *const, size_t); 98size_t cprng_strong(cprng_strong_t *const, void *const, size_t, int);
95 99
96void cprng_strong_destroy(cprng_strong_t *); 100void cprng_strong_destroy(cprng_strong_t *);
97 101
98extern cprng_strong_t * kern_cprng; 102extern cprng_strong_t * kern_cprng;
99 103
100static inline uint32_t 104static inline uint32_t
101cprng_strong32(void) 105cprng_strong32(void)
102{ 106{
103 uint32_t r; 107 uint32_t r;
104 cprng_strong(kern_cprng, &r, sizeof(r)); 108 cprng_strong(kern_cprng, &r, sizeof(r), 0);
105 return r; 109 return r;
106} 110}
107 111
108static inline uint64_t 112static inline uint64_t
109cprng_strong64(void) 113cprng_strong64(void)
110{ 114{
111 uint64_t r; 115 uint64_t r;
112 cprng_strong(kern_cprng, &r, sizeof(r)); 116 cprng_strong(kern_cprng, &r, sizeof(r), 0);
113 return r; 117 return r;
114} 118}
115 119
 120static inline int
 121cprng_strong_ready(cprng_strong_t *c)
 122{
 123 int ret = 0;
 124
 125 mutex_enter(&c->mtx);
 126 if (c->drbg.reseed_counter < NIST_CTR_DRBG_RESEED_INTERVAL) {
 127 ret = 1;
 128 }
 129 mutex_exit(&c->mtx);
 130 return ret;
 131}
 132
 133static inline void
 134cprng_strong_deplete(cprng_strong_t *c)
 135{
 136 mutex_enter(&c->mtx);
 137 c->drbg.reseed_counter = NIST_CTR_DRBG_RESEED_INTERVAL + 1;
 138 mutex_exit(&c->mtx);
 139}
 140
 141static inline int
 142cprng_strong_strength(cprng_strong_t *c)
 143{
 144 return NIST_BLOCK_KEYLEN_BYTES;
 145}
 146
116void cprng_init(void); 147void cprng_init(void);
117int cprng_strong_getflags(cprng_strong_t *const); 148int cprng_strong_getflags(cprng_strong_t *const);
118void cprng_strong_setflags(cprng_strong_t *const, int); 149void cprng_strong_setflags(cprng_strong_t *const, int);
119 150
120#endif 151#endif

cvs diff -r1.397 -r1.398 src/sys/sys/param.h (expand / switch to unified diff)

--- src/sys/sys/param.h 2011/11/28 08:05:07 1.397
+++ src/sys/sys/param.h 2011/12/17 20:05:40 1.398
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: param.h,v 1.397 2011/11/28 08:05:07 tls Exp $ */ 1/* $NetBSD: param.h,v 1.398 2011/12/17 20:05:40 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1982, 1986, 1989, 1993 4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc. 6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed 7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph 8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc. 10 * the permission of UNIX System Laboratories, Inc.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -53,27 +53,27 @@ @@ -53,27 +53,27 @@
53 * m = minor version; a minor number of 99 indicates current. 53 * m = minor version; a minor number of 99 indicates current.
54 * r = 0 (*) 54 * r = 0 (*)
55 * p = patchlevel 55 * p = patchlevel
56 * 56 *
57 * When new releases are made, src/gnu/usr.bin/groff/tmac/mdoc.local 57 * When new releases are made, src/gnu/usr.bin/groff/tmac/mdoc.local
58 * needs to be updated and the changes sent back to the groff maintainers. 58 * needs to be updated and the changes sent back to the groff maintainers.
59 * 59 *
60 * (*) Up to 2.0I "release" used to be "",A-Z,Z[A-Z] but numeric 60 * (*) Up to 2.0I "release" used to be "",A-Z,Z[A-Z] but numeric
61 * e.g. NetBSD-1.2D = 102040000 ('D' == 4) 61 * e.g. NetBSD-1.2D = 102040000 ('D' == 4)
62 * NetBSD-2.0H (200080000) was changed on 20041001 to: 62 * NetBSD-2.0H (200080000) was changed on 20041001 to:
63 * 2.99.9 (299000900) 63 * 2.99.9 (299000900)
64 */ 64 */
65 65
66#define __NetBSD_Version__ 599005800 /* NetBSD 5.99.58 */ 66#define __NetBSD_Version__ 599005900 /* NetBSD 5.99.59 */
67 67
68#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \ 68#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
69 (m) * 1000000) + (p) * 100) <= __NetBSD_Version__) 69 (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)
70 70
71/* 71/*
72 * Historical NetBSD #define 72 * Historical NetBSD #define
73 * 73 *
74 * NetBSD 1.4 was the last release for which this value was incremented. 74 * NetBSD 1.4 was the last release for which this value was incremented.
75 * The value is now permanently fixed at 199905. It will never be 75 * The value is now permanently fixed at 199905. It will never be
76 * changed again. 76 * changed again.
77 * 77 *
78 * New code must use __NetBSD_Version__ instead, and should not even 78 * New code must use __NetBSD_Version__ instead, and should not even
79 * count on NetBSD being defined. 79 * count on NetBSD being defined.

cvs diff -r1.27 -r1.28 src/sys/sys/rnd.h (expand / switch to unified diff)

--- src/sys/sys/rnd.h 2011/12/17 12:59:21 1.27
+++ src/sys/sys/rnd.h 2011/12/17 20:05:40 1.28
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rnd.h,v 1.27 2011/12/17 12:59:21 apb Exp $ */ 1/* $NetBSD: rnd.h,v 1.28 2011/12/17 20:05:40 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org>. This code uses ideas and 8 * by Michael Graff <explorer@flame.org>. This code uses ideas and
9 * algorithms from the Linux driver written by Ted Ts'o. 9 * algorithms from the Linux driver written by Ted Ts'o.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -155,26 +155,28 @@ uint32_t rndpool_extract_data(rndpool_t  @@ -155,26 +155,28 @@ uint32_t rndpool_extract_data(rndpool_t
155void rnd_init(void); 155void rnd_init(void);
156void rnd_add_uint32(krndsource_t *, uint32_t); 156void rnd_add_uint32(krndsource_t *, uint32_t);
157void rnd_add_data(krndsource_t *, const void *const, uint32_t, 157void rnd_add_data(krndsource_t *, const void *const, uint32_t,
158 uint32_t); 158 uint32_t);
159void rnd_attach_source(krndsource_t *, const char *, 159void rnd_attach_source(krndsource_t *, const char *,
160 uint32_t, uint32_t); 160 uint32_t, uint32_t);
161void rnd_detach_source(krndsource_t *); 161void rnd_detach_source(krndsource_t *);
162 162
163void rndsink_attach(rndsink_t *); 163void rndsink_attach(rndsink_t *);
164void rndsink_detach(rndsink_t *); 164void rndsink_detach(rndsink_t *);
165 165
166void rnd_seed(void *, size_t); 166void rnd_seed(void *, size_t);
167 167
 168extern int rnd_full;
 169
168#endif /* _KERNEL */ 170#endif /* _KERNEL */
169 171
170#define RND_MAXSTATCOUNT 10 /* 10 sources at once max */ 172#define RND_MAXSTATCOUNT 10 /* 10 sources at once max */
171 173
172/* 174/*
173 * return "count" random entries, starting at "start" 175 * return "count" random entries, starting at "start"
174 */ 176 */
175typedef struct { 177typedef struct {
176 uint32_t start; 178 uint32_t start;
177 uint32_t count; 179 uint32_t count;
178 rndsource_t source[RND_MAXSTATCOUNT]; 180 rndsource_t source[RND_MAXSTATCOUNT];
179} rndstat_t; 181} rndstat_t;
180 182