summaryrefslogtreecommitdiff
path: root/ports/winnt/libntp/arc4wrap.c
diff options
context:
space:
mode:
Diffstat (limited to 'ports/winnt/libntp/arc4wrap.c')
-rw-r--r--ports/winnt/libntp/arc4wrap.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/ports/winnt/libntp/arc4wrap.c b/ports/winnt/libntp/arc4wrap.c
new file mode 100644
index 000000000000..9513d154a048
--- /dev/null
+++ b/ports/winnt/libntp/arc4wrap.c
@@ -0,0 +1,84 @@
+/*
+ * arc4wrap.c - wrapper for libevent's ARCFOUR random number generator
+ *
+ * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
+ * The contents of 'html/copyright.html' apply.
+ * --------------------------------------------------------------------
+ * This is an inclusion wrapper for the ARCFOUR implementation in
+ * libevent. It's main usage is to enable a openSSL-free build on Win32
+ * without a full integration of libevent. This provides Win32 specific
+ * glue to make the PRNG working. Porting to POSIX should be easy, but
+ * on most POSIX systems using openSSL is no problem and falling back to
+ * using ARCFOUR instead of the openSSL PRNG is not necessary. And even
+ * if it is, there's a good chance that ARCFOUR is a system library.
+ */
+#include <config.h>
+#ifdef _WIN32
+# include <wincrypt.h>
+# include <process.h>
+#else
+# error this is currently a pure windows port
+#endif
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include "ntp_types.h"
+#include "ntp_stdlib.h"
+
+/* ARCFOUR implementation glue */
+/* export type is empty, since this goes into a static library*/
+#define ARC4RANDOM_EXPORT
+/* we use default uint32_t as UINT32 */
+#define ARC4RANDOM_UINT32 uint32_t
+/* do not use ARCFOUR's default includes - we gobble it all up here. */
+#define ARC4RANDOM_NO_INCLUDES
+/* And the locking. Could probably be left empty. */
+#define ARC4_LOCK_() private_lock_()
+#define ARC4_UNLOCK_() private_unlock_()
+
+/* support code */
+
+static void
+evutil_memclear_(
+ void *buf,
+ size_t len)
+{
+ memset(buf, 0, len);
+}
+
+/* locking uses a manual thread-safe ONCE pattern. There's no static
+ * initialiser pattern that can be used for critical sections, and
+ * we must make sure we do the creation exactly once on the first call.
+ */
+
+static long once_ = 0;
+static CRITICAL_SECTION csec_;
+
+static void
+private_lock_(void)
+{
+again:
+ switch (InterlockedCompareExchange(&once_, 1, 0)) {
+ case 0:
+ InitializeCriticalSection(&csec_);
+ InterlockedExchange(&once_, 2);
+ case 2:
+ EnterCriticalSection(&csec_);
+ break;
+
+ default:
+ YieldProcessor();
+ goto again;
+ }
+}
+
+static void
+private_unlock_(void)
+{
+ if (InterlockedExchangeAdd(&once_, 0) == 2)
+ LeaveCriticalSection(&csec_);
+}
+
+#pragma warning(disable : 4244)
+#include "../../../sntp/libevent/arc4random.c"