]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/random.h
Random: Switched flags and buf_size arguments of strongrand (slightly nicer usage).
[libucw.git] / ucw / random.h
index 703b1b09a7660bc5002359122123a7ac9d048ca1..dfe7494bd9ac547d2a03aacff2f9e5796dfccbfa 100644 (file)
 #define fastrand_max ucw_fastrand_max
 #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-fast.c */
@@ -54,7 +60,10 @@ void fastrand_set_seed(struct fastrand *c, fastrand_seed_t seed);
 /**
  * Generate a seed for fastrand_set_seed().
  *
- * We currently mix these things (you can add more if needed):
+ * Since glibc 2.25 and kernel 3.17, we use getrandom() syscall
+ * to read kernel's urandom.
+ *
+ * Otherwise we mix these things:
  * -- current time
  * -- process id to deal with frequent fork() or startups
  * -- counter to deal with multiple contexts, for example in threaded application
@@ -94,4 +103,71 @@ u64 fastrand_max_u64(struct fastrand *c, u64 bound);
 /** Generate @size random bytes. **/
 void fastrand_mem(struct fastrand *c, void *ptr, size_t size);
 
+/** Uniformly generate a random number from range [0.0, 1.0) + possible inaccuracies from basic floating point operations. **/
+double fastrand_double(struct fastrand *c);
+
+/* random-strong.c */
+
+/**
+ * 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;                            /* (mandatory) 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);
+
+/**
+ * Open kernel's random generator.
+ * Requires exactly one of these flags, among others:
+ * -- STRONGRAND_STD_URANDOM
+ * -- STRONGRAND_STD_RANDOM
+ *
+ * Since glibc 2.25 and kernel 3.17, we use getrandom() syscall,
+ * otherwise we open and read from "/dev/[u]random" device.
+ *
+ * @buf_size can be 0 for unbuffered reading.
+ *
+ * STRONGRAND_STD_x_RESET flags are only useful for buffered 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 or last reset (empty buffer)
+ **/
+struct strongrand *strongrand_std_open(uint flags, uint buf_size);
+
+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);
+
 #endif