2 * arc4wrap.c - wrapper for libevent's ARCFOUR random number generator
4 * Written by Juergen Perlinger (perlinger@ntp.org) for the NTP project.
5 * The contents of 'html/copyright.html' apply.
6 * --------------------------------------------------------------------
7 * This is an inclusion wrapper for the ARCFOUR implementation in
8 * libevent. It's main usage is to enable a openSSL-free build on Win32
9 * without a full integration of libevent. This provides Win32 specific
10 * glue to make the PRNG working. Porting to POSIX should be easy, but
11 * on most POSIX systems using openSSL is no problem and falling back to
12 * using ARCFOUR instead of the openSSL PRNG is not necessary. And even
13 * if it is, there's a good chance that ARCFOUR is a system library.
17 # include <wincrypt.h>
20 # error this is currently a pure windows port
26 #include "ntp_types.h"
27 #include "ntp_stdlib.h"
29 /* ARCFOUR implementation glue */
30 /* export type is empty, since this goes into a static library*/
31 #define ARC4RANDOM_EXPORT
32 /* we use default uint32_t as UINT32 */
33 #define ARC4RANDOM_UINT32 uint32_t
34 /* do not use ARCFOUR's default includes - we gobble it all up here. */
35 #define ARC4RANDOM_NO_INCLUDES
36 /* And the locking. Could probably be left empty. */
37 #define ARC4_LOCK_() private_lock_()
38 #define ARC4_UNLOCK_() private_unlock_()
50 /* locking uses a manual thread-safe ONCE pattern. There's no static
51 * initialiser pattern that can be used for critical sections, and
52 * we must make sure we do the creation exactly once on the first call.
55 static long once_ = 0;
56 static CRITICAL_SECTION csec_;
62 switch (InterlockedCompareExchange(&once_, 1, 0)) {
64 InitializeCriticalSection(&csec_);
65 InterlockedExchange(&once_, 2);
67 EnterCriticalSection(&csec_);
79 if (InterlockedExchangeAdd(&once_, 0) == 2)
80 LeaveCriticalSection(&csec_);
83 #pragma warning(disable : 4244)
84 #include "../../../sntp/libevent/arc4random.c"