From e285ea02b573ac4cf4cd0d98667002f0c46dca97 Mon Sep 17 00:00:00 2001 From: bcook <> Date: Sat, 16 Aug 2014 17:21:56 +0000 Subject: [PATCH] getrandom(2) support for getentropy_linux This enables support for the new getrandom(2) syscall in Linux 3.17. If the call exists and fails, return a failure in getentropy(2) emulation as well. This adds a EINTR check in case the urandom pool is not initialized. Tested on Fedora Rawhide with 3.17rc0 and Ubuntu 14.04 ok deraadt@ --- .../libcrypto/arc4random/getentropy_linux.c | 23 ++++++++----------- src/lib/libcrypto/crypto/getentropy_linux.c | 23 ++++++++----------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/lib/libcrypto/arc4random/getentropy_linux.c b/src/lib/libcrypto/arc4random/getentropy_linux.c index 59bc3628..a84f7ad8 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.32 2014/07/22 01:15:58 bcook Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.33 2014/08/16 17:21:56 bcook Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -98,6 +98,8 @@ getentropy(void *buf, size_t len) ret = getentropy_getrandom(buf, len); if (ret != -1) return (ret); + if (errno != ENOSYS) + return (-1); /* * Try to get entropy with /dev/urandom @@ -187,23 +189,18 @@ gotdata(char *buf, size_t len) static int getentropy_getrandom(void *buf, size_t len) { -#if 0 - -/* Hand-definitions until the API becomes commonplace */ -#ifndef SYS__getrandom -#ifdef __LP64__ -#define SYS__getrandom 317 -#else -#define SYS__getrandom 354 -#endif -#endif +#ifdef SYS_getrandom + int ret; if (len > 256) return (-1); - ret = syscall(SYS__getrandom, buf, len, 0); + do { + ret = syscall(SYS_getrandom, buf, len, 0); + } while (ret == -1 && errno == EINTR); + if (ret == len) return (0); #endif - return -1; + return (-1); } static int diff --git a/src/lib/libcrypto/crypto/getentropy_linux.c b/src/lib/libcrypto/crypto/getentropy_linux.c index 59bc3628..a84f7ad8 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.32 2014/07/22 01:15:58 bcook Exp $ */ +/* $OpenBSD: getentropy_linux.c,v 1.33 2014/08/16 17:21:56 bcook Exp $ */ /* * Copyright (c) 2014 Theo de Raadt @@ -98,6 +98,8 @@ getentropy(void *buf, size_t len) ret = getentropy_getrandom(buf, len); if (ret != -1) return (ret); + if (errno != ENOSYS) + return (-1); /* * Try to get entropy with /dev/urandom @@ -187,23 +189,18 @@ gotdata(char *buf, size_t len) static int getentropy_getrandom(void *buf, size_t len) { -#if 0 - -/* Hand-definitions until the API becomes commonplace */ -#ifndef SYS__getrandom -#ifdef __LP64__ -#define SYS__getrandom 317 -#else -#define SYS__getrandom 354 -#endif -#endif +#ifdef SYS_getrandom + int ret; if (len > 256) return (-1); - ret = syscall(SYS__getrandom, buf, len, 0); + do { + ret = syscall(SYS_getrandom, buf, len, 0); + } while (ret == -1 && errno == EINTR); + if (ret == len) return (0); #endif - return -1; + return (-1); } static int