Coverage Report

Created: 2026-04-01 06:53

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