From 49d28d3f3aed6c35b9b6eefe2884f83180be7a64 Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Thu, 26 Nov 2009 01:39:42 -0500 Subject: [PATCH] Thread safety for rand-w32 --- lib/hcrypto/rand-w32.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/hcrypto/rand-w32.c b/lib/hcrypto/rand-w32.c index d3f7cf6f5..bc9d24f58 100644 --- a/lib/hcrypto/rand-w32.c +++ b/lib/hcrypto/rand-w32.c @@ -32,8 +32,8 @@ */ #include +#include -#include #include #include @@ -41,27 +41,37 @@ #include #include -#include - #include "randi.h" -static HCRYPTPROV cryptprovider = 0; +volatile static HCRYPTPROV g_cryptprovider = 0; static HCRYPTPROV _hc_CryptProvider(void) { BOOL res; + HCRYPTPROV cryptprovider = 0; + + if (g_cryptprovider != 0) + return g_cryptprovider; - if (cryptprovider != 0) - return cryptprovider; - res = CryptAcquireContext(&cryptprovider, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0); - if(!res) - CryptAcquireContext(&cryptprovider, NULL, - MS_ENHANCED_PROV, PROV_RSA_FULL, - CRYPT_NEWKEYSET); + + if (GetLastError() == NTE_BAD_KEYSET) { + if(!res) + res = CryptAcquireContext(&cryptprovider, NULL, + MS_ENHANCED_PROV, PROV_RSA_FULL, + CRYPT_NEWKEYSET); + } + + if (res && + InterlockedCompareExchange(&g_cryptprovider, cryptprovider, 0) != 0) { + + CryptReleaseContext(cryptprovider, 0); + cryptprovider = g_cryptprovider; + } + return cryptprovider; } @@ -79,7 +89,7 @@ w32crypto_seed(const void *indata, int size) static int w32crypto_bytes(unsigned char *outdata, int size) { - if (CryptGenRandom(_hc_CryptProvider(), size, outdata) == 0) + if (CryptGenRandom(_hc_CryptProvider(), size, outdata)) return 0; return 1; } @@ -97,12 +107,13 @@ w32crypto_add(const void *indata, int size, double entropi) static int w32crypto_pseudorand(unsigned char *outdata, int size) { + return 1; } static int w32crypto_status(void) { - if (_hc_CryptProvider() == NULL) + if (_hc_CryptProvider() == 0) return 0; return 1; }