Deleted Added
full compact
getentropy_solaris.c (356345) getentropy_solaris.c (361435)
1/* $OpenBSD: getentropy_solaris.c,v 1.13 2018/11/20 08:04:28 deraadt Exp $ */
1/* $OpenBSD: getentropy_solaris.c,v 1.4 2014/07/12 20:41:47 wouter Exp $ */
2
3/*
4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
5 * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2
3/*
4 * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
5 * Copyright (c) 2014 Bob Beck <beck@obtuse.com>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * Emulation of getentropy(2) as documented at:
20 * http://man.openbsd.org/getentropy.2
21 */
18 */
22
23#include "config.h"
19#include "config.h"
20
24#include <sys/types.h>
25#include <sys/param.h>
26#include <sys/ioctl.h>
27#include <sys/resource.h>
28#include <sys/syscall.h>
29#include <sys/statvfs.h>
30#include <sys/socket.h>
31#include <sys/mount.h>
32#include <sys/mman.h>
33#include <sys/stat.h>
34#include <sys/time.h>
35#include <stdlib.h>
36#ifdef HAVE_STDINT_H
37#include <stdint.h>
38#endif
39#include <stdio.h>
21#include <sys/types.h>
22#include <sys/param.h>
23#include <sys/ioctl.h>
24#include <sys/resource.h>
25#include <sys/syscall.h>
26#include <sys/statvfs.h>
27#include <sys/socket.h>
28#include <sys/mount.h>
29#include <sys/mman.h>
30#include <sys/stat.h>
31#include <sys/time.h>
32#include <stdlib.h>
33#ifdef HAVE_STDINT_H
34#include <stdint.h>
35#endif
36#include <stdio.h>
40#include <link.h>
41#include <termios.h>
42#include <fcntl.h>
43#include <signal.h>
44#include <string.h>
45#include <errno.h>
46#include <unistd.h>
47#include <time.h>
48#ifdef HAVE_SYS_SHA2_H

--- 17 unchanged lines hidden (view full) ---

66 if ((a)) \
67 HD(errno); \
68 else \
69 HD(b); \
70 } while (0)
71
72#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
73#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
37#include <termios.h>
38#include <fcntl.h>
39#include <signal.h>
40#include <string.h>
41#include <errno.h>
42#include <unistd.h>
43#include <time.h>
44#ifdef HAVE_SYS_SHA2_H

--- 17 unchanged lines hidden (view full) ---

