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 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|. 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 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. 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|. 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