rand_ssl(3)rand_ssl(3)NAMErand_ssl - Pseudo-random number generator
unsigned char *buf, int num ); int RAND_pseudo_bytes(
unsigned char *buf, int num ); void RAND_seed(
const void *buf, int num ); void RAND_add(
const void *buf, int num, int entropy ); int RAND_status(
void ); void RAND_screen(
void ); int RAND_load_file(
const char *file, long max_bytes ); int RAND_write_file(
const char *file ); const char *RAND_file_name(
char *file, size_t num ); int RAND_egd(
const char *path ); void RAND_set_rand_method(
RAND_METHOD *meth ); RAND_METHOD *RAND_get_rand_method(
void ); RAND_METHOD *RAND_SSLeay(
void ); void RAND_cleanup(
These functions implement a cryptographically secure pseudo-random num‐
ber generator (PRNG). It is used by other library functions, for exam‐
ple, to generate random keys. Applications can use it when they need
A cryptographic PRNG must be seeded with unpredictable data, such as
mouse movements or keys pressed at random by the user. This is
described in RAND_add(3). Its state can be saved in a seed file (see
RAND_load_file(3)) to avoid having to go through the seeding process
whenever the application is started.
For more information on how to obtain random data from the PRNG, see
The RAND_SSLeay() method implements a PRNG based on a cryptographic
The following description of its design is based on the SSLeay documen‐
tation. A good RNG includes the following components: A good hashing
algorithm to mix things up and to convert the RNG state to random num‐
bers. An initial source of random state. The state should be very
large. If the RNG is used to generate 4096 bit RSA keys, two 2048-bit
random strings are required (at a minimum). If your RNG state only has
128 bits, you are limiting the search space to 128 bits, not 2048. It
should be easier to break a cipher than guess the RNG seed data. Any
RNG seed data should influence all subsequent random numbers generated.
This implies that any random seed data entered will have an influence
on all subsequent random numbers generated. When using data to seed
the RNG state, the data should not be extractable from the RNG state.
We believe this should be a requirement because one possible source of
secret semi-random data would be a private key or a password. This
data must not be disclosed by either subsequent random numbers or a
core dump left by a program crash. Given the same initial state, two
systems should deviate in their RNG state (and hence the random numbers
generated) over time if at all possible. Given the random number out‐
put stream, it should not be possible to determine the RNG state or the
next random number.
The algorithm is as follows.
There is global state made up of a 1023 byte buffer (the state), a
working hash value (md), and a counter (count).
Whenever seed data is added, it is inserted into the state as follows:
The input is divided into blocks of 20 bytes (or less for the last
block). Each block is run through the hash function as follows: The
data passed to the hash function is the current md, the same number of
bytes from the state (the location determined by an incremented looping
index) as the current block, the new key data block, and count (which
is incremented after each use). The result of this is kept in md and
also xored into the state at the same locations that were used as input
into the hash function. This system addresses points 1 (hash function;
currently SHA-1), 3 (the state), 4 (via the md), and 5 (by the use of a
hash function and xor).
When bytes are extracted from the RNG, the following process is used.
For each group of 10 bytes (or less), you do the following:
Input into the hash function the local md (which is initialized from
the global md before any bytes are generated), the bytes that are to be
overwritten by the random bytes, and bytes from the state (incrementing
looping index). From this digest output (which is kept in md), the top
(up to) 10 bytes are returned to the caller and the bottom 10 bytes are
xored into the state.
Finally, after you finish num random bytes for the caller, count (which
is incremented) and the local and global md are fed into the hash func‐
tion and the results are kept in the global md.
I believe the above addressed points 1 (use of SHA-1), 6 (by hashing
into the 'state' the 'old' data from the caller that is about to be
overwritten) and 7 (by not using the 10 bytes given to the caller to
update the 'state', but they are used to update 'md').
Of the points raised, only the second is not addressed (see
Functions: BN_rand(3), RAND_add(3), RAND_load_file(3), RAND_egd(3),
RAND_bytes(3), RAND_set_rand_method(3), RAND_cleanup(3)rand(3)rand_ssl(3)