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} |