diff --git a/src/include/stdlib.h b/src/include/stdlib.h index 1f8e4a35..d048e704 100644 --- a/src/include/stdlib.h +++ b/src/include/stdlib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stdlib.h,v 1.61 2014/12/08 20:39:56 tedu Exp $ */ +/* $OpenBSD: stdlib.h,v 1.62 2014/12/08 21:45:19 deraadt Exp $ */ /* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */ /*- @@ -131,6 +131,7 @@ void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); int rand(void); void *realloc(void *, size_t); void srand(unsigned); +void srand_deterministic(unsigned); double strtod(const char *, char **); float strtof(const char *, char **); long strtol(const char *, char **, int); @@ -159,11 +160,14 @@ double drand48(void); double erand48(unsigned short[3]); long jrand48(unsigned short[3]); void lcong48(unsigned short[7]); +void lcong48_deterministic(unsigned short[7]); long lrand48(void); long mrand48(void); long nrand48(unsigned short[3]); unsigned short *seed48(unsigned short[3]); +unsigned short *seed48_deterministic(unsigned short[3]); void srand48(long); +void srand48_deterministic(long); int putenv(char *); #endif @@ -190,6 +194,7 @@ char *initstate(unsigned int, char *, size_t) long random(void); char *setstate(char *); void srandom(unsigned int); +void srandom_deterministic(unsigned int); char *realpath(const char *, char *) __attribute__((__bounded__ (__minbytes__,2,1024))); diff --git a/src/lib/libc/stdlib/Makefile.inc b/src/lib/libc/stdlib/Makefile.inc index 3a13d9ff..3e99fe11 100644 --- a/src/lib/libc/stdlib/Makefile.inc +++ b/src/lib/libc/stdlib/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.56 2014/12/08 20:39:16 tedu Exp $ +# $OpenBSD: Makefile.inc,v 1.57 2014/12/08 21:45:20 deraadt Exp $ # stdlib sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/stdlib ${LIBCSRCDIR}/stdlib @@ -43,12 +43,14 @@ MLINKS+=malloc.3 free.3 malloc.3 realloc.3 malloc.3 calloc.3 MLINKS+=malloc.3 reallocarray.3 MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 MLINKS+=radixsort.3 sradixsort.3 -MLINKS+=rand.3 srand.3 rand.3 rand_r.3 +MLINKS+=rand.3 srand.3 rand.3 rand_r.3 rand.3 srand_deterministic.3 MLINKS+=random.3 initstate.3 random.3 setstate.3 -MLINKS+=random.3 srandom.3 random.3 srandomdev.3 +MLINKS+=random.3 srandom.3 random.3 srandomdev.3 random.3 srandom_deterministic.3 MLINKS+=rand48.3 drand48.3 rand48.3 erand48.3 rand48.3 lrand48.3 MLINKS+=rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 jrand48.3 -MLINKS+=rand48.3 srand48.3 rand48.3 seed48.3 rand48.3 lcong48.3 +MLINKS+=rand48.3 srand48.3 rand48.3 srand48_deterministic.3 +MLINKS+=rand48.3 seed48.3 rand48.3 seed48_deterministic.3 +MLINKS+=rand48.3 lcong48.3 rand48.3 lcong48_deterministic.3 MLINKS+=ptsname.3 grantpt.3 ptsname.3 unlockpt.3 MLINKS+=strtod.3 strtof.3 strtod.3 strtold.3 MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.3 diff --git a/src/lib/libc/stdlib/drand48.c b/src/lib/libc/stdlib/drand48.c index b6c046c8..bbeedf8a 100644 --- a/src/lib/libc/stdlib/drand48.c +++ b/src/lib/libc/stdlib/drand48.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ +/* $OpenBSD: drand48.c,v 1.4 2014/12/08 21:45:20 deraadt Exp $ */ /* * Copyright (c) 1993 Martin Birgmeier * All rights reserved. @@ -19,5 +19,13 @@ extern unsigned short __rand48_seed[3]; double drand48(void) { + if (__rand48_deterministic == 0) { + short rseed[3]; + + arc4random_buf(rseed, sizeof rseed); + return ldexp((double) rseed[0], -48) + + ldexp((double) rseed[1], -32) + + ldexp((double) rseed[2], -16); + } return erand48(__rand48_seed); } diff --git a/src/lib/libc/stdlib/lcong48.c b/src/lib/libc/stdlib/lcong48.c index 2cf5c271..09726efb 100644 --- a/src/lib/libc/stdlib/lcong48.c +++ b/src/lib/libc/stdlib/lcong48.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lcong48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ +/* $OpenBSD: lcong48.c,v 1.4 2014/12/08 21:45:20 deraadt Exp $ */ /* * Copyright (c) 1993 Martin Birgmeier * All rights reserved. @@ -21,6 +21,14 @@ extern unsigned short __rand48_add; void lcong48(unsigned short p[7]) { + lcong48_deterministic(p); + __rand48_deterministic = 0; +} + +void +lcong48_deterministic(unsigned short p[7]) +{ + __rand48_deterministic = 1; __rand48_seed[0] = p[0]; __rand48_seed[1] = p[1]; __rand48_seed[2] = p[2]; diff --git a/src/lib/libc/stdlib/lrand48.c b/src/lib/libc/stdlib/lrand48.c index 21beb858..22508594 100644 --- a/src/lib/libc/stdlib/lrand48.c +++ b/src/lib/libc/stdlib/lrand48.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lrand48.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */ +/* $OpenBSD: lrand48.c,v 1.4 2014/12/08 21:45:20 deraadt Exp $ */ /* * Copyright (c) 1993 Martin Birgmeier * All rights reserved. @@ -19,6 +19,8 @@ extern unsigned short __rand48_seed[3]; long lrand48(void) { + if (__rand48_deterministic == 0) + return arc4random() & 0x7fffffff; __dorand48(__rand48_seed); return ((long) __rand48_seed[2] << 15) + ((long) __rand48_seed[1] >> 1); } diff --git a/src/lib/libc/stdlib/mrand48.c b/src/lib/libc/stdlib/mrand48.c index 977264ab..7bfccbbf 100644 --- a/src/lib/libc/stdlib/mrand48.c +++ b/src/lib/libc/stdlib/mrand48.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mrand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ +/* $OpenBSD: mrand48.c,v 1.4 2014/12/08 21:45:20 deraadt Exp $ */ /* * Copyright (c) 1993 Martin Birgmeier * All rights reserved. @@ -19,6 +19,8 @@ extern unsigned short __rand48_seed[3]; long mrand48(void) { + if (__rand48_deterministic == 0) + return arc4random(); __dorand48(__rand48_seed); return ((long) __rand48_seed[2] << 16) + (long) __rand48_seed[1]; } diff --git a/src/lib/libc/stdlib/rand.3 b/src/lib/libc/stdlib/rand.3 index 5d4bfe7a..c760161b 100644 --- a/src/lib/libc/stdlib/rand.3 +++ b/src/lib/libc/stdlib/rand.3 @@ -29,52 +29,65 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: rand.3,v 1.17 2014/11/25 17:41:12 millert Exp $ +.\" $OpenBSD: rand.3,v 1.18 2014/12/08 21:45:20 deraadt Exp $ .\" -.Dd $Mdocdate: November 25 2014 $ +.Dd $Mdocdate: December 8 2014 $ .Dt RAND 3 .Os .Sh NAME .Nm rand , .Nm rand_r , -.Nm srand +.Nm srand , +.Nm srand_deterministic .Nd bad pseudo-random number generator .Sh SYNOPSIS .In stdlib.h .Ft void .Fn srand "unsigned int seed" +.Ft void +.Fn srand_deterministic "unsigned int seed" .Ft int .Fn rand void .Ft int .Fn rand_r "unsigned int *seed" .Sh DESCRIPTION .Bf -symbolic -These interfaces are obsoleted by -.Xr random 3 , -which is also unsafe. -Consider using -.Xr arc4random 3 . +Standards insist that this interface return deterministic results. +Unsafe usage is very common, so +.Ox +changed the subsystem to return non-deterministic results by default. .Ef .Pp -The +To satisfy portable code, +.Fn srand +may be called to initialize the subsystem. +In +.Ox +the +.Ar seed +variable is ignored, and strong random number results will be provided from +.Xr arc4random 3. +In other systems, the +.Ar seed +variable primes a simplistic deterministic algorithm. +.Pp +If the standardized behavior is required +.Fn srand_deterministic +can be substituted for +.Fn srand , +then subsequent .Fn rand -function computes a sequence of pseudo-random integers in the range -of 0 to -.Dv RAND_MAX -(as defined by the header file -.In stdlib.h ) . +calls will return results using the deterministic algorithm. .Pp The -.Fn srand -function sets its argument as the seed for a new sequence of -pseudo-random numbers to be returned by -.Fn rand . -These sequences are repeatable by calling -.Fn srand -with the same seed value. -.Pp -If no seed value is provided, the functions are automatically -seeded with a value of 1. +.Fn rand +function returns a result in the range of 0 to +.Dv RAND_MAX . +By default, this result comes from +.Xr arc4random 3 . +If +.Fn srand_deterministic +was called, the result will be computed using the deterministic algorithm. .Pp The .Fn rand_r @@ -83,6 +96,7 @@ is a thread-safe version of Storage for the seed must be provided through the .Fa seed argument, and needs to have been initialized by the caller. +It always operates using the deterministic algorithm. .Sh SEE ALSO .Xr arc4random 3 , .Xr rand48 3 , @@ -90,15 +104,23 @@ argument, and needs to have been initialized by the caller. .Sh STANDARDS The .Fn rand -and -.Fn srand -functions conform to +function conforms to .St -ansiC . .Pp The .Fn rand_r function conforms to .St -p1003.1-2008 . +.Pp +The +.Fn srand +function does not conform to +.St -ansiC , +intentionally. +.Pp +The +.Fn srand_deterministic +function is an OpenBSD extension. .Sh HISTORY The functions .Fn rand diff --git a/src/lib/libc/stdlib/rand.c b/src/lib/libc/stdlib/rand.c index 6860dd4f..618559fd 100644 --- a/src/lib/libc/stdlib/rand.c +++ b/src/lib/libc/stdlib/rand.c @@ -30,6 +30,7 @@ #include #include +static int rand_deterministic; static u_int next = 1; int @@ -47,6 +48,8 @@ __warn_references(rand_r, int rand(void) { + if (rand_deterministic) + return (arc4random() % ((u_int)RAND_MAX + 1)); return (rand_r(&next)); } @@ -58,10 +61,12 @@ __warn_references(rand, void srand(u_int seed) { - next = seed; + rand_deterministic = 0; } -#if defined(APIWARN) -__warn_references(srand, - "warning: srand() seed choices are invariably poor"); -#endif +void +srand_deterministic(u_int seed) +{ + rand_deterministic = 1; + next = seed; +} diff --git a/src/lib/libc/stdlib/rand48.3 b/src/lib/libc/stdlib/rand48.3 index a4473185..dce8c0dd 100644 --- a/src/lib/libc/stdlib/rand48.3 +++ b/src/lib/libc/stdlib/rand48.3 @@ -9,9 +9,9 @@ .\" of any kind. I shall in no event be liable for anything that happens .\" to anyone/anything when using this software. .\" -.\" $OpenBSD: rand48.3,v 1.16 2014/11/25 17:26:34 millert Exp $ +.\" $OpenBSD: rand48.3,v 1.17 2014/12/08 21:45:20 deraadt Exp $ .\" -.Dd $Mdocdate: November 25 2014 $ +.Dd $Mdocdate: December 8 2014 $ .Dt RAND48 3 .Os .Sh NAME @@ -22,8 +22,11 @@ .Nm mrand48 , .Nm jrand48 , .Nm srand48 , +.Nm srand48_deterministic , .Nm seed48 , +.Nm seed48_deterministic , .Nm lcong48 +.Nm lcong48_deterministic .Nd pseudo-random number generators and initialization routines .Sh SYNOPSIS .In stdlib.h @@ -41,31 +44,56 @@ .Fn jrand48 "unsigned short xseed[3]" .Ft void .Fn srand48 "long seed" +.Ft void +.Fn srand48_deterministic "long seed" .Ft "unsigned short *" .Fn seed48 "unsigned short xseed[3]" +.Ft "unsigned short *" +.Fn seed48_deterministic "unsigned short xseed[3]" .Ft void .Fn lcong48 "unsigned short p[7]" +.Ft void +.Fn lcong48_deterministic "unsigned short p[7]" .Sh DESCRIPTION .Bf -symbolic -This interface is not cryptographically secure, so consider using -.Xr arc4random 3 -instead. +Standards insist that this interface return deterministic results. +Unsafe usage is very common, so +.Ox +changed the subsystem to return non-deterministic results by default. .Ef .Pp -The -.Fn rand48 -family of functions generates pseudo-random numbers using a linear -congruential algorithm working on integers 48 bits in size. -The particular formula employed is -r(n+1) = (a * r(n) + c) mod m -where the default values are -for the multiplicand a = 0xfdeece66d = 25214903917 and -the addend c = 0xb = 11. -The modulus is always fixed at m = 2 ** 48. -r(n) is called the seed of the random number generator. +To satisfy portable code, +.Fn srand48 , +.Fn seed48 , +or +.Fn lcong48 +should be called to initialize the subsystem. +In +.Ox +the +seeding parameters are ignored, and strong random number results will be +provided from +.Xr arc4random 3. +In other systems, the +parameters prime a simplistic deterministic algorithm. .Pp -For all the six generator routines described next, the first -computational step is to perform a single iteration of the algorithm. +If the standardized behavior is required then +.Fn srand48_deterministic , +.Fn seed48_deterministic , +and +.Fn lcong48_deterministic +can be substituted for +.Fn srand48 , +.Fn seed48 , +and +.Fn lcong48 . +That will cause subsequent +calls to +.Fn drand48 , +.Fn lrand48 , +and +.Fn jrand48 +to return results using the deterministic algorithm. .Pp .Fn drand48 and @@ -91,6 +119,21 @@ return values of type long in the range [-2**31, 2**31-1]. The high-order (32) bits of r(n+1) are loaded into the returned value. .Pp +In the deterministic mode, the +.Fn rand48 +family of functions generates numbers using a linear congruential +algorithm working on integers 48 bits in size. +The particular formula employed is +r(n+1) = (a * r(n) + c) mod m +where the default values are +for the multiplicand a = 0xfdeece66d = 25214903917 and +the addend c = 0xb = 11. +The modulus is always fixed at m = 2 ** 48. +r(n) is called the seed of the random number generator. +.Pp +For all the six generator routines described next, the first +computational step is to perform a single iteration of the algorithm. +.Pp .Fn drand48 , .Fn lrand48 , and @@ -110,7 +153,7 @@ holds the least significant bits. .Pp All functions share the same multiplicand and addend. .Pp -.Fn srand48 +.Fn srand48_deterministic is used to initialize the internal buffer r(n) of .Fn drand48 , .Fn lrand48 , @@ -121,7 +164,7 @@ of r(n), with the lower 16 bits of r(n) arbitrarily being set to 0x330e. Additionally, the constant multiplicand and addend of the algorithm are reset to the default values given above. .Pp -.Fn seed48 +.Fn seed48_deterministic also initializes the internal buffer r(n) of .Fn drand48 , .Fn lrand48 , @@ -131,14 +174,14 @@ but here all 48 bits of the seed can be specified in an array of 3 shorts, where the zeroth member specifies the lowest bits. Again, the constant multiplicand and addend of the algorithm are reset to the default values given above. -.Fn seed48 +.Fn seed48_deterministic returns a pointer to an array of 3 shorts which contains the old seed. This array is statically allocated, so its contents are lost after each new call to -.Fn seed48 . +.Fn seed48_deterministic . .Pp Finally, -.Fn lcong48 +.Fn lcong48_deterministic allows full control over the multiplicand and addend used in .Fn drand48 , .Fn erand48 , @@ -169,14 +212,27 @@ The .Fn drand48 , .Fn erand48 , .Fn jrand48 , -.Fn lcong48 , .Fn lrand48 , .Fn mrand48 , -.Fn nrand48 , -.Fn seed48 , and -.Fn srand48 +.Fn nrand48 , functions conform to .St -p1003.1-2008 . +.Pp +The +.Fn seed48 , +.Fn srand48 , +and +.Fn lcong48 +function do not conform to +.St -ansiC , +intentionally. +.Pp +The +.Fn seed48_deterministic , +.Fn srand48_deterministic , +and +.Fn lcong48_deterministic +functions are OpenBSD extensions. .Sh AUTHORS .An Martin Birgmeier diff --git a/src/lib/libc/stdlib/rand48.h b/src/lib/libc/stdlib/rand48.h index afa49f65..ee701747 100644 --- a/src/lib/libc/stdlib/rand48.h +++ b/src/lib/libc/stdlib/rand48.h @@ -10,7 +10,7 @@ * of any kind. I shall in no event be liable for anything that happens * to anyone/anything when using this software. * - * $OpenBSD: rand48.h,v 1.3 2002/02/16 21:27:24 millert Exp $ + * $OpenBSD: rand48.h,v 1.4 2014/12/08 21:45:20 deraadt Exp $ */ #ifndef _RAND48_H_ @@ -20,6 +20,7 @@ #include void __dorand48(unsigned short[3]); +extern int __rand48_deterministic; #define RAND48_SEED_0 (0x330e) #define RAND48_SEED_1 (0xabcd) diff --git a/src/lib/libc/stdlib/random.3 b/src/lib/libc/stdlib/random.3 index b3bc560a..ad92b603 100644 --- a/src/lib/libc/stdlib/random.3 +++ b/src/lib/libc/stdlib/random.3 @@ -25,14 +25,15 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: random.3,v 1.26 2014/11/25 17:40:38 millert Exp $ +.\" $OpenBSD: random.3,v 1.27 2014/12/08 21:45:20 deraadt Exp $ .\" -.Dd $Mdocdate: November 25 2014 $ +.Dd $Mdocdate: December 8 2014 $ .Dt RANDOM 3 .Os .Sh NAME .Nm random , .Nm srandom , +.Nm srandom_deterministic , .Nm srandomdev , .Nm initstate , .Nm setstate @@ -44,6 +45,8 @@ .Ft void .Fn srandom "unsigned int seed" .Ft void +.Fn srandom_deterministic "unsigned int seed" +.Ft void .Fn srandomdev void .Ft char * .Fn initstate "unsigned int seed" "char *state" "size_t n" @@ -51,58 +54,48 @@ .Fn setstate "char *state" .Sh DESCRIPTION .Bf -symbolic -This interface is not cryptographically secure, so consider using -.Xr arc4random 3 -instead. +Standards insist that this interface return deterministic results. +Unsafe usage is very common, so +.Ox +changed the subsystem to return non-deterministic results by default. .Ef .Pp -The -.Fn random -function uses a non-linear additive feedback random number generator employing -a default table of size 31 long integers to return successive pseudo-random -numbers in the range from 0 to (2**31)\-1. -The period of this random number generator is very large, approximately -16*((2**31)\-1). -.Pp -The -.Fn random -and +To satisfy portable code, .Fn srandom -functions have (almost) the same calling sequence and initialization -properties as -.Xr rand 3 Ns / Ns Xr srand 3 . -The difference is that -.Xr rand -produces a much less random sequence \(em in fact, the low dozen bits -generated by rand go through a cyclic pattern. -All the bits generated by +or +.Fn srandomdev +may be called to initialize the subsystem. +In +.Ox +the +.Ar seed +variable is ignored, and strong random number results will be provided from +.Xr arc4random 3. +In other systems, the +.Ar seed +variable primes a simplistic deterministic algorithm. +.Pp +If the standardized behavior is required +.Fn srandom_deterministic +can be substituted for +.Fn srandom , +then subsequent .Fn random -are usable. -For example, -.Sq Li random()&01 -will produce a random binary -value. +calls will return results using the deterministic algorithm. .Pp -Like -.Xr rand 3 , +In non-deterministic (default) mode, the .Fn random -will by default produce a sequence of numbers that can be duplicated -by calling -.Fn srandom -with -.Ql 1 -as the seed. +function returns results from +.Xr arc4random 3 +in the range from 0 to (2**31)\-1. .Pp -The -.Fn srandomdev -routine switches to an algorithm using state derived from -random numbers obtained from the kernel. -Note that this particular seeding procedure can generate -states which are impossible to reproduce by calling -.Fn srandom -with any value, since the succeeding terms in the -state buffer are no longer derived from the LC algorithm applied to -a fixed seed. +In deterministic mode, the +.Fn random +function uses a non-linear additive feedback random number generator employing +a default table of size 31 long integers to return successive pseudo-random +numbers in the range from 0 to (2**31)\-1. +The period of this random number generator is very large, approximately +16*((2**31)\-1), but the results are a deterministic sequence from the seed. .Pp The .Fn initstate @@ -151,9 +144,12 @@ and is that the size of the state array does not have to be remembered after it is initialized. .Pp -With 256 bytes of state information, the period of the random number -generator is greater than 2**69 -which should be sufficient for most purposes. +Use of +.Fn srandom_deterministic , +.Fn initstate , +or +.Fn setstate +forces the subsystem into deterministic mode. .Sh DIAGNOSTICS If .Fn initstate @@ -169,7 +165,6 @@ messages are printed on the standard error output. .Sh STANDARDS The .Fn random , -.Fn srandom , .Fn initstate , and .Fn setstate @@ -177,14 +172,21 @@ functions conform to .St -xpg4.2 . .Pp The +.Fn srandom +function does not conform to +.St -xpg4.2 , +intentionally. +.Pp +The .Fn srandomdev function is an extension. +.Pp +The +.Fn srandom_deterministic +function is an OpenBSD extension. .Sh HISTORY These functions appeared in .Bx 4.2 . .Sh AUTHORS .An Earl T. Cohen -.Sh BUGS -The historical implementation used to have very weak seeding. -As a result, the random sequence did not vary much with the seed. diff --git a/src/lib/libc/stdlib/random.c b/src/lib/libc/stdlib/random.c index e4ff07ea..cba088c7 100644 --- a/src/lib/libc/stdlib/random.c +++ b/src/lib/libc/stdlib/random.c @@ -1,4 +1,4 @@ -/* $OpenBSD: random.c,v 1.24 2014/10/13 20:54:13 chl Exp $ */ +/* $OpenBSD: random.c,v 1.25 2014/12/08 21:45:20 deraadt Exp $ */ /* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. @@ -176,7 +176,7 @@ static int rand_type = TYPE_3; static int rand_deg = DEG_3; static int rand_sep = SEP_3; -static int use_arc4random; +static int random_deterministic; _THREAD_PRIVATE_MUTEX(random); static long random_l(void); @@ -203,7 +203,7 @@ srandom_l(unsigned int x) int32_t test; div_t val; - use_arc4random = 0; + random_deterministic = 1; if (rand_type == TYPE_0) state[0] = x; else { @@ -231,39 +231,23 @@ srandom_l(unsigned int x) void srandom(unsigned int x) { - LOCK(); - srandom_l(x); - UNLOCK(); + random_deterministic = 0; } -#if defined(APIWARN) -__warn_references(srandom, - "warning: srandom() seed choices are invariably poor"); -#endif - -/* - * srandomdev: - * - * Many programs choose the seed value in a totally predictable manner. - * This often causes problems. We seed the generator using random data. - * Note that this particular seeding procedure can generate states - * which are impossible to reproduce by calling srandom() with any - * value, since the succeeding terms in the state buffer are no longer - * derived from the LC algorithm applied to a fixed seed. - */ void srandomdev(void) +{ + random_deterministic = 0; /* back to the default */ +} + +void +srandom_deterministic(unsigned int x) { LOCK(); - use_arc4random = 1; + srandom_l(x); UNLOCK(); } -#if defined(APIWARN) -__warn_references(srandomdev, - "warning: srandomdev() usage; consider switching to arc4random()"); -#endif - /* * initstate: * @@ -289,7 +273,7 @@ initstate(u_int seed, char *arg_state, size_t n) char *ostate = (char *)(&state[-1]); LOCK(); - use_arc4random = 0; + random_deterministic = 1; if (rand_type == TYPE_0) state[-1] = rand_type; else @@ -354,7 +338,7 @@ setstate(char *arg_state) char *ostate = (char *)(&state[-1]); LOCK(); - use_arc4random = 0; + random_deterministic = 1; if (rand_type == TYPE_0) state[-1] = rand_type; else @@ -405,7 +389,7 @@ random_l(void) { int32_t i; - if (use_arc4random) + if (random_deterministic == 0) return arc4random() & 0x7fffffff; if (rand_type == TYPE_0) @@ -431,8 +415,3 @@ random(void) UNLOCK(); return r; } - -#if defined(APIWARN) -__warn_references(random, - "warning: random() isn't random; consider using arc4random()"); -#endif diff --git a/src/lib/libc/stdlib/seed48.c b/src/lib/libc/stdlib/seed48.c index 583262f2..7acb4e6d 100644 --- a/src/lib/libc/stdlib/seed48.c +++ b/src/lib/libc/stdlib/seed48.c @@ -1,4 +1,4 @@ -/* $OpenBSD: seed48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ +/* $OpenBSD: seed48.c,v 1.4 2014/12/08 21:45:20 deraadt Exp $ */ /* * Copyright (c) 1993 Martin Birgmeier * All rights reserved. @@ -20,9 +20,20 @@ extern unsigned short __rand48_add; unsigned short * seed48(unsigned short xseed[3]) +{ + unsigned short *res; + + res = seed48_deterministic(xseed); + __rand48_deterministic = 0; + return res; +} + +unsigned short * +seed48_deterministic(unsigned short xseed[3]) { static unsigned short sseed[3]; + __rand48_deterministic = 1; sseed[0] = __rand48_seed[0]; sseed[1] = __rand48_seed[1]; sseed[2] = __rand48_seed[2]; diff --git a/src/lib/libc/stdlib/srand48.c b/src/lib/libc/stdlib/srand48.c index f76b6cca..115b9e82 100644 --- a/src/lib/libc/stdlib/srand48.c +++ b/src/lib/libc/stdlib/srand48.c @@ -1,4 +1,4 @@ -/* $OpenBSD: srand48.c,v 1.3 2005/08/08 08:05:37 espie Exp $ */ +/* $OpenBSD: srand48.c,v 1.4 2014/12/08 21:45:20 deraadt Exp $ */ /* * Copyright (c) 1993 Martin Birgmeier * All rights reserved. @@ -18,9 +18,19 @@ extern unsigned short __rand48_seed[3]; extern unsigned short __rand48_mult[3]; extern unsigned short __rand48_add; +int __rand48_deterministic; + void srand48(long seed) { + srand48_deterministic(seed); + __rand48_deterministic = 0; +} + +void +srand48_deterministic(long seed) +{ + __rand48_deterministic = 1; __rand48_seed[0] = RAND48_SEED_0; __rand48_seed[1] = (unsigned short) seed; __rand48_seed[2] = (unsigned short) (seed >> 16);