summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic/missing_random.h4
-rw-r--r--src/basic/random-util.c18
-rw-r--r--src/basic/random-util.h1
-rw-r--r--src/test/test-random-util.c1
4 files changed, 22 insertions, 2 deletions
diff --git a/src/basic/missing_random.h b/src/basic/missing_random.h
index 2e76031b32..17af87a3ae 100644
--- a/src/basic/missing_random.h
+++ b/src/basic/missing_random.h
@@ -14,3 +14,7 @@
#ifndef GRND_RANDOM
#define GRND_RANDOM 0x0002
#endif
+
+#ifndef GRND_INSECURE
+#define GRND_INSECURE 0x0004
+#endif
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
index c32e6e2aac..73cc7272db 100644
--- a/src/basic/random-util.c
+++ b/src/basic/random-util.c
@@ -208,7 +208,9 @@ int genuine_random_bytes(void *p, size_t n, RandomFlags flags) {
if (have_syscall != 0 && !HAS_FEATURE_MEMORY_SANITIZER) {
for (;;) {
- r = getrandom(p, n, FLAGS_SET(flags, RANDOM_BLOCK) ? 0 : GRND_NONBLOCK);
+ r = getrandom(p, n,
+ (FLAGS_SET(flags, RANDOM_BLOCK) ? 0 : GRND_NONBLOCK) |
+ (FLAGS_SET(flags, RANDOM_ALLOW_INSECURE) ? GRND_INSECURE : 0));
if (r > 0) {
have_syscall = true;
@@ -264,6 +266,18 @@ int genuine_random_bytes(void *p, size_t n, RandomFlags flags) {
/* Use /dev/urandom instead */
break;
+
+ } else if (errno == EINVAL) {
+
+ /* Most likely: unknown flag. We know that GRND_INSECURE might cause this,
+ * hence try without. */
+
+ if (FLAGS_SET(flags, RANDOM_ALLOW_INSECURE)) {
+ flags = flags &~ RANDOM_ALLOW_INSECURE;
+ continue;
+ }
+
+ return -errno;
} else
return -errno;
}
@@ -395,7 +409,7 @@ void random_bytes(void *p, size_t n) {
* This function is hence not useful for generating UUIDs or cryptographic key material.
*/
- if (genuine_random_bytes(p, n, RANDOM_EXTEND_WITH_PSEUDO|RANDOM_MAY_FAIL|RANDOM_ALLOW_RDRAND) >= 0)
+ if (genuine_random_bytes(p, n, RANDOM_EXTEND_WITH_PSEUDO|RANDOM_MAY_FAIL|RANDOM_ALLOW_RDRAND|RANDOM_ALLOW_INSECURE) >= 0)
return;
/* If for some reason some user made /dev/urandom unavailable to us, or the kernel has no entropy, use a PRNG instead. */
diff --git a/src/basic/random-util.h b/src/basic/random-util.h
index facc11b976..d8e067d96e 100644
--- a/src/basic/random-util.h
+++ b/src/basic/random-util.h
@@ -10,6 +10,7 @@ typedef enum RandomFlags {
RANDOM_BLOCK = 1 << 1, /* Rather block than return crap randomness (only if the kernel supports that) */
RANDOM_MAY_FAIL = 1 << 2, /* If we can't get any randomness at all, return early with -ENODATA */
RANDOM_ALLOW_RDRAND = 1 << 3, /* Allow usage of the CPU RNG */
+ RANDOM_ALLOW_INSECURE = 1 << 4, /* Allow usage of GRND_INSECURE flag to kernel's getrandom() API */
} RandomFlags;
int genuine_random_bytes(void *p, size_t n, RandomFlags flags); /* returns "genuine" randomness, optionally filled up with pseudo random, if not enough is available */
diff --git a/src/test/test-random-util.c b/src/test/test-random-util.c
index 94c431f7e6..ad5bc72a4e 100644
--- a/src/test/test-random-util.c
+++ b/src/test/test-random-util.c
@@ -58,6 +58,7 @@ int main(int argc, char **argv) {
test_genuine_random_bytes(0);
test_genuine_random_bytes(RANDOM_BLOCK);
test_genuine_random_bytes(RANDOM_ALLOW_RDRAND);
+ test_genuine_random_bytes(RANDOM_ALLOW_INSECURE);
test_pseudo_random_bytes();