Files
NetworkManager/src/libnm-glib-aux/nm-random-utils.h
Jason A. Donenfeld c627bbea4c nm-random-utils: always generate good random bytes and prioritize getrandom support
The current mess of code seems like a hodgepodge of complex ideas,
partially copied from systemd, but then subtly different, and it's a
mess. Let's simplify this drastically.

First, assume that getrandom() is always available. If the kernel is too
old, we have an unoptimized slowpath for still supporting ancient
kernels, a path that should be removed at some point. If getrandom()
isn't available and the fallback path doesn't work, the system has much
larger problems, so just crash. This should basically never happen.
getrandom() and having randomness available in general is a critical
system API that should be expected to be available on any functioning
system.

Second, assume that the rng is initialized, so that asking for random
numbers should never block. This is virtually always true on modern
kernels. On ancient kernels, it usually becomes true. But, more
importantly, this is not the responsibility of various daemons, even
ones that run at boot. Instead, this is something for the kernel and/or
init to ensure.

Putting these together, we adopt new behavior:

- First, try getrandom(..., ..., 0). The 0 flags field means that this
  call will only return good random bytes, not insecure ones.

- If this fails for some reason that isn't ENOSYS, crash.

- If this fails due to ENOSYS, poll on /dev/random until 1 byte is
  available, suggesting that subsequent reads from the rng will almost
  have good random bytes. If this fails, crash. Then, read from
  /dev/urandom. If this fails, crash.

We don't bother caching when getrandom() returns ENOSYS. We don't apply
any other fancy optimizations to the slow fallback path. We keep that as
barebones and minimal as we can. It works. It's for ancient kernels. It
should be removed soon. It's not worth spending cycles over. Instead,
the goal is to eventually reduce all of this down to a simple boring
call to getrandom(..., ..., 0).

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2127
2025-02-11 10:04:26 +01:00

41 lines
650 B
C

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2017 Red Hat, Inc.
*/
#ifndef __NM_RANDOM_UTILS_H__
#define __NM_RANDOM_UTILS_H__
void nm_random_get_bytes(void *p, size_t n);
static inline guint32
nm_random_u32(void)
{
guint32 v;
nm_random_get_bytes(&v, sizeof(v));
return v;
}
static inline guint64
nm_random_u64(void)
{
guint64 v;
nm_random_get_bytes(&v, sizeof(v));
return v;
}
static inline bool
nm_random_bool(void)
{
guint8 ch;
nm_random_get_bytes(&ch, sizeof(ch));
return ch % 2u;
}
guint64 nm_random_u64_range(guint64 begin, guint64 end);
#endif /* __NM_RANDOM_UTILS_H__ */