Merge "Revert "Update getentropy_linux.c from upstream.""
This commit is contained in:
commit
9f798246ba
1 changed files with 46 additions and 29 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: getentropy_linux.c,v 1.42 2016/04/19 20:20:24 tj Exp $ */
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.28 2014/07/20 03:24:10 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
|
@ -17,7 +17,7 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Emulation of getentropy(2) as documented at:
|
||||
* http://man.openbsd.org/getentropy.2
|
||||
* http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
|
@ -27,8 +27,8 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#ifdef SYS__sysctl
|
||||
#include <linux/sysctl.h>
|
||||
#ifdef HAVE_SYS_SYSCTL_H
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -51,8 +51,8 @@
|
|||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/sysctl.h>
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
@ -76,7 +76,9 @@
|
|||
int getentropy(void *buf, size_t len);
|
||||
|
||||
static int gotdata(char *buf, size_t len);
|
||||
#ifdef SYS__getrandom
|
||||
static int getentropy_getrandom(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
#ifdef SYS__sysctl
|
||||
static int getentropy_sysctl(void *buf, size_t len);
|
||||
|
@ -93,17 +95,17 @@ getentropy(void *buf, size_t len)
|
|||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SYS__getrandom
|
||||
/*
|
||||
* Try descriptor-less getrandom()
|
||||
*/
|
||||
ret = getentropy_getrandom(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
if (errno != ENOSYS)
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Try to get entropy with /dev/urandom
|
||||
|
@ -120,7 +122,7 @@ getentropy(void *buf, size_t len)
|
|||
* 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
|
||||
* exhausted.
|
||||
* exhuasted.
|
||||
*
|
||||
* However this can fail if the Linux kernel removes support
|
||||
* for sysctl. Starting in 2007, there have been efforts to
|
||||
|
@ -188,26 +190,39 @@ gotdata(char *buf, size_t len)
|
|||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SYS__getrandom
|
||||
static int
|
||||
getentropy_getrandom(void *buf, size_t len)
|
||||
{
|
||||
int pre_errno = errno;
|
||||
int ret;
|
||||
#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
|
||||
struct __getrandom_args args = {
|
||||
.buf = buf;
|
||||
.len = len;
|
||||
.flags = 0;
|
||||
};
|
||||
|
||||
if (len > 256)
|
||||
return (-1);
|
||||
do {
|
||||
ret = syscall(SYS_getrandom, buf, len, 0);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if ((size_t)ret != len)
|
||||
return (-1);
|
||||
errno = pre_errno;
|
||||
return (0);
|
||||
ret = syscall(SYS__getrandom, &args);
|
||||
if (ret == len)
|
||||
return (0);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
getentropy_urandom(void *buf, size_t len)
|
||||
|
@ -260,11 +275,11 @@ start:
|
|||
close(fd);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef SYS__sysctl
|
||||
|
@ -282,7 +297,7 @@ getentropy_sysctl(void *buf, size_t len)
|
|||
struct __sysctl_args args = {
|
||||
.name = mib,
|
||||
.nlen = 3,
|
||||
.oldval = (char *)buf + i,
|
||||
.oldval = (char*) buf + i,
|
||||
.oldlenp = &chunk,
|
||||
};
|
||||
if (syscall(SYS__sysctl, &args) != 0)
|
||||
|
@ -295,12 +310,13 @@ getentropy_sysctl(void *buf, size_t len)
|
|||
}
|
||||
sysctlfailed:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
static const int cl[] = {
|
||||
|
||||
static int cl[] = {
|
||||
CLOCK_REALTIME,
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
CLOCK_MONOTONIC,
|
||||
|
@ -331,7 +347,7 @@ getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data)
|
|||
SHA512_CTX *ctx = data;
|
||||
|
||||
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -540,9 +556,10 @@ getentropy_fallback(void *buf, size_t len)
|
|||
memset(results, 0, sizeof results);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
|
Loading…
Reference in a new issue