diff options
Diffstat (limited to 'ports/winnt/libntp/arc4wrap.c')
-rw-r--r-- | ports/winnt/libntp/arc4wrap.c | 84 |
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" |