diff options
Diffstat (limited to 'libgcrypt-1.4.6/random/random.c')
-rw-r--r-- | libgcrypt-1.4.6/random/random.c | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/libgcrypt-1.4.6/random/random.c b/libgcrypt-1.4.6/random/random.c new file mode 100644 index 0000000..8df87e2 --- /dev/null +++ b/libgcrypt-1.4.6/random/random.c @@ -0,0 +1,323 @@ +/* random.c - Random number switch + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/* + This module switches between different implementations of random + number generators and provides a few help functions. + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +#include "g10lib.h" +#include "random.h" +#include "rand-internal.h" +#include "ath.h" + + +/* If not NULL a progress function called from certain places and the + opaque value passed along. Registred by + _gcry_register_random_progress (). */ +static void (*progress_cb) (void *,const char*,int,int, int ); +static void *progress_cb_data; + + + + +/* --- Functions --- */ + + +/* Used to register a progress callback. This needs to be called + before any threads are created. */ +void +_gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int), + void *cb_data ) +{ + progress_cb = cb; + progress_cb_data = cb_data; +} + + +/* This progress function is currently used by the random modules to + give hints on how much more entropy is required. */ +void +_gcry_random_progress (const char *what, int printchar, int current, int total) +{ + if (progress_cb) + progress_cb (progress_cb_data, what, printchar, current, total); +} + + + +/* Initialize this random subsystem. If FULL is false, this function + merely calls the basic initialization of the module and does not do + anything more. Doing this is not really required but when running + in a threaded environment we might get a race condition + otherwise. */ +void +_gcry_random_initialize (int full) +{ + if (fips_mode ()) + _gcry_rngfips_initialize (full); + else + _gcry_rngcsprng_initialize (full); +} + + +void +_gcry_random_dump_stats (void) +{ + if (fips_mode ()) + _gcry_rngfips_dump_stats (); + else + _gcry_rngcsprng_dump_stats (); +} + + +/* This function should be called during initialization and beore + intialization of this module to place the random pools into secure + memory. */ +void +_gcry_secure_random_alloc (void) +{ + if (fips_mode ()) + ; /* Not used; the fips rng is allows in secure mode. */ + else + _gcry_rngcsprng_secure_alloc (); +} + + +/* This may be called before full initialization to degrade the + quality of the RNG for the sake of a faster running test suite. */ +void +_gcry_enable_quick_random_gen (void) +{ + if (fips_mode ()) + ; /* Not used. */ + else + _gcry_rngcsprng_enable_quick_gen (); +} + + +void +_gcry_set_random_daemon_socket (const char *socketname) +{ + if (fips_mode ()) + ; /* Not used. */ + else + _gcry_rngcsprng_set_daemon_socket (socketname); +} + +/* With ONOFF set to 1, enable the use of the daemon. With ONOFF set + to 0, disable the use of the daemon. With ONOF set to -1, return + whether the daemon has been enabled. */ +int +_gcry_use_random_daemon (int onoff) +{ + if (fips_mode ()) + return 0; /* Never enabled in fips mode. */ + else + return _gcry_rngcsprng_use_daemon (onoff); +} + + +/* This function returns true if no real RNG is available or the + quality of the RNG has been degraded for test purposes. */ +int +_gcry_random_is_faked (void) +{ + if (fips_mode ()) + return _gcry_rngfips_is_faked (); + else + return _gcry_rngcsprng_is_faked (); +} + + +/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY + should be in the range of 0..100 to indicate the goodness of the + entropy added, or -1 for goodness not known. */ +gcry_error_t +gcry_random_add_bytes (const void *buf, size_t buflen, int quality) +{ + if (fips_mode ()) + return 0; /* No need for this in fips mode. */ + else + return _gcry_rngcsprng_add_bytes (buf, buflen, quality); +} + + +/* Helper function. */ +static void +do_randomize (void *buffer, size_t length, enum gcry_random_level level) +{ + if (fips_mode ()) + _gcry_rngfips_randomize (buffer, length, level); + else + _gcry_rngcsprng_randomize (buffer, length, level); +} + +/* The public function to return random data of the quality LEVEL. + Returns a pointer to a newly allocated and randomized buffer of + LEVEL and NBYTES length. Caller must free the buffer. */ +void * +gcry_random_bytes (size_t nbytes, enum gcry_random_level level) +{ + void *buffer; + + buffer = gcry_xmalloc (nbytes); + do_randomize (buffer, nbytes, level); + return buffer; +} + + +/* The public function to return random data of the quality LEVEL; + this version of the function returns the random in a buffer allocated + in secure memory. Caller must free the buffer. */ +void * +gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) +{ + void *buffer; + + /* Historical note (1.3.0--1.4.1): The buffer was only allocated + in secure memory if the pool in random-csprng.c was also set to + use secure memory. */ + buffer = gcry_xmalloc_secure (nbytes); + do_randomize (buffer, nbytes, level); + return buffer; +} + + +/* Public function to fill the buffer with LENGTH bytes of + cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is + not very strong, GCRY_STRONG_RANDOM is strong enough for most + usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but + may be very slow. */ +void +gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) +{ + do_randomize (buffer, length, level); +} + + +/* This function may be used to specify the file to be used as a seed + file for the PRNG. This fucntion should be called prior to the + initialization of the random module. NAME may not be NULL. */ +void +_gcry_set_random_seed_file (const char *name) +{ + if (fips_mode ()) + ; /* No need for this in fips mode. */ + else + _gcry_rngcsprng_set_seed_file (name); +} + + +/* If a seed file has been setup, this function may be used to write + back the random numbers entropy pool. */ +void +_gcry_update_random_seed_file (void) +{ + if (fips_mode ()) + ; /* No need for this in fips mode. */ + else + _gcry_rngcsprng_update_seed_file (); +} + + + +/* The fast random pool function as called at some places in + libgcrypt. This is merely a wrapper to make sure that this module + is initalized and to lock the pool. Note, that this function is a + NOP unless a random function has been used or _gcry_initialize (1) + has been used. We use this hack so that the internal use of this + function in cipher_open and md_open won't start filling up the + random pool, even if no random will be required by the process. */ +void +_gcry_fast_random_poll (void) +{ + if (fips_mode ()) + ; /* No need for this in fips mode. */ + else + _gcry_rngcsprng_fast_poll (); +} + + + +/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ +void +gcry_create_nonce (void *buffer, size_t length) +{ + if (fips_mode ()) + _gcry_rngfips_create_nonce (buffer, length); + else + _gcry_rngcsprng_create_nonce (buffer, length); +} + + +/* Run the self-tests for the RNG. This is currently only implemented + for the FIPS generator. */ +gpg_error_t +_gcry_random_selftest (selftest_report_func_t report) +{ + if (fips_mode ()) + return _gcry_rngfips_selftest (report); + else + return 0; /* No selftests yet. */ +} + + +/* Create a new test context for an external RNG test driver. On + success the test context is stored at R_CONTEXT; on failure NULL is + stored at R_CONTEXT and an error code is returned. */ +gcry_err_code_t +_gcry_random_init_external_test (void **r_context, + unsigned int flags, + const void *key, size_t keylen, + const void *seed, size_t seedlen, + const void *dt, size_t dtlen) +{ + (void)flags; + if (fips_mode ()) + return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, + seed, seedlen, + dt, dtlen); + else + return GPG_ERR_NOT_SUPPORTED; +} + +/* Get BUFLEN bytes from the RNG using the test CONTEXT and store them + at BUFFER. Return 0 on success or an error code. */ +gcry_err_code_t +_gcry_random_run_external_test (void *context, char *buffer, size_t buflen) +{ + if (fips_mode ()) + return _gcry_rngfips_run_external_test (context, buffer, buflen); + else + return GPG_ERR_NOT_SUPPORTED; +} + +/* Release the test CONTEXT. */ +void +_gcry_random_deinit_external_test (void *context) +{ + if (fips_mode ()) + _gcry_rngfips_deinit_external_test (context); +} |