Fix a strict warnings error in rand_pool_acquire_entropy
[openssl.git] / crypto / rand / rand_unix.c
1 /*
2  * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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 #ifndef _GNU_SOURCE
11 # define _GNU_SOURCE
12 #endif
13 #include "e_os.h"
14 #include <stdio.h>
15 #include "internal/cryptlib.h"
16 #include <openssl/rand.h>
17 #include <openssl/crypto.h>
18 #include "rand_lcl.h"
19 #include "internal/rand_int.h"
20 #include <stdio.h>
21 #include "internal/dso.h"
22 #ifdef __linux
23 # include <sys/syscall.h>
24 # ifdef DEVRANDOM_WAIT
25 #  include <sys/shm.h>
26 #  include <sys/utsname.h>
27 # endif
28 #endif
29 #if defined(__FreeBSD__) && !defined(OPENSSL_SYS_UEFI)
30 # include <sys/types.h>
31 # include <sys/sysctl.h>
32 # include <sys/param.h>
33 #endif
34 #if defined(__OpenBSD__) || defined(__NetBSD__)
35 # include <sys/param.h>
36 #endif
37
38 #if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \
39      || defined(__DJGPP__)
40 # include <sys/types.h>
41 # include <sys/stat.h>
42 # include <fcntl.h>
43 # include <unistd.h>
44 # include <sys/time.h>
45
46 static uint64_t get_time_stamp(void);
47 static uint64_t get_timer_bits(void);
48
49 /* Macro to convert two thirty two bit values into a sixty four bit one */
50 # define TWO32TO64(a, b) ((((uint64_t)(a)) << 32) + (b))
51
52 /*
53  * Check for the existence and support of POSIX timers.  The standard
54  * says that the _POSIX_TIMERS macro will have a positive value if they
55  * are available.
56  *
57  * However, we want an additional constraint: that the timer support does
58  * not require an extra library dependency.  Early versions of glibc
59  * require -lrt to be specified on the link line to access the timers,
60  * so this needs to be checked for.
61  *
62  * It is worse because some libraries define __GLIBC__ but don't
63  * support the version testing macro (e.g. uClibc).  This means
64  * an extra check is needed.
65  *
66  * The final condition is:
67  *      "have posix timers and either not glibc or glibc without -lrt"
68  *
69  * The nested #if sequences are required to avoid using a parameterised
70  * macro that might be undefined.
71  */
72 # undef OSSL_POSIX_TIMER_OKAY
73 # if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0
74 #  if defined(__GLIBC__)
75 #   if defined(__GLIBC_PREREQ)
76 #    if __GLIBC_PREREQ(2, 17)
77 #     define OSSL_POSIX_TIMER_OKAY
78 #    endif
79 #   endif
80 #  else
81 #   define OSSL_POSIX_TIMER_OKAY
82 #  endif
83 # endif
84 #endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */
85
86 #if defined(OPENSSL_RAND_SEED_NONE)
87 /* none means none. this simplifies the following logic */
88 # undef OPENSSL_RAND_SEED_OS
89 # undef OPENSSL_RAND_SEED_GETRANDOM
90 # undef OPENSSL_RAND_SEED_LIBRANDOM
91 # undef OPENSSL_RAND_SEED_DEVRANDOM
92 # undef OPENSSL_RAND_SEED_RDTSC
93 # undef OPENSSL_RAND_SEED_RDCPU
94 # undef OPENSSL_RAND_SEED_EGD
95 #endif
96
97 #if defined(OPENSSL_SYS_UEFI) && !defined(OPENSSL_RAND_SEED_NONE)
98 # error "UEFI only supports seeding NONE"
99 #endif
100
101 #if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) \
102     || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) \
103     || defined(OPENSSL_SYS_UEFI))
104
105 # if defined(OPENSSL_SYS_VOS)
106
107 #  ifndef OPENSSL_RAND_SEED_OS
108 #   error "Unsupported seeding method configured; must be os"
109 #  endif
110
111 #  if defined(OPENSSL_SYS_VOS_HPPA) && defined(OPENSSL_SYS_VOS_IA32)
112 #   error "Unsupported HP-PA and IA32 at the same time."
113 #  endif
114 #  if !defined(OPENSSL_SYS_VOS_HPPA) && !defined(OPENSSL_SYS_VOS_IA32)
115 #   error "Must have one of HP-PA or IA32"
116 #  endif
117
118 /*
119  * The following algorithm repeatedly samples the real-time clock (RTC) to
120  * generate a sequence of unpredictable data.  The algorithm relies upon the
121  * uneven execution speed of the code (due to factors such as cache misses,
122  * interrupts, bus activity, and scheduling) and upon the rather large
123  * relative difference between the speed of the clock and the rate at which
124  * it can be read.  If it is ported to an environment where execution speed
125  * is more constant or where the RTC ticks at a much slower rate, or the
126  * clock can be read with fewer instructions, it is likely that the results
127  * would be far more predictable.  This should only be used for legacy
128  * platforms.
129  *
130  * As a precaution, we assume only 2 bits of entropy per byte.
131  */
132 size_t rand_pool_acquire_entropy(RAND_POOL *pool)
133 {
134     short int code;
135     int i, k;
136     size_t bytes_needed;
137     struct timespec ts;
138     unsigned char v;
139 #  ifdef OPENSSL_SYS_VOS_HPPA
140     long duration;
141     extern void s$sleep(long *_duration, short int *_code);
142 #  else
143     long long duration;
144     extern void s$sleep2(long long *_duration, short int *_code);
145 #  endif
146
147     bytes_needed = rand_pool_bytes_needed(pool, 4 /*entropy_factor*/);
148
149     for (i = 0; i < bytes_needed; i++) {
150         /*
151          * burn some cpu; hope for interrupts, cache collisions, bus
152          * interference, etc.
153          */
154         for (k = 0; k < 99; k++)
155             ts.tv_nsec = random();
156
157 #  ifdef OPENSSL_SYS_VOS_HPPA
158         /* sleep for 1/1024 of a second (976 us).  */
159         duration = 1;
160         s$sleep(&duration, &code);
161 #  else
162         /* sleep for 1/65536 of a second (15 us).  */
163         duration = 1;
164         s$sleep2(&duration, &code);
165 #  endif
166
167         /* Get wall clock time, take 8 bits. */
168         clock_gettime(CLOCK_REALTIME, &ts);
169         v = (unsigned char)(ts.tv_nsec & 0xFF);
170         rand_pool_add(pool, arg, &v, sizeof(v) , 2);
171     }
172     return rand_pool_entropy_available(pool);
173 }
174
175 void rand_pool_cleanup(void)
176 {
177 }
178
179 void rand_pool_keep_random_devices_open(int keep)
180 {
181 }
182
183 # else
184
185 #  if defined(OPENSSL_RAND_SEED_EGD) && \
186         (defined(OPENSSL_NO_EGD) || !defined(DEVRANDOM_EGD))
187 #   error "Seeding uses EGD but EGD is turned off or no device given"
188 #  endif
189
190 #  if defined(OPENSSL_RAND_SEED_DEVRANDOM) && !defined(DEVRANDOM)
191 #   error "Seeding uses urandom but DEVRANDOM is not configured"
192 #  endif
193
194 #  if defined(OPENSSL_RAND_SEED_OS)
195 #   if !defined(DEVRANDOM)
196 #    error "OS seeding requires DEVRANDOM to be configured"
197 #   endif
198 #   define OPENSSL_RAND_SEED_GETRANDOM
199 #   define OPENSSL_RAND_SEED_DEVRANDOM
200 #  endif
201
202 #  if defined(OPENSSL_RAND_SEED_LIBRANDOM)
203 #   error "librandom not (yet) supported"
204 #  endif
205
206 #  if (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
207 /*
208  * sysctl_random(): Use sysctl() to read a random number from the kernel
209  * Returns the number of bytes returned in buf on success, -1 on failure.
210  */
211 static ssize_t sysctl_random(char *buf, size_t buflen)
212 {
213     int mib[2];
214     size_t done = 0;
215     size_t len;
216
217     /*
218      * Note: sign conversion between size_t and ssize_t is safe even
219      * without a range check, see comment in syscall_random()
220      */
221
222     /*
223      * On FreeBSD old implementations returned longs, newer versions support
224      * variable sizes up to 256 byte. The code below would not work properly
225      * when the sysctl returns long and we want to request something not a
226      * multiple of longs, which should never be the case.
227      */
228     if (!ossl_assert(buflen % sizeof(long) == 0)) {
229         errno = EINVAL;
230         return -1;
231     }
232
233     /*
234      * On NetBSD before 4.0 KERN_ARND was an alias for KERN_URND, and only
235      * filled in an int, leaving the rest uninitialized. Since NetBSD 4.0
236      * it returns a variable number of bytes with the current version supporting
237      * up to 256 bytes.
238      * Just return an error on older NetBSD versions.
239      */
240 #if   defined(__NetBSD__) && __NetBSD_Version__ < 400000000
241     errno = ENOSYS;
242     return -1;
243 #endif
244
245     mib[0] = CTL_KERN;
246     mib[1] = KERN_ARND;
247
248     do {
249         len = buflen;
250         if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
251             return done > 0 ? done : -1;
252         done += len;
253         buf += len;
254         buflen -= len;
255     } while (buflen > 0);
256
257     return done;
258 }
259 #  endif
260
261 #  if defined(OPENSSL_RAND_SEED_GETRANDOM)
262
263 #   if defined(__linux) && !defined(__NR_getrandom)
264 #    if defined(__arm__) && defined(__NR_SYSCALL_BASE)
265 #     define __NR_getrandom    (__NR_SYSCALL_BASE+384)
266 #    elif defined(__i386__)
267 #     define __NR_getrandom    355
268 #    elif defined(__x86_64__) && !defined(__ILP32__)
269 #     define __NR_getrandom    318
270 #    endif
271 #   endif
272
273 /*
274  * syscall_random(): Try to get random data using a system call
275  * returns the number of bytes returned in buf, or < 0 on error.
276  */
277 static ssize_t syscall_random(void *buf, size_t buflen)
278 {
279     /*
280      * Note: 'buflen' equals the size of the buffer which is used by the
281      * get_entropy() callback of the RAND_DRBG. It is roughly bounded by
282      *
283      *   2 * RAND_POOL_FACTOR * (RAND_DRBG_STRENGTH / 8) = 2^14
284      *
285      * which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion
286      * between size_t and ssize_t is safe even without a range check.
287      */
288
289     /*
290      * Do runtime detection to find getentropy().
291      *
292      * Known OSs that should support this:
293      * - Darwin since 16 (OSX 10.12, IOS 10.0).
294      * - Solaris since 11.3
295      * - OpenBSD since 5.6
296      * - Linux since 3.17 with glibc 2.25
297      * - FreeBSD since 12.0 (1200061)
298      */
299 #  if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux)
300     extern int getentropy(void *buffer, size_t length) __attribute__((weak));
301
302     if (getentropy != NULL)
303         return getentropy(buf, buflen) == 0 ? (ssize_t)buflen : -1;
304 #  elif !defined(FIPS_MODE)
305     union {
306         void *p;
307         int (*f)(void *buffer, size_t length);
308     } p_getentropy;
309
310     /*
311      * We could cache the result of the lookup, but we normally don't
312      * call this function often.
313      */
314     ERR_set_mark();
315     p_getentropy.p = DSO_global_lookup("getentropy");
316     ERR_pop_to_mark();
317     if (p_getentropy.p != NULL)
318         return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1;
319 #  endif
320
321     /* Linux supports this since version 3.17 */
322 #  if defined(__linux) && defined(__NR_getrandom)
323     return syscall(__NR_getrandom, buf, buflen, 0);
324 #  elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
325     return sysctl_random(buf, buflen);
326 #  else
327     errno = ENOSYS;
328     return -1;
329 #  endif
330 }
331 #  endif    /* defined(OPENSSL_RAND_SEED_GETRANDOM) */
332
333 #  if defined(OPENSSL_RAND_SEED_DEVRANDOM)
334 static const char *random_device_paths[] = { DEVRANDOM };
335 static struct random_device {
336     int fd;
337     dev_t dev;
338     ino_t ino;
339     mode_t mode;
340     dev_t rdev;
341 } random_devices[OSSL_NELEM(random_device_paths)];
342 static int keep_random_devices_open = 1;
343
344 #   if defined(__linux) && defined(DEVRANDOM_WAIT)
345 static void *shm_addr;
346
347 #    if !defined(FIPS_MODE)
348 static void cleanup_shm(void)
349 {
350     shmdt(shm_addr);
351 }
352 #    endif
353
354 /*
355  * Ensure that the system randomness source has been adequately seeded.
356  * This is done by having the first start of libcrypto, wait until the device
357  * /dev/random becomes able to supply a byte of entropy.  Subsequent starts
358  * of the library and later reseedings do not need to do this.
359  */
360 static int wait_random_seeded(void)
361 {
362     static int seeded = OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID < 0;
363     static const int kernel_version[] = { DEVRANDOM_SAFE_KERNEL };
364     int kernel[2];
365     int shm_id, fd, r;
366     char c, *p;
367     struct utsname un;
368     fd_set fds;
369
370     if (!seeded) {
371         /* See if anything has created the global seeded indication */
372         if ((shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1, 0)) == -1) {
373             /*
374              * Check the kernel's version and fail if it is too recent.
375              *
376              * Linux kernels from 4.8 onwards do not guarantee that
377              * /dev/urandom is properly seeded when /dev/random becomes
378              * readable.  However, such kernels support the getentropy(2)
379              * system call and this should always succeed which renders
380              * this alternative but essentially identical source moot.
381              */
382             if (uname(&un) == 0) {
383                 kernel[0] = atoi(un.release);
384                 p = strchr(un.release, '.');
385                 kernel[1] = p == NULL ? 0 : atoi(p + 1);
386                 if (kernel[0] > kernel_version[0]
387                     || (kernel[0] == kernel_version[0]
388                         && kernel[1] >= kernel_version[1])) {
389                     return 0;
390                 }
391             }
392             /* Open /dev/random and wait for it to be readable */
393             if ((fd = open(DEVRANDOM_WAIT, O_RDONLY)) != -1) {
394                 if (DEVRANDM_WAIT_USE_SELECT && fd < FD_SETSIZE) {
395                     FD_ZERO(&fds);
396                     FD_SET(fd, &fds);
397                     while ((r = select(fd + 1, &fds, NULL, NULL, NULL)) < 0
398                            && errno == EINTR);
399                 } else {
400                     while ((r = read(fd, &c, 1)) < 0 && errno == EINTR);
401                 }
402                 close(fd);
403                 if (r == 1) {
404                     seeded = 1;
405                     /* Create the shared memory indicator */
406                     shm_id = shmget(OPENSSL_RAND_SEED_DEVRANDOM_SHM_ID, 1,
407                                     IPC_CREAT | S_IRUSR | S_IRGRP | S_IROTH);
408                 }
409             }
410         }
411         if (shm_id != -1) {
412             seeded = 1;
413             /*
414              * Map the shared memory to prevent its premature destruction.
415              * If this call fails, it isn't a big problem.
416              */
417             shm_addr = shmat(shm_id, NULL, SHM_RDONLY);
418 #    ifndef FIPS_MODE
419             /* TODO 3.0: The FIPS provider doesn't have OPENSSL_atexit */
420             if (shm_addr != (void *)-1)
421                 OPENSSL_atexit(&cleanup_shm);
422 #    endif
423         }
424     }
425     return seeded;
426 }
427 #   else /* defined __linux */
428 static int wait_random_seeded(void)
429 {
430     return 1;
431 }
432 #   endif
433
434 /*
435  * Verify that the file descriptor associated with the random source is
436  * still valid. The rationale for doing this is the fact that it is not
437  * uncommon for daemons to close all open file handles when daemonizing.
438  * So the handle might have been closed or even reused for opening
439  * another file.
440  */
441 static int check_random_device(struct random_device * rd)
442 {
443     struct stat st;
444
445     return rd->fd != -1
446            && fstat(rd->fd, &st) != -1
447            && rd->dev == st.st_dev
448            && rd->ino == st.st_ino
449            && ((rd->mode ^ st.st_mode) & ~(S_IRWXU | S_IRWXG | S_IRWXO)) == 0
450            && rd->rdev == st.st_rdev;
451 }
452
453 /*
454  * Open a random device if required and return its file descriptor or -1 on error
455  */
456 static int get_random_device(size_t n)
457 {
458     struct stat st;
459     struct random_device * rd = &random_devices[n];
460
461     /* reuse existing file descriptor if it is (still) valid */
462     if (check_random_device(rd))
463         return rd->fd;
464
465     /* open the random device ... */
466     if ((rd->fd = open(random_device_paths[n], O_RDONLY)) == -1)
467         return rd->fd;
468
469     /* ... and cache its relevant stat(2) data */
470     if (fstat(rd->fd, &st) != -1) {
471         rd->dev = st.st_dev;
472         rd->ino = st.st_ino;
473         rd->mode = st.st_mode;
474         rd->rdev = st.st_rdev;
475     } else {
476         close(rd->fd);
477         rd->fd = -1;
478     }
479
480     return rd->fd;
481 }
482
483 /*
484  * Close a random device making sure it is a random device
485  */
486 static void close_random_device(size_t n)
487 {
488     struct random_device * rd = &random_devices[n];
489
490     if (check_random_device(rd))
491         close(rd->fd);
492     rd->fd = -1;
493 }
494
495 int rand_pool_init(void)
496 {
497     size_t i;
498
499     for (i = 0; i < OSSL_NELEM(random_devices); i++)
500         random_devices[i].fd = -1;
501
502     return 1;
503 }
504
505 void rand_pool_cleanup(void)
506 {
507     size_t i;
508
509     for (i = 0; i < OSSL_NELEM(random_devices); i++)
510         close_random_device(i);
511 }
512
513 void rand_pool_keep_random_devices_open(int keep)
514 {
515     if (!keep)
516         rand_pool_cleanup();
517
518     keep_random_devices_open = keep;
519 }
520
521 #  else     /* !defined(OPENSSL_RAND_SEED_DEVRANDOM) */
522
523 int rand_pool_init(void)
524 {
525     return 1;
526 }
527
528 void rand_pool_cleanup(void)
529 {
530 }
531
532 void rand_pool_keep_random_devices_open(int keep)
533 {
534 }
535
536 #  endif    /* defined(OPENSSL_RAND_SEED_DEVRANDOM) */
537
538 /*
539  * Try the various seeding methods in turn, exit when successful.
540  *
541  * TODO(DRBG): If more than one entropy source is available, is it
542  * preferable to stop as soon as enough entropy has been collected
543  * (as favored by @rsalz) or should one rather be defensive and add
544  * more entropy than requested and/or from different sources?
545  *
546  * Currently, the user can select multiple entropy sources in the
547  * configure step, yet in practice only the first available source
548  * will be used. A more flexible solution has been requested, but
549  * currently it is not clear how this can be achieved without
550  * overengineering the problem. There are many parameters which
551  * could be taken into account when selecting the order and amount
552  * of input from the different entropy sources (trust, quality,
553  * possibility of blocking).
554  */
555 size_t rand_pool_acquire_entropy(RAND_POOL *pool)
556 {
557 #  if defined(OPENSSL_RAND_SEED_NONE)
558     return rand_pool_entropy_available(pool);
559 #  else
560     size_t entropy_available;
561
562 #   if defined(OPENSSL_RAND_SEED_GETRANDOM)
563     {
564         size_t bytes_needed;
565         unsigned char *buffer;
566         ssize_t bytes;
567         /* Maximum allowed number of consecutive unsuccessful attempts */
568         int attempts = 3;
569
570         bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
571         while (bytes_needed != 0 && attempts-- > 0) {
572             buffer = rand_pool_add_begin(pool, bytes_needed);
573             bytes = syscall_random(buffer, bytes_needed);
574             if (bytes > 0) {
575                 rand_pool_add_end(pool, bytes, 8 * bytes);
576                 bytes_needed -= bytes;
577                 attempts = 3; /* reset counter after successful attempt */
578             } else if (bytes < 0 && errno != EINTR) {
579                 break;
580             }
581         }
582     }
583     entropy_available = rand_pool_entropy_available(pool);
584     if (entropy_available > 0)
585         return entropy_available;
586 #   endif
587
588 #   if defined(OPENSSL_RAND_SEED_LIBRANDOM)
589     {
590         /* Not yet implemented. */
591     }
592 #   endif
593
594 #   if defined(OPENSSL_RAND_SEED_DEVRANDOM)
595     if (wait_random_seeded()) {
596         size_t bytes_needed;
597         unsigned char *buffer;
598         size_t i;
599
600         bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
601         for (i = 0; bytes_needed > 0 && i < OSSL_NELEM(random_device_paths);
602              i++) {
603             ssize_t bytes = 0;
604             /* Maximum number of consecutive unsuccessful attempts */
605             int attempts = 3;
606             const int fd = get_random_device(i);
607
608             if (fd == -1)
609                 continue;
610
611             while (bytes_needed != 0 && attempts-- > 0) {
612                 buffer = rand_pool_add_begin(pool, bytes_needed);
613                 bytes = read(fd, buffer, bytes_needed);
614
615                 if (bytes > 0) {
616                     rand_pool_add_end(pool, bytes, 8 * bytes);
617                     bytes_needed -= bytes;
618                     attempts = 3; /* reset counter on successful attempt */
619                 } else if (bytes < 0 && errno != EINTR) {
620                     break;
621                 }
622             }
623             if (bytes < 0 || !keep_random_devices_open)
624                 close_random_device(i);
625
626             bytes_needed = rand_pool_bytes_needed(pool, 1);
627         }
628         entropy_available = rand_pool_entropy_available(pool);
629         if (entropy_available > 0)
630             return entropy_available;
631     }
632 #   endif
633
634 #   if defined(OPENSSL_RAND_SEED_RDTSC)
635     entropy_available = rand_acquire_entropy_from_tsc(pool);
636     if (entropy_available > 0)
637         return entropy_available;
638 #   endif
639
640 #   if defined(OPENSSL_RAND_SEED_RDCPU)
641     entropy_available = rand_acquire_entropy_from_cpu(pool);
642     if (entropy_available > 0)
643         return entropy_available;
644 #   endif
645
646 #   if defined(OPENSSL_RAND_SEED_EGD)
647     {
648         static const char *paths[] = { DEVRANDOM_EGD, NULL };
649         size_t bytes_needed;
650         unsigned char *buffer;
651         int i;
652
653         bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
654         for (i = 0; bytes_needed > 0 && paths[i] != NULL; i++) {
655             size_t bytes = 0;
656             int num;
657
658             buffer = rand_pool_add_begin(pool, bytes_needed);
659             num = RAND_query_egd_bytes(paths[i],
660                                        buffer, (int)bytes_needed);
661             if (num == (int)bytes_needed)
662                 bytes = bytes_needed;
663
664             rand_pool_add_end(pool, bytes, 8 * bytes);
665             bytes_needed = rand_pool_bytes_needed(pool, 1);
666         }
667         entropy_available = rand_pool_entropy_available(pool);
668         if (entropy_available > 0)
669             return entropy_available;
670     }
671 #   endif
672
673     return rand_pool_entropy_available(pool);
674 #  endif
675 }
676 # endif
677 #endif
678
679 #if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \
680      || defined(__DJGPP__)
681 int rand_pool_add_nonce_data(RAND_POOL *pool)
682 {
683     struct {
684         pid_t pid;
685         CRYPTO_THREAD_ID tid;
686         uint64_t time;
687     } data;
688
689     /* Erase the entire structure including any padding */
690     memset(&data, 0, sizeof(data));
691
692     /*
693      * Add process id, thread id, and a high resolution timestamp to
694      * ensure that the nonce is unique with high probability for
695      * different process instances.
696      */
697     data.pid = getpid();
698     data.tid = CRYPTO_THREAD_get_current_id();
699     data.time = get_time_stamp();
700
701     return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
702 }
703
704 int rand_pool_add_additional_data(RAND_POOL *pool)
705 {
706     struct {
707         CRYPTO_THREAD_ID tid;
708         uint64_t time;
709     } data;
710
711     /* Erase the entire structure including any padding */
712     memset(&data, 0, sizeof(data));
713
714     /*
715      * Add some noise from the thread id and a high resolution timer.
716      * The thread id adds a little randomness if the drbg is accessed
717      * concurrently (which is the case for the <master> drbg).
718      */
719     data.tid = CRYPTO_THREAD_get_current_id();
720     data.time = get_timer_bits();
721
722     return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
723 }
724
725
726 /*
727  * Get the current time with the highest possible resolution
728  *
729  * The time stamp is added to the nonce, so it is optimized for not repeating.
730  * The current time is ideal for this purpose, provided the computer's clock
731  * is synchronized.
732  */
733 static uint64_t get_time_stamp(void)
734 {
735 # if defined(OSSL_POSIX_TIMER_OKAY)
736     {
737         struct timespec ts;
738
739         if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
740             return TWO32TO64(ts.tv_sec, ts.tv_nsec);
741     }
742 # endif
743 # if defined(__unix__) \
744      || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
745     {
746         struct timeval tv;
747
748         if (gettimeofday(&tv, NULL) == 0)
749             return TWO32TO64(tv.tv_sec, tv.tv_usec);
750     }
751 # endif
752     return time(NULL);
753 }
754
755 /*
756  * Get an arbitrary timer value of the highest possible resolution
757  *
758  * The timer value is added as random noise to the additional data,
759  * which is not considered a trusted entropy sourec, so any result
760  * is acceptable.
761  */
762 static uint64_t get_timer_bits(void)
763 {
764     uint64_t res = OPENSSL_rdtsc();
765
766     if (res != 0)
767         return res;
768
769 # if defined(__sun) || defined(__hpux)
770     return gethrtime();
771 # elif defined(_AIX)
772     {
773         timebasestruct_t t;
774
775         read_wall_time(&t, TIMEBASE_SZ);
776         return TWO32TO64(t.tb_high, t.tb_low);
777     }
778 # elif defined(OSSL_POSIX_TIMER_OKAY)
779     {
780         struct timespec ts;
781
782 #  ifdef CLOCK_BOOTTIME
783 #   define CLOCK_TYPE CLOCK_BOOTTIME
784 #  elif defined(_POSIX_MONOTONIC_CLOCK)
785 #   define CLOCK_TYPE CLOCK_MONOTONIC
786 #  else
787 #   define CLOCK_TYPE CLOCK_REALTIME
788 #  endif
789
790         if (clock_gettime(CLOCK_TYPE, &ts) == 0)
791             return TWO32TO64(ts.tv_sec, ts.tv_nsec);
792     }
793 # endif
794 # if defined(__unix__) \
795      || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
796     {
797         struct timeval tv;
798
799         if (gettimeofday(&tv, NULL) == 0)
800             return TWO32TO64(tv.tv_sec, tv.tv_usec);
801     }
802 # endif
803     return time(NULL);
804 }
805 #endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */