1/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#if !defined(_GNU_SOURCE)
16#define _GNU_SOURCE // needed for syscall() on Linux.
17#endif
18
19#include <openssl/rand.h>
20
21#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_FUCHSIA) && \
22 !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) && !defined(OPENSSL_TRUSTY)
23
24#include <assert.h>
25#include <errno.h>
26#include <fcntl.h>
27#include <stdio.h>
28#include <string.h>
29#include <unistd.h>
30
31#if defined(OPENSSL_LINUX)
32#if defined(BORINGSSL_FIPS)
33#include <linux/random.h>
34#include <sys/ioctl.h>
35#endif
36#include <sys/syscall.h>
37
38#if !defined(OPENSSL_ANDROID)
39#define OPENSSL_HAS_GETAUXVAL
40#endif
41// glibc prior to 2.16 does not have getauxval and sys/auxv.h. Android has some
42// host builds (i.e. not building for Android itself, so |OPENSSL_ANDROID| is
43// unset) which are still using a 2.15 sysroot.
44//
45// TODO(davidben): Remove this once Android updates their sysroot.
46#if defined(__GLIBC_PREREQ)
47#if !__GLIBC_PREREQ(2, 16)
48#undef OPENSSL_HAS_GETAUXVAL
49#endif
50#endif
51#if defined(OPENSSL_HAS_GETAUXVAL)
52#include <sys/auxv.h>
53#endif
54#endif // OPENSSL_LINUX
55
56#include <openssl/thread.h>
57#include <openssl/mem.h>
58
59#include "internal.h"
60#include "../delocate.h"
61#include "../../internal.h"
62
63
64#if defined(OPENSSL_LINUX)
65
66#if defined(OPENSSL_X86_64)
67#define EXPECTED_NR_getrandom 318
68#elif defined(OPENSSL_X86)
69#define EXPECTED_NR_getrandom 355
70#elif defined(OPENSSL_AARCH64)
71#define EXPECTED_NR_getrandom 278
72#elif defined(OPENSSL_ARM)
73#define EXPECTED_NR_getrandom 384
74#elif defined(OPENSSL_PPC64LE)
75#define EXPECTED_NR_getrandom 359
76#endif
77
78#if defined(EXPECTED_NR_getrandom)
79#define USE_NR_getrandom
80
81#if defined(__NR_getrandom)
82
83#if __NR_getrandom != EXPECTED_NR_getrandom
84#error "system call number for getrandom is not the expected value"
85#endif
86
87#else // __NR_getrandom
88
89#define __NR_getrandom EXPECTED_NR_getrandom
90
91#endif // __NR_getrandom
92
93#if defined(OPENSSL_MSAN)
94void __msan_unpoison(void *, size_t);
95#endif
96
97static ssize_t boringssl_getrandom(void *buf, size_t buf_len, unsigned flags) {
98 ssize_t ret;
99 do {
100 ret = syscall(__NR_getrandom, buf, buf_len, flags);
101 } while (ret == -1 && errno == EINTR);
102
103#if defined(OPENSSL_MSAN)
104 if (ret > 0) {
105 // MSAN doesn't recognise |syscall| and thus doesn't notice that we have
106 // initialised the output buffer.
107 __msan_unpoison(buf, ret);
108 }
109#endif // OPENSSL_MSAN
110
111 return ret;
112}
113
114#endif // EXPECTED_NR_getrandom
115
116#if !defined(GRND_NONBLOCK)
117#define GRND_NONBLOCK 1
118#endif
119
120#endif // OPENSSL_LINUX
121
122// rand_lock is used to protect the |*_requested| variables.
123DEFINE_STATIC_MUTEX(rand_lock)
124
125// The following constants are magic values of |urandom_fd|.
126static const int kUnset = 0;
127static const int kHaveGetrandom = -3;
128
129// urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by
130// |rand_lock|.
131DEFINE_BSS_GET(int, urandom_fd_requested)
132
133// urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|.
134DEFINE_BSS_GET(int, urandom_fd)
135
136DEFINE_STATIC_ONCE(rand_once)
137
138// init_once initializes the state of this module to values previously
139// requested. This is the only function that modifies |urandom_fd| and
140// |urandom_buffering|, whose values may be read safely after calling the
141// once.
142static void init_once(void) {
143 CRYPTO_STATIC_MUTEX_lock_read(rand_lock_bss_get());
144 int fd = *urandom_fd_requested_bss_get();
145 CRYPTO_STATIC_MUTEX_unlock_read(rand_lock_bss_get());
146
147#if defined(USE_NR_getrandom)
148 uint8_t dummy;
149 ssize_t getrandom_ret =
150 boringssl_getrandom(&dummy, sizeof(dummy), GRND_NONBLOCK);
151
152 if (getrandom_ret == -1 && errno == EAGAIN) {
153 // Attempt to get the path of the current process to aid in debugging when
154 // something blocks.
155 const char *current_process = "<unknown>";
156#if defined(OPENSSL_HAS_GETAUXVAL)
157 const unsigned long getauxval_ret = getauxval(AT_EXECFN);
158 if (getauxval_ret != 0) {
159 current_process = (const char *)getauxval_ret;
160 }
161#endif
162
163 fprintf(stderr,
164 "%s: getrandom indicates that the entropy pool has not been "
165 "initialized. Rather than continue with poor entropy, this process "
166 "will block until entropy is available.\n",
167 current_process);
168
169 getrandom_ret =
170 boringssl_getrandom(&dummy, sizeof(dummy), 0 /* no flags */);
171 }
172
173 if (getrandom_ret == 1) {
174 *urandom_fd_bss_get() = kHaveGetrandom;
175 return;
176 }
177
178 // Ignore ENOSYS and fallthrough to using /dev/urandom, below. Otherwise it's
179 // a fatal error.
180 if (getrandom_ret != -1 || errno != ENOSYS) {
181 perror("getrandom");
182 abort();
183 }
184#endif // USE_NR_getrandom
185
186 if (fd == kUnset) {
187 do {
188 fd = open("/dev/urandom", O_RDONLY);
189 } while (fd == -1 && errno == EINTR);
190 }
191
192 if (fd < 0) {
193 perror("failed to open /dev/urandom");
194 abort();
195 }
196
197 assert(kUnset == 0);
198 if (fd == kUnset) {
199 // Because we want to keep |urandom_fd| in the BSS, we have to initialise
200 // it to zero. But zero is a valid file descriptor too. Thus if open
201 // returns zero for /dev/urandom, we dup it to get a non-zero number.
202 fd = dup(fd);
203 close(kUnset);
204
205 if (fd <= 0) {
206 perror("failed to dup /dev/urandom fd");
207 abort();
208 }
209 }
210
211#if defined(BORINGSSL_FIPS)
212 // In FIPS mode we ensure that the kernel has sufficient entropy before
213 // continuing. This is automatically handled by getrandom, which requires
214 // that the entropy pool has been initialised, but for urandom we have to
215 // poll.
216 for (;;) {
217 int entropy_bits;
218 if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) {
219 fprintf(stderr,
220 "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this "
221 "case when in FIPS mode.\n");
222 abort();
223 }
224
225 static const int kBitsNeeded = 256;
226 if (entropy_bits >= kBitsNeeded) {
227 break;
228 }
229
230 usleep(250000);
231 }
232#endif
233
234 int flags = fcntl(fd, F_GETFD);
235 if (flags == -1) {
236 // Native Client doesn't implement |fcntl|.
237 if (errno != ENOSYS) {
238 perror("failed to get flags from urandom fd");
239 abort();
240 }
241 } else {
242 flags |= FD_CLOEXEC;
243 if (fcntl(fd, F_SETFD, flags) == -1) {
244 perror("failed to set FD_CLOEXEC on urandom fd");
245 abort();
246 }
247 }
248 *urandom_fd_bss_get() = fd;
249}
250
251void RAND_set_urandom_fd(int fd) {
252 fd = dup(fd);
253 if (fd < 0) {
254 perror("failed to dup supplied urandom fd");
255 abort();
256 }
257
258 assert(kUnset == 0);
259 if (fd == kUnset) {
260 // Because we want to keep |urandom_fd| in the BSS, we have to initialise
261 // it to zero. But zero is a valid file descriptor too. Thus if dup
262 // returned zero we dup it again to get a non-zero number.
263 fd = dup(fd);
264 close(kUnset);
265
266 if (fd <= 0) {
267 perror("failed to dup supplied urandom fd");
268 abort();
269 }
270 }
271
272 CRYPTO_STATIC_MUTEX_lock_write(rand_lock_bss_get());
273 *urandom_fd_requested_bss_get() = fd;
274 CRYPTO_STATIC_MUTEX_unlock_write(rand_lock_bss_get());
275
276 CRYPTO_once(rand_once_bss_get(), init_once);
277 if (*urandom_fd_bss_get() == kHaveGetrandom) {
278 close(fd);
279 } else if (*urandom_fd_bss_get() != fd) {
280 fprintf(stderr, "RAND_set_urandom_fd called after initialisation.\n");
281 abort();
282 }
283}
284
285// fill_with_entropy writes |len| bytes of entropy into |out|. It returns one
286// on success and zero on error.
287static char fill_with_entropy(uint8_t *out, size_t len) {
288 while (len > 0) {
289 ssize_t r;
290
291 if (*urandom_fd_bss_get() == kHaveGetrandom) {
292#if defined(USE_NR_getrandom)
293 r = boringssl_getrandom(out, len, 0 /* no flags */);
294#else // USE_NR_getrandom
295 fprintf(stderr, "urandom fd corrupt.\n");
296 abort();
297#endif
298 } else {
299 do {
300 r = read(*urandom_fd_bss_get(), out, len);
301 } while (r == -1 && errno == EINTR);
302 }
303
304 if (r <= 0) {
305 return 0;
306 }
307 out += r;
308 len -= r;
309 }
310
311 return 1;
312}
313
314// CRYPTO_sysrand puts |requested| random bytes into |out|.
315void CRYPTO_sysrand(uint8_t *out, size_t requested) {
316 if (requested == 0) {
317 return;
318 }
319
320 CRYPTO_once(rand_once_bss_get(), init_once);
321
322 if (!fill_with_entropy(out, requested)) {
323 perror("entropy fill failed");
324 abort();
325 }
326
327#if defined(BORINGSSL_FIPS_BREAK_CRNG)
328 // This breaks the "continuous random number generator test" defined in FIPS
329 // 140-2, section 4.9.2, and implemented in rand_get_seed().
330 OPENSSL_memset(out, 0, requested);
331#endif
332}
333
334#endif /* !OPENSSL_WINDOWS && !defined(OPENSSL_FUCHSIA) && \
335 !BORINGSSL_UNSAFE_DETERMINISTIC_MODE && !OPENSSL_TRUSTY */
336