diff options
author | beck <> | 2002-05-15 02:29:21 +0000 |
---|---|---|
committer | beck <> | 2002-05-15 02:29:21 +0000 |
commit | b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9 (patch) | |
tree | fa27cf82a1250b64ed3bf5f4a18c7354d470bbcc /src/lib/libcrypto/rand/rand_egd.c | |
parent | e471e1ea98d673597b182ea85f29e30c97cd08b5 (diff) | |
download | openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.tar.gz openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.tar.bz2 openbsd-b64270d1e45fe7f3241e4c9b6ce60d5ac89bc2e9.zip |
OpenSSL 0.9.7 stable 2002 05 08 merge
Diffstat (limited to 'src/lib/libcrypto/rand/rand_egd.c')
-rw-r--r-- | src/lib/libcrypto/rand/rand_egd.c | 240 |
1 files changed, 182 insertions, 58 deletions
diff --git a/src/lib/libcrypto/rand/rand_egd.c b/src/lib/libcrypto/rand/rand_egd.c index 79b5e6fa57..dd490c8254 100644 --- a/src/lib/libcrypto/rand/rand_egd.c +++ b/src/lib/libcrypto/rand/rand_egd.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* crypto/rand/rand_egd.c */ | 1 | /* crypto/rand/rand_egd.c */ |
2 | /* Written by Ulf Moeller for the OpenSSL project. */ | 2 | /* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */ |
3 | /* ==================================================================== | 3 | /* ==================================================================== |
4 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. | 4 | * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. |
5 | * | 5 | * |
@@ -54,12 +54,51 @@ | |||
54 | * | 54 | * |
55 | */ | 55 | */ |
56 | 56 | ||
57 | #include <openssl/e_os2.h> | ||
57 | #include <openssl/rand.h> | 58 | #include <openssl/rand.h> |
58 | 59 | ||
59 | /* Query the EGD <URL: http://www.lothar.com/tech/crypto/>. | 60 | /* |
61 | * Query the EGD <URL: http://www.lothar.com/tech/crypto/>. | ||
62 | * | ||
63 | * This module supplies three routines: | ||
64 | * | ||
65 | * RAND_query_egd_bytes(path, buf, bytes) | ||
66 | * will actually query "bytes" bytes of entropy form the egd-socket located | ||
67 | * at path and will write them to buf (if supplied) or will directly feed | ||
68 | * it to RAND_seed() if buf==NULL. | ||
69 | * The number of bytes is not limited by the maximum chunk size of EGD, | ||
70 | * which is 255 bytes. If more than 255 bytes are wanted, several chunks | ||
71 | * of entropy bytes are requested. The connection is left open until the | ||
72 | * query is competed. | ||
73 | * RAND_query_egd_bytes() returns with | ||
74 | * -1 if an error occured during connection or communication. | ||
75 | * num the number of bytes read from the EGD socket. This number is either | ||
76 | * the number of bytes requested or smaller, if the EGD pool is | ||
77 | * drained and the daemon signals that the pool is empty. | ||
78 | * This routine does not touch any RAND_status(). This is necessary, since | ||
79 | * PRNG functions may call it during initialization. | ||
80 | * | ||
81 | * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them | ||
82 | * used to seed the PRNG. | ||
83 | * RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL. | ||
84 | * Unlike RAND_query_egd_bytes(), RAND_status() is used to test the | ||
85 | * seed status so that the return value can reflect the seed state: | ||
86 | * -1 if an error occured during connection or communication _or_ | ||
87 | * if the PRNG has still not received the required seeding. | ||
88 | * num the number of bytes read from the EGD socket. This number is either | ||
89 | * the number of bytes requested or smaller, if the EGD pool is | ||
90 | * drained and the daemon signals that the pool is empty. | ||
91 | * | ||
92 | * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed | ||
93 | * the PRNG. | ||
94 | * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. | ||
60 | */ | 95 | */ |
61 | 96 | ||
62 | #if defined(WIN32) || defined(VMS) || defined(__VMS) | 97 | #if defined(OPENSSL_SYS_WIN32) || defined(VMS) || defined(__VMS) |
98 | int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) | ||
99 | { | ||
100 | return(-1); | ||
101 | } | ||
63 | int RAND_egd(const char *path) | 102 | int RAND_egd(const char *path) |
64 | { | 103 | { |
65 | return(-1); | 104 | return(-1); |
@@ -75,7 +114,11 @@ int RAND_egd_bytes(const char *path,int bytes) | |||
75 | #include <sys/types.h> | 114 | #include <sys/types.h> |
76 | #include <sys/socket.h> | 115 | #include <sys/socket.h> |
77 | #ifndef NO_SYS_UN_H | 116 | #ifndef NO_SYS_UN_H |
78 | #include <sys/un.h> | 117 | # ifdef OPENSSL_SYS_VSWORKS |
118 | # include <streams/un.h> | ||
119 | # else | ||
120 | # include <sys/un.h> | ||
121 | # endif | ||
79 | #else | 122 | #else |
80 | struct sockaddr_un { | 123 | struct sockaddr_un { |
81 | short sun_family; /* AF_UNIX */ | 124 | short sun_family; /* AF_UNIX */ |
@@ -83,50 +126,20 @@ struct sockaddr_un { | |||
83 | }; | 126 | }; |
84 | #endif /* NO_SYS_UN_H */ | 127 | #endif /* NO_SYS_UN_H */ |
85 | #include <string.h> | 128 | #include <string.h> |
129 | #include <errno.h> | ||
86 | 130 | ||
87 | #ifndef offsetof | 131 | #ifndef offsetof |
88 | # define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) | 132 | # define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) |
89 | #endif | 133 | #endif |
90 | 134 | ||
91 | int RAND_egd(const char *path) | 135 | int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) |
92 | { | ||
93 | int ret = -1; | ||
94 | struct sockaddr_un addr; | ||
95 | int len, num; | ||
96 | int fd = -1; | ||
97 | unsigned char buf[256]; | ||
98 | |||
99 | memset(&addr, 0, sizeof(addr)); | ||
100 | addr.sun_family = AF_UNIX; | ||
101 | if (strlen(path) > sizeof(addr.sun_path)) | ||
102 | return (-1); | ||
103 | strcpy(addr.sun_path,path); | ||
104 | len = offsetof(struct sockaddr_un, sun_path) + strlen(path); | ||
105 | fd = socket(AF_UNIX, SOCK_STREAM, 0); | ||
106 | if (fd == -1) return (-1); | ||
107 | if (connect(fd, (struct sockaddr *)&addr, len) == -1) goto err; | ||
108 | buf[0] = 1; | ||
109 | buf[1] = 255; | ||
110 | write(fd, buf, 2); | ||
111 | if (read(fd, buf, 1) != 1) goto err; | ||
112 | if (buf[0] == 0) goto err; | ||
113 | num = read(fd, buf, 255); | ||
114 | if (num < 1) goto err; | ||
115 | RAND_seed(buf, num); | ||
116 | if (RAND_status() == 1) | ||
117 | ret = num; | ||
118 | err: | ||
119 | if (fd != -1) close(fd); | ||
120 | return(ret); | ||
121 | } | ||
122 | |||
123 | int RAND_egd_bytes(const char *path,int bytes) | ||
124 | { | 136 | { |
125 | int ret = 0; | 137 | int ret = 0; |
126 | struct sockaddr_un addr; | 138 | struct sockaddr_un addr; |
127 | int len, num; | 139 | int len, num, numbytes; |
128 | int fd = -1; | 140 | int fd = -1; |
129 | unsigned char buf[255]; | 141 | int success; |
142 | unsigned char egdbuf[2], tempbuf[255], *retrievebuf; | ||
130 | 143 | ||
131 | memset(&addr, 0, sizeof(addr)); | 144 | memset(&addr, 0, sizeof(addr)); |
132 | addr.sun_family = AF_UNIX; | 145 | addr.sun_family = AF_UNIX; |
@@ -136,34 +149,126 @@ int RAND_egd_bytes(const char *path,int bytes) | |||
136 | len = offsetof(struct sockaddr_un, sun_path) + strlen(path); | 149 | len = offsetof(struct sockaddr_un, sun_path) + strlen(path); |
137 | fd = socket(AF_UNIX, SOCK_STREAM, 0); | 150 | fd = socket(AF_UNIX, SOCK_STREAM, 0); |
138 | if (fd == -1) return (-1); | 151 | if (fd == -1) return (-1); |
139 | if (connect(fd, (struct sockaddr *)&addr, len) == -1) goto err; | 152 | success = 0; |
153 | while (!success) | ||
154 | { | ||
155 | if (connect(fd, (struct sockaddr *)&addr, len) == 0) | ||
156 | success = 1; | ||
157 | else | ||
158 | { | ||
159 | switch (errno) | ||
160 | { | ||
161 | #ifdef EINTR | ||
162 | case EINTR: | ||
163 | #endif | ||
164 | #ifdef EAGAIN | ||
165 | case EAGAIN: | ||
166 | #endif | ||
167 | #ifdef EINPROGRESS | ||
168 | case EINPROGRESS: | ||
169 | #endif | ||
170 | #ifdef EALREADY | ||
171 | case EALREADY: | ||
172 | #endif | ||
173 | /* No error, try again */ | ||
174 | break; | ||
175 | #ifdef EISCONN | ||
176 | case EISCONN: | ||
177 | success = 1; | ||
178 | break; | ||
179 | #endif | ||
180 | default: | ||
181 | goto err; /* failure */ | ||
182 | } | ||
183 | } | ||
184 | } | ||
140 | 185 | ||
141 | while(bytes > 0) | 186 | while(bytes > 0) |
142 | { | 187 | { |
143 | buf[0] = 1; | 188 | egdbuf[0] = 1; |
144 | buf[1] = bytes < 255 ? bytes : 255; | 189 | egdbuf[1] = bytes < 255 ? bytes : 255; |
145 | write(fd, buf, 2); | 190 | numbytes = 0; |
146 | if (read(fd, buf, 1) != 1) | 191 | while (numbytes != 2) |
147 | { | 192 | { |
148 | ret=-1; | 193 | num = write(fd, egdbuf + numbytes, 2 - numbytes); |
149 | goto err; | 194 | if (num >= 0) |
195 | numbytes += num; | ||
196 | else | ||
197 | { | ||
198 | switch (errno) | ||
199 | { | ||
200 | #ifdef EINTR | ||
201 | case EINTR: | ||
202 | #endif | ||
203 | #ifdef EAGAIN | ||
204 | case EAGAIN: | ||
205 | #endif | ||
206 | /* No error, try again */ | ||
207 | break; | ||
208 | default: | ||
209 | ret = -1; | ||
210 | goto err; /* failure */ | ||
211 | } | ||
212 | } | ||
150 | } | 213 | } |
151 | if(buf[0] == 0) | 214 | numbytes = 0; |
152 | goto err; | 215 | while (numbytes != 1) |
153 | num = read(fd, buf, buf[0]); | ||
154 | if (num < 1) | ||
155 | { | 216 | { |
156 | ret=-1; | 217 | num = read(fd, egdbuf, 1); |
157 | goto err; | 218 | if (num >= 0) |
219 | numbytes += num; | ||
220 | else | ||
221 | { | ||
222 | switch (errno) | ||
223 | { | ||
224 | #ifdef EINTR | ||
225 | case EINTR: | ||
226 | #endif | ||
227 | #ifdef EAGAIN | ||
228 | case EAGAIN: | ||
229 | #endif | ||
230 | /* No error, try again */ | ||
231 | break; | ||
232 | default: | ||
233 | ret = -1; | ||
234 | goto err; /* failure */ | ||
235 | } | ||
236 | } | ||
158 | } | 237 | } |
159 | RAND_seed(buf, num); | 238 | if(egdbuf[0] == 0) |
160 | if (RAND_status() != 1) | ||
161 | { | ||
162 | ret=-1; | ||
163 | goto err; | 239 | goto err; |
240 | if (buf) | ||
241 | retrievebuf = buf + ret; | ||
242 | else | ||
243 | retrievebuf = tempbuf; | ||
244 | numbytes = 0; | ||
245 | while (numbytes != egdbuf[0]) | ||
246 | { | ||
247 | num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes); | ||
248 | if (num >= 0) | ||
249 | numbytes += num; | ||
250 | else | ||
251 | { | ||
252 | switch (errno) | ||
253 | { | ||
254 | #ifdef EINTR | ||
255 | case EINTR: | ||
256 | #endif | ||
257 | #ifdef EAGAIN | ||
258 | case EAGAIN: | ||
259 | #endif | ||
260 | /* No error, try again */ | ||
261 | break; | ||
262 | default: | ||
263 | ret = -1; | ||
264 | goto err; /* failure */ | ||
265 | } | ||
266 | } | ||
164 | } | 267 | } |
165 | ret += num; | 268 | ret += egdbuf[0]; |
166 | bytes-=num; | 269 | bytes -= egdbuf[0]; |
270 | if (!buf) | ||
271 | RAND_seed(tempbuf, egdbuf[0]); | ||
167 | } | 272 | } |
168 | err: | 273 | err: |
169 | if (fd != -1) close(fd); | 274 | if (fd != -1) close(fd); |
@@ -171,4 +276,23 @@ int RAND_egd_bytes(const char *path,int bytes) | |||
171 | } | 276 | } |
172 | 277 | ||
173 | 278 | ||
279 | int RAND_egd_bytes(const char *path, int bytes) | ||
280 | { | ||
281 | int num, ret = 0; | ||
282 | |||
283 | num = RAND_query_egd_bytes(path, NULL, bytes); | ||
284 | if (num < 1) goto err; | ||
285 | if (RAND_status() == 1) | ||
286 | ret = num; | ||
287 | err: | ||
288 | return(ret); | ||
289 | } | ||
290 | |||
291 | |||
292 | int RAND_egd(const char *path) | ||
293 | { | ||
294 | return (RAND_egd_bytes(path, 255)); | ||
295 | } | ||
296 | |||
297 | |||
174 | #endif | 298 | #endif |