summaryrefslogtreecommitdiff
path: root/libgcrypt-1.4.6/random/random.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgcrypt-1.4.6/random/random.c')
-rw-r--r--libgcrypt-1.4.6/random/random.c323
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);
+}