OpenCoverage

rand_unix.c

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

Generated by Squish Coco 4.2.2