From 25c3d15ed7edcb8483dc3de7a55cf4579f6504c4 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 28 Dec 2014 19:04:05 +0100 Subject: Windows: support loading TrueCrypt volumes. Implement converting TrueCrypt volumes to VeraCrypt using the change password functionality. --- src/Common/Apidrvr.h | 1 + src/Common/BootEncryption.cpp | 4 ++-- src/Common/Cache.c | 6 +++--- src/Common/Cache.h | 2 +- src/Common/Crypto.h | 1 + src/Common/Dlgcode.c | 21 ++++++++++++++------ src/Common/Dlgcode.h | 4 ++-- src/Common/Format.c | 2 +- src/Common/Language.xml | 7 +++++-- src/Common/Password.c | 8 ++++---- src/Common/Password.h | 2 +- src/Common/Pkcs5.c | 11 +++++++---- src/Common/Pkcs5.h | 2 +- src/Common/Tcdefs.h | 3 ++- src/Common/Volumes.c | 45 ++++++++++++++++++++++++++++++++++--------- src/Common/Volumes.h | 2 +- 16 files changed, 83 insertions(+), 38 deletions(-) (limited to 'src/Common') diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index ac1689be..f14319ed 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -102,6 +102,7 @@ typedef struct BOOL RecoveryMode; int pkcs5_prf; int ProtectedHidVolPkcs5Prf; + BOOL bTrueCryptMode; } MOUNT_STRUCT; typedef struct diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index b1fd5e94..43cee062 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -1638,7 +1638,7 @@ namespace VeraCrypt // Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize) memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader)); - ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, pkcs5, NULL, cryptoInfo); + ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, pkcs5, FALSE, NULL, cryptoInfo); DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); @@ -2159,7 +2159,7 @@ namespace VeraCrypt PCRYPTO_INFO cryptoInfo = NULL; - int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, old_pkcs5, &cryptoInfo, NULL); + int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, old_pkcs5, FALSE, &cryptoInfo, NULL); finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); }); if (status != 0) diff --git a/src/Common/Cache.c b/src/Common/Cache.c index 2ecf9d86..33043f78 100644 --- a/src/Common/Cache.c +++ b/src/Common/Cache.c @@ -21,7 +21,7 @@ Password CachedPasswords[CACHE_SIZE]; int cacheEmpty = 1; static int nPasswordIdx = 0; -int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, int pkcs5_prf, PCRYPTO_INFO *retInfo) +int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, int pkcs5_prf, BOOL truecryptMode, PCRYPTO_INFO *retInfo) { int nReturnCode = ERR_PASSWORD_WRONG; int i; @@ -29,7 +29,7 @@ int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *pas /* Attempt to recognize volume using mount password */ if (password->Length > 0) { - nReturnCode = ReadVolumeHeader (bBoot, header, password, pkcs5_prf, retInfo, NULL); + nReturnCode = ReadVolumeHeader (bBoot, header, password, pkcs5_prf, truecryptMode, retInfo, NULL); /* Save mount passwords back into cache if asked to do so */ if (bCache && (nReturnCode == 0 || nReturnCode == ERR_CIPHER_INIT_WEAK_KEY)) @@ -59,7 +59,7 @@ int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *pas { if (CachedPasswords[i].Length > 0) { - nReturnCode = ReadVolumeHeader (bBoot, header, &CachedPasswords[i], pkcs5_prf, retInfo, NULL); + nReturnCode = ReadVolumeHeader (bBoot, header, &CachedPasswords[i], pkcs5_prf, truecryptMode, retInfo, NULL); if (nReturnCode != ERR_PASSWORD_WRONG) break; diff --git a/src/Common/Cache.h b/src/Common/Cache.h index 3c68479e..10f120b0 100644 --- a/src/Common/Cache.h +++ b/src/Common/Cache.h @@ -19,5 +19,5 @@ extern int cacheEmpty; void AddPasswordToCache (Password *password); -int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, int pkcs5_prf, PCRYPTO_INFO *retInfo); +int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, int pkcs5_prf, BOOL truecryptMode, PCRYPTO_INFO *retInfo); void WipeCache (void); diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index 4695239b..70f481d8 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -211,6 +211,7 @@ typedef struct CRYPTO_INFO_t unsigned __int8 k2[MASTER_KEYDATA_SIZE]; /* For XTS, this contains the secondary key (if cascade, multiple concatenated). For LRW (deprecated/legacy), it contains the tweak key. For CBC (deprecated/legacy), it contains the IV seed. */ unsigned __int8 salt[PKCS5_SALT_SIZE]; int noIterations; + BOOL bTrueCryptMode; uint64 volume_creation_time; // Legacy uint64 header_creation_time; // Legacy diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 9c72751b..9bb4ac49 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -4028,6 +4028,10 @@ void handleError (HWND hwndDlg, int code) // A non-error break; + case ERR_UNSUPPORTED_TRUECRYPT_FORMAT: + MessageBoxW (hwndDlg, GetString ("UNSUPPORTED_TRUECRYPT_FORMAT"), lpszTitle, ICON_HAND); + break; + default: StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("ERR_UNKNOWN"), code); MessageBoxW (hwndDlg, szTmp, lpszTitle, ICON_HAND); @@ -4504,22 +4508,22 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) case SHA512: /* PKCS-5 test with HMAC-SHA-512 used as the PRF */ - derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); + derive_key_sha512 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE, FALSE), dk, MASTER_KEYDATA_SIZE); break; case SHA256: /* PKCS-5 test with HMAC-SHA-256 used as the PRF */ - derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); + derive_key_sha256 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE, FALSE), dk, MASTER_KEYDATA_SIZE); break; case RIPEMD160: /* PKCS-5 test with HMAC-RIPEMD-160 used as the PRF */ - derive_key_ripemd160 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); + derive_key_ripemd160 ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE, FALSE), dk, MASTER_KEYDATA_SIZE); break; case WHIRLPOOL: /* PKCS-5 test with HMAC-Whirlpool used as the PRF */ - derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE), dk, MASTER_KEYDATA_SIZE); + derive_key_whirlpool ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, FALSE, FALSE), dk, MASTER_KEYDATA_SIZE); break; } } @@ -6289,6 +6293,7 @@ int MountVolume (HWND hwndDlg, char *volumePath, Password *password, int pkcs5, + BOOL truecryptMode, BOOL cachePassword, BOOL sharedAccess, const MountOptions* const mountOptions, @@ -6360,6 +6365,7 @@ retry: mount.bMountManager = TRUE; mount.pkcs5_prf = pkcs5; + mount.bTrueCryptMode = truecryptMode; // Windows 2000 mount manager causes problems with remounted volumes if (CurrentOSMajor == 5 && CurrentOSMinor == 0) @@ -6412,6 +6418,8 @@ retry: &mount.nPartitionInInactiveSysEncScopeDriveNo, sizeof(mount.nPartitionInInactiveSysEncScopeDriveNo)) != 1) { + if (!quiet) + Warning ("NO_SYSENC_PARTITION_SELECTED", hwndDlg); return -1; } @@ -6436,6 +6444,7 @@ retry: burn (&mount.VolumePassword, sizeof (mount.VolumePassword)); burn (&mount.ProtectedHidVolPassword, sizeof (mount.ProtectedHidVolPassword)); burn (&mount.pkcs5_prf, sizeof (mount.pkcs5_prf)); + burn (&mount.bTrueCryptMode, sizeof (mount.bTrueCryptMode)); burn (&mount.ProtectedHidVolPkcs5Prf, sizeof (mount.ProtectedHidVolPkcs5Prf)); if (bResult == FALSE) @@ -8954,7 +8963,7 @@ void ReportUnexpectedState (char *techInfo) #ifndef SETUP -int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, int pkcs5_prf, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader) +int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, int pkcs5_prf, BOOL truecryptMode, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader) { int status = ERR_PARAMETER_INCORRECT; int volumeType; @@ -9104,7 +9113,7 @@ int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *pa } // Decrypt volume header - status = ReadVolumeHeader (FALSE, buffer, password, pkcs5_prf, &context->CryptoInfo, NULL); + status = ReadVolumeHeader (FALSE, buffer, password, pkcs5_prf, truecryptMode, &context->CryptoInfo, NULL); if (status == ERR_PASSWORD_WRONG) continue; // Try next volume type diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 5af52b15..601871ce 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -325,7 +325,7 @@ BOOL IsDriveAvailable (int driveNo); BOOL IsDeviceMounted (char *deviceName); int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced); void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap); -int MountVolume (HWND hwndDlg, int driveNo, char *volumePath, Password *password, int pkcs5, BOOL cachePassword, BOOL sharedAccess, const MountOptions* const mountOptions, BOOL quiet, BOOL bReportWrongPassword); +int MountVolume (HWND hwndDlg, int driveNo, char *volumePath, Password *password, int pkcs5, BOOL truecryptMode, BOOL cachePassword, BOOL sharedAccess, const MountOptions* const mountOptions, BOOL quiet, BOOL bReportWrongPassword); BOOL UnmountVolume (HWND hwndDlg , int nDosDriveNo, BOOL forceUnmount); BOOL IsPasswordCacheEmpty (void); BOOL IsMountedVolume (const char *volname); @@ -447,7 +447,7 @@ void ToBootPwdField (HWND hwndDlg, UINT ctrlId); void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT hFont); BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize); BOOL DoDriverInstall (HWND hwndDlg); -int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, int pkcs5_prf, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader); +int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, int pkcs5_prf, BOOL truecryptMode, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader); void CloseVolume (OpenVolumeContext *context); int ReEncryptVolumeHeader (HWND hwndDlg, char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, BOOL wipeMode); BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly); diff --git a/src/Common/Format.c b/src/Common/Format.c index 3b7a8127..54dddf64 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -624,7 +624,7 @@ error: mountOptions.PartitionInInactiveSysEncScope = FALSE; mountOptions.UseBackupHeader = FALSE; - if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1) + if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1) { MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND); MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); diff --git a/src/Common/Language.xml b/src/Common/Language.xml index c4ea0562..d090ac1b 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -167,6 +167,7 @@ Display password Open &Explorer window for mounted volume &Cache password in driver memory + TrueCrypt Mode Di&smount All &Volume Properties... Volume &Tools... @@ -1033,6 +1034,7 @@ \nThe extra boot partition can be removed before installing Windows. To do so, follow these steps:\n\n1) Boot your Windows installation disc.\n\n2) In the Windows installer screen, click 'Install now' > 'Custom (advanced)'.\n\n3) Click 'Drive Options'.\n\n4) Select the main system partition and delete it by clicking 'Delete' and 'OK'.\n\n5) Select the 'System Reserved' partition, click 'Extend', and increase its size so that the operating system can be installed to it.\n\n6) Click 'Apply' and 'OK'.\n\n7) Install Windows on the 'System Reserved' partition.\n\n\nShould an attacker ask why you removed the extra boot partition, you can answer that you wanted to prevent any possible data leaks to the unencrypted boot partition.\n\nNote: You can print this text by clicking the 'Print' button below. If you save a copy of this text or print it (strongly recommended, unless your printer stores copies of documents it prints on its internal drive), you should destroy any copies of it after removing the extra boot partition (otherwise, if such a copy was found, it might indicate that there is a hidden operating system on this computer). Warning: There is unallocated space between the system partition and the first partition behind it. After you create the hidden operating system, you must not create any new partitions in that unallocated space. Otherwise, the hidden operating system will be impossible to boot (until you delete such newly created partitions). This algorithm is currently not supported for system encryption. + This algorithm is not supported for TrueCrypt mode. Keyfiles are currently not supported for system encryption. Warning: VeraCrypt could not restore the original keyboard layout. This may cause you to enter a password incorrectly. Error: Cannot set the keyboard layout for VeraCrypt to the standard US keyboard layout.\n\nNote that the password needs to be typed in the pre-boot environment (before Windows starts) where non-US Windows keyboard layouts are not available. Therefore, the password must always be typed using the standard US keyboard layout. @@ -1231,8 +1233,9 @@ Do you want VeraCrypt to attempt to disable write protection of the partition/drive? WARNING: This setting may degrade performance.\n\nAre you sure you want to use this setting? Warning: VeraCrypt volume auto-dismounted - Before you physically remove or turn off a device containing a mounted volume, you should always dismount the volume in VeraCrypt first.\n\nUnexpected spontaneous dismount is usually caused by an intermittently failing cable, drive (enclosure), etc. - Test + Before you physically remove or turn off a device containing a mounted volume, you should always dismount the volume in VeraCrypt first.\n\nUnexpected spontaneous dismount is usually caused by an intermittently failing cable, drive (enclosure), etc. + VeraCrypt supports only TrueCrypt volumes created with TrueCrypt 7.x series + Test Keyfile Backspace Tab diff --git a/src/Common/Password.c b/src/Common/Password.c index db7ad7f7..f8fd3c1c 100644 --- a/src/Common/Password.c +++ b/src/Common/Password.c @@ -119,7 +119,7 @@ BOOL CheckPasswordLength (HWND hwndDlg, HWND hwndItem) return TRUE; } -int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, Password *newPassword, int pkcs5, int wipePassCount, HWND hwndDlg) +int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, BOOL truecryptMode, Password *newPassword, int pkcs5, int wipePassCount, HWND hwndDlg) { int nDosLinkCreated = 1, nStatus = ERR_OS_ERROR; char szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH]; @@ -143,7 +143,7 @@ int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, Pas if (oldPassword->Length == 0 || newPassword->Length == 0) return -1; - if (wipePassCount <= 0) + if ((wipePassCount <= 0) || (truecryptMode && (old_pkcs5 == SHA256))) { nStatus = ERR_PARAMETER_INCORRECT; handleError (hwndDlg, nStatus); @@ -281,7 +281,7 @@ int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, Pas /* Try to decrypt the header */ - nStatus = ReadVolumeHeader (FALSE, buffer, oldPassword, old_pkcs5, &cryptoInfo, NULL); + nStatus = ReadVolumeHeader (FALSE, buffer, oldPassword, old_pkcs5, truecryptMode, &cryptoInfo, NULL); if (nStatus == ERR_CIPHER_INIT_WEAK_KEY) nStatus = 0; // We can ignore this error here @@ -353,7 +353,7 @@ int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, Pas (volumeType == TC_VOLUME_TYPE_HIDDEN) ? cryptoInfo->hiddenVolumeSize : 0, cryptoInfo->EncryptedAreaStart.Value, cryptoInfo->EncryptedAreaLength.Value, - cryptoInfo->RequiredProgramVersion, + truecryptMode? 0 : cryptoInfo->RequiredProgramVersion, cryptoInfo->HeaderFlags, cryptoInfo->SectorSize, wipePass < wipePassCount - 1); diff --git a/src/Common/Password.h b/src/Common/Password.h index 66903b53..62fe23a7 100644 --- a/src/Common/Password.h +++ b/src/Common/Password.h @@ -35,7 +35,7 @@ typedef struct void VerifyPasswordAndUpdate ( HWND hwndDlg , HWND hButton , HWND hPassword , HWND hVerify , unsigned char *szPassword , char *szVerify, BOOL keyFilesEnabled ); BOOL CheckPasswordLength (HWND hwndDlg, HWND hwndItem); BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw); -int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, Password *newPassword, int pkcs5, int wipePassCount, HWND hwndDlg); +int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, BOOL truecryptMode, Password *newPassword, int pkcs5, int wipePassCount, HWND hwndDlg); #endif // defined(_WIN32) && !defined(TC_WINDOWS_DRIVER) diff --git a/src/Common/Pkcs5.c b/src/Common/Pkcs5.c index 8f0c3645..e522a360 100644 --- a/src/Common/Pkcs5.c +++ b/src/Common/Pkcs5.c @@ -665,19 +665,22 @@ char *get_pkcs5_prf_name (int pkcs5_prf_id) -int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot) +int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL truecryptMode, BOOL bBoot) { switch (pkcs5_prf_id) { case RIPEMD160: - return bBoot? 327661 : 655331; + if (truecryptMode) + return bBoot ? 1000 : 2000; + else + return bBoot? 327661 : 655331; case SHA512: - return 500000; + return truecryptMode? 1000 : 500000; case WHIRLPOOL: - return 500000; + return truecryptMode? 1000 : 500000; case SHA256: return bBoot? 200000 : 500000; diff --git a/src/Common/Pkcs5.h b/src/Common/Pkcs5.h index be8c8cdb..d7ab90db 100644 --- a/src/Common/Pkcs5.h +++ b/src/Common/Pkcs5.h @@ -31,7 +31,7 @@ void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int void hmac_whirlpool (char *k, int lk, char *d, int ld, char *out, int t); void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b); void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen); -int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot); +int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL truecryptMode, BOOL bBoot); char *get_pkcs5_prf_name (int pkcs5_prf_id); #if defined(__cplusplus) diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h index 85b428c7..cf8bd349 100644 --- a/src/Common/Tcdefs.h +++ b/src/Common/Tcdefs.h @@ -295,7 +295,8 @@ enum ERR_PARAMETER_INCORRECT = 30, ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG = 31, ERR_NONSYS_INPLACE_ENC_INCOMPLETE = 32, - ERR_USER_ABORT = 33 + ERR_USER_ABORT = 33, + ERR_UNSUPPORTED_TRUECRYPT_FORMAT = 34 }; #endif // #ifndef TCDEFS_H diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 4e7bd0e3..7e001004 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -163,7 +163,7 @@ typedef struct BOOL ReadVolumeHeaderRecoveryMode = FALSE; -int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int selected_pkcs5_prf, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo) +int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int selected_pkcs5_prf, BOOL truecryptMode, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo) { char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; KEY_INFO keyInfo; @@ -184,6 +184,14 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int LONG outstandingWorkItemCount = 0; int i; + if (truecryptMode) + { + // SHA-256 not supported in TrueCrypt mode + if (selected_pkcs5_prf == SHA256) + return ERR_PARAMETER_INCORRECT; + pkcs5PrfCount--; // don't count SHA-256 in case of TrueCrypt mode + } + if (retHeaderCryptoInfo != NULL) { cryptoInfo = retHeaderCryptoInfo; @@ -246,6 +254,10 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int if (selected_pkcs5_prf != 0 && enqPkcs5Prf != selected_pkcs5_prf) continue; + // skip SHA-256 in case of TrueCrypt mode + if (truecryptMode && (enqPkcs5Prf == SHA256)) + continue; + if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { // Enqueue key derivation on thread pool @@ -262,7 +274,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int EncryptionThreadPoolBeginKeyDerivation (&keyDerivationCompletedEvent, &noOutstandingWorkItemEvent, &item->KeyReady, &outstandingWorkItemCount, enqPkcs5Prf, keyInfo.userKey, - keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, bBoot), item->DerivedKey); + keyInfo.keyLength, keyInfo.salt, get_pkcs5_iteration_count (enqPkcs5Prf, truecryptMode, bBoot), item->DerivedKey); ++queuedWorkItems; break; @@ -284,7 +296,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int if (!item->Free && InterlockedExchangeAdd (&item->KeyReady, 0) == TRUE) { pkcs5_prf = item->Pkcs5Prf; - keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot); + keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, truecryptMode, bBoot); memcpy (dk, item->DerivedKey, sizeof (dk)); item->Free = TRUE; @@ -302,7 +314,7 @@ KeyReady: ; else { pkcs5_prf = enqPkcs5Prf; - keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, bBoot); + keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, truecryptMode, bBoot); switch (pkcs5_prf) { @@ -386,8 +398,10 @@ KeyReady: ; DecryptBuffer (header + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); - // Magic 'VERA' - if (GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241) + // Magic 'VERA' or 'TRUE' depending if we are in TrueCrypt mode or not + if ((truecryptMode && GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x54525545) + || (!truecryptMode && GetHeaderField32 (header, TC_HEADER_OFFSET_MAGIC) != 0x56455241) + ) continue; // Header version @@ -407,7 +421,17 @@ KeyReady: ; // Required program version cryptoInfo->RequiredProgramVersion = GetHeaderField16 (header, TC_HEADER_OFFSET_REQUIRED_VERSION); - cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x10b; + if (truecryptMode) + { + if (cryptoInfo->RequiredProgramVersion < 0x700 || cryptoInfo->RequiredProgramVersion > 0x71a) + { + status = ERR_UNSUPPORTED_TRUECRYPT_FORMAT; + goto err; + } + cryptoInfo->LegacyVolume = FALSE; + } + else + cryptoInfo->LegacyVolume = cryptoInfo->RequiredProgramVersion < 0x10b; // Check CRC of the key set if (!ReadVolumeHeaderRecoveryMode @@ -417,7 +441,7 @@ KeyReady: ; // Now we have the correct password, cipher, hash algorithm, and volume type // Check the version required to handle this volume - if (cryptoInfo->RequiredProgramVersion > VERSION_NUM) + if (!truecryptMode && (cryptoInfo->RequiredProgramVersion > VERSION_NUM)) { status = ERR_NEW_VERSION_REQUIRED; goto err; @@ -469,6 +493,7 @@ KeyReady: ; { cryptoInfo->pkcs5 = pkcs5_prf; cryptoInfo->noIterations = keyInfo.noIterations; + cryptoInfo->bTrueCryptMode = truecryptMode; goto ret; } @@ -490,6 +515,7 @@ KeyReady: ; memcpy (cryptoInfo->salt, keyInfo.salt, PKCS5_SALT_SIZE); cryptoInfo->pkcs5 = pkcs5_prf; cryptoInfo->noIterations = keyInfo.noIterations; + cryptoInfo->bTrueCryptMode = truecryptMode; // Init the cipher with the decrypted master key status = EAInit (cryptoInfo->ea, keyInfo.master_keydata + primaryKeyOffset, cryptoInfo->ks); @@ -768,13 +794,14 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, // User key memcpy (keyInfo.userKey, password->Text, nUserKeyLen); keyInfo.keyLength = nUserKeyLen; - keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, bBoot); + keyInfo.noIterations = get_pkcs5_iteration_count (pkcs5_prf, FALSE, bBoot); // User selected encryption algorithm cryptoInfo->ea = ea; // User selected PRF cryptoInfo->pkcs5 = pkcs5_prf; + cryptoInfo->bTrueCryptMode = FALSE; // Mode of operation cryptoInfo->mode = mode; diff --git a/src/Common/Volumes.h b/src/Common/Volumes.h index 2d0b7d5d..96997774 100644 --- a/src/Common/Volumes.h +++ b/src/Common/Volumes.h @@ -129,7 +129,7 @@ UINT64_STRUCT GetHeaderField64 (byte *header, int offset); #ifdef TC_WINDOWS_BOOT int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); #else -int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int pkcs5_prf, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); +int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int pkcs5_prf, BOOL truecryptMode, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); #endif #if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT) -- cgit v1.2.3