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 #endif 38 39 #include <openssl/thread.h> 40 #include <openssl/mem.h> 41 42 #include "internal.h" 43 #include "../delocate.h" 44 #include "../../internal.h" 45 46 47 #if defined(OPENSSL_LINUX) 48 49 #if defined(OPENSSL_X86_64) 50 #define EXPECTED_NR_getrandom 318 51 #elif defined(OPENSSL_X86) 52 #define EXPECTED_NR_getrandom 355 53 #elif defined(OPENSSL_AARCH64) 54 #define EXPECTED_NR_getrandom 278 55 #elif defined(OPENSSL_ARM) 56 #define EXPECTED_NR_getrandom 384 57 #elif defined(OPENSSL_PPC64LE) 58 #define EXPECTED_NR_getrandom 359 59 #endif 60 61 #if defined(EXPECTED_NR_getrandom) 62 #define USE_NR_getrandom 63 64 #if defined(__NR_getrandom) 65 66 #if __NR_getrandom != EXPECTED_NR_getrandom 67 #error "system call number for getrandom is not the expected value" 68 #endif 69 70 #else // __NR_getrandom 71 72 #define __NR_getrandom EXPECTED_NR_getrandom 73 74 #endif // __NR_getrandom 75 76 #endif // EXPECTED_NR_getrandom 77 78 #if !defined(GRND_NONBLOCK) 79 #define GRND_NONBLOCK 1 80 #endif 81 82 #endif // OPENSSL_LINUX 83 84 // rand_lock is used to protect the |*_requested| variables. 85 DEFINE_STATIC_MUTEX(rand_lock); 86 87 // The following constants are magic values of |urandom_fd|. 88 static const int kUnset = 0; 89 static const int kHaveGetrandom = -3; 90 91 // urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by 92 // |rand_lock|. 93 DEFINE_BSS_GET(int, urandom_fd_requested); 94 95 // urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. 96 DEFINE_BSS_GET(int, urandom_fd); 97 98 DEFINE_STATIC_ONCE(rand_once); 99 100 #if defined(USE_NR_getrandom) || defined(BORINGSSL_FIPS) 101 // message writes |msg| to stderr. We use this because referencing |stderr| 102 // with |fprintf| generates relocations, which is a problem inside the FIPS 103 // module. 104 static void message(const char *msg) { 105 ssize_t r; 106 do { 107 r = write(2, msg, strlen(msg)); 108 } while (r == -1 && errno == EINTR); 109 } 110 #endif 111 112 // init_once initializes the state of this module to values previously 113 // requested. This is the only function that modifies |urandom_fd| and 114 // |urandom_buffering|, whose values may be read safely after calling the 115 // once. 116 static void init_once(void) { 117 CRYPTO_STATIC_MUTEX_lock_read(rand_lock_bss_get()); 118 int fd = *urandom_fd_requested_bss_get(); 119 CRYPTO_STATIC_MUTEX_unlock_read(rand_lock_bss_get()); 120 121 #if defined(USE_NR_getrandom) 122 uint8_t dummy; 123 long getrandom_ret = 124 syscall(__NR_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK); 125 126 if (getrandom_ret == 1) { 127 *urandom_fd_bss_get() = kHaveGetrandom; 128 return; 129 } else if (getrandom_ret == -1 && errno == EAGAIN) { 130 message( 131 "getrandom indicates that the entropy pool has not been initialized. " 132 "Rather than continue with poor entropy, this process will block until " 133 "entropy is available.\n"); 134 135 do { 136 getrandom_ret = 137 syscall(__NR_getrandom, &dummy, sizeof(dummy), 0 /* no flags */); 138 } while (getrandom_ret == -1 && errno == EINTR); 139 140 if (getrandom_ret == 1) { 141 *urandom_fd_bss_get() = kHaveGetrandom; 142 return; 143 } 144 } 145 #endif // USE_NR_getrandom 146 147 if (fd == kUnset) { 148 do { 149 fd = open("/dev/urandom", O_RDONLY); 150 } while (fd == -1 && errno == EINTR); 151 } 152 153 if (fd < 0) { 154 abort(); 155 } 156 157 assert(kUnset == 0); 158 if (fd == kUnset) { 159 // Because we want to keep |urandom_fd| in the BSS, we have to initialise 160 // it to zero. But zero is a valid file descriptor too. Thus if open 161 // returns zero for /dev/urandom, we dup it to get a non-zero number. 162 fd = dup(fd); 163 close(kUnset); 164 165 if (fd <= 0) { 166 abort(); 167 } 168 } 169 170 #if defined(BORINGSSL_FIPS) 171 // In FIPS mode we ensure that the kernel has sufficient entropy before 172 // continuing. This is automatically handled by getrandom, which requires 173 // that the entropy pool has been initialised, but for urandom we have to 174 // poll. 175 for (;;) { 176 int entropy_bits; 177 if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) { 178 message( 179 "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " 180 "case when in FIPS mode.\n"); 181 abort(); 182 } 183 184 static const int kBitsNeeded = 256; 185 if (entropy_bits >= kBitsNeeded) { 186 break; 187 } 188 189 usleep(250000); 190 } 191 #endif 192 193 int flags = fcntl(fd, F_GETFD); 194 if (flags == -1) { 195 // Native Client doesn't implement |fcntl|. 196 if (errno != ENOSYS) { 197 abort(); 198 } 199 } else { 200 flags |= FD_CLOEXEC; 201 if (fcntl(fd, F_SETFD, flags) == -1) { 202 abort(); 203 } 204 } 205 *urandom_fd_bss_get() = fd; 206 } 207 208 void RAND_set_urandom_fd(int fd) { 209 fd = dup(fd); 210 if (fd < 0) { 211 abort(); 212 } 213 214 assert(kUnset == 0); 215 if (fd == kUnset) { 216 // Because we want to keep |urandom_fd| in the BSS, we have to initialise 217 // it to zero. But zero is a valid file descriptor too. Thus if dup 218 // returned zero we dup it again to get a non-zero number. 219 fd = dup(fd); 220 close(kUnset); 221 222 if (fd <= 0) { 223 abort(); 224 } 225 } 226 227 CRYPTO_STATIC_MUTEX_lock_write(rand_lock_bss_get()); 228 *urandom_fd_requested_bss_get() = fd; 229 CRYPTO_STATIC_MUTEX_unlock_write(rand_lock_bss_get()); 230 231 CRYPTO_once(rand_once_bss_get(), init_once); 232 if (*urandom_fd_bss_get() == kHaveGetrandom) { 233 close(fd); 234 } else if (*urandom_fd_bss_get() != fd) { 235 abort(); // Already initialized. 236 } 237 } 238 239 #if defined(USE_NR_getrandom) && defined(OPENSSL_MSAN) 240 void __msan_unpoison(void *, size_t); 241 #endif 242 243 // fill_with_entropy writes |len| bytes of entropy into |out|. It returns one 244 // on success and zero on error. 245 static char fill_with_entropy(uint8_t *out, size_t len) { 246 while (len > 0) { 247 ssize_t r; 248 249 if (*urandom_fd_bss_get() == kHaveGetrandom) { 250 #if defined(USE_NR_getrandom) 251 do { 252 r = syscall(__NR_getrandom, out, len, 0 /* no flags */); 253 } while (r == -1 && errno == EINTR); 254 255 #if defined(OPENSSL_MSAN) 256 if (r > 0) { 257 // MSAN doesn't recognise |syscall| and thus doesn't notice that we 258 // have initialised the output buffer. 259 __msan_unpoison(out, r); 260 } 261 #endif // OPENSSL_MSAN 262 263 #else // USE_NR_getrandom 264 abort(); 265 #endif 266 } else { 267 do { 268 r = read(*urandom_fd_bss_get(), out, len); 269 } while (r == -1 && errno == EINTR); 270 } 271 272 if (r <= 0) { 273 return 0; 274 } 275 out += r; 276 len -= r; 277 } 278 279 return 1; 280 } 281 282 // CRYPTO_sysrand puts |requested| random bytes into |out|. 283 void CRYPTO_sysrand(uint8_t *out, size_t requested) { 284 if (requested == 0) { 285 return; 286 } 287 288 CRYPTO_once(rand_once_bss_get(), init_once); 289 290 if (!fill_with_entropy(out, requested)) { 291 abort(); 292 } 293 294 #if defined(BORINGSSL_FIPS_BREAK_CRNG) 295 // This breaks the "continuous random number generator test" defined in FIPS 296 // 140-2, section 4.9.2, and implemented in rand_get_seed(). 297 OPENSSL_memset(out, 0, requested); 298 #endif 299 } 300 301 #endif /* !OPENSSL_WINDOWS && !defined(OPENSSL_FUCHSIA) && \ 302 !BORINGSSL_UNSAFE_DETERMINISTIC_MODE && !OPENSSL_TRUSTY */ 303