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