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 */