mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-19 10:20:31 +01:00
glib-aux: reseed state for "bad" random bytes every time
nm_utils_random_bytes() is supposed to give us good random number from kernel. It guarantees to always provide some bytes, and it has a boolean return value that estimates whether the bytes are good randomness. In practice, most callers ignore that return value, because what would they do about it anyway? Of course, we want to primarily use getrandom() (or "/dev/urandom"). But if we fail to get random bytes from them, we have a fallback path that tries to generate "random" bytes. It does so, by initializing a global seed from various sources, and keep sha256 hashing the buffer in a loop. That's certainly not efficient nor elegant, but we already are in a fallback path. Still, we can do slightly better. Instead of just using the global state and keep updating it (entirely deterministically), every time also mix in the results from getrandom() and a current timestamp. The idea is that if you have a virtual machine that gets cloned, we don't want that our global state keeps giving the same random numbers. In particular, because getrandom() might handle that case, even if it doesn't have good entropy.
This commit is contained in:
parent
0f3eb6fabb
commit
3c349ee11b
1 changed files with 19 additions and 0 deletions
|
|
@ -72,6 +72,10 @@ typedef struct _nm_packed {
|
|||
guint8 u8[NM_UTILS_CHECKSUM_LENGTH_SHA256 / 2];
|
||||
guint32 u32[((NM_UTILS_CHECKSUM_LENGTH_SHA256 / 2) + 3) / 4];
|
||||
} rand_vals;
|
||||
#if HAVE_GETRANDOM
|
||||
guint8 rand_vals_getrandom[16];
|
||||
#endif
|
||||
gint16 rand_vals_timestamp;
|
||||
GRand *rand;
|
||||
} BadRandState;
|
||||
|
||||
|
|
@ -168,6 +172,21 @@ _bad_random_bytes(guint8 *buf, gsize n)
|
|||
nm_utils_checksum_get_digest(sum, gl_state.sha_digest.full);
|
||||
}
|
||||
|
||||
#if HAVE_GETRANDOM
|
||||
{
|
||||
ssize_t r;
|
||||
|
||||
/* This is likely to fail, because we already failed a moment earlier. Still, give
|
||||
* it a try. */
|
||||
r = getrandom(gl_state.rand_vals_getrandom,
|
||||
sizeof(gl_state.rand_vals_getrandom),
|
||||
GRND_INSECURE | GRND_NONBLOCK);
|
||||
(void) r;
|
||||
}
|
||||
#endif
|
||||
|
||||
gl_state.rand_vals_timestamp = nm_utils_clock_gettime_nsec(CLOCK_BOOTTIME);
|
||||
|
||||
while (TRUE) {
|
||||
int i;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue