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)
94 void __msan_unpoison(void *, size_t);
95 #endif
96
boringssl_getrandom(void * buf,size_t buf_len,unsigned flags)97 static 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.
123 DEFINE_STATIC_MUTEX(rand_lock)
124
125 // The following constants are magic values of |urandom_fd|.
126 static const int kUnset = 0;
127 static const int kHaveGetrandom = -3;
128
129 // urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by
130 // |rand_lock|.
DEFINE_BSS_GET(int,urandom_fd_requested)131 DEFINE_BSS_GET(int, urandom_fd_requested)
132
133 // urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|.
134 DEFINE_BSS_GET(int, urandom_fd)
135
136 DEFINE_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.
142 static 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
RAND_set_urandom_fd(int fd)251 void 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.
fill_with_entropy(uint8_t * out,size_t len)287 static 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|.
CRYPTO_sysrand(uint8_t * out,size_t requested)315 void 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