diff --git a/contrib/win32/openssh/config.h.vs b/contrib/win32/openssh/config.h.vs
index 4322af57f..3f8deebdd 100644
--- a/contrib/win32/openssh/config.h.vs
+++ b/contrib/win32/openssh/config.h.vs
@@ -207,13 +207,13 @@
/* #undef HAVE_ADDR_V6_IN_UTMPX */
/* Define to 1 if you have the `arc4random' function. */
-#define HAVE_ARC4RANDOM 1
+/* #undef HAVE_ARC4RANDOM */
/* Define to 1 if you have the `arc4random_buf' function. */
-#define HAVE_ARC4RANDOM_BUF 1
+/* #undef HAVE_ARC4RANDOM_BUF */
/* Define to 1 if you have the `arc4random_uniform' function. */
-#define HAVE_ARC4RANDOM_UNIFORM 1
+/* #undef HAVE_ARC4RANDOM_UNIFORM */
/* Define to 1 if you have the `asprintf' function. */
/* #undef HAVE_ASPRINTF */
diff --git a/contrib/win32/openssh/openbsd_compat.vcxproj b/contrib/win32/openssh/openbsd_compat.vcxproj
index 5f6616796..2f851ea00 100644
--- a/contrib/win32/openssh/openbsd_compat.vcxproj
+++ b/contrib/win32/openssh/openbsd_compat.vcxproj
@@ -103,6 +103,8 @@
+
+
@@ -138,6 +140,7 @@
+
{DD483F7D-C553-4740-BC1A-903805AD0174}
diff --git a/contrib/win32/openssh/openbsd_compat.vcxproj.filters b/contrib/win32/openssh/openbsd_compat.vcxproj.filters
index 802c71b90..f109029e7 100644
--- a/contrib/win32/openssh/openbsd_compat.vcxproj.filters
+++ b/contrib/win32/openssh/openbsd_compat.vcxproj.filters
@@ -222,6 +222,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
@@ -317,5 +323,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/openbsd-compat/arc4random.c b/openbsd-compat/arc4random.c
index a97bb7b89..af6f32b88 100644
--- a/openbsd-compat/arc4random.c
+++ b/openbsd-compat/arc4random.c
@@ -88,12 +88,16 @@ static struct _rsx {
static inline int _rs_allocate(struct _rs **, struct _rsx **);
static inline void _rs_forkdetect(void);
+#ifdef WINDOWS
+#include "arc4random_win.h"
+#else
#include "arc4random.h"
+#endif /* WINDOWS*/
static inline void _rs_rekey(u_char *dat, size_t datlen);
static inline void
-_rs_init(u_char *buf, size_t n)
+_rs_init(u_char* buf, size_t n)
{
if (n < KEYSZ + IVSZ)
return;
diff --git a/openbsd-compat/arc4random_win.h b/openbsd-compat/arc4random_win.h
new file mode 100644
index 000000000..deec8a1ef
--- /dev/null
+++ b/openbsd-compat/arc4random_win.h
@@ -0,0 +1,78 @@
+/* $OpenBSD: arc4random_win.h,v 1.6 2016/06/30 12:17:29 bcook Exp $ */
+
+/*
+ * Copyright (c) 1996, David Mazieres
+ * Copyright (c) 2008, Damien Miller
+ * Copyright (c) 2013, Markus Friedl
+ * Copyright (c) 2014, Theo de Raadt
+ *
+ * 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
+
+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)
+{
+}