[openssh-commits] [openssh] 01/02: Split EGD/PRNGD interface into its own file.

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Jun 18 19:34:43 AEST 2021


This is an automated email from the git hooks/post-receive script.

dtucker pushed a commit to branch master
in repository openssh.

commit e43a898043faa3a965dbaa1193cc60e0b479033d
Author: Darren Tucker <dtucker at dtucker.net>
Date:   Fri Jun 18 18:32:51 2021 +1000

    Split EGD/PRNGD interface into its own file.
    
    This will allow us to use it when building --without-openssl.
---
 entropy.c                                | 123 -------------------------------
 openbsd-compat/Makefile.in               |   1 +
 openbsd-compat/bsd-misc.h                |   1 +
 entropy.c => openbsd-compat/port-prngd.c | 114 ++--------------------------
 4 files changed, 7 insertions(+), 232 deletions(-)

diff --git a/entropy.c b/entropy.c
index 19ddeeaf..a4088e43 100644
--- a/entropy.c
+++ b/entropy.c
@@ -29,20 +29,12 @@
 #ifdef WITH_OPENSSL
 
 #include <sys/types.h>
-#include <sys/socket.h>
-#ifdef HAVE_SYS_UN_H
-# include <sys/un.h>
-#endif
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
 
 #include <errno.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <stddef.h> /* for offsetof */
 
 #include <openssl/rand.h>
 #include <openssl/crypto.h>
@@ -67,121 +59,6 @@
  */
 #ifndef OPENSSL_PRNG_ONLY
 
