source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_unix.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 9.4 KB
RevLine 
[331]1/*
2 * Copyright 1995-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 <stdio.h>
11
12#define USE_SOCKETS
13#include "e_os.h"
14#include "internal/cryptlib.h"
15#include <openssl/rand.h>
16#include "rand_lcl.h"
17
18#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI))
19
20# include <sys/types.h>
21# include <sys/time.h>
22# include <sys/times.h>
23# include <sys/stat.h>
24# include <fcntl.h>
25# include <unistd.h>
26# include <time.h>
27# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
28 * everywhere */
29# include <poll.h>
30# endif
31# include <limits.h>
32# ifndef FD_SETSIZE
33# define FD_SETSIZE (8*sizeof(fd_set))
34# endif
35
36# if defined(OPENSSL_SYS_VOS)
37
38/*
39 * The following algorithm repeatedly samples the real-time clock (RTC) to
40 * generate a sequence of unpredictable data. The algorithm relies upon the
41 * uneven execution speed of the code (due to factors such as cache misses,
42 * interrupts, bus activity, and scheduling) and upon the rather large
43 * relative difference between the speed of the clock and the rate at which
44 * it can be read.
45 *
46 * If this code is ported to an environment where execution speed is more
47 * constant or where the RTC ticks at a much slower rate, or the clock can be
48 * read with fewer instructions, it is likely that the results would be far
49 * more predictable.
50 *
51 * As a precaution, we generate 4 times the minimum required amount of seed
52 * data.
53 */
54
55int RAND_poll(void)
56{
57 short int code;
58 gid_t curr_gid;
59 pid_t curr_pid;
60 uid_t curr_uid;
61 int i, k;
62 struct timespec ts;
63 unsigned char v;
64
65# ifdef OPENSSL_SYS_VOS_HPPA
66 long duration;
67 extern void s$sleep(long *_duration, short int *_code);
68# else
69# ifdef OPENSSL_SYS_VOS_IA32
70 long long duration;
71 extern void s$sleep2(long long *_duration, short int *_code);
72# else
73# error "Unsupported Platform."
74# endif /* OPENSSL_SYS_VOS_IA32 */
75# endif /* OPENSSL_SYS_VOS_HPPA */
76
77 /*
78 * Seed with the gid, pid, and uid, to ensure *some* variation between
79 * different processes.
80 */
81
82 curr_gid = getgid();
83 RAND_add(&curr_gid, sizeof curr_gid, 1);
84 curr_gid = 0;
85
86 curr_pid = getpid();
87 RAND_add(&curr_pid, sizeof curr_pid, 1);
88 curr_pid = 0;
89
90 curr_uid = getuid();
91 RAND_add(&curr_uid, sizeof curr_uid, 1);
92 curr_uid = 0;
93
94 for (i = 0; i < (ENTROPY_NEEDED * 4); i++) {
95 /*
96 * burn some cpu; hope for interrupts, cache collisions, bus
97 * interference, etc.
98 */
99 for (k = 0; k < 99; k++)
100 ts.tv_nsec = random();
101
102# ifdef OPENSSL_SYS_VOS_HPPA
103 /* sleep for 1/1024 of a second (976 us). */
104 duration = 1;
105 s$sleep(&duration, &code);
106# else
107# ifdef OPENSSL_SYS_VOS_IA32
108 /* sleep for 1/65536 of a second (15 us). */
109 duration = 1;
110 s$sleep2(&duration, &code);
111# endif /* OPENSSL_SYS_VOS_IA32 */
112# endif /* OPENSSL_SYS_VOS_HPPA */
113
114 /* get wall clock time. */
115 clock_gettime(CLOCK_REALTIME, &ts);
116
117 /* take 8 bits */
118 v = (unsigned char)(ts.tv_nsec % 256);
119 RAND_add(&v, sizeof v, 1);
120 v = 0;
121 }
122 return 1;
123}
124# elif defined __OpenBSD__
125int RAND_poll(void)
126{
127 u_int32_t rnd = 0, i;
128 unsigned char buf[ENTROPY_NEEDED];
129
130 for (i = 0; i < sizeof(buf); i++) {
131 if (i % 4 == 0)
132 rnd = arc4random();
133 buf[i] = rnd;
134 rnd >>= 8;
135 }
136 RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
137 OPENSSL_cleanse(buf, sizeof(buf));
138
139 return 1;
140}
141# else /* !defined(__OpenBSD__) */
142int RAND_poll(void)
143{
144 unsigned long l;
145 pid_t curr_pid = getpid();
146# if defined(DEVRANDOM) || (!defined(OPENSS_NO_EGD) && defined(DEVRANDOM_EGD))
147 unsigned char tmpbuf[ENTROPY_NEEDED];
148 int n = 0;
149# endif
150# ifdef DEVRANDOM
151 static const char *randomfiles[] = { DEVRANDOM };
152 struct stat randomstats[OSSL_NELEM(randomfiles)];
153 int fd;
154 unsigned int i;
155# endif
156# if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
157 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
158 const char **egdsocket = NULL;
159# endif
160
161# ifdef DEVRANDOM
162 memset(randomstats, 0, sizeof(randomstats));
163 /*
164 * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have
165 * this. Use /dev/urandom if you can as /dev/random may block if it runs
166 * out of random entries.
167 */
168
169 for (i = 0; (i < OSSL_NELEM(randomfiles)) && (n < ENTROPY_NEEDED); i++) {
170 if ((fd = open(randomfiles[i], O_RDONLY
171# ifdef O_NONBLOCK
172 | O_NONBLOCK
173# endif
174# ifdef O_BINARY
175 | O_BINARY
176# endif
177# ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do
178 * not make it our controlling tty */
179 | O_NOCTTY
180# endif
181 )) >= 0) {
182 int usec = 10 * 1000; /* spend 10ms on each file */
183 int r;
184 unsigned int j;
185 struct stat *st = &randomstats[i];
186
187 /*
188 * Avoid using same input... Used to be O_NOFOLLOW above, but
189 * it's not universally appropriate...
190 */
191 if (fstat(fd, st) != 0) {
192 close(fd);
193 continue;
194 }
195 for (j = 0; j < i; j++) {
196 if (randomstats[j].st_ino == st->st_ino &&
197 randomstats[j].st_dev == st->st_dev)
198 break;
199 }
200 if (j < i) {
201 close(fd);
202 continue;
203 }
204
205 do {
206 int try_read = 0;
207
208# if defined(OPENSSL_SYS_LINUX)
209 /* use poll() */
210 struct pollfd pset;
211
212 pset.fd = fd;
213 pset.events = POLLIN;
214 pset.revents = 0;
215
216 if (poll(&pset, 1, usec / 1000) < 0)
217 usec = 0;
218 else
219 try_read = (pset.revents & POLLIN) != 0;
220
221# else
222 /* use select() */
223 fd_set fset;
224 struct timeval t;
225
226 t.tv_sec = 0;
227 t.tv_usec = usec;
228
229 if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) {
230 /*
231 * can't use select, so just try to read once anyway
232 */
233 try_read = 1;
234 } else {
235 FD_ZERO(&fset);
236 FD_SET(fd, &fset);
237
238 if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) {
239 usec = t.tv_usec;
240 if (FD_ISSET(fd, &fset))
241 try_read = 1;
242 } else
243 usec = 0;
244 }
245# endif
246
247 if (try_read) {
248 r = read(fd, (unsigned char *)tmpbuf + n,
249 ENTROPY_NEEDED - n);
250 if (r > 0)
251 n += r;
252 } else
253 r = -1;
254
255 /*
256 * Some Unixen will update t in select(), some won't. For
257 * those who won't, or if we didn't use select() in the first
258 * place, give up here, otherwise, we will do this once again
259 * for the remaining time.
260 */
261 if (usec == 10 * 1000)
262 usec = 0;
263 }
264 while ((r > 0 ||
265 (errno == EINTR || errno == EAGAIN)) && usec != 0
266 && n < ENTROPY_NEEDED);
267
268 close(fd);
269 }
270 }
271# endif /* defined(DEVRANDOM) */
272
273# if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
274 /*
275 * Use an EGD socket to read entropy from an EGD or PRNGD entropy
276 * collecting daemon.
277 */
278
279 for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED;
280 egdsocket++) {
281 int r;
282
283 r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n,
284 ENTROPY_NEEDED - n);
285 if (r > 0)
286 n += r;
287 }
288# endif /* defined(DEVRANDOM_EGD) */
289
290# if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
291 if (n > 0) {
292 RAND_add(tmpbuf, sizeof tmpbuf, (double)n);
293 OPENSSL_cleanse(tmpbuf, n);
294 }
295# endif
296
297 /* put in some default random data, we need more than just this */
298 l = curr_pid;
299 RAND_add(&l, sizeof(l), 0.0);
300 l = getuid();
301 RAND_add(&l, sizeof(l), 0.0);
302
303 l = time(NULL);
304 RAND_add(&l, sizeof(l), 0.0);
305
306# if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
307 return 1;
308# else
309 return 0;
310# endif
311}
312
313# endif /* defined(__OpenBSD__) */
314#endif /* !(defined(OPENSSL_SYS_WINDOWS) ||
315 * defined(OPENSSL_SYS_WIN32) ||
316 * defined(OPENSSL_SYS_VMS) ||
317 * defined(OPENSSL_SYS_VXWORKS) */
318
319#if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)
320int RAND_poll(void)
321{
322 return 0;
323}
324#endif
Note: See TracBrowser for help on using the repository browser.