mirror of
https://github.com/systemd/systemd.git
synced 2025-03-19 22:50:17 +03:00
random-util: make use of GRND_INSECURE when it is defined
kernel 5.6 added support for a new flag for getrandom(): GRND_INSECURE. If we set it we can get some random data out of the kernel random pool, even if it is not yet initializated. This is great for us to initialize hash table seeds and such, where it is OK if they are crap initially. We used RDRAND for these cases so far, but RDRAND is only available on newer CPUs and some archs. Let's now use GRND_INSECURE for these cases as well, which means we won't needlessly delay boot anymore even on archs/CPUs that do not have RDRAND. Of course we never set this flag when generating crypto keys or uuids. Which makes it different from RDRAND for us (and is the reason I think we should keep explicit RDRAND support in): RDRAND we don't trust enough for crypto keys. But we do trust it enough for UUIDs.
This commit is contained in:
parent
e2b5546452
commit
0497c4c28a
@ -14,3 +14,7 @@
|
||||
#ifndef GRND_RANDOM
|
||||
#define GRND_RANDOM 0x0002
|
||||
#endif
|
||||
|
||||
#ifndef GRND_INSECURE
|
||||
#define GRND_INSECURE 0x0004
|
||||
#endif
|
||||
|
@ -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. */
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user