summaryrefslogtreecommitdiff
path: root/entropy.c
diff options
context:
space:
mode:
Diffstat (limited to 'entropy.c')
-rw-r--r--entropy.c99
1 files changed, 61 insertions, 38 deletions
diff --git a/entropy.c b/entropy.c
index 09dcae3ba..83759ca65 100644
--- a/entropy.c
+++ b/entropy.c
@@ -35,7 +35,7 @@
35#include <openssl/rand.h> 35#include <openssl/rand.h>
36#include <openssl/sha.h> 36#include <openssl/sha.h>
37 37
38RCSID("$Id: entropy.c,v 1.14 2000/06/18 04:07:04 djm Exp $"); 38RCSID("$Id: entropy.c,v 1.15 2000/06/26 03:01:33 djm Exp $");
39 39
40#ifndef offsetof 40#ifndef offsetof
41# define offsetof(type, member) ((size_t) &((type *)0)->member) 41# define offsetof(type, member) ((size_t) &((type *)0)->member)
@@ -66,64 +66,83 @@ RCSID("$Id: entropy.c,v 1.14 2000/06/18 04:07:04 djm Exp $");
66 66
67#ifdef EGD_SOCKET 67#ifdef EGD_SOCKET
68/* Collect entropy from EGD */ 68/* Collect entropy from EGD */
69void get_random_bytes(unsigned char *buf, int len) 69int get_random_bytes(unsigned char *buf, int len)
70{ 70{
71 static int egd_socket = -1; 71 int fd;
72 int c; 72 char msg[2];
73 char egd_message[2] = { 0x02, 0x00 };
74 struct sockaddr_un addr; 73 struct sockaddr_un addr;
75 int addr_len; 74 int addr_len;
76 75
77 memset(&addr, '\0', sizeof(addr)); 76 /* Sanity checks */
78 addr.sun_family = AF_UNIX;
79
80 /* FIXME: compile time check? */
81 if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path)) 77 if (sizeof(EGD_SOCKET) > sizeof(addr.sun_path))
82 fatal("Random pool path is too long"); 78 fatal("Random pool path is too long");
83 79 if (len > 255)
80 fatal("Too many bytes to read from EGD");
81
82 memset(&addr, '\0', sizeof(addr));
83 addr.sun_family = AF_UNIX;
84 strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path)); 84 strlcpy(addr.sun_path, EGD_SOCKET, sizeof(addr.sun_path));
85
86 addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET); 85 addr_len = offsetof(struct sockaddr_un, sun_path) + sizeof(EGD_SOCKET);
87 86
88 if (egd_socket == -1) { 87 fd = socket(AF_UNIX, SOCK_STREAM, 0);
89 egd_socket = socket(AF_UNIX, SOCK_STREAM, 0); 88 if (fd == -1) {
90 if (egd_socket == -1) 89 error("Couldn't create AF_UNIX socket: %s", strerror(errno));
91 fatal("Couldn't create AF_UNIX socket: %s", strerror(errno)); 90 return(0);
92 if (connect(egd_socket, (struct sockaddr*)&addr, addr_len) == -1) 91 }
93 fatal("Couldn't connect to EGD socket \"%s\": %s", addr.sun_path, strerror(errno)); 92
94 } 93 if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
94 error("Couldn't connect to EGD socket \"%s\": %s",
95 addr.sun_path, strerror(errno));
96 close(fd);
97 return(0);
98 }
95 99
96 if (len > 255)
97 fatal("Too many bytes to read from EGD");
98
99 /* Send blocking read request to EGD */ 100 /* Send blocking read request to EGD */
100 egd_message[1] = len; 101 msg[0] = 0x02;
102 msg[1] = len;
101 103
102 c = atomicio(write, egd_socket, egd_message, sizeof(egd_message)); 104 if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) {
103 if (c == -1) 105 error("Couldn't write to EGD socket \"%s\": %s",
104 fatal("Couldn't write to EGD socket \"%s\": %s", EGD_SOCKET, strerror(errno)); 106 EGD_SOCKET, strerror(errno));
107 close(fd);
108 return(0);
109 }
105 110
106 c = atomicio(read, egd_socket, buf, len); 111 if (atomicio(read, fd, buf, len) != len) {
107 if (c <= 0) 112 error("Couldn't read from EGD socket \"%s\": %s",
108 fatal("Couldn't read from EGD socket \"%s\": %s", EGD_SOCKET, strerror(errno)); 113 EGD_SOCKET, strerror(errno));
114 close(fd);
115 return(0);
116 }
117
118 close(fd);
119
120 return(1);
109} 121}
110#else /* !EGD_SOCKET */ 122#else /* !EGD_SOCKET */
111#ifdef RANDOM_POOL 123#ifdef RANDOM_POOL
112/* Collect entropy from /dev/urandom or pipe */ 124/* Collect entropy from /dev/urandom or pipe */
113void get_random_bytes(unsigned char *buf, int len) 125int get_random_bytes(unsigned char *buf, int len)
114{ 126{
115 static int random_pool = -1; 127 int random_pool;
116 int c;
117 128
129 random_pool = open(RANDOM_POOL, O_RDONLY);
118 if (random_pool == -1) { 130 if (random_pool == -1) {
119 random_pool = open(RANDOM_POOL, O_RDONLY); 131 error("Couldn't open random pool \"%s\": %s",
120 if (random_pool == -1) 132 RANDOM_POOL, strerror(errno));
121 fatal("Couldn't open random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); 133 return(0);
122 } 134 }
123 135
124 c = atomicio(read, random_pool, buf, len); 136 if (atomicio(read, random_pool, buf, len) != len) {
125 if (c <= 0) 137 error("Couldn't read from random pool \"%s\": %s",
126 fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno)); 138 RANDOM_POOL, strerror(errno));
139 close(random_pool);
140 return(0);
141 }
142
143 close(random_pool);
144
145 return(1);
127} 146}
128#endif /* RANDOM_POOL */ 147#endif /* RANDOM_POOL */
129#endif /* EGD_SOCKET */ 148#endif /* EGD_SOCKET */
@@ -138,8 +157,12 @@ seed_rng(void)
138 char buf[32]; 157 char buf[32];
139 158
140 debug("Seeding random number generator"); 159 debug("Seeding random number generator");
141 get_random_bytes(buf, sizeof(buf)); 160
161 if (!get_random_bytes(buf, sizeof(buf)) && !RAND_status())
162 fatal("Entropy collection failed and entropy exhausted");
163
142 RAND_add(buf, sizeof(buf), sizeof(buf)); 164 RAND_add(buf, sizeof(buf), sizeof(buf));
165
143 memset(buf, '\0', sizeof(buf)); 166 memset(buf, '\0', sizeof(buf));
144} 167}
145 168