]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/random.h
Random: Implemented strong random source.
[libucw.git] / ucw / random.h
index 1d3b8a1450f5bd855321a317534ec1b8e4019218..ec31b0dec292e9a71f453afa3635ff61cf269165 100644 (file)
 #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
 
@@ -104,7 +108,61 @@ double fastrand_double(struct fastrand *c);
 
 /* 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);