diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 0e4fddbfb8..0d3929bfe1 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -583,6 +583,7 @@ WC_STRICT_SIG WC_WANT_FLAG_DONT_USE_AESNI WC_XMSS_FULL_HASH WIFI_AVAILABLE +WIN_REUSE_CRYPT_HANDLE WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE WOLFSENTRY_H WOLFSENTRY_NO_JSON diff --git a/src/internal.c b/src/internal.c index e7f7e454c4..93c5b00c2a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -19059,7 +19059,7 @@ static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, int additionalSz, /* length of additional input plus padding */ XMEMSET(padding, 0, sizeof(padding)); - padding[0] = additionalSz; + padding[0] = (byte)additionalSz; if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding))) != 0) return ret; @@ -19141,7 +19141,8 @@ int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, } #endif - addSz = writeAeadAuthData(ssl, msgLen, type, add, 0, &seq, verifyOrder); + addSz = writeAeadAuthData(ssl, (word16)msgLen, type, add, 0, &seq, + verifyOrder); if (addSz < 0) return addSz; @@ -19336,7 +19337,8 @@ int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, #endif - addSz = writeAeadAuthData(ssl, msgLen, no_type, add, 1, &seq, PEER_ORDER); + addSz = writeAeadAuthData(ssl, (word16)msgLen, no_type, add, 1, &seq, + PEER_ORDER); if (addSz < 0) return addSz; diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 746a06b90f..311d5a71c0 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2711,6 +2711,34 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) #elif defined(USE_WINDOWS_API) +#ifdef WIN_REUSE_CRYPT_HANDLE +/* shared crypt handle for RNG use */ +static ProviderHandle gHandle = 0; + +int wc_WinCryptHandleInit(void) +{ + int ret = 0; + if (gHandle == 0) { + if(!CryptAcquireContext(&gHandle, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + DWORD dw = GetLastError(); + WOLFSSL_MSG("CryptAcquireContext failed!"); + WOLFSSL_ERROR((int)dw); + ret = WINCRYPT_E; + } + } + return ret; +} + +void wc_WinCryptHandleCleanup(void) +{ + if (gHandle != 0) { + CryptReleaseContext(gHandle, 0); + gHandle = 0; + } +} +#endif /* WIN_REUSE_CRYPT_HANDLE */ + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { #ifdef WOLF_CRYPTO_CB @@ -2741,14 +2769,27 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) } #endif /* HAVE_INTEL_RDSEED */ - if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) +#ifdef WIN_REUSE_CRYPT_HANDLE + /* Check that handle was initialized. + * Note: initialization should be done through: + * wolfSSL_Init -> wolfCrypt_Init -> wc_WinCryptHandleInit + */ + if (wc_WinCryptHandleInit() != 0) { return WINCRYPT_E; - - if (!CryptGenRandom(os->handle, sz, output)) + } + if (!CryptGenRandom(gHandle, sz, output)) return CRYPTGEN_E; - +#else + if (!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + return WINCRYPT_E; + } + if (!CryptGenRandom(os->handle, sz, output)) { + return CRYPTGEN_E; + } CryptReleaseContext(os->handle, 0); + os->handle = 0; +#endif return 0; } diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a75785227b..ee876752ee 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -339,13 +339,20 @@ int wolfCrypt_Init(void) return ret; #endif -#ifdef HAVE_ENTROPY_MEMUSE - ret = Entropy_Init(); - if (ret != 0) { - WOLFSSL_MSG("Error initializing entropy"); - return ret; - } -#endif + #if defined(USE_WINDOWS_API) && defined(WIN_REUSE_CRYPT_HANDLE) + /* A failure here should not happen, but if it does the actual RNG seed + * call will fail. This init is for a shared crypt provider handle for + * RNG */ + (void)wc_WinCryptHandleInit(); + #endif + + #ifdef HAVE_ENTROPY_MEMUSE + ret = Entropy_Init(); + if (ret != 0) { + WOLFSSL_MSG("Error initializing entropy"); + return ret; + } + #endif #ifdef HAVE_ECC #ifdef FP_ECC @@ -516,6 +523,10 @@ int wolfCrypt_Cleanup(void) Entropy_Final(); #endif + #if defined(USE_WINDOWS_API) && defined(WIN_REUSE_CRYPT_HANDLE) + wc_WinCryptHandleCleanup(); + #endif + #ifdef WOLF_CRYPTO_CB wc_CryptoCb_Cleanup(); #endif diff --git a/wolfssl.vcxproj b/wolfssl.vcxproj index 01f2a8f3a9..58410b144a 100644 --- a/wolfssl.vcxproj +++ b/wolfssl.vcxproj @@ -437,6 +437,7 @@ + diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 3b4533e0d8..5abd6c011f 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -133,6 +133,12 @@ #else typedef unsigned long ProviderHandle; #endif + + #ifdef WIN_REUSE_CRYPT_HANDLE + /* called from wolfCrypt_Init() and wolfCrypt_Cleanup() */ + WOLFSSL_LOCAL int wc_WinCryptHandleInit(void); + WOLFSSL_LOCAL void wc_WinCryptHandleCleanup(void); + #endif #endif #ifndef WC_RNG_TYPE_DEFINED /* guard on redeclaration */