summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/random.c')
-rw-r--r--src/lib/libc/stdlib/random.c188
1 files changed, 135 insertions, 53 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c
index 469b6d976a..00edf2dca1 100644
--- a/src/lib/libc/stdlib/random.c
+++ b/src/lib/libc/stdlib/random.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: random.c,v 1.19 2013/08/01 19:42:08 kettenis Exp $ */
1/* 2/*
2 * Copyright (c) 1983 Regents of the University of California. 3 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 14 * 3. Neither the name of the University nor the names of its contributors
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,13 +28,15 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint) 31#include <sys/param.h>
35/*static char *sccsid = "from: @(#)random.c 5.9 (Berkeley) 2/23/91";*/ 32#include <sys/sysctl.h>
36static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"; 33#include <sys/time.h>
37#endif /* LIBC_SCCS and not lint */ 34#include <fcntl.h>
38
39#include <stdio.h> 35#include <stdio.h>
40#include <stdlib.h> 36#include <stdlib.h>
37#include <unistd.h>
38
39#include "thread_private.h"
41 40
42/* 41/*
43 * random.c: 42 * random.c:
@@ -55,10 +54,10 @@ static char *rcsid = "$Id: random.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $"
55 * congruential generator. If the amount of state information is less than 54 * congruential generator. If the amount of state information is less than
56 * 32 bytes, a simple linear congruential R.N.G. is used. 55 * 32 bytes, a simple linear congruential R.N.G. is used.
57 * 56 *
58 * Internally, the state information is treated as an array of longs; the 57 * Internally, the state information is treated as an array of int32_t; the
59 * zeroeth element of the array is the type of R.N.G. being used (small 58 * zeroeth element of the array is the type of R.N.G. being used (small
60 * integer); the remainder of the array is the state information for the 59 * integer); the remainder of the array is the state information for the
61 * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of 60 * R.N.G. Thus, 32 bytes of state information will give 7 int32_ts worth of
62 * state information, which will allow a degree seven polynomial. (Note: 61 * state information, which will allow a degree seven polynomial. (Note:
63 * the zeroeth word of state information also has some other information 62 * the zeroeth word of state information also has some other information
64 * stored in it -- see setstate() for details). 63 * stored in it -- see setstate() for details).
@@ -134,14 +133,14 @@ static int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
134 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. 133 * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
135 */ 134 */
136 135
137static long randtbl[DEG_3 + 1] = { 136static int32_t randtbl[DEG_3 + 1] = {
138 TYPE_3, 137 TYPE_3,
139 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, 138 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
140 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 139 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
141 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, 140 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
142 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, 141 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
143 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, 142 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
144 0x27fb47b9, 143 0xf3bec5da,
145}; 144};
146 145
147/* 146/*
@@ -158,8 +157,8 @@ static long randtbl[DEG_3 + 1] = {
158 * in the initialization of randtbl) because the state table pointer is set 157 * in the initialization of randtbl) because the state table pointer is set
159 * to point to randtbl[1] (as explained below). 158 * to point to randtbl[1] (as explained below).
160 */ 159 */
161static long *fptr = &randtbl[SEP_3 + 1]; 160static int32_t *fptr = &randtbl[SEP_3 + 1];
162static long *rptr = &randtbl[1]; 161static int32_t *rptr = &randtbl[1];
163 162
164/* 163/*
165 * The following things are the pointer to the state information table, the 164 * The following things are the pointer to the state information table, the
@@ -171,11 +170,17 @@ static long *rptr = &randtbl[1];
171 * this is more efficient than indexing every time to find the address of 170 * this is more efficient than indexing every time to find the address of
172 * the last element to see if the front and rear pointers have wrapped. 171 * the last element to see if the front and rear pointers have wrapped.
173 */ 172 */
174static long *state = &randtbl[1]; 173static int32_t *state = &randtbl[1];
174static int32_t *end_ptr = &randtbl[DEG_3 + 1];
175static int rand_type = TYPE_3; 175static int rand_type = TYPE_3;
176static int rand_deg = DEG_3; 176static int rand_deg = DEG_3;
177static int rand_sep = SEP_3; 177static int rand_sep = SEP_3;
178static long *end_ptr = &randtbl[DEG_3 + 1]; 178
179_THREAD_PRIVATE_MUTEX(random);
180static long random_l(void);
181
182#define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random)
183#define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random)
179 184
180/* 185/*
181 * srandom: 186 * srandom:
@@ -189,26 +194,89 @@ static long *end_ptr = &randtbl[DEG_3 + 1];
189 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] 194 * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
190 * for default usage relies on values produced by this routine. 195 * for default usage relies on values produced by this routine.
191 */ 196 */
192void 197static void
193srandom(x) 198srandom_l(unsigned int x)
194 u_int x;
195{ 199{
196 register int i, j; 200 int i;
201 int32_t test;
202 div_t val;
197 203
198 if (rand_type == TYPE_0) 204 if (rand_type == TYPE_0)
199 state[0] = x; 205 state[0] = x;
200 else { 206 else {
201 j = 1; 207 /* A seed of 0 would result in state[] always being zero. */
202 state[0] = x; 208 state[0] = x ? x : 1;
203 for (i = 1; i < rand_deg; i++) 209 for (i = 1; i < rand_deg; i++) {
204 state[i] = 1103515245 * state[i - 1] + 12345; 210 /*
211 * Implement the following, without overflowing 31 bits:
212 *
213 * state[i] = (16807 * state[i - 1]) % 2147483647;
214 *
215 * 2^31-1 (prime) = 2147483647 = 127773*16807+2836
216 */
217 val = div(state[i-1], 127773);
218 test = 16807 * val.rem - 2836 * val.quot;
219 state[i] = test + (test < 0 ? 2147483647 : 0);
220 }
205 fptr = &state[rand_sep]; 221 fptr = &state[rand_sep];
206 rptr = &state[0]; 222 rptr = &state[0];
207 for (i = 0; i < 10 * rand_deg; i++) 223 for (i = 0; i < 10 * rand_deg; i++)
208 (void)random(); 224 (void)random_l();
209 } 225 }
210} 226}
211 227
228void
229srandom(unsigned int x)
230{
231 LOCK();
232 srandom_l(x);
233 UNLOCK();
234}
235
236#if defined(APIWARN)
237__warn_references(srandom,
238 "warning: srandom() seed choices are invariably poor");
239#endif
240
241/*
242 * srandomdev:
243 *
244 * Many programs choose the seed value in a totally predictable manner.
245 * This often causes problems. We seed the generator using random
246 * data from the kernel.
247 * Note that this particular seeding procedure can generate states
248 * which are impossible to reproduce by calling srandom() with any
249 * value, since the succeeding terms in the state buffer are no longer
250 * derived from the LC algorithm applied to a fixed seed.
251 */
252void
253srandomdev(void)
254{
255 int mib[2];
256 size_t len;
257
258 LOCK();
259 if (rand_type == TYPE_0)
260 len = sizeof(state[0]);
261 else
262 len = rand_deg * sizeof(state[0]);
263
264 mib[0] = CTL_KERN;
265 mib[1] = KERN_ARND;
266 sysctl(mib, 2, state, &len, NULL, 0);
267
268 if (rand_type != TYPE_0) {
269 fptr = &state[rand_sep];
270 rptr = &state[0];
271 }
272 UNLOCK();
273}
274
275#if defined(APIWARN)
276__warn_references(srandomdev,
277 "warning: srandomdev() usage; consider switching to arc4random()");
278#endif
279
212/* 280/*
213 * initstate: 281 * initstate:
214 * 282 *
@@ -229,21 +297,18 @@ srandom(x)
229 * Returns a pointer to the old state. 297 * Returns a pointer to the old state.
230 */ 298 */
231char * 299char *
232initstate(seed, arg_state, n) 300initstate(u_int seed, char *arg_state, size_t n)
233 u_int seed; /* seed for R.N.G. */
234 char *arg_state; /* pointer to state array */
235 int n; /* # bytes of state info */
236{ 301{
237 register char *ostate = (char *)(&state[-1]); 302 char *ostate = (char *)(&state[-1]);
238 303
304 LOCK();
239 if (rand_type == TYPE_0) 305 if (rand_type == TYPE_0)
240 state[-1] = rand_type; 306 state[-1] = rand_type;
241 else 307 else
242 state[-1] = MAX_TYPES * (rptr - state) + rand_type; 308 state[-1] = MAX_TYPES * (rptr - state) + rand_type;
243 if (n < BREAK_0) { 309 if (n < BREAK_0) {
244 (void)fprintf(stderr, 310 UNLOCK();
245 "random: not enough state (%d bytes); ignored.\n", n); 311 return(NULL);
246 return(0);
247 } 312 }
248 if (n < BREAK_1) { 313 if (n < BREAK_1) {
249 rand_type = TYPE_0; 314 rand_type = TYPE_0;
@@ -266,13 +331,14 @@ initstate(seed, arg_state, n)
266 rand_deg = DEG_4; 331 rand_deg = DEG_4;
267 rand_sep = SEP_4; 332 rand_sep = SEP_4;
268 } 333 }
269 state = &(((long *)arg_state)[1]); /* first location */ 334 state = &(((int32_t *)arg_state)[1]); /* first location */
270 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ 335 end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
271 srandom(seed); 336 srandom_l(seed);
272 if (rand_type == TYPE_0) 337 if (rand_type == TYPE_0)
273 state[-1] = rand_type; 338 state[-1] = rand_type;
274 else 339 else
275 state[-1] = MAX_TYPES*(rptr - state) + rand_type; 340 state[-1] = MAX_TYPES*(rptr - state) + rand_type;
341 UNLOCK();
276 return(ostate); 342 return(ostate);
277} 343}
278 344
@@ -292,14 +358,14 @@ initstate(seed, arg_state, n)
292 * Returns a pointer to the old state information. 358 * Returns a pointer to the old state information.
293 */ 359 */
294char * 360char *
295setstate(arg_state) 361setstate(char *arg_state)
296 char *arg_state;
297{ 362{
298 register long *new_state = (long *)arg_state; 363 int32_t *new_state = (int32_t *)arg_state;
299 register int type = new_state[0] % MAX_TYPES; 364 int32_t type = new_state[0] % MAX_TYPES;
300 register int rear = new_state[0] / MAX_TYPES; 365 int32_t rear = new_state[0] / MAX_TYPES;
301 char *ostate = (char *)(&state[-1]); 366 char *ostate = (char *)(&state[-1]);
302 367
368 LOCK();
303 if (rand_type == TYPE_0) 369 if (rand_type == TYPE_0)
304 state[-1] = rand_type; 370 state[-1] = rand_type;
305 else 371 else
@@ -315,8 +381,8 @@ setstate(arg_state)
315 rand_sep = seps[type]; 381 rand_sep = seps[type];
316 break; 382 break;
317 default: 383 default:
318 (void)fprintf(stderr, 384 UNLOCK();
319 "random: state info corrupted; not changed.\n"); 385 return(NULL);
320 } 386 }
321 state = &new_state[1]; 387 state = &new_state[1];
322 if (rand_type != TYPE_0) { 388 if (rand_type != TYPE_0) {
@@ -324,6 +390,7 @@ setstate(arg_state)
324 fptr = &state[(rear + rand_sep) % rand_deg]; 390 fptr = &state[(rear + rand_sep) % rand_deg];
325 } 391 }
326 end_ptr = &state[rand_deg]; /* set end_ptr too */ 392 end_ptr = &state[rand_deg]; /* set end_ptr too */
393 UNLOCK();
327 return(ostate); 394 return(ostate);
328} 395}
329 396
@@ -344,10 +411,10 @@ setstate(arg_state)
344 * 411 *
345 * Returns a 31-bit random number. 412 * Returns a 31-bit random number.
346 */ 413 */
347long 414static long
348random() 415random_l(void)
349{ 416{
350 long i; 417 int32_t i;
351 418
352 if (rand_type == TYPE_0) 419 if (rand_type == TYPE_0)
353 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; 420 i = state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff;
@@ -360,5 +427,20 @@ random()
360 } else if (++rptr >= end_ptr) 427 } else if (++rptr >= end_ptr)
361 rptr = state; 428 rptr = state;
362 } 429 }
363 return(i); 430 return((long)i);
431}
432
433long
434random(void)
435{
436 long r;
437 LOCK();
438 r = random_l();
439 UNLOCK();
440 return r;
364} 441}
442
443#if defined(APIWARN)
444__warn_references(random,
445 "warning: random() isn't random; consider using arc4random()");
446#endif