2c197517f2
The non-cryptographic RNG implemented by random() has the property that a seed value of zero will result in a generated sequence of all-zero values. This situation can arise if currticks() returns zero at start of day. Work around this problem by falling back to a fixed non-zero seed if necessary. This has no effect on the separate DRBG used by cryptographic code. Signed-off-by: Michael Brown <mcb30@ipxe.org>
44 lines
869 B
C
44 lines
869 B
C
/** @file
|
|
*
|
|
* Random number generation
|
|
*
|
|
*/
|
|
|
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|
|
|
#include <stdlib.h>
|
|
#include <ipxe/timer.h>
|
|
|
|
static int32_t rnd_seed = 0;
|
|
|
|
/**
|
|
* Seed the pseudo-random number generator
|
|
*
|
|
* @v seed Seed value
|
|
*/
|
|
void srandom ( unsigned int seed ) {
|
|
rnd_seed = seed;
|
|
if ( ! rnd_seed )
|
|
rnd_seed = 4; /* Chosen by fair dice roll */
|
|
}
|
|
|
|
/**
|
|
* Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
|
|
*
|
|
* @ret rand Pseudo-random number
|
|
*/
|
|
long int random ( void ) {
|
|
int32_t q;
|
|
|
|
if ( ! rnd_seed ) /* Initialize linear congruential generator */
|
|
srandom ( currticks() );
|
|
|
|
/* simplified version of the LCG given in Bruce Schneier's
|
|
"Applied Cryptography" */
|
|
q = ( rnd_seed / 53668 );
|
|
rnd_seed = ( 40014 * ( rnd_seed - 53668 * q ) - 12211 * q );
|
|
if ( rnd_seed < 0 )
|
|
rnd_seed += 2147483563L;
|
|
return rnd_seed;
|
|
}
|