diff --git a/build-aux/m4/zw_endianness.m4 b/build-aux/m4/zw_endianness.m4 index 95132161..00c3fdde 100644 --- a/build-aux/m4/zw_endianness.m4 +++ b/build-aux/m4/zw_endianness.m4 @@ -101,6 +101,10 @@ m4_define([zw_C_ENDIANNESS_options], [ [ [_MIPSEB and _MIPSEL], [(defined _MIPSEB) != (defined _MIPSEL)], [defined _MIPSEB], [defined _MIPSEL], [0], +], +[ [_MSC_VER and _M_X64 or _M_IX86], + [defined _MSC_VER && (defined _M_X64 || defined _M_IX86)], + [0], [1], [0], ] ]) diff --git a/lib/alg-sha256.c b/lib/alg-sha256.c index 7298fa31..3fad12ba 100644 --- a/lib/alg-sha256.c +++ b/lib/alg-sha256.c @@ -101,9 +101,9 @@ static const uint32_t Krnd[64] = { * the 512-bit input block to produce a new state. */ static void -SHA256_Transform(uint32_t state[static restrict 8], - const uint8_t block[static restrict 64], - uint32_t W[static restrict 64], uint32_t S[static restrict 8]) +SHA256_Transform(uint32_t state[STATIC_RESTRICT 8], + const uint8_t block[STATIC_RESTRICT 64], + uint32_t W[STATIC_RESTRICT 64], uint32_t S[STATIC_RESTRICT 8]) { int i; @@ -174,7 +174,7 @@ static const uint8_t PAD[64] = { /* Add padding and terminating bit-count. */ static void -SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[static restrict 72]) +SHA256_Pad(SHA256_CTX * ctx, uint32_t tmp32[STATIC_RESTRICT 72]) { size_t r; @@ -228,7 +228,7 @@ SHA256_Init(SHA256_CTX * ctx) */ static void _SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len, - uint32_t tmp32[static restrict 72]) + uint32_t tmp32[STATIC_RESTRICT 72]) { uint32_t r; const uint8_t * src = in; @@ -286,7 +286,7 @@ SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len) */ static void _SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx, - uint32_t tmp32[static restrict 72]) + uint32_t tmp32[STATIC_RESTRICT 72]) { /* Add padding. */ @@ -342,8 +342,8 @@ SHA256_Buf(const void * in, size_t len, uint8_t digest[32]) */ static void _HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen, - uint32_t tmp32[static restrict 72], uint8_t pad[static restrict 64], - uint8_t khash[static restrict 32]) + uint32_t tmp32[STATIC_RESTRICT 72], uint8_t pad[STATIC_RESTRICT 64], + uint8_t khash[STATIC_RESTRICT 32]) { const uint8_t * K = _K; size_t i; @@ -395,7 +395,7 @@ HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) */ static void _HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len, - uint32_t tmp32[static restrict 72]) + uint32_t tmp32[STATIC_RESTRICT 72]) { /* Feed data to the inner SHA256 operation. */ @@ -422,7 +422,7 @@ HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len) */ static void _HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx, - uint32_t tmp32[static restrict 72], uint8_t ihash[static restrict 32]) + uint32_t tmp32[STATIC_RESTRICT 72], uint8_t ihash[STATIC_RESTRICT 32]) { /* Finish the inner SHA256 operation. */ @@ -478,8 +478,8 @@ HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len, /* Add padding and terminating bit-count, but don't invoke Transform yet. */ static int -SHA256_Pad_Almost(SHA256_CTX * ctx, uint8_t len[static restrict 8], - uint32_t tmp32[static restrict 72]) +SHA256_Pad_Almost(SHA256_CTX * ctx, uint8_t len[STATIC_RESTRICT 8], + uint32_t tmp32[STATIC_RESTRICT 72]) { uint32_t r; diff --git a/lib/crypt-port.h b/lib/crypt-port.h index a7079396..f389c463 100644 --- a/lib/crypt-port.h +++ b/lib/crypt-port.h @@ -49,6 +49,9 @@ #ifdef HAVE_SYS_PARAM_H #include #endif +#ifdef _MSC_VER +#include +#endif /* unistd.h may contain declarations of crypt, crypt_r, crypt_data, encrypt, and setkey; if present, they may be incompatible with our @@ -83,6 +86,8 @@ /* Functions that should not be inlined. */ #if defined __GNUC__ && __GNUC__ >= 3 # define NO_INLINE __attribute__ ((__noinline__)) +#elif defined(_MSC_VER) +# define NO_INLINE __declspec(noinline) #else # error "Don't know how to prevent function inlining" #endif @@ -99,6 +104,13 @@ #define MIN_SIZE(x) (x) #endif +/* MSVC does not support static restrict array declarations. */ +#ifdef _MSC_VER +#define STATIC_RESTRICT +#else +#define STATIC_RESTRICT static restrict +#endif + /* Detect system endianness. */ #if ENDIANNESS_IS_BIG # define XCRYPT_USE_BIGENDIAN 1 @@ -139,6 +151,10 @@ typedef union } max_align_t; #endif +#ifdef _MSC_VER +typedef SSIZE_T ssize_t; +#endif + /* Several files expect the traditional definitions of these macros. (We don't trust sys/param.h to define them correctly.) */ #undef MIN @@ -166,6 +182,8 @@ typedef union #define explicit_bzero(s, len) explicit_memset(s, 0, len) #elif defined HAVE_MEMSET_S #define explicit_bzero(s, len) memset_s(s, len, 0, len) +#elif defined _MSC_VER +#define explicit_bzero(s, len) SecureZeroMemory(s, len) #else /* activate our fallback implementation */ #undef INCLUDE_explicit_bzero @@ -240,7 +258,11 @@ extern size_t strcpy_or_abort (void *dst, size_t d_size, const void *src); /* A construct with the same syntactic role as the expansion of symver_set, but which does nothing. */ +#ifdef _MSC_VER +#define symver_nop() +#else #define symver_nop() __asm__ ("") +#endif /* The macros for versioned symbols work differently in this library than they do in glibc. They are mostly auto-generated diff --git a/lib/util-get-random-bytes.c b/lib/util-get-random-bytes.c index 79816db3..b59cd8fd 100644 --- a/lib/util-get-random-bytes.c +++ b/lib/util-get-random-bytes.c @@ -31,6 +31,9 @@ #ifdef HAVE_SYS_STAT_H #include #endif +#ifdef _MSC_VER +#include +#endif /* If we have O_CLOEXEC, we use it, but if we don't, we don't worry about it. */ @@ -52,7 +55,10 @@ getentropy() and enforced regardless of the actual back-end in use). If we fall all the way back to /dev/urandom, we open and close it on - each call. */ + each call. + + With MSVC we fall back to BCryptGenRandom(), and open and close the + provider on each call. */ bool get_random_bytes(void *buf, size_t buflen) @@ -146,6 +152,27 @@ get_random_bytes(void *buf, size_t buflen) } } #endif + +#ifdef _MSC_VER + static bool bcrypt_doesnt_work; + if (!bcrypt_doesnt_work) + { + BCRYPT_ALG_HANDLE algo; + NTSTATUS res; + res = BCryptOpenAlgorithmProvider(&algo, BCRYPT_RNG_ALGORITHM, NULL, 0); + if (!BCRYPT_SUCCESS(res)) + bcrypt_doesnt_work = true; + else + { + res = BCryptGenRandom(algo, buf, (ULONG) buflen, 0); + if (!BCRYPT_SUCCESS(res)) + bcrypt_doesnt_work = true; + + BCryptCloseAlgorithmProvider(algo, 0); + return !bcrypt_doesnt_work; + } + } +#endif #endif /* no arc4random_buf */ /* if we get here, we're just completely hosed */