-/*
- * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
- * listening either on 'tcp_port', or via Unix domain socket at *
- * 'socket_path'.
- * Either a non-zero tcp_port or a non-null socket_path must be
- * supplied.
- * Returns 0 on success, -1 on error
- */
-int
-get_random_bytes_prngd(unsigned char *buf, int len,
-    unsigned short tcp_port, char *socket_path)
-{
-	int fd, addr_len, rval, errors;
-	u_char msg[2];
-	struct sockaddr_storage addr;
-	struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
-	struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;
-	sshsig_t old_sigpipe;
-
-	/* Sanity checks */
-	if (socket_path == NULL && tcp_port == 0)
-		fatal("You must specify a port or a socket");
-	if (socket_path != NULL &&
-	    strlen(socket_path) >= sizeof(addr_un->sun_path))
-		fatal("Random pool path is too long");
-	if (len <= 0 || len > 255)
-		fatal("Too many bytes (%d) to read from PRNGD", len);
-
-	memset(&addr, '\0', sizeof(addr));
-
-	if (tcp_port != 0) {
-		addr_in->sin_family = AF_INET;
-		addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-		addr_in->sin_port = htons(tcp_port);
-		addr_len = sizeof(*addr_in);
-	} else {
-		addr_un->sun_family = AF_UNIX;
-		strlcpy(addr_un->sun_path, socket_path,
-		    sizeof(addr_un->sun_path));
-		addr_len = offsetof(struct sockaddr_un, sun_path) +
-		    strlen(socket_path) + 1;
-	}
-
-	old_sigpipe = ssh_signal(SIGPIPE, SIG_IGN);
-
-	errors = 0;
-	rval = -1;
-reopen:
-	fd = socket(addr.ss_family, SOCK_STREAM, 0);
-	if (fd == -1) {
-		error("Couldn't create socket: %s", strerror(errno));
-		goto done;
-	}
-
-	if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
-		if (tcp_port != 0) {
-			error("Couldn't connect to PRNGD port %d: %s",
-			    tcp_port, strerror(errno));
-		} else {
-			error("Couldn't connect to PRNGD socket \"%s\": %s",
-			    addr_un->sun_path, strerror(errno));
-		}
-		goto done;
-	}
-
-	/* Send blocking read request to PRNGD */
-	msg[0] = 0x02;
-	msg[1] = len;
-
-	if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) {
-		if (errno == EPIPE && errors < 10) {
-			close(fd);
-			errors++;
-			goto reopen;
-		}
-		error("Couldn't write to PRNGD socket: %s",
-		    strerror(errno));
-		goto done;
-	}
-
-	if (atomicio(read, fd, buf, len) != (size_t)len) {
-		if (errno == EPIPE && errors < 10) {
-			close(fd);
-			errors++;
-			goto reopen;
-		}
-		error("Couldn't read from PRNGD socket: %s",
-		    strerror(errno));
-		goto done;
-	}
-
-	rval = 0;
-done:
-	ssh_signal(SIGPIPE, old_sigpipe);
-	if (fd != -1)
-		close(fd);
-	return rval;
-}
-
-static int
-seed_from_prngd(unsigned char *buf, size_t bytes)
-{
-#ifdef PRNGD_PORT
-	debug("trying egd/prngd port %d", PRNGD_PORT);
-	if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == 0)
-		return 0;
-#endif
-#ifdef PRNGD_SOCKET
-	debug("trying egd/prngd socket %s", PRNGD_SOCKET);
-	if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == 0)
-		return 0;
-#endif
-	return -1;
-}
-
 void
 rexec_send_rng_seed(struct sshbuf *m)
 {
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index 555e09b5..5d53bef5 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -95,6 +95,7 @@ COMPAT=	arc4random.o \
 PORTS=	port-aix.o \
 	port-irix.o \
 	port-linux.o \
+	port-prngd.o \
 	port-solaris.o \
 	port-net.o \
 	port-uw.o
diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h
index def64238..2206e1a8 100644
--- a/openbsd-compat/bsd-misc.h
+++ b/openbsd-compat/bsd-misc.h
@@ -20,6 +20,7 @@
 #include "includes.h"
 
 char *ssh_get_progname(char *);
+int seed_from_prngd(unsigned char *, size_t);
 
 #ifndef HAVE_SETSID
 #define setsid() setpgrp(0, getpid())
diff --git a/entropy.c b/openbsd-compat/port-prngd.c
similarity index 66%
copy from entropy.c
copy to openbsd-compat/port-prngd.c
index 19ddeeaf..915f8206 100644
--- a/entropy.c
+++ b/openbsd-compat/port-prngd.c
@@ -24,10 +24,6 @@
 
 #include "includes.h"
 
-#define RANDOM_SEED_SIZE 48
-
-#ifdef WITH_OPENSSL
-
 #include <sys/types.h>
 #include <sys/socket.h>
 #ifdef HAVE_SYS_UN_H
@@ -44,30 +40,13 @@
 #include <unistd.h>
 #include <stddef.h> /* for offsetof */
 
-#include <openssl/rand.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-
-#include "openbsd-compat/openssl-compat.h"
-
-#include "ssh.h"
-#include "misc.h"
-#include "xmalloc.h"
 #include "atomicio.h"
-#include "pathnames.h"
+#include "misc.h"
 #include "log.h"
-#include "sshbuf.h"
-#include "ssherr.h"
-
-/*
- * Portable OpenSSH PRNG seeding:
- * If OpenSSL has not "internally seeded" itself (e.g. pulled data from
- * /dev/random), then collect RANDOM_SEED_SIZE bytes of randomness from
- * PRNGd.
- */
-#ifndef OPENSSL_PRNG_ONLY
 
 /*
+ * EGD/PRNGD interface.
+ *
  * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
  * listening either on 'tcp_port', or via Unix domain socket at *
  * 'socket_path'.
@@ -75,7 +54,7 @@
  * supplied.
  * Returns 0 on success, -1 on error
  */
-int
+static int
 get_random_bytes_prngd(unsigned char *buf, int len,
     unsigned short tcp_port, char *socket_path)
 {
@@ -166,7 +145,7 @@ done:
 	return rval;
 }
 
-static int
+int
 seed_from_prngd(unsigned char *buf, size_t bytes)
 {
 #ifdef PRNGD_PORT
@@ -181,86 +160,3 @@ seed_from_prngd(unsigned char *buf, size_t bytes)
 #endif
 	return -1;
 }
-
-void
-rexec_send_rng_seed(struct sshbuf *m)
-{
-	u_char buf[RANDOM_SEED_SIZE];
-	size_t len = sizeof(buf);
-	int r;
-
-	if (RAND_bytes(buf, sizeof(buf)) <= 0) {
-		error("Couldn't obtain random bytes (error %ld)",
-		    ERR_get_error());
-		len = 0;
-	}
-	if ((r = sshbuf_put_string(m, buf, len)) != 0)
-		fatal("%s: buffer error: %s", __func__, ssh_err(r));
-	explicit_bzero(buf, sizeof(buf));
-}
-
-void
-rexec_recv_rng_seed(struct sshbuf *m)
-{
-	const u_char *buf = NULL;
-	size_t len = 0;
-	int r;
-
-	if ((r = sshbuf_get_string_direct(m, &buf, &len)) != 0)
-		fatal("%s: buffer error: %s", __func__, ssh_err(r));
-
-	debug3("rexec_recv_rng_seed: seeding rng with %lu bytes",
-	    (unsigned long)len);
-	RAND_add(buf, len, len);
-}
-#endif /* OPENSSL_PRNG_ONLY */
-
-void
-seed_rng(void)
-{
-	unsigned char buf[RANDOM_SEED_SIZE];
-
-	/* Initialise libcrypto */
-	ssh_libcrypto_init();
-
-	if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER,
-	    OpenSSL_version_num()))
-		fatal("OpenSSL version mismatch. Built against %lx, you "
-		    "have %lx", (u_long)OPENSSL_VERSION_NUMBER,
-		    OpenSSL_version_num());
-
-#ifndef OPENSSL_PRNG_ONLY
-	if (RAND_status() == 1)
-		debug3("RNG is ready, skipping seeding");
-	else {
-		if (seed_from_prngd(buf, sizeof(buf)) == -1)
-			fatal("Could not obtain seed from PRNGd");
-		RAND_add(buf, sizeof(buf), sizeof(buf));
-	}
-#endif /* OPENSSL_PRNG_ONLY */
-
-	if (RAND_status() != 1)
-		fatal("PRNG is not seeded");
-
-	/* Ensure arc4random() is primed */
-	arc4random_buf(buf, sizeof(buf));
-	explicit_bzero(buf, sizeof(buf));
-}
-
-#else /* WITH_OPENSSL */
-
-#include <stdlib.h>
-#include <string.h>
-
-/* Actual initialisation is handled in arc4random() */
-void
-seed_rng(void)
-{
-	unsigned char buf[RANDOM_SEED_SIZE];
-
-	/* Ensure arc4random() is primed */
-	arc4random_buf(buf, sizeof(buf));
-	explicit_bzero(buf, sizeof(buf));
-}
-
-#endif /* WITH_OPENSSL */

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list