rand - pseudo-random number generator


SYNOPSIS

        #include <openssl/rand.h>

        int  RAND_bytes(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(void);


DESCRIPTION

       These functions implement a cryptographically secure
       pseudo-random number generator (PRNG). It is used by other
       library functions for example to generate random keys, and
       applications can use it when they need randomness.

       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.

       RAND_bytes(3) describes how to obtain random data from the
       PRNG.


INTERNALS

       The RAND_SSLeay() method implements a PRNG based on a
       cryptographic hash function.

       The following description of its design is based on the
       SSLeay documentation:

       First up I will state the things I believe I need for a
       good RNG.

           convert the RNG 'state' to random numbers.

       2   An initial source of random 'state'.

       3   The state should be very large.  If the RNG is being
           used to generate 4096 bit RSA keys, 2 2048 bit random
           strings are required (at a minimum).  If your RNG
           state only has 128 bits, you are obviously limiting
           the search space to 128 bits, not 2048.  I'm probably
           getting a little carried away on this last point but
           it does indicate that it may not be a bad idea to keep
           quite a lot of RNG state.  It should be easier to
           break a cipher than guess the RNG seed data.

       4   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.

       5   When using data to seed the RNG state, the data used
           should not be extractable from the RNG state.  I
           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.

       6   Given the same initial 'state', 2 systems should
           deviate in their RNG state (and hence the random
           numbers generated) over time if at all possible.

       7   Given the random number output 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 chopped up into units of 20 bytes (or less
       for the last block).  Each of these blocks 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 in
       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

       system addresses points 1 (hash function; currently
       SHA-1), 3 (the 'state'), 4 (via the 'md'), 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), we
       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 we have finished 'num' random bytes for the
       caller, 'count' (which is incremented) and the local and
       global 'md' are fed into the hash function 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').

       So of the points raised, only 2 is not addressed (but see
       RAND_add(3)).


SEE ALSO

       BN_rand(3), RAND_add(3), RAND_load_file(3), RAND_egd(3),
       RAND_bytes(3), RAND_set_rand_method(3), RAND_cleanup(3)


Man(1) output converted with man2html