]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/random-util.c
2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <linux/random.h>
24 #ifdef HAVE_SYS_AUXV_H
28 #include <sys/types.h>
34 #include "random-util.h"
35 #include "time-util.h"
38 int dev_urandom(void *p
, size_t n
) {
39 static int have_syscall
= -1;
41 _cleanup_close_
int fd
= -1;
44 /* Gathers some randomness from the kernel. This call will
45 * never block, and will always return some data from the
46 * kernel, regardless if the random pool is fully initialized
47 * or not. It thus makes no guarantee for the quality of the
48 * returned entropy, but is good enough for or usual usecases
49 * of seeding the hash functions for hashtable */
51 /* Use the getrandom() syscall unless we know we don't have
52 * it, or when the requested size is too large for it. */
53 if (have_syscall
!= 0 || (size_t) (int) n
!= n
) {
54 r
= getrandom(p
, n
, GRND_NONBLOCK
);
62 /* we lack the syscall, continue with
63 * reading from /dev/urandom */
65 else if (errno
== EAGAIN
)
66 /* not enough entropy for now. Let's
67 * remember to use the syscall the
68 * next time, again, but also read
69 * from /dev/urandom for now, which
70 * doesn't care about the current
71 * amount of entropy. */
80 fd
= open("/dev/urandom", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
82 return errno
== ENOENT
? -ENOSYS
: -errno
;
84 return loop_read_exact(fd
, p
, n
, true);
87 void initialize_srand(void) {
88 static bool srand_called
= false;
90 #ifdef HAVE_SYS_AUXV_H
99 #ifdef HAVE_SYS_AUXV_H
100 /* The kernel provides us with a bit of entropy in auxv, so
101 * let's try to make use of that to seed the pseudo-random
102 * generator. It's better than nothing... */
104 auxv
= (void*) getauxval(AT_RANDOM
);
106 x
^= *(unsigned*) auxv
;
109 x
^= (unsigned) now(CLOCK_REALTIME
);
110 x
^= (unsigned) gettid();
116 void random_bytes(void *p
, size_t n
) {
120 r
= dev_urandom(p
, n
);
124 /* If some idiot made /dev/urandom unavailable to us, he'll
125 * get a PRNG instead. */
129 for (q
= p
; q
< (uint8_t*) p
+ n
; q
++)