david/ipxe
Archived
1
0
This repository has been archived on 2020-12-06. You can view files and clone it, but cannot push or open issues or pull requests.
ipxe/src/core/random.c
Michael Brown 2c197517f2 [libc] Always use a non-zero seed for the (non-crypto) RNG
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>
2016-06-09 08:44:32 +01:00

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;
}