#include <string.h>
#include <unistd.h>
-#ifdef HAVE_SYS_RANDOM_H
-# include <sys/random.h>
-#endif
-
#ifndef HAVE_ARC4RANDOM
#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b))
-#ifdef WITH_OPENSSL
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#endif
-
#include "log.h"
#define KEYSTREAM_ONLY
chacha_ivsetup(&rs, buf + KEYSZ);
}
-#ifndef WITH_OPENSSL
-# ifndef SSH_RANDOM_DEV
-# define SSH_RANDOM_DEV "/dev/urandom"
-# endif /* SSH_RANDOM_DEV */
-static void
-getrnd(u_char *s, size_t len)
-{
- int fd, save_errno;
- ssize_t r;
- size_t o = 0;
-
-#ifdef HAVE_GETRANDOM
- if ((r = getrandom(s, len, 0)) > 0 && (size_t)r == len)
- return;
-#endif /* HAVE_GETRANDOM */
-
- if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) {
- save_errno = errno;
- /* Try egd/prngd before giving up. */
- if (seed_from_prngd(s, len) == 0)
- return;
- fatal("Couldn't open %s: %s", SSH_RANDOM_DEV,
- strerror(save_errno));
- }
- while (o < len) {
- r = read(fd, s + o, len - o);
- if (r < 0) {
- if (errno == EAGAIN || errno == EINTR ||
- errno == EWOULDBLOCK)
- continue;
- fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno));
- }
- o += r;
- }
- close(fd);
-}
-#endif /* WITH_OPENSSL */
-
static void
_rs_stir(void)
{
u_char rnd[KEYSZ + IVSZ];
-#ifdef WITH_OPENSSL
- if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
- fatal("Couldn't obtain random bytes (error 0x%lx)",
- (unsigned long)ERR_get_error());
-#else
- getrnd(rnd, sizeof(rnd));
-#endif
+ if (getentropy(rnd, sizeof rnd) == -1)
+ fatal("getentropy failed");
if (!rs_initialized) {
rs_initialized = 1;
--- /dev/null
+/*
+ * Copyright (c) 1996, David Mazieres <dm@uun.org>
+ * Copyright (c) 2008, Damien Miller <djm@openbsd.org>
+ * Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#ifndef HAVE_GETENTROPY
+
+#ifndef SSH_RANDOM_DEV
+# define SSH_RANDOM_DEV "/dev/urandom"
+#endif /* SSH_RANDOM_DEV */
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_RANDOM_H
+# include <sys/random.h>
+#endif
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef WITH_OPENSSL
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#endif
+
+#include "log.h"
+
+int
+getentropy(void *s, size_t len)
+{
+#ifdef WITH_OPENSSL
+ if (RAND_bytes(s, len) <= 0)
+ fatal("Couldn't obtain random bytes (error 0x%lx)",
+ (unsigned long)ERR_get_error());
+#else
+ int fd, save_errno;
+ ssize_t r;
+ size_t o = 0;
+
+#ifdef HAVE_GETRANDOM
+ if ((r = getrandom(s, len, 0)) > 0 && (size_t)r == len)
+ return 0;
+#endif /* HAVE_GETRANDOM */
+
+ if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) {
+ save_errno = errno;
+ /* Try egd/prngd before giving up. */
+ if (seed_from_prngd(s, len) == 0)
+ return 0;
+ fatal("Couldn't open %s: %s", SSH_RANDOM_DEV,
+ strerror(save_errno));
+ }
+ while (o < len) {
+ r = read(fd, (u_char *)s + o, len - o);
+ if (r < 0) {
+ if (errno == EAGAIN || errno == EINTR ||
+ errno == EWOULDBLOCK)
+ continue;
+ fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno));
+ }
+ o += r;
+ }
+ close(fd);
+#endif /* WITH_OPENSSL */
+ return 0;
+}
+#endif /* WITH_GETENTROPY */