Document RAND library.

This commit is contained in:
Ulf Möller 2000-01-21 17:50:27 +00:00
parent 5d82c5b3f4
commit 60b5245360
11 changed files with 392 additions and 34 deletions

View File

@ -184,17 +184,18 @@ static void ssleay_rand_add(const void *buf, int num, int add)
#endif
/*
* (Based on doc/ssleay.txt, section rand.doc:)
* (Based on the rand(3) manpage)
*
* The input is chopped up into units of 16 bytes (or less for
* the last block). Each of these blocks is run through the MD5
* message digest as follow: The data passed to the MD5 digest
* the last block). Each of these blocks is run through the hash
* function as follow: 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 used as input into the MD5.
* 'state' at the same locations that were used as input into the
* hash function.
*/
CRYPTO_w_lock(CRYPTO_LOCK_RAND);

View File

@ -92,7 +92,6 @@ int RAND_load_file(const char *file, long bytes)
i=stat(file,&sb);
/* If the state fails, put some crap in anyway */
RAND_add(&sb,sizeof(sb),0);
ret+=sizeof(sb);
if (i < 0) return(0);
if (bytes <= 0) return(ret);

60
doc/crypto/RAND_add.pod Normal file
View File

@ -0,0 +1,60 @@
=pod
=head1 NAME
RAND_add, RAND_seed, RAND_screen - Add entropy to the PRNG
=head1 SYNOPSIS
#include <openssl/rand.h>
void RAND_seed(const void *buf, int num);
void RAND_add(const void *buf, int num, int entropy);
void RAND_screen(void);
=head1 DESCRIPTION
RAND_add() mixes the B<num> bytes at B<buf> into the PRNG state. Thus,
if the data at B<buf> are unpredictable to an adversary, this
increases the uncertainty about the state and makes the PRNG output
less predictable. Suitable input comes from user interaction (random
key presses, mouse movements) and certain hardware events. The
B<entropy> argument is (the lower bound of) an estimate of how much
randomness is contained in B<buf>. Details about sources of randomness
and how to estimate their entropy can be found in the literature,
e.g. RFC 1750.
RAND_add() may be called with sensitive data such as user entered
passwords. The seed values cannot be recovered from the PRNG output.
OpenSSL makes sure that the PRNG state is unique for each thread. On
systems that provide C</dev/random>, the randomness device is used
to seed the PRNG transparently. However, on all other systems, the
application is responsible for seeding the PRNG by calling RAND_add()
or RAND_load_file(3).
RAND_seed() is equivalent to RAND_add() when B<num == entropy>.
The RAND_screen() function is available for the convenience of Windows
programmers. It adds the current contents of the screen to the PRNG.
For applications that can catch Windows events, seeding the PRNG with
the parameters of B<WM_MOUSEMOVE> events is a significantly better
source of randomness. It should be noted that both methods cannot be
used on servers that run without user interaction.
=head1 RETURN VALUES
These functions do not return values.
=head1 SEE ALSO
rand(3), RAND_load_file(3), RAND_cleanup(3)
=head1 HISTORY
RAND_seed() and RAND_screen() are available in all versions of SSLeay
and OpenSSL. RAND_add() was added in OpenSSL 0.9.5.
=cut

43
doc/crypto/RAND_bytes.pod Normal file
View File

@ -0,0 +1,43 @@
=pod
=head1 NAME
RAND_bytes, RAND_pseudo_bytes - Generate random data
=head1 SYNOPSIS
#include <openssl/rand.h>
int RAND_bytes(unsigned char *buf, int num);
int RAND_pseudo_bytes(unsigned char *buf, int num);
=head1 DESCRIPTION
RAND_bytes() puts B<num> random bytes into B<buf>. An error occurs if
the PRNG has not been seeded with enough randomness.
RAND_pseudo_bytes() puts B<num> pseudo-random bytes into B<buf>. These
bytes are guaranteed to be unique, but not unpredictable. They can be
used for non-cryptographic purposes and for certain purposes in
cryptographic protocols, but not for key generation etc.
=head1 RETURN VALUES
RAND_bytes() returns 1 on success, 0 otherwise. The error code can be
obtained by ERR_get_error(3). RAND_pseudo_bytes() returns 1 if the
bytes generated are cryptographically strong, 0 otherwise. Both
functions return -1 if they are not supported by the current RAND
method.
=head1 SEE ALSO
rand(3), err(3), RAND_add(3)
=head1 HISTORY
RAND_bytes() is available in all versions of SSLeay and OpenSSL. It
has a return value since OpenSSL 0.9.5. RAND_pseudo_bytes() was added
in OpenSSL 0.9.5.
=cut

