#define fastrand_max_u64 ucw_fastrand_max_u64
#define fastrand_mem ucw_fastrand_mem
#define fastrand_double ucw_fastrand_double
+#define strongrand_close ucw_strongrand_close
+#define strongrand_reset ucw_strongrand_reset
+#define strongrand_mem ucw_strongrand_mem
+#define strongrand_std_open ucw_strongrand_std_open
#define strongrand_getrandom_mem_try ucw_strongrand_getrandom_mem_try
#endif
/* random-strong.c */
-/* FIXME: interface for strong randomness */
+/**
+ * Context structure for a strong random generator.
+ * Useful for things like generating random ids or cryptography.
+ * The library is generally thread-safe, but each context must be used by at most one thread at one time.
+ *
+ * Also be careful with fork(). Unless said otherwise, it's forbidden to use the context
+ * in a forked child, we can even assert changes of pid. See strongrand_reset() if you
+ * need that.
+ **/
+struct strongrand {
+ const char *name; /* Context name for logging. */
+ void (*read)(struct strongrand *sr, byte *ptr, int size); /* (mandatory) Generate @size random bytes. */
+ void (*close)(struct strongrand *sr); /* Called from strongrand_close(). */
+ void (*reset)(struct strongrand *sr); /* Called from strongrand_reset(). */
+};
+
+/** Close a previously opened context. **/
+void strongrand_close(struct strongrand *c);
+
+/**
+ * If you want to use the same context in multiple forked subprocesses, you must
+ * call this function after the fork() to flush any buffered randomness.
+ * Some future back-ends could use it for even more things, for example
+ * to re-connect somewhere.
+ **/
+void strongrand_reset(struct strongrand *sr);
+
+/** Generate @size random bytes. **/
+void strongrand_mem(struct strongrand *c, void *ptr, size_t size);
+
+/** Kernel's random generator. **/
+
+/**
+ * Open kernel's random generator.
+ * Requires exactly one of these flags, among others:
+ * -- STRONGRAND_STD_URANDOM
+ * -- STRONGRAND_STD_RANDOM
+ *
+ * @buf_size can be 0 for unbuffered reading.
+ *
+ * If at least one of the following conditions are met,
+ * strongrand_reset() after fork() is not necessary:
+ * -- zero @buf_size
+ * -- STRONGRAND_STD_AUTO_RESET flag
+ * -- no read since open (empty buffer)
+ **/
+struct strongrand *strongrand_std_open(uint buf_size, uint flags);
+
+enum strongrand_std_flags {
+ STRONGRAND_STD_URANDOM = 0x1, // Use kernel's "urandom" source.
+ STRONGRAND_STD_RANDOM = 0x2, // Use kernel's "random" source.
+ STRONGRAND_STD_DELAYED = 0x4, // Delay non-trivial initializations like opening file descriptor to first read.
+ STRONGRAND_STD_AUTO_RESET = 0x8, // Automatically do strongrand_reset() after changes of getpid(); adds overhead to each read.
+ STRONGRAND_STD_ASSERT_RESET = 0x10, // Assert correct usage of strongrand_reset() after changes of getpid(); for debugging.
+};
// Internals
bool strongrand_getrandom_mem_try(void *buf, size_t size);