From 954bfd45d05291930d0823b08ea5b84715f188af Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 28 Feb 2019 20:24:35 +0100 Subject: Windows Driver: Implement RAM encryption for cached passwords --- src/Common/Cache.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/Common/Crypto.c | 4 +-- src/Common/Crypto.h | 1 + 3 files changed, 91 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/Common/Cache.c b/src/Common/Cache.c index 4a4ebc9a..c204e03e 100644 --- a/src/Common/Cache.c +++ b/src/Common/Cache.c @@ -24,6 +24,25 @@ int CachedPim[CACHE_SIZE]; int cacheEmpty = 1; static int nPasswordIdx = 0; +#ifdef _WIN64 + +uint64 VcGetPasswordEncryptionID (Password* pPassword) +{ + return ((uint64) pPassword->Text) + ((uint64) pPassword); +} + +void VcProtectPassword (Password* pPassword, uint64 encID) +{ + VcProtectMemory (encID, (unsigned char*) pPassword->Text, sizeof(pPassword->Text), (unsigned char*) &pPassword->Length, sizeof (pPassword->Length)); +} + +void VcUnprotectPassword (Password* pPassword, uint64 encID) +{ + VcProtectPassword (pPassword, encID); +} + +#endif + int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, char *header, Password *password, int pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo) { int nReturnCode = ERR_PASSWORD_WRONG; @@ -37,16 +56,37 @@ int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, char *heade /* Save mount passwords back into cache if asked to do so */ if (bCache && (nReturnCode == 0 || nReturnCode == ERR_CIPHER_INIT_WEAK_KEY)) { +#ifdef _WIN64 + Password tmpPass; +#endif for (i = 0; i < CACHE_SIZE; i++) { - if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0) + Password* pCurrentPassword = &CachedPasswords[i]; +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + memcpy (&tmpPass, pCurrentPassword, sizeof (Password)); + VcUnprotectPassword (&tmpPass, VcGetPasswordEncryptionID (pCurrentPassword)); + pCurrentPassword = &tmpPass; + } +#endif + if (memcmp (pCurrentPassword, password, sizeof (Password)) == 0) break; } +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + burn (&tmpPass, sizeof (Password)); +#endif + if (i == CACHE_SIZE) { /* Store the password */ CachedPasswords[nPasswordIdx] = *password; +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + VcProtectPassword (&CachedPasswords[nPasswordIdx], VcGetPasswordEncryptionID (&CachedPasswords[nPasswordIdx])); +#endif /* Store also PIM if requested, otherwise set to default */ if (bCachePim && (pim > 0)) @@ -67,10 +107,22 @@ int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, char *heade } else if (!cacheEmpty) { +#ifdef _WIN64 + Password tmpPass; +#endif /* Attempt to recognize volume using cached passwords */ for (i = 0; i < CACHE_SIZE; i++) { - if (CachedPasswords[i].Length > 0) + Password* pCurrentPassword = &CachedPasswords[i]; +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + memcpy (&tmpPass, pCurrentPassword, sizeof (Password)); + VcUnprotectPassword (&tmpPass, VcGetPasswordEncryptionID (pCurrentPassword)); + pCurrentPassword = &tmpPass; + } +#endif + if ((pCurrentPassword->Length > 0) && (pCurrentPassword->Length <= (unsigned int) ((bBoot? MAX_LEGACY_PASSWORD: MAX_PASSWORD)))) { if (truecryptMode) effectivePim = 0; @@ -78,12 +130,16 @@ int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, char *heade effectivePim = CachedPim[i]; else effectivePim = pim; - nReturnCode = ReadVolumeHeader (bBoot, header, &CachedPasswords[i], pkcs5_prf, effectivePim, truecryptMode, retInfo, NULL); + nReturnCode = ReadVolumeHeader (bBoot, header, pCurrentPassword, pkcs5_prf, effectivePim, truecryptMode, retInfo, NULL); if (nReturnCode != ERR_PASSWORD_WRONG) break; } } +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + burn (&tmpPass, sizeof (Password)); +#endif } return nReturnCode; @@ -92,17 +148,40 @@ int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, char *heade void AddPasswordToCache (Password *password, int pim) { +#ifdef _WIN64 + Password tmpPass; +#endif int i; for (i = 0; i < CACHE_SIZE; i++) { - if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0) - return; + Password* pCurrentPassword = &CachedPasswords[i]; +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + { + memcpy (&tmpPass, pCurrentPassword, sizeof (Password)); + VcUnprotectPassword (&tmpPass, VcGetPasswordEncryptionID (pCurrentPassword)); + pCurrentPassword = &tmpPass; + } +#endif + if (memcmp (pCurrentPassword, password, sizeof (Password)) == 0) + break; } - CachedPasswords[nPasswordIdx] = *password; - CachedPim[nPasswordIdx] = pim > 0? pim : 0; - nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE; - cacheEmpty = 0; + if (i == CACHE_SIZE) + { + CachedPasswords[nPasswordIdx] = *password; +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + VcProtectPassword (&CachedPasswords[nPasswordIdx], VcGetPasswordEncryptionID (&CachedPasswords[nPasswordIdx])); +#endif + CachedPim[nPasswordIdx] = pim > 0? pim : 0; + nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE; + cacheEmpty = 0; + } +#ifdef _WIN64 + if (IsRamEncryptionEnabled()) + burn (&tmpPass, sizeof (Password)); +#endif } void AddLegacyPasswordToCache (PasswordLegacy *password, int pim) diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index d4184a53..a88f19a4 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -1388,9 +1388,9 @@ void ClearSecurityParameters() } #ifdef TC_WINDOWS_DRIVER -static void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData, unsigned char* pbData2, size_t cbData2) +void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData, unsigned char* pbData2, size_t cbData2) #else -static void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData, +void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData, unsigned char* pbData2, size_t cbData2, unsigned char* pbData3, size_t cbData3, unsigned char* pbData4, size_t cbData4) diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index 0951b20b..5a8724f6 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -388,6 +388,7 @@ void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_ #if defined(_WIN64) && !defined (_UEFI) && defined(TC_WINDOWS_DRIVER) BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback); void ClearSecurityParameters(); +void VcProtectMemory (uint64 encID, unsigned char* pbData, size_t cbData, unsigned char* pbData2, size_t cbData2); uint64 VcGetEncryptionID (PCRYPTO_INFO pCryptoInfo); void VcProtectKeys (PCRYPTO_INFO pCryptoInfo, uint64 encID); void VcUnprotectKeys (PCRYPTO_INFO pCryptoInfo, uint64 encID); -- cgit v1.2.3