Document RAND library.
authorUlf Möller <ulf@openssl.org>
Fri, 21 Jan 2000 17:50:27 +0000 (17:50 +0000)
committerUlf Möller <ulf@openssl.org>
Fri, 21 Jan 2000 17:50:27 +0000 (17:50 +0000)
crypto/rand/md_rand.c
crypto/rand/randfile.c
doc/crypto/RAND_add.pod [new file with mode: 0644]
doc/crypto/RAND_bytes.pod [new file with mode: 0644]
doc/crypto/RAND_cleanup.pod [new file with mode: 0644]
doc/crypto/RAND_load_file.pod [new file with mode: 0644]
doc/crypto/RAND_set_rand_method.pod [new file with mode: 0644]
doc/crypto/RSA_generate_key.pod
doc/crypto/RSA_new.pod
doc/crypto/rand.pod [new file with mode: 0644]
doc/crypto/rsa.pod

index 7b8cde9..1a84022 100644 (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);
index cf98643..e9721f6 100644 (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);
 
diff --git a/doc/crypto/RAND_add.pod b/doc/crypto/RAND_add.pod
new file mode 100644 (file)
index 0000000..fe53919
--- /dev/null
@@ -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
diff --git a/doc/crypto/RAND_bytes.pod b/doc/crypto/RAND_bytes.pod
new file mode 100644 (file)
index 0000000..4abe93a
--- /dev/null
@@ -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
diff --git a/doc/crypto/RAND_cleanup.pod b/doc/crypto/RAND_cleanup.pod
new file mode 100644 (file)
index 0000000..578de8f
--- /dev/null
@@ -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
diff --git a/doc/crypto/RAND_load_file.pod b/doc/crypto/RAND_load_file.pod
new file mode 100644 (file)
index 0000000..8fc985e
--- /dev/null
@@ -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
diff --git a/doc/crypto/RAND_set_rand_method.pod b/doc/crypto/RAND_set_rand_method.pod
new file mode 100644 (file)
index 0000000..4f85de6
--- /dev/null
@@ -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
index cdf5270..3cdc07f 100644 (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).
index a5df377..95e44c7 100644 (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
 
diff --git a/doc/crypto/rand.pod b/doc/crypto/rand.pod
new file mode 100644 (file)
index 0000000..baddd43
--- /dev/null
@@ -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
index fafe337..395ef2c 100644 (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