Commit 599c0353 authored by Lutz Jänicke's avatar Lutz Jänicke
Browse files

Add automatic query of EGD sockets to RAND_poll(). The EGD sockets are

only queried when the /dev/[u]random devices did not return enough
entropy. Only the amount of entropy missing to reach the required minimum
is queried, as EGD may be drained.
Queried locations are: /etc/entropy, /var/run/egd-pool
parent 56a67adb
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -10,6 +10,12 @@
     (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example).
     [Geoff Thorpe]

  *) Add automatic query of EGD sockets in RAND_poll() for the unix variant.
     If an EGD or PRNGD is running and enough entropy is returned, automatic
     seeding like with /dev/[u]random will be performed.
     Positions tried are: /etc/entropy, /var/run/egd-pool.
     [Lutz Jaenicke]

  *) Change the Unix RAND_poll() variant to be able to poll several
     random devices and only read data for a small fragment of time
     to avoid hangs.  Also separate out the Unix variant to it's own
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ int RAND_load_file(const char *file,long max_bytes);
int  RAND_write_file(const char *file);
const char *RAND_file_name(char *file,int num);
int RAND_status(void);
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
int RAND_egd(const char *path);
int RAND_egd_bytes(const char *path,int bytes);
void ERR_load_RAND_strings(void);
+40 −10
Original line number Diff line number Diff line
@@ -60,6 +60,10 @@
 */

#if defined(WIN32) || defined(VMS) || defined(__VMS)
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
	{
	return(-1);
	}
int RAND_egd(const char *path)
	{
	return(-1);
@@ -81,13 +85,13 @@ int RAND_egd_bytes(const char *path,int bytes)
#  define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif

int RAND_egd(const char *path)
int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
	{
	int ret = -1;
	int ret = 0;
	struct sockaddr_un addr;
	int len, num;
	int fd = -1;
	unsigned char buf[256];
	unsigned char egdbuf[2];

	memset(&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
@@ -98,18 +102,44 @@ int RAND_egd(const char *path)
	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (fd == -1) return (-1);
	if (connect(fd, (struct sockaddr *)&addr, len) == -1) goto err;
	buf[0] = 1;
	buf[1] = 255;
	write(fd, buf, 2);
	if (read(fd, buf, 1) != 1) goto err;
	if (buf[0] == 0) goto err;
	num = read(fd, buf, 255);

	while(bytes > 0)
	    {
	    egdbuf[0] = 1;
	    egdbuf[1] = bytes < 255 ? bytes : 255;
	    write(fd, egdbuf, 2);
	    if (read(fd, egdbuf, 1) != 1)
		{
		ret=-1;
		goto err;
		}
	    if(egdbuf[0] == 0)
		goto err;
	    num = read(fd, buf + ret, egdbuf[0]);
	    if (num < 1)
		{
		ret=-1;
		goto err;
		}
	    ret += num;
	    bytes-=num;
	    }
 err:
	if (fd != -1) close(fd);
	return(ret);
	}

int RAND_egd(const char *path)
	{
	int num, ret;
	unsigned char buf[256];

	num = RAND_query_egd_bytes(path, buf, 255);
	if (num < 1) goto err;
	RAND_seed(buf, num);
	if (RAND_status() == 1)
		ret = num;
 err:
	if (fd != -1) close(fd);
	return(ret);
	}

+26 −2
Original line number Diff line number Diff line
@@ -125,13 +125,19 @@ int RAND_poll(void)
{
	unsigned long l;
	pid_t curr_pid = getpid();
#ifdef DEVRANDOM
#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
	unsigned char tmpbuf[ENTROPY_NEEDED];
	int n = 0;
#endif
#ifdef DEVRANDOM
	static const char *randomfiles[] = { DEVRANDOM, NULL };
	const char **randomfile = NULL;
	int fd;
#endif
#ifdef DEVRANDOM_EGD
	static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
	const char **egdsocket = NULL;
#endif

#ifdef DEVRANDOM
	/* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
@@ -185,6 +191,24 @@ int RAND_poll(void)
			close(fd);
			}
		}
#endif

#ifdef DEVRANDOM_EGD
	/* Use an EGD socket to read entropy from an EGD or PRNGD entropy
	 * collecting daemon. */

	for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
		{
		int r;

		r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
					 ENTROPY_NEEDED-n);
		if (r > 0)
			n += r;
		}
#endif

#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
	if (n > 0)
		{
		RAND_add(tmpbuf,sizeof tmpbuf,n);
@@ -201,7 +225,7 @@ int RAND_poll(void)
	l=time(NULL);
	RAND_add(&l,sizeof(l),0);

#ifdef DEVRANDOM
#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
	return 1;
#endif
	return 0;
+6 −0
Original line number Diff line number Diff line
@@ -81,6 +81,12 @@ extern "C" {
 * My default, we will try to read at least one of these files */
#define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
#endif
#ifndef DEVRANDOM_EGD
/* set this to a comma-seperated list of 'egd' sockets to try out. These
 * sockets will be tried in the order listed in case accessing the device files
 * listed in DEVRANDOM did not return enough entropy. */
#define DEVRANDOM_EGD "/etc/entropy","/var/run/egd-pool"
#endif

#if defined(__MWERKS__) && defined(macintosh)
# if macintosh==1