diff options
Diffstat (limited to 'source4/heimdal/lib/hcrypto/rand.c')
-rw-r--r-- | source4/heimdal/lib/hcrypto/rand.c | 166 |
1 files changed, 162 insertions, 4 deletions
diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c index 79dd39eb76..1561f2ad39 100644 --- a/source4/heimdal/lib/hcrypto/rand.c +++ b/source4/heimdal/lib/hcrypto/rand.c @@ -35,7 +35,7 @@ #include <config.h> #endif -RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $"); +RCSID("$Id: rand.c 23464 2008-07-27 12:15:21Z lha $"); #include <stdio.h> #include <stdlib.h> @@ -48,8 +48,14 @@ RCSID("$Id: rand.c 22199 2007-12-07 13:43:25Z lha $"); #define O_BINARY 0 #endif +/** + * @page page_rand RAND - random number + * + * See the library functions here: @ref hcrypto_rand + */ const static RAND_METHOD *selected_meth = NULL; +static ENGINE *selected_engine = NULL; static void init_method(void) @@ -59,6 +65,16 @@ init_method(void) selected_meth = &hc_rand_fortuna_method; } +/** + * Seed that random number generator. Secret material can securely be + * feed into the function, they will never be returned. + * + * @param indata seed data + * @param size length seed data + * + * @ingroup hcrypto_rand + */ + void RAND_seed(const void *indata, size_t size) { @@ -66,6 +82,16 @@ RAND_seed(const void *indata, size_t size) (*selected_meth->seed)(indata, size); } +/** + * Get a random block from the random generator, can be used for key material. + * + * @param outdata random data + * @param size length random data + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ int RAND_bytes(void *outdata, size_t size) { @@ -73,13 +99,39 @@ RAND_bytes(void *outdata, size_t size) return (*selected_meth->bytes)(outdata, size); } +/** + * Reset and free memory used by the random generator. + * + * @ingroup hcrypto_rand + */ + void RAND_cleanup(void) { - init_method(); - (*selected_meth->cleanup)(); + const RAND_METHOD *meth = selected_meth; + ENGINE *engine = selected_engine; + + selected_meth = NULL; + selected_engine = NULL; + + if (meth) + (*meth->cleanup)(); + if (engine) + ENGINE_finish(engine); } +/** + * Seed that random number generator. Secret material can securely be + * feed into the function, they will never be returned. + * + * @param indata the input data. + * @param size size of in data. + * @param entropi entropi in data. + * + * + * @ingroup hcrypto_rand + */ + void RAND_add(const void *indata, size_t size, double entropi) { @@ -87,6 +139,17 @@ RAND_add(const void *indata, size_t size, double entropi) (*selected_meth->add)(indata, size, entropi); } +/** + * Get a random block from the random generator, should NOT be used for key material. + * + * @param outdata random data + * @param size length random data + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ + int RAND_pseudo_bytes(void *outdata, size_t size) { @@ -94,6 +157,14 @@ RAND_pseudo_bytes(void *outdata, size_t size) return (*selected_meth->pseudorand)(outdata, size); } +/** + * Return status of the random generator + * + * @return 1 if the random generator can deliver random data. + * + * @ingroup hcrypto_rand + */ + int RAND_status(void) { @@ -101,27 +172,92 @@ RAND_status(void) return (*selected_meth->status)(); } +/** + * Set the default random method. + * + * @param meth set the new default method. + * + * @return 1 on success. + * + * @ingroup hcrypto_rand + */ + int RAND_set_rand_method(const RAND_METHOD *meth) { + const RAND_METHOD *old = selected_meth; selected_meth = meth; + if (old) + (*old->cleanup)(); + if (selected_engine) { + ENGINE_finish(selected_engine); + selected_engine = NULL; + } return 1; } +/** + * Get the default random method. + * + * @ingroup hcrypto_rand + */ + const RAND_METHOD * RAND_get_rand_method(void) { + init_method(); return selected_meth; } +/** + * Set the default random method from engine. + * + * @param engine use engine, if NULL is passed it, old method and engine is cleared. + * + * @return 1 on success, 0 on failure. + * + * @ingroup hcrypto_rand + */ + int RAND_set_rand_engine(ENGINE *engine) { + const RAND_METHOD *meth, *old = selected_meth; + + if (engine) { + ENGINE_up_ref(engine); + meth = ENGINE_get_RAND(engine); + if (meth == NULL) { + ENGINE_finish(engine); + return 0; + } + } else { + meth = NULL; + } + + if (old) + (*old->cleanup)(); + + if (selected_engine) + ENGINE_finish(selected_engine); + + selected_engine = engine; + selected_meth = meth; + return 1; } #define RAND_FILE_SIZE 1024 +/** + * Load a a file and feed it into RAND_seed(). + * + * @param filename name of file to read. + * @param size minimum size to read. + * + * @ingroup hcrypto_rand + */ + int RAND_load_file(const char *filename, size_t size) { @@ -133,7 +269,7 @@ RAND_load_file(const char *filename, size_t size) fd = open(filename, O_RDONLY | O_BINARY, 0600); if (fd < 0) return 0; - + rk_cloexec(fd); len = 0; while(len < size) { slen = read(fd, buf, sizeof(buf)); @@ -147,6 +283,15 @@ RAND_load_file(const char *filename, size_t size) return len ? 1 : 0; } +/** + * Write of random numbers to a file to store for later initiation with RAND_load_file(). + * + * @param filename name of file to write. + * + * @return 1 on success and non-one on failure. + * @ingroup hcrypto_rand + */ + int RAND_write_file(const char *filename) { @@ -157,6 +302,7 @@ RAND_write_file(const char *filename) fd = open(filename, O_WRONLY | O_CREAT | O_BINARY, 0600); if (fd < 0) return 0; + rk_cloexec(fd); len = 0; while(len < RAND_FILE_SIZE) { @@ -175,6 +321,18 @@ RAND_write_file(const char *filename) return res; } +/** + * Return the default random state filename for a user to use for + * RAND_load_file(), and RAND_write_file(). + * + * @param filename buffer to hold file name. + * @param size size of buffer filename. + * + * @return the buffer filename or NULL on failure. + * + * @ingroup hcrypto_rand + */ + const char * RAND_file_name(char *filename, size_t size) { |