summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2022-12-17 23:16:55 +0100
committerMitya Selivanov <automainint@guattari.tech>2022-12-17 23:16:55 +0100
commit901478a2d04fcae70cf1f99f19b7508256633fa0 (patch)
treef4bdbbe46e66bbdd88c1de86a3d8fbd7808f5f7b /source
parent6f2eb1abd023c6ede47f3bc58230b0646f2e6222 (diff)
downloadkit-901478a2d04fcae70cf1f99f19b7508256633fa0.zip
Secure random fallback: thread safety
Diffstat (limited to 'source')
-rw-r--r--source/kit/secure_random.c36
-rw-r--r--source/kit/secure_random.h5
-rw-r--r--source/kit/time.h8
-rw-r--r--source/test/unittests/secure_random.test.c4
4 files changed, 44 insertions, 9 deletions
diff --git a/source/kit/secure_random.c b/source/kit/secure_random.c
index 8852524..8f48c9d 100644
--- a/source/kit/secure_random.c
+++ b/source/kit/secure_random.c
@@ -1,6 +1,7 @@
#include "secure_random.h"
#include "mersenne_twister_64.h"
+#include "mutex.h"
#include "time.h"
#include <stdio.h>
@@ -26,8 +27,16 @@ static uint64_t get_available_memory() {
#endif
}
+#ifndef KIT_DISABLE_SYSTEM_THREADS
+static mtx_t kit_secure_random_fallback_mutex;
+#endif
+
static void secure_random_fallback(ptrdiff_t const size,
void *const data) {
+#ifndef KIT_DISABLE_SYSTEM_THREADS
+ mtx_lock(&kit_secure_random_fallback_mutex);
+#endif
+
/* Try to get some unpredictable system properties and use them to
* seed the pseudo random number generator.
*/
@@ -42,11 +51,11 @@ static void secure_random_fallback(ptrdiff_t const size,
kit_mt64_state_t state;
if (time_sec == 0 && time_nsec == 0) {
- uint64_t seed[4] = { n++, get_available_memory(),
+ uint64_t seed[4] = { n, get_available_memory(),
(uint64_t) t.tv_sec, (uint64_t) t.tv_nsec };
kit_mt64_init_array(&state, sizeof seed / sizeof *seed, seed);
} else {
- uint64_t seed[6] = { n++,
+ uint64_t seed[6] = { n,
get_available_memory(),
(uint64_t) t.tv_sec,
(uint64_t) t.tv_nsec,
@@ -55,17 +64,34 @@ static void secure_random_fallback(ptrdiff_t const size,
kit_mt64_init_array(&state, sizeof seed / sizeof *seed, seed);
}
- time_sec = (uint64_t) t.tv_sec;
- time_nsec = (uint64_t) t.tv_nsec;
-
/* Bootstrap the generator.
*/
for (ptrdiff_t i = 0; i < KIT_MT64_N; i++)
kit_mt64_generate(&state);
+ n = kit_mt64_generate(&state);
+ time_sec = (uint64_t) t.tv_sec;
+ time_nsec = (uint64_t) t.tv_nsec;
+
for (ptrdiff_t i = 0; i < size; i++)
((uint8_t *) data)[i] = (uint8_t) (kit_mt64_generate(&state) >>
56);
+
+#ifndef KIT_DISABLE_SYSTEM_THREADS
+ mtx_unlock(&kit_secure_random_fallback_mutex);
+#endif
+}
+
+void kit_secure_random_init() {
+#ifndef KIT_DISABLE_SYSTEM_THREADS
+ mtx_init(&kit_secure_random_fallback_mutex, mtx_plain);
+#endif
+}
+
+void kit_secure_random_cleanup() {
+#ifndef KIT_DISABLE_SYSTEM_THREADS
+ mtx_destroy(&kit_secure_random_fallback_mutex);
+#endif
}
void kit_secure_random(ptrdiff_t const size, void *const data) {
diff --git a/source/kit/secure_random.h b/source/kit/secure_random.h
index 758478d..5b461f9 100644
--- a/source/kit/secure_random.h
+++ b/source/kit/secure_random.h
@@ -9,9 +9,14 @@
extern "C" {
#endif
+void kit_secure_random_init();
+void kit_secure_random_cleanup();
+
void kit_secure_random(ptrdiff_t size, void *data);
#ifndef KIT_DISABLE_SHORT_NAMES
+# define secure_random_init kit_secure_random_init
+# define secure_random_cleanup kit_secure_random_cleanup
# define secure_random kit_secure_random
#endif
diff --git a/source/kit/time.h b/source/kit/time.h
index dbf8883..0d995f4 100644
--- a/source/kit/time.h
+++ b/source/kit/time.h
@@ -38,21 +38,21 @@ struct timespec {
/*-------------------------- functions --------------------------*/
#if !defined(KIT_HAVE_TIMESPEC_GET)
-# define KIT_HAVE_TIMESPEC_GET_NEED_DECL_
+# define KIT_TIMESPEC_GET_NEED_DECL_
#elif defined(__APPLE__) && defined(__cplusplus) && \
(__cplusplus < 201703L)
/* On macOS, the guard for declaration of timespec_get is by
* (defined(__cplusplus) && __cplusplus >= 201703L),
* fix the declaration for C++14 and lower here
*/
-# define KIT_HAVE_TIMESPEC_GET_NEED_DECL_
+# define KIT_TIMESPEC_GET_NEED_DECL_
#endif
-#ifdef KIT_HAVE_TIMESPEC_GET_NEED_DECL_
+#ifdef KIT_TIMESPEC_GET_NEED_DECL_
/*-------------------- 7.25.7 Time functions --------------------*/
// 7.25.6.1
int timespec_get(struct timespec *ts, int base);
-# undef KIT_HAVE_TIMESPEC_GET_NEED_DECL_
+# undef KIT_TIMESPEC_GET_NEED_DECL_
#endif
#ifdef __cplusplus
diff --git a/source/test/unittests/secure_random.test.c b/source/test/unittests/secure_random.test.c
index ec0a7b2..eadae65 100644
--- a/source/test/unittests/secure_random.test.c
+++ b/source/test/unittests/secure_random.test.c
@@ -8,9 +8,13 @@ TEST("secure random") {
int v[20];
memset(v, 0, sizeof v);
+ secure_random_init();
+
secure_random(40, v);
secure_random(40, v + 10);
+ secure_random_cleanup();
+
int repeats = 0;
for (int i = 1; i < sizeof v / sizeof *v; i++)