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 #include <assert.h> 18 #include <limits.h> 19 #include <string.h> 20 21 #include <openssl/chacha.h> 22 #include <openssl/cpu.h> 23 #include <openssl/mem.h> 24 25 #include "internal.h" 26 #include "../internal.h" 27 28 29 /* It's assumed that the operating system always has an unfailing source of 30 * entropy which is accessed via |CRYPTO_sysrand|. (If the operating system 31 * entropy source fails, it's up to |CRYPTO_sysrand| to abort the process—we 32 * don't try to handle it.) 33 * 34 * In addition, the hardware may provide a low-latency RNG. Intel's rdrand 35 * instruction is the canonical example of this. When a hardware RNG is 36 * available we don't need to worry about an RNG failure arising from fork()ing 37 * the process or moving a VM, so we can keep thread-local RNG state and XOR 38 * the hardware entropy in. 39 * 40 * (We assume that the OS entropy is safe from fork()ing and VM duplication. 41 * This might be a bit of a leap of faith, esp on Windows, but there's nothing 42 * that we can do about it.) */ 43 44 /* rand_thread_state contains the per-thread state for the RNG. This is only 45 * used if the system has support for a hardware RNG. */ 46 struct rand_thread_state { 47 uint8_t key[32]; 48 uint64_t calls_used; 49 size_t bytes_used; 50 uint8_t partial_block[64]; 51 unsigned partial_block_used; 52 }; 53 54 /* kMaxCallsPerRefresh is the maximum number of |RAND_bytes| calls that we'll 55 * serve before reading a new key from the operating system. This only applies 56 * if we have a hardware RNG. */ 57 static const unsigned kMaxCallsPerRefresh = 1024; 58 59 /* kMaxBytesPerRefresh is the maximum number of bytes that we'll return from 60 * |RAND_bytes| before reading a new key from the operating system. This only 61 * applies if we have a hardware RNG. */ 62 static const uint64_t kMaxBytesPerRefresh = 1024 * 1024; 63 64 /* rand_thread_state_free frees a |rand_thread_state|. This is called when a 65 * thread exits. */ rand_thread_state_free(void * state)66 static void rand_thread_state_free(void *state) { 67 if (state == NULL) { 68 return; 69 } 70 71 OPENSSL_cleanse(state, sizeof(struct rand_thread_state)); 72 OPENSSL_free(state); 73 } 74 75 #if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) 76 77 /* These functions are defined in asm/rdrand-x86_64.pl */ 78 extern int CRYPTO_rdrand(uint8_t out[8]); 79 extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len); 80 have_rdrand(void)81 static int have_rdrand(void) { 82 return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0; 83 } 84 hwrand(uint8_t * buf,size_t len)85 static int hwrand(uint8_t *buf, size_t len) { 86 if (!have_rdrand()) { 87 return 0; 88 } 89 90 const size_t len_multiple8 = len & ~7; 91 if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) { 92 return 0; 93 } 94 len -= len_multiple8; 95 96 if (len != 0) { 97 assert(len < 8); 98 99 uint8_t rand_buf[8]; 100 if (!CRYPTO_rdrand(rand_buf)) { 101 return 0; 102 } 103 memcpy(buf + len_multiple8, rand_buf, len); 104 } 105 106 return 1; 107 } 108 109 #else 110 hwrand(uint8_t * buf,size_t len)111 static int hwrand(uint8_t *buf, size_t len) { 112 return 0; 113 } 114 115 #endif 116 RAND_bytes(uint8_t * buf,size_t len)117 int RAND_bytes(uint8_t *buf, size_t len) { 118 if (len == 0) { 119 return 1; 120 } 121 122 if (!hwrand(buf, len)) { 123 /* Without a hardware RNG to save us from address-space duplication, the OS 124 * entropy is used directly. */ 125 CRYPTO_sysrand(buf, len); 126 return 1; 127 } 128 129 struct rand_thread_state *state = 130 CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_RAND); 131 if (state == NULL) { 132 state = OPENSSL_malloc(sizeof(struct rand_thread_state)); 133 if (state == NULL || 134 !CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_RAND, state, 135 rand_thread_state_free)) { 136 CRYPTO_sysrand(buf, len); 137 return 1; 138 } 139 140 memset(state->partial_block, 0, sizeof(state->partial_block)); 141 state->calls_used = kMaxCallsPerRefresh; 142 } 143 144 if (state->calls_used >= kMaxCallsPerRefresh || 145 state->bytes_used >= kMaxBytesPerRefresh) { 146 CRYPTO_sysrand(state->key, sizeof(state->key)); 147 state->calls_used = 0; 148 state->bytes_used = 0; 149 state->partial_block_used = sizeof(state->partial_block); 150 } 151 152 if (len >= sizeof(state->partial_block)) { 153 size_t remaining = len; 154 while (remaining > 0) { 155 /* kMaxBytesPerCall is only 2GB, while ChaCha can handle 256GB. But this 156 * is sufficient and easier on 32-bit. */ 157 static const size_t kMaxBytesPerCall = 0x80000000; 158 size_t todo = remaining; 159 if (todo > kMaxBytesPerCall) { 160 todo = kMaxBytesPerCall; 161 } 162 uint8_t nonce[12]; 163 memset(nonce, 0, 4); 164 memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used)); 165 CRYPTO_chacha_20(buf, buf, todo, state->key, nonce, 0); 166 buf += todo; 167 remaining -= todo; 168 state->calls_used++; 169 } 170 } else { 171 if (sizeof(state->partial_block) - state->partial_block_used < len) { 172 uint8_t nonce[12]; 173 memset(nonce, 0, 4); 174 memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used)); 175 CRYPTO_chacha_20(state->partial_block, state->partial_block, 176 sizeof(state->partial_block), state->key, nonce, 0); 177 state->partial_block_used = 0; 178 } 179 180 unsigned i; 181 for (i = 0; i < len; i++) { 182 buf[i] ^= state->partial_block[state->partial_block_used++]; 183 } 184 state->calls_used++; 185 } 186 state->bytes_used += len; 187 188 return 1; 189 } 190 RAND_pseudo_bytes(uint8_t * buf,size_t len)191 int RAND_pseudo_bytes(uint8_t *buf, size_t len) { 192 return RAND_bytes(buf, len); 193 } 194 RAND_seed(const void * buf,int num)195 void RAND_seed(const void *buf, int num) { 196 /* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed 197 * file descriptors etc will be opened. */ 198 uint8_t unused; 199 RAND_bytes(&unused, sizeof(unused)); 200 } 201 RAND_load_file(const char * path,long num)202 int RAND_load_file(const char *path, long num) { 203 if (num < 0) { /* read the "whole file" */ 204 return 1; 205 } else if (num <= INT_MAX) { 206 return (int) num; 207 } else { 208 return INT_MAX; 209 } 210 } 211 RAND_add(const void * buf,int num,double entropy)212 void RAND_add(const void *buf, int num, double entropy) {} 213 RAND_egd(const char * path)214 int RAND_egd(const char *path) { 215 return 255; 216 } 217 RAND_poll(void)218 int RAND_poll(void) { 219 return 1; 220 } 221 RAND_status(void)222 int RAND_status(void) { 223 return 1; 224 } 225 226 static const struct rand_meth_st kSSLeayMethod = { 227 RAND_seed, 228 RAND_bytes, 229 RAND_cleanup, 230 RAND_add, 231 RAND_pseudo_bytes, 232 RAND_status, 233 }; 234 RAND_SSLeay(void)235 RAND_METHOD *RAND_SSLeay(void) { 236 return (RAND_METHOD*) &kSSLeayMethod; 237 } 238 RAND_set_rand_method(const RAND_METHOD * method)239 void RAND_set_rand_method(const RAND_METHOD *method) {} 240