Re: [PATCH] rand.c updates from FreeBSD RELENG_5

看板DFBSD_submit作者時間21年前 (2004/05/13 16:32), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串7/18 (看更多)
This is a multi-part message in MIME format. --------------050404070007040706070202 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Matthew Dillon wrote: > It looks pretty good. Hiten had some minor comments about retaining > the $ cvs tags, but that isn't something you actually need to worry > about since either Hiten or I will add them back in when we commit > now that we know they are missing. > > I have one comment, and that is that the use of /dev/random has > created lots of unexpected problems in FreeBSD which they have > hacked around. I think we should simply use /dev/urandom here, > which is guarenteed not to block and will certainly produce a > random enough seed for rand's tiny little seed. > > -Matt > > I have created a new patch with your recommendations above and do not use /dev/random any longer. I also retrieved the latest man page updates from the FreeBSD team and generated a patch out of those (they talk about sranddev). Also, as per another one of your emails, I have re-added the CVS tags. I noticed that my earlier patch removed them. I'm not sure how/why it did that, but the new patches do not do that. I think these will work better for you. Thanks again, Mike --------------050404070007040706070202 Content-Type: text/plain; name="rand.c.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rand.c.patch" --- rand.c 2004-05-12 15:43:31.000000000 -0500 +++ rand.c.new 2004-05-12 15:42:39.000000000 -0500 @@ -32,14 +32,20 @@ * * Posix rand_r function added May 1999 by Wes Peters <wes@softweyr.com>. * - * $FreeBSD: src/lib/libc/stdlib/rand.c,v 1.2.2.1 2001/03/05 11:33:57 obrien Exp $ + * $FreeBSD: src/lib/libc/stdlib/rand.c,v 1.15 2001/03/05 11:33:57 ache Exp $ * $DragonFly: src/lib/libc/stdlib/rand.c,v 1.2 2003/06/17 04:26:46 dillon Exp $ - * - * @(#)rand.c 8.1 (Berkeley) 6/14/93 */ +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93"; +#endif /* LIBC_SCCS and not lint */ +#include <sys/cdefs.h> + +#include <sys/time.h> /* for sranddev() */ #include <sys/types.h> +#include <fcntl.h> /* for sranddev() */ #include <stdlib.h> +#include <unistd.h> /* for sranddev() */ #ifdef TEST #include <stdio.h> @@ -48,7 +54,34 @@ static int do_rand(unsigned long *ctx) { +#ifdef USE_WEAK_SEEDING +/* + * Historic implementation compatibility. + * The random sequences do not vary much with the seed, + * even with overflowing. + */ return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1)); +#else /* !USE_WEAK_SEEDING */ +/* + * Compute x = (7^5 * x) mod (2^31 - 1) + * wihout overflowing 31 bits: + * (2^31 - 1) = 127773 * (7^5) + 2836 + * From "Random number generators: good ones are hard to find", + * Park and Miller, Communications of the ACM, vol. 31, no. 10, + * October 1988, p. 1195. + */ + long hi, lo, x; + + /* Can't be initialized with 0, so use another value. */ + if (*ctx == 0) + *ctx = 123459876; + hi = *ctx / 127773; + lo = *ctx % 127773; + x = 16807 * lo - 2836 * hi; + if (x < 0) + x += 0x7fffffff; + return ((*ctx = x) % ((u_long)RAND_MAX + 1)); +#endif /* !USE_WEAK_SEEDING */ } @@ -56,8 +89,10 @@ rand_r(unsigned int *ctx) { u_long val = (u_long) *ctx; - *ctx = do_rand(&val); - return (int) *ctx; + int r = do_rand(&val); + + *ctx = (unsigned int) val; + return (r); } @@ -66,7 +101,7 @@ int rand() { - return do_rand(&next); + return (do_rand(&next)); } void @@ -76,6 +111,42 @@ next = seed; } + +/* + * sranddev: + * + * Many programs choose the seed value in a totally predictable manner. + * This often causes problems. We seed the generator using the much more + * secure random(4) interface. + * + * FreeBSD chooses to use /dev/random for their seed. However, because + * of possible problems surrounding /dev/random, we use /dev/urandom for now, + * which is guaranteed not to block and will produce a "good enough" seed + * for us for the time being. + */ +void +sranddev() +{ + int fd, done; + + done = 0; + fd = _open("/dev/urandom", O_RDONLY, 0); + if (fd >= 0) { + if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next)) + done = 1; + _close(fd); + } + + if (!done) { + struct timeval tv; + unsigned long junk; + + gettimeofday(&tv, NULL); + srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk); + } +} + + #ifdef TEST main() --------------050404070007040706070202 Content-Type: text/plain; name="rand.3.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rand.3.patch" --- rand.3.old 2004-05-12 15:51:12.000000000 -0500 +++ rand.3.new 2004-05-12 15:51:53.000000000 -0500 @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)rand.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/stdlib/rand.3,v 1.4.2.5 2001/12/14 18:33:58 ru Exp $ +.\" $FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/rand.3,v 1.14 2003/09/08 19:57:15 ru Exp $ .\" $DragonFly: src/lib/libc/stdlib/rand.3,v 1.2 2003/06/17 04:26:46 dillon Exp $ .\" .Dd May 25, 1999 @@ -43,6 +43,7 @@ .Sh NAME .Nm rand , .Nm srand , +.Nm sranddev , .Nm rand_r .Nd bad random number generator .Sh LIBRARY @@ -51,6 +52,8 @@ .In stdlib.h .Ft void .Fn srand "unsigned seed" +.Ft void +.Fn sranddev void .Ft int .Fn rand void .Ft int @@ -67,7 +70,7 @@ of 0 to .Dv RAND_MAX (as defined by the header file -.Aq Pa stdlib.h ) . +.In stdlib.h ) . .Pp The .Fn srand @@ -85,14 +88,24 @@ value is provided, the functions are automatically seeded with a value of 1. .Pp +The +.Fn sranddev +function initializes a seed using the +.Xr random 4 +random number device which returns good random numbers, +suitable for cryptographic use. +.Pp +The .Fn rand_r +function provides the same functionality as .Fn rand . A pointer to the context value .Fa ctx must be supplied by the caller. .Sh SEE ALSO -.Xr random 3 +.Xr random 3 , +.Xr random 4 .Sh STANDARDS The .Fn rand --------------050404070007040706070202--
文章代碼(AID): #10epA900 (DFBSD_submit)
討論串 (同標題文章)
文章代碼(AID): #10epA900 (DFBSD_submit)