62 if ((a)) \
63 HD(errno); \
64 else \
65 HD(b); \
66 } while (0)
67
68#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
69#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
74#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
70#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
75
76int getentropy(void *buf, size_t len);
77
71
72int getentropy(void *buf, size_t len);
73
74#ifdef CAN_REFERENCE_MAIN
75extern int main(int, char *argv[]);
76#endif
77static int gotdata(char *buf, size_t len);
78static int getentropy_urandom(void *buf, size_t len, const char *path,
79 int devfscheck);
80static int getentropy_fallback(void *buf, size_t len);
78static int getentropy_urandom(void *buf, size_t len, const char *path,
79 int devfscheck);
80static int getentropy_fallback(void *buf, size_t len);
81static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
82
83int
84getentropy(void *buf, size_t len)
85{
86 int ret = -1;
87
88 if (len > 256) {
89 errno = EIO;
81
82int
83getentropy(void *buf, size_t len)
84{
85 int ret = -1;
86
87 if (len > 256) {
88 errno = EIO;
90 return (-1);
89 return -1;
91 }
92
93 /*
94 * Try to get entropy with /dev/urandom
95 *
96 * Solaris provides /dev/urandom as a symbolic link to
97 * /devices/pseudo/random@0:urandom which is provided by
98 * a devfs filesystem. Best practice is to use O_NOFOLLOW,

--- 50 unchanged lines hidden (view full) ---

149 ret = getentropy_fallback(buf, len);
150 if (ret != -1)
151 return (ret);
152
153 errno = EIO;
154 return (ret);
155}
156
90 }
91
92 /*
93 * Try to get entropy with /dev/urandom
94 *
95 * Solaris provides /dev/urandom as a symbolic link to
96 * /devices/pseudo/random@0:urandom which is provided by
97 * a devfs filesystem. Best practice is to use O_NOFOLLOW,

--- 50 unchanged lines hidden (view full) ---

148 ret = getentropy_fallback(buf, len);
149 if (ret != -1)
150 return (ret);
151
152 errno = EIO;
153 return (ret);
154}
155
156/*
157 * Basic sanity checking; wish we could do better.
158 */
157static int
159static int
160gotdata(char *buf, size_t len)
161{
162 char any_set = 0;
163 size_t i;
164
165 for (i = 0; i < len; ++i)
166 any_set |= buf[i];
167 if (any_set == 0)
168 return -1;
169 return 0;
170}
171
172static int
158getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
159{
160 struct stat st;
161 size_t i;
162 int fd, flags;
163 int save_errno = errno;
164
165start:

--- 29 unchanged lines hidden (view full) ---

195 if (errno == EAGAIN || errno == EINTR)
196 continue;
197 close(fd);
198 goto nodevrandom;
199 }
200 i += ret;
201 }
202 close(fd);
173getentropy_urandom(void *buf, size_t len, const char *path, int devfscheck)
174{
175 struct stat st;
176 size_t i;
177 int fd, flags;
178 int save_errno = errno;
179
180start:

--- 29 unchanged lines hidden (view full) ---

210 if (errno == EAGAIN || errno == EINTR)
211 continue;
212 close(fd);
213 goto nodevrandom;
214 }
215 i += ret;
216 }
217 close(fd);
203 errno = save_errno;
204 return (0); /* satisfied */
218 if (gotdata(buf, len) == 0) {
219 errno = save_errno;
220 return 0; /* satisfied */
221 }
205nodevrandom:
206 errno = EIO;
222nodevrandom:
223 errno = EIO;
207 return (-1);
224 return -1;
208}
209
210static const int cl[] = {
211 CLOCK_REALTIME,
212#ifdef CLOCK_MONOTONIC
213 CLOCK_MONOTONIC,
214#endif
215#ifdef CLOCK_MONOTONIC_RAW

--- 12 unchanged lines hidden (view full) ---

228 CLOCK_PROCESS_CPUTIME_ID,
229#endif
230#ifdef CLOCK_THREAD_CPUTIME_ID
231 CLOCK_THREAD_CPUTIME_ID,
232#endif
233};
234
235static int
225}
226
227static const int cl[] = {
228 CLOCK_REALTIME,
229#ifdef CLOCK_MONOTONIC
230 CLOCK_MONOTONIC,
231#endif
232#ifdef CLOCK_MONOTONIC_RAW

--- 12 unchanged lines hidden (view full) ---

245 CLOCK_PROCESS_CPUTIME_ID,
246#endif
247#ifdef CLOCK_THREAD_CPUTIME_ID
248 CLOCK_THREAD_CPUTIME_ID,
249#endif
250};
251
252static int
236getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
237{
238 SHA512_CTX *ctx = data;
239
240 SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
241 return (0);
242}
243
244static int
245getentropy_fallback(void *buf, size_t len)
246{
247 uint8_t results[SHA512_DIGEST_LENGTH];
248 int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
249 static int cnt;
250 struct timespec ts;
251 struct timeval tv;
252 double loadavg[3];

--- 20 unchanged lines hidden (view full) ---

273 SHA512_Init(&ctx);
274 for (j = 0; j < repeat; j++) {
275 HX((e = gettimeofday(&tv, NULL)) == -1, tv);
276 if (e != -1) {
277 cnt += (int)tv.tv_sec;
278 cnt += (int)tv.tv_usec;
279 }
280
253getentropy_fallback(void *buf, size_t len)
254{
255 uint8_t results[SHA512_DIGEST_LENGTH];
256 int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
257 static int cnt;
258 struct timespec ts;
259 struct timeval tv;
260 double loadavg[3];

--- 20 unchanged lines hidden (view full) ---

281 SHA512_Init(&ctx);
282 for (j = 0; j < repeat; j++) {
283 HX((e = gettimeofday(&tv, NULL)) == -1, tv);
284 if (e != -1) {
285 cnt += (int)tv.tv_sec;
286 cnt += (int)tv.tv_usec;
287 }
288
281 dl_iterate_phdr(getentropy_phdr, &ctx);
282
283 for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
284 HX(clock_gettime(cl[ii], &ts) == -1, ts);
285
286 HX((pid = getpid()) == -1, pid);
287 HX((pid = getsid(pid)) == -1, pid);
288 HX((pid = getppid()) == -1, pid);
289 HX((pid = getpgid(0)) == -1, pid);
290 HX((e = getpriority(0, 0)) == -1, e);

--- 4 unchanged lines hidden (view full) ---

295 ts.tv_nsec = 1;
296 (void) nanosleep(&ts, NULL);
297 }
298
299 HX(sigpending(&sigset) == -1, sigset);
300 HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
301 sigset);
302
289 for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
290 HX(clock_gettime(cl[ii], &ts) == -1, ts);
291
292 HX((pid = getpid()) == -1, pid);
293 HX((pid = getsid(pid)) == -1, pid);
294 HX((pid = getppid()) == -1, pid);
295 HX((pid = getpgid(0)) == -1, pid);
296 HX((e = getpriority(0, 0)) == -1, e);

--- 4 unchanged lines hidden (view full) ---

301 ts.tv_nsec = 1;
302 (void) nanosleep(&ts, NULL);
303 }
304
305 HX(sigpending(&sigset) == -1, sigset);
306 HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
307 sigset);
308
309#ifdef CAN_REFERENCE_MAIN
310 HF(main); /* an addr in program */
311#endif
303 HF(getentropy); /* an addr in this library */
304 HF(printf); /* an addr in libc */
305 p = (char *)&p;
306 HD(p); /* an addr on stack */
307 p = (char *)&errno;
308 HD(p); /* the addr of errno */
309
310 if (i == 0) {

--- 106 unchanged lines hidden (view full) ---

417 }
418
419 HD(cnt);
420 }
421 SHA512_Final(results, &ctx);
422 memcpy((char *)buf + i, results, min(sizeof(results), len - i));
423 i += min(sizeof(results), len - i);
424 }
312 HF(getentropy); /* an addr in this library */
313 HF(printf); /* an addr in libc */
314 p = (char *)&p;
315 HD(p); /* an addr on stack */
316 p = (char *)&errno;
317 HD(p); /* the addr of errno */
318
319 if (i == 0) {

--- 106 unchanged lines hidden (view full) ---

426 }
427
428 HD(cnt);
429 }
430 SHA512_Final(results, &ctx);
431 memcpy((char *)buf + i, results, min(sizeof(results), len - i));
432 i += min(sizeof(results), len - i);
433 }
425 explicit_bzero(&ctx, sizeof ctx);
426 explicit_bzero(results, sizeof results);
427 errno = save_errno;
428 return (0); /* satisfied */
434 memset(results, 0, sizeof results);
435 if (gotdata(buf, len) == 0) {
436 errno = save_errno;
437 return 0; /* satisfied */
438 }
439 errno = EIO;
440 return -1;
429}
441}