1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* Copyright (c) 2014, Google Inc. 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Permission to use, copy, modify, and/or distribute this software for any 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * purpose with or without fee is hereby granted, provided that the above 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * copyright notice and this permission notice appear in all copies. 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/rand.h> 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley#include <limits.h> 18e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <string.h> 19e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 20e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <openssl/mem.h> 21e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 22e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "internal.h" 23e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include "../internal.h" 24e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 25e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 26e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* It's assumed that the operating system always has an unfailing source of 27e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * entropy which is accessed via |CRYPTO_sysrand|. (If the operating system 28e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * entropy source fails, it's up to |CRYPTO_sysrand| to abort the process—we 29e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * don't try to handle it.) 30e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 31e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * In addition, the hardware may provide a low-latency RNG. Intel's rdrand 32e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * instruction is the canonical example of this. When a hardware RNG is 33e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * available we don't need to worry about an RNG failure arising from fork()ing 34e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * the process or moving a VM, so we can keep thread-local RNG state and XOR 35e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * the hardware entropy in. 36e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * 37e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * (We assume that the OS entropy is safe from fork()ing and VM duplication. 38e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * This might be a bit of a leap of faith, esp on Windows, but there's nothing 39e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * that we can do about it.) */ 40e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 41e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* rand_thread_state contains the per-thread state for the RNG. This is only 42e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * used if the system has support for a hardware RNG. */ 43e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystruct rand_thread_state { 44e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint8_t key[32]; 45e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint64_t calls_used; 46e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley size_t bytes_used; 47e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley uint8_t partial_block[64]; 48e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley unsigned partial_block_used; 49e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley}; 50e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 51e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* kMaxCallsPerRefresh is the maximum number of |RAND_bytes| calls that we'll 52e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * serve before reading a new key from the operating system. This only applies 53e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * if we have a hardware RNG. */ 54e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const unsigned kMaxCallsPerRefresh = 1024; 55e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 56e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* kMaxBytesPerRefresh is the maximum number of bytes that we'll return from 57e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * |RAND_bytes| before reading a new key from the operating system. This only 58e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * applies if we have a hardware RNG. */ 59e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic const uint64_t kMaxBytesPerRefresh = 1024 * 1024; 60e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 61e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* rand_thread_state_free frees a |rand_thread_state|. This is called when a 62e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * thread exits. */ 63e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic void rand_thread_state_free(void *state) { 64e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (state == NULL) { 65e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return; 66e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 67e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 68e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley OPENSSL_cleanse(state, sizeof(struct rand_thread_state)); 69e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley OPENSSL_free(state); 70e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 71e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 72e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyextern void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, 73e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley const uint8_t key[32], const uint8_t nonce[8], 74e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley size_t counter); 75e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 76e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint RAND_bytes(uint8_t *buf, size_t len) { 77e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (len == 0) { 78e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return 1; 79e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 80e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 81e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (!CRYPTO_have_hwrand()) { 82e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley /* Without a hardware RNG to save us from address-space duplication, the OS 83e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * entropy is used directly. */ 84e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_sysrand(buf, len); 85e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return 1; 86e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 87e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 88e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley struct rand_thread_state *state = 89e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_RAND); 90e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (state == NULL) { 91e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state = OPENSSL_malloc(sizeof(struct rand_thread_state)); 92e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (state == NULL || 93e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley !CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_RAND, state, 94e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley rand_thread_state_free)) { 95e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_sysrand(buf, len); 96e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return 1; 97e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 98e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 9953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley memset(state->partial_block, 0, sizeof(state->partial_block)); 100e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->calls_used = kMaxCallsPerRefresh; 101e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 102e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 103e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (state->calls_used >= kMaxCallsPerRefresh || 104e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->bytes_used >= kMaxBytesPerRefresh) { 105e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_sysrand(state->key, sizeof(state->key)); 106e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->calls_used = 0; 107e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->bytes_used = 0; 108e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->partial_block_used = sizeof(state->partial_block); 109e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 110e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 111e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_hwrand(buf, len); 112e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 113e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (len >= sizeof(state->partial_block)) { 114e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley size_t remaining = len; 115e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley while (remaining > 0) { 116e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley // kMaxBytesPerCall is only 2GB, while ChaCha can handle 256GB. But this 117e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley // is sufficient and easier on 32-bit. 118e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley static const size_t kMaxBytesPerCall = 0x80000000; 119e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley size_t todo = remaining; 120e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (todo > kMaxBytesPerCall) { 121e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley todo = kMaxBytesPerCall; 122e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 123e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_chacha_20(buf, buf, todo, state->key, 124e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley (uint8_t *)&state->calls_used, 0); 125e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley buf += todo; 126e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley remaining -= todo; 127e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->calls_used++; 128e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 129e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } else { 130e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley if (sizeof(state->partial_block) - state->partial_block_used < len) { 131e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley CRYPTO_chacha_20(state->partial_block, state->partial_block, 132e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley sizeof(state->partial_block), state->key, 133e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley (uint8_t *)&state->calls_used, 0); 134e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->partial_block_used = 0; 135e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 136e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 137e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley unsigned i; 138e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley for (i = 0; i < len; i++) { 139e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley buf[i] ^= state->partial_block[state->partial_block_used++]; 140e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 141e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->calls_used++; 142e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley } 143e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley state->bytes_used += len; 144e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley 145e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley return 1; 146e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley} 147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 148d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint RAND_pseudo_bytes(uint8_t *buf, size_t len) { 149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return RAND_bytes(buf, len); 150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 151d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 152d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid RAND_seed(const void *buf, int num) {} 153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 15453b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langleyint RAND_load_file(const char *path, long num) { 15553b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley if (num < 0) { /* read the "whole file" */ 15653b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley return 1; 15753b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley } else if (num <= INT_MAX) { 15853b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley return (int) num; 15953b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley } else { 16053b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley return INT_MAX; 16153b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley } 16253b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley} 16353b272a2813a0b11f107d77100ff8805ada8fbd2Adam Langley 164d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyvoid RAND_add(const void *buf, int num, double entropy) {} 165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 166d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint RAND_poll(void) { 167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 168d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 169f7e890d94bfb2ecad87621eed301e1897b5a6aefAdam Langley 170f7e890d94bfb2ecad87621eed301e1897b5a6aefAdam Langleyint RAND_status(void) { 171f7e890d94bfb2ecad87621eed301e1897b5a6aefAdam Langley return 1; 172f7e890d94bfb2ecad87621eed301e1897b5a6aefAdam Langley} 173