diff options
Diffstat (limited to 'contrib/ntp/libntp/ntp_crypto_rnd.c')
-rw-r--r-- | contrib/ntp/libntp/ntp_crypto_rnd.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/contrib/ntp/libntp/ntp_crypto_rnd.c b/contrib/ntp/libntp/ntp_crypto_rnd.c new file mode 100644 index 000000000000..5fe7382efb79 --- /dev/null +++ b/contrib/ntp/libntp/ntp_crypto_rnd.c @@ -0,0 +1,115 @@ +/* + * Crypto-quality random number functions + * + * Author: Harlan Stenn, 2014 + * + * This file is Copyright (c) 2014 by Network Time Foundation. + * BSD terms apply: see the file COPYRIGHT in the distribution root for details. + */ + +#include "config.h" +#include <sys/types.h> +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif +#include <stdio.h> + +#include <ntp_stdlib.h> +#include <ntp_random.h> +#include "safecast.h" + +#ifdef USE_OPENSSL_CRYPTO_RAND +#include <openssl/err.h> +#include <openssl/rand.h> + +int crypto_rand_init = 0; +#elif !defined(HAVE_ARC4RANDOM_BUF) +#include <event2/util.h> +#endif + +int crypto_rand_ok = 0; + +/* + * As of late 2014, here's how we plan to provide cryptographic-quality + * random numbers: + * + * - If we are building with OpenSSL, use RAND_poll() and RAND_bytes(). + * - Otherwise, use arc4random(). + * + * Use of arc4random() can be forced using configure options + * --disable-openssl-random or --without-crypto. + * + * We can count on arc4random existing, thru the OS or thru libevent. + * The quality of arc4random depends on the implementor. + * + * RAND_poll() doesn't show up until XXX. If it's not present, we + * need to either provide our own or use arc4random(). + */ + + /* + * ntp_crypto_srandom: + * + * Initialize the random number generator, if needed by the underlying + * crypto random number generation mechanism. + */ + +void +ntp_crypto_srandom( + void +) +{ +#ifdef USE_OPENSSL_CRYPTO_RAND + if (!crypto_rand_init) { + if (RAND_poll()) + crypto_rand_ok = 1; + crypto_rand_init = 1; + } +#elif HAVE_ARC4RANDOM_BUF + /* + * arc4random_buf has no error return and needs no seeding nor reseeding. + */ + crypto_rand_ok = 1; +#else + /* + * Explicitly init libevent secure RNG to make sure it seeds. + * This is the only way we can tell if it can successfully get + * entropy from the system. + */ + if (!evutil_secure_rng_init()) + crypto_rand_ok = 1; +#endif +} + + +/* + * ntp_crypto_random_buf: Used by ntp-keygen + * + * Returns 0 on success, -1 on error. + */ +int +ntp_crypto_random_buf( + void *buf, + size_t nbytes + ) +{ + if (!crypto_rand_ok) + return -1; + +#if defined(USE_OPENSSL_CRYPTO_RAND) + if (1 != RAND_bytes(buf, size2int_chk(nbytes))) { + unsigned long err; + char *err_str; + + err = ERR_get_error(); + err_str = ERR_error_string(err, NULL); + msyslog(LOG_ERR, "RAND_bytes failed: %s", err_str); + + return -1; + } +#elif defined(HAVE_ARC4RANDOM_BUF) + arc4random_buf(buf, nbytes); +#else + evutil_secure_rng_get_bytes(buf, nbytes); +#endif + return 0; +} |