195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (c) 2014, Google Inc. 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Permission to use, copy, modify, and/or distribute this software for any 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * purpose with or without fee is hereby granted, provided that the above 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copyright notice and this permission notice appear in all copies. 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/rand.h> 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if !defined(OPENSSL_WINDOWS) 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <assert.h> 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <errno.h> 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <fcntl.h> 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <stdlib.h> 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <string.h> 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <unistd.h> 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/thread.h> 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* This file implements a PRNG by reading from /dev/urandom, optionally with a 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * fork-safe buffer. 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If buffering is enabled then it maintains a global, linked list of buffers. 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Threads which need random bytes grab a buffer from the list under a lock and 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copy out the bytes that they need. In the rare case that the buffer is 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * empty, it's refilled from /dev/urandom outside of the lock. 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Large requests are always serviced from /dev/urandom directly. 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Each buffer contains the PID of the process that created it and it's tested 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * against the current PID each time. Thus processes that fork will discard all 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the buffers filled by the parent process. There are two problems with this: 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1) glibc maintains a cache of the current PID+PPID and, if this cache isn't 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * correctly invalidated, the getpid() will continue to believe that 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * it's the old process. Glibc depends on the glibc wrappers for fork, 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * vfork and clone being used in order to invalidate the getpid() cache. 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2) If a process forks, dies and then its child forks, it's possible that 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the third process will end up with the same PID as the original process. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If the second process never used any random values then this will mean 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * that the third process has stale, cached values and won't notice. 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* BUF_SIZE is intended to be a 4K allocation with malloc overhead. struct 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * rand_buffer also fits in this space and the remainder is entropy. */ 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define BUF_SIZE (4096 - 16) 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* rand_buffer contains unused, random bytes. These structures form a linked 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * list via the |next| pointer, which is NULL in the final element. */ 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystruct rand_buffer { 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t used; /* used contains the number of bytes of |rand| that have 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley been consumed. */ 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley struct rand_buffer *next; 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pid_t pid; /* pid contains the pid at the time that the buffer was 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley created so that data is not duplicated after a fork. */ 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pid_t ppid; /* ppid contains the parent pid in order to try and reduce 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley the possibility of duplicated PID confusing the 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley detection of a fork. */ 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley uint8_t rand[]; 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* rand_bytes_per_buf is the number of actual entropy bytes in a buffer. */ 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic const size_t rand_bytes_per_buf = BUF_SIZE - sizeof(struct rand_buffer); 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* list_head is the start of a global, linked-list of rand_buffer objects. It's 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * protected by CRYPTO_LOCK_RAND. */ 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic struct rand_buffer *list_head; 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* urandom_fd is a file descriptor to /dev/urandom. It's protected by 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * CRYPTO_LOCK_RAND. */ 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int urandom_fd = -2; 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* urandom_buffering controls whether buffering is enabled (1) or not (0). This 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * is protected by CRYPTO_LOCK_RAND. */ 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int urandom_buffering = 0; 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* urandom_get_fd_locked returns a file descriptor to /dev/urandom. The caller 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * of this function must hold CRYPTO_LOCK_RAND. */ 90c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David Benjaminstatic int urandom_get_fd_locked(void) { 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (urandom_fd != -2) 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return urandom_fd; 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 940113a4fb60c3b6e9e93a217d5b4d373eb343a8c6Adam Langley urandom_fd = open("/dev/urandom", O_RDONLY); 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return urandom_fd; 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* RAND_cleanup frees all buffers, closes any cached file descriptor 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * and resets the global state. */ 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid RAND_cleanup(void) { 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley struct rand_buffer *cur; 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_RAND); 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while ((cur = list_head)) { 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley list_head = cur->next; 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(cur); 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (urandom_fd >= 0) { 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley close(urandom_fd); 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley urandom_fd = -2; 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley list_head = NULL; 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the case of an error it returns 0. */ 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic char read_full(int fd, uint8_t *out, size_t len) { 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ssize_t r; 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (len > 0) { 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley do { 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley r = read(fd, out, len); 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } while (r == -1 && errno == EINTR); 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (r <= 0) { 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += r; 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley len -= r; 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* urandom_rand_pseudo_bytes puts |num| random bytes into |out|. It returns 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * one on success and zero otherwise. */ 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint RAND_bytes(uint8_t *out, size_t requested) { 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int fd; 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley struct rand_buffer *buf; 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t todo; 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pid_t pid, ppid; 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (requested == 0) { 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_RAND); 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley fd = urandom_get_fd_locked(); 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (fd < 0) { 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley abort(); 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If buffering is not enabled, or if the request is large, then the 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * result comes directly from urandom. */ 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!urandom_buffering || requested > BUF_SIZE / 2) { 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!read_full(fd, out, requested)) { 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley abort(); 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley pid = getpid(); 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ppid = getppid(); 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (;;) { 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf = list_head; 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf && buf->pid == pid && buf->ppid == ppid && 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rand_bytes_per_buf - buf->used >= requested) { 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(out, &buf->rand[buf->used], requested); 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->used += requested; 17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If we don't immediately have enough entropy with the correct 18295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * PID, remove the buffer from the list in order to gain 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * exclusive access and unlock. */ 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf) { 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley list_head = buf->next; 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 18795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 18995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!buf) { 19095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf = (struct rand_buffer *)OPENSSL_malloc(BUF_SIZE); 19195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* The buffer doesn't contain any random bytes yet 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * so we mark it as fully used so that it will be 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * filled below. */ 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->used = rand_bytes_per_buf; 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->next = NULL; 19695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->pid = pid; 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->ppid = ppid; 19895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf->pid == pid && buf->ppid == ppid) { 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We have forked and so cannot use these bytes as they 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * may have been used in another process. */ 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(buf); 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_RAND); 20895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 21095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (requested > 0) { 21195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley todo = rand_bytes_per_buf - buf->used; 21295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (todo > requested) { 21395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley todo = requested; 21495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 21595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(out, &buf->rand[buf->used], todo); 21695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley requested -= todo; 21795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += todo; 21895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->used += todo; 21995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (buf->used < rand_bytes_per_buf) { 22195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley break; 22295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 22495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!read_full(fd, buf->rand, rand_bytes_per_buf)) { 22595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(buf); 22695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley abort(); 22795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 22895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 22995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->used = 0; 23195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 23295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 23395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_lock(CRYPTO_LOCK_RAND); 23495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(list_head != buf); 23595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley buf->next = list_head; 23695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley list_head = buf; 23795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 23895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 23995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 24095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 24195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif /* !OPENSSL_WINDOWS */ 242