diff --git a/src/lib/libcrypto/arc4random/getentropy_linux.c b/src/lib/libcrypto/arc4random/getentropy_linux.c index 1a22d2d3..993c1d2a 100644 --- a/src/lib/libcrypto/arc4random/getentropy_linux.c +++ b/src/lib/libcrypto/arc4random/getentropy_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_linux.c,v 1.1 2014/06/20 19:08:11 beck Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.2 2014/06/20 19:53:36 otto Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -61,8 +61,86 @@ int getentropy(void *buf, size_t len); -extern int main(int, char *argv[]); static int gotdata(char *buf, size_t len); +static int getentropy_urandom(void *buf, size_t len); +static int getentropy_sysctl(void *buf, size_t len); +static int getentropy_fallback(void *buf, size_t len); + +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 RANDOM_UUID + /* + * 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. 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 /* RANDOM_UUID */ + + /* + * 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_HARD_WHEN_LINUX_DEPRECATES_SYSCTL +#ifdef FAIL_HARD_WHEN_LINUX_DEPRECATES_SYSCTL + raise(SIGKILL); +#endif + ret = getentropy_fallback(buf, len); + if (ret != -1) + return (ret); + + errno = EIO; + return (ret); +} /* * XXX Should be replaced with a proper entropy measure. @@ -361,79 +439,3 @@ getentropy_fallback(void *buf, size_t len) errno = EIO; return -1; } - -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 RANDOM_UUID - /* - * 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. 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 /* RANDOM_UUID */ - - /* - * 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_HARD_WHEN_LINUX_DEPRECATES_SYSCTL -#ifdef FAIL_HARD_WHEN_LINUX_DEPRECATES_SYSCTL - raise(SIGKILL); -#endif - ret = getentropy_fallback(buf, len); - if (ret != -1) - return (ret); - - errno = EIO; - return (ret); -} diff --git a/src/lib/libcrypto/crypto/getentropy_linux.c b/src/lib/libcrypto/crypto/getentropy_linux.c index 1a22d2d3..993c1d2a 100644 --- a/src/lib/libcrypto/crypto/getentropy_linux.c +++ b/src/lib/libcrypto/crypto/getentropy_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getentropy_linux.c,v 1.1 2014/06/20 19:08:11 beck Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.2 2014/06/20 19:53:36 otto Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -61,8 +61,86 @@ int getentropy(void *buf, size_t len); -extern int main(int, char *argv[]); static int gotdata(char *buf, size_t len); +static int getentropy_urandom(void *buf, size_t len); +static int getentropy_sysctl(void *buf, size_t len); +static int getentropy_fallback(void *buf, size_t len); + +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 RANDOM_UUID + /* + * 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. 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 /* RANDOM_UUID */ + + /* + * 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_HARD_WHEN_LINUX_DEPRECATES_SYSCTL +#ifdef FAIL_HARD_WHEN_LINUX_DEPRECATES_SYSCTL + raise(SIGKILL); +#endif + ret = getentropy_fallback(buf, len); + if (ret != -1) + return (ret); + + errno = EIO; + return (ret); +} /* * XXX Should be replaced with a proper entropy measure. @@ -361,79 +439,3 @@ getentropy_fallback(void *buf, size_t len) errno = EIO; return -1; } - -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 RANDOM_UUID - /* - * 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. 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 /* RANDOM_UUID */ - - /* - * 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_HARD_WHEN_LINUX_DEPRECATES_SYSCTL -#ifdef FAIL_HARD_WHEN_LINUX_DEPRECATES_SYSCTL - raise(SIGKILL); -#endif - ret = getentropy_fallback(buf, len); - if (ret != -1) - return (ret); - - errno = EIO; - return (ret); -}