Add getentropy, getrandom, <sys/random.h> [BZ #17252]
2016-12-06 Florian Weimer <fweimer@redhat.com>
[BZ #17252]
Add getentropy, getrandom.
* stdlib/sys/random.h: New file.
(headers): Add it.
* stdlib/Makefile (routines): Add getentropy, getrandom.
(tests): Add tst-getrandom.
* stdlib/Versions (GLIBC_2.25): Add getrandom, __libc_getrandom,
getentropy, __libc_getentropy.
* stdlib/getentropy.c: New file.
* stdlib/getrandom.c: Likewise.
* stdlib/tst-getrandom.c: Likewise.
* sysdeps/unix/sysv/linux/getentropy.c: Likewise.
* sysdeps/unix/sysv/linux/getrandom.c: Likewise.
* manual/crypt.texi (Unpredictable Bytes): New section.
* manual/math.texi (Pseudo-Random Numbers): Add cross-reference.
* sysdeps/arm/nacl/libc.abilist: Add __libc_getentropy,
__libc_getrandom, getrandom, getentropy.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/alpha/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/arm/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/hppa/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/ia64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/microblaze/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/nios2/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc-le.abilist: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/sh/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/tile/tilepro/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
@@ -83,6 +83,9 @@ Version 2.25
affect the ABI of other libraries that use this type in their interfaces,
if they are compiled or used with those options.
+* The getentropy and getrandom functions, and the <sys/random.h> header file
+ have been added.
+
* The buffer size for byte-oriented stdio streams is now limited to 8192
bytes by default. Previously, on Linux, the default buffer size on most
file systems was 4096 bytes (and thus remains unchanged), except on
@@ -45,6 +45,7 @@ encrypted authentication use normal DES.
* getpass:: Prompting the user for a password.
* crypt:: A one-way function for passwords.
* DES Encryption:: Routines for DES encryption.
+* Unpredictable Bytes:: Randomness for cryptography purposes.
@end menu
@node Legal Problems
@@ -428,3 +429,114 @@ each byte.
The @code{ecb_crypt}, @code{cbc_crypt}, and @code{des_setparity}
functions and their accompanying macros are all defined in the header
@file{rpc/des_crypt.h}.
+
+@node Unpredictable Bytes
+@section Generating Unpredictable Bytes
+
+Some cryptographic applications (such as session key generation) need
+unpredictable bytes.
+
+In general, application code should use a deterministic random bit
+generator, which could call the @code{getentropy} function described
+below internally to obtain randomness to seed the generator. The
+@code{getrandom} function is intended for low-level applications which
+need additional control over the blocking behavior.
+
+@comment sys/random.h
+@comment GNU
+@deftypefun int getentropy (void *@var{buffer}, size_t @var{length})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+
+This function writes @var{length} bytes of random data to the array
+starting at @var{buffer}, which must be at most 256 bytes long. The
+function returns zero on success. On failure, it returns @code{-1} and
+@code{errno} is updated accordingly.
+
+The @code{getentropy} function is declared in the header file
+@file{sys/random.h}. It is derived from OpenBSD.
+
+The @code{getentropy} function is not a cancellation point. A call to
+@code{getentropy} can block if the system has just booted and the kernel
+entropy pool has not yet been initialized. In this case, the function
+will keep blocking even if a signal arrives, and return only after the
+entropy pool has been initialized.
+
+The @code{getentropy} function can fail with several errors, some of
+which are listed below.
+
+@table @code
+@item ENOSYS
+The kernel does not implement the required system call.
+
+@item EFAULT
+The combination of @var{buffer} and @var{length} arguments specifies
+an invalid memory range.
+
+@item EIO
+More than 256 bytes of randomness have been requested, or the buffer
+could not be overwritten with random data for an unspecified reason.
+
+@end table
+
+@end deftypefun
+
+@comment sys/random.h
+@comment GNU
+@deftypefun ssize_t getrandom (void *@var{buffer}, size_t @var{length}, unsigned int @var{flags})
+@safety{@mtsafe{}@assafe{}@acsafe{}}
+
+This function writes @var{length} bytes of random data to the array
+starting at @var{buffer}. On success, this function returns the number
+of bytes which have been written to the buffer (which can be less than
+@var{length}). On error, @code{-1} is returned, and @code{errno} is
+updated accordingly.
+
+The @code{getrandom} function is declared in the header file
+@file{sys/random.h}. It is a GNU extension.
+
+The following flags are defined for the @var{flags} argument:
+
+@table @code
+@item GRND_RANDOM
+Use the @file{/dev/random} (blocking) pool instead of the
+@file{/dev/urandom} (non-blocking) pool to obtain randomness. If the
+@code{GRND_RANDOM} flag is specified, the @code{getrandom} function can
+block even after the randomness source has been initialized.
+
+@item GRND_NONBLOCK
+Instead of blocking, return to the caller immediately if no data is
+available.
+@end table
+
+The @code{getrandom} function is a cancellation point.
+
+Obtaining randomness from the @file{/dev/urandom} pool (i.e., a call
+without the @code{GRND_RANDOM} flag) can block if the system has just
+booted and the pool has not yet been initialized.
+
+The @code{getrandom} function can fail with several errors, some of
+which are listed below. In addition, the function may not fill the
+buffer completely and return a value less than @var{length}.
+
+@table @code
+@item ENOSYS
+The kernel does not implement the @code{getrandom} system call.
+
+@item EAGAIN
+No random data was available and @code{GRND_NONBLOCK} was specified in
+@var{flags}.
+
+@item EFAULT
+The combination of @var{buffer} and @var{length} arguments specifies
+an invalid memory range.
+
+@item EINTR
+The system call was interrupted. During the system boot process, before
+the kernel randomness pool is initialized, this can happen even if
+@var{flags} is zero.
+
+@item EINVAL
+The @var{flags} argument contains an invalid combination of flags.
+@end table
+
+@end deftypefun
@@ -1443,7 +1443,8 @@ is convenient when you are debugging a program, but it is unhelpful if
you want the program to behave unpredictably. If you want a different
pseudo-random series each time your program runs, you must specify a
different seed each time. For ordinary purposes, basing the seed on the
-current time works well.
+current time works well. For random numbers in cryptography,
+@pxref{Unpredictable Bytes}.
You can obtain repeatable sequences of numbers on a particular machine type
by specifying the same initial seed value for the random number
@@ -28,7 +28,7 @@ headers := stdlib.h bits/stdlib.h bits/stdlib-ldbl.h bits/stdlib-float.h \
errno.h sys/errno.h bits/errno.h \
ucontext.h sys/ucontext.h \
alloca.h fmtmsg.h \
- bits/stdlib-bsearch.h
+ bits/stdlib-bsearch.h sys/random.h
routines := \
atof atoi atol atoll \
@@ -45,7 +45,7 @@ routines := \
srand48 seed48 lcong48 \
drand48_r erand48_r lrand48_r nrand48_r mrand48_r jrand48_r \
srand48_r seed48_r lcong48_r \
- drand48-iter \
+ drand48-iter getrandom getentropy \
strfromf strfromd strfroml \
strtol strtoul strtoll strtoull \
strtol_l strtoul_l strtoll_l strtoull_l \
@@ -79,7 +79,8 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
tst-setcontext3 tst-tls-atexit-nodelete \
tst-strtol-locale tst-strtod-nan-locale tst-strfmon_l \
tst-quick_exit tst-thread-quick_exit tst-width \
- tst-width-stdint tst-strfrom tst-strfrom-locale
+ tst-width-stdint tst-strfrom tst-strfrom-locale \
+ tst-getrandom
tests-static := tst-secure-getenv
ifeq ($(have-cxx-thread_local),yes)
CFLAGS-tst-quick_exit.o = -std=c++11
@@ -115,6 +115,7 @@ libc {
GLIBC_2.25 {
# s*
strfromd; strfromf; strfroml;
+ getrandom; __libc_getrandom; getentropy; __libc_getentropy;
}
GLIBC_PRIVATE {
# functions which have an additional interface since they are
new file mode 100644
@@ -0,0 +1,37 @@
+/* Stub for getentropy.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Do not alias getentropy to __libc_getentropy. */
+#define getentropy getentropy_noalias
+#include <sys/random.h>
+#undef getentropy
+
+#include <errno.h>
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Return 0 on
+ success and -1 on failure. */
+ssize_t
+__libc_getentropy (void *buffer, size_t length)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+stub_warning (__libc_getentropy)
+
+weak_alias (__libc_getentropy, getentropy)
new file mode 100644
@@ -0,0 +1,37 @@
+/* Stub for getrandom.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Do not alias getrandom to __libc_getrandom. */
+#define getrandom getrandom_noalias
+#include <sys/random.h>
+#undef getrandom
+
+#include <errno.h>
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Return the
+ number of bytes written, or -1 on error. */
+ssize_t
+__libc_getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+stub_warning (__libc_getrandom)
+
+weak_alias (__libc_getrandom, getrandom)
new file mode 100644
@@ -0,0 +1,61 @@
+/* Interfaces for obtaining random bytes.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_RANDOM_H
+#define _SYS_RANDOM_H 1
+
+#include <features.h>
+#include <sys/types.h>
+
+/* Flags for use with getrandom. */
+#define GRND_NONBLOCK 0x01
+#define GRND_RANDOM 0x02
+
+__BEGIN_DECLS
+
+#ifdef __REDIRECT
+/* For GNU compilers: Redirect getrandom to __libc_getrandom, to
+ protect against accidental interposition. (Application code should
+ still use the getrandom symbol.) */
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Return the
+ number of bytes written, or -1 on error. */
+ssize_t __libc_getrandom (void *__buffer, size_t __length,
+ unsigned int __flags) __wur;
+extern ssize_t __REDIRECT (getrandom,
+ (void *__buffer, size_t __length,
+ unsigned int __flags),
+ __libc_getrandom);
+
+/* Write LENGTH bytes of randomness starting at BUFFER. Return 0 on
+ success or -1 on error. */
+int __libc_getentropy (void *__buffer, size_t __length) __wur;
+extern int __REDIRECT (getentropy, (void *__buffer, size_t __length),
+ __libc_getentropy);
+
+#else
+/* Non-GNU compilers do not receive protection against accidental
+ interposition. */
+ssize_t getrandom (void *__buffer, size_t __length, unsigned int __flags)
+ __wur;
+int getentropy (void *__buffer, size_t __length) __wur;
+#endif /* __REDIRECT */
+
+__END_DECLS
+
+#endif /* _SYS_RANDOM_H */
new file mode 100644
@@ -0,0 +1,246 @@
+/* Tests for the getentropy, getrandom functions.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/random.h>
+
+/* Set to true if any errors are encountered. */
+static bool errors;
+
+/* Test getrandom with a single buffer length. NB: The passed-in
+ buffer must have room for four extra bytes after the specified
+ length, which are used to test that getrandom leaves those bytes
+ unchanged. */
+static void
+test_length (char *buffer, size_t length, unsigned int flags)
+{
+ memset (buffer, 0, length);
+ strcpy (buffer + length, "123");
+ ssize_t ret = getrandom (buffer, length, flags);
+ if (ret < 0)
+ {
+ /* EAGAIN is an expected error with GRND_RANDOM and
+ GRND_NONBLOCK. */
+ if ((flags & GRND_RANDOM)
+ && (flags & GRND_NONBLOCK)
+ && errno == EAGAIN)
+ return;
+ printf ("error: getrandom (%zu, 0x%x): %m\n", length, flags);
+ errors = true;
+ return;
+ }
+ if (ret != length)
+ {
+ if (flags & GRND_RANDOM)
+ {
+ if (ret == 0 || ret > length)
+ {
+ printf ("error: getrandom (%zu, 0x%x) returned %zd\n",
+ length, flags, ret);
+ errors = true;
+ }
+ }
+ else
+ {
+ printf ("error: getrandom (%zu, 0x%x) returned %zd\n",
+ length, flags, ret);
+ errors = true;
+ }
+ }
+ if (length >= 7)
+ {
+ /* One spurious test failure in 2**56 is sufficiently
+ unlikely. */
+ int non_null = 0;
+ for (int i = 0; i < length; ++i)
+ non_null += buffer[i] != 0;
+ if (non_null == 0)
+ {
+ printf ("error: getrandom (%zu, 0x%x) returned all-zero bytes\n",
+ length, flags);
+ errors = true;
+ }
+ }
+ if (memcmp (buffer + length, "123", 4) != 0)
+ {
+ printf ("error: getrandom (%zu, 0x%x) wrote spurious bytes\n",
+ length, flags);
+ errors = true;
+ }
+}
+
+/* Call getrandom repeatedly to fill the buffer. */
+static bool
+getrandom_full (char *buffer, size_t length, unsigned int flags)
+{
+ char *end = buffer + length;
+ while (buffer < end)
+ {
+ ssize_t ret = getrandom (buffer, end - buffer, flags);
+ if (ret < 0)
+ {
+ printf ("error: getrandom (%zu, 0x%x): %m\n", length, flags);
+ errors = true;
+ return false;
+ }
+ buffer += ret;
+ }
+
+ return true;
+}
+
+static void
+test_flags (unsigned int flags)
+{
+ /* Test various lengths, but only for !GRND_RANDOM, to conserve
+ entropy. */
+ {
+ enum { max_length = 300 };
+ char buffer[max_length + 4];
+ if (flags & GRND_RANDOM)
+ test_length (buffer, 0, flags);
+ else
+ {
+ for (int length = 0; length <= 9; ++length)
+ test_length (buffer, length, flags);
+ test_length (buffer, 16, flags);
+ test_length (buffer, max_length, flags);
+ }
+ }
+
+ /* Test that getrandom returns different data. */
+ if (!(flags & GRND_NONBLOCK))
+ {
+ char buffer1[8];
+ memset (buffer1, 0, sizeof (buffer1));
+
+ char buffer2[8];
+ memset (buffer2, 0, sizeof (buffer2));
+
+ if (getrandom_full (buffer1, sizeof (buffer1), flags)
+ && getrandom_full (buffer2, sizeof (buffer2), flags))
+ {
+ /* The probability that these two 8-byte buffers are equal
+ is very small (assuming that two subsequent calls to
+ getrandom result are independent, uniformly distributed
+ random variables). */
+ if (memcmp (buffer1, buffer2, sizeof (buffer1)) == 0)
+ {
+ printf ("error: getrandom returns constant value\n");
+ errors = true;
+ }
+ }
+ }
+}
+
+static void
+test_getentropy (void)
+{
+ char buf[16];
+ memset (buf, '@', sizeof (buf));
+ if (getentropy (buf, 0) != 0)
+ {
+ printf ("error: getentropy zero length: %m\n");
+ errors = true;
+ return;
+ }
+ for (size_t i = 0; i < sizeof (buf); ++i)
+ if (buf[i] != '@')
+ {
+ printf ("error: getentropy modified zero-length buffer\n");
+ errors = true;
+ return;
+ }
+
+ if (getentropy (buf, sizeof (buf)) != 0)
+ {
+ printf ("error: getentropy buf: %m\n");
+ errors = true;
+ return;
+ }
+
+ char buf2[256];
+ _Static_assert (sizeof (buf) < sizeof (buf2), "buf and buf2 compatible");
+ memset (buf2, '@', sizeof (buf2));
+ if (getentropy (buf2, sizeof (buf)) != 0)
+ {
+ printf ("error: getentropy buf2: %m\n");
+ errors = true;
+ return;
+ }
+
+ /* The probability that these two buffers are equal is very
+ small. */
+ if (memcmp (buf, buf2, sizeof (buf) == 0))
+ {
+ printf ("error: getentropy appears to return constant bytes\n");
+ errors = true;
+ return;
+ }
+
+ for (size_t i = sizeof (buf); i < sizeof (buf2); ++i)
+ if (buf2[i] != '@')
+ {
+ printf ("error: getentropy wrote beyond the end of the buffer\n");
+ errors = true;
+ return;
+ }
+
+ char buf3[257];
+ if (getentropy (buf3, sizeof (buf3)) == 0)
+ {
+ printf ("error: getentropy successful for 257 byte buffer\n");
+ errors = true;
+ return;
+ }
+ if (errno != EIO)
+ {
+ printf ("error: getentropy wrong error for 257 byte buffer: %m\n");
+ errors = true;
+ return;
+ }
+}
+
+static int
+do_test (void)
+{
+ /* Check if getrandom is not supported by this system. */
+ if (getrandom (NULL, 0, 0) == -1 && errno == ENOSYS)
+ return 77;
+
+ for (int use_random = 0; use_random < 2; ++use_random)
+ for (int use_nonblock = 0; use_nonblock < 2; ++use_nonblock)
+ {
+ unsigned int flags = 0;
+ if (use_random)
+ flags |= GRND_RANDOM;
+ if (use_nonblock)
+ flags |= GRND_NONBLOCK;
+ test_flags (flags);
+ }
+
+ test_getentropy ();
+
+ return errors;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
@@ -1843,6 +1843,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 gnu_dev_major F
GLIBC_2.25 gnu_dev_makedev F
GLIBC_2.25 gnu_dev_minor F
@@ -2090,6 +2090,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2001,6 +2001,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -91,6 +91,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
new file mode 100644
@@ -0,0 +1,83 @@
+/* Implementation of getentropy based on the getrandom system call.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Do not alias getentropy to __libc_getentropy. */
+#define getentropy getentropy_noalias
+#include <sys/random.h>
+#undef getentropy
+
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef __NR_getrandom
+/* Write LENGTH bytes of randomness starting at BUFFER. Return 0 on
+ success and -1 on failure. */
+int
+__libc_getentropy (void *buffer, size_t length)
+{
+ /* The interface is documented to return EIO for buffer lengths
+ longer than 256 bytes. */
+ if (length > 256)
+ {
+ __set_errno (EIO);
+ return -1;
+ }
+
+ /* Try to fill the buffer completely. Even with the 256 byte limit
+ above, we might still receive an EINTR error (when blocking
+ during boot). */
+ void *end = buffer + length;
+ while (buffer < end)
+ {
+ /* NB: No cancellation point. */
+ ssize_t bytes = INLINE_SYSCALL_CALL (getrandom, buffer, end - buffer, 0);
+ if (bytes < 0)
+ {
+ if (errno == EINTR)
+ /* Try again if interrupted by a signal. */
+ continue;
+ else
+ return -1;
+ }
+ /* The Linux implementation never returns zero if the length
+ argument is not zero, and does not perform a short read for
+ sizes <= 256. */
+ assert (bytes == length);
+ if (bytes == 0)
+ {
+ /* No more bytes available. This should not happen under
+ normal circumstances. */
+ __set_errno (EIO);
+ return -1;
+ }
+ /* Try again in case of a short read. */
+ buffer += bytes;
+ }
+ return 0;
+}
+#else
+int
+__libc_getentropy (void *buffer, size_t length)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+#endif
+
+weak_alias (__libc_getentropy, getentropy)
new file mode 100644
@@ -0,0 +1,49 @@
+/* Implementation of the getrandom system call.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Do not alias getrandom to __libc_getrandom. */
+#define getrandom getrandom_noalias
+#include <sys/random.h>
+#undef getrandom
+
+#include <errno.h>
+#include <unistd.h>
+#include <sysdep-cancel.h>
+
+#ifdef __NR_getrandom
+/* Write LENGTH bytes of randomness starting at BUFFER. Return 0 on
+ success and -1 on failure. */
+ssize_t
+__libc_getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ return SYSCALL_CANCEL (getrandom, buffer, length, flags);
+}
+#else
+/* Always provide a definition, even if the kernel headers lack the
+ system call number. */
+ssize_t
+__libc_getrandom (void *buffer, size_t length, unsigned int flags)
+{
+ /* Ideally, we would add a cancellation point here, but we currently
+ cannot do so inside libc. */
+ __set_errno (ENOSYS);
+ return -1;
+}
+#endif
+
+weak_alias (__libc_getrandom, getrandom)
@@ -1855,6 +1855,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2013,6 +2013,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1877,6 +1877,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -92,6 +92,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1969,6 +1969,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2090,6 +2090,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1944,6 +1944,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1942,6 +1942,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1940,6 +1940,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1935,6 +1935,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2131,6 +2131,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1973,6 +1973,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1978,6 +1978,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2178,6 +2178,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -92,6 +92,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1973,6 +1973,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1874,6 +1874,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1859,6 +1859,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1965,6 +1965,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1903,6 +1903,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2097,6 +2097,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2097,6 +2097,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2097,6 +2097,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -1854,6 +1854,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F
@@ -2097,6 +2097,10 @@ GLIBC_2.23 fts64_set F
GLIBC_2.24 GLIBC_2.24 A
GLIBC_2.24 quick_exit F
GLIBC_2.25 GLIBC_2.25 A
+GLIBC_2.25 __libc_getentropy F
+GLIBC_2.25 __libc_getrandom F
+GLIBC_2.25 getentropy F
+GLIBC_2.25 getrandom F
GLIBC_2.25 strfromd F
GLIBC_2.25 strfromf F
GLIBC_2.25 strfroml F