View File

@ -0,0 +1,29 @@
=pod
=head1 NAME
RAND_cleanup - erase the PRNG state
=head1 SYNOPSIS
#include <openssl/rand.h>
void RAND_cleanup(void);
=head1 DESCRIPTION
RAND_cleanup() erases the memory used by the PRNG.
=head1 RETURN VALUE
RAND_cleanup() returns no value.
=head1 SEE ALSO
rand(3)
=head1 HISTORY
RAND_cleanup() is available in all versions of SSLeay and OpenSSL.
=cut

View File

@ -0,0 +1,51 @@
=pod
=head1 NAME
RAND_load_file, RAND_write_file, RAND_file_name - PRNG seed file
=head1 SYNOPSIS
#include <openssl/rand.h>
char *RAND_file_name(char *buf, int num);
int RAND_load_file(const char *filename, long max_bytes);
int RAND_write_file(const char *filename);
=head1 DESCRIPTION
RAND_file_name() generates a default path for the random seed
file. B<buf> points to a buffer of size B<num> in which to store the
filename. The seed file is $RANDFILE, if that environment variable is
set, $HOME/.rand otherwise. If $HOME is not set either, or B<num> is
too small for the path name, an error occurs.
RAND_load_file() reads up to B<max_bytes> from file B<filename> and
adds them to the PRNG.
RAND_write_file() writes a number of random bytes (currently 1024) to
file B<filename> which can be used to initialze the PRNG by calling
RAND_load_file() in a later session.
=head1 RETURN VALUES
RAND_load_file() returns the number of bytes read.
RAND_write_file() returns the number of bytes written, and -1 if the
bytes written were generated without appropriate seed.
RAND_file_name() returns a pointer to B<buf> on success, and NULL on
error.
=head1 SEE ALSO
rand(3), RAND_add(3), RAND_cleanup(3)
=head1 HISTORY
RAND_load_file(), RAND_write_file() and RAND_file_name() are available in
all versions of SSLeay and OpenSSL.
=cut

View File

@ -0,0 +1,57 @@
=pod
=head1 NAME
RAND_set_rand_method, RAND_get_rand_method, RAND_SSLeay - Select RAND method
=head1 SYNOPSIS
#include <openssl/rand.h>
void RAND_set_rand_method(RAND_METHOD *meth);
RAND_METHOD *RAND_get_rand_method(void);
RAND_METHOD *RAND_SSLeay(void);
=head1 DESCRIPTION
A B<RAND_METHOD> specifies the functions that OpenSSL uses for random
number generation. By modifying the method, alternative
implementations such as hardware RNGs may be used. Initially, the
default is to use the OpenSSL internal implementation. RAND_SSLeay()
returns a pointer to that method.
RAND_set_rand_method() sets the RAND method to B<meth>.
RAND_get_rand_method() returns a pointer to the current method.
=head1 THE RAND_METHOD STUCTURE
typedef struct rand_meth_st
{
void (*seed)(const void *buf, int num);
int (*bytes)(unsigned char *buf, int num);
void (*cleanup)(void);
void (*add)(const void *buf, int num, int entropy);
int (*pseudorand)(unsigned char *buf, int num);
} RAND_METHOD;
The components point to the implementation of RAND_seed(),
RAND_bytes(), RAND_cleanup(), RAND_add() and RAND_pseudo_rand().
Each component may be NULL if the function is not implemented.
=head1 RETURN VALUES
RAND_set_rand_method() returns no value. RAND_get_rand_method() and
RAND_SSLeay() return pointers to the respective methods.
=head1 SEE ALSO
rand(3)
=head1 HISTORY
RAND_set_rand_method(), RAND_get_rand_method() and RAND_SSLeay() are
available in all versions of OpenSSL.
=cut

View File

@ -46,7 +46,7 @@ it is called as B<callback(3, 0, cb_arg)>.
The process is then repeated for prime q with B<callback(3, 1, cb_arg)>.
=head1 RETURN VALUES
=head1 RETURN VALUE
If key generation fails, RSA_generate_key() returns B<NULL>; the
error codes can be obtained by ERR_get_error(3).

View File

@ -17,7 +17,7 @@ RSA_new, RSA_free - allocate and free RSA objects
RSA_new() allocates and initializes an B<RSA> structure.
RSA_free() frees the B<RSA> structure and its components. The key is
erased before the memory is erased returned to the system.
erased before the memory is returned to the system.
=head1 RETURN VALUES

145
doc/crypto/rand.pod Normal file
View File

