changeset 272:3be7ae2e8dfa

Only read /dev/random once when the program starts rather than for every connection, to "conserve entropy".
author Matt Johnston <matt@ucc.asn.au>
date Sat, 11 Feb 2006 15:15:37 +0000
parents be18c7dd486e
children 8438ff0cdb74
files cli-session.c random.c random.h svr-chansession.c svr-main.c svr-session.c
diffstat 6 files changed, 39 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/cli-session.c	Wed Feb 01 09:05:13 2006 +0000
+++ b/cli-session.c	Sat Feb 11 15:15:37 2006 +0000
@@ -76,12 +76,14 @@
 
 void cli_session(int sock, char* remotehost) {
 
+	seedrandom();
+
 	crypto_init();
+
 	common_session_init(sock, remotehost);
 
 	chaninitialise(cli_chantypes);
 
-
 	/* Set up cli_ses vars */
 	cli_session_init();
 
@@ -91,12 +93,8 @@
 	/* Exchange identification */
 	session_identification();
 
-	seedrandom();
-
 	send_msg_kexinit();
 
-	/* XXX here we do stuff differently */
-
 	session_loop(cli_sessionloop);
 
 	/* Not reached */
--- a/random.c	Wed Feb 01 09:05:13 2006 +0000
+++ b/random.c	Sat Feb 11 15:15:37 2006 +0000
@@ -30,8 +30,8 @@
 static int donerandinit = 0;
 
 /* this is used to generate unique output from the same hashpool */
-static unsigned int counter = 0;
-#define MAX_COUNTER 1000000/* the max value for the counter, so it won't loop */
+static uint32_t counter = 0;
+#define MAX_COUNTER 1<<31 /* the max value for the counter, so it won't loop */
 
 static unsigned char hashpool[SHA1_HASH_SIZE];
 
@@ -132,7 +132,8 @@
 
 	hash_state hs;
 
-	/* initialise so compilers will be happy about hashing it */
+	/* initialise so that things won't warn about
+     * hashing an undefined buffer */
 	if (!donerandinit) {
 		m_burn(hashpool, sizeof(hashpool));
 	}
@@ -150,6 +151,30 @@
 	donerandinit = 1;
 }
 
+/* hash the current random pool with some unique identifiers
+ * for this process and point-in-time. this is used to separate
+ * the random pools for fork()ed processes. */
+void reseedrandom() {
+
+    pid_t pid;
+    struct timeval tv;
+
+	if (!donerandinit) {
+		dropbear_exit("seedrandom not done");
+	}
+
+    pid = getpid();
+    gettimeofday(&tv, NULL);
+
+	hash_state hs;
+	unsigned char hash[SHA1_HASH_SIZE];
+	sha1_init(&hs);
+	sha1_process(&hs, (void*)hashpool, sizeof(hashpool));
+	sha1_process(&hs, (void*)&pid, sizeof(pid));
+	sha1_process(&hs, (void*)&tv, sizeof(tv));
+	sha1_done(&hs, hashpool);
+}
+
 /* return len bytes of pseudo-random data */
 void genrandom(unsigned char* buf, unsigned int len) {
 
--- a/random.h	Wed Feb 01 09:05:13 2006 +0000
+++ b/random.h	Sat Feb 11 15:15:37 2006 +0000
@@ -28,6 +28,7 @@
 struct mp_int;
 
 void seedrandom();
+void reseedrandom();
 void genrandom(unsigned char* buf, int len);
 void addrandom(unsigned char* buf, int len);
 void gen_random_mpint(mp_int *max, mp_int *rand);
--- a/svr-chansession.c	Wed Feb 01 09:05:13 2006 +0000
+++ b/svr-chansession.c	Sat Feb 11 15:15:37 2006 +0000
@@ -833,7 +833,7 @@
 	svr_opts.hostkey = NULL;
 
 	/* overwrite the prng state */
-	seedrandom();
+	reseedrandom();
 
 	/* close file descriptors except stdin/stdout/stderr
 	 * Need to be sure FDs are closed here to avoid reading files as root */
--- a/svr-main.c	Wed Feb 01 09:05:13 2006 +0000
+++ b/svr-main.c	Sat Feb 11 15:15:37 2006 +0000
@@ -83,7 +83,7 @@
 	int remoteaddrlen;
 	char * addrstring = NULL;
 
-	/* Set up handlers, syslog */
+	/* Set up handlers, syslog, seed random */
 	commonsetup();
 
 	remoteaddrlen = sizeof(remoteaddr);
@@ -359,6 +359,8 @@
 	/* Now we can setup the hostkeys - needs to be after logging is on,
 	 * otherwise we might end up blatting error messages to the socket */
 	loadhostkeys();
+
+    seedrandom();
 }
 
 /* Set up listening sockets for all the requested ports */
--- a/svr-session.c	Wed Feb 01 09:05:13 2006 +0000
+++ b/svr-session.c	Sat Feb 11 15:15:37 2006 +0000
@@ -78,7 +78,9 @@
 		char* remotehost, char *addrstring) {
 
 	struct timeval timeout;
-	
+
+    reseedrandom();
+
 	crypto_init();
 	common_session_init(sock, remotehost);
 
@@ -110,8 +112,6 @@
 	/* exchange identification, version etc */
 	session_identification();
 
-	seedrandom();
-
 	/* start off with key exchange */
 	send_msg_kexinit();