Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 
 

336 righe
8.6 KiB

  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. #if !defined(_GNU_SOURCE)
  15. #define _GNU_SOURCE /* needed for syscall() on Linux. */
  16. #endif
  17. #include <openssl/rand.h>
  18. #if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_FUCHSIA) && \
  19. !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
  20. #include <assert.h>
  21. #include <errno.h>
  22. #include <fcntl.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #if defined(OPENSSL_LINUX)
  27. #include <sys/syscall.h>
  28. #endif
  29. #include <openssl/thread.h>
  30. #include <openssl/mem.h>
  31. #include "internal.h"
  32. #include "../internal.h"
  33. #if defined(OPENSSL_LINUX)
  34. #if defined(OPENSSL_X86_64)
  35. #define EXPECTED_SYS_getrandom 318
  36. #elif defined(OPENSSL_X86)
  37. #define EXPECTED_SYS_getrandom 355
  38. #elif defined(OPENSSL_AARCH64)
  39. #define EXPECTED_SYS_getrandom 278
  40. #elif defined(OPENSSL_ARM)
  41. #define EXPECTED_SYS_getrandom 384
  42. #elif defined(OPENSSL_PPC64LE)
  43. #define EXPECTED_SYS_getrandom 359
  44. #endif
  45. #if defined(EXPECTED_SYS_getrandom)
  46. #define USE_SYS_getrandom
  47. #if defined(SYS_getrandom)
  48. #if SYS_getrandom != EXPECTED_SYS_getrandom
  49. #error "system call number for getrandom is not the expected value"
  50. #endif
  51. #else /* SYS_getrandom */
  52. #define SYS_getrandom EXPECTED_SYS_getrandom
  53. #endif /* SYS_getrandom */
  54. #endif /* EXPECTED_SYS_getrandom */
  55. #if !defined(GRND_NONBLOCK)
  56. #define GRND_NONBLOCK 1
  57. #endif
  58. #endif /* OPENSSL_LINUX */
  59. /* This file implements a PRNG by reading from /dev/urandom, optionally with a
  60. * buffer, which is unsafe across |fork|. */
  61. #define BUF_SIZE 4096
  62. /* rand_buffer contains unused, random bytes, some of which may have been
  63. * consumed already. */
  64. struct rand_buffer {
  65. size_t used;
  66. uint8_t rand[BUF_SIZE];
  67. };
  68. /* requested_lock is used to protect the |*_requested| variables. */
  69. static struct CRYPTO_STATIC_MUTEX requested_lock = CRYPTO_STATIC_MUTEX_INIT;
  70. /* The following constants are magic values of |urandom_fd|. */
  71. static const int kUnset = -2;
  72. static const int kHaveGetrandom = -3;
  73. /* urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by
  74. * |requested_lock|. */
  75. static int urandom_fd_requested = -2 /* kUnset */;
  76. /* urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. */
  77. static int urandom_fd = -2 /* kUnset */;
  78. /* urandom_buffering_requested is set by |RAND_enable_fork_unsafe_buffering|.
  79. * It's protected by |requested_lock|. */
  80. static int urandom_buffering_requested = 0;
  81. /* urandom_buffering controls whether buffering is enabled (1) or not (0). This
  82. * is protected by |once|. */
  83. static int urandom_buffering = 0;
  84. static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
  85. /* init_once initializes the state of this module to values previously
  86. * requested. This is the only function that modifies |urandom_fd| and
  87. * |urandom_buffering|, whose values may be read safely after calling the
  88. * once. */
  89. static void init_once(void) {
  90. CRYPTO_STATIC_MUTEX_lock_read(&requested_lock);
  91. urandom_buffering = urandom_buffering_requested;
  92. int fd = urandom_fd_requested;
  93. CRYPTO_STATIC_MUTEX_unlock_read(&requested_lock);
  94. #if defined(USE_SYS_getrandom)
  95. uint8_t dummy;
  96. long getrandom_ret =
  97. syscall(SYS_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK);
  98. if (getrandom_ret == 1) {
  99. urandom_fd = kHaveGetrandom;
  100. return;
  101. } else if (getrandom_ret == -1 && errno == EAGAIN) {
  102. fprintf(stderr,
  103. "getrandom indicates that the entropy pool has not been "
  104. "initialized. Rather than continue with poor entropy, this process "
  105. "will block until entropy is available.\n");
  106. do {
  107. getrandom_ret =
  108. syscall(SYS_getrandom, &dummy, sizeof(dummy), 0 /* no flags */);
  109. } while (getrandom_ret == -1 && errno == EINTR);
  110. if (getrandom_ret == 1) {
  111. urandom_fd = kHaveGetrandom;
  112. return;
  113. }
  114. }
  115. #endif /* USE_SYS_getrandom */
  116. if (fd == kUnset) {
  117. do {
  118. fd = open("/dev/urandom", O_RDONLY);
  119. } while (fd == -1 && errno == EINTR);
  120. }
  121. if (fd < 0) {
  122. abort();
  123. }
  124. int flags = fcntl(fd, F_GETFD);
  125. if (flags == -1) {
  126. /* Native Client doesn't implement |fcntl|. */
  127. if (errno != ENOSYS) {
  128. abort();
  129. }
  130. } else {
  131. flags |= FD_CLOEXEC;
  132. if (fcntl(fd, F_SETFD, flags) == -1) {
  133. abort();
  134. }
  135. }
  136. urandom_fd = fd;
  137. }
  138. void RAND_set_urandom_fd(int fd) {
  139. fd = dup(fd);
  140. if (fd < 0) {
  141. abort();
  142. }
  143. CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
  144. urandom_fd_requested = fd;
  145. CRYPTO_STATIC_MUTEX_unlock_write(&requested_lock);
  146. CRYPTO_once(&once, init_once);
  147. if (urandom_fd == kHaveGetrandom) {
  148. close(fd);
  149. } else if (urandom_fd != fd) {
  150. abort(); // Already initialized.
  151. }
  152. }
  153. void RAND_enable_fork_unsafe_buffering(int fd) {
  154. if (fd >= 0) {
  155. fd = dup(fd);
  156. if (fd < 0) {
  157. abort();
  158. }
  159. } else {
  160. fd = kUnset;
  161. }
  162. CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
  163. urandom_buffering_requested = 1;
  164. urandom_fd_requested = fd;
  165. CRYPTO_STATIC_MUTEX_unlock_write(&requested_lock);
  166. CRYPTO_once(&once, init_once);
  167. if (urandom_buffering != 1) {
  168. abort(); // Already initialized
  169. }
  170. if (fd >= 0) {
  171. if (urandom_fd == kHaveGetrandom) {
  172. close(fd);
  173. } else if (urandom_fd != fd) {
  174. abort(); // Already initialized.
  175. }
  176. }
  177. }
  178. static struct rand_buffer *get_thread_local_buffer(void) {
  179. struct rand_buffer *buf =
  180. CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF);
  181. if (buf != NULL) {
  182. return buf;
  183. }
  184. buf = OPENSSL_malloc(sizeof(struct rand_buffer));
  185. if (buf == NULL) {
  186. return NULL;
  187. }
  188. buf->used = BUF_SIZE; /* To trigger a |fill_with_entropy| on first use. */
  189. if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF, buf,
  190. OPENSSL_free)) {
  191. OPENSSL_free(buf);
  192. return NULL;
  193. }
  194. return buf;
  195. }
  196. #if defined(USE_SYS_getrandom) && defined(__has_feature)
  197. #if __has_feature(memory_sanitizer)
  198. void __msan_unpoison(void *, size_t);
  199. #endif
  200. #endif
  201. /* fill_with_entropy writes |len| bytes of entropy into |out|. It returns one
  202. * on success and zero on error. */
  203. static char fill_with_entropy(uint8_t *out, size_t len) {
  204. while (len > 0) {
  205. ssize_t r;
  206. if (urandom_fd == kHaveGetrandom) {
  207. #if defined(USE_SYS_getrandom)
  208. do {
  209. r = syscall(SYS_getrandom, out, len, 0 /* no flags */);
  210. } while (r == -1 && errno == EINTR);
  211. #if defined(__has_feature)
  212. #if __has_feature(memory_sanitizer)
  213. if (r > 0) {
  214. /* MSAN doesn't recognise |syscall| and thus doesn't notice that we
  215. * have initialised the output buffer. */
  216. __msan_unpoison(out, r);
  217. }
  218. #endif /* memory_sanitizer */
  219. #endif /*__has_feature */
  220. #else /* USE_SYS_getrandom */
  221. abort();
  222. #endif
  223. } else {
  224. do {
  225. r = read(urandom_fd, out, len);
  226. } while (r == -1 && errno == EINTR);
  227. }
  228. if (r <= 0) {
  229. return 0;
  230. }
  231. out += r;
  232. len -= r;
  233. }
  234. return 1;
  235. }
  236. /* read_from_buffer reads |requested| random bytes from the buffer into |out|,
  237. * refilling it if necessary to satisfy the request. */
  238. static void read_from_buffer(struct rand_buffer *buf,
  239. uint8_t *out, size_t requested) {
  240. size_t remaining = BUF_SIZE - buf->used;
  241. while (requested > remaining) {
  242. OPENSSL_memcpy(out, &buf->rand[buf->used], remaining);
  243. buf->used += remaining;
  244. out += remaining;
  245. requested -= remaining;
  246. if (!fill_with_entropy(buf->rand, BUF_SIZE)) {
  247. abort();
  248. return;
  249. }
  250. buf->used = 0;
  251. remaining = BUF_SIZE;
  252. }
  253. OPENSSL_memcpy(out, &buf->rand[buf->used], requested);
  254. buf->used += requested;
  255. }
  256. /* CRYPTO_sysrand puts |requested| random bytes into |out|. */
  257. void CRYPTO_sysrand(uint8_t *out, size_t requested) {
  258. if (requested == 0) {
  259. return;
  260. }
  261. CRYPTO_once(&once, init_once);
  262. if (urandom_buffering && requested < BUF_SIZE) {
  263. struct rand_buffer *buf = get_thread_local_buffer();
  264. if (buf != NULL) {
  265. read_from_buffer(buf, out, requested);
  266. return;
  267. }
  268. }
  269. if (!fill_with_entropy(out, requested)) {
  270. abort();
  271. }
  272. }
  273. #endif /* !OPENSSL_WINDOWS && !defined(OPENSSL_FUCHSIA) && \
  274. !BORINGSSL_UNSAFE_DETERMINISTIC_MODE */