Add Windows support for getentropy() and arc4random()

Import from OpenBSD.
This commit is contained in:
Guillem Jover 2018-05-15 00:55:02 +02:00
parent 6f68c93076
commit a1730c1063
6 changed files with 145 additions and 0 deletions

View File

@ -449,6 +449,7 @@ Files:
src/arc4random_openbsd.h src/arc4random_openbsd.h
src/arc4random_uniform.c src/arc4random_uniform.c
src/arc4random_unix.h src/arc4random_unix.h
src/arc4random_win.h
src/closefrom.c src/closefrom.c
src/getentropy_aix.c src/getentropy_aix.c
src/getentropy_bsd.c src/getentropy_bsd.c
@ -457,6 +458,7 @@ Files:
src/getentropy_linux.c src/getentropy_linux.c
src/getentropy_osx.c src/getentropy_osx.c
src/getentropy_solaris.c src/getentropy_solaris.c
src/getentropy_win.c
src/readpassphrase.c src/readpassphrase.c
src/reallocarray.c src/reallocarray.c
src/strlcat.c src/strlcat.c

View File

@ -16,6 +16,7 @@ libbsd_la_included_sources = \
getentropy_linux.c \ getentropy_linux.c \
getentropy_osx.c \ getentropy_osx.c \
getentropy_solaris.c \ getentropy_solaris.c \
getentropy_win.c \
$(nil) $(nil)
EXTRA_DIST = \ EXTRA_DIST = \
@ -64,6 +65,7 @@ libbsd_la_SOURCES = \
arc4random_openbsd.h \ arc4random_openbsd.h \
arc4random_uniform.c \ arc4random_uniform.c \
arc4random_unix.h \ arc4random_unix.h \
arc4random_win.h \
bsd_getopt.c \ bsd_getopt.c \
chacha_private.h \ chacha_private.h \
closefrom.c \ closefrom.c \

View File

@ -36,6 +36,8 @@ getentropy(void *buf, size_t len);
#include "arc4random_openbsd.h" #include "arc4random_openbsd.h"
#elif defined(__linux__) #elif defined(__linux__)
#include "arc4random_linux.h" #include "arc4random_linux.h"
#elif defined(_WIN32)
#include "arc4random_win.h"
#else #else
#include "arc4random_unix.h" #include "arc4random_unix.h"
#endif #endif

78
src/arc4random_win.h Normal file
View File

@ -0,0 +1,78 @@
/* $OpenBSD: arc4random_win.h,v 1.6 2016/06/30 12:17:29 bcook Exp $ */
/*
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Stub functions for portability.
*/
#include <windows.h>
static volatile HANDLE arc4random_mtx = NULL;
/*
* Initialize the mutex on the first lock attempt. On collision, each thread
* will attempt to allocate a mutex and compare-and-swap it into place as the
* global mutex. On failure to swap in the global mutex, the mutex is closed.
*/
#define _ARC4_LOCK() { \
if (!arc4random_mtx) { \
HANDLE p = CreateMutex(NULL, FALSE, NULL); \
if (InterlockedCompareExchangePointer((void **)&arc4random_mtx, (void *)p, NULL)) \
CloseHandle(p); \
} \
WaitForSingleObject(arc4random_mtx, INFINITE); \
} \
#define _ARC4_UNLOCK() ReleaseMutex(arc4random_mtx)
static inline void
_getentropy_fail(void)
{
TerminateProcess(GetCurrentProcess(), 0);
}
static inline int
_rs_allocate(struct _rs **rsp, struct _rsx **rsxp)
{
*rsp = VirtualAlloc(NULL, sizeof(**rsp),
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (*rsp == NULL)
return (-1);
*rsxp = VirtualAlloc(NULL, sizeof(**rsxp),
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (*rsxp == NULL) {
VirtualFree(*rsp, 0, MEM_RELEASE);
*rsp = NULL;
return (-1);
}
return (0);
}
static inline void
_rs_forkhandler(void)
{
}
static inline void
_rs_forkdetect(void)
{
}

View File

@ -40,6 +40,8 @@
#include "getentropy_aix.c" #include "getentropy_aix.c"
#elif defined(__hpux) #elif defined(__hpux)
#include "getentropy_hpux.c" #include "getentropy_hpux.c"
#elif defined(_WIN32)
#include "getentropy_win.c"
#else #else
#error "No getentropy hooks defined for this platform." #error "No getentropy hooks defined for this platform."
#endif #endif

59
src/getentropy_win.c Normal file
View File

@ -0,0 +1,59 @@
/* $OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */
/*
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
* Copyright (c) 2014, Bob Beck <beck@obtuse.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://man.openbsd.org/getentropy.2
*/
#include <windows.h>
#include <errno.h>
#include <stdint.h>
#include <sys/types.h>
#include <wincrypt.h>
#include <process.h>
int getentropy(void *buf, size_t len);
/*
* On Windows, CryptGenRandom is supposed to be a well-seeded
* cryptographically strong random number generator.
*/
int
getentropy(void *buf, size_t len)
{
HCRYPTPROV provider;
if (len > 256) {
errno = EIO;
return (-1);
}
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT) == 0)
goto fail;
if (CryptGenRandom(provider, len, buf) == 0) {
CryptReleaseContext(provider, 0);
goto fail;
}
CryptReleaseContext(provider, 0);
return (0);
fail:
errno = EIO;
return (-1);
}