You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ottery-internal.h 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /* Libottery by Nick Mathewson.
  2. This software has been dedicated to the public domain under the CC0
  3. public domain dedication.
  4. To the extent possible under law, the person who associated CC0 with
  5. libottery has waived all copyright and related or neighboring rights
  6. to libottery.
  7. You should have received a copy of the CC0 legalcode along with this
  8. work in doc/cc0.txt. If not, see
  9. <http://creativecommons.org/publicdomain/zero/1.0/>.
  10. */
  11. #ifndef OTTERY_INTERNAL_H_HEADER_INCLUDED_
  12. #define OTTERY_INTERNAL_H_HEADER_INCLUDED_
  13. #include <stdint.h>
  14. #include <sys/types.h>
  15. #ifdef BUILD_RSPAMD
  16. #include "config.h"
  17. #endif
  18. #include "ottery-threading.h"
  19. /**
  20. * Version number for Libottery. The first three bytes are the major number,
  21. * minor number, and patch-level respectively. The final byte is 0 for a
  22. * released version, and nonzero otherwise.
  23. */
  24. #define OTTERY_VERSION 0x00000001
  25. /**
  26. * Human-readable string representing the Libottery version.
  27. */
  28. #define OTTERY_VERSION_STRING "0.0.0"
  29. /** Largest possible state_bytes value. */
  30. #define MAX_STATE_BYTES 64
  31. /** Largest possible state_len value. */
  32. #define MAX_STATE_LEN 256
  33. /** Largest possible output_len value. */
  34. #define MAX_OUTPUT_LEN 1024
  35. /**
  36. * @brief Flags for external entropy sources.
  37. *
  38. * @{ */
  39. /** An RNG that probably provides strong entropy. */
  40. #define OTTERY_ENTROPY_FL_STRONG 0x000001
  41. /** An RNG that runs very quickly. */
  42. #define OTTERY_ENTROPY_FL_FAST 0x000002
  43. /** @} */
  44. /**
  45. * @brief Identifying external entropy domains.
  46. */
  47. /** An RNG provided by the operating system. */
  48. #define OTTERY_ENTROPY_DOM_OS 0x000100
  49. /** An RNG provided by the CPU. */
  50. #define OTTERY_ENTROPY_DOM_CPU 0x000200
  51. /** An EGD-style entropy source */
  52. #define OTTERY_ENTROPY_DOM_EGD 0x000400
  53. /** @} */
  54. #define OTTERY_ENTROPY_FLAG_MASK 0x000000ff
  55. #define OTTERY_ENTROPY_DOM_MASK 0x0000ff00
  56. #define OTTERY_ENTROPY_ALL_SOURCES 0x0fff0000
  57. struct sockaddr;
  58. /** Configuration for the strong RNG the we use for entropy. */
  59. struct ottery_entropy_config {
  60. /** The filename to use as /dev/urandom. Ignored if this
  61. * is not a unix-like operating system. If this is NULL, we use
  62. * the default value. */
  63. const char *urandom_fname;
  64. /** An fd to use to access /dev/urandom. -1 if not set. Overrides
  65. * urandom_fname. */
  66. int urandom_fd;
  67. /** True if urandom_fd has been set. */
  68. unsigned urandom_fd_is_set;
  69. /** Socket for egd */
  70. const struct sockaddr *egd_sockaddr;
  71. /** Socklen for egd_sockaddr. */
  72. int egd_socklen;
  73. /** Bitmask of sources to disable. */
  74. uint32_t disabled_sources;
  75. /** Bitmask of sources to consider weak. */
  76. uint32_t weak_sources;
  77. /** If true, we don't enforce that urandom_fname must be a device file.
  78. * This is for testing, and is not exposed to user code.
  79. */
  80. unsigned allow_nondev_urandom;
  81. };
  82. struct ottery_entropy_state {
  83. /* Cached value for the inode of the urandom device. If this value changes,
  84. * we assume that somebody messed with the fd by accident. */
  85. uint64_t urandom_fd_inode;
  86. };
  87. /**
  88. * Return the buffer size to allocate when getting at least n bytes from each
  89. * entropy source. We might not actually need so many. */
  90. size_t ottery_get_entropy_bufsize_(size_t n);
  91. /**
  92. * Interface to underlying strong RNGs. If this were fast, we'd just use it
  93. * for everything, and forget about having a userspace PRNG. Unfortunately,
  94. * it typically isn't.
  95. *
  96. * @param config A correctly set-up ottery_entropy_config.
  97. * @param state A correctly set-up ottery_entropy_state.
  98. * @param require_flags Only run entropy sources with *all* of these
  99. * OTTERY_ENTROPY_* flags set. Set this to 0 to use all the sources
  100. * that work.
  101. * @param bytes A buffer to receive random bytes.
  102. * @param n The number of bytes to try to get from each entropy source.
  103. * @param bufsize The number of bytes available in the buffer; modified
  104. * to hold the number of bytes actually written.
  105. * @param flags_out Set to a bitwise OR of all of the OTTERY_ENTROPY_* flags
  106. * for sources in the result.
  107. * @return Zero on success, or an error code on failure. On failure, it is not
  108. * safe to treat the contents of the buffer as random at all.
  109. */
  110. int ottery_get_entropy_(const struct ottery_entropy_config *config,
  111. struct ottery_entropy_state *state,
  112. uint32_t require_flags,
  113. uint8_t *bytes, size_t n, size_t *bufsize,
  114. uint32_t *flags_out);
  115. /**
  116. * Clear all bytes stored in a structure. Unlike memset, the compiler is not
  117. * going to optimize this out of existence because the target is about to go
  118. * out of scope.
  119. *
  120. * @param mem Pointer to the memory to erase.
  121. * @param len The number of bytes to erase.
  122. */
  123. void ottery_memclear_(void *mem, size_t len);
  124. /**
  125. * Information on a single pseudorandom function that we can use to generate
  126. * a bytestream which (we hope) an observer can't distinguish from random
  127. * bytes.
  128. *
  129. * Broadly speaking, every ottery_prf has an underlying function from an
  130. * (state_bytes)-byte state and a 4 byte counter to an output_len-byte
  131. * output block.
  132. **/
  133. struct ottery_prf {
  134. /** The name of this algorithm. */
  135. const char *name;
  136. /** The name of the implementation of this algorithm*/
  137. const char *impl;
  138. /** The name of the flavor of the implementation of this algorithm*/
  139. const char *flav;
  140. /** The length of the object that's used to hold the state (keys, nonces,
  141. * subkeys as needed, etc) for this PRF. This can be longer than
  142. * state_bytes because of key expansion or structure padding. It must be
  143. * no greater than MAX_STATE_LEN. */
  144. unsigned state_len;
  145. /** The number of bytes used to generate a state object. It must be no
  146. * greater than MAX_STATE_BYTES. It must be no grater than output_len. */
  147. unsigned state_bytes;
  148. /** The number of bytes generated by a single call to the generate
  149. * function. It must be no larger than MAX_OUTPUT_LEN.
  150. */
  151. unsigned output_len;
  152. /** Bitmask of CPU flags required to run this PRF. */
  153. uint32_t required_cpucap;
  154. /** Pointer to a function to initialize a state structure for the PRF.
  155. *
  156. * @param state An object of size at least (state_len) that will
  157. * hold the state and any derived values. It must be aligned to
  158. * a 16-byte boundary.
  159. * @param bytes An array of (state_bytes) random bytes.
  160. */
  161. void (*setup)(void *state, const uint8_t *bytes);
  162. /** Pointer to a function that calculates the PRF.
  163. *
  164. * @param state A state object previously initialized by the setup
  165. * function.
  166. * @param output An array of (output_len) bytes in which to store the
  167. * result of the function
  168. * @param idx A counter value for the function.
  169. */
  170. void (*generate)(void *state, uint8_t *output, uint32_t idx);
  171. };
  172. /**
  173. * Evaluate the condition 'x', while hinting to the compiler that it is
  174. * likely to be false.
  175. */
  176. #ifdef __GNUC__
  177. #define UNLIKELY(x) __builtin_expect((x), 0)
  178. #else
  179. #define UNLIKELY(x) (x)
  180. #endif
  181. #ifdef OTTERY_INTERNAL
  182. struct ottery_config {
  183. /** The PRF that we should use. If NULL, we use the default. */
  184. const struct ottery_prf *impl;
  185. /** Configuration for how we will set up our entropy sources. */
  186. struct ottery_entropy_config entropy_config;
  187. };
  188. #define ottery_state_nolock ottery_state
  189. struct RSPAMD_ALIGNED(16) ottery_state {
  190. /**
  191. * Holds up to prf.output_len bytes that have been generated by the
  192. * pseudorandom function. */
  193. uint8_t buffer[MAX_OUTPUT_LEN] RSPAMD_ALIGNED(16);
  194. /**
  195. * Holds the state information (typically nonces and keys) used by the
  196. * pseudorandom function. */
  197. uint8_t state[MAX_STATE_LEN] RSPAMD_ALIGNED(16);
  198. /**
  199. * Parameters and function pointers for the cryptographic pseudorandom
  200. * function that we're using. */
  201. struct ottery_prf prf;
  202. /**
  203. * Index of the *next* block counter to use when generating random bytes
  204. * with prf. When this equals or exceeds prf.stir_after, we should stir
  205. * the PRNG. */
  206. uint32_t block_counter;
  207. /**
  208. * Magic number; used to tell whether this state is initialized.
  209. */
  210. uint32_t magic;
  211. /**
  212. * Index of the next byte in (buffer) to yield to the user.
  213. *
  214. * Invariant: this is less than prf.output_len. */
  215. uint16_t pos;
  216. /**
  217. * The pid of the process in which this PRF was most recently seeded
  218. * from the OS. We use this to avoid use-after-fork problems; see
  219. * ottery_st_rand_lock_and_check(). */
  220. pid_t pid;
  221. /**
  222. * Combined flags_out results from all calls to the entropy source that
  223. * have influenced our current state.
  224. */
  225. uint32_t entropy_src_flags;
  226. /**
  227. * flags_out result from our last call to the entropy source.
  228. */
  229. uint32_t last_entropy_flags;
  230. /**
  231. * Configuration for the entropy source.
  232. */
  233. struct ottery_entropy_config entropy_config;
  234. /** State for the entropy source.
  235. */
  236. struct ottery_entropy_state entropy_state;
  237. /**
  238. * @brief Locks for this structure.
  239. *
  240. * This lock will not necessarily be recursive. It's probably a
  241. * spinlock.
  242. *
  243. * @{
  244. */
  245. DECL_LOCK(mutex)
  246. /**@}*/
  247. };
  248. #endif
  249. struct ottery_config;
  250. /**
  251. * For testing: manually supply a PRF.
  252. */
  253. void ottery_config_set_manual_prf_(struct ottery_config *cfg,
  254. const struct ottery_prf *prf);
  255. /** Called when a fatal error has occurred: Die horribly, or invoke
  256. * ottery_fatal_handler. */
  257. void ottery_fatal_error_(int error);
  258. #define OTTERY_CPUCAP_SIMD (1<<0)
  259. #define OTTERY_CPUCAP_SSSE3 (1<<1)
  260. #define OTTERY_CPUCAP_AES (1<<2)
  261. #define OTTERY_CPUCAP_RAND (1<<3)
  262. /** Return a mask of OTTERY_CPUCAP_* for what the CPU will offer us. */
  263. uint32_t ottery_get_cpu_capabilities_(void);
  264. /** Tell ottery_get_cpu_capabilities to never report certain capabilities as
  265. * present. */
  266. void ottery_disable_cpu_capabilities_(uint32_t disable);
  267. /**
  268. * @brief pure-C portable ChaCha implementations.
  269. *
  270. * @{
  271. */
  272. extern const struct ottery_prf ottery_prf_chacha8_merged_;
  273. extern const struct ottery_prf ottery_prf_chacha12_merged_;
  274. extern const struct ottery_prf ottery_prf_chacha20_merged_;
  275. #ifdef BUILD_RSPAMD
  276. #ifdef __x86_64__
  277. extern const struct ottery_prf ottery_prf_aes_cryptobox_;
  278. #endif
  279. extern const struct ottery_prf ottery_prf_chacha20_cryptobox_;
  280. #endif
  281. /**@}*/
  282. /**
  283. * @brief SIMD-basd ChaCha implementations.
  284. *
  285. * These are much, much faster.
  286. *
  287. * @{ */
  288. #ifdef HAVE_SIMD_CHACHA
  289. extern const struct ottery_prf ottery_prf_chacha8_krovetz_1_;
  290. extern const struct ottery_prf ottery_prf_chacha12_krovetz_1_;
  291. extern const struct ottery_prf ottery_prf_chacha20_krovetz_1_;
  292. #endif
  293. #ifdef HAVE_SIMD_CHACHA_2
  294. extern const struct ottery_prf ottery_prf_chacha8_krovetz_2_;
  295. extern const struct ottery_prf ottery_prf_chacha12_krovetz_2_;
  296. extern const struct ottery_prf ottery_prf_chacha20_krovetz_2_;
  297. #endif
  298. /** @} */
  299. #endif