159191Skris=pod
259191Skris
359191Skris=head1 NAME
459191Skris
559191Skrisrand - pseudo-random number generator
659191Skris
759191Skris=head1 SYNOPSIS
859191Skris
959191Skris #include <openssl/rand.h>
1059191Skris
11109998Smarkm int  RAND_set_rand_engine(ENGINE *engine);
12109998Smarkm
1376866Skris int  RAND_bytes(unsigned char *buf, int num);
1476866Skris int  RAND_pseudo_bytes(unsigned char *buf, int num);
1559191Skris
1676866Skris void RAND_seed(const void *buf, int num);
1776866Skris void RAND_add(const void *buf, int num, int entropy);
1859191Skris int  RAND_status(void);
1959191Skris
2076866Skris int  RAND_load_file(const char *file, long max_bytes);
2159191Skris int  RAND_write_file(const char *file);
2276866Skris const char *RAND_file_name(char *file, size_t num);
2359191Skris
2459191Skris int  RAND_egd(const char *path);
2559191Skris
26109998Smarkm void RAND_set_rand_method(const RAND_METHOD *meth);
27109998Smarkm const RAND_METHOD *RAND_get_rand_method(void);
2859191Skris RAND_METHOD *RAND_SSLeay(void);
2959191Skris
3059191Skris void RAND_cleanup(void);
3159191Skris
32109998Smarkm /* For Win32 only */
33109998Smarkm void RAND_screen(void);
34109998Smarkm int RAND_event(UINT, WPARAM, LPARAM);
35109998Smarkm
3659191Skris=head1 DESCRIPTION
3759191Skris
38109998SmarkmSince the introduction of the ENGINE API, the recommended way of controlling
39109998Smarkmdefault implementations is by using the ENGINE API functions. The default
40109998SmarkmB<RAND_METHOD>, as set by RAND_set_rand_method() and returned by
41109998SmarkmRAND_get_rand_method(), is only used if no ENGINE has been set as the default
42109998Smarkm"rand" implementation. Hence, these two functions are no longer the recommened
43109998Smarkmway to control defaults.
44109998Smarkm
45109998SmarkmIf an alternative B<RAND_METHOD> implementation is being used (either set
46109998Smarkmdirectly or as provided by an ENGINE module), then it is entirely responsible
47109998Smarkmfor the generation and management of a cryptographically secure PRNG stream. The
48109998Smarkmmechanisms described below relate solely to the software PRNG implementation
49109998Smarkmbuilt in to OpenSSL and used by default.
50109998Smarkm
5159191SkrisThese functions implement a cryptographically secure pseudo-random
5259191Skrisnumber generator (PRNG). It is used by other library functions for
5359191Skrisexample to generate random keys, and applications can use it when they
5459191Skrisneed randomness.
5559191Skris
5659191SkrisA cryptographic PRNG must be seeded with unpredictable data such as
5759191Skrismouse movements or keys pressed at random by the user. This is
5859191Skrisdescribed in L<RAND_add(3)|RAND_add(3)>. Its state can be saved in a seed file
5959191Skris(see L<RAND_load_file(3)|RAND_load_file(3)>) to avoid having to go through the
6059191Skrisseeding process whenever the application is started.
6159191Skris
6259191SkrisL<RAND_bytes(3)|RAND_bytes(3)> describes how to obtain random data from the
6359191SkrisPRNG. 
6459191Skris
6559191Skris=head1 INTERNALS
6659191Skris
6759191SkrisThe RAND_SSLeay() method implements a PRNG based on a cryptographic
6859191Skrishash function.
6959191Skris
7059191SkrisThe following description of its design is based on the SSLeay
7159191Skrisdocumentation:
7259191Skris
7359191SkrisFirst up I will state the things I believe I need for a good RNG.
7459191Skris
7559191Skris=over 4
7659191Skris
7759191Skris=item 1
7859191Skris
7959191SkrisA good hashing algorithm to mix things up and to convert the RNG 'state'
8059191Skristo random numbers.
8159191Skris
8259191Skris=item 2
8359191Skris
8459191SkrisAn initial source of random 'state'.
8559191Skris
8659191Skris=item 3
8759191Skris
8859191SkrisThe state should be very large.  If the RNG is being used to generate
8959191Skris4096 bit RSA keys, 2 2048 bit random strings are required (at a minimum).
9059191SkrisIf your RNG state only has 128 bits, you are obviously limiting the
9159191Skrissearch space to 128 bits, not 2048.  I'm probably getting a little
9259191Skriscarried away on this last point but it does indicate that it may not be
9359191Skrisa bad idea to keep quite a lot of RNG state.  It should be easier to
9459191Skrisbreak a cipher than guess the RNG seed data.
9559191Skris
9659191Skris=item 4
9759191Skris
9859191SkrisAny RNG seed data should influence all subsequent random numbers
9959191Skrisgenerated.  This implies that any random seed data entered will have
10059191Skrisan influence on all subsequent random numbers generated.
10159191Skris
10259191Skris=item 5
10359191Skris
10459191SkrisWhen using data to seed the RNG state, the data used should not be
10559191Skrisextractable from the RNG state.  I believe this should be a
10659191Skrisrequirement because one possible source of 'secret' semi random
10759191Skrisdata would be a private key or a password.  This data must
10859191Skrisnot be disclosed by either subsequent random numbers or a
10959191Skris'core' dump left by a program crash.
11059191Skris
11159191Skris=item 6
11259191Skris
11359191SkrisGiven the same initial 'state', 2 systems should deviate in their RNG state
11459191Skris(and hence the random numbers generated) over time if at all possible.
11559191Skris
11659191Skris=item 7
11759191Skris
11859191SkrisGiven the random number output stream, it should not be possible to determine
11959191Skristhe RNG state or the next random number.
12059191Skris
12159191Skris=back
12259191Skris
12359191SkrisThe algorithm is as follows.
12459191Skris
12559191SkrisThere is global state made up of a 1023 byte buffer (the 'state'), a
12659191Skrisworking hash value ('md'), and a counter ('count').
12759191Skris
12859191SkrisWhenever seed data is added, it is inserted into the 'state' as
12959191Skrisfollows.
13059191Skris
13159191SkrisThe input is chopped up into units of 20 bytes (or less for
13259191Skristhe last block).  Each of these blocks is run through the hash
13359191Skrisfunction as follows:  The data passed to the hash function
13459191Skrisis the current 'md', the same number of bytes from the 'state'
13559191Skris(the location determined by in incremented looping index) as
13659191Skristhe current 'block', the new key data 'block', and 'count'
13759191Skris(which is incremented after each use).
13859191SkrisThe result of this is kept in 'md' and also xored into the
13959191Skris'state' at the same locations that were used as input into the
14059191Skrishash function. I
14159191Skrisbelieve this system addresses points 1 (hash function; currently
14259191SkrisSHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash
14359191Skrisfunction and xor).
14459191Skris
14559191SkrisWhen bytes are extracted from the RNG, the following process is used.
14659191SkrisFor each group of 10 bytes (or less), we do the following:
14759191Skris
14879998SkrisInput into the hash function the local 'md' (which is initialized from
14979998Skristhe global 'md' before any bytes are generated), the bytes that are to
15079998Skrisbe overwritten by the random bytes, and bytes from the 'state'
15179998Skris(incrementing looping index). From this digest output (which is kept
15279998Skrisin 'md'), the top (up to) 10 bytes are returned to the caller and the
15379998Skrisbottom 10 bytes are xored into the 'state'.
15459191Skris
15559191SkrisFinally, after we have finished 'num' random bytes for the caller,
15659191Skris'count' (which is incremented) and the local and global 'md' are fed
15759191Skrisinto the hash function and the results are kept in the global 'md'.
15859191Skris
15959191SkrisI believe the above addressed points 1 (use of SHA-1), 6 (by hashing
16059191Skrisinto the 'state' the 'old' data from the caller that is about to be
16159191Skrisoverwritten) and 7 (by not using the 10 bytes given to the caller to
16259191Skrisupdate the 'state', but they are used to update 'md').
16359191Skris
16459191SkrisSo of the points raised, only 2 is not addressed (but see
16559191SkrisL<RAND_add(3)|RAND_add(3)>).
16659191Skris
16759191Skris=head1 SEE ALSO
16859191Skris
16959191SkrisL<BN_rand(3)|BN_rand(3)>, L<RAND_add(3)|RAND_add(3)>,
17059191SkrisL<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_egd(3)|RAND_egd(3)>,
17159191SkrisL<RAND_bytes(3)|RAND_bytes(3)>,
17259191SkrisL<RAND_set_rand_method(3)|RAND_set_rand_method(3)>,
17359191SkrisL<RAND_cleanup(3)|RAND_cleanup(3)> 
17459191Skris
17559191Skris=cut
176