From: Ulf Möller Date: Fri, 21 Jan 2000 17:50:27 +0000 (+0000) Subject: Document RAND library. X-Git-Tag: OpenSSL_0_9_5beta1~229 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=60b5245360a70f4b10a6c77aa0bf5ee04b2e7262;p=oweals%2Fopenssl.git Document RAND library. --- diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index 7b8cde9401..1a840220fc 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -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); diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index cf98643d3c..e9721f66c2 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -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 index 0000000000..fe53919801 --- /dev/null +++ b/doc/crypto/RAND_add.pod @@ -0,0 +1,60 @@ +=pod + +=head1 NAME + +RAND_add, RAND_seed, RAND_screen - Add entropy to the PRNG + +=head1 SYNOPSIS + + #include + + 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 bytes at B into the PRNG state. Thus, +if the data at B 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 argument is (the lower bound of) an estimate of how much +randomness is contained in B. 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, 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. + +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 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 index 0000000000..4abe93a832 --- /dev/null +++ b/doc/crypto/RAND_bytes.pod @@ -0,0 +1,43 @@ +=pod + +=head1 NAME + +RAND_bytes, RAND_pseudo_bytes - Generate random data + +=head1 SYNOPSIS + + #include + + int RAND_bytes(unsigned char *buf, int num); + + int RAND_pseudo_bytes(unsigned char *buf, int num); + +=head1 DESCRIPTION + +RAND_bytes() puts B random bytes into B. An error occurs if +the PRNG has not been seeded with enough randomness. + +RAND_pseudo_bytes() puts B pseudo-random bytes into B. 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 index 0000000000..578de8f91d --- /dev/null +++ b/doc/crypto/RAND_cleanup.pod @@ -0,0 +1,29 @@ +=pod + +=head1 NAME + +RAND_cleanup - erase the PRNG state + +=head1 SYNOPSIS + + #include + + 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 index 0000000000..8fc985ee3e --- /dev/null +++ b/doc/crypto/RAND_load_file.pod @@ -0,0 +1,51 @@ +=pod + +=head1 NAME + +RAND_load_file, RAND_write_file, RAND_file_name - PRNG seed file + +=head1 SYNOPSIS + + #include + + 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 points to a buffer of size B 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 is +too small for the path name, an error occurs. + +RAND_load_file() reads up to B from file B and +adds them to the PRNG. + +RAND_write_file() writes a number of random bytes (currently 1024) to +file B 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 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 index 0000000000..4f85de6269 --- /dev/null +++ b/doc/crypto/RAND_set_rand_method.pod @@ -0,0 +1,57 @@ +=pod + +=head1 NAME + +RAND_set_rand_method, RAND_get_rand_method, RAND_SSLeay - Select RAND method + +=head1 SYNOPSIS + + #include + + void RAND_set_rand_method(RAND_METHOD *meth); + + RAND_METHOD *RAND_get_rand_method(void); + + RAND_METHOD *RAND_SSLeay(void); + +=head1 DESCRIPTION + +A B 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. +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 diff --git a/doc/crypto/RSA_generate_key.pod b/doc/crypto/RSA_generate_key.pod index cdf527069a..3cdc07f374 100644 --- a/doc/crypto/RSA_generate_key.pod +++ b/doc/crypto/RSA_generate_key.pod @@ -46,7 +46,7 @@ it is called as B. The process is then repeated for prime q with B. -=head1 RETURN VALUES +=head1 RETURN VALUE If key generation fails, RSA_generate_key() returns B; the error codes can be obtained by ERR_get_error(3). diff --git a/doc/crypto/RSA_new.pod b/doc/crypto/RSA_new.pod index a5df37777f..95e44c73fa 100644 --- a/doc/crypto/RSA_new.pod +++ b/doc/crypto/RSA_new.pod @@ -17,7 +17,7 @@ RSA_new, RSA_free - allocate and free RSA objects RSA_new() allocates and initializes an B structure. RSA_free() frees the B 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 index 0000000000..baddd4379c --- /dev/null +++ b/doc/crypto/rand.pod @@ -0,0 +1,145 @@ +=pod + +=head1 NAME + +rand - Psdeudo-random number generator + +=head1 SYNOPSIS + + #include + + 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. Its state can be saved in a seed file +(see L) to avoid having to go through the seeding +process whenever the application is started. + +L 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). + +=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 diff --git a/doc/crypto/rsa.pod b/doc/crypto/rsa.pod index fafe337a4b..395ef2c786 100644 --- a/doc/crypto/rsa.pod +++ b/doc/crypto/rsa.pod @@ -9,18 +9,15 @@ rsa - RSA public key cryptosystem #include 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