Exemplo n.º 1
0
int getentropy(void* buffer, size_t buffer_size) {
  if (buffer_size > 256) {
    errno = EIO;
    return -1;
  }

  int saved_errno = errno;

  size_t collected = 0;
  while (collected < buffer_size) {
    long count = TEMP_FAILURE_RETRY(getrandom(static_cast<char*>(buffer) + collected,
                                              buffer_size - collected, GRND_NONBLOCK));
    if (count == -1) {
      // EAGAIN: there isn't enough entropy right now.
      // ENOSYS/EINVAL: getrandom(2) or GRND_NONBLOCK isn't supported.
      // EFAULT: `buffer` is invalid.
      // Try /dev/urandom regardless because it can't hurt,
      // and we don't need to optimize the EFAULT case.
      // See http://b/33059407 and http://b/67015565.
      return getentropy_urandom(buffer, buffer_size, saved_errno);
    }
    collected += count;
  }

  errno = saved_errno;
  return 0;
}
Exemplo n.º 2
0
int
getentropy(void *buf, size_t len)
{
	int ret = -1;

	if (len > 256) {
		errno = EIO;
		return (-1);
	}

	/*
	 * Try to get entropy with /dev/urandom
	 *
	 * This can fail if the process is inside a chroot or if file
	 * descriptors are exhausted.
	 */
	ret = getentropy_urandom(buf, len);
	if (ret != -1)
		return (ret);

	/*
	 * Entropy collection via /dev/urandom and sysctl have failed.
	 *
	 * No other API exists for collecting entropy, and we have
	 * no failsafe way to get it on OSX that is not sensitive
	 * to resource exhaustion.
	 *
	 * We have very few options:
	 *     - Even syslog_r is unsafe to call at this low level, so
	 *	 there is no way to alert the user or program.
	 *     - Cannot call abort() because some systems have unsafe
	 *	 corefiles.
	 *     - Could raise(SIGKILL) resulting in silent program termination.
	 *     - Return EIO, to hint that arc4random's stir function
	 *       should raise(SIGKILL)
	 *     - Do the best under the circumstances....
	 *
	 * This code path exists to bring light to the issue that OSX
	 * does not provide a failsafe API for entropy collection.
	 *
	 * We hope this demonstrates that OSX should consider
	 * providing a new failsafe API which works in a chroot or
	 * when file descriptors are exhausted.
	 */
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
	raise(SIGKILL);
#endif
	ret = getentropy_fallback(buf, len);
	if (ret != -1)
		return (ret);

	errno = EIO;
	return (ret);
}
Exemplo n.º 3
0
int
getentropy(void *buf, size_t len)
{
	int ret = -1;

	if (len > 256) {
		errno = EIO;
		return -1;
	}

	/*
	 * Try to get entropy with /dev/urandom
	 *
	 * This can fail if the process is inside a chroot or if file
	 * descriptors are exhausted.
	 */
	ret = getentropy_urandom(buf, len);
	if (ret != -1)
		return (ret);

#ifdef CTL_MAXNAME
	/*
	 * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
	 * sysctl is a failsafe API, so it guarantees a result.  This
	 * should work inside a chroot, or when file descriptors are
	 * exhuasted.
	 *
	 * However this can fail if the Linux kernel removes support
	 * for sysctl.  Starting in 2007, there have been efforts to
	 * deprecate the sysctl API/ABI, and push callers towards use
	 * of the chroot-unavailable fd-using /proc mechanism --
	 * essentially the same problems as /dev/urandom.
	 *
	 * Numerous setbacks have been encountered in their deprecation
	 * schedule, so as of June 2014 the kernel ABI still exists on
	 * most Linux architectures. The sysctl() stub in libc is missing
	 * on some systems.  There are also reports that some kernels
	 * spew messages to the console.
	 */
	ret = getentropy_sysctl(buf, len);
	if (ret != -1)
		return (ret);
#endif /* CTL_MAXNAME */

	/*
	 * Entropy collection via /dev/urandom and sysctl have failed.
	 *
	 * No other API exists for collecting entropy.  See the large
	 * comment block above.
	 *
	 * We have very few options:
	 *     - Even syslog_r is unsafe to call at this low level, so
	 *	 there is no way to alert the user or program.
	 *     - Cannot call abort() because some systems have unsafe
	 *	 corefiles.
	 *     - Could raise(SIGKILL) resulting in silent program termination.
	 *     - Return EIO, to hint that arc4random's stir function
	 *       should raise(SIGKILL)
	 *     - Do the best under the circumstances....
	 *
	 * This code path exists to bring light to the issue that Linux
	 * does not provide a failsafe API for entropy collection.
	 *
	 * We hope this demonstrates that Linux should either retain their
	 * sysctl ABI, or consider providing a new failsafe API which
	 * works in a chroot or when file descriptors are exhausted.
	 */
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
	raise(SIGKILL);
#endif
	ret = getentropy_fallback(buf, len);
	if (ret != -1)
		return (ret);

	errno = EIO;
	return (ret);
}
Exemplo n.º 4
0
int
getentropy(void *buf, size_t len)
{
	int ret = -1;

	if (len > 256) {
		errno = EIO;
		return -1;
	}

	/*
	 * Try to get entropy with /dev/urandom
	 *
	 * Solaris provides /dev/urandom as a symbolic link to
	 * /devices/pseudo/random@0:urandom which is provided by
	 * a devfs filesystem.  Best practice is to use O_NOFOLLOW,
	 * so we must try the unpublished name directly.
	 *
	 * This can fail if the process is inside a chroot which lacks
	 * the devfs mount, or if file descriptors are exhausted.
	 */
	ret = getentropy_urandom(buf, len,
	    "/devices/pseudo/random@0:urandom", 1);
	if (ret != -1)
		return (ret);

	/*
	 * Unfortunately, chroot spaces on Solaris are sometimes setup
	 * with direct device node of the well-known /dev/urandom name
	 * (perhaps to avoid dragging all of devfs into the space).
	 *
	 * This can fail if the process is inside a chroot or if file
	 * descriptors are exhausted.
	 */
	ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
	if (ret != -1)
		return (ret);

	/*
	 * Entropy collection via /dev/urandom has failed.
	 *
	 * No other API exists for collecting entropy, and we have
	 * no failsafe way to get it on Solaris that is not sensitive
	 * to resource exhaustion.
	 *
	 * We have very few options:
	 *     - Even syslog_r is unsafe to call at this low level, so
	 *	 there is no way to alert the user or program.
	 *     - Cannot call abort() because some systems have unsafe
	 *	 corefiles.
	 *     - Could raise(SIGKILL) resulting in silent program termination.
	 *     - Return EIO, to hint that arc4random's stir function
	 *       should raise(SIGKILL)
	 *     - Do the best under the circumstances....
	 *
	 * This code path exists to bring light to the issue that Solaris
	 * does not provide a failsafe API for entropy collection.
	 *
	 * We hope this demonstrates that Solaris should consider
	 * providing a new failsafe API which works in a chroot or
	 * when file descriptors are exhausted.
	 */
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
	raise(SIGKILL);
#endif
	ret = getentropy_fallback(buf, len);
	if (ret != -1)
		return (ret);

	errno = EIO;
	return (ret);
}