@ -0,0 +1,145 @@
=pod
=head1 NAME
rand - Psdeudo-random number generator
=head1 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);
void RAND_screen(void);
int RAND_load_file(const char *file,long max_bytes);
int RAND_write_file(const char *file);
char *RAND_file_name(char *file,int num);
void RAND_set_rand_method(RAND_METHOD *meth);
RAND_METHOD *RAND_get_rand_method(void);
RAND_METHOD *RAND_SSLeay(void);
void RAND_cleanup(void);
=head1 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 L<RAND_add(3)>. Its state can be saved in a seed file
(see L<RAND_load_file(3)>) to avoid having to go through the seeding
process whenever the application is started.
L<RAND_bytes(3)> describes how to obtain random data from the PRNG.
=head1 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.
=over 4
=item 1
A good hashing algorithm to mix things up and to convert the RNG 'state'
to random numbers.
=item 2
An initial source of random 'state'.
=item 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.
=item 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.
=item 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.
=item 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.
=item 7
Given the random number output stream, it should not be possible to determine
the RNG state or the next random number.
=back
The algorithm is as follows.
There is global state made up of a 1023 byte buffer (the 'state'), a
working hash function ('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 16 bytes (or less for the last
block). Each of these blocks is run through the hash function. 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' and the new key data 'block'.
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. I
believe this 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 8 bytes (or less), we do the following,
Input into the hash function, the top 8 bytes from 'md', the byte that
are to be overwritten by the random bytes and bytes from the 'state'
(incrementing looping index). From this hash function output (which
is kept in 'md'), the top (upto) 8 bytes are returned to the caller
and the bottom (upto) 8 bytes are xored into the 'state'.
Finally, after we have finished 'generation' random bytes for the
called, 'count' (which is incremented) and 'md' are fed into the hash
function and the results are kept in '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 8 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
L<RAND_add()>).
=head1 SEE ALSO
BN_rand(3), RAND_add(3), RAND_load_file(3), RAND_bytes(3),
RAND_set_rand_method(3), RAND_cleanup(3)
=cut

View File

@ -9,18 +9,15 @@ rsa - RSA public key cryptosystem
#include <openssl/rsa.h>
RSA * RSA_new(void);
void RSA_free(RSA *rsa);
int RSA_public_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_sign(int type, unsigned char *m, unsigned int m_len,
unsigned char *sigret, unsigned int *siglen, RSA *rsa);
int RSA_verify(int type, unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
@ -32,83 +29,59 @@ rsa - RSA public key cryptosystem
int RSA_check_key(RSA *rsa);
int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
void RSA_blinding_off(RSA *rsa);
void RSA_set_default_method(RSA_METHOD *meth);
RSA_METHOD *RSA_get_default_method(void);
RSA_METHOD *RSA_set_method(RSA *rsa, RSA_METHOD *meth);
RSA_METHOD *RSA_get_method(RSA *rsa);
RSA_METHOD *RSA_PKCS1_SSLeay(void);
RSA_METHOD *RSA_PKCS1_RSAref(void);
RSA_METHOD *RSA_null_method(void);
int RSA_flags(RSA *rsa);
RSA *RSA_new_method(RSA_METHOD *method);
int RSA_print(BIO *bp, RSA *x, int offset);
int RSA_print_fp(FILE *fp, RSA *x, int offset);
int RSA_get_ex_new_index(long argl, char *argp, int (*new_func)(),
int (*dup_func)(), void (*free_func)());
int RSA_set_ex_data(RSA *r,int idx,char *arg);
char *RSA_get_ex_data(RSA *r, int idx);
int RSA_private_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
int RSA_public_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa,int padding);
int RSA_sign_ASN1_OCTET_STRING(int dummy, unsigned char *m,
unsigned int m_len, unsigned char *sigret, unsigned int *siglen,
RSA *rsa);
int RSA_verify_ASN1_OCTET_STRING(int dummy, unsigned char *m,
unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
RSA *rsa);
int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
unsigned char *f, int fl);
int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
unsigned char *f, int fl, int rsa_len);
int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
unsigned char *f, int fl);
int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
unsigned char *f, int fl, int rsa_len);
int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
unsigned char *f, int fl, unsigned char *p, int pl);
int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
unsigned char *f, int fl, int rsa_len, unsigned char *p, int pl);
int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
unsigned char *f, int fl);
int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
unsigned char *f, int fl, int rsa_len);
int RSA_padding_add_none(unsigned char *to, int tlen,
unsigned char *f, int fl);
int RSA_padding_check_none(unsigned char *to, int tlen,
unsigned char *f, int fl, int rsa_len);
=head1 DESCRIPTION
These functions implement RSA public key encryption and signatures