Re: [PATCH v3] arc4random: simplify design for better safety

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As before, I'll paste the main function in question standalone so that
this is a bit easier to read for those not applying this to an actual
tree.

void
__arc4random_buf (void *p, size_t n)
{
  static bool have_getrandom = true, seen_initialized = false;
  int fd;

  if (n == 0)
    return;

  for (;;)
    {
      ssize_t l;

      if (!have_getrandom)
	break;

      l = __getrandom_nocancel (p, n, 0);
      if (l > 0)
	{
	  if ((size_t) l == n)
	    return; /* Done reading, success. */
	  p = (uint8_t *) p + l;
	  n -= l;
	  continue; /* Interrupted by a signal; keep going. */
	}
      else if (l == 0)
	arc4random_getrandom_failure (); /* Weird, should never happen. */
      else if (l == -EINTR)
	continue; /* Interrupted by a signal; keep going. */
      else if (l == -ENOSYS)
	{
	  have_getrandom = false;
	  break; /* No syscall, so fallback to /dev/urandom. */
	}
      arc4random_getrandom_failure (); /* Unknown error, should never happen. */
    }

  if (!seen_initialized)
    {
      struct pollfd pfd = { .events = POLLIN };
      pfd.fd = TEMP_FAILURE_RETRY (
	  __open64_nocancel ("/dev/random", O_RDONLY | O_CLOEXEC | O_NOCTTY));
      if (pfd.fd < 0)
	arc4random_getrandom_failure ();
      if (TEMP_FAILURE_RETRY (__poll_nocancel (&pfd, 1, -1)) < 0)
	arc4random_getrandom_failure ();
      if (__close_nocancel (pfd.fd) < 0)
	arc4random_getrandom_failure ();
      seen_initialized = true;
    }

  fd = TEMP_FAILURE_RETRY (
      __open64_nocancel ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY));
  if (fd < 0)
    arc4random_getrandom_failure ();
  do
    {
      ssize_t l = TEMP_FAILURE_RETRY (__read_nocancel (fd, p, n));
      if (l <= 0)
	arc4random_getrandom_failure ();
      p = (uint8_t *) p + l;
      n -= l;
    }
  while (n);
  if (__close_nocancel (fd) < 0)
    arc4random_getrandom_failure ();
}



[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]
  Powered by Linux