2020-12-23 22:21:36 +01:00
|
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
2019-09-25 13:13:40 +02:00
|
|
|
/*
|
2019-10-01 09:20:35 +02:00
|
|
|
* Copyright (C) 2017 Red Hat, Inc.
|
2017-10-14 13:28:20 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef __NM_RANDOM_UTILS_H__
|
|
|
|
|
#define __NM_RANDOM_UTILS_H__
|
|
|
|
|
|
glib-aux: rework random number utils
Heavily inspired by systemd ([1]).
We now also have nm_random_get_bytes{,_full}() and
nm_random_get_crypto_bytes(), like systemd's random_bytes()
and crypto_random_bytes(), respectively.
Differences:
- instead of systemd's random_bytes(), our nm_random_get_bytes_full()
also estimates whether the output is of high quality. The caller
may find that interesting. Due to that, we will first try to call
getrandom(GRND_NONBLOCK) before getrandom(GRND_INSECURE). That is
reversed from systemd's random_bytes(), because we want to find
out whether we can get good random numbers. In most cases, kernel
should have entropy already, and it makes no difference.
Otherwise, heavily rework the code. It should be easy to understand
and correct.
There is also a major bugfix here. Previously, if getrandom() failed
with ENOSYS and we fell back to /dev/urandom, we would assume that we
have high quality random numbers. That assumption is not warranted.
Now instead poll on /dev/random to find out.
[1] https://github.com/systemd/systemd/blob/a268e7f4021072e120a03b42660fad21e465c44e/src/basic/random-util.c#L81
2022-08-02 20:11:23 +02:00
|
|
|
void nm_random_get_bytes_full(void *p, size_t n, gboolean *out_high_quality);
|
|
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
|
nm_random_get_bytes(void *p, size_t n)
|
|
|
|
|
{
|
|
|
|
|
nm_random_get_bytes_full(p, n, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int nm_random_get_crypto_bytes(void *p, size_t n);
|
2017-10-14 13:28:20 +02:00
|
|
|
|
2023-01-27 12:28:54 +01:00
|
|
|
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_full(guint64 begin, guint64 end, gboolean crypto_bytes);
|
|
|
|
|
|
|
|
|
|
static inline guint64
|
|
|
|
|
nm_random_u64_range(guint64 end)
|
|
|
|
|
{
|
|
|
|
|
return nm_random_u64_range_full(0, end, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-14 13:28:20 +02:00
|
|
|
#endif /* __NM_RANDOM_UTILS_H__ */
|