1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* 2c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Redistribution and use in source and binary forms, with or without 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * modification, are permitted provided that the following conditions 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * are met: 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * 1. Redistributions of source code must retain the above copyright 8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * notice, this list of conditions and the following disclaimer. 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * 2. Redistributions in binary form must reproduce the above copyright 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * notice, this list of conditions and the following disclaimer in the 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * documentation and/or other materials provided with the distribution. 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * 3. The name of the author may not be used to endorse or promote products 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * derived from this software without specific prior written permission. 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper */ 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard/* This file has our secure PRNG code. On platforms that have arc4random(), 28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * we just use that. Otherwise, we include arc4random.c as a bunch of static 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * functions, and wrap it lightly. We don't expose the arc4random*() APIs 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * because A) they aren't in our namespace, and B) it's not nice to name your 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * APIs after their implementations. We keep them in a separate file 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * so that other people can rip it out and use it for whatever. 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "event2/event-config.h" 36390dd3d21c5b92dda139da744edae7093d70fc9bMark Wielaard 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <limits.h> 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "util-internal.h" 40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "evthread-internal.h" 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 421ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard#ifdef _EVENT_HAVE_ARC4RANDOM 431ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard#include <stdlib.h> 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h> 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint 46c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_set_urandom_device_file(char *fname) 47c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 48bb9d1b4bf225a604ceb69130f5a54a66f95b525dMark Wielaard (void) fname; 49c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard return -1; 50bb9d1b4bf225a604ceb69130f5a54a66f95b525dMark Wielaard} 51c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardint 52c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_init(void) 53c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 54c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard /* call arc4random() now to force it to self-initialize */ 55c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard (void) arc4random(); 56bb9d1b4bf225a604ceb69130f5a54a66f95b525dMark Wielaard return 0; 57c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 58c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardint 59c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_global_setup_locks_(const int enable_locks) 60bb9d1b4bf225a604ceb69130f5a54a66f95b525dMark Wielaard{ 61c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard return 0; 62bb9d1b4bf225a604ceb69130f5a54a66f95b525dMark Wielaard} 63c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 64c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardstatic void 65c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardev_arc4random_buf(void *buf, size_t n) 66c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 67c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#if defined(_EVENT_HAVE_ARC4RANDOM_BUF) && !defined(__APPLE__) 68c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard return arc4random_buf(buf, n); 69c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#else 70c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard unsigned char *b = buf; 71c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 72c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#if defined(_EVENT_HAVE_ARC4RANDOM_BUF) 73c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard /* OSX 10.7 introducd arc4random_buf, so if you build your program 74c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard * there, you'll get surprised when older versions of OSX fail to run. 75c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard * To solve this, we can check whether the function pointer is set, 76c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard * and fall back otherwise. (OSX does this using some linker 77c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard * trickery.) 78c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard */ 79c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard { 80c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard void (*tptr)(void *,size_t) = 81c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard (void (*)(void*,size_t))arc4random_buf; 82c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard if (tptr != NULL) { 83c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard return arc4random_buf(buf, n); 84c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard } 85c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard } 86c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif 87c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard /* Make sure that we start out with b at a 4-byte alignment; plenty 88c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard * of CPUs care about this for 32-bit access. */ 89c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard if (n >= 4 && ((ev_uintptr_t)b) & 3) { 90c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard ev_uint32_t u = arc4random(); 91c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard int n_bytes = 4 - (((ev_uintptr_t)b) & 3); 92c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard memcpy(b, &u, n_bytes); 93c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard b += n_bytes; 94c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard n -= n_bytes; 95c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard } 96c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard while (n >= 4) { 97c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard *(ev_uint32_t*)b = arc4random(); 98c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard b += 4; 99c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard n -= 4; 100c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard } 101c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard if (n) { 102c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard ev_uint32_t u = arc4random(); 103c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard memcpy(b, &u, n); 104c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard } 105c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif 106c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 107c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 108c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#else /* !_EVENT_HAVE_ARC4RANDOM { */ 109c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 110c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#ifdef _EVENT_ssize_t 111c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define ssize_t _EVENT_SSIZE_t 112c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif 113c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define ARC4RANDOM_EXPORT static 114c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define _ARC4_LOCK() EVLOCK_LOCK(arc4rand_lock, 0) 115c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define _ARC4_UNLOCK() EVLOCK_UNLOCK(arc4rand_lock, 0) 116c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#ifndef _EVENT_DISABLE_THREAD_SUPPORT 117c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardstatic void *arc4rand_lock; 118c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif 119c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 120c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define ARC4RANDOM_UINT32 ev_uint32_t 121c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define ARC4RANDOM_NOSTIR 122c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define ARC4RANDOM_NORANDOM 123c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#define ARC4RANDOM_NOUNIFORM 124c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 125c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#include "./arc4random.c" 126c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 127c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#ifndef _EVENT_DISABLE_THREAD_SUPPORT 128c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardint 129c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_global_setup_locks_(const int enable_locks) 130c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 131c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard EVTHREAD_SETUP_GLOBAL_LOCK(arc4rand_lock, 0); 132c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard return 0; 133c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 134c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif 135c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 136c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardint 137c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_set_urandom_device_file(char *fname) 138c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 139c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#ifdef TRY_SEED_URANDOM 140c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard _ARC4_LOCK(); 141c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard arc4random_urandom_filename = fname; 142c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard _ARC4_UNLOCK(); 143c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif 144c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard return 0; 145c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 146c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 147c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardint 148c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_init(void) 149c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 150c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard int val; 151c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 152c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard _ARC4_LOCK(); 153c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard if (!arc4_seeded_ok) 154c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard arc4_stir(); 155c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard val = arc4_seeded_ok ? 0 : -1; 156c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard _ARC4_UNLOCK(); 157c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard return val; 158c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 159c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 160c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardstatic void 161c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardev_arc4random_buf(void *buf, size_t n) 162c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 163c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard arc4random_buf(buf, n); 164c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 165c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 166c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif /* } !_EVENT_HAVE_ARC4RANDOM */ 167c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 168390dd3d21c5b92dda139da744edae7093d70fc9bMark Wielaardvoid 169c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_get_bytes(void *buf, size_t n) 170c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 171c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard ev_arc4random_buf(buf, n); 172c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 173c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 174c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardvoid 175c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaardevutil_secure_rng_add_bytes(const char *buf, size_t n) 176c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard{ 177c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#if !defined(__BIONIC__) /* bionic and OpenBSD removed this; it's a no-op in their current implementation. */ 178c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard arc4random_addrandom((unsigned char*)buf, 179c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard n>(size_t)INT_MAX ? INT_MAX : (int)n); 180c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard#endif 181c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard} 182c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard 183c5da7c9e08c2bdb6dba8e115dcc09ed51a07f0e4Mark Wielaard