public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Cc: GNU C Library <libc-alpha@sourceware.org>,
	Florian Weimer <fweimer@redhat.com>
Subject: Re: [PATCH v3 1/9] stdlib: Add arc4random, arc4random_buf, and arc4random_uniform (BZ #4417)
Date: Tue, 19 Apr 2022 14:52:45 -0700	[thread overview]
Message-ID: <CAMe9rOqMPAARPrYXU1kmc5EjyLCRoY3xq2NJP+UdX6zfA+Jg_A@mail.gmail.com> (raw)
In-Reply-To: <20220419212812.2688764-2-adhemerval.zanella@linaro.org>

On Tue, Apr 19, 2022 at 2:29 PM Adhemerval Zanella via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> The implementation is based on scalar Chacha20, with global cache and
> locking.  It uses getrandom or /dev/urandom as fallback to get the
> initial entropy, and reseeds the internal state on every 16MB of
> consumed buffer.
>
> It maintains an internal buffer which consumes at maximum one page on
> most systems (assuming minimum of 4k pages).  The internal buf optimizes
> the cipher encrypt calls, by amortize arc4random calls (where both
> function call and locks cost are the dominating factor).
>
> The ChaCha20 implementation is based on the RFC8439 [1], with last
> step that XOR with the input omited.  Since the input stream will either
> zero bytes (initial state) or the PRNG output itself this step does not
> add any extra entropy.
>
> The arc4random_uniform is based on previous work by Florian Weimer.
>
> Checked on x86_64-linux-gnu, aarch64-linux, and powerpc64le-linux-gnu.
>
> Co-authored-by: Florian Weimer <fweimer@redhat.com>
>
> [1] https://datatracker.ietf.org/doc/html/rfc8439
> ---
>  NEWS                                          |   4 +-
>  include/stdlib.h                              |  13 +
>  posix/fork.c                                  |   2 +
>  stdlib/Makefile                               |   2 +
>  stdlib/Versions                               |   5 +
>  stdlib/arc4random.c                           | 245 ++++++++++++++++++
>  stdlib/arc4random_uniform.c                   | 152 +++++++++++
>  stdlib/chacha20.c                             | 163 ++++++++++++
>  stdlib/stdlib.h                               |  14 +
>  sysdeps/generic/not-cancel.h                  |   2 +
>  sysdeps/mach/hurd/i386/libc.abilist           |   3 +
>  sysdeps/mach/hurd/not-cancel.h                |   3 +
>  sysdeps/unix/sysv/linux/aarch64/libc.abilist  |   3 +
>  sysdeps/unix/sysv/linux/alpha/libc.abilist    |   3 +
>  sysdeps/unix/sysv/linux/arc/libc.abilist      |   3 +
>  sysdeps/unix/sysv/linux/arm/be/libc.abilist   |   3 +
>  sysdeps/unix/sysv/linux/arm/le/libc.abilist   |   3 +
>  sysdeps/unix/sysv/linux/csky/libc.abilist     |   3 +
>  sysdeps/unix/sysv/linux/hppa/libc.abilist     |   3 +
>  sysdeps/unix/sysv/linux/i386/libc.abilist     |   3 +
>  sysdeps/unix/sysv/linux/ia64/libc.abilist     |   3 +
>  .../sysv/linux/m68k/coldfire/libc.abilist     |   3 +
>  .../unix/sysv/linux/m68k/m680x0/libc.abilist  |   3 +
>  .../sysv/linux/microblaze/be/libc.abilist     |   3 +
>  .../sysv/linux/microblaze/le/libc.abilist     |   3 +
>  .../sysv/linux/mips/mips32/fpu/libc.abilist   |   3 +
>  .../sysv/linux/mips/mips32/nofpu/libc.abilist |   3 +
>  .../sysv/linux/mips/mips64/n32/libc.abilist   |   3 +
>  .../sysv/linux/mips/mips64/n64/libc.abilist   |   3 +
>  sysdeps/unix/sysv/linux/nios2/libc.abilist    |   3 +
>  sysdeps/unix/sysv/linux/not-cancel.h          |   7 +
>  sysdeps/unix/sysv/linux/or1k/libc.abilist     |   3 +
>  .../linux/powerpc/powerpc32/fpu/libc.abilist  |   3 +
>  .../powerpc/powerpc32/nofpu/libc.abilist      |   3 +
>  .../linux/powerpc/powerpc64/be/libc.abilist   |   3 +
>  .../linux/powerpc/powerpc64/le/libc.abilist   |   3 +
>  .../unix/sysv/linux/riscv/rv32/libc.abilist   |   3 +
>  .../unix/sysv/linux/riscv/rv64/libc.abilist   |   3 +
>  .../unix/sysv/linux/s390/s390-32/libc.abilist |   3 +
>  .../unix/sysv/linux/s390/s390-64/libc.abilist |   3 +
>  sysdeps/unix/sysv/linux/sh/be/libc.abilist    |   3 +
>  sysdeps/unix/sysv/linux/sh/le/libc.abilist    |   3 +
>  .../sysv/linux/sparc/sparc32/libc.abilist     |   3 +
>  .../sysv/linux/sparc/sparc64/libc.abilist     |   3 +
>  .../unix/sysv/linux/x86_64/64/libc.abilist    |   3 +
>  .../unix/sysv/linux/x86_64/x32/libc.abilist   |   3 +
>  46 files changed, 713 insertions(+), 1 deletion(-)
>  create mode 100644 stdlib/arc4random.c
>  create mode 100644 stdlib/arc4random_uniform.c
>  create mode 100644 stdlib/chacha20.c
>
> diff --git a/NEWS b/NEWS
> index 4b6d9de2b5..4d9d95b35b 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -9,7 +9,9 @@ Version 2.36
>
>  Major new features:
>
> -  [Add new features here]
> +* The functions arc4random, arc4random_buf, arc4random_uniform have been
> +  added.  The functions use a cryptographic pseudo-random number generator
> +  based on ChaCha20 initilized with entropy from kernel.
                                         ^^^^^^^^ Typo.
>
>  Deprecated and removed features, and other changes affecting compatibility:
>
> diff --git a/include/stdlib.h b/include/stdlib.h
> index 1c6f70b082..055f9d2965 100644
> --- a/include/stdlib.h
> +++ b/include/stdlib.h
> @@ -144,6 +144,19 @@ libc_hidden_proto (__ptsname_r)
>  libc_hidden_proto (grantpt)
>  libc_hidden_proto (unlockpt)
>
> +__typeof (arc4random) __arc4random;
> +libc_hidden_proto (__arc4random);
> +__typeof (arc4random_buf) __arc4random_buf;
> +libc_hidden_proto (__arc4random_buf);
> +__typeof (arc4random_uniform) __arc4random_uniform;
> +libc_hidden_proto (__arc4random_uniform);
> +extern void __arc4random_buf_internal (void *buffer, size_t len)
> +     attribute_hidden;
> +/* Called from the fork function to reinitialize the internal lock in thte
> +   child process.  This avoids deadlocks if fork is called in multi-threaded
> +   processes.  */
> +extern void __arc4random_fork_subprocess (void) attribute_hidden;
> +
>  extern double __strtod_internal (const char *__restrict __nptr,
>                                  char **__restrict __endptr, int __group)
>       __THROW __nonnull ((1)) __wur;
> diff --git a/posix/fork.c b/posix/fork.c
> index 6b50c091f9..87d8329b46 100644
> --- a/posix/fork.c
> +++ b/posix/fork.c
> @@ -96,6 +96,8 @@ __libc_fork (void)
>                                      &nss_database_data);
>         }
>
> +      call_function_static_weak (__arc4random_fork_subprocess);
> +
>        /* Reset the lock the dynamic loader uses to protect its data.  */
>        __rtld_lock_initialize (GL(dl_load_lock));
>
> diff --git a/stdlib/Makefile b/stdlib/Makefile
> index 60fc59c12c..9f9cc1bd7f 100644
> --- a/stdlib/Makefile
> +++ b/stdlib/Makefile
> @@ -53,6 +53,8 @@ routines := \
>    a64l \
>    abort \
>    abs \
> +  arc4random \
> +  arc4random_uniform \
>    at_quick_exit \
>    atof \
>    atoi \
> diff --git a/stdlib/Versions b/stdlib/Versions
> index 5e9099a153..d09a308fb5 100644
> --- a/stdlib/Versions
> +++ b/stdlib/Versions
> @@ -136,6 +136,11 @@ libc {
>      strtof32; strtof64; strtof32x;
>      strtof32_l; strtof64_l; strtof32x_l;
>    }
> +  GLIBC_2.36 {
> +    arc4random;
> +    arc4random_buf;
> +    arc4random_uniform;
> +  }
>    GLIBC_PRIVATE {
>      # functions which have an additional interface since they are
>      # are cancelable.
> diff --git a/stdlib/arc4random.c b/stdlib/arc4random.c
> new file mode 100644
> index 0000000000..cddb0e405a
> --- /dev/null
> +++ b/stdlib/arc4random.c
> @@ -0,0 +1,245 @@
> +/* Pseudo Random Number Generator based on ChaCha20.
> +   Copyright (C) 2020 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 <libc-lock.h>
> +#include <not-cancel.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/mman.h>
> +#include <sys/param.h>
> +#include <sys/random.h>
> +
> +/* Besides the cipher state 'ctx', it keeps two counters: 'have' is the
> +   current valid bytes not yet consumed in 'buf', while 'count' is the maximum
> +   number of bytes until a reseed.
> +
> +   Both the initial seed an reseed tries to obtain entropy from the kernel
                                         ^^^^^^^^^^^^^^^^ Typo?
> +   and abort the process if none could be obtained.
> +
> +   The state 'buf' improves the usage of the cipher call, allowing to call
> +   optimized implementations (if the archictecture provides it) and optimize
                                                              ^^^^^^^^^^^^ Typo?
> +   arc4random calls (since only multiple call it will encrypt the next block).
> + */
> +
> +/* Maximum number bytes until reseed (16 MB).  */
> +#define CHACHE_RESEED_SIZE     (16 * 1024 * 1024)
> +/* Internal buffer size in bytes (1KB).  */
> +#define CHACHA20_BUFSIZE        (8 * CHACHA20_BLOCK_SIZE)
> +
> +#include <chacha20.c>
> +
> +static struct arc4random_state
> +{
> +  uint32_t ctx[CHACHA20_STATE_LEN];
> +  size_t have;
> +  size_t count;
> +  uint8_t buf[CHACHA20_BUFSIZE];
> +} *state;
> +
> +/* Indicate that MADV_WIPEONFORK is supported by the kernel and thus
> +   it does not require to clear the internal state.  */
> +static bool __arc4random_wipeonfork = false;
> +
> +__libc_lock_define_initialized (, __arc4random_lock);
> +
> +/* Called from the fork function to reset the state if MADV_WIPEONFORK is
> +   not supported and to reinit the internal lock.  */
> +void
> +__arc4random_fork_subprocess (void)
> +{
> +  if (__arc4random_wipeonfork && state != NULL)

Should it be !__arc4random_wipeonfork?

> +    memset (state, 0, sizeof (struct arc4random_state));
> +
> +  __libc_lock_init (__arc4random_lock);
> +}
> +
> +static void
> +arc4random_allocate_failure (void)
> +{
> +  __libc_fatal ("Fatal glibc error: Cannot allocate memory for arc4random\n");
> +}
> +
> +static void
> +arc4random_getrandom_failure (void)
> +{
> +  __libc_fatal ("Fatal glibc error: Cannot get entropy for arc4random\n");
> +}
> +
> +/* Fork detection is done by checking if MADV_WIPEONFORK supported.  If not
> +   the fork callback will reset the state on the fork call.  It does not
> +   handle direct clone calls, nor vfork or _Fork (arc4random is not
> +   async-signal-safe due the internal lock usage).  */
> +static void
> +arc4random_init (uint8_t *buf, size_t len)
> +{
> +  state = __mmap (NULL, sizeof (struct arc4random_state),
> +                 PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
> +  if (state == MAP_FAILED)
> +    arc4random_allocate_failure ();
> +
> +#ifdef MADV_WIPEONFORK
> +  int r = __madvise (state, sizeof (struct arc4random_state), MADV_WIPEONFORK);
> +  if (r == 0)
> +    __arc4random_wipeonfork = true;
> +  else if (errno != EINVAL)
> +    arc4random_allocate_failure ();
> +#endif
> +
> +  chacha20_init (state->ctx, buf, buf + CHACHA20_KEY_SIZE);
> +}
> +
> +#define min(x,y) (((x) > (y)) ? (y) : (x))
> +
> +static void
> +arc4random_rekey (uint8_t *rnd, size_t rndlen)
> +{
> +  memset (state->buf, 0, sizeof state->buf);
> +  chacha20_crypt (state->ctx, state->buf, state->buf, sizeof state->buf);
> +
> +  /* Mix some extra entropy if provided.  */
> +  if (rnd != NULL)
> +    {
> +      size_t m = min (rndlen, CHACHA20_KEY_SIZE + CHACHA20_IV_SIZE);
> +      for (size_t i = 0; i < m; i++)
> +       state->buf[i] ^= rnd[i];
> +    }
> +
> +  /* Immediately reinit for backtracking resistance.  */
> +  chacha20_init (state->ctx, state->buf, state->buf + CHACHA20_KEY_SIZE);
> +  memset (state->buf, 0, CHACHA20_KEY_SIZE + CHACHA20_IV_SIZE);
> +  state->have = sizeof (state->buf) - (CHACHA20_KEY_SIZE + CHACHA20_IV_SIZE);
> +}
> +
> +static void
> +arc4random_getentropy (uint8_t *rnd, size_t len)
> +{
> +  if (__getrandomn_nocancel (rnd, len, GRND_NONBLOCK) == len)
> +    return;
> +
> +  int fd = __open64_nocancel ("/dev/urandom", O_RDONLY);
> +  if (fd != -1)
> +    {
> +      unsigned char *p = rnd;
> +      unsigned char *end = p + len;
> +      do
> +       {
> +         ssize_t ret = TEMP_FAILURE_RETRY (__read_nocancel (fd, p, end - p));
> +         if (ret <= 0)
> +           arc4random_getrandom_failure ();
> +         p += ret;
> +       }
> +      while (p < end);
> +
> +      if (__close_nocancel (fd) != 0)
> +       return;
> +    }
> +  arc4random_getrandom_failure ();
> +}
> +
> +/* Either allocates the state buffer or reinit it by reseeding the cipher
> +   state with kernel entropy.  */
> +static void
> +arc4random_stir (void)
> +{
> +  uint8_t rnd[CHACHA20_KEY_SIZE + CHACHA20_IV_SIZE];
> +  arc4random_getentropy (rnd, sizeof rnd);
> +
> +  if (state == NULL)
> +    arc4random_init (rnd, sizeof rnd);
> +  else
> +    arc4random_rekey (rnd, sizeof rnd);
> +
> +  explicit_bzero (rnd, sizeof rnd);
> +
> +  state->have = 0;
> +  memset (state->buf, 0, sizeof state->buf);
> +  state->count = CHACHE_RESEED_SIZE;
> +}
> +
> +static void
> +arc4random_check_stir (size_t len)
> +{
> +  if (state == NULL || state->count < len)
> +    arc4random_stir ();
> +  if (state->count <= len)
> +    state->count = 0;
> +  else
> +    state->count -= len;
> +}
> +
> +void
> +__arc4random_buf_internal (void *buffer, size_t len)
> +{
> +  arc4random_check_stir (len);
> +
> +  while (len > 0)
> +    {
> +      if (state->have > 0)
> +       {
> +         size_t m = min (len, state->have);
> +         uint8_t *ks = state->buf + sizeof (state->buf) - state->have;
> +         memcpy (buffer, ks, m);
> +         memset (ks, 0, m);
> +         buffer += m;
> +         len -= m;
> +         state->have -= m;
> +       }
> +      if (state->have == 0)
> +       arc4random_rekey (NULL, 0);
> +    }
> +}
> +
> +void
> +__arc4random_buf (void *buffer, size_t len)
> +{
> +  __libc_lock_lock (__arc4random_lock);
> +  __arc4random_buf_internal (buffer, len);
> +  __libc_lock_unlock (__arc4random_lock);
> +}
> +libc_hidden_def (__arc4random_buf)
> +weak_alias (__arc4random_buf, arc4random_buf)
> +
> +
> +static uint32_t
> +__arc4random_internal (void)
> +{
> +  uint32_t r;
> +
> +  arc4random_check_stir (sizeof (uint32_t));
> +  if (state->have < sizeof (uint32_t))
> +    arc4random_rekey (NULL, 0);
> +  uint8_t *ks = state->buf + sizeof (state->buf) - state->have;
> +  memcpy (&r, ks, sizeof (uint32_t));
> +  memset (ks, 0, sizeof (uint32_t));
> +  state->have -= sizeof (uint32_t);
> +
> +  return r;
> +}
> +
> +uint32_t
> +__arc4random (void)
> +{
> +  uint32_t r;
> +  __libc_lock_lock (__arc4random_lock);
> +  r = __arc4random_internal ();
> +  __libc_lock_unlock (__arc4random_lock);
> +  return r;
> +}
> +libc_hidden_def (__arc4random)
> +weak_alias (__arc4random, arc4random)
> diff --git a/stdlib/arc4random_uniform.c b/stdlib/arc4random_uniform.c
> new file mode 100644
> index 0000000000..96ffe62df1
> --- /dev/null
> +++ b/stdlib/arc4random_uniform.c
> @@ -0,0 +1,152 @@
> +/* Random pseudo generator numbers between 0 and 2**-31 (inclusive)
> +   uniformly distributed but with an upper_bound.
> +   Copyright (C) 2022 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 <endian.h>
> +#include <libc-lock.h>
> +#include <stdlib.h>
> +#include <sys/param.h>
> +
> +/* Return the number of bytes which cover values up to the limit.  */
> +__attribute__ ((const))
> +static uint32_t
> +byte_count (uint32_t n)
> +{
> +  if (n <= (1U << 8))
> +    return 1;
> +  else if (n <= (1U << 16))
> +    return 2;
> +  else if (n <= (1U << 24))
> +    return 3;
> +  else
> +    return 4;
> +}
> +
> +/* Fill the lower bits of the result with randomness, according to the
> +   number of bytes requested.  */
> +static void
> +random_bytes (uint32_t *result, uint32_t byte_count)
> +{
> +  *result = 0;
> +  unsigned char *ptr = (unsigned char *) result;
> +  if (__BYTE_ORDER == __BIG_ENDIAN)
> +    ptr += 4 - byte_count;
> +  __arc4random_buf_internal (ptr, byte_count);
> +}
> +
> +static uint32_t
> +compute_uniform (uint32_t n)
> +{
> +  if (n <= 1)
> +    /* There is no valid return value for a zero limit, and 0 is the
> +       only possible result for limit 1.  */
> +    return 0;
> +
> +  /* The bits variable serves as a source for bits.  Prefetch the
> +     minimum number of bytes needed.  */
> +  unsigned count = byte_count (n);
> +  uint32_t bits_length = count * CHAR_BIT;
> +  uint32_t bits;
> +  random_bytes (&bits, count);
> +
> +  /* Powers of two are easy.  */
> +  if (powerof2 (n))
> +    return bits & (n - 1);
> +
> +  /* The general case.  This algorithm follows Jérémie Lumbroso,
> +     Optimal Discrete Uniform Generation from Coin Flips, and
> +     Applications (2013), who credits Donald E. Knuth and Andrew
> +     C. Yao, The complexity of nonuniform random number generation
> +     (1976), for solving the general case.
> +
> +     The implementation below unrolls the initialization stage of the
> +     loop, where v is less than n.  */
> +
> +  /* Use 64-bit variables even though the intermediate results are
> +     never larger that 33 bits.  This ensures the code easier to
                               than
> +     compile on 64-bit architectures.  */
> +  uint64_t v;
> +  uint64_t c;
> +
> +  /* Initialize v and c.  v is the smallest power of 2 which is larger
> +     than n.*/
> +  {
> +    uint32_t log2p1 = 32 - __builtin_clz (n);
> +    v = 1ULL << log2p1;
> +    c = bits & (v - 1);
> +    bits >>= log2p1;
> +    bits_length -= log2p1;
> +  }
> +
> +  /* At the start of the loop, c is uniformly distributed within the
> +     half-open interval [0, v), and v < 2n < 2**33.  */
> +  while (true)
> +    {
> +      if (v >= n)
> +        {
> +          /* If the candidate is less than n, accept it.  */
> +          if (c < n)
> +            /* c is uniformly distributed on [0, n).  */
> +            return c;
> +          else
> +            {
> +              /* c is uniformly distributed on [n, v).  */
> +              v -= n;
> +              c -= n;
> +              /* The distribution was shifted, so c is uniformly
> +                 distributed on [0, v) again.  */
> +            }
> +        }
> +      /* v < n here.  */
> +
> +      /* Replenish the bit source if necessary.  */
> +      if (bits_length == 0)
> +        {
> +          /* Overwrite the least significant byte.  */
> +         random_bytes (&bits, 1);
> +         bits_length = CHAR_BIT;
> +        }
> +
> +      /* Double the range.  No overflow because v < n < 2**32.  */
> +      v *= 2;
> +      /* v < 2n here.  */
> +
> +      /* Extract a bit and append it to c.  c remains less than v and
> +         thus 2**33.  */
> +      c = (c << 1) | (bits & 1);
> +      bits >>= 1;
> +      --bits_length;
> +
> +      /* At this point, c is uniformly distributed on [0, v) again,
> +         and v < 2n < 2**33.  */
> +    }
> +}
> +
> +__libc_lock_define (extern , __arc4random_lock attribute_hidden)
> +
> +uint32_t
> +__arc4random_uniform (uint32_t upper_bound)
> +{
> +  uint32_t r;
> +  __libc_lock_lock (__arc4random_lock);
> +  r = compute_uniform (upper_bound);
> +  __libc_lock_unlock (__arc4random_lock);
> +  return r;
> +}
> +libc_hidden_def (__arc4random_uniform)
> +weak_alias (__arc4random_uniform, arc4random_uniform)
> diff --git a/stdlib/chacha20.c b/stdlib/chacha20.c
> new file mode 100644
> index 0000000000..af4ffa9860
> --- /dev/null
> +++ b/stdlib/chacha20.c
> @@ -0,0 +1,163 @@
> +/* Generic ChaCha20 implementation (used on arc4random).
> +   Copyright (C) 2022 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 <array_length.h>
> +#include <endian.h>
> +#include <stddef.h>
> +#include <stdint.h>
> +#include <string.h>
> +
> +/* 32-bit stream position, then 96-bit nonce.  */
> +#define CHACHA20_IV_SIZE       16
> +#define CHACHA20_KEY_SIZE      32
> +
> +#define CHACHA20_BLOCK_SIZE     64
> +#define CHACHA20_BLOCK_WORDS    (CHACHA20_BLOCK_SIZE / sizeof (uint32_t))
> +
> +#define CHACHA20_STATE_LEN     16
> +
> +/* Defining CHACHA20_XOR_FINAL issues the final XOR using the input as defined
> +   Sby RFC8439.  Since the input stream will either zero bytes (initial state)
         by
> +   or the PRNG output itself this step does not add any extra entropy.   */
> +
> +enum chacha20_constants
> +{
> +  CHACHA20_CONSTANT_EXPA = 0x61707865U,
> +  CHACHA20_CONSTANT_ND_3 = 0x3320646eU,
> +  CHACHA20_CONSTANT_2_BY = 0x79622d32U,
> +  CHACHA20_CONSTANT_TE_K = 0x6b206574U
> +};
> +
> +static inline uint32_t
> +read_unaligned_32 (const uint8_t *p)
> +{
> +  uint32_t r;
> +  memcpy (&r, p, sizeof (r));
> +  return r;
> +}
> +
> +static inline void
> +write_unaligned_32 (uint8_t *p, uint32_t v)
> +{
> +  memcpy (p, &v, sizeof (v));
> +}
> +
> +#if __BYTE_ORDER == __BIG_ENDIAN
> +# define read_unaligned_le32(p) __builtin_bswap32 (read_unaligned_32 (p))
> +# define set_state(v)          __builtin_bswap32 ((v))
> +#else
> +# define read_unaligned_le32(p) read_unaligned_32 ((p))
> +# define set_state(v)          (v)
> +#endif
> +
> +static inline void
> +chacha20_init (uint32_t *state, const uint8_t *key, const uint8_t *iv)
> +{
> +  state[0]  = CHACHA20_CONSTANT_EXPA;
> +  state[1]  = CHACHA20_CONSTANT_ND_3;
> +  state[2]  = CHACHA20_CONSTANT_2_BY;
> +  state[3]  = CHACHA20_CONSTANT_TE_K;
> +
> +  state[4]  = read_unaligned_le32 (key + 0 * sizeof (uint32_t));
> +  state[5]  = read_unaligned_le32 (key + 1 * sizeof (uint32_t));
> +  state[6]  = read_unaligned_le32 (key + 2 * sizeof (uint32_t));
> +  state[7]  = read_unaligned_le32 (key + 3 * sizeof (uint32_t));
> +  state[8]  = read_unaligned_le32 (key + 4 * sizeof (uint32_t));
> +  state[9]  = read_unaligned_le32 (key + 5 * sizeof (uint32_t));
> +  state[10] = read_unaligned_le32 (key + 6 * sizeof (uint32_t));
> +  state[11] = read_unaligned_le32 (key + 7 * sizeof (uint32_t));
> +
> +  state[12] = read_unaligned_le32 (iv + 0 * sizeof (uint32_t));
> +  state[13] = read_unaligned_le32 (iv + 1 * sizeof (uint32_t));
> +  state[14] = read_unaligned_le32 (iv + 2 * sizeof (uint32_t));
> +  state[15] = read_unaligned_le32 (iv + 3 * sizeof (uint32_t));
> +}
> +
> +static inline uint32_t
> +rotl32 (unsigned int shift, uint32_t word)
> +{
> +  return (word << (shift & 31)) | (word >> ((-shift) & 31));
> +}
> +
> +#define QROUND(x0, x1, x2, x3)                         \
> +  do {                                         \
> +   x0 = x0 + x1; x3 = rotl32 (16, (x0 ^ x3));  \
> +   x2 = x2 + x3; x1 = rotl32 (12, (x1 ^ x2));  \
> +   x0 = x0 + x1; x3 = rotl32 (8,  (x0 ^ x3));  \
> +   x2 = x2 + x3; x1 = rotl32 (7,  (x1 ^ x2));  \
> +  } while(0)
> +
> +static inline void
> +chacha20_block (uint32_t *state, uint32_t *stream)
> +{
> +  uint32_t x[CHACHA20_STATE_LEN];
> +  memcpy (x, state, sizeof x);
> +
> +  for (int i = 0; i < 20; i += 2)
> +    {
> +      QROUND (x[0], x[4], x[8],  x[12]);
> +      QROUND (x[1], x[5], x[9],  x[13]);
> +      QROUND (x[2], x[6], x[10], x[14]);
> +      QROUND (x[3], x[7], x[11], x[15]);
> +
> +      QROUND (x[0], x[5], x[10], x[15]);
> +      QROUND (x[1], x[6], x[11], x[12]);
> +      QROUND (x[2], x[7], x[8],  x[13]);
> +      QROUND (x[3], x[4], x[9],  x[14]);
> +    }
> +
> +  /* Unroll the loop a bit.  */
> +  for (int i = 0; i < CHACHA20_BLOCK_WORDS / 4; i++)
> +    {
> +      stream[i*4+0] = set_state (x[i*4+0] + state[i*4+0]);
> +      stream[i*4+1] = set_state (x[i*4+1] + state[i*4+1]);
> +      stream[i*4+2] = set_state (x[i*4+2] + state[i*4+2]);
> +      stream[i*4+3] = set_state (x[i*4+3] + state[i*4+3]);
> +    }
> +
> +  state[12]++;
> +}
> +
> +static void
> +chacha20_crypt (uint32_t *state, uint8_t *dst, const uint8_t *src,
> +               size_t bytes)
> +{
> +  uint32_t stream[CHACHA20_BLOCK_WORDS];
> +
> +  while (bytes >= CHACHA20_BLOCK_SIZE)
> +    {
> +      chacha20_block (state, stream);
> +#ifdef CHACHA20_XOR_FINAL
> +      for (int i = 0; i < CHACHA20_BLOCK_WORDS; i++)
> +       stream[i] ^= read_unaligned_32 (&src[i * sizeof (uint32_t)]);
> +#endif
> +      memcpy (dst, stream, CHACHA20_BLOCK_SIZE);
> +      bytes -= CHACHA20_BLOCK_SIZE;
> +      dst += CHACHA20_BLOCK_SIZE;
> +      src += CHACHA20_BLOCK_SIZE;
> +    }
> +  if (bytes != 0)
> +    {
> +      chacha20_block (state, stream);
> +#ifdef CHACHA20_XOR_FINAL
> +      for (int i = 0; i < CHACHA20_BLOCK_WORDS; i++)
> +       stream[i] ^= read_unaligned_32 (&src[i * sizeof (uint32_t)]);
> +#endif
> +      memcpy (dst, stream, bytes);
> +    }
> +}
> diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
> index bf7cd438e1..f2b0c83c12 100644
> --- a/stdlib/stdlib.h
> +++ b/stdlib/stdlib.h
> @@ -485,6 +485,7 @@ extern unsigned short int *seed48 (unsigned short int __seed16v[3])
>  extern void lcong48 (unsigned short int __param[7]) __THROW __nonnull ((1));
>
>  # ifdef __USE_MISC
> +#  include <bits/stdint-uintn.h>
>  /* Data structure for communication with thread safe versions.  This
>     type is to be regarded as opaque.  It's only exported because users
>     have to allocate objects of this type.  */
> @@ -533,6 +534,19 @@ extern int seed48_r (unsigned short int __seed16v[3],
>  extern int lcong48_r (unsigned short int __param[7],
>                       struct drand48_data *__buffer)
>       __THROW __nonnull ((1, 2));
> +
> +/* Return a random integer between zero and 2**31-1 (inclusive).  */
> +extern uint32_t arc4random (void)
> +     __THROW __wur;
> +
> +/* Fill the buffer with random data.  */
> +extern void arc4random_buf (void *__buf, size_t __size)
> +     __THROW __nonnull ((1));
> +
> +/* Return a random number between zero (inclusive) and the specified
> +   limit (exclusive).  */
> +extern uint32_t arc4random_uniform (uint32_t __upper_bound)
> +     __THROW __wur;
>  # endif        /* Use misc.  */
>  #endif /* Use misc or X/Open.  */
>
> diff --git a/sysdeps/generic/not-cancel.h b/sysdeps/generic/not-cancel.h
> index 2104efeb54..f4882a9ffd 100644
> --- a/sysdeps/generic/not-cancel.h
> +++ b/sysdeps/generic/not-cancel.h
> @@ -48,5 +48,7 @@
>    (void) __writev (fd, iov, n)
>  #define __fcntl64_nocancel(fd, cmd, ...) \
>    __fcntl64 (fd, cmd, __VA_ARGS__)
> +#define __getrandomn_nocancel(buf, size, flags) \
> +  __getrandom (buf, size, flags)
>
>  #endif /* NOT_CANCEL_H  */
> diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist
> index 4dc87e9061..7bd565103b 100644
> --- a/sysdeps/mach/hurd/i386/libc.abilist
> +++ b/sysdeps/mach/hurd/i386/libc.abilist
> @@ -2289,6 +2289,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 close_range F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/mach/hurd/not-cancel.h b/sysdeps/mach/hurd/not-cancel.h
> index 6ec92ced84..39edfe76b6 100644
> --- a/sysdeps/mach/hurd/not-cancel.h
> +++ b/sysdeps/mach/hurd/not-cancel.h
> @@ -74,6 +74,9 @@ __typeof (__fcntl) __fcntl_nocancel;
>  #define __fcntl64_nocancel(...) \
>    __fcntl_nocancel (__VA_ARGS__)
>
> +#define __getrandomn_nocancel(buf, size, flags) \
> +  __getrandom (buf, size, flags)
> +
>  #if IS_IN (libc)
>  hidden_proto (__close_nocancel)
>  hidden_proto (__close_nocancel_nostatus)
> diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> index 1b63d9e447..f8f38bb205 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist
> @@ -2616,3 +2616,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> index e7e4cf7d2a..9de1726de0 100644
> --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist
> @@ -2713,6 +2713,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist
> index bc3d228e31..16e2532838 100644
> --- a/sysdeps/unix/sysv/linux/arc/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist
> @@ -2377,3 +2377,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> index db7039c4ab..ae9e465088 100644
> --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist
> @@ -496,6 +496,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
>  GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> index d2add4fb49..b669f43194 100644
> --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist
> @@ -493,6 +493,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0xa0
>  GLIBC_2.4 _IO_2_1_stdin_ D 0xa0
> diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist
> index 355d72a30c..42daa90248 100644
> --- a/sysdeps/unix/sysv/linux/csky/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist
> @@ -2652,3 +2652,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> index 3df39bb28c..090be20f53 100644
> --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist
> @@ -2601,6 +2601,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist
> index c4da358f80..6b7cf064bb 100644
> --- a/sysdeps/unix/sysv/linux/i386/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist
> @@ -2785,6 +2785,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> index 241bac70ea..3e766f64dd 100644
> --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist
> @@ -2551,6 +2551,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> index 78bf372b72..c0b99199a8 100644
> --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist
> @@ -497,6 +497,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _Exit F
>  GLIBC_2.4 _IO_2_1_stderr_ D 0x98
>  GLIBC_2.4 _IO_2_1_stdin_ D 0x98
> diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> index 00df5c901f..4d0be7c86d 100644
> --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist
> @@ -2728,6 +2728,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> index e8118569c3..b944680ede 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist
> @@ -2701,3 +2701,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> index c0d2373e64..28f7d19983 100644
> --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist
> @@ -2698,3 +2698,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> index 2d0fd04f54..3da7cdaca5 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
> @@ -2693,6 +2693,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> index e39ccfb312..9fe87f15be 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
> @@ -2691,6 +2691,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> index 1e900f86e4..c14fca2111 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
> @@ -2699,6 +2699,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> index 9145ba7931..a363830226 100644
> --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
> @@ -2602,6 +2602,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> index e95d60d926..89b6f98667 100644
> --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist
> @@ -2740,3 +2740,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/not-cancel.h b/sysdeps/unix/sysv/linux/not-cancel.h
> index 75b9e0ee1e..be5df35927 100644
> --- a/sysdeps/unix/sysv/linux/not-cancel.h
> +++ b/sysdeps/unix/sysv/linux/not-cancel.h
> @@ -67,6 +67,13 @@ __writev_nocancel_nostatus (int fd, const struct iovec *iov, int iovcnt)
>    INTERNAL_SYSCALL_CALL (writev, fd, iov, iovcnt);
>  }
>
> +static inline int
> +__getrandomn_nocancel (void *buf, size_t buflen, unsigned int flags)
> +{
> +  return INTERNAL_SYSCALL_CALL (getrandom, buf, buflen, flags);
> +}
> +
> +
>  /* Uncancelable fcntl.  */
>  __typeof (__fcntl) __fcntl64_nocancel;
>
> diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> index ca934e374b..94c0ff9526 100644
> --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist
> @@ -2123,3 +2123,6 @@ GLIBC_2.35 wprintf F
>  GLIBC_2.35 write F
>  GLIBC_2.35 writev F
>  GLIBC_2.35 wscanf F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> index 3820b9f235..d6188de00b 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
> @@ -2755,6 +2755,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> index 464dc27fcd..8201230059 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
> @@ -2788,6 +2788,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> index 2f7e58747f..623505d783 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
> @@ -2510,6 +2510,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> index 4f3043d913..23b0d83408 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
> @@ -2812,3 +2812,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> index 84b6ac815a..a72e8ed9cc 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
> @@ -2379,3 +2379,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> index 4d5c19c56a..f3faecc2ae 100644
> --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
> @@ -2579,3 +2579,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> index 7c5ee8d569..105e5a9231 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist
> @@ -2753,6 +2753,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> index 50de0b46cf..c08c6c8301 100644
> --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist
> @@ -2547,6 +2547,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> index 66fba013ca..8ec1005644 100644
> --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist
> @@ -2608,6 +2608,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> index 38703f8aa0..5d776576f9 100644
> --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist
> @@ -2605,6 +2605,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> index 6df55eb765..f5f07f612e 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist
> @@ -2748,6 +2748,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 _IO_fprintf F
>  GLIBC_2.4 _IO_printf F
>  GLIBC_2.4 _IO_sprintf F
> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> index b90569d881..be687ebe02 100644
> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist
> @@ -2574,6 +2574,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> index e88b0f101f..7f456fbb55 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist
> @@ -2525,6 +2525,9 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
>  GLIBC_2.4 __confstr_chk F
>  GLIBC_2.4 __fgets_chk F
>  GLIBC_2.4 __fgets_unlocked_chk F
> diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> index e0755272eb..c737201248 100644
> --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist
> @@ -2631,3 +2631,6 @@ GLIBC_2.35 __memcmpeq F
>  GLIBC_2.35 _dl_find_object F
>  GLIBC_2.35 epoll_pwait2 F
>  GLIBC_2.35 posix_spawn_file_actions_addtcsetpgrp_np F
> +GLIBC_2.36 arc4random F
> +GLIBC_2.36 arc4random_buf F
> +GLIBC_2.36 arc4random_uniform F
> --
> 2.32.0
>


-- 
H.J.

  reply	other threads:[~2022-04-19 21:53 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-19 21:28 [PATCH v3 0/9] Add arc4random support Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 1/9] stdlib: Add arc4random, arc4random_buf, and arc4random_uniform (BZ #4417) Adhemerval Zanella
2022-04-19 21:52   ` H.J. Lu [this message]
2022-04-20 12:38     ` Adhemerval Zanella
2022-04-22 13:54   ` Yann Droneaud
2022-04-25 12:15     ` Adhemerval Zanella
2022-04-25 12:20       ` Adhemerval Zanella
2022-04-25  2:22   ` Mark Harris
2022-04-25 12:26     ` Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 2/9] stdlib: Add arc4random tests Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 3/9] benchtests: Add arc4random benchtest Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 4/9] aarch64: Add optimized chacha20 Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 5/9] x86: Add SSE2 " Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 6/9] x86: Add AVX2 " Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 7/9] powerpc64: Add " Adhemerval Zanella
2022-04-20 18:38   ` Paul E Murphy
2022-04-20 19:23     ` Adhemerval Zanella
2022-04-22 21:09       ` Paul E Murphy
2022-04-19 21:28 ` [PATCH v3 8/9] s390x: " Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 9/9] stdlib: Add TLS optimization to arc4random Adhemerval Zanella
2022-04-22 16:02   ` Yann Droneaud
2022-04-25 12:36     ` Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAMe9rOqMPAARPrYXU1kmc5EjyLCRoY3xq2NJP+UdX6zfA+Jg_A@mail.gmail.com \
    --to=hjl.tools@gmail.com \
    --cc=adhemerval.zanella@linaro.org \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).