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 processwe 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. */ 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 !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) 77 78 /* These functions are defined in asm/rdrand-x86_64.pl */ 79 extern int CRYPTO_rdrand(uint8_t out[8]); 80 extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len); 81 82 static int have_rdrand(void) { 83 return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0; 84 } 85 86 static int hwrand(uint8_t *buf, size_t len) { 87 if (!have_rdrand()) { 88 return 0; 89 } 90 91 const size_t len_multiple8 = len & ~7; 92 if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) { 93 return 0; 94 } 95 len -= len_multiple8; 96 97 if (len != 0) { 98 assert(len < 8); 99 100 uint8_t rand_buf[8]; 101 if (!CRYPTO_rdrand(rand_buf)) { 102 return 0; 103 } 104 OPENSSL_memcpy(buf + len_multiple8, rand_buf, len); 105 } 106 107 return 1; 108 } 109 110 #else 111 112 static int hwrand(uint8_t *buf, size_t len) { 113 return 0; 114 } 115 116 #endif 117 118 int RAND_bytes(uint8_t *buf, size_t len) { 119 if (len == 0) { 120 return 1; 121 } 122 123 if (!hwrand(buf, len)) { 124 /* Without a hardware RNG to save us from address-space duplication, the OS 125 * entropy is used directly. */ 126 CRYPTO_sysrand(buf, len); 127 return 1; 128 } 129 130 struct rand_thread_state *state = 131 CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_RAND); 132 if (state == NULL) { 133 state = OPENSSL_malloc(sizeof(struct rand_thread_state)); 134 if (state == NULL || 135 !CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_RAND, state, 136 rand_thread_state_free)) { 137 CRYPTO_sysrand(buf, len); 138 return 1; 139 } 140 141 OPENSSL_memset(state->partial_block, 0, sizeof(state->partial_block)); 142 state->calls_used = kMaxCallsPerRefresh; 143 } 144 145 if (state->calls_used >= kMaxCallsPerRefresh || 146 state->bytes_used >= kMaxBytesPerRefresh) { 147 CRYPTO_sysrand(state->key, sizeof(state->key)); 148 state->calls_used = 0; 149 state->bytes_used = 0; 150 state->partial_block_used = sizeof(state->partial_block); 151 } 152 153 if (len >= sizeof(state->partial_block)) { 154 size_t remaining = len; 155 while (remaining > 0) { 156 /* kMaxBytesPerCall is only 2GB, while ChaCha can handle 256GB. But this 157 * is sufficient and easier on 32-bit. */ 158 static const size_t kMaxBytesPerCall = 0x80000000; 159 size_t todo = remaining; 160 if (todo > kMaxBytesPerCall) { 161 todo = kMaxBytesPerCall; 162 } 163 uint8_t nonce[12]; 164 OPENSSL_memset(nonce, 0, 4); 165 OPENSSL_memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used)); 166 CRYPTO_chacha_20(buf, buf, todo, state->key, nonce, 0); 167 buf += todo; 168 remaining -= todo; 169 state->calls_used++; 170 } 171 } else { 172 if (sizeof(state->partial_block) - state->partial_block_used < len) { 173 uint8_t nonce[12]; 174 OPENSSL_memset(nonce, 0, 4); 175 OPENSSL_memcpy(nonce + 4, &state->calls_used, sizeof(state->calls_used)); 176 CRYPTO_chacha_20(state->partial_block, state->partial_block, 177 sizeof(state->partial_block), state->key, nonce, 0); 178 state->partial_block_used = 0; 179 } 180 181 unsigned i; 182 for (i = 0; i < len; i++) { 183 buf[i] ^= state->partial_block[state->partial_block_used++]; 184 } 185 state->calls_used++; 186 } 187 state->bytes_used += len; 188 189 return 1; 190 } 191 192 int RAND_pseudo_bytes(uint8_t *buf, size_t len) { 193 return RAND_bytes(buf, len); 194 } 195 196 void RAND_seed(const void *buf, int num) { 197 /* OpenSSH calls |RAND_seed| before jailing on the assumption that any needed 198 * file descriptors etc will be opened. */ 199 uint8_t unused; 200 RAND_bytes(&unused, sizeof(unused)); 201 } 202 203 int RAND_load_file(const char *path, long num) { 204 if (num < 0) { /* read the "whole file" */ 205 return 1; 206 } else if (num <= INT_MAX) { 207 return (int) num; 208 } else { 209 return INT_MAX; 210 } 211 } 212 213 const char *RAND_file_name(char *buf, size_t num) { return NULL; } 214 215 void RAND_add(const void *buf, int num, double entropy) {} 216 217 int RAND_egd(const char *path) { 218 return 255; 219 } 220 221 int RAND_poll(void) { 222 return 1; 223 } 224 225 int RAND_status(void) { 226 return 1; 227 } 228 229 static const struct rand_meth_st kSSLeayMethod = { 230 RAND_seed, 231 RAND_bytes, 232 RAND_cleanup, 233 RAND_add, 234 RAND_pseudo_bytes, 235 RAND_status, 236 }; 237 238 RAND_METHOD *RAND_SSLeay(void) { 239 return (RAND_METHOD*) &kSSLeayMethod; 240 } 241 242 void RAND_set_rand_method(const RAND_METHOD *method) {} 243 244 void RAND_cleanup(void) {} 245