VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.0g/crypto/rand/rand_egd.c@ 69890

Last change on this file since 69890 was 69890, checked in by vboxsync, 7 years ago

Added OpenSSL 1.1.0g with unneeded files removed, otherwise unmodified.
bugref:8070: src/libs maintenance

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1/*
2 * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <openssl/opensslconf.h>
11#ifdef OPENSSL_NO_EGD
12NON_EMPTY_TRANSLATION_UNIT
13#else
14
15# include <openssl/crypto.h>
16# include <openssl/e_os2.h>
17# include <openssl/rand.h>
18
19/*-
20 * Query the EGD <URL: http://www.lothar.com/tech/crypto/>.
21 *
22 * This module supplies three routines:
23 *
24 * RAND_query_egd_bytes(path, buf, bytes)
25 * will actually query "bytes" bytes of entropy form the egd-socket located
26 * at path and will write them to buf (if supplied) or will directly feed
27 * it to RAND_seed() if buf==NULL.
28 * The number of bytes is not limited by the maximum chunk size of EGD,
29 * which is 255 bytes. If more than 255 bytes are wanted, several chunks
30 * of entropy bytes are requested. The connection is left open until the
31 * query is competed.
32 * RAND_query_egd_bytes() returns with
33 * -1 if an error occurred during connection or communication.
34 * num the number of bytes read from the EGD socket. This number is either
35 * the number of bytes requested or smaller, if the EGD pool is
36 * drained and the daemon signals that the pool is empty.
37 * This routine does not touch any RAND_status(). This is necessary, since
38 * PRNG functions may call it during initialization.
39 *
40 * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them
41 * used to seed the PRNG.
42 * RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL.
43 * Unlike RAND_query_egd_bytes(), RAND_status() is used to test the
44 * seed status so that the return value can reflect the seed state:
45 * -1 if an error occurred during connection or communication _or_
46 * if the PRNG has still not received the required seeding.
47 * num the number of bytes read from the EGD socket. This number is either
48 * the number of bytes requested or smaller, if the EGD pool is
49 * drained and the daemon signals that the pool is empty.
50 *
51 * RAND_egd(path) will query 255 bytes and use the bytes retrieved to seed
52 * the PRNG.
53 * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
54 */
55
56# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_UEFI)
57int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
58{
59 return (-1);
60}
61
62int RAND_egd(const char *path)
63{
64 return (-1);
65}
66
67int RAND_egd_bytes(const char *path, int bytes)
68{
69 return (-1);
70}
71# else
72# include <openssl/opensslconf.h>
73# include OPENSSL_UNISTD
74# include <stddef.h>
75# include <sys/types.h>
76# include <sys/socket.h>
77# ifndef NO_SYS_UN_H
78# ifdef OPENSSL_SYS_VXWORKS
79# include <streams/un.h>
80# else
81# include <sys/un.h>
82# endif
83# else
84struct sockaddr_un {
85 short sun_family; /* AF_UNIX */
86 char sun_path[108]; /* path name (gag) */
87};
88# endif /* NO_SYS_UN_H */
89# include <string.h>
90# include <errno.h>
91
92int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
93{
94 int ret = 0;
95 struct sockaddr_un addr;
96 int len, num, numbytes;
97 int fd = -1;
98 int success;
99 unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
100
101 memset(&addr, 0, sizeof(addr));
102 addr.sun_family = AF_UNIX;
103 if (strlen(path) >= sizeof(addr.sun_path))
104 return (-1);
105 OPENSSL_strlcpy(addr.sun_path, path, sizeof addr.sun_path);
106 len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
107 fd = socket(AF_UNIX, SOCK_STREAM, 0);
108 if (fd == -1)
109 return (-1);
110 success = 0;
111 while (!success) {
112 if (connect(fd, (struct sockaddr *)&addr, len) == 0)
113 success = 1;
114 else {
115 switch (errno) {
116# ifdef EINTR
117 case EINTR:
118# endif
119# ifdef EAGAIN
120 case EAGAIN:
121# endif
122# ifdef EINPROGRESS
123 case EINPROGRESS:
124# endif
125# ifdef EALREADY
126 case EALREADY:
127# endif
128 /* No error, try again */
129 break;
130# ifdef EISCONN
131 case EISCONN:
132 success = 1;
133 break;
134# endif
135 default:
136 ret = -1;
137 goto err; /* failure */
138 }
139 }
140 }
141
142 while (bytes > 0) {
143 egdbuf[0] = 1;
144 egdbuf[1] = bytes < 255 ? bytes : 255;
145 numbytes = 0;
146 while (numbytes != 2) {
147 num = write(fd, egdbuf + numbytes, 2 - numbytes);
148 if (num >= 0)
149 numbytes += num;
150 else {
151 switch (errno) {
152# ifdef EINTR
153 case EINTR:
154# endif
155# ifdef EAGAIN
156 case EAGAIN:
157# endif
158 /* No error, try again */
159 break;
160 default:
161 ret = -1;
162 goto err; /* failure */
163 }
164 }
165 }
166 numbytes = 0;
167 while (numbytes != 1) {
168 num = read(fd, egdbuf, 1);
169 if (num == 0)
170 goto err; /* descriptor closed */
171 else if (num > 0)
172 numbytes += num;
173 else {
174 switch (errno) {
175# ifdef EINTR
176 case EINTR:
177# endif
178# ifdef EAGAIN
179 case EAGAIN:
180# endif
181 /* No error, try again */
182 break;
183 default:
184 ret = -1;
185 goto err; /* failure */
186 }
187 }
188 }
189 if (egdbuf[0] == 0)
190 goto err;
191 if (buf)
192 retrievebuf = buf + ret;
193 else
194 retrievebuf = tempbuf;
195 numbytes = 0;
196 while (numbytes != egdbuf[0]) {
197 num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
198 if (num == 0)
199 goto err; /* descriptor closed */
200 else if (num > 0)
201 numbytes += num;
202 else {
203 switch (errno) {
204# ifdef EINTR
205 case EINTR:
206# endif
207# ifdef EAGAIN
208 case EAGAIN:
209# endif
210 /* No error, try again */
211 break;
212 default:
213 ret = -1;
214 goto err; /* failure */
215 }
216 }
217 }
218 ret += egdbuf[0];
219 bytes -= egdbuf[0];
220 if (!buf)
221 RAND_seed(tempbuf, egdbuf[0]);
222 }
223 err:
224 if (fd != -1)
225 close(fd);
226 return (ret);
227}
228
229int RAND_egd_bytes(const char *path, int bytes)
230{
231 int num, ret = -1;
232
233 num = RAND_query_egd_bytes(path, NULL, bytes);
234 if (num < 0)
235 goto err;
236 if (RAND_status() == 1)
237 ret = num;
238 err:
239 return (ret);
240}
241
242int RAND_egd(const char *path)
243{
244 return (RAND_egd_bytes(path, 255));
245}
246
247# endif
248
249#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette