diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2015-04-05 22:21:59 +0200 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2015-04-06 00:22:36 +0200 |
commit | 2784652ab880dcea82aa212096b64d39695012fc (patch) | |
tree | b6cc4636a3e47efaeae338dca1fca87a347b82b8 /src/Common/Random.c | |
parent | a284922ce45ca777dd98b53e846603c63cb44904 (diff) | |
download | VeraCrypt-2784652ab880dcea82aa212096b64d39695012fc.tar.gz VeraCrypt-2784652ab880dcea82aa212096b64d39695012fc.zip |
Windows vulnerability fix: CryptAcquireContext vulnerability fix. Add checks to random generator to abort in case of error and display a diagnose message to the user.
Diffstat (limited to 'src/Common/Random.c')
-rw-r--r-- | src/Common/Random.c | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/src/Common/Random.c b/src/Common/Random.c index e8433c27..ae91f2da 100644 --- a/src/Common/Random.c +++ b/src/Common/Random.c @@ -60,12 +60,14 @@ HANDLE hNetAPI32 = NULL; // CryptoAPI
BOOL CryptoAPIAvailable = FALSE;
+DWORD CryptoAPILastError = ERROR_SUCCESS;
HCRYPTPROV hCryptProv;
/* Init the random number generator, setup the hooks, and start the thread */
int Randinit ()
{
+ DWORD dwLastError = ERROR_SUCCESS;
if (GetMaxPkcs5OutSize() > RNG_POOL_SIZE)
TC_THROW_FATAL_EXCEPTION;
@@ -75,6 +77,7 @@ int Randinit () InitializeCriticalSection (&critRandProt);
bRandDidInit = TRUE;
+ CryptoAPILastError = ERROR_SUCCESS;
if (pRandPool == NULL)
{
@@ -98,10 +101,13 @@ int Randinit () handleWin32Error (0);
goto error;
}
-
- if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)
- && !CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+
+ if (!CryptAcquireContext (&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+ {
CryptoAPIAvailable = FALSE;
+ CryptoAPILastError = GetLastError ();
+ goto error;
+ }
else
CryptoAPIAvailable = TRUE;
@@ -111,7 +117,9 @@ int Randinit () return 0;
error:
+ dwLastError = GetLastError();
RandStop (TRUE);
+ SetLastError (dwLastError);
return 1;
}
@@ -149,6 +157,7 @@ void RandStop (BOOL freePool) {
CryptReleaseContext (hCryptProv, 0);
CryptoAPIAvailable = FALSE;
+ CryptoAPILastError = ERROR_SUCCESS;
}
hMouse = NULL;
@@ -359,13 +368,19 @@ BOOL RandgetBytesFull ( void* hwndDlg, unsigned char *buf , int len, BOOL forceS if (bDidSlowPoll == FALSE || forceSlowPoll)
{
if (!SlowPoll ())
+ {
+ handleError ((HWND) hwndDlg, ERR_CAPI_INIT_FAILED);
ret = FALSE;
+ }
else
bDidSlowPoll = TRUE;
}
if (!FastPoll ())
+ {
+ handleError ((HWND) hwndDlg, ERR_CAPI_INIT_FAILED);
ret = FALSE;
+ }
/* There's never more than RNG_POOL_SIZE worth of randomess */
if ( (!allowAnyLength) && (len > RNG_POOL_SIZE))
@@ -692,13 +707,24 @@ BOOL SlowPoll (void) CloseHandle (hDevice);
}
- // CryptoAPI
- if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
+ // CryptoAPI: We always have a valid CryptoAPI context when we arrive here but
+ // we keep the check for clarity purpose
+ if ( !CryptoAPIAvailable )
+ return FALSE;
+ if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
+ {
RandaddBuf (buffer, sizeof (buffer));
- burn(buffer, sizeof (buffer));
- Randmix();
- return TRUE;
+ burn(buffer, sizeof (buffer));
+ Randmix();
+ return TRUE;
+ }
+ else
+ {
+ /* return error in case CryptGenRandom fails */
+ CryptoAPILastError = GetLastError ();
+ return FALSE;
+ }
}
@@ -803,9 +829,21 @@ BOOL FastPoll (void) RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
}
- // CryptoAPI
- if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
+ // CryptoAPI: We always have a valid CryptoAPI context when we arrive here but
+ // we keep the check for clarity purpose
+ if ( !CryptoAPIAvailable )
+ return FALSE;
+ if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
+ {
RandaddBuf (buffer, sizeof (buffer));
+ burn (buffer, sizeof(buffer));
+ }
+ else
+ {
+ /* return error in case CryptGenRandom fails */
+ CryptoAPILastError = GetLastError ();
+ return FALSE;
+ }
/* Apply the pool mixing function */
Randmix();
|