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 #include <openssl/rand.h> 16 17 #if !defined(OPENSSL_WINDOWS) 18 19 #include <assert.h> 20 #include <errno.h> 21 #include <fcntl.h> 22 #include <string.h> 23 #include <unistd.h> 24 25 #include <openssl/thread.h> 26 #include <openssl/mem.h> 27 28 #include "internal.h" 29 #include "../internal.h" 30 31 32 /* This file implements a PRNG by reading from /dev/urandom, optionally with a 33 * fork-safe buffer. 34 * 35 * If buffering is enabled then it maintains a global, linked list of buffers. 36 * Threads which need random bytes grab a buffer from the list under a lock and 37 * copy out the bytes that they need. In the rare case that the buffer is 38 * empty, it's refilled from /dev/urandom outside of the lock. 39 * 40 * Large requests are always serviced from /dev/urandom directly. 41 * 42 * Each buffer contains the PID of the process that created it and it's tested 43 * against the current PID each time. Thus processes that fork will discard all 44 * the buffers filled by the parent process. There are two problems with this: 45 * 46 * 1) glibc maintains a cache of the current PID+PPID and, if this cache isn't 47 * correctly invalidated, the getpid() will continue to believe that 48 * it's the old process. Glibc depends on the glibc wrappers for fork, 49 * vfork and clone being used in order to invalidate the getpid() cache. 50 * 51 * 2) If a process forks, dies and then its child forks, it's possible that 52 * the third process will end up with the same PID as the original process. 53 * If the second process never used any random values then this will mean 54 * that the third process has stale, cached values and won't notice. 55 */ 56 57 /* BUF_SIZE is intended to be a 4K allocation with malloc overhead. struct 58 * rand_buffer also fits in this space and the remainder is entropy. */ 59 #define BUF_SIZE (4096 - 16) 60 61 /* rand_buffer contains unused, random bytes. These structures form a linked 62 * list via the |next| pointer, which is NULL in the final element. */ 63 struct rand_buffer { 64 size_t used; /* used contains the number of bytes of |rand| that have 65 been consumed. */ 66 struct rand_buffer *next; 67 pid_t pid; /* pid contains the pid at the time that the buffer was 68 created so that data is not duplicated after a fork. */ 69 pid_t ppid; /* ppid contains the parent pid in order to try and reduce 70 the possibility of duplicated PID confusing the 71 detection of a fork. */ 72 uint8_t rand[]; 73 }; 74 75 /* rand_bytes_per_buf is the number of actual entropy bytes in a buffer. */ 76 static const size_t rand_bytes_per_buf = BUF_SIZE - sizeof(struct rand_buffer); 77 78 static struct CRYPTO_STATIC_MUTEX global_lock = CRYPTO_STATIC_MUTEX_INIT; 79 80 /* list_head is the start of a global, linked-list of rand_buffer objects. It's 81 * protected by |global_lock|. */ 82 static struct rand_buffer *list_head; 83 84 /* urandom_fd is a file descriptor to /dev/urandom. It's protected by 85 * |global_lock|. */ 86 static int urandom_fd = -2; 87 88 /* urandom_buffering controls whether buffering is enabled (1) or not (0). This 89 * is protected by |global_lock|. */ 90 static int urandom_buffering = 0; 91 92 /* urandom_get_fd_locked returns a file descriptor to /dev/urandom. The caller 93 * of this function must hold |global_lock|. */ 94 static int urandom_get_fd_locked(void) { 95 if (urandom_fd != -2) { 96 return urandom_fd; 97 } 98 99 urandom_fd = open("/dev/urandom", O_RDONLY); 100 return urandom_fd; 101 } 102 103 /* RAND_cleanup frees all buffers, closes any cached file descriptor 104 * and resets the global state. */ 105 void RAND_cleanup(void) { 106 struct rand_buffer *cur; 107 108 CRYPTO_STATIC_MUTEX_lock_write(&global_lock); 109 while ((cur = list_head)) { 110 list_head = cur->next; 111 OPENSSL_free(cur); 112 } 113 if (urandom_fd >= 0) { 114 close(urandom_fd); 115 } 116 urandom_fd = -2; 117 list_head = NULL; 118 CRYPTO_STATIC_MUTEX_unlock(&global_lock); 119 } 120 121 /* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In 122 * the case of an error it returns 0. */ 123 static char read_full(int fd, uint8_t *out, size_t len) { 124 ssize_t r; 125 126 while (len > 0) { 127 do { 128 r = read(fd, out, len); 129 } while (r == -1 && errno == EINTR); 130 131 if (r <= 0) { 132 return 0; 133 } 134 out += r; 135 len -= r; 136 } 137 138 return 1; 139 } 140 141 /* CRYPTO_sysrand puts |num| random bytes into |out|. */ 142 void CRYPTO_sysrand(uint8_t *out, size_t requested) { 143 int fd; 144 struct rand_buffer *buf; 145 size_t todo; 146 pid_t pid, ppid; 147 148 if (requested == 0) { 149 return; 150 } 151 152 CRYPTO_STATIC_MUTEX_lock_write(&global_lock); 153 fd = urandom_get_fd_locked(); 154 155 if (fd < 0) { 156 CRYPTO_STATIC_MUTEX_unlock(&global_lock); 157 abort(); 158 return; 159 } 160 161 /* If buffering is not enabled, or if the request is large, then the 162 * result comes directly from urandom. */ 163 if (!urandom_buffering || requested > BUF_SIZE / 2) { 164 CRYPTO_STATIC_MUTEX_unlock(&global_lock); 165 if (!read_full(fd, out, requested)) { 166 abort(); 167 } 168 return; 169 } 170 171 pid = getpid(); 172 ppid = getppid(); 173 174 for (;;) { 175 buf = list_head; 176 if (buf && buf->pid == pid && buf->ppid == ppid && 177 rand_bytes_per_buf - buf->used >= requested) { 178 memcpy(out, &buf->rand[buf->used], requested); 179 buf->used += requested; 180 CRYPTO_STATIC_MUTEX_unlock(&global_lock); 181 return; 182 } 183 184 /* If we don't immediately have enough entropy with the correct 185 * PID, remove the buffer from the list in order to gain 186 * exclusive access and unlock. */ 187 if (buf) { 188 list_head = buf->next; 189 } 190 CRYPTO_STATIC_MUTEX_unlock(&global_lock); 191 192 if (!buf) { 193 buf = (struct rand_buffer *)OPENSSL_malloc(BUF_SIZE); 194 if (!buf) { 195 abort(); 196 return; 197 } 198 /* The buffer doesn't contain any random bytes yet 199 * so we mark it as fully used so that it will be 200 * filled below. */ 201 buf->used = rand_bytes_per_buf; 202 buf->next = NULL; 203 buf->pid = pid; 204 buf->ppid = ppid; 205 } 206 207 if (buf->pid == pid && buf->ppid == ppid) { 208 break; 209 } 210 211 /* We have forked and so cannot use these bytes as they 212 * may have been used in another process. */ 213 OPENSSL_free(buf); 214 CRYPTO_STATIC_MUTEX_lock_write(&global_lock); 215 } 216 217 while (requested > 0) { 218 todo = rand_bytes_per_buf - buf->used; 219 if (todo > requested) { 220 todo = requested; 221 } 222 memcpy(out, &buf->rand[buf->used], todo); 223 requested -= todo; 224 out += todo; 225 buf->used += todo; 226 227 if (buf->used < rand_bytes_per_buf) { 228 break; 229 } 230 231 if (!read_full(fd, buf->rand, rand_bytes_per_buf)) { 232 OPENSSL_free(buf); 233 abort(); 234 return; 235 } 236 237 buf->used = 0; 238 } 239 240 CRYPTO_STATIC_MUTEX_lock_write(&global_lock); 241 assert(list_head != buf); 242 buf->next = list_head; 243 list_head = buf; 244 CRYPTO_STATIC_MUTEX_unlock(&global_lock); 245 } 246 247 #endif /* !OPENSSL_WINDOWS */ 248