diff options
author | deraadt <> | 2014-12-08 21:45:20 +0000 |
---|---|---|
committer | deraadt <> | 2014-12-08 21:45:20 +0000 |
commit | 1e2b0be5bee045db1b0abb1f87801004db563bb8 (patch) | |
tree | bf17a76201de02c2ce50358a383001a6b6c5cc64 /src/lib/libc/stdlib/random.c | |
parent | 4b0b4fc5d98edef87738071b3784e13573327bab (diff) | |
download | openbsd-1e2b0be5bee045db1b0abb1f87801004db563bb8.tar.gz openbsd-1e2b0be5bee045db1b0abb1f87801004db563bb8.tar.bz2 openbsd-1e2b0be5bee045db1b0abb1f87801004db563bb8.zip |
Change rand(), random(), drand48(), lrand48(), mrand48(), and srand48()
to returning strong random by default, source from arc4random(3).
Parameters to the seeding functions are ignored, and the subsystems remain
in strong random mode. If you wish the standardized deterministic mode,
call srand_deterministic(), srandom_determistic(), srand48_deterministic(),
seed48_deterministic() or lcong48_deterministic() instead.
The re-entrant functions rand_r(), erand48(), nrand48(), jrand48() are
unaffected by this change and remain in deterministic mode (for now).
Verified as a good roadmap forward by auditing 8800 pieces of software.
Roughly 60 pieces of software will need adaptation to request the
deterministic mode.
Violates POSIX and C89, which violate best practice in this century.
ok guenther tedu millert
Diffstat (limited to 'src/lib/libc/stdlib/random.c')
-rw-r--r-- | src/lib/libc/stdlib/random.c | 49 |
1 files changed, 14 insertions, 35 deletions
diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c index e4ff07ea0c..cba088c751 100644 --- a/src/lib/libc/stdlib/random.c +++ b/src/lib/libc/stdlib/random.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: random.c,v 1.24 2014/10/13 20:54:13 chl Exp $ */ | 1 | /* $OpenBSD: random.c,v 1.25 2014/12/08 21:45:20 deraadt Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1983 Regents of the University of California. | 3 | * Copyright (c) 1983 Regents of the University of California. |
4 | * All rights reserved. | 4 | * All rights reserved. |
@@ -176,7 +176,7 @@ static int rand_type = TYPE_3; | |||
176 | static int rand_deg = DEG_3; | 176 | static int rand_deg = DEG_3; |
177 | static int rand_sep = SEP_3; | 177 | static int rand_sep = SEP_3; |
178 | 178 | ||
179 | static int use_arc4random; | 179 | static int random_deterministic; |
180 | 180 | ||
181 | _THREAD_PRIVATE_MUTEX(random); | 181 | _THREAD_PRIVATE_MUTEX(random); |
182 | static long random_l(void); | 182 | static long random_l(void); |
@@ -203,7 +203,7 @@ srandom_l(unsigned int x) | |||
203 | int32_t test; | 203 | int32_t test; |
204 | div_t val; | 204 | div_t val; |
205 | 205 | ||
206 | use_arc4random = 0; | 206 | random_deterministic = 1; |
207 | if (rand_type == TYPE_0) | 207 | if (rand_type == TYPE_0) |
208 | state[0] = x; | 208 | state[0] = x; |
209 | else { | 209 | else { |
@@ -231,39 +231,23 @@ srandom_l(unsigned int x) | |||
231 | void | 231 | void |
232 | srandom(unsigned int x) | 232 | srandom(unsigned int x) |
233 | { | 233 | { |
234 | LOCK(); | 234 | random_deterministic = 0; |
235 | srandom_l(x); | ||
236 | UNLOCK(); | ||
237 | } | 235 | } |
238 | 236 | ||
239 | #if defined(APIWARN) | ||
240 | __warn_references(srandom, | ||
241 | "warning: srandom() seed choices are invariably poor"); | ||
242 | #endif | ||
243 | |||
244 | /* | ||
245 | * srandomdev: | ||
246 | * | ||
247 | * Many programs choose the seed value in a totally predictable manner. | ||
248 | * This often causes problems. We seed the generator using random data. | ||
249 | * Note that this particular seeding procedure can generate states | ||
250 | * which are impossible to reproduce by calling srandom() with any | ||
251 | * value, since the succeeding terms in the state buffer are no longer | ||
252 | * derived from the LC algorithm applied to a fixed seed. | ||
253 | */ | ||
254 | void | 237 | void |
255 | srandomdev(void) | 238 | srandomdev(void) |
256 | { | 239 | { |
240 | random_deterministic = 0; /* back to the default */ | ||
241 | } | ||
242 | |||
243 | void | ||
244 | srandom_deterministic(unsigned int x) | ||
245 | { | ||
257 | LOCK(); | 246 | LOCK(); |
258 | use_arc4random = 1; | 247 | srandom_l(x); |
259 | UNLOCK(); | 248 | UNLOCK(); |
260 | } | 249 | } |
261 | 250 | ||
262 | #if defined(APIWARN) | ||
263 | __warn_references(srandomdev, | ||
264 | "warning: srandomdev() usage; consider switching to arc4random()"); | ||
265 | #endif | ||
266 | |||
267 | /* | 251 | /* |
268 | * initstate: | 252 | * initstate: |
269 | * | 253 | * |
@@ -289,7 +273,7 @@ initstate(u_int seed, char *arg_state, size_t n) | |||
289 | char *ostate = (char *)(&state[-1]); | 273 | char *ostate = (char *)(&state[-1]); |
290 | 274 | ||
291 | LOCK(); | 275 | LOCK(); |
292 | use_arc4random = 0; | 276 | random_deterministic = 1; |
293 | if (rand_type == TYPE_0) | 277 | if (rand_type == TYPE_0) |
294 | state[-1] = rand_type; | 278 | state[-1] = rand_type; |
295 | else | 279 | else |
@@ -354,7 +338,7 @@ setstate(char *arg_state) | |||
354 | char *ostate = (char *)(&state[-1]); | 338 | char *ostate = (char *)(&state[-1]); |
355 | 339 | ||
356 | LOCK(); | 340 | LOCK(); |
357 | use_arc4random = 0; | 341 | random_deterministic = 1; |
358 | if (rand_type == TYPE_0) | 342 | if (rand_type == TYPE_0) |
359 | state[-1] = rand_type; | 343 | state[-1] = rand_type; |
360 | else | 344 | else |
@@ -405,7 +389,7 @@ random_l(void) | |||
405 | { | 389 | { |
406 | int32_t i; | 390 | int32_t i; |
407 | 391 | ||
408 | if (use_arc4random) | 392 | if (random_deterministic == 0) |
409 | return arc4random() & 0x7fffffff; | 393 | return arc4random() & 0x7fffffff; |
410 | 394 | ||
411 | if (rand_type == TYPE_0) | 395 | if (rand_type == TYPE_0) |
@@ -431,8 +415,3 @@ random(void) | |||
431 | UNLOCK(); | 415 | UNLOCK(); |
432 | return r; | 416 | return r; |
433 | } | 417 | } |
434 | |||
435 | #if defined(APIWARN) | ||
436 | __warn_references(random, | ||
437 | "warning: random() isn't random; consider using arc4random()"); | ||
438 | #endif | ||