NetworkManager/src/libnm-glib-aux/nm-random-utils.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

41 lines
650 B
C
Raw Normal View History

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2017 Red Hat, Inc.
*/
#ifndef __NM_RANDOM_UTILS_H__
#define __NM_RANDOM_UTILS_H__
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-05 03:06:06 +01:00
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;
}
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-05 03:06:06 +01:00
guint64 nm_random_u64_range(guint64 begin, guint64 end);
#endif /* __NM_RANDOM_UTILS_H__ */