3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
12 #include <lutil_md5.h>
15 * lutil_entropy() provides nbytes of entropy in buf.
16 * Quality offerred is suitable for one-time uses, such as "once" keys.
18 int lutil_entropy( char *buf, int nbytes )
20 if( nbytes < 0 ) return -1;
21 if( nbytes == 0 ) return 0;
25 /* Linux and *BSD offer a urandom device */
29 fd = open( URANDOM_DEVICE, O_RDONLY );
31 if( fd < 0 ) return -1;
33 rc = read( fd, buf, nbytes );
36 /* should return nbytes */
37 if( rc < nbytes ) return -1;
43 /* based upon Phil Karn's "practical randomness" idea
44 * but implementation 100% OpenLDAP. So don't blame Phil. */
45 /* worse case is this is a MD5 hash of a counter, if
46 * MD5 is a strong cryptographic hash, this should
47 * be fairly resistant to attack
49 static int counter = 0;
56 struct rdata_s *stack;
60 #ifdef HAVE_GETTIMEOFDAY
68 /* make sure rdata differs for each process */
71 /* make sure rdata differs for each program */
75 for( n = 0; n < nbytes; n += 16 ) {
76 struct lutil_MD5Context ctx;
79 /* hopefully has good resolution */
80 #ifdef HAVE_GETTIMEOFDAY
81 (void) gettimeofday( &rdata.tv, sizeof( rdata.tv ) );
83 (void) time( &rdata.time );
86 /* make sure rdata differs */
87 rdata.counter = ++counter;
91 lutil_MD5Init( &ctx );
92 lutil_MD5Update( &ctx, (char *) &rdata, sizeof( rdata ) );
93 lutil_MD5Final( digest, &ctx );
95 memcpy( &buf[n], digest,
96 nbytes - n > 16 ? 16 : nbytes - n );