/crypto/external/bsd/heimdal/dist/lib/krb5/crypto-rand.c
http://www.minix3.org/ · C · 111 lines · 57 code · 13 blank · 41 comment · 14 complexity · 5616485d2605680b94ae7c684b77cac5 MD5 · raw file
- /* $NetBSD: crypto-rand.c,v 1.1.1.1 2011/04/13 18:15:32 elric Exp $ */
- /*
- * Copyright (c) 1997 - 2008 Kungliga Tekniska Hรถgskolan
- * (Royal Institute of Technology, Stockholm, Sweden).
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
- #include "krb5_locl.h"
- #define ENTROPY_NEEDED 128
- static HEIMDAL_MUTEX crypto_mutex = HEIMDAL_MUTEX_INITIALIZER;
- static int
- seed_something(void)
- {
- char buf[1024], seedfile[256];
- /* If there is a seed file, load it. But such a file cannot be trusted,
- so use 0 for the entropy estimate */
- if (RAND_file_name(seedfile, sizeof(seedfile))) {
- int fd;
- fd = open(seedfile, O_RDONLY | O_BINARY | O_CLOEXEC);
- if (fd >= 0) {
- ssize_t ret;
- rk_cloexec(fd);
- ret = read(fd, buf, sizeof(buf));
- if (ret > 0)
- RAND_add(buf, ret, 0.0);
- close(fd);
- } else
- seedfile[0] = '\0';
- } else
- seedfile[0] = '\0';
- /* Calling RAND_status() will try to use /dev/urandom if it exists so
- we do not have to deal with it. */
- if (RAND_status() != 1) {
- #ifndef _WIN32
- krb5_context context;
- const char *p;
- /* Try using egd */
- if (!krb5_init_context(&context)) {
- p = krb5_config_get_string(context, NULL, "libdefaults",
- "egd_socket", NULL);
- if (p != NULL)
- RAND_egd_bytes(p, ENTROPY_NEEDED);
- krb5_free_context(context);
- }
- #else
- /* TODO: Once a Windows CryptoAPI RAND method is defined, we
- can use that and failover to another method. */
- #endif
- }
- if (RAND_status() == 1) {
- /* Update the seed file */
- if (seedfile[0])
- RAND_write_file(seedfile);
- return 0;
- } else
- return -1;
- }
- KRB5_LIB_FUNCTION void KRB5_LIB_CALL
- krb5_generate_random_block(void *buf, size_t len)
- {
- static int rng_initialized = 0;
- HEIMDAL_MUTEX_lock(&crypto_mutex);
- if (!rng_initialized) {
- if (seed_something())
- krb5_abortx(NULL, "Fatal: could not seed the "
- "random number generator");
- rng_initialized = 1;
- }
- HEIMDAL_MUTEX_unlock(&crypto_mutex);
- if (RAND_bytes(buf, len) <= 0)
- krb5_abortx(NULL, "Failed to generate random block");
- }