From be1aee00340f40f9c81676d8b65f728f4a34cd9b Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 22 Jan 2020 11:46:37 +0100 Subject: Windows: Fix regression in Expander and Format when RAM encryption is enable that was causing volume headers to be corrupted. --- src/Common/Fat.c | 36 +++++++++++++++++++-- src/Common/Format.c | 72 +++++++++++++++++++++++++++++++++++++++++ src/ExpandVolume/ExpandVolume.c | 43 ++++++++++++++++++++++++ src/ExpandVolume/InitDataArea.c | 27 ++++++++++++++++ src/Format/InPlace.c | 41 +++++++++++++++++++++++ 5 files changed, 217 insertions(+), 2 deletions(-) diff --git a/src/Common/Fat.c b/src/Common/Fat.c index b47e531c..8d4cc7d8 100644 --- a/src/Common/Fat.c +++ b/src/Common/Fat.c @@ -394,6 +394,8 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void if(!quickFormat) { + CRYPTO_INFO tmpCI; + if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) goto fail; @@ -402,23 +404,41 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void deniability of hidden volumes (and also reduces the amount of predictable plaintext within the volume). */ + VirtualLock (&tmpCI, sizeof (tmpCI)); + memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO)); + cryptoInfo = &tmpCI; + // Temporary master key if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE)) + { + burn (&tmpCI, sizeof (tmpCI)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); goto fail; + } // Temporary secondary key (XTS mode) if (!RandgetBytes (hwndDlg, cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE)) + { + burn (&tmpCI, sizeof (tmpCI)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); goto fail; + } retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks); if (retVal != ERR_SUCCESS) { + TCfree (write_buf); burn (temporaryKey, sizeof(temporaryKey)); + burn (&tmpCI, sizeof (tmpCI)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); return retVal; } if (!EAInitMode (cryptoInfo, cryptoInfo->k2)) { + TCfree (write_buf); burn (temporaryKey, sizeof(temporaryKey)); + burn (&tmpCI, sizeof (tmpCI)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); return ERR_MODE_INIT_FAILED; } @@ -430,12 +450,24 @@ FormatFat (void* hwndDlgPtr, unsigned __int64 startSector, fatparams * ft, void goto fail; } UpdateProgressBar (nSecNo * ft->sector_size); + + if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) + { + burn (&tmpCI, sizeof (tmpCI)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); + goto fail; + } + + burn (&tmpCI, sizeof (tmpCI)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); } else + { UpdateProgressBar ((uint64) ft->num_sectors * ft->sector_size); - if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) - goto fail; + if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo)) + goto fail; + } TCfree (write_buf); burn (temporaryKey, sizeof(temporaryKey)); diff --git a/src/Common/Format.c b/src/Common/Format.c index 4aaf8b32..1edbdf96 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -100,6 +100,10 @@ int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams) LARGE_INTEGER offset; BOOL bFailedRequiredDASD = FALSE; HWND hwndDlg = volParams->hwndDlg; +#ifdef _WIN64 + CRYPTO_INFO tmpCI; + PCRYPTO_INFO cryptoInfoBackup = NULL; +#endif FormatSectorSize = volParams->sectorSize; @@ -574,6 +578,17 @@ begin_format: goto error; } +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof (tmpCI)); + memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo)); + cryptoInfoBackup = cryptoInfo; + cryptoInfo = &tmpCI; + } +#endif + nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, header, volParams->ea, @@ -592,6 +607,15 @@ begin_format: FormatSectorSize, FALSE); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + cryptoInfo = cryptoInfoBackup; + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); + } +#endif + if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header)) { nStatus = ERR_OS_ERROR; @@ -603,8 +627,28 @@ begin_format: { BOOL bUpdateBackup = FALSE; +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof (tmpCI)); + memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo)); + cryptoInfoBackup = cryptoInfo; + cryptoInfo = &tmpCI; + } +#endif + nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + cryptoInfo = cryptoInfoBackup; + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); + } +#endif + if (nStatus != ERR_SUCCESS) goto error; @@ -794,6 +838,10 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, LARGE_INTEGER startOffset; LARGE_INTEGER newOffset; +#ifdef _WIN64 + CRYPTO_INFO tmpCI; +#endif + // Seek to start sector startOffset.QuadPart = startSector * FormatSectorSize; if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN) @@ -811,6 +859,16 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, memset (sector, 0, sizeof (sector)); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof (tmpCI)); + memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo)); + cryptoInfo = &tmpCI; + } +#endif + // Remember the original secondary key (XTS mode) before generating a temporary one memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2)); @@ -873,6 +931,13 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, VirtualUnlock (temporaryKey, sizeof (temporaryKey)); VirtualUnlock (originalK2, sizeof (originalK2)); TCfree (write_buf); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); + } +#endif return 0; @@ -884,6 +949,13 @@ fail: VirtualUnlock (temporaryKey, sizeof (temporaryKey)); VirtualUnlock (originalK2, sizeof (originalK2)); TCfree (write_buf); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); + } +#endif SetLastError (err); return (retVal ? retVal : ERR_OS_ERROR); diff --git a/src/ExpandVolume/ExpandVolume.c b/src/ExpandVolume/ExpandVolume.c index 8db2b573..73878bbb 100644 --- a/src/ExpandVolume/ExpandVolume.c +++ b/src/ExpandVolume/ExpandVolume.c @@ -512,6 +512,10 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas BOOL backupHeader; byte *wipeBuffer = NULL; uint32 workChunkSize = TC_VOLUME_HEADER_GROUP_SIZE; +#ifdef _WIN64 + CRYPTO_INFO tmpCI; + PCRYPTO_INFO cryptoInfoBackup = NULL; +#endif if (pVolumePassword->Length == 0) return -1; @@ -851,6 +855,17 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas else DebugAddProgressDlgStatus(hwndDlg, L"Writing re-encrypted primary header ...\r\n"); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof (CRYPTO_INFO)); + memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo)); + cryptoInfoBackup = cryptoInfo; + cryptoInfo = &tmpCI; + } +#endif + // Prepare new volume header nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, buffer, @@ -870,6 +885,15 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas cryptoInfo->SectorSize, FALSE ); // use slow poll +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + cryptoInfo = cryptoInfoBackup; + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (CRYPTO_INFO)); + } +#endif + if (ci != NULL) crypto_close (ci); @@ -901,7 +925,26 @@ static int ExpandVolume (HWND hwndDlg, wchar_t *lpszVolume, Password *pVolumePas PCRYPTO_INFO dummyInfo = NULL; LARGE_INTEGER hiddenOffset; +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof (CRYPTO_INFO)); + memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo)); + cryptoInfoBackup = cryptoInfo; + cryptoInfo = &tmpCI; + } +#endif + nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, newDataAreaSize, !backupHeader, backupHeader); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + cryptoInfo = cryptoInfoBackup; + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (CRYPTO_INFO)); + } +#endif if (nStatus != ERR_SUCCESS) goto error; diff --git a/src/ExpandVolume/InitDataArea.c b/src/ExpandVolume/InitDataArea.c index afca2306..618358d1 100644 --- a/src/ExpandVolume/InitDataArea.c +++ b/src/ExpandVolume/InitDataArea.c @@ -56,6 +56,9 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, LARGE_INTEGER startOffset; LARGE_INTEGER newOffset; +#ifdef _WIN64 + CRYPTO_INFO tmpCI; +#endif // Seek to start sector startOffset.QuadPart = startSector * FormatSectorSize; @@ -74,6 +77,16 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, memset (sector, 0, sizeof (sector)); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof (tmpCI)); + memcpy (&tmpCI, cryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (cryptoInfo)); + cryptoInfo = &tmpCI; + } +#endif + // Remember the original secondary key (XTS mode) before generating a temporary one memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2)); @@ -136,6 +149,13 @@ int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, VirtualUnlock (temporaryKey, sizeof (temporaryKey)); VirtualUnlock (originalK2, sizeof (originalK2)); TCfree (write_buf); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); + } +#endif return 0; @@ -147,6 +167,13 @@ fail: VirtualUnlock (temporaryKey, sizeof (temporaryKey)); VirtualUnlock (originalK2, sizeof (originalK2)); TCfree (write_buf); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof (tmpCI)); + } +#endif SetLastError (err); return (retVal ? retVal : ERR_OS_ERROR); diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c index 7117a8a4..d844be2c 100644 --- a/src/Format/InPlace.c +++ b/src/Format/InPlace.c @@ -1097,6 +1097,19 @@ inplace_enc_read: { PCRYPTO_INFO dummyInfo = NULL; +#ifdef _WIN64 + CRYPTO_INFO tmpCI; + PCRYPTO_INFO cryptoInfoBackup = NULL; + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof(tmpCI)); + memcpy (&tmpCI, masterCryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (masterCryptoInfo)); + cryptoInfoBackup = masterCryptoInfo; + masterCryptoInfo = &tmpCI; + } +#endif + nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, header, headerCryptoInfo->ea, @@ -1115,6 +1128,15 @@ inplace_enc_read: masterCryptoInfo->SectorSize, wipeAlgorithm == TC_WIPE_NONE ? FALSE : (wipePass < PRAND_HEADER_WIPE_PASSES - 1)); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + masterCryptoInfo = cryptoInfoBackup; + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof(tmpCI)); + } +#endif + if (nStatus != ERR_SUCCESS) goto closing_seq; @@ -1128,9 +1150,28 @@ inplace_enc_read: goto closing_seq; } +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + VirtualLock (&tmpCI, sizeof(tmpCI)); + memcpy (&tmpCI, headerCryptoInfo, sizeof (CRYPTO_INFO)); + VcUnprotectKeys (&tmpCI, VcGetEncryptionID (headerCryptoInfo)); + cryptoInfoBackup = headerCryptoInfo; + headerCryptoInfo = &tmpCI; + } +#endif // Fill the reserved sectors of the header area with random data nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, headerCryptoInfo, masterCryptoInfo->VolumeSize.Value, TRUE, FALSE); +#ifdef _WIN64 + if (IsRamEncryptionEnabled ()) + { + headerCryptoInfo = cryptoInfoBackup; + burn (&tmpCI, sizeof (CRYPTO_INFO)); + VirtualUnlock (&tmpCI, sizeof(tmpCI)); + } +#endif + if (nStatus != ERR_SUCCESS) goto closing_seq; -- cgit v1.2.3