14 #define CRYPTO_RAND_PRIVATE
24 #include "lib/crypt_ops/compat_openssl.h"
46 DISABLE_GCC_WARNING(
"-Wredundant-decls")
47 #include <openssl/rand.h>
48 #include <openssl/sha.h>
49 ENABLE_GCC_WARNING(
"-Wredundant-decls")
58 #if __GNUC__ && GCC_VERSION >= 402
59 #if GCC_VERSION >= 406
60 #pragma GCC diagnostic pop
62 #pragma GCC diagnostic warning "-Wredundant-decls"
69 #ifdef HAVE_SYS_FCNTL_H
70 #include <sys/fcntl.h>
72 #ifdef HAVE_SYS_STAT_H
78 #ifdef HAVE_SYS_SYSCALL_H
79 #include <sys/syscall.h>
81 #ifdef HAVE_SYS_RANDOM_H
82 #include <sys/random.h>
94 #define ADD_ENTROPY 32
99 #define MAX_DNS_LABEL_SIZE 63
104 #define MAX_STRONGEST_RAND_SIZE 256
117 #ifdef TOR_UNIT_TESTS
118 int break_strongest_rng_syscall = 0;
119 int break_strongest_rng_fallback = 0;
138 #ifdef TOR_UNIT_TESTS
139 if (break_strongest_rng_syscall)
144 static int provider_set = 0;
145 static HCRYPTPROV provider;
148 if (!CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
149 CRYPT_VERIFYCONTEXT)) {
150 log_notice(
LD_CRYPTO,
"Unable to set Windows CryptoAPI provider [1].");
155 if (!CryptGenRandom(provider, out_len, out)) {
156 log_notice(
LD_CRYPTO,
"Unable get entropy from the Windows CryptoAPI.");
161 #elif defined(__linux__) && defined(SYS_getrandom)
162 static int getrandom_works = 1;
180 if (PREDICT_LIKELY(getrandom_works)) {
186 const unsigned int flags = 0;
188 ret = syscall(SYS_getrandom, out, out_len, flags);
189 }
while (ret == -1 && ((errno == EINTR) ||(errno == EAGAIN)));
191 if (PREDICT_UNLIKELY(ret == -1)) {
197 if (errno == ENOSYS) {
198 log_notice(
LD_CRYPTO,
"Can't get entropy from getrandom()."
199 " You are running a version of Tor built to support"
200 " getrandom(), but the kernel doesn't implement this"
201 " function--probably because it is too old?"
202 " Trying fallback method instead.");
204 log_notice(
LD_CRYPTO,
"Can't get entropy from getrandom(): %s."
205 " Trying fallback method instead.",
219 #elif defined(HAVE_GETENTROPY)
223 return getentropy(out, out_len);
241 #ifdef TOR_UNIT_TESTS
242 if (break_strongest_rng_fallback)
252 static const char *filenames[] = {
253 "/dev/srandom",
"/dev/urandom",
"/dev/random", NULL
258 for (i = 0; filenames[i]; ++i) {
259 log_debug(
LD_FS,
"Considering %s as entropy source", filenames[i]);
262 log_info(
LD_CRYPTO,
"Reading entropy from \"%s\"", filenames[i]);
269 "Error reading from entropy source %s (read only %lu bytes).",
291 static const size_t sanity_min_size = 16;
292 static const int max_attempts = 3;
304 for (
int i = 0; i < max_attempts; i++) {
313 "Cannot get strong entropy: no entropy source found.");
329 log_warn(
LD_CRYPTO,
"Strong OS entropy returned all zero buffer.");
352 #define DLEN DIGEST512_LEN
362 memset(inp, 0,
sizeof(inp));
363 #ifdef ENABLE_OPENSSL
364 RAND_bytes(inp, DLEN);
367 PK11_GenerateRandom(inp+DLEN, DLEN);
371 log_err(
LD_CRYPTO,
"Failed to load strong entropy when generating an "
372 "important key. Exiting.");
377 if (out_len >= DLEN) {
383 memcpy(out, tmp, out_len);
392 #ifdef ENABLE_OPENSSL
398 crypto_seed_openssl_rng(
void)
400 int rand_poll_ok = 0, load_entropy_ok = 0;
406 rand_poll_ok = RAND_poll();
407 if (rand_poll_ok == 0)
408 log_warn(
LD_CRYPTO,
"RAND_poll() failed.");
411 if (load_entropy_ok) {
412 RAND_seed(buf,
sizeof(buf));
417 if ((rand_poll_ok || load_entropy_ok) && RAND_status() == 1)
430 crypto_seed_nss_rng(
void)
435 if (load_entropy_ok) {
436 if (PK11_RandomUpdate(buf,
sizeof(buf)) != SECSuccess) {
443 return load_entropy_ok ? 0 : -1;
456 if (crypto_seed_nss_rng() < 0)
460 #ifdef ENABLE_OPENSSL
461 if (crypto_seed_openssl_rng() < 0)
499 SECStatus s = PK11_GenerateRandom((
unsigned char*)to, (
int)n);
500 if (s != SECSuccess) {
511 tor_assert(PR_GetError() == SEC_ERROR_INVALID_ARGS && n > BUFLEN);
512 unsigned char buf[BUFLEN];
513 s = PK11_GenerateRandom(buf, BUFLEN);
524 int r = RAND_bytes((
unsigned char*)to, (
int)n);
555 char *result, *rand_bytes;
556 int randlen, rand_bytes_len;
557 size_t resultlen, prefixlen;
561 if (min_rand_len > max_rand_len)
562 min_rand_len = max_rand_len;
566 prefixlen = strlen(prefix);
567 resultlen = prefixlen + strlen(suffix) + randlen + 16;
569 rand_bytes_len = ((randlen*5)+7)/8;
570 if (rand_bytes_len % 5)
571 rand_bytes_len += 5 - (rand_bytes_len%5);
572 rand_bytes = tor_malloc(rand_bytes_len);
575 result = tor_malloc(resultlen);
576 memcpy(result, prefix, prefixlen);
578 rand_bytes, rand_bytes_len);
580 strlcpy(result+prefixlen+randlen, suffix, resultlen-(prefixlen+randlen));
592 int len = smartlist_len(sl);
609 for (i = smartlist_len(sl)-1; i > 0; --i) {
620 #ifdef ENABLE_OPENSSL
621 RAND_METHOD *default_method;
622 default_method = RAND_OpenSSL();
623 if (RAND_get_rand_method() != default_method) {
624 log_notice(
LD_CRYPTO,
"It appears that one of our engines has provided "
625 "a replacement the OpenSSL RNG. Resetting it to the default "
627 RAND_set_rand_method(default_method);
void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen)
Header for compat_string.c.
void crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len)
crypto_xof_t * crypto_xof_new(void)
void crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len)
Headers for crypto_digest.c.
int crypto_digest512(char *digest, const char *m, size_t len, digest_algorithm_t algorithm)
#define crypto_xof_free(xof)
Headers for crypto_nss_mgt.c.
int crypto_seed_rng(void)
#define MAX_DNS_LABEL_SIZE
static int crypto_strongest_rand_fallback(uint8_t *out, size_t out_len)
static int crypto_strongest_rand_syscall(uint8_t *out, size_t out_len)
STATIC int crypto_strongest_rand_raw(uint8_t *out, size_t out_len)
void crypto_strongest_rand_(uint8_t *out, size_t out_len)
char * crypto_random_hostname(int min_rand_len, int max_rand_len, const char *prefix, const char *suffix)
void crypto_rand(char *to, size_t n)
uint32_t crypto_rand_u32(void)
void crypto_rand_unmocked(char *to, size_t n)
void crypto_seed_weak_rng(tor_weak_rng_t *rng)
void smartlist_shuffle(smartlist_t *sl)
int crypto_force_rand_ssleay(void)
#define MAX_STRONGEST_RAND_SIZE
void * smartlist_choose(const smartlist_t *sl)
void crypto_strongest_rand(uint8_t *out, size_t out_len)
Common functions for using (pseudo-)random number generators.
int crypto_rand_int_range(unsigned int min, unsigned int max)
int crypto_rand_int(unsigned int max)
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
int safe_mem_is_zero(const void *mem, size_t sz)
Definitions for common sizes of cryptographic digests.
Wrappers for reading and writing data to files on disk.
ssize_t read_all_from_fd(int fd, char *buf, size_t count)
Headers for util_malloc.c.
Header file for sandbox.c.
#define sandbox_intern_string(s)
static void smartlist_swap(smartlist_t *sl, int idx1, int idx2)
Macros to implement mocking and selective exposure for the test code.
#define MOCK_IMPL(rv, funcname, arglist)
Macros to manage assertions, fatal and non-fatal.
Header for util_string.c.
void tor_init_weak_random(tor_weak_rng_t *rng, unsigned seed)