diff options
36 files changed, 605 insertions, 870 deletions
diff --git a/src/Boot/Windows/BootCommon.h b/src/Boot/Windows/BootCommon.h index 45a1a650..0e6c973c 100644 --- a/src/Boot/Windows/BootCommon.h +++ b/src/Boot/Windows/BootCommon.h @@ -1,91 +1,92 @@ /* Derived from source code of TrueCrypt 7.1a, which is Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #ifndef TC_HEADER_Boot_BootCommon #define TC_HEADER_Boot_BootCommon #include "Common/Password.h" +#include "Crypto/config.h" #include "BootDefs.h" // The user will be advised to upgrade the rescue disk if upgrading from the following or any previous version #define TC_RESCUE_DISK_UPGRADE_NOTICE_MAX_VERSION 0x0125 #define TC_BOOT_LOADER_AREA_SIZE (TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS) #define TC_BOOT_VOLUME_HEADER_SECTOR (TC_BOOT_LOADER_AREA_SECTOR_COUNT - 1) #define TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET (TC_BOOT_VOLUME_HEADER_SECTOR * TC_SECTOR_SIZE_BIOS) #define TC_CD_BOOTSECTOR_OFFSET 0xd000 #define TC_CD_BOOT_LOADER_SECTOR 26 #define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR TC_BOOT_LOADER_AREA_SECTOR_COUNT #define TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR * TC_SECTOR_SIZE_BIOS) #define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR (TC_ORIG_BOOT_LOADER_BACKUP_SECTOR + TC_BOOT_LOADER_AREA_SECTOR_COUNT) #define TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET (TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR * TC_SECTOR_SIZE_BIOS) #define TC_MBR_SECTOR 0 #define TC_MAX_MBR_BOOT_CODE_SIZE 440 #define TC_MAX_EXTRA_BOOT_PARTITION_SIZE (512UL * 1024UL * 1024UL) #pragma pack (1) typedef struct { uint8 Flags; } BootSectorConfiguration; // Modifying this value can introduce incompatibility with previous versions #define TC_BOOT_LOADER_ARGS_OFFSET 0x10 typedef struct { // Modifying this structure can introduce incompatibility with previous versions char Signature[8]; uint16 BootLoaderVersion; uint16 CryptoInfoOffset; uint16 CryptoInfoLength; uint32 HeaderSaltCrc32; - PasswordLegacy BootPassword; + CRYPTOPP_ALIGN_DATA(8) PasswordLegacy BootPassword; uint64 HiddenSystemPartitionStart; uint64 DecoySystemPartitionStart; uint32 Flags; uint32 BootDriveSignature; uint32 BootArgumentsCrc32; } BootArguments; // Modifying these values can introduce incompatibility with previous versions #define TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION 0x1 #pragma pack () // Boot arguments signature should not be defined as a static string // Modifying these values can introduce incompatibility with previous versions #define TC_SET_BOOT_ARGUMENTS_SIGNATURE(SG) do { SG[0] = 'T'; SG[1] = 'R'; SG[2] = 'U'; SG[3] = 'E'; SG[4] = 0x11; SG[5] = 0x23; SG[6] = 0x45; SG[7] = 0x66; } while (FALSE) #define TC_IS_BOOT_ARGUMENTS_SIGNATURE(SG) (SG[0] == 'T' && SG[1] == 'R' && SG[2] == 'U' && SG[3] == 'E' && SG[4] == 0x11 && SG[5] == 0x23 && SG[6] == 0x45 && SG[7] == 0x66) #if defined(_MSC_VER) && !defined(TC_WINDOWS_BOOT) #define DCS_DISK_ENTRY_LIST_HEADER_SIGN SIGNATURE_64 ('D','C','S','D','E','L','S','T') #ifndef CSTATIC_ASSERT #define CSTATIC_ASSERT(b, name) typedef int StaticAssertFailed##name[b ? 1 : -1]; #endif #define DE_IDX_CRYPTOHEADER 0 #define DE_IDX_LIST 1 #define DE_IDX_DISKID 2 diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp index f79e7339..ed185fc0 100644 --- a/src/Common/BootEncryption.cpp +++ b/src/Common/BootEncryption.cpp @@ -4355,68 +4355,68 @@ namespace VeraCrypt { File rescueFile (imageFile, true); rescueFile.CheckOpened (SRC_POS); size_t verifiedSectorCount = (TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET + TC_BOOT_LOADER_AREA_SIZE) / 2048; Buffer buffer ((verifiedSectorCount + 1) * 2048); DWORD bytesRead = rescueFile.Read (buffer.Ptr(), (DWORD) buffer.Size()); if ( (bytesRead == buffer.Size()) && (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0) ) { return true; } } catch (...) { } } return false; } #ifndef SETUP void BootEncryption::CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5, int pim) { PCRYPTO_INFO cryptoInfo = NULL; if (!IsRandomNumberGeneratorStarted()) throw ParameterIncorrect (SRC_POS); - throw_sys_if (CreateVolumeHeaderInMemory (ParentWindow, TRUE, (char *) VolumeHeader, ea, mode, password, pkcs5, pim, NULL, &cryptoInfo, + throw_sys_if (CreateVolumeHeaderInMemory (ParentWindow, TRUE, VolumeHeader, ea, mode, password, pkcs5, pim, NULL, &cryptoInfo, volumeSize, 0, encryptedAreaStart, 0, TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION, TC_HEADER_FLAG_ENCRYPTED_SYSTEM, TC_SECTOR_SIZE_BIOS, FALSE) != 0); finally_do_arg (PCRYPTO_INFO*, &cryptoInfo, { crypto_close (*finally_arg); }); // Initial rescue disk assumes encryption of the drive has been completed (EncryptedAreaLength == volumeSize) memcpy (RescueVolumeHeader, VolumeHeader, sizeof (RescueVolumeHeader)); - if (0 != ReadVolumeHeader (TRUE, (char *) RescueVolumeHeader, password, pkcs5, pim, NULL, cryptoInfo)) + if (0 != ReadVolumeHeader (TRUE, RescueVolumeHeader, password, pkcs5, pim, NULL, cryptoInfo)) throw ParameterIncorrect (SRC_POS); DecryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); if (GetHeaderField32 (RescueVolumeHeader, TC_HEADER_OFFSET_MAGIC) != 0x56455241) throw ParameterIncorrect (SRC_POS); uint8 *fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH; mputInt64 (fieldPos, volumeSize); // CRC of the header fields uint32 crc = GetCrc32 (RescueVolumeHeader + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC); fieldPos = RescueVolumeHeader + TC_HEADER_OFFSET_HEADER_CRC; mputLong (fieldPos, crc); EncryptBuffer (RescueVolumeHeader + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, cryptoInfo); VolumeHeaderValid = true; RescueVolumeHeaderValid = true; } void BootEncryption::InstallVolumeHeader () { if (!VolumeHeaderValid) throw ParameterIncorrect (SRC_POS); Device device (GetSystemDriveConfiguration().DevicePath); device.CheckOpened (SRC_POS); @@ -5364,91 +5364,91 @@ namespace VeraCrypt RegisterSystemFavoritesService (FALSE); } catch (...) { } try { if (displayWaitDialog) DisplayStaticModelessWaitDlg (ParentWindow); finally_do_arg (bool, displayWaitDialog, { if (finally_arg) CloseStaticModelessWaitDlg(); }); RestoreSystemLoader (); } catch (Exception &e) { e.Show (ParentWindow); throw ErrorException ("SYS_LOADER_RESTORE_FAILED", SRC_POS); } } int BootEncryption::ChangePassword (Password *oldPassword, int old_pkcs5, int old_pim, Password *newPassword, int pkcs5, int pim, int wipePassCount, HWND hwndDlg) { BootEncryptionStatus encStatus = GetStatus(); if (encStatus.SetupInProgress || (wipePassCount <= 0)) throw ParameterIncorrect (SRC_POS); SystemDriveConfiguration config = GetSystemDriveConfiguration (); - char header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; + unsigned char header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE]; Device device (config.DevicePath); device.CheckOpened (SRC_POS); // Only one algorithm is currently supported if (pkcs5 != 0) throw ParameterIncorrect (SRC_POS); int64 headerOffset = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET; int64 backupHeaderOffset = -1; if (encStatus.HiddenSystem) { headerOffset = encStatus.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET; // Find hidden system partition foreach (const Partition &partition, config.Partitions) { if (partition.Info.StartingOffset.QuadPart == encStatus.HiddenSystemPartitionStart) { backupHeaderOffset = partition.Info.StartingOffset.QuadPart + partition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_SIZE; break; } } if (backupHeaderOffset == -1) throw ParameterIncorrect (SRC_POS); } device.SeekAt (headerOffset); - device.Read ((uint8 *) header, sizeof (header)); + device.Read (header, sizeof (header)); PCRYPTO_INFO cryptoInfo = NULL; int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, old_pkcs5, old_pim, &cryptoInfo, NULL); finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); }); // if the XTS master key is vulnerable, return error and do not allow the user to change the password since the master key will not be changed if ((status == 0) && cryptoInfo->bVulnerableMasterKey) status = ERR_SYSENC_XTS_MASTERKEY_VULNERABLE; if (status != 0) { handleError (hwndDlg, status, SRC_POS); return status; } // Change the PKCS-5 PRF if requested by user if (pkcs5 != 0) { cryptoInfo->pkcs5 = pkcs5; RandSetHashFunction (pkcs5); } if (Randinit() != 0) { if (CryptoAPILastError == ERROR_SUCCESS) throw RandInitFailed (SRC_POS, GetLastError ()); else throw CryptoApiFailed (SRC_POS, CryptoAPILastError); } diff --git a/src/Common/Cache.c b/src/Common/Cache.c index 46249b9c..0d7a221f 100644 --- a/src/Common/Cache.c +++ b/src/Common/Cache.c @@ -16,61 +16,61 @@ #include "Fat.h" #include "Volumes.h" #include "Apidrvr.h" #include "Common.h" #include "Cache.h" Password CachedPasswords[CACHE_SIZE]; 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, PCRYPTO_INFO *retInfo) +int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, unsigned char *header, Password *password, int pkcs5_prf, int pim, PCRYPTO_INFO *retInfo) { int nReturnCode = ERR_PASSWORD_WRONG; int i, effectivePim; /* Attempt to recognize volume using mount password */ if (password->Length > 0) { nReturnCode = ReadVolumeHeader (bBoot, header, password, pkcs5_prf, pim, retInfo, NULL); /* 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++) { 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; } diff --git a/src/Common/Cache.h b/src/Common/Cache.h index 0988bf29..84bb6937 100644 --- a/src/Common/Cache.h +++ b/src/Common/Cache.h @@ -1,26 +1,26 @@ /* Legal Notice: Some portions of the source code contained in this file were derived from the source code of TrueCrypt 7.1a, which is Copyright (c) 2003-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "Common.h" #ifndef CACHE_SIZE /* WARNING: Changing this value might not be safe (some items may be hard coded for 4)! Inspection necessary. */ #define CACHE_SIZE 4 #endif extern int cacheEmpty; void AddPasswordToCache (Password *password, int pim, BOOL bCachePim); void AddLegacyPasswordToCache (PasswordLegacy *password, int pim); -int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim,char *header, Password *password, int pkcs5_prf, int pim, PCRYPTO_INFO *retInfo); +int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, unsigned char *header, Password *password, int pkcs5_prf, int pim, PCRYPTO_INFO *retInfo); void WipeCache (void); diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index 9c4ee5a3..5856df48 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -632,71 +632,71 @@ int EAGetKeySize (int ea) while (i = EAGetNextCipher (ea, i)) { size += CipherGetKeySize (i); } return size; } #ifndef TC_WINDOWS_BOOT // Returns the first mode of operation of EA int EAGetFirstMode (int ea) { return (EncryptionAlgorithms[ea].Modes[0]); } int EAGetNextMode (int ea, int previousModeId) { int c, i = 0; while (c = EncryptionAlgorithms[ea].Modes[i++]) { if (c == previousModeId) return EncryptionAlgorithms[ea].Modes[i]; } return 0; } -// Returns the name of the mode of operation of the whole EA -wchar_t *EAGetModeName (int ea, int mode, BOOL capitalLetters) +// Returns the name of the mode of operation +const wchar_t *EAGetModeName (int mode) { switch (mode) { case XTS: return L"XTS"; } - return L"[unknown]"; + return L"[UNKNOWN]"; } #endif // TC_WINDOWS_BOOT // Returns sum of key schedule sizes of all ciphers of the EA int EAGetKeyScheduleSize (int ea) { int i = EAGetFirstCipher(ea); int size = CipherGetKeyScheduleSize (i); while (i = EAGetNextCipher(ea, i)) { size += CipherGetKeyScheduleSize (i); } return size; } #ifndef TC_WINDOWS_BOOT // Returns number of ciphers in EA int EAGetCipherCount (int ea) { int i = 0; while (EncryptionAlgorithms[ea].Ciphers[i++]); return i - 1; } @@ -864,61 +864,61 @@ PCRYPTO_INFO crypto_open () { #ifndef TC_WINDOWS_BOOT /* Do the crt allocation */ PCRYPTO_INFO cryptoInfo = (PCRYPTO_INFO) TCalloc (sizeof (CRYPTO_INFO)); if (cryptoInfo == NULL) return NULL; memset (cryptoInfo, 0, sizeof (CRYPTO_INFO)); #if !defined(DEVICE_DRIVER) && !defined(_UEFI) VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO)); #endif cryptoInfo->ea = -1; return cryptoInfo; #else // TC_WINDOWS_BOOT #if 0 if (CryptoInfoBufferInUse) TC_THROW_FATAL_EXCEPTION; #endif CryptoInfoBufferInUse = 1; return &CryptoInfoBuffer; #endif // TC_WINDOWS_BOOT } #ifndef TC_WINDOWS_BOOT -void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen) +void crypto_loadkey (PKEY_INFO keyInfo, unsigned char *lpszUserKey, int nUserKeyLen) { keyInfo->keyLength = nUserKeyLen; burn (keyInfo->userKey, sizeof (keyInfo->userKey)); memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen); } void crypto_eraseKeys (PCRYPTO_INFO cryptoInfo) { burn (cryptoInfo->ks, sizeof (cryptoInfo->ks)); burn (cryptoInfo->ks2, sizeof (cryptoInfo->ks2)); #ifdef TC_WINDOWS_DRIVER burn (cryptoInfo->master_keydata_hash, sizeof (cryptoInfo->master_keydata_hash)); #else burn (cryptoInfo->master_keydata, sizeof (cryptoInfo->master_keydata)); burn (cryptoInfo->k2, sizeof (cryptoInfo->k2)); #endif burn (&cryptoInfo->noIterations, sizeof (cryptoInfo->noIterations)); burn (&cryptoInfo->volumePim, sizeof (cryptoInfo->volumePim)); } #endif void crypto_close (PCRYPTO_INFO cryptoInfo) { #ifndef TC_WINDOWS_BOOT if (cryptoInfo != NULL) { burn (cryptoInfo, sizeof (CRYPTO_INFO)); #if !defined(DEVICE_DRIVER) && !defined(_UEFI) VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO)); @@ -1212,63 +1212,65 @@ BOOL IsAesHwCpuSupported () return 0; #else return (HasAESNI() && !HwEncryptionDisabled)? TRUE : FALSE; #endif } void EnableHwEncryption (BOOL enable) { #if defined (TC_WINDOWS_BOOT) if (enable) aes_hw_cpu_enable_sse(); #endif HwEncryptionDisabled = !enable; } BOOL IsHwEncryptionEnabled () { return !HwEncryptionDisabled; } #endif // !TC_WINDOWS_BOOT #if !defined (TC_WINDOWS_BOOT) && !defined (_UEFI) static BOOL CpuRngDisabled = TRUE; static BOOL RamEncryptionEnabled = FALSE; BOOL IsCpuRngSupported () { +#ifndef _M_ARM64 if (HasRDSEED() || HasRDRAND()) return TRUE; else +#endif return FALSE; } void EnableCpuRng (BOOL enable) { CpuRngDisabled = !enable; } BOOL IsCpuRngEnabled () { return !CpuRngDisabled; } BOOL IsRamEncryptionSupported () { #ifdef _WIN64 if (t1ha_selfcheck__t1ha2() == 0) return TRUE; else return FALSE; #else return FALSE; #endif } void EnableRamEncryption (BOOL enable) { RamEncryptionEnabled = enable; } @@ -1286,61 +1288,61 @@ uint8 GetRngMask (uint8 count) return 0x7F; if (count >= 32) return 0x3F; if (count >= 16) return 0x1F; if (count >= 8) return 0x0F; if (count >= 4) return 0x07; if (count >= 2) return 0x03; return 1; } uint8 GetRandomIndex (ChaCha20RngCtx* pCtx, uint8 elementsCount) { uint8 index = 0; uint8 mask = GetRngMask (elementsCount); while (TRUE) { ChaCha20RngGetBytes (pCtx, &index, 1); index &= mask; if (index < elementsCount) break; } return index; } -#if defined(_WIN64) && !defined (_UEFI) +#if !defined (_UEFI) /* declaration of variables and functions used for RAM encryption on 64-bit build */ static uint8* pbKeyDerivationArea = NULL; static ULONG cbKeyDerivationArea = 0; static uint64 HashSeedMask = 0; static uint64 CipherIVMask = 0; #ifdef TC_WINDOWS_DRIVER ULONG AllocTag = 'MMCV'; #endif #if !defined(PAGE_SIZE) #define PAGE_SIZE 4096 #endif BOOL InitializeSecurityParameters(GetRandSeedFn rngCallback) { ChaCha20RngCtx ctx; uint8 pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ]; #ifdef TC_WINDOWS_DRIVER uint8 i; char randomStr[4]; Dump ("InitializeSecurityParameters BEGIN\n"); #endif rngCallback (pbSeed, sizeof (pbSeed)); ChaCha20RngInit (&ctx, pbSeed, rngCallback, 0); #ifdef TC_WINDOWS_DRIVER diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index 89d22f0e..6fc75b43 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -201,63 +201,63 @@ typedef struct #include "blake2.h" #ifndef TC_WINDOWS_BOOT # include "Sha2.h" # include "Whirlpool.h" # include "Streebog.h" # include "kuznyechik.h" # include "Camellia.h" #if !defined (_UEFI) # include "chachaRng.h" # ifdef _WIN64 # include "t1ha.h" # endif #endif #else # include "CamelliaSmall.h" #endif #include "GfMul.h" #include "Password.h" #ifndef TC_WINDOWS_BOOT #include "config.h" typedef struct keyInfo_t { int noIterations; /* Number of times to iterate (PKCS-5) */ int keyLength; /* Length of the key */ uint64 dummy; /* Dummy field to ensure 16-byte alignment of this structure */ - __int8 salt[PKCS5_SALT_SIZE]; /* PKCS-5 salt */ - CRYPTOPP_ALIGN_DATA(16) __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* Concatenated master primary and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */ - CRYPTOPP_ALIGN_DATA(16) __int8 userKey[MAX_PASSWORD]; /* Password (to which keyfiles may have been applied). WITHOUT +1 for the null terminator. */ + unsigned __int8 salt[PKCS5_SALT_SIZE]; /* PKCS-5 salt */ + CRYPTOPP_ALIGN_DATA(16) unsigned __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* Concatenated master primary and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */ + CRYPTOPP_ALIGN_DATA(16) unsigned __int8 userKey[MAX_PASSWORD]; /* Password (to which keyfiles may have been applied). WITHOUT +1 for the null terminator. */ } KEY_INFO, *PKEY_INFO; #endif typedef struct CRYPTO_INFO_t { int ea; /* Encryption algorithm ID */ int mode; /* Mode of operation (e.g., XTS) */ int pkcs5; /* PRF algorithm */ unsigned __int8 ks[MAX_EXPANDED_KEY]; /* Primary key schedule (if it is a cascade, it conatins multiple concatenated keys) */ unsigned __int8 ks2[MAX_EXPANDED_KEY]; /* Secondary key schedule (if cascade, multiple concatenated) for XTS mode. */ BOOL hiddenVolume; // Indicates whether the volume is mounted/mountable as hidden volume #ifndef TC_WINDOWS_BOOT uint16 HeaderVersion; #ifdef TC_WINDOWS_DRIVER unsigned __int8 master_keydata_hash[BLAKE2S_DIGESTSIZE]; #else CRYPTOPP_ALIGN_DATA(16) unsigned __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* This holds the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */ CRYPTOPP_ALIGN_DATA(16) 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. */ #endif int noIterations; int volumePim; BOOL bProtectHiddenVolume; // Indicates whether the volume contains a hidden volume to be protected against overwriting BOOL bHiddenVolProtectionAction; // TRUE if a write operation has been denied by the driver in order to prevent the hidden volume from being overwritten (set to FALSE upon volume mount). @@ -282,100 +282,100 @@ typedef struct CRYPTO_INFO_t #endif // !TC_WINDOWS_BOOT UINT64_STRUCT VolumeSize; UINT64_STRUCT EncryptedAreaStart; UINT64_STRUCT EncryptedAreaLength; uint32 HeaderFlags; } CRYPTO_INFO, *PCRYPTO_INFO; #if defined(_WIN32) || defined(_UEFI) #pragma pack (push) #pragma pack(1) typedef struct BOOT_CRYPTO_HEADER_t { __int16 ea; /* Encryption algorithm ID */ __int16 mode; /* Mode of operation (e.g., XTS) */ __int16 pkcs5; /* PRF algorithm */ } BOOT_CRYPTO_HEADER, *PBOOT_CRYPTO_HEADER; #pragma pack (pop) #endif PCRYPTO_INFO crypto_open (void); #ifndef TC_WINDOWS_BOOT -void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen); +void crypto_loadkey (PKEY_INFO keyInfo, unsigned char *lpszUserKey, int nUserKeyLen); void crypto_eraseKeys (PCRYPTO_INFO cryptoInfo); #endif void crypto_close (PCRYPTO_INFO cryptoInfo); int CipherGetBlockSize (int cipher); int CipherGetKeySize (int cipher); int CipherGetKeyScheduleSize (int cipher); BOOL CipherSupportsIntraDataUnitParallelization (int cipher); #ifndef TC_WINDOWS_BOOT const wchar_t * CipherGetName (int cipher); #endif int CipherInit (int cipher, unsigned char *key, unsigned char *ks); #ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE int EAInit (int ea, unsigned char *key, unsigned char *ks); #else int EAInit (unsigned char *key, unsigned char *ks); #endif BOOL EAInitMode (PCRYPTO_INFO ci, unsigned char* key2); void EncipherBlock(int cipher, void *data, void *ks); void DecipherBlock(int cipher, void *data, void *ks); #ifndef TC_WINDOWS_BOOT void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount); void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount); #endif int EAGetFirst (); int EAGetCount (void); int EAGetNext (int previousEA); #ifndef TC_WINDOWS_BOOT wchar_t * EAGetName (wchar_t *buf, size_t bufLen, int ea, int guiDisplay); int EAGetByName (wchar_t *name); #endif int EAGetKeySize (int ea); int EAGetFirstMode (int ea); int EAGetNextMode (int ea, int previousModeId); #ifndef TC_WINDOWS_BOOT -wchar_t * EAGetModeName (int ea, int mode, BOOL capitalLetters); +const wchar_t * EAGetModeName (int mode); #endif int EAGetKeyScheduleSize (int ea); int EAGetLargestKey (); int EAGetLargestKeyForMode (int mode); int EAGetCipherCount (int ea); int EAGetFirstCipher (int ea); int EAGetLastCipher (int ea); int EAGetNextCipher (int ea, int previousCipherId); int EAGetPreviousCipher (int ea, int previousCipherId); #ifndef TC_WINDOWS_BOOT int EAIsFormatEnabled (int ea); int EAIsMbrSysEncEnabled (int ea); #endif BOOL EAIsModeSupported (int ea, int testedMode); #ifndef TC_WINDOWS_BOOT const wchar_t *HashGetName (int hash_algo_id); #ifdef _WIN32 int HashGetIdByName (wchar_t *name); #endif Hash *HashGet (int id); void HashGetName2 (wchar_t *buf, size_t bufLen, int hashId); BOOL HashIsDeprecated (int hashId); BOOL HashForSystemEncryption (int hashId); int GetMaxPkcs5OutSize (void); #endif diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index b91167d4..ba0173ac 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -832,65 +832,60 @@ BOOL TCCopyFile (wchar_t *sourceFileName, wchar_t *destinationFile) GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (src == INVALID_HANDLE_VALUE) return FALSE; dst = CreateFileW (destinationFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (dst == INVALID_HANDLE_VALUE) { CloseHandle (src); return FALSE; } return TCCopyFileBase (src, dst); } BOOL VerifyModuleSignature (const wchar_t* path) { #if defined(NDEBUG) && !defined (VC_SKIP_OS_DRIVER_REQ_CHECK) BOOL bResult = FALSE; HRESULT hResult; GUID gActionID = WINTRUST_ACTION_GENERIC_VERIFY_V2; WINTRUST_FILE_INFO fileInfo = {0}; WINTRUST_DATA WVTData = {0}; wchar_t filePath [TC_MAX_PATH + 1024]; - // we check our own authenticode signature only starting from Windows 10 since this is - // the minimal supported OS apart from XP where we can't verify SHA256 signatures - if (!IsOSAtLeast (WIN_10)) - return TRUE; - // Strip quotation marks (if any) if (path [0] == L'"') { StringCbCopyW (filePath, sizeof(filePath), path + 1); } else { StringCbCopyW (filePath, sizeof(filePath), path); } // Strip quotation marks (if any) if (filePath [wcslen (filePath) - 1] == L'"') filePath [wcslen (filePath) - 1] = 0; fileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO); fileInfo.pcwszFilePath = filePath; fileInfo.hFile = NULL; WVTData.cbStruct = sizeof(WINTRUST_DATA); WVTData.dwUIChoice = WTD_UI_NONE; WVTData.fdwRevocationChecks = WTD_REVOKE_NONE; WVTData.dwUnionChoice = WTD_CHOICE_FILE; WVTData.pFile = &fileInfo; WVTData.dwStateAction = WTD_STATEACTION_VERIFY; WVTData.dwProvFlags = WTD_REVOCATION_CHECK_NONE | WTD_CACHE_ONLY_URL_RETRIEVAL; hResult = WinVerifyTrust(0, &gActionID, &WVTData); if (0 == hResult) { PCRYPT_PROVIDER_DATA pProviderData = WTHelperProvDataFromStateData (WVTData.hWVTStateData); @@ -3576,64 +3571,64 @@ extern "C" { // activate process mitigations (currently only ASLR, dynamic code and extensions points) ActivateProcessMitigations(); #ifndef SETUP // call ActivateMemoryProtection if corresponding setting has been enabled (default is enabled) if (ReadMemoryProtectionConfig()) { ActivateMemoryProtection(); } #endif return wWinMainCRTStartup(); } } #endif /* InitApp - initialize the application, this function is called once in the applications WinMain function, but before the main dialog has been created */ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine) { WNDCLASSW wc; char langId[6]; SetDefaultDllDirectoriesPtr SetDefaultDllDirectoriesFn = NULL; #if !defined(SETUP) wchar_t modPath[MAX_PATH]; #endif INITCOMMONCONTROLSEX InitCtrls; InitOSVersionInfo(); - if (!IsOSAtLeast (WIN_7)) + if (!IsOSAtLeast (WIN_10)) { - // abort using a message that says that VeraCrypt can run only on Windows 7 and later and that it is officially supported only on Windows 10 and later - AbortProcessDirect(L"VeraCrypt requires at least Windows 7 to run."); + // abort using a message that says that VeraCrypt can run only on Windows 10 and later + AbortProcessDirect(L"VeraCrypt requires at least Windows 10 to run."); } SetDefaultDllDirectoriesFn = (SetDefaultDllDirectoriesPtr) GetProcAddress (GetModuleHandle(L"kernel32.dll"), "SetDefaultDllDirectories"); if (!SetDefaultDllDirectoriesFn) { // This can happen only if KB2533623 is missing from Windows 7 AbortProcessDirect(L"VeraCrypt requires KB2533623 to be installed on Windows 7 and Windows Server 2008 R2 in order to run."); } VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin)); InitGlobalLocks (); // call InitCommonControlsEx function to initialize the common controls InitCtrls.dwSize = sizeof (InitCtrls); InitCtrls.dwICC = ICC_WIN95_CLASSES | ICC_PAGESCROLLER_CLASS | ICC_NATIVEFNTCTL_CLASS | ICC_STANDARD_CLASSES | ICC_LINK_CLASS; InitCommonControlsEx (&InitCtrls); // Load RichEdit library in order to be able to use RichEdit20W class LoadLibraryEx (L"Riched20.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); #if !defined(SETUP) GetModuleFileNameW (NULL, modPath, ARRAYSIZE (modPath)); if (!VerifyModuleSignature (modPath)) AbortProcessDirect (L"This distribution package is damaged. Please try downloading it again (preferably from the official VeraCrypt website at https://www.veracrypt.fr)."); #endif #ifndef SETUP /* enable drag-n-drop when we are running elevated */ AllowMessageInUIPI (WM_DROPFILES); @@ -6239,99 +6234,99 @@ static BOOL PerformBenchmark(HWND hBenchDlg, HWND hwndDlg) STREEBOG_init(&stctx); STREEBOG_add(&stctx, lpTestBuffer, benchmarkBufferSize); STREEBOG_finalize(&stctx, (unsigned char *)digest); break; } #endif } if (QueryPerformanceCounter (&performanceCountEnd) == 0) goto counter_error; benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; benchmarkTable[benchmarkTotalItems].decSpeed = benchmarkTable[benchmarkTotalItems].encSpeed; benchmarkTable[benchmarkTotalItems].id = hid; benchmarkTable[benchmarkTotalItems].meanBytesPerSec = (unsigned __int64) (benchmarkBufferSize / ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart / 2)); StringCbPrintfW (benchmarkTable[benchmarkTotalItems].name, sizeof(benchmarkTable[benchmarkTotalItems].name),L"%s", HashGetName(hid)); benchmarkTotalItems++; } } break; case BENCHMARK_TYPE_PRF: /* Measures the time that it takes for the PKCS-5 routine to derive a header key using each of the implemented PRF algorithms. */ { int thid, i; - char dk[MASTER_KEYDATA_SIZE]; + unsigned char dk[MASTER_KEYDATA_SIZE]; char *tmp_salt = {"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF\x01\x23\x45\x67\x89\xAB\xCD\xEF\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"}; for (thid = FIRST_PRF_ID; thid <= LAST_PRF_ID; thid++) { if (benchmarkPreBoot && !benchmarkGPT && !HashForSystemEncryption (thid)) continue; if (QueryPerformanceCounter (&performanceCountStart) == 0) goto counter_error; for (i = 1; i <= 2; i++) { switch (thid) { 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, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_sha512 ((unsigned char*) "passphrase-1234567890", 21, (unsigned char*) tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), 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, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_sha256 ((unsigned char*)"passphrase-1234567890", 21, (unsigned char*) tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); break; #ifndef WOLFCRYPT_BACKEND case BLAKE2S: /* PKCS-5 test with HMAC-BLAKE2s used as the PRF */ - derive_key_blake2s ("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_blake2s ((unsigned char*)"passphrase-1234567890", 21, (unsigned char*) tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), 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, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_whirlpool ((unsigned char*)"passphrase-1234567890", 21, (unsigned char*) tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); break; case STREEBOG: /* PKCS-5 test with HMAC-STREEBOG used as the PRF */ - derive_key_streebog("passphrase-1234567890", 21, tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); + derive_key_streebog((unsigned char*)"passphrase-1234567890", 21, (unsigned char*) tmp_salt, 64, get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot), dk, MASTER_KEYDATA_SIZE); break; } #endif } if (QueryPerformanceCounter (&performanceCountEnd) == 0) goto counter_error; benchmarkTable[benchmarkTotalItems].encSpeed = performanceCountEnd.QuadPart - performanceCountStart.QuadPart; benchmarkTable[benchmarkTotalItems].id = thid; benchmarkTable[benchmarkTotalItems].decSpeed = get_pkcs5_iteration_count(thid, benchmarkPim, benchmarkPreBoot); benchmarkTable[benchmarkTotalItems].meanBytesPerSec = (unsigned __int64) (1000 * ((float) benchmarkTable[benchmarkTotalItems].encSpeed / benchmarkPerformanceFrequency.QuadPart / 2)); if (benchmarkPreBoot) { /* heuristics for boot times */ if (benchmarkGPT) { benchmarkTable[benchmarkTotalItems].meanBytesPerSec = (benchmarkTable[benchmarkTotalItems].meanBytesPerSec * 8) / 5; } else { if (thid == SHA256) { #ifdef _WIN64 benchmarkTable[benchmarkTotalItems].meanBytesPerSec = (benchmarkTable[benchmarkTotalItems].meanBytesPerSec * 26); #else benchmarkTable[benchmarkTotalItems].meanBytesPerSec = (benchmarkTable[benchmarkTotalItems].meanBytesPerSec * 24); #endif } else @@ -7612,61 +7607,61 @@ CipherTestDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) for (ci->ea = EAGetFirst (); ci->ea != 0 ; ci->ea = EAGetNext (ci->ea)) if (EAGetCipherCount (ci->ea) == 1 && EAGetFirstCipher (ci->ea) == idTestCipher) break; if ((tmpRetVal = EAInit (ci->ea, (unsigned char *) key, ci->ks)) != ERR_SUCCESS) { handleError (hwndDlg, tmpRetVal, SRC_POS); crypto_close (ci); return 1; } memcpy (&ci->k2, secondaryKey, sizeof (secondaryKey)); if (!EAInitMode (ci, ci->k2)) { crypto_close (ci); return 1; } structDataUnitNo.Value = BE64(((unsigned __int64 *)dataUnitNo)[0]); if (bEncrypt) EncryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher); else DecryptBufferXTS ((unsigned char *) tmp, pt, &structDataUnitNo, blockNo, (unsigned char *) (ci->ks), (unsigned char *) ci->ks2, idTestCipher); crypto_close (ci); } else { - CipherInit2(idTestCipher, key, ks_tmp, ks); + CipherInit2(idTestCipher, key, ks_tmp); if (bEncrypt) { EncipherBlock(idTestCipher, tmp, ks_tmp); } else { DecipherBlock(idTestCipher, tmp, ks_tmp); } } *szTmp = 0; for (n = 0; n < pt; n ++) { wchar_t szTmp2[3]; StringCbPrintfW(szTmp2, sizeof(szTmp2), L"%02x", (int)((unsigned char)tmp[n])); StringCbCatW(szTmp, sizeof(szTmp), szTmp2); } if (bEncrypt) SetWindowText(GetDlgItem(hwndDlg,IDC_CIPHERTEXT), szTmp); else SetWindowText(GetDlgItem(hwndDlg,IDC_PLAINTEXT), szTmp); } return 1; } if (lw == IDCLOSE || lw == IDCANCEL) @@ -11453,61 +11448,61 @@ BYTE *MapResource (wchar_t *resourceType, int resourceId, PDWORD size) return (BYTE *) LockResource (hResL); } void InconsistencyResolved (char *techInfo) { wchar_t finalMsg[8024]; StringCbPrintfW (finalMsg, sizeof(finalMsg), GetString ("INCONSISTENCY_RESOLVED"), techInfo); MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST); } void ReportUnexpectedState (const char *techInfo) { wchar_t finalMsg[8024]; StringCbPrintfW (finalMsg, sizeof(finalMsg), GetString ("UNEXPECTED_STATE"), techInfo); MessageBoxW (MainDlg, finalMsg, lpszTitle, MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST); } #ifndef SETUP int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password *password, int pkcs5_prf, int pim, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader) { int status = ERR_PARAMETER_INCORRECT; int volumeType; wchar_t szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH]; wchar_t szDosDevice[TC_MAX_PATH]; - char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + unsigned char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; LARGE_INTEGER headerOffset; DWORD dwResult; DISK_GEOMETRY_EX deviceGeometry; context->VolumeIsOpen = FALSE; context->CryptoInfo = NULL; context->HostFileHandle = INVALID_HANDLE_VALUE; context->TimestampsValid = FALSE; CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), volumePath, &context->IsDevice); if (context->IsDevice) { status = FakeDosNameForDevice (szDiskFile, szDosDevice, sizeof(szDosDevice), szCFDevice, sizeof(szCFDevice), FALSE); if (status != 0) return status; preserveTimestamps = FALSE; if (!GetDriveGeometry (volumePath, &deviceGeometry)) { status = ERR_OS_ERROR; goto error; } } else StringCbCopyW (szCFDevice, sizeof(szCFDevice), szDiskFile); context->HostFileHandle = CreateFile (szCFDevice, GENERIC_READ | (write ? GENERIC_WRITE : (!context->IsDevice && preserveTimestamps? FILE_WRITE_ATTRIBUTES : 0)), FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); @@ -11667,61 +11662,61 @@ error: SetLastError (sysError); return status; } void CloseVolume (OpenVolumeContext *context) { if (!context->VolumeIsOpen) return; if (context->HostFileHandle != INVALID_HANDLE_VALUE) { if (context->TimestampsValid) SetFileTime (context->HostFileHandle, &context->CreationTime, &context->LastAccessTime, &context->LastWriteTime); CloseHandle (context->HostFileHandle); context->HostFileHandle = INVALID_HANDLE_VALUE; } if (context->CryptoInfo) { crypto_close (context->CryptoInfo); context->CryptoInfo = NULL; } context->VolumeIsOpen = FALSE; } -int ReEncryptVolumeHeader (HWND hwndDlg, char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, int pim, BOOL wipeMode) +int ReEncryptVolumeHeader (HWND hwndDlg, unsigned char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, int pim, BOOL wipeMode) { CRYPTO_INFO *newCryptoInfo = NULL; RandSetHashFunction (cryptoInfo->pkcs5); if (Randinit() != ERR_SUCCESS) { if (CryptoAPILastError == ERROR_SUCCESS) return ERR_RAND_INIT_FAILED; else return ERR_CAPI_INIT_FAILED; } UserEnrichRandomPool (NULL); int status = CreateVolumeHeaderInMemory (hwndDlg, bBoot, buffer, cryptoInfo->ea, cryptoInfo->mode, password, cryptoInfo->pkcs5, pim, (char *) cryptoInfo->master_keydata, &newCryptoInfo, cryptoInfo->VolumeSize.Value, cryptoInfo->hiddenVolume ? cryptoInfo->hiddenVolumeSize : 0, cryptoInfo->EncryptedAreaStart.Value, cryptoInfo->EncryptedAreaLength.Value, cryptoInfo->RequiredProgramVersion, cryptoInfo->HeaderFlags, diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 288daecd..1b2ead2a 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -513,61 +513,61 @@ void HandleDriveNotReadyError (HWND hwnd); BOOL CALLBACK CloseTCWindowsEnum( HWND hwnd, LPARAM lParam); BOOL CALLBACK FindTCWindowEnum (HWND hwnd, LPARAM lParam); BYTE *MapResource (wchar_t *resourceType, int resourceId, PDWORD size); void InconsistencyResolved (char *msg); void ReportUnexpectedState (const char *techInfo); void OpenOnlineHelp (); BOOL GetPartitionInfo (const wchar_t *deviceName, PPARTITION_INFORMATION rpartInfo); BOOL GetDeviceInfo (const wchar_t *deviceName, DISK_PARTITION_INFO_STRUCT *info); BOOL GetDriveGeometry (const wchar_t *deviceName, PDISK_GEOMETRY_EX diskGeometry); BOOL GetPhysicalDriveGeometry (int driveNumber, PDISK_GEOMETRY diskGeometry); BOOL IsVolumeDeviceHosted (const wchar_t *lpszDiskFile); int CompensateXDPI (int val); int CompensateYDPI (int val); int CompensateDPIFont (int val); int GetTextGfxWidth (HWND hwndDlgItem, const wchar_t *text, HFONT hFont); int GetTextGfxHeight (HWND hwndDlgItem, const wchar_t *text, HFONT hFont); BOOL ToHyperlink (HWND hwndDlg, UINT ctrlId); BOOL ToCustHyperlink (HWND hwndDlg, UINT ctrlId, HFONT hFont); void DisableCloseButton (HWND hwndDlg); void EnableCloseButton (HWND hwndDlg); void ToBootPwdField (HWND hwndDlg, UINT ctrlId); void ToNormalPwdField (HWND hwndDlg, UINT ctrlId); void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT hFont); void AccommodateCheckBoxTextWidth (HWND hwndDlg, UINT ctrlId); void MakeControlsContiguous(HWND hwndDlg, UINT ctrl1ID, UINT ctrl2ID); BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize); BOOL GetSysDevicePaths (HWND hwndDlg); BOOL DoDriverInstall (HWND hwndDlg); int OpenVolume (OpenVolumeContext *context, const wchar_t *volumePath, Password *password, int pkcs5_prf, int pim, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader); void CloseVolume (OpenVolumeContext *context); -int ReEncryptVolumeHeader (HWND hwndDlg, char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, int pim, BOOL wipeMode); +int ReEncryptVolumeHeader (HWND hwndDlg, unsigned char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, int pim, BOOL wipeMode); BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly); BOOL IsPagingFileWildcardActive (); BOOL DisablePagingFile (); BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); BOOL InitSecurityTokenLibrary (HWND hwndDlg); BOOL FileHasReadOnlyAttribute (const wchar_t *path); BOOL IsFileOnReadOnlyFilesystem (const wchar_t *path); void CheckFilesystem (HWND hwndDlg, int driveNo, BOOL fixErrors); BOOL BufferContainsPattern (const uint8 *buffer, size_t bufferSize, const uint8 *pattern, size_t patternSize); BOOL BufferContainsString (const uint8 *buffer, size_t bufferSize, const char *str); BOOL BufferContainsWideString (const uint8 *buffer, size_t bufferSize, const wchar_t *str); int AskNonSysInPlaceEncryptionResume (HWND hwndDlg, BOOL* pbDecrypt); BOOL RemoveDeviceWriteProtection (HWND hwndDlg, wchar_t *devicePath); void EnableElevatedCursorChange (HWND parent); BOOL DisableFileCompression (HANDLE file); BOOL VolumePathExists (const wchar_t *volumePath); BOOL IsWindowsIsoBurnerAvailable (); BOOL LaunchWindowsIsoBurner (HWND hwnd, const wchar_t *isoPath); BOOL IsApplicationInstalled (const wchar_t *appName); int GetPim (HWND hwndDlg, UINT ctrlId, int defaultPim); void SetPim (HWND hwndDlg, UINT ctrlId, int pim); BOOL GetPassword (HWND hwndDlg, UINT ctrlID, char* passValue, int bufSize, BOOL bLegacyPassword, BOOL bShowError); void SetPassword (HWND hwndDlg, UINT ctrlID, char* passValue); void HandleShowPasswordFieldAction (HWND hwndDlg, UINT checkBoxId, UINT edit1Id, UINT edit2Id); HKEY OpenDeviceClassRegKey (const GUID *deviceClassGuid); LSTATUS DeleteRegistryKey (HKEY, LPCTSTR); HIMAGELIST CreateImageList(int cx, int cy, UINT flags, int cInitial, int cGrow); int AddBitmapToImageList(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask); HRESULT VCStrDupW(LPCWSTR psz, LPWSTR *ppwsz); diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c index 79f1c890..3078e895 100644 --- a/src/Common/EncryptionThreadPool.c +++ b/src/Common/EncryptionThreadPool.c @@ -71,68 +71,68 @@ typedef enum WorkItemReady, WorkItemBusy } WorkItemState; typedef struct EncryptionThreadPoolWorkItemStruct { WorkItemState State; EncryptionThreadPoolWorkType Type; TC_EVENT ItemCompletedEvent; struct EncryptionThreadPoolWorkItemStruct *FirstFragment; LONG OutstandingFragmentCount; union { struct { PCRYPTO_INFO CryptoInfo; uint8 *Data; UINT64_STRUCT StartUnitNo; uint32 UnitCount; } Encryption; struct { TC_EVENT *CompletionEvent; LONG *CompletionFlag; - char *DerivedKey; + unsigned char *DerivedKey; int IterationCount; TC_EVENT *NoOutstandingWorkItemEvent; LONG *OutstandingWorkItemCount; - char *Password; + unsigned char *Password; int PasswordLength; int Pkcs5Prf; - char *Salt; + unsigned char *Salt; } KeyDerivation; struct { TC_EVENT *KeyDerivationCompletedEvent; TC_EVENT *NoOutstandingWorkItemEvent; LONG *outstandingWorkItemCount; void* keyInfoBuffer; int keyInfoBufferSize; void* keyDerivationWorkItems; int keyDerivationWorkItemsSize; } ReadVolumeHeaderFinalization; }; } EncryptionThreadPoolWorkItem; static volatile BOOL ThreadPoolRunning = FALSE; static volatile BOOL StopPending = FALSE; static uint32 ThreadCount; static TC_THREAD_HANDLE ThreadHandles[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT]; static WORD ThreadProcessorGroups[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT]; static EncryptionThreadPoolWorkItem WorkItemQueue[TC_ENC_THREAD_POOL_QUEUE_SIZE]; static volatile int EnqueuePosition; static volatile int DequeuePosition; @@ -506,61 +506,61 @@ void EncryptionThreadPoolStop () for (i = 0; i < ThreadCount; ++i) { #ifdef DEVICE_DRIVER TCStopThread (ThreadHandles[i], &WorkItemReadyEvent); #else TC_WAIT_EVENT (ThreadHandles[i]); #endif } ThreadCount = 0; #ifndef DEVICE_DRIVER CloseHandle (DequeueMutex); CloseHandle (EnqueueMutex); CloseHandle (WorkItemReadyEvent); CloseHandle (WorkItemCompletedEvent); for (i = 0; i < sizeof (WorkItemQueue) / sizeof (WorkItemQueue[0]); ++i) { if (WorkItemQueue[i].ItemCompletedEvent) CloseHandle (WorkItemQueue[i].ItemCompletedEvent); } #endif ThreadPoolRunning = FALSE; } -void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey) +void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, unsigned char *password, int passwordLength, unsigned char *salt, int iterationCount, unsigned char *derivedKey) { EncryptionThreadPoolWorkItem *workItem; if (!ThreadPoolRunning) TC_THROW_FATAL_EXCEPTION; TC_ACQUIRE_MUTEX (&EnqueueMutex); workItem = &WorkItemQueue[EnqueuePosition++]; if (EnqueuePosition >= ThreadQueueSize) EnqueuePosition = 0; while (GetWorkItemState (workItem) != WorkItemFree) { TC_WAIT_EVENT (WorkItemCompletedEvent); } workItem->Type = DeriveKeyWork; workItem->KeyDerivation.CompletionEvent = completionEvent; workItem->KeyDerivation.CompletionFlag = completionFlag; workItem->KeyDerivation.DerivedKey = derivedKey; workItem->KeyDerivation.IterationCount = iterationCount; workItem->KeyDerivation.NoOutstandingWorkItemEvent = noOutstandingWorkItemEvent; workItem->KeyDerivation.OutstandingWorkItemCount = outstandingWorkItemCount; workItem->KeyDerivation.Password = password; workItem->KeyDerivation.PasswordLength = passwordLength; workItem->KeyDerivation.Pkcs5Prf = pkcs5Prf; workItem->KeyDerivation.Salt = salt; InterlockedIncrement (outstandingWorkItemCount); diff --git a/src/Common/EncryptionThreadPool.h b/src/Common/EncryptionThreadPool.h index 71df4e4d..2e727a74 100644 --- a/src/Common/EncryptionThreadPool.h +++ b/src/Common/EncryptionThreadPool.h @@ -5,44 +5,44 @@ Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #ifndef TC_HEADER_ENCRYPTION_THREAD_POOL #define TC_HEADER_ENCRYPTION_THREAD_POOL #include "Tcdefs.h" #include "Crypto.h" #ifdef __cplusplus extern "C" { #endif typedef enum { EncryptDataUnitsWork, DecryptDataUnitsWork, DeriveKeyWork, ReadVolumeHeaderFinalizationWork } EncryptionThreadPoolWorkType; #ifndef DEVICE_DRIVER size_t GetCpuCount (WORD* pGroupCount); #endif -void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey); +void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, unsigned char *password, int passwordLength, unsigned char *salt, int iterationCount, unsigned char *derivedKey); void EncryptionThreadPoolBeginReadVolumeHeaderFinalization (TC_EVENT *keyDerivationCompletedEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG* outstandingWorkItemCount, void* keyInfoBuffer, int keyInfoBufferSize, void* keyDerivationWorkItems, int keyDerivationWorkItemsSize); void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, uint8 *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo); BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount); void EncryptionThreadPoolStop (); size_t GetEncryptionThreadCount (); size_t GetMaxEncryptionThreadCount (); BOOL IsEncryptionThreadPoolRunning (); #ifdef __cplusplus } #endif #endif // TC_HEADER_ENCRYPTION_THREAD_POOL diff --git a/src/Common/Format.c b/src/Common/Format.c index 7eff80e6..635a2b09 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -57,61 +57,61 @@ uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize) # error TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE too large for very small volumes. Revise the code. #endif #if TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH < TC_MAX_VOLUME_SECTOR_SIZE # error TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH too small. #endif if (volumeSize < TC_VOLUME_SMALL_SIZE_THRESHOLD) reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE; else reservedSize = TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH; // Ensure size of a hidden volume larger than TC_VOLUME_SMALL_SIZE_THRESHOLD is a multiple of the maximum supported sector size } else { reservedSize = TC_TOTAL_VOLUME_HEADERS_SIZE; } if (volumeSize < reservedSize) return 0; return volumeSize - reservedSize; } int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams) { int nStatus; PCRYPTO_INFO cryptoInfo = NULL; HANDLE dev = INVALID_HANDLE_VALUE; DWORD dwError; - char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + unsigned char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; unsigned __int64 num_sectors, startSector; fatparams ft; FILETIME ftCreationTime; FILETIME ftLastWriteTime; FILETIME ftLastAccessTime; BOOL bTimeStampValid = FALSE; BOOL bInstantRetryOtherFilesys = FALSE; WCHAR dosDev[TC_MAX_PATH] = { 0 }; WCHAR devName[MAX_PATH] = { 0 }; int driveLetter = -1; WCHAR deviceName[MAX_PATH]; uint64 dataOffset, dataAreaSize; LARGE_INTEGER offset; BOOL bFailedRequiredDASD = FALSE; HWND hwndDlg = volParams->hwndDlg; #ifdef _WIN64 CRYPTO_INFO tmpCI; PCRYPTO_INFO cryptoInfoBackup = NULL; #endif FormatSectorSize = volParams->sectorSize; if (FormatSectorSize < TC_MIN_VOLUME_SECTOR_SIZE || FormatSectorSize > TC_MAX_VOLUME_SECTOR_SIZE || FormatSectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0) { Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg); return ERR_DONT_REPORT; } diff --git a/src/Common/Password.c b/src/Common/Password.c index c0247207..aed7cfb9 100644 --- a/src/Common/Password.c +++ b/src/Common/Password.c @@ -146,61 +146,61 @@ BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim return FALSE; } #ifndef _DEBUG if (!bSkipPasswordWarning && (MessageBoxW (hwndDlg, GetString ("PASSWORD_LENGTH_WARNING"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2) != IDYES)) return FALSE; #endif } #ifndef _DEBUG else if (bCustomPimSmall) { if (!bSkipPimWarning && AskWarnNoYes ("PIM_SMALL_WARNING", hwndDlg) != IDYES) return FALSE; } #endif if ((pim != 0) && (pim > (bootPimCondition? 98 : 485))) { // warn that mount/boot will take more time Warning ("PIM_LARGE_WARNING", hwndDlg); } return TRUE; } int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5, int old_pim, Password *newPassword, int pkcs5, int pim, int wipePassCount, HWND hwndDlg) { int nDosLinkCreated = 1, nStatus = ERR_OS_ERROR; wchar_t szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH]; wchar_t szDosDevice[TC_MAX_PATH]; - char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + unsigned char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; PCRYPTO_INFO cryptoInfo = NULL, ci = NULL; void *dev = INVALID_HANDLE_VALUE; DWORD dwError; DWORD bytesRead; BOOL bDevice; unsigned __int64 hostSize = 0; int volumeType; int wipePass; FILETIME ftCreationTime; FILETIME ftLastWriteTime; FILETIME ftLastAccessTime; BOOL bTimeStampValid = FALSE; LARGE_INTEGER headerOffset; BOOL backupHeader; if (oldPassword->Length == 0 || newPassword->Length == 0) return -1; if (wipePassCount <= 0) { nStatus = ERR_PARAMETER_INCORRECT; handleError (hwndDlg, nStatus, SRC_POS); return nStatus; } if (!lpszVolume) { nStatus = ERR_OUTOFMEMORY; handleError (hwndDlg, nStatus, SRC_POS); return nStatus; } diff --git a/src/Common/Pkcs5.c b/src/Common/Pkcs5.c index d81078e8..7b78767e 100644 --- a/src/Common/Pkcs5.c +++ b/src/Common/Pkcs5.c @@ -16,1264 +16,1165 @@ #include <memory.h> #include <stdlib.h> #endif #include "blake2.h" #ifndef TC_WINDOWS_BOOT #include "Sha2.h" #include "Whirlpool.h" #include "cpu.h" #include "misc.h" #else #pragma optimize ("t", on) #include <string.h> #if defined( _MSC_VER ) # ifndef DEBUG # pragma intrinsic( memcpy ) # pragma intrinsic( memset ) # endif #endif #include "Sha2Small.h" #endif #include "Pkcs5.h" #include "Crypto.h" #if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_SHA2) typedef struct hmac_sha256_ctx_struct { sha256_ctx ctx; sha256_ctx inner_digest_ctx; /*pre-computed inner digest context */ sha256_ctx outer_digest_ctx; /*pre-computed outer digest context */ - char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the SHA256 hash */ - char u[SHA256_DIGESTSIZE]; + unsigned char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the SHA256 hash */ + unsigned char u[SHA256_DIGESTSIZE]; } hmac_sha256_ctx; void hmac_sha256_internal ( - char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ + unsigned char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ int ld, /* length of input data in bytes */ hmac_sha256_ctx* hmac /* HMAC-SHA256 context which holds temporary variables */ ) { sha256_ctx* ctx = &(hmac->ctx); /**** Restore Precomputed Inner Digest Context ****/ memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (sha256_ctx)); - sha256_hash ((unsigned char *) d, ld, ctx); + sha256_hash (d, ld, ctx); - sha256_end ((unsigned char *) d, ctx); /* d = inner digest */ + sha256_end (d, ctx); /* d = inner digest */ /**** Restore Precomputed Outer Digest Context ****/ memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (sha256_ctx)); - sha256_hash ((unsigned char *) d, SHA256_DIGESTSIZE, ctx); + sha256_hash (d, SHA256_DIGESTSIZE, ctx); - sha256_end ((unsigned char *) d, ctx); /* d = outer digest */ + sha256_end (d, ctx); /* d = outer digest */ } #ifndef TC_WINDOWS_BOOT void hmac_sha256 ( - char *k, /* secret key */ + unsigned char *k, /* secret key */ int lk, /* length of the key in bytes */ - char *d, /* data */ + unsigned char *d, /* data */ int ld /* length of data in bytes */ ) { hmac_sha256_ctx hmac; sha256_ctx* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b; - char key[SHA256_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) + unsigned char key[SHA256_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; -#ifdef _WIN64 XSTATE_SAVE SaveState; if (IsCpuIntel() && HasSAVX()) saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); -#else - KFLOATING_SAVE floatingPointState; - if (HasSSE2()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif #endif /* If the key is longer than the hash algorithm block size, let key = sha256(key), as per HMAC specifications. */ if (lk > SHA256_BLOCKSIZE) { sha256_ctx tctx; sha256_begin (&tctx); - sha256_hash ((unsigned char *) k, lk, &tctx); - sha256_end ((unsigned char *) key, &tctx); + sha256_hash (k, lk, &tctx); + sha256_end (key, &tctx); k = key; lk = SHA256_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); sha256_begin (ctx); /* Pad the key for inner digest */ for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x36); + buf[b] = (unsigned char) (k[b] ^ 0x36); memset (&buf[lk], 0x36, SHA256_BLOCKSIZE - lk); - sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx); + sha256_hash (buf, SHA256_BLOCKSIZE, ctx); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); sha256_begin (ctx); for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x5C); + buf[b] = (unsigned char) (k[b] ^ 0x5C); memset (&buf[lk], 0x5C, SHA256_BLOCKSIZE - lk); - sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx); + sha256_hash (buf, SHA256_BLOCKSIZE, ctx); hmac_sha256_internal(d, ld, &hmac); -#if defined (DEVICE_DRIVER) +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) if (NT_SUCCESS (saveStatus)) -#ifdef _WIN64 KeRestoreExtendedProcessorStateVC(&SaveState); -#else - KeRestoreFloatingPointState (&floatingPointState); -#endif #endif /* Prevent leaks */ burn(&hmac, sizeof(hmac)); burn(key, sizeof(key)); } #endif -static void derive_u_sha256 (char *salt, int salt_len, uint32 iterations, int b, hmac_sha256_ctx* hmac) +static void derive_u_sha256 (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_sha256_ctx* hmac) { - char* k = hmac->k; - char* u = hmac->u; + unsigned char* k = hmac->k; + unsigned char* u = hmac->u; uint32 c; int i; #ifdef TC_WINDOWS_BOOT /* In bootloader mode, least significant bit of iterations is a boolean (TRUE for boot derivation mode, FALSE otherwise) * and the most significant 16 bits hold the pim value * This enables us to save code space needed for implementing other features. */ c = iterations >> 16; i = ((int) iterations) & 0x01; if (i) c = (c == 0)? 200000 : c << 11; else c = (c == 0)? 500000 : 15000 + c * 1000; #else c = iterations; #endif /* iteration 1 */ memcpy (k, salt, salt_len); /* salt */ /* big-endian block number */ #ifdef TC_WINDOWS_BOOT /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256 */ memset (&k[salt_len], 0, 3); - k[salt_len + 3] = (char) b; + k[salt_len + 3] = (unsigned char) b; #else b = bswap_32 (b); memcpy (&k[salt_len], &b, 4); #endif hmac_sha256_internal (k, salt_len + 4, hmac); memcpy (u, k, SHA256_DIGESTSIZE); /* remaining iterations */ while (c > 1) { hmac_sha256_internal (k, SHA256_DIGESTSIZE, hmac); for (i = 0; i < SHA256_DIGESTSIZE; i++) { u[i] ^= k[i]; } c--; } } -void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) +void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) { hmac_sha256_ctx hmac; sha256_ctx* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b, l, r; #ifndef TC_WINDOWS_BOOT - char key[SHA256_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) + unsigned char key[SHA256_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; -#ifdef _WIN64 XSTATE_SAVE SaveState; if (IsCpuIntel() && HasSAVX()) saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); -#else - KFLOATING_SAVE floatingPointState; - if (HasSSE2()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif #endif /* If the password is longer than the hash algorithm block size, let pwd = sha256(pwd), as per HMAC specifications. */ if (pwd_len > SHA256_BLOCKSIZE) { sha256_ctx tctx; sha256_begin (&tctx); - sha256_hash ((unsigned char *) pwd, pwd_len, &tctx); - sha256_end ((unsigned char *) key, &tctx); + sha256_hash (pwd, pwd_len, &tctx); + sha256_end (key, &tctx); pwd = key; pwd_len = SHA256_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } #endif if (dklen % SHA256_DIGESTSIZE) { l = 1 + dklen / SHA256_DIGESTSIZE; } else { l = dklen / SHA256_DIGESTSIZE; } r = dklen - (l - 1) * SHA256_DIGESTSIZE; /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); sha256_begin (ctx); /* Pad the key for inner digest */ for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x36); + buf[b] = (unsigned char) (pwd[b] ^ 0x36); memset (&buf[pwd_len], 0x36, SHA256_BLOCKSIZE - pwd_len); - sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx); + sha256_hash (buf, SHA256_BLOCKSIZE, ctx); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); sha256_begin (ctx); for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x5C); + buf[b] = (unsigned char) (pwd[b] ^ 0x5C); memset (&buf[pwd_len], 0x5C, SHA256_BLOCKSIZE - pwd_len); - sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx); + sha256_hash (buf, SHA256_BLOCKSIZE, ctx); /* first l - 1 blocks */ for (b = 1; b < l; b++) { derive_u_sha256 (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, SHA256_DIGESTSIZE); dk += SHA256_DIGESTSIZE; } /* last block */ derive_u_sha256 (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); -#if defined (DEVICE_DRIVER) +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) if (NT_SUCCESS (saveStatus)) -#ifdef _WIN64 KeRestoreExtendedProcessorStateVC(&SaveState); -#else - KeRestoreFloatingPointState (&floatingPointState); -#endif #endif /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); #ifndef TC_WINDOWS_BOOT burn (key, sizeof(key)); #endif } #endif #ifndef TC_WINDOWS_BOOT typedef struct hmac_sha512_ctx_struct { sha512_ctx ctx; sha512_ctx inner_digest_ctx; /*pre-computed inner digest context */ sha512_ctx outer_digest_ctx; /*pre-computed outer digest context */ - char k[SHA512_BLOCKSIZE]; /* enough to hold (salt_len + 4) and also the SHA512 hash */ - char u[SHA512_DIGESTSIZE]; + unsigned char k[SHA512_BLOCKSIZE]; /* enough to hold (salt_len + 4) and also the SHA512 hash */ + unsigned char u[SHA512_DIGESTSIZE]; } hmac_sha512_ctx; void hmac_sha512_internal ( - char *d, /* data and also output buffer of at least 64 bytes */ + unsigned char *d, /* data and also output buffer of at least 64 bytes */ int ld, /* length of data in bytes */ hmac_sha512_ctx* hmac ) { sha512_ctx* ctx = &(hmac->ctx); /**** Restore Precomputed Inner Digest Context ****/ memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (sha512_ctx)); - sha512_hash ((unsigned char *) d, ld, ctx); + sha512_hash (d, ld, ctx); - sha512_end ((unsigned char *) d, ctx); + sha512_end (d, ctx); /**** Restore Precomputed Outer Digest Context ****/ memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (sha512_ctx)); - sha512_hash ((unsigned char *) d, SHA512_DIGESTSIZE, ctx); + sha512_hash (d, SHA512_DIGESTSIZE, ctx); - sha512_end ((unsigned char *) d, ctx); + sha512_end (d, ctx); } void hmac_sha512 ( - char *k, /* secret key */ + unsigned char *k, /* secret key */ int lk, /* length of the key in bytes */ - char *d, /* data and also output buffer of at least 64 bytes */ + unsigned char *d, /* data and also output buffer of at least 64 bytes */ int ld /* length of data in bytes */ ) { hmac_sha512_ctx hmac; sha512_ctx* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b; - char key[SHA512_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) + unsigned char key[SHA512_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; -#ifdef _WIN64 XSTATE_SAVE SaveState; if (IsCpuIntel() && HasSAVX()) saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); -#else - KFLOATING_SAVE floatingPointState; - if (HasSSSE3() && HasMMX()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif #endif /* If the key is longer than the hash algorithm block size, let key = sha512(key), as per HMAC specifications. */ if (lk > SHA512_BLOCKSIZE) { sha512_ctx tctx; sha512_begin (&tctx); - sha512_hash ((unsigned char *) k, lk, &tctx); - sha512_end ((unsigned char *) key, &tctx); + sha512_hash (k, lk, &tctx); + sha512_end (key, &tctx); k = key; lk = SHA512_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); sha512_begin (ctx); /* Pad the key for inner digest */ for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x36); + buf[b] = (unsigned char) (k[b] ^ 0x36); memset (&buf[lk], 0x36, SHA512_BLOCKSIZE - lk); - sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx); + sha512_hash (buf, SHA512_BLOCKSIZE, ctx); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); sha512_begin (ctx); for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x5C); + buf[b] = (unsigned char) (k[b] ^ 0x5C); memset (&buf[lk], 0x5C, SHA512_BLOCKSIZE - lk); - sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx); + sha512_hash (buf, SHA512_BLOCKSIZE, ctx); hmac_sha512_internal (d, ld, &hmac); -#if defined (DEVICE_DRIVER) +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) if (NT_SUCCESS (saveStatus)) -#ifdef _WIN64 KeRestoreExtendedProcessorStateVC(&SaveState); -#else - KeRestoreFloatingPointState (&floatingPointState); -#endif #endif /* Prevent leaks */ burn (&hmac, sizeof(hmac)); burn (key, sizeof(key)); } -static void derive_u_sha512 (char *salt, int salt_len, uint32 iterations, int b, hmac_sha512_ctx* hmac) +static void derive_u_sha512 (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_sha512_ctx* hmac) { - char* k = hmac->k; - char* u = hmac->u; + unsigned char* k = hmac->k; + unsigned char* u = hmac->u; uint32 c, i; /* iteration 1 */ memcpy (k, salt, salt_len); /* salt */ /* big-endian block number */ b = bswap_32 (b); memcpy (&k[salt_len], &b, 4); hmac_sha512_internal (k, salt_len + 4, hmac); memcpy (u, k, SHA512_DIGESTSIZE); /* remaining iterations */ for (c = 1; c < iterations; c++) { hmac_sha512_internal (k, SHA512_DIGESTSIZE, hmac); for (i = 0; i < SHA512_DIGESTSIZE; i++) { u[i] ^= k[i]; } } } -void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) +void derive_key_sha512 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) { hmac_sha512_ctx hmac; sha512_ctx* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b, l, r; - char key[SHA512_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) + unsigned char key[SHA512_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; -#ifdef _WIN64 XSTATE_SAVE SaveState; if (IsCpuIntel() && HasSAVX()) saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); -#else - KFLOATING_SAVE floatingPointState; - if (HasSSSE3() && HasMMX()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif #endif /* If the password is longer than the hash algorithm block size, let pwd = sha512(pwd), as per HMAC specifications. */ if (pwd_len > SHA512_BLOCKSIZE) { sha512_ctx tctx; sha512_begin (&tctx); - sha512_hash ((unsigned char *) pwd, pwd_len, &tctx); - sha512_end ((unsigned char *) key, &tctx); + sha512_hash (pwd, pwd_len, &tctx); + sha512_end (key, &tctx); pwd = key; pwd_len = SHA512_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } if (dklen % SHA512_DIGESTSIZE) { l = 1 + dklen / SHA512_DIGESTSIZE; } else { l = dklen / SHA512_DIGESTSIZE; } r = dklen - (l - 1) * SHA512_DIGESTSIZE; /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); sha512_begin (ctx); /* Pad the key for inner digest */ for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x36); + buf[b] = (unsigned char) (pwd[b] ^ 0x36); memset (&buf[pwd_len], 0x36, SHA512_BLOCKSIZE - pwd_len); - sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx); + sha512_hash (buf, SHA512_BLOCKSIZE, ctx); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); sha512_begin (ctx); for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x5C); + buf[b] = (unsigned char) (pwd[b] ^ 0x5C); memset (&buf[pwd_len], 0x5C, SHA512_BLOCKSIZE - pwd_len); - sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx); + sha512_hash (buf, SHA512_BLOCKSIZE, ctx); /* first l - 1 blocks */ for (b = 1; b < l; b++) { derive_u_sha512 (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, SHA512_DIGESTSIZE); dk += SHA512_DIGESTSIZE; } /* last block */ derive_u_sha512 (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); -#if defined (DEVICE_DRIVER) +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) if (NT_SUCCESS (saveStatus)) -#ifdef _WIN64 KeRestoreExtendedProcessorStateVC(&SaveState); -#else - KeRestoreFloatingPointState (&floatingPointState); -#endif #endif /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); burn (key, sizeof(key)); } #endif // TC_WINDOWS_BOOT #if !defined(TC_WINDOWS_BOOT) || defined(TC_WINDOWS_BOOT_BLAKE2S) typedef struct hmac_blake2s_ctx_struct { blake2s_state ctx; blake2s_state inner_digest_ctx; /*pre-computed inner digest context */ blake2s_state outer_digest_ctx; /*pre-computed outer digest context */ - char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Blake2s hash */ - char u[BLAKE2S_DIGESTSIZE]; + unsigned char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Blake2s hash */ + unsigned char u[BLAKE2S_DIGESTSIZE]; } hmac_blake2s_ctx; void hmac_blake2s_internal ( - char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ + unsigned char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ int ld, /* length of input data in bytes */ hmac_blake2s_ctx* hmac /* HMAC-BLAKE2S context which holds temporary variables */ ) { blake2s_state* ctx = &(hmac->ctx); /**** Restore Precomputed Inner Digest Context ****/ memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (blake2s_state)); blake2s_update (ctx, d, ld); - blake2s_final (ctx, (unsigned char*) d); /* d = inner digest */ + blake2s_final (ctx, d); /* d = inner digest */ /**** Restore Precomputed Outer Digest Context ****/ memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (blake2s_state)); blake2s_update (ctx, d, BLAKE2S_DIGESTSIZE); - blake2s_final (ctx, (unsigned char *) d); /* d = outer digest */ + blake2s_final (ctx, d); /* d = outer digest */ } #ifndef TC_WINDOWS_BOOT void hmac_blake2s ( - char *k, /* secret key */ + unsigned char *k, /* secret key */ int lk, /* length of the key in bytes */ - char *d, /* data */ + unsigned char *d, /* data */ int ld /* length of data in bytes */ ) { hmac_blake2s_ctx hmac; blake2s_state* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b; - char key[BLAKE2S_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) + unsigned char key[BLAKE2S_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; -#ifdef _WIN64 XSTATE_SAVE SaveState; if (IsCpuIntel() && HasSAVX()) saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); -#else - KFLOATING_SAVE floatingPointState; - if (HasSSE2()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif #endif /* If the key is longer than the hash algorithm block size, let key = blake2s(key), as per HMAC specifications. */ if (lk > BLAKE2S_BLOCKSIZE) { blake2s_state tctx; blake2s_init (&tctx); blake2s_update (&tctx, k, lk); - blake2s_final (&tctx, (unsigned char *) key); + blake2s_final (&tctx, key); k = key; lk = BLAKE2S_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); blake2s_init (ctx); /* Pad the key for inner digest */ for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x36); + buf[b] = (unsigned char) (k[b] ^ 0x36); memset (&buf[lk], 0x36, BLAKE2S_BLOCKSIZE - lk); - blake2s_update (ctx, (unsigned char *) buf, BLAKE2S_BLOCKSIZE); + blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); blake2s_init (ctx); for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x5C); + buf[b] = (unsigned char) (k[b] ^ 0x5C); memset (&buf[lk], 0x5C, BLAKE2S_BLOCKSIZE - lk); - blake2s_update (ctx, (unsigned char *) buf, BLAKE2S_BLOCKSIZE); + blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE); hmac_blake2s_internal(d, ld, &hmac); -#if defined (DEVICE_DRIVER) +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) if (NT_SUCCESS (saveStatus)) -#ifdef _WIN64 KeRestoreExtendedProcessorStateVC(&SaveState); -#else - KeRestoreFloatingPointState (&floatingPointState); -#endif #endif /* Prevent leaks */ burn(&hmac, sizeof(hmac)); burn(key, sizeof(key)); } #endif -static void derive_u_blake2s (char *salt, int salt_len, uint32 iterations, int b, hmac_blake2s_ctx* hmac) +static void derive_u_blake2s (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_blake2s_ctx* hmac) { - char* k = hmac->k; - char* u = hmac->u; + unsigned char* k = hmac->k; + unsigned char* u = hmac->u; uint32 c; int i; #ifdef TC_WINDOWS_BOOT /* In bootloader mode, least significant bit of iterations is a boolean (TRUE for boot derivation mode, FALSE otherwise) * and the most significant 16 bits hold the pim value * This enables us to save code space needed for implementing other features. */ c = iterations >> 16; i = ((int) iterations) & 0x01; if (i) c = (c == 0)? 200000 : c << 11; else c = (c == 0)? 500000 : 15000 + c * 1000; #else c = iterations; #endif /* iteration 1 */ memcpy (k, salt, salt_len); /* salt */ /* big-endian block number */ #ifdef TC_WINDOWS_BOOT /* specific case of 16-bit bootloader: b is a 16-bit integer that is always < 256 */ memset (&k[salt_len], 0, 3); - k[salt_len + 3] = (char) b; + k[salt_len + 3] = (unsigned char) b; #else b = bswap_32 (b); memcpy (&k[salt_len], &b, 4); #endif hmac_blake2s_internal (k, salt_len + 4, hmac); memcpy (u, k, BLAKE2S_DIGESTSIZE); /* remaining iterations */ while (c > 1) { hmac_blake2s_internal (k, BLAKE2S_DIGESTSIZE, hmac); for (i = 0; i < BLAKE2S_DIGESTSIZE; i++) { u[i] ^= k[i]; } c--; } } -void derive_key_blake2s (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) +void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) { hmac_blake2s_ctx hmac; blake2s_state* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b, l, r; #ifndef TC_WINDOWS_BOOT - char key[BLAKE2S_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) + unsigned char key[BLAKE2S_DIGESTSIZE]; +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; -#ifdef _WIN64 XSTATE_SAVE SaveState; if (IsCpuIntel() && HasSAVX()) saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); -#else KFLOATING_SAVE floatingPointState; if (HasSSE2()) saveStatus = KeSaveFloatingPointState (&floatingPointState); #endif -#endif /* If the password is longer than the hash algorithm block size, let pwd = blake2s(pwd), as per HMAC specifications. */ if (pwd_len > BLAKE2S_BLOCKSIZE) { blake2s_state tctx; blake2s_init (&tctx); blake2s_update (&tctx, pwd, pwd_len); - blake2s_final (&tctx, (unsigned char *) key); + blake2s_final (&tctx, key); pwd = key; pwd_len = BLAKE2S_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } #endif if (dklen % BLAKE2S_DIGESTSIZE) { l = 1 + dklen / BLAKE2S_DIGESTSIZE; } else { l = dklen / BLAKE2S_DIGESTSIZE; } r = dklen - (l - 1) * BLAKE2S_DIGESTSIZE; /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); blake2s_init (ctx); /* Pad the key for inner digest */ for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x36); + buf[b] = (unsigned char) (pwd[b] ^ 0x36); memset (&buf[pwd_len], 0x36, BLAKE2S_BLOCKSIZE - pwd_len); blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); blake2s_init (ctx); for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x5C); + buf[b] = (unsigned char) (pwd[b] ^ 0x5C); memset (&buf[pwd_len], 0x5C, BLAKE2S_BLOCKSIZE - pwd_len); blake2s_update (ctx, buf, BLAKE2S_BLOCKSIZE); /* first l - 1 blocks */ for (b = 1; b < l; b++) { derive_u_blake2s (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, BLAKE2S_DIGESTSIZE); dk += BLAKE2S_DIGESTSIZE; } /* last block */ derive_u_blake2s (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); -#if defined (DEVICE_DRIVER) +#if defined (DEVICE_DRIVER) && !defined(_M_ARM64) if (NT_SUCCESS (saveStatus)) -#ifdef _WIN64 KeRestoreExtendedProcessorStateVC(&SaveState); -#else - KeRestoreFloatingPointState (&floatingPointState); -#endif #endif /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); #ifndef TC_WINDOWS_BOOT burn (key, sizeof(key)); #endif } #endif #ifndef TC_WINDOWS_BOOT typedef struct hmac_whirlpool_ctx_struct { WHIRLPOOL_CTX ctx; WHIRLPOOL_CTX inner_digest_ctx; /*pre-computed inner digest context */ WHIRLPOOL_CTX outer_digest_ctx; /*pre-computed outer digest context */ - CRYPTOPP_ALIGN_DATA(16) char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Whirlpool hash */ - char u[WHIRLPOOL_DIGESTSIZE]; + CRYPTOPP_ALIGN_DATA(16) unsigned char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Whirlpool hash */ + unsigned char u[WHIRLPOOL_DIGESTSIZE]; } hmac_whirlpool_ctx; void hmac_whirlpool_internal ( - char *d, /* input/output data. d pointer is guaranteed to be at least 64-bytes long */ + unsigned char *d, /* input/output data. d pointer is guaranteed to be at least 64-bytes long */ int ld, /* length of input data in bytes */ hmac_whirlpool_ctx* hmac /* HMAC-Whirlpool context which holds temporary variables */ ) { WHIRLPOOL_CTX* ctx = &(hmac->ctx); /**** Restore Precomputed Inner Digest Context ****/ memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (WHIRLPOOL_CTX)); - WHIRLPOOL_add ((unsigned char *) d, ld, ctx); + WHIRLPOOL_add (d, ld, ctx); - WHIRLPOOL_finalize (ctx, (unsigned char *) d); + WHIRLPOOL_finalize (ctx, d); /**** Restore Precomputed Outer Digest Context ****/ memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (WHIRLPOOL_CTX)); - WHIRLPOOL_add ((unsigned char *) d, WHIRLPOOL_DIGESTSIZE, ctx); + WHIRLPOOL_add (d, WHIRLPOOL_DIGESTSIZE, ctx); - WHIRLPOOL_finalize (ctx, (unsigned char *) d); + WHIRLPOOL_finalize (ctx, d); } void hmac_whirlpool ( - char *k, /* secret key */ + unsigned char *k, /* secret key */ int lk, /* length of the key in bytes */ - char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ + unsigned char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ int ld /* length of data in bytes */ ) { hmac_whirlpool_ctx hmac; WHIRLPOOL_CTX* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b; - char key[WHIRLPOOL_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; - if (HasISSE()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif + unsigned char key[WHIRLPOOL_DIGESTSIZE]; /* If the key is longer than the hash algorithm block size, let key = whirlpool(key), as per HMAC specifications. */ if (lk > WHIRLPOOL_BLOCKSIZE) { WHIRLPOOL_CTX tctx; WHIRLPOOL_init (&tctx); - WHIRLPOOL_add ((unsigned char *) k, lk, &tctx); - WHIRLPOOL_finalize (&tctx, (unsigned char *) key); + WHIRLPOOL_add (k, lk, &tctx); + WHIRLPOOL_finalize (&tctx, key); k = key; lk = WHIRLPOOL_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); WHIRLPOOL_init (ctx); /* Pad the key for inner digest */ for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x36); + buf[b] = (unsigned char) (k[b] ^ 0x36); memset (&buf[lk], 0x36, WHIRLPOOL_BLOCKSIZE - lk); - WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx); + WHIRLPOOL_add (buf, WHIRLPOOL_BLOCKSIZE, ctx); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); WHIRLPOOL_init (ctx); for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x5C); + buf[b] = (unsigned char) (k[b] ^ 0x5C); memset (&buf[lk], 0x5C, WHIRLPOOL_BLOCKSIZE - lk); - WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx); + WHIRLPOOL_add (buf, WHIRLPOOL_BLOCKSIZE, ctx); hmac_whirlpool_internal(d, ld, &hmac); -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - if (NT_SUCCESS (saveStatus)) - KeRestoreFloatingPointState (&floatingPointState); -#endif /* Prevent leaks */ burn(&hmac, sizeof(hmac)); } -static void derive_u_whirlpool (char *salt, int salt_len, uint32 iterations, int b, hmac_whirlpool_ctx* hmac) +static void derive_u_whirlpool (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_whirlpool_ctx* hmac) { - char* u = hmac->u; - char* k = hmac->k; + unsigned char* u = hmac->u; + unsigned char* k = hmac->k; uint32 c, i; /* iteration 1 */ memcpy (k, salt, salt_len); /* salt */ /* big-endian block number */ b = bswap_32 (b); memcpy (&k[salt_len], &b, 4); hmac_whirlpool_internal (k, salt_len + 4, hmac); memcpy (u, k, WHIRLPOOL_DIGESTSIZE); /* remaining iterations */ for (c = 1; c < iterations; c++) { hmac_whirlpool_internal (k, WHIRLPOOL_DIGESTSIZE, hmac); for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++) { u[i] ^= k[i]; } } } -void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) +void derive_key_whirlpool (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) { hmac_whirlpool_ctx hmac; WHIRLPOOL_CTX* ctx; - char* buf = hmac.k; - char key[WHIRLPOOL_DIGESTSIZE]; + unsigned char* buf = hmac.k; + unsigned char key[WHIRLPOOL_DIGESTSIZE]; int b, l, r; -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; - if (HasISSE()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif /* If the password is longer than the hash algorithm block size, let pwd = whirlpool(pwd), as per HMAC specifications. */ if (pwd_len > WHIRLPOOL_BLOCKSIZE) { WHIRLPOOL_CTX tctx; WHIRLPOOL_init (&tctx); - WHIRLPOOL_add ((unsigned char *) pwd, pwd_len, &tctx); - WHIRLPOOL_finalize (&tctx, (unsigned char *) key); + WHIRLPOOL_add (pwd, pwd_len, &tctx); + WHIRLPOOL_finalize (&tctx, key); pwd = key; pwd_len = WHIRLPOOL_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } if (dklen % WHIRLPOOL_DIGESTSIZE) { l = 1 + dklen / WHIRLPOOL_DIGESTSIZE; } else { l = dklen / WHIRLPOOL_DIGESTSIZE; } r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE; /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); WHIRLPOOL_init (ctx); /* Pad the key for inner digest */ for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x36); + buf[b] = (unsigned char) (pwd[b] ^ 0x36); memset (&buf[pwd_len], 0x36, WHIRLPOOL_BLOCKSIZE - pwd_len); - WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx); + WHIRLPOOL_add (buf, WHIRLPOOL_BLOCKSIZE, ctx); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); WHIRLPOOL_init (ctx); for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x5C); + buf[b] = (unsigned char) (pwd[b] ^ 0x5C); memset (&buf[pwd_len], 0x5C, WHIRLPOOL_BLOCKSIZE - pwd_len); - WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE, ctx); + WHIRLPOOL_add (buf, WHIRLPOOL_BLOCKSIZE, ctx); /* first l - 1 blocks */ for (b = 1; b < l; b++) { derive_u_whirlpool (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, WHIRLPOOL_DIGESTSIZE); dk += WHIRLPOOL_DIGESTSIZE; } /* last block */ derive_u_whirlpool (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - if (NT_SUCCESS (saveStatus)) - KeRestoreFloatingPointState (&floatingPointState); -#endif - /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); burn (key, sizeof(key)); } typedef struct hmac_streebog_ctx_struct { STREEBOG_CTX ctx; STREEBOG_CTX inner_digest_ctx; /*pre-computed inner digest context */ STREEBOG_CTX outer_digest_ctx; /*pre-computed outer digest context */ - CRYPTOPP_ALIGN_DATA(16) char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Streebog hash */ - char u[STREEBOG_DIGESTSIZE]; + CRYPTOPP_ALIGN_DATA(16) unsigned char k[PKCS5_SALT_SIZE + 4]; /* enough to hold (salt_len + 4) and also the Streebog hash */ + unsigned char u[STREEBOG_DIGESTSIZE]; } hmac_streebog_ctx; void hmac_streebog_internal ( - char *d, /* input/output data. d pointer is guaranteed to be at least 64-bytes long */ + unsigned char *d, /* input/output data. d pointer is guaranteed to be at least 64-bytes long */ int ld, /* length of input data in bytes */ hmac_streebog_ctx* hmac /* HMAC-Whirlpool context which holds temporary variables */ ) { STREEBOG_CTX* ctx = &(hmac->ctx); /**** Restore Precomputed Inner Digest Context ****/ memcpy (ctx, &(hmac->inner_digest_ctx), sizeof (STREEBOG_CTX)); - STREEBOG_add (ctx, (unsigned char *) d, ld); + STREEBOG_add (ctx, d, ld); - STREEBOG_finalize (ctx, (unsigned char *) d); + STREEBOG_finalize (ctx, d); /**** Restore Precomputed Outer Digest Context ****/ memcpy (ctx, &(hmac->outer_digest_ctx), sizeof (STREEBOG_CTX)); - STREEBOG_add (ctx, (unsigned char *) d, STREEBOG_DIGESTSIZE); + STREEBOG_add (ctx, d, STREEBOG_DIGESTSIZE); - STREEBOG_finalize (ctx, (unsigned char *) d); + STREEBOG_finalize (ctx, d); } void hmac_streebog ( - char *k, /* secret key */ + unsigned char *k, /* secret key */ int lk, /* length of the key in bytes */ - char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ + unsigned char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ int ld /* length of data in bytes */ ) { hmac_streebog_ctx hmac; STREEBOG_CTX* ctx; - char* buf = hmac.k; + unsigned char* buf = hmac.k; int b; - CRYPTOPP_ALIGN_DATA(16) char key[STREEBOG_DIGESTSIZE]; -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; - if (HasSSE2() || HasSSE41()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif + CRYPTOPP_ALIGN_DATA(16) unsigned char key[STREEBOG_DIGESTSIZE]; /* If the key is longer than the hash algorithm block size, let key = streebog(key), as per HMAC specifications. */ if (lk > STREEBOG_BLOCKSIZE) { STREEBOG_CTX tctx; STREEBOG_init (&tctx); - STREEBOG_add (&tctx, (unsigned char *) k, lk); - STREEBOG_finalize (&tctx, (unsigned char *) key); + STREEBOG_add (&tctx, k, lk); + STREEBOG_finalize (&tctx, key); k = key; lk = STREEBOG_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); STREEBOG_init (ctx); /* Pad the key for inner digest */ for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x36); + buf[b] = (unsigned char) (k[b] ^ 0x36); memset (&buf[lk], 0x36, STREEBOG_BLOCKSIZE - lk); - STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE); + STREEBOG_add (ctx, buf, STREEBOG_BLOCKSIZE); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); STREEBOG_init (ctx); for (b = 0; b < lk; ++b) - buf[b] = (char) (k[b] ^ 0x5C); + buf[b] = (unsigned char) (k[b] ^ 0x5C); memset (&buf[lk], 0x5C, STREEBOG_BLOCKSIZE - lk); - STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE); + STREEBOG_add (ctx, buf, STREEBOG_BLOCKSIZE); hmac_streebog_internal(d, ld, &hmac); -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - if (NT_SUCCESS (saveStatus)) - KeRestoreFloatingPointState (&floatingPointState); -#endif /* Prevent leaks */ burn(&hmac, sizeof(hmac)); } -static void derive_u_streebog (char *salt, int salt_len, uint32 iterations, int b, hmac_streebog_ctx* hmac) +static void derive_u_streebog (const unsigned char *salt, int salt_len, uint32 iterations, int b, hmac_streebog_ctx* hmac) { - char* u = hmac->u; - char* k = hmac->k; + unsigned char* u = hmac->u; + unsigned char* k = hmac->k; uint32 c, i; /* iteration 1 */ memcpy (k, salt, salt_len); /* salt */ /* big-endian block number */ b = bswap_32 (b); memcpy (&k[salt_len], &b, 4); hmac_streebog_internal (k, salt_len + 4, hmac); memcpy (u, k, STREEBOG_DIGESTSIZE); /* remaining iterations */ for (c = 1; c < iterations; c++) { hmac_streebog_internal (k, STREEBOG_DIGESTSIZE, hmac); for (i = 0; i < STREEBOG_DIGESTSIZE; i++) { u[i] ^= k[i]; } } } -void derive_key_streebog (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) +void derive_key_streebog (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) { hmac_streebog_ctx hmac; STREEBOG_CTX* ctx; - char* buf = hmac.k; - char key[STREEBOG_DIGESTSIZE]; + unsigned char* buf = hmac.k; + unsigned char key[STREEBOG_DIGESTSIZE]; int b, l, r; -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; - if (HasSSE2() || HasSSE41()) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif /* If the password is longer than the hash algorithm block size, let pwd = streebog(pwd), as per HMAC specifications. */ if (pwd_len > STREEBOG_BLOCKSIZE) { STREEBOG_CTX tctx; STREEBOG_init (&tctx); - STREEBOG_add (&tctx, (unsigned char *) pwd, pwd_len); - STREEBOG_finalize (&tctx, (unsigned char *) key); + STREEBOG_add (&tctx, pwd, pwd_len); + STREEBOG_finalize (&tctx, key); pwd = key; pwd_len = STREEBOG_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } if (dklen % STREEBOG_DIGESTSIZE) { l = 1 + dklen / STREEBOG_DIGESTSIZE; } else { l = dklen / STREEBOG_DIGESTSIZE; } r = dklen - (l - 1) * STREEBOG_DIGESTSIZE; /**** Precompute HMAC Inner Digest ****/ ctx = &(hmac.inner_digest_ctx); STREEBOG_init (ctx); /* Pad the key for inner digest */ for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x36); + buf[b] = (unsigned char) (pwd[b] ^ 0x36); memset (&buf[pwd_len], 0x36, STREEBOG_BLOCKSIZE - pwd_len); - STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE); + STREEBOG_add (ctx, buf, STREEBOG_BLOCKSIZE); /**** Precompute HMAC Outer Digest ****/ ctx = &(hmac.outer_digest_ctx); STREEBOG_init (ctx); for (b = 0; b < pwd_len; ++b) - buf[b] = (char) (pwd[b] ^ 0x5C); + buf[b] = (unsigned char) (pwd[b] ^ 0x5C); memset (&buf[pwd_len], 0x5C, STREEBOG_BLOCKSIZE - pwd_len); - STREEBOG_add (ctx, (unsigned char *) buf, STREEBOG_BLOCKSIZE); + STREEBOG_add (ctx, buf, STREEBOG_BLOCKSIZE); /* first l - 1 blocks */ for (b = 1; b < l; b++) { derive_u_streebog (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, STREEBOG_DIGESTSIZE); dk += STREEBOG_DIGESTSIZE; } /* last block */ derive_u_streebog (salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - if (NT_SUCCESS (saveStatus)) - KeRestoreFloatingPointState (&floatingPointState); -#endif - /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); burn (key, sizeof(key)); } wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id) { switch (pkcs5_prf_id) { case SHA512: return L"HMAC-SHA-512"; case SHA256: return L"HMAC-SHA-256"; case BLAKE2S: return L"HMAC-BLAKE2s-256"; case WHIRLPOOL: return L"HMAC-Whirlpool"; case STREEBOG: return L"HMAC-STREEBOG"; default: return L"(Unknown)"; } } diff --git a/src/Common/Pkcs5.h b/src/Common/Pkcs5.h index a9abeec5..65fad038 100644 --- a/src/Common/Pkcs5.h +++ b/src/Common/Pkcs5.h @@ -1,61 +1,61 @@ /* Legal Notice: Some portions of the source code contained in this file were derived from the source code of TrueCrypt 7.1a, which is Copyright (c) 2003-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #ifndef TC_HEADER_PKCS5 #define TC_HEADER_PKCS5 #include "Tcdefs.h" #if defined(__cplusplus) extern "C" { #endif /* output written to input_digest which must be at lease 32 bytes long */ -void hmac_blake2s (char *key, int keylen, char *input_digest, int len); -void derive_key_blake2s (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen); +void hmac_blake2s (unsigned char *key, int keylen, unsigned char *input_digest, int len); +void derive_key_blake2s (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); /* output written to d which must be at lease 32 bytes long */ -void hmac_sha256 (char *k, int lk, char *d, int ld); -void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen); +void hmac_sha256 (unsigned char *k, int lk, unsigned char *d, int ld); +void derive_key_sha256 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); #ifndef TC_WINDOWS_BOOT /* output written to d which must be at lease 64 bytes long */ -void hmac_sha512 (char *k, int lk, char *d, int ld); -void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen); +void hmac_sha512 (unsigned char *k, int lk, unsigned char *d, int ld); +void derive_key_sha512 (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); /* output written to d which must be at lease 64 bytes long */ -void hmac_whirlpool (char *k, int lk, char *d, int ld); -void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen); +void hmac_whirlpool (unsigned char *k, int lk, unsigned char *d, int ld); +void derive_key_whirlpool (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); -void hmac_streebog (char *k, int32 lk, char *d, int32 ld); -void derive_key_streebog (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen); +void hmac_streebog (unsigned char *k, int lk, unsigned char *d, int ld); +void derive_key_streebog (const unsigned char *pwd, int pwd_len, const unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen); int get_pkcs5_iteration_count (int pkcs5_prf_id, int pim, BOOL bBoot); wchar_t *get_pkcs5_prf_name (int pkcs5_prf_id); /* check if given PRF supported.*/ typedef enum { PRF_BOOT_NO = 0, PRF_BOOT_MBR, PRF_BOOT_GPT } PRF_BOOT_TYPE; int is_pkcs5_prf_supported (int pkcs5_prf_id, PRF_BOOT_TYPE bootType); #endif #if defined(__cplusplus) } #endif #endif // TC_HEADER_PKCS5 diff --git a/src/Common/Random.c b/src/Common/Random.c index ee3fcf53..0be4d601 100644 --- a/src/Common/Random.c +++ b/src/Common/Random.c @@ -1,51 +1,52 @@ /* Legal Notice: Some portions of the source code contained in this file were derived from the source code of TrueCrypt 7.1a, which is Copyright (c) 2003-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "Tcdefs.h" #include "Crc.h" #include "Random.h" #include "Dlgcode.h" #include "Crypto\cpu.h" #include "Crypto\jitterentropy.h" #include "Crypto\rdrand.h" #include <Strsafe.h> +#include <bcrypt.h> static unsigned __int8 buffer[RNG_POOL_SIZE]; static unsigned char *pRandPool = NULL; static BOOL bRandDidInit = FALSE; static int nRandIndex = 0, randPoolReadIndex = 0; static int HashFunction = DEFAULT_HASH_ALGORITHM; static BOOL bDidSlowPoll = FALSE; BOOL volatile bFastPollEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */ BOOL volatile bRandmixEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */ static BOOL RandomPoolEnrichedByUser = FALSE; static HANDLE PeriodicFastPollThreadHandle = NULL; /* Macro to add a single byte to the pool */ #define RandaddByte(x) {\ if (nRandIndex == RNG_POOL_SIZE) nRandIndex = 0;\ pRandPool[nRandIndex] = (unsigned char) ((unsigned char)x + pRandPool[nRandIndex]); \ if (nRandIndex % RANDMIX_BYTE_INTERVAL == 0) Randmix();\ nRandIndex++; \ } /* Macro to add four bytes to the pool */ #define RandaddInt32(x) RandAddInt((unsigned __int32)x); #ifdef _WIN64 #define RandaddIntPtr(x) RandAddInt64((unsigned __int64)x); #else #define RandaddIntPtr(x) RandAddInt((unsigned __int32)x); #endif void RandAddInt (unsigned __int32 x) @@ -62,176 +63,171 @@ void RandAddInt64 (unsigned __int64 x) RandaddByte((x >> 8)); RandaddByte((x >> 16)); RandaddByte((x >> 24)); RandaddByte((x >> 32)); RandaddByte((x >> 40)); RandaddByte((x >> 48)); RandaddByte((x >> 56)); } #include <tlhelp32.h> #include "Dlgcode.h" #ifndef SRC_POS #define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__)) #endif HHOOK hMouse = NULL; /* Mouse hook for the random number generator */ HHOOK hKeyboard = NULL; /* Keyboard hook for the random number generator */ DWORD ProcessedMouseEventsCounter = 0; /* Variables for thread control, the thread is used to gather up info about the system in in the background */ CRITICAL_SECTION critRandProt; /* The critical section */ BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among thread's so its made volatile */ /* Network library handle for the SlowPoll function */ HANDLE hNetAPI32 = NULL; // CryptoAPI -BOOL CryptoAPIAvailable = FALSE; DWORD CryptoAPILastError = ERROR_SUCCESS; -HCRYPTPROV hCryptProv; +typedef DWORD (WINAPI *RtlNtStatusToDosError_t)(NTSTATUS); +RtlNtStatusToDosError_t pRtlNtStatusToDosError = NULL; /* Init the random number generator, setup the hooks, and start the thread */ int RandinitWithCheck ( int* pAlreadyInitialized) { BOOL bIgnoreHookError = FALSE; DWORD dwLastError = ERROR_SUCCESS; + HMODULE ntdll; if (GetMaxPkcs5OutSize() > RNG_POOL_SIZE) TC_THROW_FATAL_EXCEPTION; if(bRandDidInit) { if (pAlreadyInitialized) *pAlreadyInitialized = 1; return 0; } if (pAlreadyInitialized) *pAlreadyInitialized = 0; InitializeCriticalSection (&critRandProt); bRandDidInit = TRUE; CryptoAPILastError = ERROR_SUCCESS; ProcessedMouseEventsCounter = 0; if (pRandPool == NULL) { pRandPool = (unsigned char *) _aligned_malloc (RANDOMPOOL_ALLOCSIZE, 16); if (pRandPool == NULL) goto error; bDidSlowPoll = FALSE; RandomPoolEnrichedByUser = FALSE; memset (pRandPool, 0, RANDOMPOOL_ALLOCSIZE); VirtualLock (pRandPool, RANDOMPOOL_ALLOCSIZE); } bIgnoreHookError = IsThreadInSecureDesktop(GetCurrentThreadId()); hKeyboard = SetWindowsHookEx (WH_KEYBOARD, (HOOKPROC)&KeyboardProc, NULL, GetCurrentThreadId ()); if (hKeyboard == 0 && !bIgnoreHookError) handleWin32Error (0, SRC_POS); hMouse = SetWindowsHookEx (WH_MOUSE, (HOOKPROC)&MouseProc, NULL, GetCurrentThreadId ()); if (hMouse == 0 && !bIgnoreHookError) { handleWin32Error (0, SRC_POS); goto error; } - if (!CryptAcquireContext (&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - { - CryptoAPIAvailable = FALSE; - CryptoAPILastError = GetLastError (); + ntdll = GetModuleHandleW(L"ntdll.dll"); + if (!ntdll) { + // If ntdll.dll is not found, return a fallback error code + CryptoAPILastError = ERROR_MOD_NOT_FOUND; goto error; } else - CryptoAPIAvailable = TRUE; + pRtlNtStatusToDosError = (RtlNtStatusToDosError_t)GetProcAddress(ntdll, "RtlNtStatusToDosError"); if (!(PeriodicFastPollThreadHandle = (HANDLE) _beginthreadex (NULL, 0, PeriodicFastPollThreadProc, NULL, 0, NULL))) goto error; return 0; error: dwLastError = GetLastError(); RandStop (TRUE); SetLastError (dwLastError); return 1; } int Randinit () { return RandinitWithCheck (NULL); } /* Close everything down, including the thread which is closed down by setting a flag which eventually causes the thread function to exit */ void RandStop (BOOL freePool) { if (!bRandDidInit && freePool && pRandPool) goto freePool; if (bRandDidInit == FALSE) return; EnterCriticalSection (&critRandProt); if (hMouse != 0) UnhookWindowsHookEx (hMouse); if (hKeyboard != 0) UnhookWindowsHookEx (hKeyboard); bThreadTerminate = TRUE; LeaveCriticalSection (&critRandProt); if (PeriodicFastPollThreadHandle) WaitForSingleObject (PeriodicFastPollThreadHandle, INFINITE); if (hNetAPI32 != 0) { FreeLibrary (hNetAPI32); hNetAPI32 = NULL; } - if (CryptoAPIAvailable) - { - CryptReleaseContext (hCryptProv, 0); - CryptoAPIAvailable = FALSE; - CryptoAPILastError = ERROR_SUCCESS; - } hMouse = NULL; hKeyboard = NULL; bThreadTerminate = FALSE; DeleteCriticalSection (&critRandProt); bRandDidInit = FALSE; freePool: if (freePool) { bDidSlowPoll = FALSE; RandomPoolEnrichedByUser = FALSE; if (pRandPool != NULL) { burn (pRandPool, RANDOMPOOL_ALLOCSIZE); _aligned_free (pRandPool); pRandPool = NULL; } } } BOOL IsRandomNumberGeneratorStarted () { return bRandDidInit; } void RandSetHashFunction (int hash_algo_id) { @@ -648,60 +644,61 @@ static unsigned __stdcall PeriodicFastPollThreadProc (void *dummy) } } /* Type definitions for function pointers to call NetAPI32 functions */ typedef DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService, DWORD dwLevel, DWORD dwOptions, LPBYTE * lpBuffer); typedef DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer); typedef DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer); NETSTATISTICSGET pNetStatisticsGet = NULL; NETAPIBUFFERSIZE pNetApiBufferSize = NULL; NETAPIBUFFERFREE pNetApiBufferFree = NULL; /* This is the slowpoll function which gathers up network/hard drive performance data for the random pool */ BOOL SlowPoll (void) { static int isWorkstation = -1; static int cbPerfData = 0x10000; HANDLE hDevice; LPBYTE lpBuffer; DWORD dwSize, status; LPWSTR lpszLanW, lpszLanS; int nDrive; + NTSTATUS bStatus = 0; /* Find out whether this is an NT server or workstation if necessary */ if (isWorkstation == -1) { HKEY hKey; if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { wchar_t szValue[32]; dwSize = sizeof (szValue); isWorkstation = TRUE; status = RegQueryValueEx (hKey, L"ProductType", 0, NULL, (LPBYTE) szValue, &dwSize); if (status == ERROR_SUCCESS && _wcsicmp (szValue, L"WinNT")) /* Note: There are (at least) three cases for ProductType: WinNT = NT Workstation, ServerNT = NT Server, LanmanNT = NT Server acting as a Domain Controller */ isWorkstation = FALSE; RegCloseKey (hKey); } } /* Initialize the NetAPI32 function pointers if necessary */ if (hNetAPI32 == NULL) { @@ -756,115 +753,114 @@ BOOL SlowPoll (void) RandaddBuf ((unsigned char *) lpBuffer, dwSize); pNetApiBufferFree (lpBuffer); } /* Get disk I/O statistics for all the hard drives */ for (nDrive = 0;; nDrive++) { DISK_PERFORMANCE diskPerformance; wchar_t szDevice[24]; /* Check whether we can access this device */ StringCchPrintfW (szDevice, ARRAYSIZE(szDevice), L"\\\\.\\PhysicalDrive%d", nDrive); hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice == INVALID_HANDLE_VALUE) break; /* Note: This only works if you have turned on the disk performance counters with 'diskperf -y'. These counters are off by default */ if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, sizeof (DISK_PERFORMANCE), &dwSize, NULL)) { RandaddBuf ((unsigned char *) &diskPerformance, dwSize); } CloseHandle (hDevice); } - // 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)) + + bStatus = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (NT_SUCCESS(bStatus)) { RandaddBuf (buffer, sizeof (buffer)); } else { - /* return error in case CryptGenRandom fails */ - CryptoAPILastError = GetLastError (); + /* return error in case BCryptGenRandom fails */ + CryptoAPILastError = pRtlNtStatusToDosError (bStatus); return FALSE; } /* use JitterEntropy library to get good quality random bytes based on CPU timing jitter */ if (0 == jent_entropy_init ()) { struct rand_data *ec = jent_entropy_collector_alloc (1, 0); if (ec) { ssize_t rndLen = jent_read_entropy (ec, (char*) buffer, sizeof (buffer)); if (rndLen > 0) RandaddBuf (buffer, (int) rndLen); jent_entropy_collector_free (ec); } } // use RDSEED or RDRAND from CPU as source of entropy if present if ( IsCpuRngEnabled() && ( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer))) || (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer))) )) { RandaddBuf (buffer, sizeof (buffer)); } burn(buffer, sizeof (buffer)); Randmix(); return TRUE; } /* This is the fastpoll function which gathers up info by calling various api's */ BOOL FastPoll (void) { int nOriginalRandIndex = nRandIndex; static BOOL addedFixedItems = FALSE; FILETIME creationTime, exitTime, kernelTime, userTime; SIZE_T minimumWorkingSetSize, maximumWorkingSetSize; LARGE_INTEGER performanceCount; MEMORYSTATUSEX memoryStatus; HANDLE handle; POINT point; + NTSTATUS bStatus = 0; /* Get various basic pieces of system information */ RandaddIntPtr (GetActiveWindow ()); /* Handle of active window */ RandaddIntPtr (GetCapture ()); /* Handle of window with mouse capture */ RandaddIntPtr (GetClipboardOwner ()); /* Handle of clipboard owner */ RandaddIntPtr (GetClipboardViewer ()); /* Handle of start of clpbd.viewer list */ RandaddIntPtr (GetCurrentProcess ()); /* Pseudohandle of current process */ RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */ RandaddIntPtr (GetCurrentThread ()); /* Pseudohandle of current thread */ RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */ RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows started */ RandaddIntPtr (GetDesktopWindow ()); /* Handle of desktop window */ RandaddIntPtr (GetFocus ()); /* Handle of window with kb.focus */ RandaddInt32 (GetInputState ()); /* Whether sys.queue has any events */ RandaddInt32 (GetMessagePos ()); /* Cursor pos.for last message */ RandaddInt32 (GetMessageTime ()); /* 1 ms time for last message */ RandaddIntPtr (GetOpenClipboardWindow ()); /* Handle of window with clpbd.open */ RandaddIntPtr (GetProcessHeap ()); /* Handle of process heap */ RandaddIntPtr (GetProcessWindowStation ()); /* Handle of procs window station */ RandaddInt32 (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in input queue */ /* Get multiword system information */ @@ -901,70 +897,68 @@ BOOL FastPoll (void) &maximumWorkingSetSize); RandaddIntPtr (minimumWorkingSetSize); RandaddIntPtr (maximumWorkingSetSize); /* The following are fixed for the lifetime of the process so we only add them once */ if (addedFixedItems == 0) { STARTUPINFO startupInfo; /* Get name of desktop, console window title, new window position and size, window flags, and handles for stdin, stdout, and stderr */ startupInfo.cb = sizeof (STARTUPINFO); GetStartupInfo (&startupInfo); RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO)); addedFixedItems = TRUE; } /* The docs say QPC can fail if appropriate hardware is not available. It works on 486 & Pentium boxes, but hasn't been tested for 386 or RISC boxes */ if (QueryPerformanceCounter (&performanceCount)) RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER)); else { /* Millisecond accuracy at best... */ DWORD dwTicks = GetTickCount (); RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks)); } - // 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)) + + bStatus = BCryptGenRandom(NULL, buffer, sizeof(buffer), BCRYPT_USE_SYSTEM_PREFERRED_RNG); + if (NT_SUCCESS(bStatus)) { RandaddBuf (buffer, sizeof (buffer)); } else { - /* return error in case CryptGenRandom fails */ - CryptoAPILastError = GetLastError (); + /* return error in case BCryptGenRandom fails */ + CryptoAPILastError = pRtlNtStatusToDosError (bStatus); return FALSE; } // use RDSEED or RDRAND from CPU as source of entropy if enabled if ( IsCpuRngEnabled() && ( (HasRDSEED() && RDSEED_getBytes (buffer, sizeof (buffer))) || (HasRDRAND() && RDRAND_getBytes (buffer, sizeof (buffer))) )) { RandaddBuf (buffer, sizeof (buffer)); } burn (buffer, sizeof(buffer)); /* Apply the pool mixing function */ Randmix(); /* Restore the original pool cursor position. If this wasn't done, mouse coordinates could be written to a limited area of the pool, especially when moving the mouse uninterruptedly. The severity of the problem would depend on the length of data written by FastPoll (if it was equal to the size of the pool, mouse coordinates would be written only to a particular 4-byte area, whenever moving the mouse uninterruptedly). */ nRandIndex = nOriginalRandIndex; return TRUE; } diff --git a/src/Common/Tcdefs.h b/src/Common/Tcdefs.h index 3fd18358..f88ff582 100644 --- a/src/Common/Tcdefs.h +++ b/src/Common/Tcdefs.h @@ -228,74 +228,64 @@ typedef int LONG; # ifdef __cplusplus extern "C" # endif void ThrowFatalException (int line); # define TC_THROW_FATAL_EXCEPTION ThrowFatalException (__LINE__) #elif defined (TC_WINDOWS_DRIVER) # define TC_THROW_FATAL_EXCEPTION KeBugCheckEx (SECURITY_SYSTEM, __LINE__, 0, 0, 'VC') #elif defined(_UEFI) void ThrowFatalException(int line); # define TC_THROW_FATAL_EXCEPTION ThrowFatalException (__LINE__) #elif (defined(__clang__) && __has_builtin(__builtin_trap)) \ || (defined(__GNUC__ ) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))) \ || (__has_builtin(__builtin_trap)) # define TC_THROW_FATAL_EXCEPTION __builtin_trap() #else # define TC_THROW_FATAL_EXCEPTION *(char *) 0 = 0 #endif #ifdef __COVERITY__ #undef TC_THROW_FATAL_EXCEPTION #define TC_THROW_FATAL_EXCEPTION __coverity_panic__() #endif #ifdef TC_WINDOWS_DRIVER #include <ntifs.h> #include <ntddk.h> /* Standard header file for nt drivers */ #include <ntdddisk.h> /* Standard I/O control codes */ -/* defines needed for using enhanced protection of NX pool under Windows 8 and later */ -#define NonPagedPoolNx 512 -#define MdlMappingNoExecute 0x40000000 - -/* variables used in the implementation of enhanced protection of NX pool under Windows 8 and later */ -extern POOL_TYPE ExDefaultNonPagedPoolType; -extern ULONG ExDefaultMdlProtection; -#ifdef _WIN64 + extern ULONG AllocTag; -#else -#define AllocTag 'MMCV' -#endif -#define TCalloc(size) ((void *) ExAllocatePoolWithTag( ExDefaultNonPagedPoolType, size, AllocTag )) +#define TCalloc(size) ((void *) ExAllocatePool2( POOL_FLAG_NON_PAGED, size, AllocTag )) #define TCfree(memblock) ExFreePoolWithTag( memblock, AllocTag ) #define DEVICE_DRIVER #ifndef BOOL typedef int BOOL; #endif #ifndef WORD typedef USHORT WORD; #endif #ifndef BOOLEAN typedef unsigned char BOOLEAN; #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE !TRUE #endif typedef NTSTATUS (NTAPI *KeSaveExtendedProcessorStateFn) ( __in ULONG64 Mask, PXSTATE_SAVE XStateSave ); diff --git a/src/Common/Tests.c b/src/Common/Tests.c index 530e7577..8f851f62 100644 --- a/src/Common/Tests.c +++ b/src/Common/Tests.c @@ -540,145 +540,134 @@ typedef struct _HashTestVector const char* hexOutput; } HashTestVector; typedef int (__cdecl HashFunction) (unsigned char* input, unsigned long inputLen, unsigned char* output); unsigned char HexCharToByte (char c) { if (c >= ('0') && c <= ('9')) return c - ('0'); else if (c >= ('A') && c <= ('F')) return c - ('A') + 10; else if (c >= ('a') && c <= ('f')) return c - ('a') + 10; else return 0xFF; } unsigned long HexStringToByteArray(const char* hexStr, unsigned char* pbData) { unsigned long count = 0; while (*hexStr) { *pbData++ = (HexCharToByte(hexStr[0]) << 4) | HexCharToByte(hexStr[1]); hexStr += 2; count++; } return count; } -BOOL RunHashTest (HashFunction fn, HashTestVector* vector, BOOL bUseSSE) +BOOL RunHashTest (HashFunction fn, HashTestVector* vector) { CRYPTOPP_ALIGN_DATA (16) unsigned char input[256]; unsigned char output[64]; unsigned char digest[64]; unsigned long i = 0, inputLen, outputLen, digestLen; BOOL bRet = TRUE; -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - KFLOATING_SAVE floatingPointState; - NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; - if (bUseSSE) - saveStatus = KeSaveFloatingPointState (&floatingPointState); -#endif while (vector[i].hexInput && vector[i].hexOutput) { inputLen = HexStringToByteArray (vector[i].hexInput, input); outputLen = HexStringToByteArray (vector[i].hexOutput, output); digestLen = fn (input, inputLen, digest); if ((digestLen != outputLen) || (0 != memcmp (digest, output, digestLen))) { bRet = FALSE; break; } i++; } -#if defined (DEVICE_DRIVER) && !defined (_WIN64) - if (NT_SUCCESS (saveStatus)) - KeRestoreFloatingPointState (&floatingPointState); -#endif - return bRet; } /* https://www.streebog.net/src/trunk/examples/ */ HashTestVector Streebog512TestVectors[] = { /* M1 */ {"303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132", "1b54d01a4af5b9d5cc3d86d68d285462b19abc2475222f35c085122be4ba1ffa00ad30f8767b3a82384c6574f024c311e2a481332b08ef7f41797891c1646f48" }, /* M2 */ {"d1e520e2e5f2f0e82c20d1f2f0e8e1eee6e820e2edf3f6e82c20e2e5fef2fa20f120eceef0ff20f1f2f0e5ebe0ece820ede020f5f0e0e1f0fbff20efebfaeafb20c8e3eef0e5e2fb", "1e88e62226bfca6f9994f1f2d51569e0daf8475a3b0fe61a5300eee46d961376035fe83549ada2b8620fcd7c496ce5b33f0cb9dddc2b6460143b03dabac9fb28" }, /* M3 */ {"", "8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a" }, /* M4 */ {"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "b0fd29ac1b0df441769ff3fdb8dc564df67721d6ac06fb28ceffb7bbaa7948c6c014ac999235b58cb26fb60fb112a145d7b4ade9ae566bf2611402c552d20db7" }, {NULL, NULL} }; /* https://github.com/openssl/openssl/blob/2d0b44126763f989a4cbffbffe9d0c7518158bb7/test/evptests.txt */ HashTestVector Blake2sTestVectors[] = { {"", "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9" }, {"61", "4a0d129873403037c2cd9b9048203687f6233fb6738956e0349bd4320fec3e90" }, {"616263", "508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982" }, {"6d65737361676520646967657374", "fa10ab775acf89b7d3c8a6e823d586f6b67bdbac4ce207fe145b7d3ac25cd28c" }, {"6162636465666768696a6b6c6d6e6f707172737475767778797a", "bdf88eb1f86a0cdf0e840ba88fa118508369df186c7355b4b16cf79fa2710a12" }, {"4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839", "c75439ea17e1de6fa4510c335dc3d3f343e6f9e1ce2773e25b4174f1df8b119b" }, {"3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930", "fdaedb290a0d5af9870864fec2e090200989dc9cd53a3c092129e8535e8b4f66" }, {NULL, NULL} }; unsigned char ks_tmp[MAX_EXPANDED_KEY]; -void CipherInit2(int cipher, void* key, void* ks, int key_len) +void CipherInit2(int cipher, void* key, void* ks) { switch (cipher) { case AES: CipherInit(cipher,key,ks); break; case SERPENT: CipherInit(cipher,key,ks); break; case TWOFISH: CipherInit(cipher,key,ks); break; case CAMELLIA: CipherInit(cipher,key,ks); break; case KUZNYECHIK: CipherInit(cipher, key, ks); break; default: /* Unknown/wrong ID */ TC_THROW_FATAL_EXCEPTION; } } BOOL TestSectorBufEncryption (PCRYPTO_INFO ci) @@ -1280,96 +1269,95 @@ BOOL TestSectorBufEncryption (PCRYPTO_INFO ci) } else if (wcscmp (name, L"Kuznyechik-AES") == 0) { if (crc != 0x4641234a) return FALSE; nTestsPerformed++; } else if (wcscmp (name, L"Kuznyechik-Serpent-Camellia") == 0) { if (crc != 0x755dad72) return FALSE; nTestsPerformed++; } #endif if (crc == 0x9f5edd58) return FALSE; DecryptBuffer (buf, sizeof (buf), ci); if (GetCrc32 (buf, sizeof (buf)) != 0x9f5edd58) return FALSE; nTestsPerformed++; } return (nTestsPerformed == 150); } static BOOL DoAutoTestAlgorithms (void) { PCRYPTO_INFO ci; - CRYPTOPP_ALIGN_DATA(16) char key[32]; + CRYPTOPP_ALIGN_DATA(16) unsigned char key[32]; unsigned char tmp[16]; BOOL bFailed = FALSE; int i; ci = crypto_open (); if (!ci) return FALSE; memset (ci, 0, sizeof (*ci)); /* AES */ for (i = 0; i < AES_TEST_COUNT; i++) { int cipher = AES; memcpy(key, aes_ecb_vectors[i].key, 32); memcpy(tmp, aes_ecb_vectors[i].plaintext, 16); CipherInit(cipher, key, ks_tmp); EncipherBlock(cipher, tmp, ks_tmp); if (memcmp(aes_ecb_vectors[i].ciphertext, tmp, 16) != 0) break; DecipherBlock(cipher, tmp, ks_tmp); if (memcmp(aes_ecb_vectors[i].plaintext, tmp, 16) != 0) break; } if (i != AES_TEST_COUNT) bFailed = TRUE; // AES EncipherBlocks()/DecipherBlocks() { uint8 testData[1024]; uint32 origCrc; - size_t i; for (i = 0; i < sizeof (testData); ++i) { testData[i] = (uint8) i; } origCrc = GetCrc32 (testData, sizeof (testData)); CipherInit (AES, testData, ks_tmp); EncipherBlocks (AES, testData, ks_tmp, sizeof (testData) / CipherGetBlockSize (AES)); if (GetCrc32 (testData, sizeof (testData)) != 0xb5cd5631) bFailed = TRUE; DecipherBlocks (AES, testData, ks_tmp, sizeof (testData) / CipherGetBlockSize (AES)); if (origCrc != GetCrc32 (testData, sizeof (testData))) bFailed = TRUE; } #ifndef WOLFCRYPT_BACKEND /* Serpent */ for (i = 0; i < SERPENT_TEST_COUNT; i++) { int cipher = SERPENT; memcpy(key, serpent_vectors[i].key, 32); memcpy(tmp, serpent_vectors[i].plaintext, 16); CipherInit(cipher, key, ks_tmp); @@ -1499,267 +1487,267 @@ BOOL AutoTestAlgorithms (void) { exceptionCatched = TRUE; } if (exceptionCatched) { /* unexepected exception raised. Disable all CPU extended feature and try again */ EnableHwEncryption (hwEncryptionEnabled); DisableCPUExtendedFeatures (); __try { result = DoAutoTestAlgorithms(); } __except (EXCEPTION_EXECUTE_HANDLER) { /* exception still occuring. Report failure. */ result = FALSE; } } #endif return result; } BOOL test_hmac_sha256 () { unsigned int i; int nTestsPerformed = 0; for (i = 0; i < sizeof (hmac_sha256_test_data) / sizeof(char *); i++) { - char digest[1024]; /* large enough to hold digets and test vector inputs */ + unsigned char digest[1024]; /* large enough to hold digets and test vector inputs */ size_t dataLen = strlen (hmac_sha256_test_data[i]); if (dataLen <= sizeof(digest)) { memcpy (digest, hmac_sha256_test_data[i], dataLen); - hmac_sha256 (hmac_sha256_test_keys[i], (int) strlen (hmac_sha256_test_keys[i]), digest, (int) dataLen); + hmac_sha256 ((unsigned char*) hmac_sha256_test_keys[i], (int) strlen (hmac_sha256_test_keys[i]), digest, (int) dataLen); if (memcmp (digest, hmac_sha256_test_vectors[i], SHA256_DIGESTSIZE) != 0) return FALSE; else nTestsPerformed++; } else { return FALSE; } } return (nTestsPerformed == 6); } BOOL test_hmac_sha512 () { unsigned int i; int nTestsPerformed = 0; for (i = 0; i < sizeof (hmac_sha512_test_data) / sizeof(char *); i++) { - char digest[1024]; /* large enough to hold digets and test vector inputs */ + unsigned char digest[1024]; /* large enough to hold digets and test vector inputs */ size_t dataLen = strlen (hmac_sha512_test_data[i]); if (dataLen <= sizeof(digest)) { memcpy (digest, hmac_sha512_test_data[i], dataLen ); - hmac_sha512 (hmac_sha512_test_keys[i], (int) strlen (hmac_sha512_test_keys[i]), digest, (int) dataLen); + hmac_sha512 ((unsigned char*) hmac_sha512_test_keys[i], (int) strlen (hmac_sha512_test_keys[i]), digest, (int) dataLen); if (memcmp (digest, hmac_sha512_test_vectors[i], SHA512_DIGESTSIZE) != 0) return FALSE; else nTestsPerformed++; } else { return FALSE; } } return (nTestsPerformed == 6); } #ifndef WOLFCRYPT_BACKEND BOOL test_hmac_blake2s () { unsigned int i; int nTestsPerformed = 0; for (i = 0; i < sizeof (hmac_blake2s_test_data) / sizeof(char *); i++) { - char digest[1024]; /* large enough to hold digets and test vector inputs */ + unsigned char digest[1024]; /* large enough to hold digets and test vector inputs */ size_t dataLen = strlen (hmac_blake2s_test_data[i]); if (dataLen <= sizeof(digest)) { memcpy (digest, hmac_blake2s_test_data[i], dataLen); - hmac_blake2s (hmac_blake2s_test_keys[i], (int) strlen (hmac_blake2s_test_keys[i]), digest, (int) dataLen); + hmac_blake2s ((unsigned char*)(unsigned char*)hmac_blake2s_test_keys[i], (int) strlen (hmac_blake2s_test_keys[i]), digest, (int) dataLen); if (memcmp (digest, hmac_blake2s_test_vectors[i], BLAKE2S_DIGESTSIZE) != 0) return FALSE; else nTestsPerformed++; } else { return FALSE; } } return (nTestsPerformed == 6); } int __cdecl Blake2sHash (unsigned char* input, unsigned long inputLen, unsigned char* output) { blake2s(output, input, (size_t) inputLen); return BLAKE2S_DIGESTSIZE; } BOOL test_hmac_whirlpool () { unsigned char digest[1024]; /* large enough to hold digets and test vector inputs */ memcpy (digest, hmac_whirlpool_test_data, strlen (hmac_whirlpool_test_data)); - hmac_whirlpool (hmac_whirlpool_test_key, 64, digest, (int) strlen (hmac_whirlpool_test_data)); + hmac_whirlpool ((unsigned char*) hmac_whirlpool_test_key, 64, digest, (int) strlen (hmac_whirlpool_test_data)); if (memcmp (digest, hmac_whirlpool_test_vectors, WHIRLPOOL_DIGESTSIZE) != 0) return FALSE; return TRUE; } #endif /* http://www.tc26.ru/methods/recommendation/%D0%A2%D0%9A26%D0%90%D0%9B%D0%93.pdf */ /* https://tools.ietf.org/html/draft-smyshlyaev-gost-usage-00 */ /* https://datatracker.ietf.org/doc/rfc7836/?include_text=1 */ static const unsigned char gost3411_2012_hmac_k1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; static const unsigned char gost3411_2012_hmac_m1[] = { 0x01, 0x26, 0xbd, 0xb8, 0x78, 0x00, 0xaf, 0x21, 0x43, 0x41, 0x45, 0x65, 0x63, 0x78, 0x01, 0x00 }; static const unsigned char gost3411_2012_hmac_r1[] = { 0xA5, 0x9B, 0xAB, 0x22, 0xEC, 0xAE, 0x19, 0xC6, 0x5F, 0xBD, 0xE6, 0xE5, 0xF4, 0xE9, 0xF5, 0xD8, 0x54, 0x9D, 0x31, 0xF0, 0x37, 0xF9, 0xDF, 0x9B, 0x90, 0x55, 0x00, 0xE1, 0x71, 0x92, 0x3A, 0x77, 0x3D, 0x5F, 0x15, 0x30, 0xF2, 0xED, 0x7E, 0x96, 0x4C, 0xB2, 0xEE, 0xDC, 0x29, 0xE9, 0xAD, 0x2F, 0x3A, 0xFE, 0x93, 0xB2, 0x81, 0x4F, 0x79, 0xF5, 0x00, 0x0F, 0xFC, 0x03, 0x66, 0xC2, 0x51, 0xE6 }; #ifndef WOLFCRYPT_BACKEND BOOL test_hmac_streebog () { - CRYPTOPP_ALIGN_DATA(16) char digest[64]; /* large enough to hold digets and test vector inputs */ + CRYPTOPP_ALIGN_DATA(16) unsigned char digest[64]; /* large enough to hold digets and test vector inputs */ memcpy (digest, gost3411_2012_hmac_m1, sizeof (gost3411_2012_hmac_m1)); - hmac_streebog ((char*) gost3411_2012_hmac_k1, sizeof(gost3411_2012_hmac_k1), digest, (int) sizeof (gost3411_2012_hmac_m1)); + hmac_streebog ((unsigned char*) gost3411_2012_hmac_k1, sizeof(gost3411_2012_hmac_k1), digest, (int) sizeof (gost3411_2012_hmac_m1)); if (memcmp (digest, gost3411_2012_hmac_r1, STREEBOG_DIGESTSIZE) != 0) return FALSE; return TRUE; } int __cdecl StreebogHash (unsigned char* input, unsigned long inputLen, unsigned char* output) { STREEBOG_CTX ctx; STREEBOG_init (&ctx); STREEBOG_add (&ctx, input, inputLen); STREEBOG_finalize (&ctx, output); return STREEBOG_DIGESTSIZE; } #endif BOOL test_pkcs5 () { - char dk[144]; + unsigned char dk[144]; /* HMAC-SHA-256 tests */ if (!test_hmac_sha256()) return FALSE; /* HMAC-SHA-512 tests */ if (!test_hmac_sha512()) return FALSE; #ifndef WOLFCRYPT_BACKEND /* HMAC-BLAKE2s tests */ if (test_hmac_blake2s() == FALSE) return FALSE; /* Blake2s hash tests */ - if (RunHashTest (Blake2sHash, Blake2sTestVectors, (HasSSE2())? TRUE : FALSE) == FALSE) + if (RunHashTest (Blake2sHash, Blake2sTestVectors)) return FALSE; /* HMAC-Whirlpool tests */ if (test_hmac_whirlpool() == FALSE) return FALSE; /* HMAC-STREEBOG tests */ if (test_hmac_streebog() == FALSE) return FALSE; /* STREEBOG hash tests */ - if (RunHashTest (StreebogHash, Streebog512TestVectors, (HasSSE2() || HasSSE41())? TRUE : FALSE) == FALSE) + if (RunHashTest (StreebogHash, Streebog512TestVectors)) return FALSE; #endif /* PKCS-5 test 1 with HMAC-SHA-256 used as the PRF (https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-00) */ - derive_key_sha256 ("passwd", 6, "\x73\x61\x6C\x74", 4, 1, dk, 64); + derive_key_sha256 ((unsigned char*) "passwd", 6, (unsigned char*) "\x73\x61\x6C\x74", 4, 1, dk, 64); if (memcmp (dk, "\x55\xac\x04\x6e\x56\xe3\x08\x9f\xec\x16\x91\xc2\x25\x44\xb6\x05\xf9\x41\x85\x21\x6d\xde\x04\x65\xe6\x8b\x9d\x57\xc2\x0d\xac\xbc\x49\xca\x9c\xcc\xf1\x79\xb6\x45\x99\x16\x64\xb3\x9d\x77\xef\x31\x7c\x71\xb8\x45\xb1\xe3\x0b\xd5\x09\x11\x20\x41\xd3\xa1\x97\x83", 64) != 0) return FALSE; /* PKCS-5 test 2 with HMAC-SHA-256 used as the PRF (https://stackoverflow.com/questions/5130513/pbkdf2-hmac-sha2-test-vectors) */ - derive_key_sha256 ("password", 8, "\x73\x61\x6C\x74", 4, 2, dk, 32); + derive_key_sha256 ((unsigned char*) "password", 8, (unsigned char*) "\x73\x61\x6C\x74", 4, 2, dk, 32); if (memcmp (dk, "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43", 32) != 0) return FALSE; /* PKCS-5 test 3 with HMAC-SHA-256 used as the PRF (MS CryptoAPI) */ - derive_key_sha256 ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4); + derive_key_sha256 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); if (memcmp (dk, "\xf2\xa0\x4f\xb2", 4) != 0) return FALSE; /* PKCS-5 test 4 with HMAC-SHA-256 used as the PRF (MS CryptoAPI) */ - derive_key_sha256 ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 144); + derive_key_sha256 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 144); if (memcmp (dk, "\xf2\xa0\x4f\xb2\xd3\xe9\xa5\xd8\x51\x0b\x5c\x06\xdf\x70\x8e\x24\xe9\xc7\xd9\x15\x3d\x22\xcd\xde\xb8\xa6\xdb\xfd\x71\x85\xc6\x99\x32\xc0\xee\x37\x27\xf7\x24\xcf\xea\xa6\xac\x73\xa1\x4c\x4e\x52\x9b\x94\xf3\x54\x06\xfc\x04\x65\xa1\x0a\x24\xfe\xf0\x98\x1d\xa6\x22\x28\xeb\x24\x55\x74\xce\x6a\x3a\x28\xe2\x04\x3a\x59\x13\xec\x3f\xf2\xdb\xcf\x58\xdd\x53\xd9\xf9\x17\xf6\xda\x74\x06\x3c\x0b\x66\xf5\x0f\xf5\x58\xa3\x27\x52\x8c\x5b\x07\x91\xd0\x81\xeb\xb6\xbc\x30\x69\x42\x71\xf2\xd7\x18\x42\xbe\xe8\x02\x93\x70\x66\xad\x35\x65\xbc\xf7\x96\x8e\x64\xf1\xc6\x92\xda\xe0\xdc\x1f\xb5\xf4", 144) != 0) return FALSE; /* PKCS-5 test 1 with HMAC-SHA-512 used as the PRF */ - derive_key_sha512 ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4); + derive_key_sha512 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); if (memcmp (dk, "\x13\x64\xae\xf8", 4) != 0) return FALSE; /* PKCS-5 test 2 with HMAC-SHA-512 used as the PRF (derives a key longer than the underlying hash output size and block size) */ - derive_key_sha512 ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 144); + derive_key_sha512 ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 144); if (memcmp (dk, "\x13\x64\xae\xf8\x0d\xf5\x57\x6c\x30\xd5\x71\x4c\xa7\x75\x3f\xfd\x00\xe5\x25\x8b\x39\xc7\x44\x7f\xce\x23\x3d\x08\x75\xe0\x2f\x48\xd6\x30\xd7\x00\xb6\x24\xdb\xe0\x5a\xd7\x47\xef\x52\xca\xa6\x34\x83\x47\xe5\xcb\xe9\x87\xf1\x20\x59\x6a\xe6\xa9\xcf\x51\x78\xc6\xb6\x23\xa6\x74\x0d\xe8\x91\xbe\x1a\xd0\x28\xcc\xce\x16\x98\x9a\xbe\xfb\xdc\x78\xc9\xe1\x7d\x72\x67\xce\xe1\x61\x56\x5f\x96\x68\xe6\xe1\xdd\xf4\xbf\x1b\x80\xe0\x19\x1c\xf4\xc4\xd3\xdd\xd5\xd5\x57\x2d\x83\xc7\xa3\x37\x87\xf4\x4e\xe0\xf6\xd8\x6d\x65\xdc\xa0\x52\xa3\x13\xbe\x81\xfc\x30\xbe\x7d\x69\x58\x34\xb6\xdd\x41\xc6", 144) != 0) return FALSE; #ifndef WOLFCRYPT_BACKEND /* PKCS-5 test 1 with HMAC-BLAKE2s used as the PRF */ - derive_key_blake2s ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4); + derive_key_blake2s ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); if (memcmp (dk, "\x8d\x51\xfa\x31", 4) != 0) return FALSE; /* PKCS-5 test 2 with HMAC-BLAKE2s used as the PRF (derives a key longer than the underlying hash) */ - derive_key_blake2s ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 48); + derive_key_blake2s ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 48); if (memcmp (dk, "\x8d\x51\xfa\x31\x46\x25\x37\x67\xa3\x29\x6b\x3c\x6b\xc1\x5d\xb2\xee\xe1\x6c\x28\x00\x26\xea\x08\x65\x9c\x12\xf1\x07\xde\x0d\xb9\x9b\x4f\x39\xfa\xc6\x80\x26\xb1\x8f\x8e\x48\x89\x85\x2d\x24\x2d", 48) != 0) return FALSE; /* PKCS-5 test 1 with HMAC-Whirlpool used as the PRF */ - derive_key_whirlpool ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4); + derive_key_whirlpool ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); if (memcmp (dk, "\x50\x7c\x36\x6f", 4) != 0) return FALSE; /* PKCS-5 test 2 with HMAC-Whirlpool used as the PRF (derives a key longer than the underlying hash) */ - derive_key_whirlpool ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 96); + derive_key_whirlpool ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 96); if (memcmp (dk, "\x50\x7c\x36\x6f\xee\x10\x2e\x9a\xe2\x8a\xd5\x82\x72\x7d\x27\x0f\xe8\x4d\x7f\x68\x7a\xcf\xb5\xe7\x43\x67\xaa\x98\x93\x52\x2b\x09\x6e\x42\xdf\x2c\x59\x4a\x91\x6d\x7e\x10\xae\xb2\x1a\x89\x8f\xb9\x8f\xe6\x31\xa9\xd8\x9f\x98\x26\xf4\xda\xcd\x7d\x65\x65\xde\x10\x95\x91\xb4\x84\x26\xae\x43\xa1\x00\x5b\x1e\xb8\x38\x97\xa4\x1e\x4b\xd2\x65\x64\xbc\xfa\x1f\x35\x85\xdb\x4f\x97\x65\x6f\xbd\x24", 96) != 0) return FALSE; /* PKCS-5 test 1 with HMAC-STREEBOG used as the PRF */ - derive_key_streebog ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 4); + derive_key_streebog ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 4); if (memcmp (dk, "\xd0\x53\xa2\x30", 4) != 0) return FALSE; /* PKCS-5 test 2 with HMAC-STREEBOG used as the PRF (derives a key longer than the underlying hash) */ - derive_key_streebog ("password", 8, "\x12\x34\x56\x78", 4, 5, dk, 96); + derive_key_streebog ((unsigned char*)"password", 8, (unsigned char*)"\x12\x34\x56\x78", 4, 5, dk, 96); if (memcmp (dk, "\xd0\x53\xa2\x30\x6f\x45\x81\xeb\xbc\x06\x81\xc5\xe7\x53\xa8\x5d\xc7\xf1\x23\x33\x1e\xbe\x64\x2c\x3b\x0f\x26\xd7\x00\xe1\x95\xc9\x65\x26\xb1\x85\xbe\x1e\xe2\xf4\x9b\xfc\x6b\x14\x84\xda\x24\x61\xa0\x1b\x9e\x79\x5c\xee\x69\x6e\xf9\x25\xb1\x1d\xca\xa0\x31\xba\x02\x6f\x9e\x99\x0f\xdb\x25\x01\x5b\xf1\xc7\x10\x19\x53\x3b\x29\x3f\x18\x00\xd6\xfc\x85\x03\xdc\xf2\xe5\xe9\x5a\xb1\x1e\x61\xde", 96) != 0) return FALSE; #endif return TRUE; } diff --git a/src/Common/Tests.h b/src/Common/Tests.h index 356d54f4..bfdf7c40 100644 --- a/src/Common/Tests.h +++ b/src/Common/Tests.h @@ -1,31 +1,31 @@ /* Legal Notice: Some portions of the source code contained in this file were derived from the source code of TrueCrypt 7.1a, which is Copyright (c) 2003-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0, also from the source code of Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License Agreement for Encryption for the Masses' Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #ifdef __cplusplus extern "C" { #endif extern unsigned char ks_tmp[MAX_EXPANDED_KEY]; -void CipherInit2(int cipher, void* key, void* ks, int key_len); +void CipherInit2(int cipher, void* key, void* ks); BOOL test_hmac_sha512 (void); BOOL test_hmac_blake2s (void); BOOL test_hmac_whirlpool (void); BOOL test_pkcs5 (void); BOOL TestSectorBufEncryption (); BOOL TestLegacySectorBufEncryption (); BOOL AutoTestAlgorithms (void); #ifdef __cplusplus } #endif diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 7ee519f6..3a836787 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -133,78 +133,78 @@ uint16 GetHeaderField16 (uint8 *header, int offset) { return BE16 (*(uint16 *) (header + offset)); } uint32 GetHeaderField32 (uint8 *header, int offset) { return BE32 (*(uint32 *) (header + offset)); } UINT64_STRUCT GetHeaderField64 (uint8 *header, int offset) { UINT64_STRUCT uint64Struct; #ifndef TC_NO_COMPILER_INT64 uint64Struct.Value = BE64 (*(uint64 *) (header + offset)); #else uint64Struct.HighPart = BE32 (*(uint32 *) (header + offset)); uint64Struct.LowPart = BE32 (*(uint32 *) (header + offset + 4)); #endif return uint64Struct; } #ifndef TC_WINDOWS_BOOT typedef struct { - char DerivedKey[MASTER_KEYDATA_SIZE]; + unsigned char DerivedKey[MASTER_KEYDATA_SIZE]; BOOL Free; LONG KeyReady; int Pkcs5Prf; } KeyDerivationWorkItem; BOOL ReadVolumeHeaderRecoveryMode = FALSE; -int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int selected_pkcs5_prf, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo) +int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *password, int selected_pkcs5_prf, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo) { - char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + unsigned char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; unsigned char* keyInfoBuffer = NULL; int keyInfoBufferSize = sizeof (KEY_INFO) + 16; size_t keyInfoBufferOffset; PKEY_INFO keyInfo; PCRYPTO_INFO cryptoInfo; - CRYPTOPP_ALIGN_DATA(16) char dk[MASTER_KEYDATA_SIZE]; + CRYPTOPP_ALIGN_DATA(16) unsigned char dk[MASTER_KEYDATA_SIZE]; int enqPkcs5Prf, pkcs5_prf; uint16 headerVersion; int status = ERR_PARAMETER_INCORRECT; int primaryKeyOffset; int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1; #if !defined(_UEFI) TC_EVENT *keyDerivationCompletedEvent = NULL; TC_EVENT *noOutstandingWorkItemEvent = NULL; KeyDerivationWorkItem *keyDerivationWorkItems = NULL; int keyDerivationWorkItemsSize = 0; KeyDerivationWorkItem *item; size_t encryptionThreadCount = GetEncryptionThreadCount(); LONG *outstandingWorkItemCount = NULL; int i; #endif size_t queuedWorkItems = 0; // allocate 16-bytes aligned buffer to hold KEY_INFO in a portable way keyInfoBuffer = TCalloc(keyInfoBufferSize); if (!keyInfoBuffer) return ERR_OUTOFMEMORY; keyInfoBufferOffset = 16 - (((uint64) keyInfoBuffer) % 16); keyInfo = (PKEY_INFO) (keyInfoBuffer + keyInfoBufferOffset); #if !defined(DEVICE_DRIVER) && !defined(_UEFI) VirtualLock (keyInfoBuffer, keyInfoBufferSize); #endif // if no PIM specified, use default value if (pim < 0) @@ -677,66 +677,66 @@ void ComputeBootloaderFingerprint (uint8 *bootLoaderBuf, unsigned int bootLoader WHIRLPOOL_add (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &whirlpool); sha512_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2); WHIRLPOOL_finalize (&whirlpool, fingerprint); sha512_end (&fingerprint [WHIRLPOOL_DIGESTSIZE], &sha2); #else sha512_ctx sha2_512; sha256_ctx sha2_256; sha512_begin (&sha2_512); sha256_begin (&sha2_256); sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2_512); sha256_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2_256); sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2_512); sha256_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2_256); sha512_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2_512); sha256_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2_256); sha512_end (&fingerprint, &sha2_512); sha256_end (&fingerprint [SHA512_DIGESTSIZE], &sha2_256); sha256_end (&fingerprint [SHA512_DIGESTSIZE + SHA256_DIGESTSIZE], &sha2_256); #endif } #endif #else // TC_WINDOWS_BOOT -int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo) +int ReadVolumeHeader (BOOL bBoot, unsigned char *header, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo) { #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE - char dk[32 * 2]; // 2 * 256-bit key + unsigned char dk[32 * 2]; // 2 * 256-bit key #else - char dk[32 * 2 * 3]; // 6 * 256-bit key + unsigned char dk[32 * 2 * 3]; // 6 * 256-bit key #endif PCRYPTO_INFO cryptoInfo; int status = ERR_SUCCESS; uint32 iterations = pim; iterations <<= 16; iterations |= bBoot; if (retHeaderCryptoInfo != NULL) cryptoInfo = retHeaderCryptoInfo; else cryptoInfo = *retInfo = crypto_open (); // PKCS5 PRF #ifdef TC_WINDOWS_BOOT_SHA2 derive_key_sha256 (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE, iterations, dk, sizeof (dk)); #else derive_key_blake2s (password->Text, (int) password->Length, header + HEADER_SALT_OFFSET, PKCS5_SALT_SIZE, iterations, dk, sizeof (dk)); #endif // Mode of operation cryptoInfo->mode = FIRST_MODE_OF_OPERATION_ID; #ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE cryptoInfo->ea = 1; #else // Test all available encryption algorithms for (cryptoInfo->ea = EAGetFirst (); cryptoInfo->ea != 0; cryptoInfo->ea = EAGetNext (cryptoInfo->ea)) @@ -855,72 +855,72 @@ int ReadVolumeHeader (BOOL bBoot, char *header, Password *password, int pim, PCR #endif goto ret; } status = ERR_PASSWORD_WRONG; err: if (cryptoInfo != retHeaderCryptoInfo) { crypto_close(cryptoInfo); *retInfo = NULL; } ret: burn (dk, sizeof(dk)); return status; } #endif // TC_WINDOWS_BOOT #if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT) #ifdef VOLFORMAT # include "../Format/TcFormat.h" # include "Dlgcode.h" #endif // Creates a volume header in memory #if defined(_UEFI) -int CreateVolumeHeaderInMemory(BOOL bBoot, char *header, int ea, int mode, Password *password, +int CreateVolumeHeaderInMemory(BOOL bBoot, unsigned char *header, int ea, int mode, Password *password, int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode) #else -int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, int mode, Password *password, +int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, unsigned char *header, int ea, int mode, Password *password, int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode) #endif // !defined(_UEFI) { - unsigned char *p = (unsigned char *) header; + unsigned char *p = header; static CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo; int nUserKeyLen = password? password->Length : 0; PCRYPTO_INFO cryptoInfo = crypto_open (); static char dk[MASTER_KEYDATA_SIZE]; int x; int retVal = 0; int primaryKeyOffset; if (cryptoInfo == NULL) return ERR_OUTOFMEMORY; // if no PIM specified, use default value if (pim < 0) pim = 0; memset (header, 0, TC_VOLUME_HEADER_EFFECTIVE_SIZE); #if !defined(_UEFI) VirtualLock (&keyInfo, sizeof (keyInfo)); VirtualLock (&dk, sizeof (dk)); #endif // !defined(_UEFI) /* Encryption setup */ if (masterKeydata == NULL) { // We have no master key data (creating a new volume) so we'll use the TrueCrypt RNG to generate them int bytesNeeded; diff --git a/src/Common/Volumes.h b/src/Common/Volumes.h index daad25e3..07ed0fe8 100644 --- a/src/Common/Volumes.h +++ b/src/Common/Volumes.h @@ -106,56 +106,56 @@ extern "C" { #define TC_HEADER_OFFSET_MAGIC 64 #define TC_HEADER_OFFSET_VERSION 68 #define TC_HEADER_OFFSET_REQUIRED_VERSION 70 #define TC_HEADER_OFFSET_KEY_AREA_CRC 72 #define TC_HEADER_OFFSET_VOLUME_CREATION_TIME 76 #define TC_HEADER_OFFSET_MODIFICATION_TIME 84 #define TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE 92 #define TC_HEADER_OFFSET_VOLUME_SIZE 100 #define TC_HEADER_OFFSET_ENCRYPTED_AREA_START 108 #define TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH 116 #define TC_HEADER_OFFSET_FLAGS 124 #define TC_HEADER_OFFSET_SECTOR_SIZE 128 #define TC_HEADER_OFFSET_HEADER_CRC 252 // Volume header flags #define TC_HEADER_FLAG_ENCRYPTED_SYSTEM 0x1 #define TC_HEADER_FLAG_NONSYS_INPLACE_ENC 0x2 // The volume has been created (or is being encrypted/decrypted) using non-system in-place encryption #ifndef TC_HEADER_Volume_VolumeHeader #include "Password.h" extern BOOL ReadVolumeHeaderRecoveryMode; uint16 GetHeaderField16 (uint8 *header, int offset); uint32 GetHeaderField32 (uint8 *header, int offset); UINT64_STRUCT GetHeaderField64 (uint8 *header, int offset); #if defined(TC_WINDOWS_BOOT) -int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); +int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *password, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); #elif defined(_UEFI) -int ReadVolumeHeader(BOOL bBoot, char *encryptedHeader, Password *password, int pkcs5_prf, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); -int CreateVolumeHeaderInMemory(BOOL bBoot, char *encryptedHeader, int ea, int mode, Password *password, int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode); +int ReadVolumeHeader(BOOL bBoot, unsigned char *encryptedHeader, Password *password, int pkcs5_prf, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); +int CreateVolumeHeaderInMemory(BOOL bBoot, unsigned char *encryptedHeader, int ea, int mode, Password *password, int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode); BOOL RandgetBytes(unsigned char *buf, int len, BOOL forceSlowPoll); #else -int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int pkcs5_prf, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); +int ReadVolumeHeader (BOOL bBoot, unsigned char *encryptedHeader, Password *password, int pkcs5_prf, int pim, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); #if defined(_WIN32) && !defined(_UEFI) void ComputeBootloaderFingerprint (uint8 *bootLoaderBuf, unsigned int bootLoaderSize, uint8* fingerprint); #endif #endif #if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT) && !defined(_UEFI) -int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *encryptedHeader, int ea, int mode, Password *password, int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode); +int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, unsigned char *encryptedHeader, int ea, int mode, Password *password, int pkcs5_prf, int pim, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode); BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, uint8 *header, DWORD *bytesRead); BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, uint8 *header); int WriteRandomDataToReservedHeaderAreas (HWND hwndDlg, HANDLE dev, CRYPTO_INFO *cryptoInfo, uint64 dataAreaSize, BOOL bPrimaryOnly, BOOL bBackupOnly); #endif #endif // !TC_HEADER_Volume_VolumeHeader #ifdef __cplusplus } #endif #endif // TC_HEADER_Common_Volumes diff --git a/src/Common/Wipe.c b/src/Common/Wipe.c index d68b517b..af3d15db 100644 --- a/src/Common/Wipe.c +++ b/src/Common/Wipe.c @@ -1,51 +1,46 @@ /* Derived from source code of TrueCrypt 7.1a, which is Copyright (c) 2008-2012 TrueCrypt Developers Association and which is governed by the TrueCrypt License 3.0. Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2017 IDRIX and are governed by the Apache License 2.0 the full text of which is contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ #include "Tcdefs.h" #include "Wipe.h" -static BOOL Wipe1PseudoRandom (int pass, uint8 *buffer, size_t size) -{ - return FALSE; -} - // Fill buffer with wipe patterns defined in "National Industrial Security Program Operating Manual", US DoD 5220.22-M. // Return: FALSE = buffer must be filled with random data static BOOL Wipe3Dod5220 (int pass, uint8 *buffer, size_t size) { uint8 wipeChar; switch (pass) { case 1: wipeChar = 0; break; case 2: wipeChar = 0xff; break; default: return FALSE; } memset (buffer, wipeChar, size); return TRUE; } static BOOL Wipe7Dod5220 (int pass, uint8 randChars[TC_WIPE_RAND_CHAR_COUNT], uint8 *buffer, size_t size) { uint8 wipeChar; @@ -146,53 +141,53 @@ wipe3: int GetWipePassCount (WipeAlgorithmId algorithm) { switch (algorithm) { case TC_WIPE_1_RAND: return 1; case TC_WIPE_3_DOD_5220: return 3; case TC_WIPE_7_DOD_5220: return 7; case TC_WIPE_35_GUTMANN: return 35; case TC_WIPE_256: return 256; } return -1; // Prevent compiler warnings } BOOL WipeBuffer (WipeAlgorithmId algorithm, uint8 randChars[TC_WIPE_RAND_CHAR_COUNT], int pass, uint8 *buffer, size_t size) { switch (algorithm) { case TC_WIPE_1_RAND: case TC_WIPE_256: - return Wipe1PseudoRandom (pass, buffer, size); + return FALSE; // Delegate buffer filling to the caller case TC_WIPE_3_DOD_5220: return Wipe3Dod5220 (pass, buffer, size); case TC_WIPE_7_DOD_5220: return Wipe7Dod5220 (pass, randChars, buffer, size); case TC_WIPE_35_GUTMANN: return Wipe35Gutmann (pass, buffer, size); /* we will never reach here because all calls to WipeBuffer are preceeded * by a call to GetWipePassCount that already checks the same algorithm * parameters and in case of unsupported value an error is returned before * calling WipeBuffer */ /* default: TC_THROW_FATAL_EXCEPTION;*/ } return FALSE; // Prevent compiler warnings } diff --git a/src/Crypto/Sha2Intel.c b/src/Crypto/Sha2Intel.c index c926f76a..943115bf 100644 --- a/src/Crypto/Sha2Intel.c +++ b/src/Crypto/Sha2Intel.c @@ -1,53 +1,113 @@ /* * Support for SHA-256 x86 instrinsic * Based on public domain code by Sean Gulley * (https://github.com/mitls/hacl-star/tree/master/experimental/hash) * * Botan is released under the Simplified BSD License (see license.txt) */ /* November 10th 2024: Modified for VeraCrypt */ #include "Sha2.h" #include "Common/Endian.h" #include "cpu.h" #include "misc.h" #if defined(_UEFI) || defined(CRYPTOPP_DISABLE_ASM) #define NO_OPTIMIZED_VERSIONS #endif #ifndef NO_OPTIMIZED_VERSIONS #if CRYPTOPP_SHANI_AVAILABLE +#ifndef _MSC_VER +#include <signal.h> +#include <setjmp.h> + +typedef void (*SigHandler)(int); + +static jmp_buf s_jmpNoSHA; +static void SigIllHandlerSHA(int p) +{ + longjmp(s_jmpNoSHA, 1); +} +#endif + +int TrySHA256() +{ + volatile int result = 0; +#ifdef _MSC_VER + __try +#else + SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA); + if (oldHandler == SIG_ERR) + return 0; + if (setjmp(s_jmpNoSHA)) + result = 0; + else +#endif + { + // Known input message block + __m128i msg0 = _mm_setr_epi32(0x12345678, 0x9ABCDEF0, 0x87654321, 0x0FEDCBA9); + __m128i msg1 = _mm_setr_epi32(0x11111111, 0x22222222, 0x33333333, 0x44444444); + + // SHA256 message schedule update + __m128i tmp = _mm_sha256msg1_epu32(msg0, msg1); + + // Verify result - these values were pre-computed for the given input +#ifdef _MSC_VER + if (tmp.m128i_u32[0] == 0xD8131B44 && + tmp.m128i_u32[1] == 0x9DE6E22B && + tmp.m128i_u32[2] == 0xA86D643A && + tmp.m128i_u32[3] == 0x74320FED) +#else + if (((uint32_t*)(&tmp))[0] == 0xD8131B44 && + ((uint32_t*)(&tmp))[1] == 0x9DE6E22B && + ((uint32_t*)(&tmp))[2] == 0xA86D643A && + ((uint32_t*)(&tmp))[3] == 0x74320FED) +#endif + result = 1; + } +#ifdef _MSC_VER + __except (EXCEPTION_EXECUTE_HANDLER) + { + // ignore error if SHA instructions not supported + } +#else + signal(SIGILL, oldHandler); +#endif + + return result; +} + // void sha256_intel(void *mp, uint_32t state[8], uint_64t num_blks) { // Constants table - align for better performance CRYPTOPP_ALIGN_DATA(64) static const uint_32t K[64] = { 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, }; const __m128i* K_mm = (const __m128i*)K; const __m128i* input_mm = (const __m128i*)mp; // Create byte shuffle mask for big-endian to little-endian conversion const __m128i MASK = _mm_set_epi64x(0x0c0d0e0f08090a0b, 0x0405060700010203); // Load initial values __m128i STATE0 = _mm_loadu_si128((__m128i*)&state[0]); __m128i STATE1 = _mm_loadu_si128((__m128i*)&state[4]); // Adjust byte ordering STATE0 = _mm_shuffle_epi32(STATE0, 0xB1); // CDAB STATE1 = _mm_shuffle_epi32(STATE1, 0x1B); // EFGH diff --git a/src/Crypto/Whirlpool.c b/src/Crypto/Whirlpool.c index 6a1fe8b4..140c7c6f 100644 --- a/src/Crypto/Whirlpool.c +++ b/src/Crypto/Whirlpool.c @@ -930,82 +930,89 @@ void WHIRLPOOL_add(const unsigned char * input, uint64 len = sourceBytes; if ((ctx->countLo = oldCountLo + (uint64)len) < oldCountLo) ctx->countHi++; // carry from low to high if (ctx->countHi < oldCountHi) return; else { uint64* dataBuf = ctx->data; uint8* data = (uint8 *)dataBuf; num = oldCountLo & 63; if (num != 0) // process left over data { if (num+len >= 64) { memcpy(data+num, input, (size_t) (64-num)); HashMultipleBlocks(ctx, dataBuf, 64); input += (64-num); len -= (64-num); // drop through and do the rest } else { memcpy(data+num, input, (size_t) len); return; } } // now process the input data in blocks of 64 bytes and save the leftovers to ctx->data - if (len >= 64) - { - if (input == data) - { - HashMultipleBlocks(ctx, dataBuf, 64); - return; - } - else if (IsAligned16(input)) - { - uint64 leftOver = HashMultipleBlocks(ctx, (uint64 *)input, len); - input += (len - leftOver); - len = leftOver; - } - else - do - { // copy input first if it's not aligned correctly - memcpy(data, input, 64); - HashMultipleBlocks(ctx, dataBuf, 64); - input+=64; - len-=64; - } while (len >= 64); - } + if (len >= 64) + { + if (input == data) + { + HashMultipleBlocks(ctx, dataBuf, 64); + return; + } + else + { +#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS + if (IsAligned16(input)) +#endif + { + uint64 leftOver = HashMultipleBlocks(ctx, (uint64*)input, len); + input += (len - leftOver); + len = leftOver; + } +#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS + else + do + { // copy input first if it's not aligned correctly + memcpy(data, input, 64); + HashMultipleBlocks(ctx, dataBuf, 64); + input += 64; + len -= 64; + } while (len >= 64); +#endif + } + } if (len && data != input) memcpy(data, input, (size_t) len); } } /** * Get the hash value from the hashing state. * * This method uses the invariant: bufferBits < DIGESTBITS */ void WHIRLPOOL_finalize(WHIRLPOOL_CTX * const ctx, unsigned char * result) { unsigned int num = ctx->countLo & 63; uint64* dataBuf = ctx->data; uint64* stateBuf = ctx->state; uint8* data = (uint8 *)dataBuf; data[num++] = 0x80; if (num <= 32) memset(data+num, 0, 32-num); else { memset(data+num, 0, 64-num); HashMultipleBlocks(ctx, dataBuf, 64); memset(data, 0, 32); } #if BYTE_ORDER == LITTLE_ENDIAN CorrectEndianness(dataBuf, dataBuf, 32); diff --git a/src/Crypto/chacha-xmm.c b/src/Crypto/chacha-xmm.c index 54c3680c..980c2c81 100644 --- a/src/Crypto/chacha-xmm.c +++ b/src/Crypto/chacha-xmm.c @@ -54,99 +54,60 @@ __inline __m128i _mm_set1_epi64x(int64 a) #define XOR(v,w) ((v) ^ (w)) #define PLUS(v,w) (U32V((v) + (w))) #define PLUSONE(v) (PLUS((v),1)) #define QUARTERROUND(a,b,c,d) \ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7); static void salsa20_wordtobyte(uint8 output[64],const uint32 input[16], unsigned int r) { uint32 x[16]; int i; for (i = 0;i < 16;++i) x[i] = input[i]; for (i = r;i > 0;--i) { QUARTERROUND( 0, 4, 8,12) QUARTERROUND( 1, 5, 9,13) QUARTERROUND( 2, 6,10,14) QUARTERROUND( 3, 7,11,15) QUARTERROUND( 0, 5,10,15) QUARTERROUND( 1, 6,11,12) QUARTERROUND( 2, 7, 8,13) QUARTERROUND( 3, 4, 9,14) } for (i = 0;i < 16;++i) x[i] = PLUS(x[i],input[i]); for (i = 0;i < 16;++i) U32TO8_LITTLE(output + 4 * i,x[i]); } -void chacha_ECRYPT_init(void) -{ - return; -} - -static const char sigma[17] = "expand 32-byte k"; -static const char tau[17] = "expand 16-byte k"; - -void chacha_ECRYPT_keysetup(uint32* input,const uint8 *k,uint32 kbits,uint32 ivbits) -{ - const char *constants; - - input[4] = U8TO32_LITTLE(k + 0); - input[5] = U8TO32_LITTLE(k + 4); - input[6] = U8TO32_LITTLE(k + 8); - input[7] = U8TO32_LITTLE(k + 12); - if (kbits == 256) { /* recommended */ - k += 16; - constants = sigma; - } else { /* kbits == 128 */ - constants = tau; - } - input[8] = U8TO32_LITTLE(k + 0); - input[9] = U8TO32_LITTLE(k + 4); - input[10] = U8TO32_LITTLE(k + 8); - input[11] = U8TO32_LITTLE(k + 12); - input[0] = U8TO32_LITTLE(constants + 0); - input[1] = U8TO32_LITTLE(constants + 4); - input[2] = U8TO32_LITTLE(constants + 8); - input[3] = U8TO32_LITTLE(constants + 12); -} - -void chacha_ECRYPT_ivsetup(uint32* input,const uint8 *iv) -{ - input[12] = 0; - input[13] = 0; - input[14] = U8TO32_LITTLE(iv + 0); - input[15] = U8TO32_LITTLE(iv + 4); -} void chacha_ECRYPT_encrypt_bytes(size_t bytes, uint32* x, const uint8* m, uint8* out, uint8* output, unsigned int r) { unsigned int i; #include "chacha_u4.h" #include "chacha_u1.h" #ifndef _M_X64 #ifdef _MSC_VER #if _MSC_VER < 1900 _mm_empty(); #endif #endif #endif if (!bytes) return; // bytes is now guaranteed to be between 1 and 63 salsa20_wordtobyte(output,x, r); x[12] = PLUSONE(x[12]); if (!x[12]) { x[13] = PLUSONE(x[13]); /* stopping at 2^70 bytes per nonce is user's responsibility */ } for (i = 0;i < bytes;++i) out[i] = m[i] ^ output[i]; } #endif diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index c00d8409..30263361 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -28,70 +28,60 @@ int CpuId(uint32 input, uint32 output[4]) __cpuid((int *)output, input); return 1; } #else #ifndef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY #if defined(__cplusplus) extern "C" { #endif typedef void (*SigHandler)(int); static jmp_buf s_jmpNoCPUID; static void SigIllHandlerCPUID(int p) { longjmp(s_jmpNoCPUID, 1); } #if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) static jmp_buf s_jmpNoAESNI; static void SigIllHandlerAESNI(int p) { longjmp(s_jmpNoAESNI, 1); } #endif -#if !defined (_UEFI) && (defined(__SHA__) || defined(__INTEL_COMPILER) || CRYPTOPP_SHANI_AVAILABLE) - -static jmp_buf s_jmpNoSHA; -static void SigIllHandlerSHA(int p) -{ - longjmp(s_jmpNoSHA, 1); -} - -#endif - #if CRYPTOPP_BOOL_X64 == 0 static jmp_buf s_jmpNoSSE2; static void SigIllHandlerSSE2(int p) { longjmp(s_jmpNoSSE2, 1); } #endif #if defined(__cplusplus) } #endif #endif int CpuId(uint32 input, uint32 output[4]) { #ifdef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY #ifndef _UEFI __try { #endif __asm { mov eax, input mov ecx, 0 cpuid mov edi, output mov [edi], eax mov [edi+4], ebx mov [edi+8], ecx mov [edi+12], edx @@ -295,106 +285,61 @@ static int Detect_MS_HyperV_AES () // when Hyper-V is enabled on older versions of Windows Server (i.e. 2008 R2), the AES-NI capability // gets masked out for all applications, even running on the host. // We try to detect Hyper-V virtual CPU and perform a dummy AES-NI operation to check its real presence uint32 cpuid[4] = {0}; char HvProductName[13]; CpuId(0x40000000, cpuid); memcpy (HvProductName, &cpuid[1], 12); HvProductName[12] = 0; if (_stricmp(HvProductName, "Microsoft Hv") == 0) { #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KFLOATING_SAVE floatingPointState; if (NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))) { #endif hasAesNI = TryAESNI (); #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KeRestoreFloatingPointState (&floatingPointState); } #endif } return hasAesNI; } #endif #if defined(__SHA__) || defined(__INTEL_COMPILER) || CRYPTOPP_SHANI_AVAILABLE -static int TrySHA256() -{ - volatile int result = 0; -#ifdef _MSC_VER - __try -#else - SigHandler oldHandler = signal(SIGILL, SigIllHandlerSHA); - if (oldHandler == SIG_ERR) - return 0; - if (setjmp(s_jmpNoSHA)) - result = 0; - else -#endif - { - // Known input message block - __m128i msg0 = _mm_setr_epi32(0x12345678, 0x9ABCDEF0, 0x87654321, 0x0FEDCBA9); - __m128i msg1 = _mm_setr_epi32(0x11111111, 0x22222222, 0x33333333, 0x44444444); - - // SHA256 message schedule update - __m128i tmp = _mm_sha256msg1_epu32(msg0, msg1); - - // Verify result - these values were pre-computed for the given input -#ifdef _MSC_VER - if (tmp.m128i_u32[0] == 0xD8131B44 && - tmp.m128i_u32[1] == 0x9DE6E22B && - tmp.m128i_u32[2] == 0xA86D643A && - tmp.m128i_u32[3] == 0x74320FED) -#else - if (((uint32_t*)(&tmp))[0] == 0xD8131B44 && - ((uint32_t*)(&tmp))[1] == 0x9DE6E22B && - ((uint32_t*)(&tmp))[2] == 0xA86D643A && - ((uint32_t*)(&tmp))[3] == 0x74320FED) -#endif - result = 1; - } -#ifdef _MSC_VER - __except (EXCEPTION_EXECUTE_HANDLER) - { - // ignore error if SHA instructions not supported - } -#else - signal(SIGILL, oldHandler); -#endif - - return result; -} +extern int TrySHA256(); #endif static BOOL CheckSHA256Support() { #if CRYPTOPP_BOOL_X64 && CRYPTOPP_SHANI_AVAILABLE #if defined(_MSC_VER) // Windows with MSVC int cpuInfo[4] = { 0 }; __cpuidex(cpuInfo, 7, 0); return (cpuInfo[1] & (1 << 29)) != 0? TRUE : FALSE; #elif defined(__GNUC__) || defined(__clang__) // Linux, FreeBSD, macOS with GCC/Clang unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0; // First check if CPUID leaf 7 is supported if (__get_cpuid(0, &eax, &ebx, &ecx, &edx)) { if (eax >= 7) { // Now check SHA-256 support in leaf 7, sub-leaf 0 if (__get_cpuid_count(7, 0, &eax, &ebx, &ecx, &edx)) { return (ebx & (1 << 29)) != 0? TRUE : FALSE; } } } return FALSE; #else #error "Unsupported compiler" #endif #else return FALSE; #endif } diff --git a/src/Crypto/wolfCrypt.c b/src/Crypto/wolfCrypt.c index 4a4946a6..da0fbe2f 100644 --- a/src/Crypto/wolfCrypt.c +++ b/src/Crypto/wolfCrypt.c @@ -205,39 +205,39 @@ void sha256(unsigned char * result, const unsigned char* source, uint_32t source wc_InitSha256(&sha256); wc_Sha256Update(&sha256, source, sourceLen); wc_Sha256Final(&sha256, result); wc_Sha256Free(&sha256); } void sha512_begin(sha512_ctx* ctx) { wc_InitSha512(ctx); } void sha512_hash(const unsigned char * source, uint_64t sourceLen, sha512_ctx *ctx) { wc_Sha512Update(ctx, source, sourceLen); } void sha512_end(unsigned char * result, sha512_ctx* ctx) { wc_Sha512Final(ctx, result); } void sha512(unsigned char * result, const unsigned char* source, uint_64t sourceLen) { wc_Sha512 sha512; wc_InitSha512(&sha512); wc_Sha512Update(&sha512, source, sourceLen); wc_Sha512Final(&sha512, result); wc_Sha512Free(&sha512); } -void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) { +void derive_key_sha512 (unsigned char *pwd, int pwd_len, unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) { (void) iterations; wc_HKDF(WC_SHA512, (uint8*)pwd, (word32)pwd_len, (uint8*)salt, (word32)salt_len, NULL, 0, (uint8*)dk, (word32)dklen); } -void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) { +void derive_key_sha256 (unsigned char *pwd, int pwd_len, unsigned char *salt, int salt_len, uint32 iterations, unsigned char *dk, int dklen) { (void) iterations; wc_HKDF(WC_SHA256, (uint8*)pwd, (word32)pwd_len, (uint8*)salt, (word32)salt_len, NULL, 0, (uint8*)dk, (word32)dklen); } diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index 6fda3c37..140c31d1 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -332,125 +332,119 @@ static void InvalidateDriveFilterKeys (DriveFilterExtension *Extension) static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, uint8* ioBuffer /* ioBuffer must be at least 512 bytes long */) { NTSTATUS status; LARGE_INTEGER offset; WHIRLPOOL_CTX whirlpool; sha512_ctx sha2; ULONG bytesToRead, remainingBytes, bootloaderTotalSize = TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE; // clear fingerprint burn (BootLoaderFingerprint, sizeof (BootLoaderFingerprint)); // compute Whirlpool+SHA512 fingerprint of bootloader including MBR // we skip user configuration fields: // TC_BOOT_SECTOR_PIM_VALUE_OFFSET = 400 // TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402 // => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4 // TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = 406 // => TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH = 24 // TC_BOOT_SECTOR_USER_CONFIG_OFFSET = 438 // // we have: TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE WHIRLPOOL_init (&whirlpool); sha512_begin (&sha2); // read the first 512 bytes offset.QuadPart = 0; status = TCReadDevice (LowerDeviceObject, ioBuffer, offset, TC_SECTOR_SIZE_BIOS); if (NT_SUCCESS (status)) { +#ifndef _M_ARM64 NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; -#ifdef _WIN64 XSTATE_SAVE SaveState; if (IsCpuIntel() && HasSAVX()) saveStatus = KeSaveExtendedProcessorStateVC(XSTATE_MASK_GSSE, &SaveState); -#else - KFLOATING_SAVE floatingPointState; - if (HasISSE() || (HasSSSE3() && HasMMX())) - saveStatus = KeSaveFloatingPointState (&floatingPointState); #endif WHIRLPOOL_add (ioBuffer, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &whirlpool); WHIRLPOOL_add (ioBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &whirlpool); sha512_hash (ioBuffer, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2); sha512_hash (ioBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2); // we has the reste of the bootloader, 512 bytes at a time offset.QuadPart = TC_SECTOR_SIZE_BIOS; remainingBytes = bootloaderTotalSize - TC_SECTOR_SIZE_BIOS; while (NT_SUCCESS (status) && (remainingBytes > 0)) { bytesToRead = (remainingBytes >= TC_SECTOR_SIZE_BIOS)? TC_SECTOR_SIZE_BIOS : remainingBytes; status = TCReadDevice (LowerDeviceObject, ioBuffer, offset, bytesToRead); if (NT_SUCCESS (status)) { remainingBytes -= bytesToRead; offset.QuadPart += bytesToRead; WHIRLPOOL_add (ioBuffer, bytesToRead, &whirlpool); sha512_hash (ioBuffer, bytesToRead, &sha2); } else { Dump ("TCReadDevice error %x during ComputeBootLoaderFingerprint call\n", status); break; } } if (NT_SUCCESS (status)) { WHIRLPOOL_finalize (&whirlpool, BootLoaderFingerprint); sha512_end (&BootLoaderFingerprint [WHIRLPOOL_DIGESTSIZE], &sha2); } - if (NT_SUCCESS (saveStatus)) -#ifdef _WIN64 +#ifndef _M_ARM64 + if (NT_SUCCESS(saveStatus)) KeRestoreExtendedProcessorStateVC(&SaveState); -#else - KeRestoreFloatingPointState (&floatingPointState); #endif } else { Dump ("TCReadDevice error %x during ComputeBootLoaderFingerprint call\n", status); } } static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, uint32 *headerSaltCrc32) { BOOL hiddenVolume = (BootArgs.HiddenSystemPartitionStart != 0); int64 hiddenHeaderOffset = BootArgs.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET; NTSTATUS status; LARGE_INTEGER offset; - char *header; + unsigned char *header; int pkcs5_prf = 0, pim = 0; PARTITION_INFORMATION_EX pi; BOOL bIsGPT = FALSE; Dump ("MountDrive pdo=%p\n", Extension->Pdo); ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); // Check disk MBR id and GPT ID if BootSecRegion is available to detect boot drive if (BootSecRegionData != NULL && BootSecRegionSize >= 1024) { uint8 mbr[TC_SECTOR_SIZE_BIOS]; DCS_DISK_ENTRY_LIST* DeList = (DCS_DISK_ENTRY_LIST*)(BootSecRegionData + 512); offset.QuadPart = 0; status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS); if (NT_SUCCESS (status) && DeList->DE[DE_IDX_DISKID].DiskId.MbrID != *(uint32 *) (mbr + 0x1b8)) return STATUS_UNSUCCESSFUL; offset.QuadPart = 512; status = TCReadDevice (Extension->LowerDeviceObject, mbr, offset, TC_SECTOR_SIZE_BIOS); if (NT_SUCCESS (status) && memcmp(&DeList->DE[DE_IDX_DISKID].DiskId.GptID, mbr + 0x38, sizeof(DCS_GUID)) != 0) return STATUS_UNSUCCESSFUL; header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); if (!header) return STATUS_INSUFFICIENT_RESOURCES; // Copy header from SecRegion instead of read from disk memcpy(header, BootSecRegionData, 512); // Set SecRegion data for the disk (sectors to substitute to hide GPT table) Extension->Queue.SecRegionData = BootSecRegionData; @@ -635,73 +629,66 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, { Extension->SystemStorageDeviceNumber = storageDeviceNumber.DeviceNumber; Extension->SystemStorageDeviceNumberValid = TRUE; } } status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &BootDriveLength, sizeof (BootDriveLength)); if (!NT_SUCCESS (status)) { Dump ("Failed to get drive length - error %x\n", status); BootDriveLength.QuadPart = 0; Extension->Queue.MaxReadAheadOffset.QuadPart = 0; } else Extension->Queue.MaxReadAheadOffset = BootDriveLength; /* encrypt keys */ #ifdef _WIN64 if (IsRamEncryptionEnabled()) { VcProtectKeys (Extension->HeaderCryptoInfo, VcGetEncryptionID (Extension->HeaderCryptoInfo)); VcProtectKeys (Extension->Queue.CryptoInfo, VcGetEncryptionID (Extension->Queue.CryptoInfo)); } #endif status = EncryptedIoQueueStart (&Extension->Queue); if (!NT_SUCCESS (status)) TC_BUG_CHECK (status); - if (IsOSAtLeast (WIN_VISTA)) + CrashDumpEnabled = TRUE; + HibernationEnabled = TRUE; + if (IsRamEncryptionEnabled()) { - CrashDumpEnabled = TRUE; - HibernationEnabled = TRUE; -#ifdef _WIN64 - if (IsRamEncryptionEnabled()) - { - HibernationEnabled = FALSE; - } -#endif + HibernationEnabled = FALSE; } - else if (!LegacyHibernationDriverFilterActive) - StartLegacyHibernationDriverFilter(); // Hidden system hibernation is not supported if an extra boot partition is present as the system is not allowed to update the boot partition if (IsHiddenSystemRunning() && (BootArgs.Flags & TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION)) { CrashDumpEnabled = FALSE; HibernationEnabled = FALSE; } } else { Dump ("Header not decrypted\n"); crypto_close (Extension->HeaderCryptoInfo); Extension->HeaderCryptoInfo = NULL; status = STATUS_UNSUCCESSFUL; } ret: TCfree (header); return status; } static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension) { NTSTATUS status = STATUS_SUCCESS; LARGE_INTEGER offset; uint8 *header; header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); @@ -839,60 +826,61 @@ static void CheckDeviceTypeAndMount (DriveFilterExtension *filterExtension) && IsVolumeDevice (filterExtension->LowerDeviceObject)) { Dump ("Drive and volume merged pdo=%p", filterExtension->Pdo); filterExtension->IsVolumeFilterDevice = TRUE; filterExtension->IsDriveFilterDevice = FALSE; } else { NTSTATUS status = KeWaitForMutexObject (&MountMutex, Executive, KernelMode, FALSE, NULL); if (!NT_SUCCESS (status)) TC_BUG_CHECK (status); if (!BootDriveFound) { Password bootPass = {0}; bootPass.Length = BootArgs.BootPassword.Length; memcpy (bootPass.Text, BootArgs.BootPassword.Text, BootArgs.BootPassword.Length); MountDrive (filterExtension, &bootPass, &BootArgs.HeaderSaltCrc32); burn (&bootPass, sizeof (bootPass)); } KeReleaseMutex (&MountMutex, FALSE); } } } static VOID MountDriveWorkItemRoutine (PDEVICE_OBJECT deviceObject, DriveFilterExtension *filterExtension) { + UNREFERENCED_PARAMETER(deviceObject); CheckDeviceTypeAndMount (filterExtension); KeSetEvent (&filterExtension->MountWorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP Irp, DriveFilterExtension *Extension) { if (Irp->PendingReturned) IoMarkIrpPending (Irp); if (Extension->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) filterDeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA; if (KeGetCurrentIrql() == PASSIVE_LEVEL) { CheckDeviceTypeAndMount (Extension); } else { PIO_WORKITEM workItem = IoAllocateWorkItem (filterDeviceObject); if (!workItem) { IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return STATUS_INSUFFICIENT_RESOURCES; } KeInitializeEvent (&Extension->MountWorkItemCompletedEvent, SynchronizationEvent, FALSE); IoQueueWorkItem (workItem, MountDriveWorkItemRoutine, DelayedWorkQueue, Extension); KeWaitForSingleObject (&Extension->MountWorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); @@ -956,111 +944,112 @@ static NTSTATUS DispatchPnp (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterE IoReleaseRemoveLockAndWait (&Extension->Queue.RemoveLock, Irp); status = PassIrp (Extension->LowerDeviceObject, Irp); IoDetachDevice (Extension->LowerDeviceObject); if (Extension->DriveMounted) DismountDrive (Extension, TRUE); if (Extension->BootDrive) { BootDriveFound = FALSE; BootDriveFilterExtension = NULL; } IoDeleteDevice (DeviceObject); return status; default: status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); } return status; } static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { NTSTATUS status; + UNREFERENCED_PARAMETER(DeviceObject); Dump ("IRP_MJ_POWER minor=%d type=%d shutdown=%d\n", (int) irpSp->MinorFunction, (int) irpSp->Parameters.Power.Type, (int) irpSp->Parameters.Power.ShutdownType); if (SetupInProgress && irpSp->MinorFunction == IRP_MN_SET_POWER && irpSp->Parameters.Power.ShutdownType == PowerActionHibernate) { while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP, NULL, 0, NULL, 0) == STATUS_INSUFFICIENT_RESOURCES); } // Dismount the system drive on shutdown on Windows 7 and later if (DriverShuttingDown && EraseKeysOnShutdown && IsOSAtLeast (WIN_7) && Extension->BootDrive && Extension->DriveMounted && irpSp->MinorFunction == IRP_MN_SET_POWER && irpSp->Parameters.Power.Type == DevicePowerState) { DismountDrive (Extension, TRUE); #ifdef _WIN64 ClearSecurityParameters (); #endif } PoStartNextPowerIrp (Irp); status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); IoSkipCurrentIrpStackLocation (Irp); status = PoCallDriver (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, DriveFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { BOOL bBlockTrim = BlockSystemTrimCommand || IsHiddenSystemRunning(); NTSTATUS status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); + UNREFERENCED_PARAMETER(DeviceObject); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: Dump ("DriverFilter-DispatchControl: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); if (bBlockTrim) { - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); DWORD inputLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; if (inputLength >= sizeof (DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) { PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pInputAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer; DEVICE_DATA_MANAGEMENT_SET_ACTION action = pInputAttrs->Action; if (action == DeviceDsmAction_Trim) { Dump ("DriverFilter-DispatchControl: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DeviceDsmAction_Trim.\n"); if (bBlockTrim) { Dump ("DriverFilter-DispatchControl:: TRIM command blocked.\n"); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); } } } } break; case IOCTL_DISK_GROW_PARTITION: Dump ("DriverFilter-DispatchControl: IOCTL_DISK_GROW_PARTITION blocked\n"); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, STATUS_UNSUCCESSFUL, 0); break; } status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } @@ -1082,159 +1071,155 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) { status = EncryptedIoQueueAddIrp (&Extension->Queue, Irp); if (status != STATUS_PENDING) TCCompleteDiskIrp (Irp, status, 0); return status; } break; case IRP_MJ_PNP: return DispatchPnp (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_POWER: return DispatchPower (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_DEVICE_CONTROL: return DispatchControl (DeviceObject, Irp, Extension, irpSp); } status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } -void EmergencyClearAllKeys (PIRP irp, PIO_STACK_LOCATION irpSp) +void EmergencyClearAllKeys (PIRP irp) { irp->IoStatus.Information = 0; if (!IoIsSystemThread (PsGetCurrentThread()) && !UserCanAccessDriveDevice()) { irp->IoStatus.Status = STATUS_ACCESS_DENIED; } else { int drive; for (drive = MIN_MOUNTED_VOLUME_DRIVE_NUMBER; drive <= MAX_MOUNTED_VOLUME_DRIVE_NUMBER; ++drive) { PDEVICE_OBJECT device = GetVirtualVolumeDeviceObject (drive); if (device) { PEXTENSION extension = (PEXTENSION) device->DeviceExtension; if (extension) { InvalidateVolumeKeys (extension); } } } if (BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted) InvalidateDriveFilterKeys (BootDriveFilterExtension); -#ifdef _WIN64 ClearSecurityParameters(); -#endif irp->IoStatus.Status = STATUS_SUCCESS; } } -void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) +void ReopenBootVolumeHeader (PIRP irp) { LARGE_INTEGER offset; - char *header; + unsigned char *header; ReopenBootVolumeHeaderRequest *request = (ReopenBootVolumeHeaderRequest *) irp->AssociatedIrp.SystemBuffer; irp->IoStatus.Information = 0; if (!IoIsSystemThread (PsGetCurrentThread()) && !UserCanAccessDriveDevice()) { irp->IoStatus.Status = STATUS_ACCESS_DENIED; return; } if (!ValidateIOBufferSize (irp, sizeof (ReopenBootVolumeHeaderRequest), ValidateInput)) return; if (!BootDriveFound || !BootDriveFilterExtension || !BootDriveFilterExtension->DriveMounted || !BootDriveFilterExtension->HeaderCryptoInfo || request->VolumePassword.Length > MAX_LEGACY_PASSWORD || request->pkcs5_prf < 0 || request->pkcs5_prf > LAST_PRF_ID || request->pim < 0 || request->pim > 65535 ) { irp->IoStatus.Status = STATUS_INVALID_PARAMETER; goto wipe; } header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); if (!header) { irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; goto wipe; } if (BootDriveFilterExtension->HiddenSystem) offset.QuadPart = BootArgs.HiddenSystemPartitionStart + TC_HIDDEN_VOLUME_HEADER_OFFSET; else offset.QuadPart = TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET; irp->IoStatus.Status = TCReadDevice (BootDriveFilterExtension->LowerDeviceObject, header, offset, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); if (!NT_SUCCESS (irp->IoStatus.Status)) { Dump ("TCReadDevice error %x\n", irp->IoStatus.Status); goto ret; } -#ifdef _WIN64 if (IsRamEncryptionEnabled()) { VcUnprotectKeys (BootDriveFilterExtension->HeaderCryptoInfo, VcGetEncryptionID (BootDriveFilterExtension->HeaderCryptoInfo)); } -#endif if (ReadVolumeHeader (!BootDriveFilterExtension->HiddenSystem, header, &request->VolumePassword, request->pkcs5_prf, request->pim, NULL, BootDriveFilterExtension->HeaderCryptoInfo) == 0) { Dump ("Header reopened\n"); -#ifdef _WIN64 + if (IsRamEncryptionEnabled()) { VcProtectKeys (BootDriveFilterExtension->HeaderCryptoInfo, VcGetEncryptionID(BootDriveFilterExtension->HeaderCryptoInfo)); } -#endif + ComputeBootLoaderFingerprint (BootDriveFilterExtension->LowerDeviceObject, header); BootDriveFilterExtension->Queue.CryptoInfo->pkcs5 = BootDriveFilterExtension->HeaderCryptoInfo->pkcs5; BootDriveFilterExtension->Queue.CryptoInfo->noIterations = BootDriveFilterExtension->HeaderCryptoInfo->noIterations; BootDriveFilterExtension->Queue.CryptoInfo->volumePim = BootDriveFilterExtension->HeaderCryptoInfo->volumePim; irp->IoStatus.Status = STATUS_SUCCESS; } else { crypto_close (BootDriveFilterExtension->HeaderCryptoInfo); BootDriveFilterExtension->HeaderCryptoInfo = NULL; Dump ("Header not reopened\n"); irp->IoStatus.Status = STATUS_INVALID_PARAMETER; } ret: TCfree (header); wipe: burn (request, sizeof (*request)); } // Legacy Windows XP/2003 hibernation dump filter typedef NTSTATUS (*HiberDriverWriteFunctionA) (ULONG arg0, PLARGE_INTEGER writeOffset, PMDL dataMdl, PVOID arg3); typedef NTSTATUS (*HiberDriverWriteFunctionB) (PLARGE_INTEGER writeOffset, PMDL dataMdl); typedef struct @@ -1431,192 +1416,139 @@ static NTSTATUS HiberDriverEntryFilter (int filterNumber, PVOID arg0, HiberDrive hiberDriverContext->PartitionStartOffset.QuadPart += BootDriveFilterExtension->Queue.RemappedAreaOffset; } return STATUS_SUCCESS; } static NTSTATUS HiberDriverEntryFilter0 (PVOID arg0, HiberDriverContext *hiberDriverContext) { return HiberDriverEntryFilter (0, arg0, hiberDriverContext); } static NTSTATUS HiberDriverEntryFilter1 (PVOID arg0, HiberDriverContext *hiberDriverContext) { return HiberDriverEntryFilter (1, arg0, hiberDriverContext); } static NTSTATUS HiberDriverEntryFilter2 (PVOID arg0, HiberDriverContext *hiberDriverContext) { return HiberDriverEntryFilter (2, arg0, hiberDriverContext); } static VOID LoadImageNotifyRoutine (PUNICODE_STRING fullImageName, HANDLE processId, PIMAGE_INFO imageInfo) { ModuleTableItem *moduleItem; LIST_ENTRY *listEntry; KIRQL origIrql; + UNREFERENCED_PARAMETER(fullImageName); + UNREFERENCED_PARAMETER(processId); if (!imageInfo || !imageInfo->SystemModeImage || !imageInfo->ImageBase || !TCDriverObject->DriverSection) return; moduleItem = *(ModuleTableItem **) TCDriverObject->DriverSection; if (!moduleItem || !moduleItem->ModuleList.Flink) return; // Search loaded system modules for hibernation driver origIrql = KeRaiseIrqlToDpcLevel(); for (listEntry = moduleItem->ModuleList.Flink->Blink; listEntry && listEntry != TCDriverObject->DriverSection; listEntry = listEntry->Flink) { moduleItem = CONTAINING_RECORD (listEntry, ModuleTableItem, ModuleList); if (moduleItem && imageInfo->ImageBase == moduleItem->ModuleBaseAddress) { if (moduleItem->ModuleName.Buffer && moduleItem->ModuleName.Length >= 5 * sizeof (wchar_t)) { if (memcmp (moduleItem->ModuleName.Buffer, L"hiber", 5 * sizeof (wchar_t)) == 0 || memcmp (moduleItem->ModuleName.Buffer, L"Hiber", 5 * sizeof (wchar_t)) == 0 || memcmp (moduleItem->ModuleName.Buffer, L"HIBER", 5 * sizeof (wchar_t)) == 0) { HiberDriverEntry filterEntry; switch (LastHiberFilterNumber) { case 0: filterEntry = HiberDriverEntryFilter0; break; case 1: filterEntry = HiberDriverEntryFilter1; break; case 2: filterEntry = HiberDriverEntryFilter2; break; default: TC_THROW_FATAL_EXCEPTION; } if (moduleItem->ModuleEntryAddress != filterEntry) { // Install filter OriginalHiberDriverEntries[LastHiberFilterNumber] = moduleItem->ModuleEntryAddress; moduleItem->ModuleEntryAddress = filterEntry; if (++LastHiberFilterNumber > TC_MAX_HIBER_FILTER_COUNT - 1) LastHiberFilterNumber = 0; } } } break; } } KeLowerIrql (origIrql); } -void StartLegacyHibernationDriverFilter () -{ - PHYSICAL_ADDRESS highestAcceptableWriteBufferAddr; - NTSTATUS status; - - ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); - ASSERT (!IsOSAtLeast (WIN_VISTA)); - - if (!TCDriverObject->DriverSection || !*(ModuleTableItem **) TCDriverObject->DriverSection) - goto err; - - // All buffers required for hibernation must be allocated here -#ifdef _WIN64 - highestAcceptableWriteBufferAddr.QuadPart = 0x7FFffffFFFFULL; -#else - highestAcceptableWriteBufferAddr.QuadPart = 0xffffFFFFULL; -#endif - - HibernationWriteBuffer = MmAllocateContiguousMemory (TC_HIBERNATION_WRITE_BUFFER_SIZE, highestAcceptableWriteBufferAddr); - if (!HibernationWriteBuffer) - goto err; - - HibernationWriteBufferMdl = IoAllocateMdl (HibernationWriteBuffer, TC_HIBERNATION_WRITE_BUFFER_SIZE, FALSE, FALSE, NULL); - if (!HibernationWriteBufferMdl) - goto err; - - MmBuildMdlForNonPagedPool (HibernationWriteBufferMdl); - - status = PsSetLoadImageNotifyRoutine (LoadImageNotifyRoutine); - if (!NT_SUCCESS (status)) - goto err; - - LegacyHibernationDriverFilterActive = TRUE; - CrashDumpEnabled = FALSE; - HibernationEnabled = TRUE; - return; - -err: - LegacyHibernationDriverFilterActive = FALSE; - CrashDumpEnabled = FALSE; - HibernationEnabled = FALSE; - - if (HibernationWriteBufferMdl) - { - IoFreeMdl (HibernationWriteBufferMdl); - HibernationWriteBufferMdl = NULL; - } - - if (HibernationWriteBuffer) - { - MmFreeContiguousMemory (HibernationWriteBuffer); - HibernationWriteBuffer = NULL; - } -} - - static VOID SetupThreadProc (PVOID threadArg) { DriveFilterExtension *Extension = BootDriveFilterExtension; LARGE_INTEGER offset; UINT64_STRUCT dataUnit; ULONG setupBlockSize = TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE; BOOL headerUpdateRequired = FALSE; int64 bytesWrittenSinceHeaderUpdate = 0; uint8 *buffer = NULL; uint8 *wipeBuffer = NULL; uint8 wipeRandChars[TC_WIPE_RAND_CHAR_COUNT]; uint8 wipeRandCharsUpdate[TC_WIPE_RAND_CHAR_COUNT]; KIRQL irql; NTSTATUS status; // generate real random values for wipeRandChars and // wipeRandCharsUpdate instead of relying on uninitialized stack memory ChaCha20RngCtx rngCtx; uint8 pbSeed[CHACHA20RNG_KEYSZ + CHACHA20RNG_IVSZ]; + UNREFERENCED_PARAMETER(threadArg); GetDriverRandomSeed (pbSeed, sizeof (pbSeed)); ChaCha20RngInit (&rngCtx, pbSeed, GetDriverRandomSeed, 0); ChaCha20RngGetBytes (&rngCtx, wipeRandChars, TC_WIPE_RAND_CHAR_COUNT); ChaCha20RngGetBytes (&rngCtx, wipeRandCharsUpdate, TC_WIPE_RAND_CHAR_COUNT); burn (&rngCtx, sizeof (rngCtx)); FAST_ERASE64 (pbSeed, sizeof (pbSeed)); SetupResult = STATUS_UNSUCCESSFUL; // Make sure volume header can be updated if (Extension->HeaderCryptoInfo == NULL) { SetupResult = STATUS_INVALID_PARAMETER; goto ret; } buffer = TCalloc (TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE); if (!buffer) { SetupResult = STATUS_INSUFFICIENT_RESOURCES; goto ret; } if (SetupRequest.SetupMode == SetupEncryption && SetupRequest.WipeAlgorithm != TC_WIPE_NONE) { wipeBuffer = TCalloc (TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE); if (!wipeBuffer) @@ -1924,99 +1856,99 @@ NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_ST NTSTATUS status; if (!UserCanAccessDriveDevice()) return STATUS_ACCESS_DENIED; if (SetupInProgress || !BootDriveFound || !BootDriveFilterExtension || !BootDriveFilterExtension->DriveMounted || BootDriveFilterExtension->HiddenSystem || irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof (BootEncryptionSetupRequest)) return STATUS_INVALID_PARAMETER; if (EncryptionSetupThread) AbortBootEncryptionSetup(); SetupRequest = *(BootEncryptionSetupRequest *) irp->AssociatedIrp.SystemBuffer; EncryptionSetupThreadAbortRequested = FALSE; KeInitializeSpinLock (&SetupStatusSpinLock); SetupStatusEncryptedAreaEnd = BootDriveFilterExtension ? BootDriveFilterExtension->Queue.EncryptedAreaEnd : -1; SetupInProgress = TRUE; status = TCStartThread (SetupThreadProc, DeviceObject, &EncryptionSetupThread); if (!NT_SUCCESS (status)) SetupInProgress = FALSE; return status; } -void GetBootDriveVolumeProperties (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootDriveVolumeProperties (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (VOLUME_PROPERTIES_STRUCT), ValidateOutput)) { DriveFilterExtension *Extension = BootDriveFilterExtension; VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) irp->AssociatedIrp.SystemBuffer; memset (prop, 0, sizeof (*prop)); if (!BootDriveFound || !Extension || !Extension->DriveMounted) { irp->IoStatus.Status = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; } else { prop->hiddenVolume = Extension->Queue.CryptoInfo->hiddenVolume; prop->diskLength = Extension->ConfiguredEncryptedAreaEnd + 1 - Extension->ConfiguredEncryptedAreaStart; prop->ea = Extension->Queue.CryptoInfo->ea; prop->mode = Extension->Queue.CryptoInfo->mode; prop->pkcs5 = Extension->Queue.CryptoInfo->pkcs5; prop->pkcs5Iterations = Extension->Queue.CryptoInfo->noIterations; prop->volumePim = Extension->Queue.CryptoInfo->volumePim; #if 0 prop->volumeCreationTime = Extension->Queue.CryptoInfo->volume_creation_time; prop->headerCreationTime = Extension->Queue.CryptoInfo->header_creation_time; #endif prop->volFormatVersion = Extension->Queue.CryptoInfo->LegacyVolume ? TC_VOLUME_FORMAT_VERSION_PRE_6_0 : TC_VOLUME_FORMAT_VERSION; prop->totalBytesRead = Extension->Queue.TotalBytesRead; prop->totalBytesWritten = Extension->Queue.TotalBytesWritten; irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT); irp->IoStatus.Status = STATUS_SUCCESS; } } } -void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootEncryptionStatus (PIRP irp) { /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */ if (ValidateIOBufferSize (irp, sizeof (BootEncryptionStatus), ValidateOutput)) { DriveFilterExtension *Extension = BootDriveFilterExtension; BootEncryptionStatus *bootEncStatus = (BootEncryptionStatus *) irp->AssociatedIrp.SystemBuffer; memset (bootEncStatus, 0, sizeof (*bootEncStatus)); if (BootArgsValid) bootEncStatus->BootLoaderVersion = BootArgs.BootLoaderVersion; bootEncStatus->DeviceFilterActive = DeviceFilterActive; bootEncStatus->SetupInProgress = SetupInProgress; bootEncStatus->SetupMode = SetupRequest.SetupMode; bootEncStatus->TransformWaitingForIdle = TransformWaitingForIdle; if (!BootDriveFound || !Extension || !Extension->DriveMounted) { bootEncStatus->DriveEncrypted = FALSE; bootEncStatus->DriveMounted = FALSE; bootEncStatus->VolumeHeaderPresent = FALSE; } else { bootEncStatus->DriveMounted = Extension->DriveMounted; bootEncStatus->VolumeHeaderPresent = Extension->VolumeHeaderPresent; bootEncStatus->DriveEncrypted = Extension->Queue.EncryptedAreaStart != -1; bootEncStatus->BootDriveLength = BootDriveLength; @@ -2024,121 +1956,121 @@ void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp) bootEncStatus->ConfiguredEncryptedAreaEnd = Extension->ConfiguredEncryptedAreaEnd; bootEncStatus->EncryptedAreaStart = Extension->Queue.EncryptedAreaStart; bootEncStatus->MasterKeyVulnerable = Extension->HeaderCryptoInfo->bVulnerableMasterKey; if (SetupInProgress) { KIRQL irql; KeAcquireSpinLock (&SetupStatusSpinLock, &irql); bootEncStatus->EncryptedAreaEnd = SetupStatusEncryptedAreaEnd; KeReleaseSpinLock (&SetupStatusSpinLock, irql); } else bootEncStatus->EncryptedAreaEnd = Extension->Queue.EncryptedAreaEnd; bootEncStatus->VolumeHeaderSaltCrc32 = Extension->VolumeHeaderSaltCrc32; bootEncStatus->HibernationPreventionCount = HibernationPreventionCount; bootEncStatus->HiddenSysLeakProtectionCount = HiddenSysLeakProtectionCount; bootEncStatus->HiddenSystem = Extension->HiddenSystem; if (Extension->HiddenSystem) bootEncStatus->HiddenSystemPartitionStart = BootArgs.HiddenSystemPartitionStart; } irp->IoStatus.Information = sizeof (BootEncryptionStatus); irp->IoStatus.Status = STATUS_SUCCESS; } } -void GetBootLoaderVersion (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootLoaderVersion (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (uint16), ValidateOutput)) { if (BootArgsValid) { *(uint16 *) irp->AssociatedIrp.SystemBuffer = BootArgs.BootLoaderVersion; irp->IoStatus.Information = sizeof (uint16); irp->IoStatus.Status = STATUS_SUCCESS; } else { irp->IoStatus.Status = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; } } } -void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootLoaderFingerprint (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (BootLoaderFingerprintRequest), ValidateOutput)) { irp->IoStatus.Information = 0; if (BootArgsValid && BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted && BootDriveFilterExtension->HeaderCryptoInfo) { BootLoaderFingerprintRequest *bootLoaderFingerprint = (BootLoaderFingerprintRequest *) irp->AssociatedIrp.SystemBuffer; /* compute the fingerprint again and check if it is the same as the one retrieved during boot */ - char *header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); + unsigned char *header = TCalloc (TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); if (!header) { irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; } else { memcpy (bootLoaderFingerprint->Fingerprint, BootLoaderFingerprint, sizeof (BootLoaderFingerprint)); ComputeBootLoaderFingerprint (BootDriveFilterExtension->LowerDeviceObject, header); burn (header, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE); TCfree (header); if (0 == memcmp (bootLoaderFingerprint->Fingerprint, BootLoaderFingerprint, sizeof (BootLoaderFingerprint))) { irp->IoStatus.Information = sizeof (BootLoaderFingerprintRequest); irp->IoStatus.Status = STATUS_SUCCESS; } else { /* fingerprint mismatch.*/ irp->IoStatus.Status = STATUS_INVALID_IMAGE_HASH; } } } else { irp->IoStatus.Status = STATUS_INVALID_PARAMETER; } } } -void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetBootEncryptionAlgorithmName (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (GetBootEncryptionAlgorithmNameRequest), ValidateOutput)) { if (BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted) { wchar_t BootEncryptionAlgorithmNameW[256]; wchar_t BootPrfAlgorithmNameW[256]; GetBootEncryptionAlgorithmNameRequest *request = (GetBootEncryptionAlgorithmNameRequest *) irp->AssociatedIrp.SystemBuffer; EAGetName (BootEncryptionAlgorithmNameW, 256, BootDriveFilterExtension->Queue.CryptoInfo->ea, 0); HashGetName2 (BootPrfAlgorithmNameW, 256, BootDriveFilterExtension->Queue.CryptoInfo->pkcs5); RtlStringCbPrintfA (request->BootEncryptionAlgorithmName, sizeof (request->BootEncryptionAlgorithmName), "%S", BootEncryptionAlgorithmNameW); RtlStringCbPrintfA (request->BootPrfAlgorithmName, sizeof (request->BootPrfAlgorithmName), "%S", BootPrfAlgorithmNameW); irp->IoStatus.Information = sizeof (GetBootEncryptionAlgorithmNameRequest); irp->IoStatus.Status = STATUS_SUCCESS; } else { irp->IoStatus.Status = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; } } } NTSTATUS GetSetupResult() { return SetupResult; } @@ -2166,60 +2098,61 @@ DriveFilterExtension *GetBootDriveFilterExtension () { return BootDriveFilterExtension; } CRYPTO_INFO *GetSystemDriveCryptoInfo () { return BootDriveFilterExtension->Queue.CryptoInfo; } NTSTATUS AbortBootEncryptionSetup () { if (!IoIsSystemThread (PsGetCurrentThread()) && !UserCanAccessDriveDevice()) return STATUS_ACCESS_DENIED; if (EncryptionSetupThread) { EncryptionSetupThreadAbortRequested = TRUE; TCStopThread (EncryptionSetupThread, NULL); EncryptionSetupThread = NULL; } return STATUS_SUCCESS; } static VOID DecoySystemWipeThreadProc (PVOID threadArg) { + UNREFERENCED_PARAMETER(threadArg); DriveFilterExtension *Extension = BootDriveFilterExtension; LARGE_INTEGER offset; UINT64_STRUCT dataUnit; ULONG wipeBlockSize = TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE; CRYPTO_INFO *wipeCryptoInfo = NULL; uint8 *wipeBuffer = NULL; uint8 *wipeRandBuffer = NULL; uint8 wipeRandChars[TC_WIPE_RAND_CHAR_COUNT]; int wipePass, wipePassCount; int ea = Extension->Queue.CryptoInfo->ea; KIRQL irql; NTSTATUS status; DecoySystemWipeResult = STATUS_UNSUCCESSFUL; wipeBuffer = TCalloc (TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE); if (!wipeBuffer) { DecoySystemWipeResult = STATUS_INSUFFICIENT_RESOURCES; goto ret; } wipeRandBuffer = TCalloc (TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE); if (!wipeRandBuffer) { DecoySystemWipeResult = STATUS_INSUFFICIENT_RESOURCES; goto ret; @@ -2349,61 +2282,61 @@ NTSTATUS StartDecoySystemWipe (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_ return STATUS_SUCCESS; if (DecoySystemWipeThread) AbortDecoySystemWipe(); request = (WipeDecoySystemRequest *) irp->AssociatedIrp.SystemBuffer; WipeDecoyRequest = *request; burn (request->WipeKey, sizeof (request->WipeKey)); DecoySystemWipeThreadAbortRequested = FALSE; KeInitializeSpinLock (&DecoySystemWipeStatusSpinLock); DecoySystemWipedAreaEnd = BootDriveFilterExtension->ConfiguredEncryptedAreaStart; DecoySystemWipeInProgress = TRUE; status = TCStartThread (DecoySystemWipeThreadProc, DeviceObject, &DecoySystemWipeThread); if (!NT_SUCCESS (status)) DecoySystemWipeInProgress = FALSE; return status; } BOOL IsDecoySystemWipeInProgress() { return DecoySystemWipeInProgress; } -void GetDecoySystemWipeStatus (PIRP irp, PIO_STACK_LOCATION irpSp) +void GetDecoySystemWipeStatus (PIRP irp) { if (ValidateIOBufferSize (irp, sizeof (DecoySystemWipeStatus), ValidateOutput)) { DecoySystemWipeStatus *wipeStatus = (DecoySystemWipeStatus *) irp->AssociatedIrp.SystemBuffer; if (!IsHiddenSystemRunning()) { irp->IoStatus.Status = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; } else { wipeStatus->WipeInProgress = DecoySystemWipeInProgress; wipeStatus->WipeAlgorithm = WipeDecoyRequest.WipeAlgorithm; if (DecoySystemWipeInProgress) { KIRQL irql; KeAcquireSpinLock (&DecoySystemWipeStatusSpinLock, &irql); wipeStatus->WipedAreaEnd = DecoySystemWipedAreaEnd; KeReleaseSpinLock (&DecoySystemWipeStatusSpinLock, irql); } else wipeStatus->WipedAreaEnd = DecoySystemWipedAreaEnd; irp->IoStatus.Information = sizeof (DecoySystemWipeStatus); irp->IoStatus.Status = STATUS_SUCCESS; } } } diff --git a/src/Driver/DriveFilter.h b/src/Driver/DriveFilter.h index b164fa5b..307880fb 100644 --- a/src/Driver/DriveFilter.h +++ b/src/Driver/DriveFilter.h @@ -32,60 +32,59 @@ typedef struct _DriveFilterExtension ULONG SystemStorageDeviceNumber; BOOL SystemStorageDeviceNumberValid; int64 ConfiguredEncryptedAreaStart; int64 ConfiguredEncryptedAreaEnd; uint32 VolumeHeaderSaltCrc32; EncryptedIoQueue Queue; BOOL BootDrive; BOOL VolumeHeaderPresent; BOOL DriveMounted; KEVENT MountWorkItemCompletedEvent; CRYPTO_INFO *HeaderCryptoInfo; BOOL HiddenSystem; } DriveFilterExtension; #define TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER 0x5645524142455854 extern BOOL BootArgsValid; extern BootArguments BootArgs; extern PKTHREAD EncryptionSetupThread; extern PKTHREAD DecoySystemWipeThread; NTSTATUS AbortBootEncryptionSetup (); NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo); NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp); -void GetBootDriveVolumeProperties (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootEncryptionAlgorithmName (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootLoaderVersion (PIRP irp, PIO_STACK_LOCATION irpSp); -void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp); +void GetBootDriveVolumeProperties (PIRP irp); +void GetBootEncryptionAlgorithmName (PIRP irp); +void GetBootEncryptionStatus (PIRP irp); +void GetBootLoaderVersion (PIRP irp); +void GetBootLoaderFingerprint (PIRP irp); NTSTATUS GetSetupResult (); DriveFilterExtension *GetBootDriveFilterExtension (); CRYPTO_INFO *GetSystemDriveCryptoInfo (); BOOL IsBootDriveMounted (); BOOL IsBootEncryptionSetupInProgress (); BOOL IsHiddenSystemRunning (); NTSTATUS LoadBootArguments (BOOL bIsEfi); static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension); NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp); -void EmergencyClearAllKeys (PIRP irp, PIO_STACK_LOCATION irpSp); -void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp); +void EmergencyClearAllKeys (PIRP irp); +void ReopenBootVolumeHeader (PIRP irp); NTSTATUS StartDecoySystemWipe (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_LOCATION irpSp); -void StartLegacyHibernationDriverFilter (); NTSTATUS AbortDecoySystemWipe (); BOOL IsDecoySystemWipeInProgress(); NTSTATUS GetDecoySystemWipeResult(); -void GetDecoySystemWipeStatus (PIRP irp, PIO_STACK_LOCATION irpSp); +void GetDecoySystemWipeStatus (PIRP irp); uint64 GetBootDriveLength (); NTSTATUS WriteBootDriveSector (PIRP irp, PIO_STACK_LOCATION irpSp); #define TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE (1536 * 1024) #define TC_ENCRYPTION_SETUP_HEADER_UPDATE_THRESHOLD (64 * 1024 * 1024) #define TC_HIBERNATION_WRITE_BUFFER_SIZE (128 * 1024) #endif // TC_HEADER_DRIVER_DRIVE_FILTER diff --git a/src/Driver/DumpFilter.c b/src/Driver/DumpFilter.c index aa059d9d..94a130d9 100644 --- a/src/Driver/DumpFilter.c +++ b/src/Driver/DumpFilter.c @@ -131,133 +131,137 @@ NTSTATUS DumpFilterEntry (PFILTER_EXTENSION filterExtension, PFILTER_INITIALIZAT #ifdef _WIN64 highestAcceptableWriteBufferAddr.QuadPart = 0x7FFffffFFFFLL; #else highestAcceptableWriteBufferAddr.QuadPart = 0xffffFFFFLL; #endif WriteFilterBuffer = MmAllocateContiguousMemory (WriteFilterBufferSize, highestAcceptableWriteBufferAddr); if (!WriteFilterBuffer) { status = STATUS_INSUFFICIENT_RESOURCES; goto err; } filterInitData->DumpStart = DumpFilterStart; filterInitData->DumpWrite = DumpFilterWrite; filterInitData->DumpFinish = DumpFilterFinish; filterInitData->DumpUnload = DumpFilterUnload; Dump ("Dump filter loaded type=%d\n", filterExtension->DumpType); return STATUS_SUCCESS; err: Dump ("DumpFilterEntry error %x\n", status); return status; } static NTSTATUS DumpFilterStart (PFILTER_EXTENSION filterExtension) { + UNREFERENCED_PARAMETER(filterExtension); Dump ("DumpFilterStart type=%d\n", filterExtension->DumpType); if (BootDriveFilterExtension->MagicNumber != TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER) TC_BUG_CHECK (STATUS_CRC_ERROR); return BootDriveFilterExtension->DriveMounted ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; } static NTSTATUS DumpFilterWrite (PFILTER_EXTENSION filterExtension, PLARGE_INTEGER diskWriteOffset, PMDL writeMdl) { ULONG dataLength = MmGetMdlByteCount (writeMdl); uint64 offset = DumpPartitionOffset.QuadPart + diskWriteOffset->QuadPart; uint64 intersectStart; uint32 intersectLength; PVOID writeBuffer; CSHORT origMdlFlags; + UNREFERENCED_PARAMETER(filterExtension); if (BootDriveFilterExtension->MagicNumber != TC_BOOT_DRIVE_FILTER_EXTENSION_MAGIC_NUMBER) TC_BUG_CHECK (STATUS_CRC_ERROR); if (BootDriveFilterExtension->Queue.EncryptedAreaEndUpdatePending) // Hibernation should always abort the setup thread TC_BUG_CHECK (STATUS_INVALID_PARAMETER); if (BootDriveFilterExtension->Queue.EncryptedAreaStart == -1 || BootDriveFilterExtension->Queue.EncryptedAreaEnd == -1) return STATUS_SUCCESS; if (dataLength > WriteFilterBufferSize) TC_BUG_CHECK (STATUS_BUFFER_OVERFLOW); // Bug check is required as returning an error does not prevent data from being written to disk if ((dataLength & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); if ((offset & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); - writeBuffer = MmGetSystemAddressForMdlSafe (writeMdl, (HighPagePriority | ExDefaultMdlProtection)); + writeBuffer = MmGetSystemAddressForMdlSafe (writeMdl, (HighPagePriority | MdlMappingNoExecute)); if (!writeBuffer) TC_BUG_CHECK (STATUS_INSUFFICIENT_RESOURCES); memcpy (WriteFilterBuffer, writeBuffer, dataLength); GetIntersection (offset, dataLength, BootDriveFilterExtension->Queue.EncryptedAreaStart, BootDriveFilterExtension->Queue.EncryptedAreaEnd, &intersectStart, &intersectLength); if (intersectLength > 0) { UINT64_STRUCT dataUnit; dataUnit.Value = intersectStart / ENCRYPTION_DATA_UNIT_SIZE; if (BootDriveFilterExtension->Queue.RemapEncryptedArea) { diskWriteOffset->QuadPart += BootDriveFilterExtension->Queue.RemappedAreaOffset; dataUnit.Value += BootDriveFilterExtension->Queue.RemappedAreaDataUnitOffset; } EncryptDataUnitsCurrentThreadEx (WriteFilterBuffer + (intersectStart - offset), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, BootDriveFilterExtension->Queue.CryptoInfo); } origMdlFlags = writeMdl->MdlFlags; MmInitializeMdl (writeMdl, WriteFilterBuffer, dataLength); MmBuildMdlForNonPagedPool (writeMdl); // Instead of using MmGetSystemAddressForMdlSafe(), some buggy custom storage drivers may directly test MDL_MAPPED_TO_SYSTEM_VA flag, // disregarding the fact that other MDL flags may be set by the system or a dump filter (e.g. MDL_SOURCE_IS_NONPAGED_POOL flag only). // Therefore, to work around this issue, the original flags will be restored even if they do not match the new MDL. // MS BitLocker also uses this hack/workaround (it should be safe to use until the MDL structure is changed). writeMdl->MdlFlags = origMdlFlags; return STATUS_SUCCESS; } static NTSTATUS DumpFilterFinish (PFILTER_EXTENSION filterExtension) { + UNREFERENCED_PARAMETER(filterExtension); Dump ("DumpFilterFinish type=%d\n", filterExtension->DumpType); return STATUS_SUCCESS; } static NTSTATUS DumpFilterUnload (PFILTER_EXTENSION filterExtension) { + UNREFERENCED_PARAMETER(filterExtension); Dump ("DumpFilterUnload type=%d\n", filterExtension->DumpType); if (WriteFilterBuffer) { memset (WriteFilterBuffer, 0, WriteFilterBufferSize); MmFreeContiguousMemory (WriteFilterBuffer); WriteFilterBuffer = NULL; } return STATUS_SUCCESS; } diff --git a/src/Driver/EncryptedIoQueue.c b/src/Driver/EncryptedIoQueue.c index 8c2e8a41..61bfe7dd 100644 --- a/src/Driver/EncryptedIoQueue.c +++ b/src/Driver/EncryptedIoQueue.c @@ -613,61 +613,61 @@ static VOID MainThreadProc (PVOID threadArg) && !item->Write && item->OriginalLength > 0 && (item->OriginalLength & (ENCRYPTION_DATA_UNIT_SIZE - 1)) == 0 && (item->OriginalOffset.QuadPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)) != 0) { uint8 *buffer; ULONG alignedLength; LARGE_INTEGER alignedOffset; hResult = ULongAdd(item->OriginalLength, ENCRYPTION_DATA_UNIT_SIZE, &alignedLength); if (hResult != S_OK) { CompleteOriginalIrp (item, STATUS_INVALID_PARAMETER, 0); continue; } alignedOffset.QuadPart = item->OriginalOffset.QuadPart & ~((LONGLONG) ENCRYPTION_DATA_UNIT_SIZE - 1); buffer = TCalloc (alignedLength); if (!buffer) { CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0); continue; } item->Status = TCReadDevice (queue->LowerDeviceObject, buffer, alignedOffset, alignedLength); if (NT_SUCCESS (item->Status)) { UINT64_STRUCT dataUnit; - dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, (HighPagePriority | ExDefaultMdlProtection)); + dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, (HighPagePriority | MdlMappingNoExecute)); if (!dataBuffer) { TCfree (buffer); CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0); continue; } if (queue->EncryptedAreaStart != -1 && queue->EncryptedAreaEnd != -1) { GetIntersection (alignedOffset.QuadPart, alignedLength, queue->EncryptedAreaStart, queue->EncryptedAreaEnd, &intersectStart, &intersectLength); if (intersectLength > 0) { dataUnit.Value = intersectStart / ENCRYPTION_DATA_UNIT_SIZE; DecryptDataUnits (buffer + (intersectStart - alignedOffset.QuadPart), &dataUnit, intersectLength / ENCRYPTION_DATA_UNIT_SIZE, queue->CryptoInfo); } } // Update subst sectors if((queue->SecRegionData != NULL) && (queue->SecRegionSize > 512)) { UpdateBuffer(buffer, queue->SecRegionData, alignedOffset.QuadPart, alignedLength, TRUE); } memcpy (dataBuffer, buffer + (item->OriginalOffset.LowPart & (ENCRYPTION_DATA_UNIT_SIZE - 1)), item->OriginalLength); } TCfree (buffer); CompleteOriginalIrp (item, item->Status, NT_SUCCESS (item->Status) ? item->OriginalLength : 0); continue; } // Validate offset and length @@ -733,61 +733,61 @@ static VOID MainThreadProc (PVOID threadArg) continue; } } } else if (item->Write && RegionsOverlap (item->OriginalOffset.QuadPart, item->OriginalOffset.QuadPart + item->OriginalLength - 1, TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET + TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE - 1)) { // Prevent inappropriately designed software from damaging important data that may be out of sync with the backup on the Rescue Disk (such as the end of the encrypted area). Dump ("Preventing write to the system encryption key data area\n"); CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0); continue; } else if (item->Write && IsHiddenSystemRunning() && (RegionsOverlap (item->OriginalOffset.QuadPart, item->OriginalOffset.QuadPart + item->OriginalLength - 1, TC_SECTOR_SIZE_BIOS, TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS - 1) || RegionsOverlap (item->OriginalOffset.QuadPart, item->OriginalOffset.QuadPart + item->OriginalLength - 1, GetBootDriveLength(), _I64_MAX))) { Dump ("Preventing write to boot loader or host protected area\n"); CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0); continue; } else if (item->Write && (queue->SecRegionData != NULL) && (queue->SecRegionSize > 512) && UpdateBuffer (NULL, queue->SecRegionData, item->OriginalOffset.QuadPart, (uint32)(item->OriginalOffset.QuadPart + item->OriginalLength - 1), FALSE)) { // Prevent inappropriately designed software from damaging important data Dump ("Preventing write to the system GPT area\n"); CompleteOriginalIrp (item, STATUS_MEDIA_WRITE_PROTECTED, 0); continue; } - dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, (HighPagePriority | ExDefaultMdlProtection)); + dataBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe (irp->MdlAddress, (HighPagePriority | MdlMappingNoExecute)); if (dataBuffer == NULL) { CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0); continue; } // Divide data block to fragments to enable efficient overlapping of encryption and IO operations dataRemaining = item->OriginalLength; fragmentOffset = item->OriginalOffset; while (dataRemaining > 0) { ULONG queueFragmentSize = queue->FragmentSize; BOOL isLastFragment = dataRemaining <= queueFragmentSize; ULONG dataFragmentLength = isLastFragment ? dataRemaining : queueFragmentSize; activeFragmentBuffer = (activeFragmentBuffer == queue->FragmentBufferA ? queue->FragmentBufferB : queue->FragmentBufferA); InterlockedIncrement (&queue->IoThreadPendingRequestCount); // Create IO request request = GetPoolBuffer (queue, sizeof (EncryptedIoRequest)); if (!request) { CompleteOriginalIrp (item, STATUS_INSUFFICIENT_RESOURCES, 0); break; } request->Item = item; diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index 96f60cdd..0edc6941 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -127,63 +127,60 @@ BOOL SelfTestsPassed; int LastUniqueVolumeId; ULONG OsMajorVersion = 0; ULONG OsMinorVersion; BOOL DriverUnloadDisabled = FALSE; BOOL PortableMode = FALSE; BOOL VolumeClassFilterRegistered = FALSE; BOOL CacheBootPassword = FALSE; BOOL CacheBootPim = FALSE; BOOL NonAdminSystemFavoritesAccessDisabled = FALSE; BOOL BlockSystemTrimCommand = FALSE; BOOL AllowWindowsDefrag = FALSE; BOOL EraseKeysOnShutdown = TRUE; // by default, we erase encryption keys on system shutdown static size_t EncryptionThreadPoolFreeCpuCountLimit = 0; static BOOL SystemFavoriteVolumeDirty = FALSE; static BOOL PagingFileCreationPrevented = FALSE; static BOOL EnableExtendedIoctlSupport = FALSE; static BOOL AllowTrimCommand = FALSE; static BOOL RamEncryptionActivated = FALSE; static KeSaveExtendedProcessorStateFn KeSaveExtendedProcessorStatePtr = NULL; static KeRestoreExtendedProcessorStateFn KeRestoreExtendedProcessorStatePtr = NULL; static ExGetFirmwareEnvironmentVariableFn ExGetFirmwareEnvironmentVariablePtr = NULL; static KeQueryInterruptTimePreciseFn KeQueryInterruptTimePrecisePtr = NULL; static KeAreAllApcsDisabledFn KeAreAllApcsDisabledPtr = NULL; static KeSetSystemGroupAffinityThreadFn KeSetSystemGroupAffinityThreadPtr = NULL; static KeQueryActiveGroupCountFn KeQueryActiveGroupCountPtr = NULL; static KeQueryActiveProcessorCountExFn KeQueryActiveProcessorCountExPtr = NULL; int EncryptionIoRequestCount = 0; int EncryptionItemCount = 0; int EncryptionFragmentSize = 0; -POOL_TYPE ExDefaultNonPagedPoolType = NonPagedPool; -ULONG ExDefaultMdlProtection = 0; - PDEVICE_OBJECT VirtualVolumeDeviceObjects[MAX_MOUNTED_VOLUME_DRIVE_NUMBER + 1]; BOOL AlignValue (ULONG ulValue, ULONG ulAlignment, ULONG *pulResult) { BOOL bRet = FALSE; HRESULT hr; if (ulAlignment == 0) { *pulResult = ulValue; bRet = TRUE; } else { ulAlignment -= 1; hr = ULongAdd (ulValue, ulAlignment, &ulValue); if (S_OK == hr) { *pulResult = ulValue & (~ulAlignment); bRet = TRUE; } } return bRet; } BOOL IsUefiBoot () { BOOL bStatus = FALSE; NTSTATUS ntStatus = STATUS_NOT_IMPLEMENTED; @@ -214,237 +211,225 @@ BOOL IsUefiBoot () } void GetDriverRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed) { LARGE_INTEGER iSeed, iSeed2; uint8 digest[WHIRLPOOL_DIGESTSIZE]; WHIRLPOOL_CTX tctx; size_t count; #ifndef _WIN64 KFLOATING_SAVE floatingPointState; NTSTATUS saveStatus = STATUS_INVALID_PARAMETER; if (HasISSE()) saveStatus = KeSaveFloatingPointState (&floatingPointState); #endif while (cbRandSeed) { WHIRLPOOL_init (&tctx); // we hash current content of digest buffer which is uninitialized the first time WHIRLPOOL_add (digest, WHIRLPOOL_DIGESTSIZE, &tctx); // we use various time information as source of entropy KeQuerySystemTime( &iSeed ); WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); iSeed = KeQueryPerformanceCounter (&iSeed2); WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); WHIRLPOOL_add ((unsigned char *) &(iSeed2.QuadPart), sizeof(iSeed2.QuadPart), &tctx); if (KeQueryInterruptTimePrecisePtr) { - iSeed.QuadPart = KeQueryInterruptTimePrecisePtr (&iSeed2.QuadPart); + iSeed.QuadPart = KeQueryInterruptTimePrecisePtr ((PULONG64) & iSeed2.QuadPart); WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); WHIRLPOOL_add ((unsigned char *) &(iSeed2.QuadPart), sizeof(iSeed2.QuadPart), &tctx); } else { iSeed.QuadPart = KeQueryInterruptTime (); WHIRLPOOL_add ((unsigned char *) &(iSeed.QuadPart), sizeof(iSeed.QuadPart), &tctx); } /* use JitterEntropy library to get good quality random bytes based on CPU timing jitter */ if (0 == jent_entropy_init ()) { struct rand_data *ec = jent_entropy_collector_alloc (1, 0); if (ec) { ssize_t rndLen = jent_read_entropy (ec, (char*) digest, sizeof (digest)); if (rndLen > 0) WHIRLPOOL_add (digest, (unsigned int) rndLen, &tctx); jent_entropy_collector_free (ec); } } // use RDSEED or RDRAND from CPU as source of entropy if enabled if ( IsCpuRngEnabled() && ( (HasRDSEED() && RDSEED_getBytes (digest, sizeof (digest))) || (HasRDRAND() && RDRAND_getBytes (digest, sizeof (digest))) )) { WHIRLPOOL_add (digest, sizeof(digest), &tctx); } WHIRLPOOL_finalize (&tctx, digest); count = VC_MIN (cbRandSeed, sizeof (digest)); // copy digest value to seed buffer memcpy (pbRandSeed, digest, count); cbRandSeed -= count; pbRandSeed += count; } #if !defined (_WIN64) if (NT_SUCCESS (saveStatus)) KeRestoreFloatingPointState (&floatingPointState); #endif FAST_ERASE64 (digest, sizeof (digest)); FAST_ERASE64 (&iSeed.QuadPart, 8); FAST_ERASE64 (&iSeed2.QuadPart, 8); burn (&tctx, sizeof(tctx)); } -NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) +NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { PKEY_VALUE_PARTIAL_INFORMATION startKeyValue; LONG version; int i; - Dump ("DriverEntry " TC_APP_NAME " " VERSION_STRING VERSION_STRING_SUFFIX "\n"); - - DetectX86Features (); + Dump("DriverEntry " TC_APP_NAME " " VERSION_STRING VERSION_STRING_SUFFIX "\n"); - PsGetVersion (&OsMajorVersion, &OsMinorVersion, NULL, NULL); + DetectX86Features(); - Dump ("OsMajorVersion=%d OsMinorVersion=%d\n", OsMajorVersion, OsMinorVersion); + PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL); - // NX pool support is available starting from Windows 8 - if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 2)) - { - ExDefaultNonPagedPoolType = (POOL_TYPE) NonPagedPoolNx; - ExDefaultMdlProtection = MdlMappingNoExecute; - } + Dump("OsMajorVersion=%d OsMinorVersion=%d\n", OsMajorVersion, OsMinorVersion); // KeAreAllApcsDisabled is available starting from Windows Server 2003 if ((OsMajorVersion > 5) || (OsMajorVersion == 5 && OsMinorVersion >= 2)) { UNICODE_STRING KeAreAllApcsDisabledFuncName; RtlInitUnicodeString(&KeAreAllApcsDisabledFuncName, L"KeAreAllApcsDisabled"); - KeAreAllApcsDisabledPtr = (KeAreAllApcsDisabledFn) MmGetSystemRoutineAddress(&KeAreAllApcsDisabledFuncName); + KeAreAllApcsDisabledPtr = (KeAreAllApcsDisabledFn)MmGetSystemRoutineAddress(&KeAreAllApcsDisabledFuncName); } // KeSaveExtendedProcessorState/KeRestoreExtendedProcessorState are available starting from Windows 7 // KeQueryActiveGroupCount/KeQueryActiveProcessorCountEx/KeSetSystemGroupAffinityThread are available starting from Windows 7 if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 1)) { UNICODE_STRING saveFuncName, restoreFuncName, groupCountFuncName, procCountFuncName, setAffinityFuncName; RtlInitUnicodeString(&saveFuncName, L"KeSaveExtendedProcessorState"); RtlInitUnicodeString(&restoreFuncName, L"KeRestoreExtendedProcessorState"); RtlInitUnicodeString(&groupCountFuncName, L"KeQueryActiveGroupCount"); RtlInitUnicodeString(&procCountFuncName, L"KeQueryActiveProcessorCountEx"); RtlInitUnicodeString(&setAffinityFuncName, L"KeSetSystemGroupAffinityThread"); - KeSaveExtendedProcessorStatePtr = (KeSaveExtendedProcessorStateFn) MmGetSystemRoutineAddress(&saveFuncName); - KeRestoreExtendedProcessorStatePtr = (KeRestoreExtendedProcessorStateFn) MmGetSystemRoutineAddress(&restoreFuncName); - KeSetSystemGroupAffinityThreadPtr = (KeSetSystemGroupAffinityThreadFn) MmGetSystemRoutineAddress(&setAffinityFuncName); - KeQueryActiveGroupCountPtr = (KeQueryActiveGroupCountFn) MmGetSystemRoutineAddress(&groupCountFuncName); - KeQueryActiveProcessorCountExPtr = (KeQueryActiveProcessorCountExFn) MmGetSystemRoutineAddress(&procCountFuncName); + KeSaveExtendedProcessorStatePtr = (KeSaveExtendedProcessorStateFn)MmGetSystemRoutineAddress(&saveFuncName); + KeRestoreExtendedProcessorStatePtr = (KeRestoreExtendedProcessorStateFn)MmGetSystemRoutineAddress(&restoreFuncName); + KeSetSystemGroupAffinityThreadPtr = (KeSetSystemGroupAffinityThreadFn)MmGetSystemRoutineAddress(&setAffinityFuncName); + KeQueryActiveGroupCountPtr = (KeQueryActiveGroupCountFn)MmGetSystemRoutineAddress(&groupCountFuncName); + KeQueryActiveProcessorCountExPtr = (KeQueryActiveProcessorCountExFn)MmGetSystemRoutineAddress(&procCountFuncName); } - + // ExGetFirmwareEnvironmentVariable is available starting from Windows 8 if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 2)) { UNICODE_STRING funcName; RtlInitUnicodeString(&funcName, L"ExGetFirmwareEnvironmentVariable"); - ExGetFirmwareEnvironmentVariablePtr = (ExGetFirmwareEnvironmentVariableFn) MmGetSystemRoutineAddress(&funcName); + ExGetFirmwareEnvironmentVariablePtr = (ExGetFirmwareEnvironmentVariableFn)MmGetSystemRoutineAddress(&funcName); } // KeQueryInterruptTimePrecise is available starting from Windows 8.1 if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 3)) { UNICODE_STRING funcName; RtlInitUnicodeString(&funcName, L"KeQueryInterruptTimePrecise"); - KeQueryInterruptTimePrecisePtr = (KeQueryInterruptTimePreciseFn) MmGetSystemRoutineAddress(&funcName); + KeQueryInterruptTimePrecisePtr = (KeQueryInterruptTimePreciseFn)MmGetSystemRoutineAddress(&funcName); } // Load dump filter if the main driver is already loaded - if (NT_SUCCESS (TCDeviceIoControl (NT_ROOT_PREFIX, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &version, sizeof (version)))) - return DumpFilterEntry ((PFILTER_EXTENSION) DriverObject, (PFILTER_INITIALIZATION_DATA) RegistryPath); + if (NT_SUCCESS(TCDeviceIoControl(NT_ROOT_PREFIX, TC_IOCTL_GET_DRIVER_VERSION, NULL, 0, &version, sizeof(version)))) + return DumpFilterEntry((PFILTER_EXTENSION)DriverObject, (PFILTER_INITIALIZATION_DATA)RegistryPath); TCDriverObject = DriverObject; - memset (VirtualVolumeDeviceObjects, 0, sizeof (VirtualVolumeDeviceObjects)); + memset(VirtualVolumeDeviceObjects, 0, sizeof(VirtualVolumeDeviceObjects)); - ReadRegistryConfigFlags (TRUE); - EncryptionThreadPoolStart (EncryptionThreadPoolFreeCpuCountLimit); + ReadRegistryConfigFlags(TRUE); + EncryptionThreadPoolStart(EncryptionThreadPoolFreeCpuCountLimit); SelfTestsPassed = AutoTestAlgorithms(); // Enable device class filters and load boot arguments if the driver is set to start at system boot - if (NT_SUCCESS (TCReadRegistryKey (RegistryPath, L"Start", &startKeyValue))) + if (NT_SUCCESS(TCReadRegistryKey(RegistryPath, L"Start", &startKeyValue))) { - if (startKeyValue->Type == REG_DWORD && *((uint32 *) startKeyValue->Data) == SERVICE_BOOT_START) + if (startKeyValue->Type == REG_DWORD && *((uint32*)startKeyValue->Data) == SERVICE_BOOT_START) { if (!SelfTestsPassed) { // in case of system encryption, if self-tests fail, disable all extended CPU // features and try again in order to workaround faulty configurations - DisableCPUExtendedFeatures (); + DisableCPUExtendedFeatures(); SelfTestsPassed = AutoTestAlgorithms(); // BUG CHECK if the self-tests still fail if (!SelfTestsPassed) - TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + TC_BUG_CHECK(STATUS_INVALID_PARAMETER); } - LoadBootArguments(IsUefiBoot ()); + LoadBootArguments(IsUefiBoot()); VolumeClassFilterRegistered = IsVolumeClassFilterRegistered(); DriverObject->DriverExtension->AddDevice = DriverAddDevice; } - TCfree (startKeyValue); + TCfree(startKeyValue); } -#ifdef _WIN64 - if ((OsMajorVersion > 6) || (OsMajorVersion == 6 && OsMinorVersion >= 1)) + + if (RamEncryptionActivated) { - // we enable RAM encryption only starting from Windows 7 - if (RamEncryptionActivated) - { - if (t1ha_selfcheck__t1ha2() != 0) - TC_BUG_CHECK (STATUS_INVALID_PARAMETER); - if (!InitializeSecurityParameters(GetDriverRandomSeed)) - TC_BUG_CHECK (STATUS_INVALID_PARAMETER); + if (t1ha_selfcheck__t1ha2() != 0) + TC_BUG_CHECK(STATUS_INVALID_PARAMETER); + if (!InitializeSecurityParameters(GetDriverRandomSeed)) + TC_BUG_CHECK(STATUS_INVALID_PARAMETER); - EnableRamEncryption (TRUE); - } + EnableRamEncryption(TRUE); } -#endif for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i) { DriverObject->MajorFunction[i] = TCDispatchQueueIRP; } DriverObject->DriverUnload = TCUnloadDriver; - return TCCreateRootDeviceObject (DriverObject); + return TCCreateRootDeviceObject(DriverObject); } NTSTATUS DriverAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) { #if defined(DEBUG) || defined (DEBUG_TRACE) char nameInfoBuffer[128]; POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION) nameInfoBuffer; ULONG nameInfoSize; Dump ("AddDevice pdo=%p type=%x name=%ws\n", pdo, pdo->DeviceType, NT_SUCCESS (ObQueryNameString (pdo, nameInfo, sizeof (nameInfoBuffer), &nameInfoSize)) ? nameInfo->Name.Buffer : L"?"); #endif if (VolumeClassFilterRegistered && BootArgsValid && BootArgs.HiddenSystemPartitionStart != 0) { PWSTR interfaceLinks = NULL; if (NT_SUCCESS (IoGetDeviceInterfaces (&GUID_DEVINTERFACE_VOLUME, pdo, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &interfaceLinks)) && interfaceLinks) { if (interfaceLinks[0] != UNICODE_NULL) { Dump ("Volume pdo=%p interface=%ws\n", pdo, interfaceLinks); ExFreePool (interfaceLinks); return VolumeFilterAddDevice (driverObject, pdo); } ExFreePool (interfaceLinks); } } return DriveFilterAddDevice (driverObject, pdo); @@ -851,112 +836,113 @@ NTSTATUS TCCreateDeviceObject (PDRIVER_OBJECT DriverObject, return STATUS_SUCCESS; } BOOL RootDeviceControlMutexAcquireNoWait () { NTSTATUS status; LARGE_INTEGER timeout; timeout.QuadPart = 0; status = KeWaitForMutexObject (&RootDeviceControlMutex, Executive, KernelMode, FALSE, &timeout); return NT_SUCCESS (status) && status != STATUS_TIMEOUT; } void RootDeviceControlMutexRelease () { KeReleaseMutex (&RootDeviceControlMutex, FALSE); } /* IOCTL_STORAGE_GET_DEVICE_NUMBER 0x002D1080 IOCTL_STORAGE_GET_HOTPLUG_INFO 0x002D0C14 IOCTL_STORAGE_QUERY_PROPERTY 0x002D1400 */ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); + UNREFERENCED_PARAMETER(DeviceObject); switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_MOUNTDEV_QUERY_DEVICE_NAME)\n"); if (!ValidateIOBufferSize (Irp, sizeof (MOUNTDEV_NAME), ValidateOutput)) { Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; } else { ULONG outLength; UNICODE_STRING ntUnicodeString; WCHAR ntName[256]; PMOUNTDEV_NAME outputBuffer = (PMOUNTDEV_NAME) Irp->AssociatedIrp.SystemBuffer; TCGetNTNameFromNumber (ntName, sizeof(ntName),Extension->nDosDriveNo); RtlInitUnicodeString (&ntUnicodeString, ntName); outputBuffer->NameLength = ntUnicodeString.Length; outLength = ntUnicodeString.Length + sizeof(USHORT); if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) { Irp->IoStatus.Information = sizeof (MOUNTDEV_NAME); Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; break; } RtlCopyMemory ((PCHAR)outputBuffer->Name,ntUnicodeString.Buffer, ntUnicodeString.Length); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = outLength; Dump ("name = %ls\n",ntName); } break; case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_MOUNTDEV_QUERY_UNIQUE_ID)\n"); if (!ValidateIOBufferSize (Irp, sizeof (MOUNTDEV_UNIQUE_ID), ValidateOutput)) { Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; } else { ULONG outLength; - UCHAR volId[128], tmp[] = { 0,0 }; + CHAR volId[128], tmp[] = { 0,0 }; PMOUNTDEV_UNIQUE_ID outputBuffer = (PMOUNTDEV_UNIQUE_ID) Irp->AssociatedIrp.SystemBuffer; RtlStringCbCopyA (volId, sizeof(volId),TC_UNIQUE_ID_PREFIX); tmp[0] = 'A' + (UCHAR) Extension->nDosDriveNo; RtlStringCbCatA (volId, sizeof(volId),tmp); outputBuffer->UniqueIdLength = (USHORT) strlen (volId); outLength = (ULONG) (strlen (volId) + sizeof (USHORT)); if (irpSp->Parameters.DeviceIoControl.OutputBufferLength < outLength) { Irp->IoStatus.Information = sizeof (MOUNTDEV_UNIQUE_ID); Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; break; } RtlCopyMemory ((PCHAR)outputBuffer->UniqueId, volId, strlen (volId)); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = outLength; Dump ("id = %s\n",volId); } break; case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME)\n"); { ULONG outLength; UNICODE_STRING ntUnicodeString; @@ -997,61 +983,60 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION case IOCTL_DISK_GET_MEDIA_TYPES: case IOCTL_DISK_GET_DRIVE_GEOMETRY: case IOCTL_STORAGE_GET_MEDIA_TYPES: case IOCTL_DISK_UPDATE_DRIVE_SIZE: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_GEOMETRY)\n"); /* Return the drive geometry for the disk. Note that we return values which were made up to suit the disk size. */ if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY), ValidateOutput)) { PDISK_GEOMETRY outputBuffer = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer; outputBuffer->MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia; outputBuffer->Cylinders.QuadPart = Extension->NumberOfCylinders; outputBuffer->TracksPerCylinder = Extension->TracksPerCylinder; outputBuffer->SectorsPerTrack = Extension->SectorsPerTrack; outputBuffer->BytesPerSector = Extension->BytesPerSector; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (DISK_GEOMETRY); } break; case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_GEOMETRY_EX)\n"); { ULONG minOutputSize = IsOSAtLeast (WIN_SERVER_2003)? sizeof (DISK_GEOMETRY_EX) : sizeof (DISK_GEOMETRY) + sizeof (LARGE_INTEGER); ULONG fullOutputSize = sizeof (DISK_GEOMETRY) + sizeof (LARGE_INTEGER) + sizeof (DISK_PARTITION_INFO) + sizeof (DISK_DETECTION_INFO); if (ValidateIOBufferSize (Irp, minOutputSize, ValidateOutput)) { - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= fullOutputSize)? TRUE : FALSE; PDISK_GEOMETRY_EX outputBuffer = (PDISK_GEOMETRY_EX) Irp->AssociatedIrp.SystemBuffer; outputBuffer->Geometry.MediaType = Extension->bRemovable ? RemovableMedia : FixedMedia; outputBuffer->Geometry.Cylinders.QuadPart = Extension->NumberOfCylinders; outputBuffer->Geometry.TracksPerCylinder = Extension->TracksPerCylinder; outputBuffer->Geometry.SectorsPerTrack = Extension->SectorsPerTrack; outputBuffer->Geometry.BytesPerSector = Extension->BytesPerSector; // Add 1MB to the disk size to emulate the geometry of a real MBR disk outputBuffer->DiskSize.QuadPart = Extension->DiskLength + BYTES_PER_MB; if (bFullBuffer) { PDISK_PARTITION_INFO pPartInfo = (PDISK_PARTITION_INFO)(((ULONG_PTR) outputBuffer) + sizeof (DISK_GEOMETRY) + sizeof (LARGE_INTEGER)); PDISK_DETECTION_INFO pDetectInfo = ((PDISK_DETECTION_INFO)((((ULONG_PTR) pPartInfo) + sizeof (DISK_PARTITION_INFO)))); pPartInfo->SizeOfPartitionInfo = sizeof (DISK_PARTITION_INFO); pPartInfo->PartitionStyle = PARTITION_STYLE_MBR; pPartInfo->Mbr.Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); pDetectInfo->SizeOfDetectInfo = sizeof (DISK_DETECTION_INFO); Irp->IoStatus.Information = fullOutputSize; } else { if (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof (DISK_GEOMETRY_EX)) Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_EX); else Irp->IoStatus.Information = minOutputSize; @@ -1311,96 +1296,94 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION outputBuffer->HiddenSectors = 0; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION); } break; case IOCTL_DISK_GET_PARTITION_INFO_EX: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_PARTITION_INFO_EX)\n"); if (ValidateIOBufferSize (Irp, sizeof (PARTITION_INFORMATION_EX), ValidateOutput)) { PPARTITION_INFORMATION_EX outputBuffer = (PPARTITION_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->RewritePartition = FALSE; outputBuffer->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionLength.QuadPart= Extension->DiskLength; outputBuffer->PartitionNumber = 1; outputBuffer->Mbr.PartitionType = Extension->PartitionType; outputBuffer->Mbr.BootIndicator = FALSE; outputBuffer->Mbr.RecognizedPartition = TRUE; outputBuffer->Mbr.HiddenSectors = 0; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (PARTITION_INFORMATION_EX); } break; case IOCTL_DISK_GET_DRIVE_LAYOUT: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_LAYOUT)\n"); if (ValidateIOBufferSize (Irp, sizeof (DRIVE_LAYOUT_INFORMATION), ValidateOutput)) { - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= (sizeof (DRIVE_LAYOUT_INFORMATION) + 3*sizeof(PARTITION_INFORMATION)))? TRUE : FALSE; PDRIVE_LAYOUT_INFORMATION outputBuffer = (PDRIVE_LAYOUT_INFORMATION) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionCount = bFullBuffer? 4 : 1; outputBuffer->Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); outputBuffer->PartitionEntry->PartitionType = Extension->PartitionType; outputBuffer->PartitionEntry->BootIndicator = FALSE; outputBuffer->PartitionEntry->RecognizedPartition = TRUE; outputBuffer->PartitionEntry->RewritePartition = FALSE; outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; outputBuffer->PartitionEntry->PartitionNumber = 1; outputBuffer->PartitionEntry->HiddenSectors = 0; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (DRIVE_LAYOUT_INFORMATION); if (bFullBuffer) { Irp->IoStatus.Information += 3*sizeof(PARTITION_INFORMATION); memset (((BYTE*) Irp->AssociatedIrp.SystemBuffer) + sizeof (DRIVE_LAYOUT_INFORMATION), 0, 3*sizeof(PARTITION_INFORMATION)); } } break; case IOCTL_DISK_GET_DRIVE_LAYOUT_EX: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_DRIVE_LAYOUT_EX)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (EnableExtendedIoctlSupport) { if (ValidateIOBufferSize (Irp, sizeof (DRIVE_LAYOUT_INFORMATION_EX), ValidateOutput)) { - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); BOOL bFullBuffer = (irpSp->Parameters.DeviceIoControl.OutputBufferLength >= (sizeof (DRIVE_LAYOUT_INFORMATION_EX) + 3*sizeof(PARTITION_INFORMATION_EX)))? TRUE : FALSE; PDRIVE_LAYOUT_INFORMATION_EX outputBuffer = (PDRIVE_LAYOUT_INFORMATION_EX) Irp->AssociatedIrp.SystemBuffer; outputBuffer->PartitionCount = bFullBuffer? 4 : 1; outputBuffer->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->Mbr.Signature = GetCrc32((unsigned char*) &(Extension->UniqueVolumeId), 4); outputBuffer->PartitionEntry->PartitionStyle = PARTITION_STYLE_MBR; outputBuffer->PartitionEntry->Mbr.BootIndicator = FALSE; outputBuffer->PartitionEntry->Mbr.RecognizedPartition = TRUE; outputBuffer->PartitionEntry->RewritePartition = FALSE; outputBuffer->PartitionEntry->StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk outputBuffer->PartitionEntry->PartitionLength.QuadPart = Extension->DiskLength; outputBuffer->PartitionEntry->PartitionNumber = 1; outputBuffer->PartitionEntry->Mbr.HiddenSectors = 0; outputBuffer->PartitionEntry->Mbr.PartitionType = Extension->PartitionType; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (DRIVE_LAYOUT_INFORMATION_EX); if (bFullBuffer) { Irp->IoStatus.Information += 3*sizeof(PARTITION_INFORMATION_EX); } } } break; case IOCTL_DISK_GET_LENGTH_INFO: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_DISK_GET_LENGTH_INFO)\n"); @@ -1501,91 +1484,74 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION { if (Extension->bReadOnly) Irp->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED; else Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; } break; case IOCTL_VOLUME_ONLINE: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_ONLINE)\n"); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; break; case IOCTL_VOLUME_POST_ONLINE: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_POST_ONLINE)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (EnableExtendedIoctlSupport) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; } break; case IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS)\n"); // Vista's, Windows 8.1 and later filesystem defragmenter fails if IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS does not succeed. - if (!(OsMajorVersion == 6 && OsMinorVersion == 0) - && !(IsOSAtLeast (WIN_8_1) && AllowWindowsDefrag && Extension->bRawDevice) - ) + if (ValidateIOBufferSize(Irp, sizeof(VOLUME_DISK_EXTENTS), ValidateOutput)) { - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; - Irp->IoStatus.Information = 0; - } - else if (ValidateIOBufferSize (Irp, sizeof (VOLUME_DISK_EXTENTS), ValidateOutput)) - { - VOLUME_DISK_EXTENTS *extents = (VOLUME_DISK_EXTENTS *) Irp->AssociatedIrp.SystemBuffer; - + VOLUME_DISK_EXTENTS* extents = (VOLUME_DISK_EXTENTS*)Irp->AssociatedIrp.SystemBuffer; - if (IsOSAtLeast (WIN_8_1)) - { - // Windows 10 filesystem defragmenter works only if we report an extent with a real disk number - // So in the case of a VeraCrypt disk based volume, we use the disk number - // of the underlaying physical disk and we report a single extent - extents->NumberOfDiskExtents = 1; - extents->Extents[0].DiskNumber = Extension->DeviceNumber; - extents->Extents[0].StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk - extents->Extents[0].ExtentLength.QuadPart = Extension->DiskLength; - } - else - { - // Vista: No extent data can be returned as this is not a physical drive. - memset (extents, 0, sizeof (*extents)); - extents->NumberOfDiskExtents = 0; - } + // Windows 10 filesystem defragmenter works only if we report an extent with a real disk number + // So in the case of a VeraCrypt disk based volume, we use the disk number + // of the underlaying physical disk and we report a single extent + extents->NumberOfDiskExtents = 1; + extents->Extents[0].DiskNumber = Extension->DeviceNumber; + extents->Extents[0].StartingOffset.QuadPart = BYTES_PER_MB; // Set offset to 1MB to emulate the partition offset on a real MBR disk + extents->Extents[0].ExtentLength.QuadPart = Extension->DiskLength; Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof (*extents); + Irp->IoStatus.Information = sizeof(*extents); } break; case IOCTL_STORAGE_READ_CAPACITY: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_READ_CAPACITY)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (EnableExtendedIoctlSupport) { if (ValidateIOBufferSize (Irp, sizeof (STORAGE_READ_CAPACITY), ValidateOutput)) { STORAGE_READ_CAPACITY *capacity = (STORAGE_READ_CAPACITY *) Irp->AssociatedIrp.SystemBuffer; capacity->Version = sizeof (STORAGE_READ_CAPACITY); capacity->Size = sizeof (STORAGE_READ_CAPACITY); capacity->BlockLength = Extension->BytesPerSector; capacity->DiskLength.QuadPart = Extension->DiskLength + BYTES_PER_MB; // Add 1MB to the disk size to emulate the geometry of a real MBR disk capacity->NumberOfBlocks.QuadPart = capacity->DiskLength.QuadPart / capacity->BlockLength; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (STORAGE_READ_CAPACITY); } } break; /*case IOCTL_STORAGE_GET_DEVICE_NUMBER: Dump ("ProcessVolumeDeviceControlIrp (IOCTL_STORAGE_GET_DEVICE_NUMBER)\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (EnableExtendedIoctlSupport) @@ -1696,61 +1662,60 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION break; case IOCTL_DISK_MEDIA_REMOVAL: case IOCTL_STORAGE_MEDIA_REMOVAL: Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_SUCCESS for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; break; case IOCTL_DISK_GET_CLUSTER_INFO: Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_NOT_SUPPORTED for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (EnableExtendedIoctlSupport) { Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; } break; case IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES: Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES\n"); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; if (Extension->bRawDevice && Extension->TrimEnabled) { if (ValidateIOBufferSize (Irp, sizeof (DEVICE_MANAGE_DATA_SET_ATTRIBUTES), ValidateInput)) { - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); DWORD inputLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pInputAttrs = (PDEVICE_MANAGE_DATA_SET_ATTRIBUTES) Irp->AssociatedIrp.SystemBuffer; DEVICE_DATA_MANAGEMENT_SET_ACTION action = pInputAttrs->Action; BOOL bEntireSet = pInputAttrs->Flags & DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE? TRUE : FALSE; ULONGLONG minSizedataSet = (ULONGLONG) pInputAttrs->DataSetRangesOffset + (ULONGLONG) pInputAttrs->DataSetRangesLength; ULONGLONG minSizeParameter = (ULONGLONG) pInputAttrs->ParameterBlockOffset + (ULONGLONG) pInputAttrs->ParameterBlockLength; ULONGLONG minSizeGeneric = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES) + (ULONGLONG) pInputAttrs->ParameterBlockLength + (ULONGLONG) pInputAttrs->DataSetRangesLength; PDEVICE_MANAGE_DATA_SET_ATTRIBUTES pNewSetAttrs = NULL; ULONG ulNewInputLength = 0; BOOL bForwardIoctl = FALSE; if (((ULONGLONG) inputLength) >= minSizeGeneric && ((ULONGLONG) inputLength) >= minSizedataSet && ((ULONGLONG) inputLength) >= minSizeParameter) { if (bEntireSet) { if (minSizedataSet) { Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set but data set range specified=> Error.\n"); Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; } else { DWORD dwDataSetOffset; DWORD dwDataSetLength = sizeof(DEVICE_DATA_SET_RANGE); if (AlignValue (inputLength, sizeof(DEVICE_DATA_SET_RANGE), &dwDataSetOffset)) { Dump ("ProcessVolumeDeviceControlIrp: IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES - DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE set. Setting data range to all volume.\n"); @@ -1928,131 +1893,131 @@ NTSTATUS ProcessVolumeDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION case FT_BALANCED_READ_MODE: case IOCTL_STORAGE_GET_DEVICE_NUMBER: case IOCTL_MOUNTDEV_LINK_CREATED: Dump ("ProcessVolumeDeviceControlIrp: returning STATUS_INVALID_DEVICE_REQUEST for %ls\n", TCTranslateCode (irpSp->Parameters.DeviceIoControl.IoControlCode)); Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; break; default: Dump ("ProcessVolumeDeviceControlIrp (unknown code 0x%.8X)\n", irpSp->Parameters.DeviceIoControl.IoControlCode); return TCCompleteIrp (Irp, STATUS_INVALID_DEVICE_REQUEST, 0); } #if defined(DEBUG) || defined (DEBG_TRACE) if (!NT_SUCCESS (Irp->IoStatus.Status)) { Dump ("IOCTL error 0x%08x (0x%x %d)\n", Irp->IoStatus.Status, (int) (irpSp->Parameters.DeviceIoControl.IoControlCode >> 16), (int) ((irpSp->Parameters.DeviceIoControl.IoControlCode & 0x1FFF) >> 2)); } #endif return TCCompleteDiskIrp (Irp, Irp->IoStatus.Status, Irp->IoStatus.Information); } NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, PIRP Irp) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); NTSTATUS ntStatus; + UNREFERENCED_PARAMETER(Extension); switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case TC_IOCTL_GET_DRIVER_VERSION: if (ValidateIOBufferSize (Irp, sizeof (LONG), ValidateOutput)) { LONG tmp = VERSION_NUM; memcpy (Irp->AssociatedIrp.SystemBuffer, &tmp, 4); Irp->IoStatus.Information = sizeof (LONG); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case TC_IOCTL_GET_DEVICE_REFCOUNT: if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) { *(int *) Irp->AssociatedIrp.SystemBuffer = DeviceObject->ReferenceCount; Irp->IoStatus.Information = sizeof (int); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED: if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) { - LONG deviceObjectCount = 0; + ULONG deviceObjectCount = 0; *(int *) Irp->AssociatedIrp.SystemBuffer = DriverUnloadDisabled; if (IoEnumerateDeviceObjectList (TCDriverObject, NULL, 0, &deviceObjectCount) == STATUS_BUFFER_TOO_SMALL && deviceObjectCount > 1) *(int *) Irp->AssociatedIrp.SystemBuffer = TRUE; Irp->IoStatus.Information = sizeof (int); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case TC_IOCTL_IS_ANY_VOLUME_MOUNTED: if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) { int drive; *(int *) Irp->AssociatedIrp.SystemBuffer = 0; for (drive = MIN_MOUNTED_VOLUME_DRIVE_NUMBER; drive <= MAX_MOUNTED_VOLUME_DRIVE_NUMBER; ++drive) { if (GetVirtualVolumeDeviceObject (drive)) { *(int *) Irp->AssociatedIrp.SystemBuffer = 1; break; } } if (IsBootDriveMounted()) *(int *) Irp->AssociatedIrp.SystemBuffer = 1; Irp->IoStatus.Information = sizeof (int); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case TC_IOCTL_OPEN_TEST: { OPEN_TEST_STRUCT *opentest = (OPEN_TEST_STRUCT *) Irp->AssociatedIrp.SystemBuffer; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE NtFileHandle; UNICODE_STRING FullFileName; IO_STATUS_BLOCK IoStatus; LARGE_INTEGER offset; ACCESS_MASK access = FILE_READ_ATTRIBUTES; - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); if (!ValidateIOBufferSize (Irp, sizeof (OPEN_TEST_STRUCT), ValidateInputOutput)) break; if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (OPEN_TEST_STRUCT)) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } // check that opentest->wszFileName is a device path that starts with "\\Device\\Harddisk" // 16 is the length of "\\Device\\Harddisk" which is the minimum if ( !CheckStringLength (opentest->wszFileName, TC_MAX_PATH, 16, (size_t) -1, NULL) || (!StringNoCaseCompare (opentest->wszFileName, L"\\Device\\Harddisk", 16)) ) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } EnsureNullTerminatedString (opentest->wszFileName, sizeof (opentest->wszFileName)); RtlInitUnicodeString (&FullFileName, opentest->wszFileName); InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bComputeVolumeIDs) access |= FILE_READ_DATA; @@ -2239,61 +2204,60 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; } else { // Determine if the first sector contains a portion of the VeraCrypt Boot Loader offset.QuadPart = 0; // MBR ntStatus = ZwReadFile (NtFileHandle, NULL, NULL, NULL, &IoStatus, readBuffer, TC_MAX_VOLUME_SECTOR_SIZE, &offset, NULL); if (NT_SUCCESS (ntStatus)) { // check that we could read all needed data if (IoStatus.Information >= TC_SECTOR_SIZE_BIOS) { size_t i; // Check for dynamic drive request->DriveIsDynamic = FALSE; if (readBuffer[510] == 0x55 && readBuffer[511] == 0xaa) { - int i; for (i = 0; i < 4; ++i) { if (readBuffer[446 + i * 16 + 4] == PARTITION_LDM) { request->DriveIsDynamic = TRUE; break; } } } request->BootLoaderVersion = 0; request->Configuration = 0; request->UserConfiguration = 0; request->CustomUserMessage[0] = 0; // Search for the string "VeraCrypt" for (i = 0; i < TC_SECTOR_SIZE_BIOS - strlen (TC_APP_NAME); ++i) { if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) { request->BootLoaderVersion = BE16 (*(uint16 *) (readBuffer + TC_BOOT_SECTOR_VERSION_OFFSET)); request->Configuration = readBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET]; if (request->BootLoaderVersion != 0 && request->BootLoaderVersion <= VERSION_NUM) { request->UserConfiguration = readBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET]; memcpy (request->CustomUserMessage, readBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH); } break; } @@ -2432,418 +2396,412 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex #endif prop->volumeHeaderFlags = ListExtension->cryptoInfo->HeaderFlags; prop->readOnly = ListExtension->bReadOnly; prop->removable = ListExtension->bRemovable; prop->mountDisabled = ListExtension->bMountManager? FALSE : TRUE; prop->partitionInInactiveSysEncScope = ListExtension->PartitionInInactiveSysEncScope; prop->hiddenVolume = ListExtension->cryptoInfo->hiddenVolume; if (ListExtension->cryptoInfo->bProtectHiddenVolume) prop->hiddenVolProtection = ListExtension->cryptoInfo->bHiddenVolProtectionAction ? HIDVOL_PROT_STATUS_ACTION_TAKEN : HIDVOL_PROT_STATUS_ACTIVE; else prop->hiddenVolProtection = HIDVOL_PROT_STATUS_NONE; prop->totalBytesRead = ListExtension->Queue.TotalBytesRead; prop->totalBytesWritten = ListExtension->Queue.TotalBytesWritten; prop->volFormatVersion = ListExtension->cryptoInfo->LegacyVolume ? TC_VOLUME_FORMAT_VERSION_PRE_6_0 : TC_VOLUME_FORMAT_VERSION; Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = sizeof (VOLUME_PROPERTIES_STRUCT); } } } break; case TC_IOCTL_GET_RESOLVED_SYMLINK: if (ValidateIOBufferSize (Irp, sizeof (RESOLVE_SYMLINK_STRUCT), ValidateInputOutput)) { RESOLVE_SYMLINK_STRUCT *resolve = (RESOLVE_SYMLINK_STRUCT *) Irp->AssociatedIrp.SystemBuffer; { - NTSTATUS ntStatus; + NTSTATUS ntStatusLocal; EnsureNullTerminatedString (resolve->symLinkName, sizeof (resolve->symLinkName)); - ntStatus = SymbolicLinkToTarget (resolve->symLinkName, + ntStatusLocal = SymbolicLinkToTarget (resolve->symLinkName, resolve->targetName, sizeof (resolve->targetName)); Irp->IoStatus.Information = sizeof (RESOLVE_SYMLINK_STRUCT); - Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Status = ntStatusLocal; } } break; case TC_IOCTL_GET_DRIVE_PARTITION_INFO: if (ValidateIOBufferSize (Irp, sizeof (DISK_PARTITION_INFO_STRUCT), ValidateInputOutput)) { DISK_PARTITION_INFO_STRUCT *info = (DISK_PARTITION_INFO_STRUCT *) Irp->AssociatedIrp.SystemBuffer; { PARTITION_INFORMATION_EX pi; - NTSTATUS ntStatus; + NTSTATUS ntStatusLocal; EnsureNullTerminatedString (info->deviceName, sizeof (info->deviceName)); - ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi)); - if (NT_SUCCESS(ntStatus)) + ntStatusLocal = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi)); + if (NT_SUCCESS(ntStatusLocal)) { memset (&info->partInfo, 0, sizeof (info->partInfo)); info->partInfo.PartitionLength = pi.PartitionLength; info->partInfo.PartitionNumber = pi.PartitionNumber; info->partInfo.StartingOffset = pi.StartingOffset; if (pi.PartitionStyle == PARTITION_STYLE_MBR) { info->partInfo.PartitionType = pi.Mbr.PartitionType; info->partInfo.BootIndicator = pi.Mbr.BootIndicator; } info->IsGPT = pi.PartitionStyle == PARTITION_STYLE_GPT; } else { // Windows 2000 does not support IOCTL_DISK_GET_PARTITION_INFO_EX - ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo)); + ntStatusLocal = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &info->partInfo, sizeof (info->partInfo)); info->IsGPT = FALSE; } - if (!NT_SUCCESS (ntStatus)) + if (!NT_SUCCESS (ntStatusLocal)) { GET_LENGTH_INFORMATION lengthInfo; - ntStatus = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &lengthInfo, sizeof (lengthInfo)); + ntStatusLocal = TCDeviceIoControl (info->deviceName, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &lengthInfo, sizeof (lengthInfo)); - if (NT_SUCCESS (ntStatus)) + if (NT_SUCCESS (ntStatusLocal)) { memset (&info->partInfo, 0, sizeof (info->partInfo)); info->partInfo.PartitionLength = lengthInfo.Length; } } info->IsDynamic = FALSE; - if (NT_SUCCESS (ntStatus) && OsMajorVersion >= 6) + if (NT_SUCCESS (ntStatusLocal)) { # define IOCTL_VOLUME_IS_DYNAMIC CTL_CODE(IOCTL_VOLUME_BASE, 18, METHOD_BUFFERED, FILE_ANY_ACCESS) if (!NT_SUCCESS (TCDeviceIoControl (info->deviceName, IOCTL_VOLUME_IS_DYNAMIC, NULL, 0, &info->IsDynamic, sizeof (info->IsDynamic)))) info->IsDynamic = FALSE; } Irp->IoStatus.Information = sizeof (DISK_PARTITION_INFO_STRUCT); - Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Status = ntStatusLocal; } } break; case TC_IOCTL_GET_DRIVE_GEOMETRY: if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY_STRUCT), ValidateInputOutput)) { DISK_GEOMETRY_STRUCT *g = (DISK_GEOMETRY_STRUCT *) Irp->AssociatedIrp.SystemBuffer; { - NTSTATUS ntStatus; + NTSTATUS ntStatusLocal; EnsureNullTerminatedString (g->deviceName, sizeof (g->deviceName)); Dump ("Calling IOCTL_DISK_GET_DRIVE_GEOMETRY on %ls\n", g->deviceName); - ntStatus = TCDeviceIoControl (g->deviceName, + ntStatusLocal = TCDeviceIoControl (g->deviceName, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &g->diskGeometry, sizeof (g->diskGeometry)); Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_STRUCT); - Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Status = ntStatusLocal; } } break; case VC_IOCTL_GET_DRIVE_GEOMETRY_EX: if (ValidateIOBufferSize (Irp, sizeof (DISK_GEOMETRY_EX_STRUCT), ValidateInputOutput)) { DISK_GEOMETRY_EX_STRUCT *g = (DISK_GEOMETRY_EX_STRUCT *) Irp->AssociatedIrp.SystemBuffer; { - NTSTATUS ntStatus; + NTSTATUS ntStatusLocal; PVOID buffer = TCalloc (256); // enough for DISK_GEOMETRY_EX and padded data if (buffer) { EnsureNullTerminatedString (g->deviceName, sizeof (g->deviceName)); Dump ("Calling IOCTL_DISK_GET_DRIVE_GEOMETRY_EX on %ls\n", g->deviceName); - ntStatus = TCDeviceIoControl (g->deviceName, + ntStatusLocal = TCDeviceIoControl (g->deviceName, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, buffer, 256); - if (NT_SUCCESS(ntStatus)) + if (NT_SUCCESS(ntStatusLocal)) { PDISK_GEOMETRY_EX pGeo = (PDISK_GEOMETRY_EX) buffer; memcpy (&g->diskGeometry, &pGeo->Geometry, sizeof (DISK_GEOMETRY)); g->DiskSize.QuadPart = pGeo->DiskSize.QuadPart; } else { DISK_GEOMETRY dg = {0}; Dump ("Failed. Calling IOCTL_DISK_GET_DRIVE_GEOMETRY on %ls\n", g->deviceName); - ntStatus = TCDeviceIoControl (g->deviceName, + ntStatusLocal = TCDeviceIoControl (g->deviceName, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof (dg)); - if (NT_SUCCESS(ntStatus)) + if (NT_SUCCESS(ntStatusLocal)) { - memcpy (&g->diskGeometry, &dg, sizeof (DISK_GEOMETRY)); + memcpy(&g->diskGeometry, &dg, sizeof(DISK_GEOMETRY)); g->DiskSize.QuadPart = dg.Cylinders.QuadPart * dg.SectorsPerTrack * dg.TracksPerCylinder * dg.BytesPerSector; - if (OsMajorVersion >= 6) + STORAGE_READ_CAPACITY storage = { 0 }; + NTSTATUS lStatus; + storage.Version = sizeof(STORAGE_READ_CAPACITY); + Dump("Calling IOCTL_STORAGE_READ_CAPACITY on %ls\n", g->deviceName); + lStatus = TCDeviceIoControl(g->deviceName, + IOCTL_STORAGE_READ_CAPACITY, + NULL, 0, &storage, sizeof(STORAGE_READ_CAPACITY)); + if (NT_SUCCESS(lStatus) + && (storage.Size == sizeof(STORAGE_READ_CAPACITY)) + ) { - STORAGE_READ_CAPACITY storage = {0}; - NTSTATUS lStatus; - storage.Version = sizeof (STORAGE_READ_CAPACITY); - Dump ("Calling IOCTL_STORAGE_READ_CAPACITY on %ls\n", g->deviceName); - lStatus = TCDeviceIoControl (g->deviceName, - IOCTL_STORAGE_READ_CAPACITY, - NULL, 0, &storage, sizeof (STORAGE_READ_CAPACITY)); - if ( NT_SUCCESS(lStatus) - && (storage.Size == sizeof (STORAGE_READ_CAPACITY)) - ) - { - g->DiskSize.QuadPart = storage.DiskLength.QuadPart; - } + g->DiskSize.QuadPart = storage.DiskLength.QuadPart; } } } TCfree (buffer); Irp->IoStatus.Information = sizeof (DISK_GEOMETRY_EX_STRUCT); - Irp->IoStatus.Status = ntStatus; + Irp->IoStatus.Status = ntStatusLocal; } else { Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Information = 0; } } } break; case TC_IOCTL_PROBE_REAL_DRIVE_SIZE: if (ValidateIOBufferSize (Irp, sizeof (ProbeRealDriveSizeRequest), ValidateInputOutput)) { ProbeRealDriveSizeRequest *request = (ProbeRealDriveSizeRequest *) Irp->AssociatedIrp.SystemBuffer; NTSTATUS status; UNICODE_STRING name; PFILE_OBJECT fileObject; PDEVICE_OBJECT deviceObject; EnsureNullTerminatedString (request->DeviceName, sizeof (request->DeviceName)); RtlInitUnicodeString (&name, request->DeviceName); status = IoGetDeviceObjectPointer (&name, FILE_READ_ATTRIBUTES, &fileObject, &deviceObject); if (!NT_SUCCESS (status)) { Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; break; } status = ProbeRealDriveSize (deviceObject, &request->RealDriveSize); ObDereferenceObject (fileObject); if (status == STATUS_TIMEOUT) { request->TimeOut = TRUE; Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest); Irp->IoStatus.Status = STATUS_SUCCESS; } else if (!NT_SUCCESS (status)) { Irp->IoStatus.Information = 0; Irp->IoStatus.Status = status; } else { request->TimeOut = FALSE; Irp->IoStatus.Information = sizeof (ProbeRealDriveSizeRequest); Irp->IoStatus.Status = status; } } break; case TC_IOCTL_MOUNT_VOLUME: if (ValidateIOBufferSize (Irp, sizeof (MOUNT_STRUCT), ValidateInputOutput)) { MOUNT_STRUCT *mount = (MOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); if ((irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (MOUNT_STRUCT)) || mount->VolumePassword.Length > MAX_PASSWORD || mount->ProtectedHidVolPassword.Length > MAX_PASSWORD || mount->pkcs5_prf < 0 || mount->pkcs5_prf > LAST_PRF_ID || mount->VolumePim < -1 || mount->VolumePim == INT_MAX || mount->ProtectedHidVolPkcs5Prf < 0 || mount->ProtectedHidVolPkcs5Prf > LAST_PRF_ID ) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } EnsureNullTerminatedString (mount->wszVolume, sizeof (mount->wszVolume)); EnsureNullTerminatedString (mount->wszLabel, sizeof (mount->wszLabel)); Irp->IoStatus.Information = sizeof (MOUNT_STRUCT); Irp->IoStatus.Status = MountDevice (DeviceObject, mount); burn (&mount->VolumePassword, sizeof (mount->VolumePassword)); burn (&mount->ProtectedHidVolPassword, sizeof (mount->ProtectedHidVolPassword)); burn (&mount->pkcs5_prf, sizeof (mount->pkcs5_prf)); burn (&mount->VolumePim, sizeof (mount->VolumePim)); burn (&mount->ProtectedHidVolPkcs5Prf, sizeof (mount->ProtectedHidVolPkcs5Prf)); burn (&mount->ProtectedHidVolPim, sizeof (mount->ProtectedHidVolPim)); } break; case TC_IOCTL_DISMOUNT_VOLUME: if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput)) { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; PDEVICE_OBJECT ListDevice = GetVirtualVolumeDeviceObject (unmount->nDosDriveNo); - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } unmount->nReturnCode = ERR_DRIVE_NOT_FOUND; if (ListDevice) { PEXTENSION ListExtension = (PEXTENSION) ListDevice->DeviceExtension; if (IsVolumeAccessibleByCurrentUser (ListExtension)) unmount->nReturnCode = UnmountDevice (unmount, ListDevice, unmount->ignoreOpenFiles); } Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case TC_IOCTL_DISMOUNT_ALL_VOLUMES: if (ValidateIOBufferSize (Irp, sizeof (UNMOUNT_STRUCT), ValidateInputOutput)) { UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) Irp->AssociatedIrp.SystemBuffer; - PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); if (irpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof (UNMOUNT_STRUCT)) { Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; Irp->IoStatus.Information = 0; break; } unmount->nReturnCode = UnmountAllDevices (unmount, unmount->ignoreOpenFiles); Irp->IoStatus.Information = sizeof (UNMOUNT_STRUCT); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case VC_IOCTL_EMERGENCY_CLEAR_ALL_KEYS: - EmergencyClearAllKeys (Irp, irpSp); + EmergencyClearAllKeys (Irp); WipeCache(); break; case TC_IOCTL_BOOT_ENCRYPTION_SETUP: Irp->IoStatus.Status = StartBootEncryptionSetup (DeviceObject, Irp, irpSp); Irp->IoStatus.Information = 0; break; case TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP: Irp->IoStatus.Status = AbortBootEncryptionSetup(); Irp->IoStatus.Information = 0; break; case TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS: - GetBootEncryptionStatus (Irp, irpSp); + GetBootEncryptionStatus (Irp); break; case TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT: Irp->IoStatus.Information = 0; Irp->IoStatus.Status = GetSetupResult(); break; case TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES: - GetBootDriveVolumeProperties (Irp, irpSp); + GetBootDriveVolumeProperties (Irp); break; case TC_IOCTL_GET_BOOT_LOADER_VERSION: - GetBootLoaderVersion (Irp, irpSp); + GetBootLoaderVersion (Irp); break; case TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER: - ReopenBootVolumeHeader (Irp, irpSp); + ReopenBootVolumeHeader (Irp); break; case VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT: - GetBootLoaderFingerprint (Irp, irpSp); + GetBootLoaderFingerprint (Irp); break; case TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME: - GetBootEncryptionAlgorithmName (Irp, irpSp); + GetBootEncryptionAlgorithmName (Irp); break; case TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING: if (ValidateIOBufferSize (Irp, sizeof (int), ValidateOutput)) { *(int *) Irp->AssociatedIrp.SystemBuffer = IsHiddenSystemRunning() ? 1 : 0; Irp->IoStatus.Information = sizeof (int); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case TC_IOCTL_START_DECOY_SYSTEM_WIPE: Irp->IoStatus.Status = StartDecoySystemWipe (DeviceObject, Irp, irpSp); Irp->IoStatus.Information = 0; break; case TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE: Irp->IoStatus.Status = AbortDecoySystemWipe(); Irp->IoStatus.Information = 0; break; case TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT: Irp->IoStatus.Status = GetDecoySystemWipeResult(); Irp->IoStatus.Information = 0; break; case TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS: - GetDecoySystemWipeStatus (Irp, irpSp); + GetDecoySystemWipeStatus (Irp); break; case TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR: Irp->IoStatus.Status = WriteBootDriveSector (Irp, irpSp); Irp->IoStatus.Information = 0; break; case TC_IOCTL_GET_WARNING_FLAGS: if (ValidateIOBufferSize (Irp, sizeof (GetWarningFlagsRequest), ValidateOutput)) { GetWarningFlagsRequest *flags = (GetWarningFlagsRequest *) Irp->AssociatedIrp.SystemBuffer; flags->PagingFileCreationPrevented = PagingFileCreationPrevented; PagingFileCreationPrevented = FALSE; flags->SystemFavoriteVolumeDirty = SystemFavoriteVolumeDirty; SystemFavoriteVolumeDirty = FALSE; Irp->IoStatus.Information = sizeof (GetWarningFlagsRequest); Irp->IoStatus.Status = STATUS_SUCCESS; } break; case TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY: if (UserCanAccessDriveDevice()) { SystemFavoriteVolumeDirty = TRUE; Irp->IoStatus.Status = STATUS_SUCCESS; } else Irp->IoStatus.Status = STATUS_ACCESS_DENIED; @@ -3478,123 +3436,126 @@ LPWSTR TCTranslateCode (ULONG ulCode) } #endif void TCDeleteDeviceObject (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) { UNICODE_STRING Win32NameString; NTSTATUS ntStatus; Dump ("TCDeleteDeviceObject BEGIN\n"); if (Extension->bRootDevice) { RtlInitUnicodeString (&Win32NameString, (LPWSTR) DOS_ROOT_PREFIX); ntStatus = IoDeleteSymbolicLink (&Win32NameString); if (!NT_SUCCESS (ntStatus)) Dump ("IoDeleteSymbolicLink failed ntStatus = 0x%08x\n", ntStatus); RootDeviceObject = NULL; } else { if (Extension->peThread != NULL) TCStopVolumeThread (DeviceObject, Extension); if (Extension->UserSid) TCfree (Extension->UserSid); if (Extension->SecurityClientContextValid) { - VOID (*PsDereferenceImpersonationTokenD) (PACCESS_TOKEN ImpersonationToken); + typedef VOID (*PsDereferenceImpersonationTokenDType) (PACCESS_TOKEN ImpersonationToken); + + PsDereferenceImpersonationTokenDType PsDereferenceImpersonationTokenD; UNICODE_STRING name; RtlInitUnicodeString (&name, L"PsDereferenceImpersonationToken"); - PsDereferenceImpersonationTokenD = MmGetSystemRoutineAddress (&name); + PsDereferenceImpersonationTokenD = (PsDereferenceImpersonationTokenDType) MmGetSystemRoutineAddress (&name); if (!PsDereferenceImpersonationTokenD) TC_BUG_CHECK (STATUS_NOT_IMPLEMENTED); # define PsDereferencePrimaryToken # define PsDereferenceImpersonationToken PsDereferenceImpersonationTokenD SeDeleteClientSecurity (&Extension->SecurityClientContext); # undef PsDereferencePrimaryToken # undef PsDereferenceImpersonationToken } VirtualVolumeDeviceObjects[Extension->nDosDriveNo] = NULL; } IoDeleteDevice (DeviceObject); Dump ("TCDeleteDeviceObject END\n"); } VOID TCUnloadDriver (PDRIVER_OBJECT DriverObject) { Dump ("TCUnloadDriver BEGIN\n"); - + UNREFERENCED_PARAMETER(DriverObject); OnShutdownPending(); if (IsBootDriveMounted()) TC_BUG_CHECK (STATUS_INVALID_DEVICE_STATE); EncryptionThreadPoolStop(); TCDeleteDeviceObject (RootDeviceObject, (PEXTENSION) RootDeviceObject->DeviceExtension); Dump ("TCUnloadDriver END\n"); } void OnShutdownPending () { UNMOUNT_STRUCT unmount; memset (&unmount, 0, sizeof (unmount)); unmount.ignoreOpenFiles = TRUE; while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_DISMOUNT_ALL_VOLUMES, &unmount, sizeof (unmount), &unmount, sizeof (unmount)) == STATUS_INSUFFICIENT_RESOURCES || unmount.HiddenVolumeProtectionTriggered) unmount.HiddenVolumeProtectionTriggered = FALSE; while (SendDeviceIoControlRequest (RootDeviceObject, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0) == STATUS_INSUFFICIENT_RESOURCES); } typedef struct { PWSTR deviceName; ULONG IoControlCode; void *InputBuffer; ULONG InputBufferSize; void *OutputBuffer; ULONG OutputBufferSize; NTSTATUS Status; KEVENT WorkItemCompletedEvent; } TCDeviceIoControlWorkItemArgs; static VOID TCDeviceIoControlWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCDeviceIoControlWorkItemArgs *arg) { + UNREFERENCED_PARAMETER(rootDeviceObject); arg->Status = TCDeviceIoControl (arg->deviceName, arg->IoControlCode, arg->InputBuffer, arg->InputBufferSize, arg->OutputBuffer, arg->OutputBufferSize); KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, void *InputBuffer, ULONG InputBufferSize, void *OutputBuffer, ULONG OutputBufferSize) { IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; PIRP irp; PFILE_OBJECT fileObject; PDEVICE_OBJECT deviceObject; KEVENT event; UNICODE_STRING name; if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) { TCDeviceIoControlWorkItemArgs args; PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); if (!workItem) return STATUS_INSUFFICIENT_RESOURCES; args.deviceName = deviceName; args.IoControlCode = IoControlCode; args.InputBuffer = InputBuffer; args.InputBufferSize = InputBufferSize; args.OutputBuffer = OutputBuffer; args.OutputBufferSize = OutputBufferSize; KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); @@ -3627,60 +3588,61 @@ NTSTATUS TCDeviceIoControl (PWSTR deviceName, ULONG IoControlCode, void *InputBu Dump ("IRP allocation failed\n"); ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto ret; } IoGetNextIrpStackLocation (irp)->FileObject = fileObject; ntStatus = IoCallDriver (deviceObject, irp); if (ntStatus == STATUS_PENDING) { KeWaitForSingleObject (&event, Executive, KernelMode, FALSE, NULL); ntStatus = ioStatusBlock.Status; } ret: ObDereferenceObject (fileObject); return ntStatus; } typedef struct { PDEVICE_OBJECT deviceObject; ULONG ioControlCode; void *inputBuffer; int inputBufferSize; void *outputBuffer; int outputBufferSize; NTSTATUS Status; KEVENT WorkItemCompletedEvent; } SendDeviceIoControlRequestWorkItemArgs; static VOID SendDeviceIoControlRequestWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, SendDeviceIoControlRequestWorkItemArgs *arg) { + UNREFERENCED_PARAMETER(rootDeviceObject); arg->Status = SendDeviceIoControlRequest (arg->deviceObject, arg->ioControlCode, arg->inputBuffer, arg->inputBufferSize, arg->outputBuffer, arg->outputBufferSize); KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } NTSTATUS SendDeviceIoControlRequest (PDEVICE_OBJECT deviceObject, ULONG ioControlCode, void *inputBuffer, int inputBufferSize, void *outputBuffer, int outputBufferSize) { IO_STATUS_BLOCK ioStatusBlock; NTSTATUS status; PIRP irp; KEVENT event; if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) { SendDeviceIoControlRequestWorkItemArgs args; PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); if (!workItem) return STATUS_INSUFFICIENT_RESOURCES; args.deviceObject = deviceObject; args.ioControlCode = ioControlCode; args.inputBuffer = inputBuffer; args.inputBufferSize = inputBufferSize; args.outputBuffer = outputBuffer; args.outputBufferSize = outputBufferSize; KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); IoQueueWorkItem (workItem, SendDeviceIoControlRequestWorkItemRoutine, DelayedWorkQueue, &args); @@ -3971,60 +3933,61 @@ NTSTATUS MountManagerUnmount (int nDosDriveNo) char buf[256], out[300]; PMOUNTMGR_MOUNT_POINT in = (PMOUNTMGR_MOUNT_POINT) buf; memset (buf, 0, sizeof buf); TCGetDosNameFromNumber ((PWSTR) &in[1], sizeof(buf) - sizeof(MOUNTMGR_MOUNT_POINT),nDosDriveNo, DeviceNamespaceDefault); // Only symbolic link can be deleted with IOCTL_MOUNTMGR_DELETE_POINTS. If any other entry is specified, the mount manager will ignore subsequent IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION for the same volume ID. in->SymbolicLinkNameOffset = sizeof (MOUNTMGR_MOUNT_POINT); in->SymbolicLinkNameLength = (USHORT) wcslen ((PWCHAR) &in[1]) * 2; ntStatus = TCDeviceIoControl (MOUNTMGR_DEVICE_NAME, IOCTL_MOUNTMGR_DELETE_POINTS, in, sizeof(MOUNTMGR_MOUNT_POINT) + in->SymbolicLinkNameLength, out, sizeof out); Dump ("IOCTL_MOUNTMGR_DELETE_POINTS returned 0x%08x\n", ntStatus); return ntStatus; } typedef struct { MOUNT_STRUCT* mount; PEXTENSION NewExtension; NTSTATUS Status; KEVENT WorkItemCompletedEvent; } UpdateFsVolumeInformationWorkItemArgs; static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewExtension); static VOID UpdateFsVolumeInformationWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, UpdateFsVolumeInformationWorkItemArgs *arg) { + UNREFERENCED_PARAMETER(rootDeviceObject); arg->Status = UpdateFsVolumeInformation (arg->mount, arg->NewExtension); KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } static NTSTATUS UpdateFsVolumeInformation (MOUNT_STRUCT* mount, PEXTENSION NewExtension) { HANDLE volumeHandle; PFILE_OBJECT volumeFileObject; ULONG labelLen = (ULONG) wcslen (mount->wszLabel); BOOL bIsNTFS = FALSE; ULONG labelMaxLen, labelEffectiveLen; if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) { UpdateFsVolumeInformationWorkItemArgs args; PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); if (!workItem) return STATUS_INSUFFICIENT_RESOURCES; args.mount = mount; args.NewExtension = NewExtension; KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); IoQueueWorkItem (workItem, UpdateFsVolumeInformationWorkItemRoutine, DelayedWorkQueue, &args); KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); IoFreeWorkItem (workItem); return args.Status; @@ -4238,60 +4201,61 @@ NTSTATUS MountDevice (PDEVICE_OBJECT DeviceObject, MOUNT_STRUCT *mount) if (mount->bMountManager) { NTSTATUS updateStatus = UpdateFsVolumeInformation (mount, NewExtension); if (!NT_SUCCESS (updateStatus)) { Dump ("MountDevice: UpdateFsVolumeInformation failed with status 0x%08x\n", updateStatus); } } } else { Dump ("Mount FAILURE TC code = 0x%08x\n", mount->nReturnCode); TCDeleteDeviceObject (NewDeviceObject, NewExtension); } return STATUS_SUCCESS; } } } typedef struct { UNMOUNT_STRUCT *unmountRequest; PDEVICE_OBJECT deviceObject; BOOL ignoreOpenFiles; NTSTATUS Status; KEVENT WorkItemCompletedEvent; } UnmountDeviceWorkItemArgs; static VOID UnmountDeviceWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, UnmountDeviceWorkItemArgs *arg) { + UNREFERENCED_PARAMETER(rootDeviceObject); arg->Status = UnmountDevice (arg->unmountRequest, arg->deviceObject, arg->ignoreOpenFiles); KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } NTSTATUS UnmountDevice (UNMOUNT_STRUCT *unmountRequest, PDEVICE_OBJECT deviceObject, BOOL ignoreOpenFiles) { PEXTENSION extension = deviceObject->DeviceExtension; NTSTATUS ntStatus; HANDLE volumeHandle; PFILE_OBJECT volumeFileObject; if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) { UnmountDeviceWorkItemArgs args; PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); if (!workItem) return STATUS_INSUFFICIENT_RESOURCES; args.deviceObject = deviceObject; args.unmountRequest = unmountRequest; args.ignoreOpenFiles = ignoreOpenFiles; KeInitializeEvent (&args.WorkItemCompletedEvent, SynchronizationEvent, FALSE); IoQueueWorkItem (workItem, UnmountDeviceWorkItemRoutine, DelayedWorkQueue, &args); KeWaitForSingleObject (&args.WorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); IoFreeWorkItem (workItem); return args.Status; diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c index 68f63f16..0486219e 100644 --- a/src/Driver/Ntvol.c +++ b/src/Driver/Ntvol.c @@ -26,250 +26,243 @@ #include "Cache.h" #if 0 && _DEBUG #define EXTRA_INFO 1 #endif #pragma warning( disable : 4127 ) #include <Ntstrsafe.h> volatile BOOL ProbingHostDeviceForWrite = FALSE; NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, MOUNT_STRUCT *mount, PWSTR pwszMountVolume, BOOL bRawDevice) { FILE_STANDARD_INFORMATION FileStandardInfo = { 0 }; FILE_BASIC_INFORMATION FileBasicInfo; OBJECT_ATTRIBUTES oaFileAttributes; UNICODE_STRING FullFileName; IO_STATUS_BLOCK IoStatusBlock; PCRYPTO_INFO cryptoInfoPtr = NULL; PCRYPTO_INFO tmpCryptoInfo = NULL; LARGE_INTEGER lDiskLength = { 0 }; __int64 partitionStartingOffset = 0; int volumeType; - char *readBuffer = 0; + unsigned char *readBuffer = 0; NTSTATUS ntStatus = 0; BOOL forceAccessCheck = !bRawDevice; BOOL disableBuffering = TRUE; BOOL exclusiveAccess = mount->bExclusiveAccess; /* when mounting with hidden volume protection, we cache the passwords after both outer and hidden volumes are mounted successfully*/ BOOL bAutoCachePassword = mount->bProtectHiddenVolume? FALSE : mount->bCache; Extension->pfoDeviceFile = NULL; Extension->hDeviceFile = NULL; Extension->bTimeStampValid = FALSE; /* default value for storage alignment */ Extension->HostMaximumTransferLength = 65536; Extension->HostMaximumPhysicalPages = 17; Extension->HostAlignmentMask = 0; /* default values for non-SSD drives */ Extension->IncursSeekPenalty = TRUE; Extension->TrimEnabled = FALSE; Extension->DeviceNumber = (ULONG) -1; RtlInitUnicodeString (&FullFileName, pwszMountVolume); InitializeObjectAttributes (&oaFileAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | (forceAccessCheck ? OBJ_FORCE_ACCESS_CHECK : 0) | OBJ_KERNEL_HANDLE, NULL, NULL); KeInitializeEvent (&Extension->keVolumeEvent, NotificationEvent, FALSE); if (Extension->SecurityClientContextValid) { ntStatus = SeImpersonateClientEx (&Extension->SecurityClientContext, NULL); if (!NT_SUCCESS (ntStatus)) goto error; } mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = FALSE; mount->VolumeMountedReadOnlyAfterPartialSysEnc = FALSE; mount->VolumeMasterKeyVulnerable = FALSE; // If we are opening a device, query its size first if (bRawDevice) { PARTITION_INFORMATION pi; PARTITION_INFORMATION_EX pix; LARGE_INTEGER diskLengthInfo; DISK_GEOMETRY_EX dg; - STORAGE_PROPERTY_QUERY storagePropertyQuery = {0}; + STORAGE_PROPERTY_QUERY storagePropertyQuery = { 0 }; uint8* dgBuffer; STORAGE_DEVICE_NUMBER storageDeviceNumber; - ntStatus = IoGetDeviceObjectPointer (&FullFileName, + ntStatus = IoGetDeviceObjectPointer(&FullFileName, FILE_READ_DATA | FILE_READ_ATTRIBUTES, &Extension->pfoDeviceFile, &Extension->pFsdDevice); - if (!NT_SUCCESS (ntStatus)) + if (!NT_SUCCESS(ntStatus)) goto error; - dgBuffer = TCalloc (256); + dgBuffer = TCalloc(256); if (!dgBuffer) { ntStatus = STATUS_INSUFFICIENT_RESOURCES; goto error; } - ntStatus = TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, (char *) dgBuffer, 256); - if (!NT_SUCCESS (ntStatus)) + ntStatus = TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, (char*)dgBuffer, 256); + if (!NT_SUCCESS(ntStatus)) { DISK_GEOMETRY geo; - ntStatus = TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char *) &geo, sizeof (geo)); - if (!NT_SUCCESS (ntStatus)) + ntStatus = TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_DRIVE_GEOMETRY, (char*)&geo, sizeof(geo)); + if (!NT_SUCCESS(ntStatus)) { - TCfree (dgBuffer); + TCfree(dgBuffer); goto error; } - memset (&dg, 0, sizeof (dg)); - memcpy (&dg.Geometry, &geo, sizeof (geo)); + memset(&dg, 0, sizeof(dg)); + memcpy(&dg.Geometry, &geo, sizeof(geo)); dg.DiskSize.QuadPart = geo.Cylinders.QuadPart * geo.SectorsPerTrack * geo.TracksPerCylinder * geo.BytesPerSector; - if (OsMajorVersion >= 6) + STORAGE_READ_CAPACITY storage = { 0 }; + NTSTATUS lStatus; + + storage.Version = sizeof(STORAGE_READ_CAPACITY); + storage.Size = sizeof(STORAGE_READ_CAPACITY); + lStatus = TCSendHostDeviceIoControlRequest(DeviceObject, Extension, + IOCTL_STORAGE_READ_CAPACITY, + (char*)&storage, sizeof(STORAGE_READ_CAPACITY)); + if (NT_SUCCESS(lStatus) + && (storage.Size == sizeof(STORAGE_READ_CAPACITY)) + ) { - STORAGE_READ_CAPACITY storage = {0}; - NTSTATUS lStatus; - - storage.Version = sizeof (STORAGE_READ_CAPACITY); - storage.Size = sizeof (STORAGE_READ_CAPACITY); - lStatus = TCSendHostDeviceIoControlRequest (DeviceObject, Extension, - IOCTL_STORAGE_READ_CAPACITY, - (char*) &storage, sizeof (STORAGE_READ_CAPACITY)); - if ( NT_SUCCESS(lStatus) - && (storage.Size == sizeof (STORAGE_READ_CAPACITY)) - ) - { - dg.DiskSize.QuadPart = storage.DiskLength.QuadPart; - } + dg.DiskSize.QuadPart = storage.DiskLength.QuadPart; } } else - memcpy (&dg, dgBuffer, sizeof (DISK_GEOMETRY_EX)); + memcpy(&dg, dgBuffer, sizeof(DISK_GEOMETRY_EX)); - TCfree (dgBuffer); + TCfree(dgBuffer); - if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, - IOCTL_STORAGE_GET_DEVICE_NUMBER, - (char*) &storageDeviceNumber, sizeof (storageDeviceNumber)))) + if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, + IOCTL_STORAGE_GET_DEVICE_NUMBER, + (char*)&storageDeviceNumber, sizeof(storageDeviceNumber)))) { Extension->DeviceNumber = storageDeviceNumber.DeviceNumber; } lDiskLength.QuadPart = dg.DiskSize.QuadPart; Extension->HostBytesPerSector = dg.Geometry.BytesPerSector; Extension->HostBytesPerPhysicalSector = dg.Geometry.BytesPerSector; - /* IOCTL_STORAGE_QUERY_PROPERTY supported only on Vista and above */ - if (OsMajorVersion >= 6) - { - STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR alignmentDesc = {0}; - STORAGE_ADAPTER_DESCRIPTOR adapterDesc = {0}; - DEVICE_SEEK_PENALTY_DESCRIPTOR penaltyDesc = {0}; - DEVICE_TRIM_DESCRIPTOR trimDesc = {0}; + STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR alignmentDesc = { 0 }; + STORAGE_ADAPTER_DESCRIPTOR adapterDesc = { 0 }; + DEVICE_SEEK_PENALTY_DESCRIPTOR penaltyDesc = { 0 }; + DEVICE_TRIM_DESCRIPTOR trimDesc = { 0 }; - storagePropertyQuery.PropertyId = StorageAccessAlignmentProperty; - storagePropertyQuery.QueryType = PropertyStandardQuery; + storagePropertyQuery.PropertyId = StorageAccessAlignmentProperty; + storagePropertyQuery.QueryType = PropertyStandardQuery; - alignmentDesc.Version = sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); - alignmentDesc.Size = sizeof (STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); + alignmentDesc.Version = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); + alignmentDesc.Size = sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR); - if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, - (char*) &storagePropertyQuery, sizeof(storagePropertyQuery), - (char *) &alignmentDesc, sizeof (alignmentDesc)))) - { - Extension->HostBytesPerPhysicalSector = alignmentDesc.BytesPerPhysicalSector; - } + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&alignmentDesc, sizeof(alignmentDesc)))) + { + Extension->HostBytesPerPhysicalSector = alignmentDesc.BytesPerPhysicalSector; + } - storagePropertyQuery.PropertyId = StorageAdapterProperty; - adapterDesc.Version = sizeof (STORAGE_ADAPTER_DESCRIPTOR); - adapterDesc.Size = sizeof (STORAGE_ADAPTER_DESCRIPTOR); + storagePropertyQuery.PropertyId = StorageAdapterProperty; + adapterDesc.Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR); + adapterDesc.Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR); - if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, - (char*) &storagePropertyQuery, sizeof(storagePropertyQuery), - (char *) &adapterDesc, sizeof (adapterDesc)))) - { - Extension->HostMaximumTransferLength = adapterDesc.MaximumTransferLength; - Extension->HostMaximumPhysicalPages = adapterDesc.MaximumPhysicalPages; - Extension->HostAlignmentMask = adapterDesc.AlignmentMask; - } + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&adapterDesc, sizeof(adapterDesc)))) + { + Extension->HostMaximumTransferLength = adapterDesc.MaximumTransferLength; + Extension->HostMaximumPhysicalPages = adapterDesc.MaximumPhysicalPages; + Extension->HostAlignmentMask = adapterDesc.AlignmentMask; + } - storagePropertyQuery.PropertyId = StorageDeviceSeekPenaltyProperty; - penaltyDesc.Version = sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR); - penaltyDesc.Size = sizeof (DEVICE_SEEK_PENALTY_DESCRIPTOR); + storagePropertyQuery.PropertyId = StorageDeviceSeekPenaltyProperty; + penaltyDesc.Version = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); + penaltyDesc.Size = sizeof(DEVICE_SEEK_PENALTY_DESCRIPTOR); - if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, - (char*) &storagePropertyQuery, sizeof(storagePropertyQuery), - (char *) &penaltyDesc, sizeof (penaltyDesc)))) - { - Extension->IncursSeekPenalty = penaltyDesc.IncursSeekPenalty; - } + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&penaltyDesc, sizeof(penaltyDesc)))) + { + Extension->IncursSeekPenalty = penaltyDesc.IncursSeekPenalty; + } - storagePropertyQuery.PropertyId = StorageDeviceTrimProperty; - trimDesc.Version = sizeof (DEVICE_TRIM_DESCRIPTOR); - trimDesc.Size = sizeof (DEVICE_TRIM_DESCRIPTOR); + storagePropertyQuery.PropertyId = StorageDeviceTrimProperty; + trimDesc.Version = sizeof(DEVICE_TRIM_DESCRIPTOR); + trimDesc.Size = sizeof(DEVICE_TRIM_DESCRIPTOR); - if (NT_SUCCESS (TCSendHostDeviceIoControlRequestEx (DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, - (char*) &storagePropertyQuery, sizeof(storagePropertyQuery), - (char *) &trimDesc, sizeof (trimDesc)))) - { - Extension->TrimEnabled = trimDesc.TrimEnabled; - } + if (NT_SUCCESS(TCSendHostDeviceIoControlRequestEx(DeviceObject, Extension, IOCTL_STORAGE_QUERY_PROPERTY, + (char*)&storagePropertyQuery, sizeof(storagePropertyQuery), + (char*)&trimDesc, sizeof(trimDesc)))) + { + Extension->TrimEnabled = trimDesc.TrimEnabled; } // Drive geometry is used only when IOCTL_DISK_GET_PARTITION_INFO fails - if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char *) &pix, sizeof (pix)))) + if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO_EX, (char*)&pix, sizeof(pix)))) { lDiskLength.QuadPart = pix.PartitionLength.QuadPart; partitionStartingOffset = pix.StartingOffset.QuadPart; } // If IOCTL_DISK_GET_PARTITION_INFO_EX fails, switch to IOCTL_DISK_GET_PARTITION_INFO - else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char *) &pi, sizeof (pi)))) + else if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_PARTITION_INFO, (char*)&pi, sizeof(pi)))) { lDiskLength.QuadPart = pi.PartitionLength.QuadPart; partitionStartingOffset = pi.StartingOffset.QuadPart; } - else if (NT_SUCCESS (TCSendHostDeviceIoControlRequest (DeviceObject, Extension, IOCTL_DISK_GET_LENGTH_INFO, &diskLengthInfo, sizeof (diskLengthInfo)))) + else if (NT_SUCCESS(TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IOCTL_DISK_GET_LENGTH_INFO, &diskLengthInfo, sizeof(diskLengthInfo)))) { lDiskLength = diskLengthInfo; } ProbingHostDeviceForWrite = TRUE; if (!mount->bMountReadOnly - && TCSendHostDeviceIoControlRequest (DeviceObject, Extension, + && TCSendHostDeviceIoControlRequest(DeviceObject, Extension, IsHiddenSystemRunning() ? TC_IOCTL_DISK_IS_WRITABLE : IOCTL_DISK_IS_WRITABLE, NULL, 0) == STATUS_MEDIA_WRITE_PROTECTED) { mount->bMountReadOnly = TRUE; DeviceObject->Characteristics |= FILE_READ_ONLY_DEVICE; mount->VolumeMountedReadOnlyAfterDeviceWriteProtected = TRUE; } ProbingHostDeviceForWrite = FALSE; // Some Windows tools (e.g. diskmgmt, diskpart, vssadmin) fail or experience timeouts when there is a raw device // open for exclusive access. Therefore, exclusive access is used only for file-hosted volumes. // Applications requiring a consistent device image need to acquire exclusive write access first. This is prevented // when a device-hosted volume is mounted. exclusiveAccess = FALSE; } else { // Limit the maximum required buffer size if (mount->BytesPerSector > 128 * BYTES_PER_KB) { ntStatus = STATUS_INVALID_PARAMETER; goto error; } Extension->HostBytesPerSector = mount->BytesPerSector; Extension->HostBytesPerPhysicalSector = mount->BytesPerPhysicalSector; Extension->HostMaximumTransferLength = mount->MaximumTransferLength; Extension->HostMaximumPhysicalPages = mount->MaximumPhysicalPages; Extension->HostAlignmentMask = mount->AlignmentMask; @@ -910,60 +903,61 @@ error: void TCCloseVolume (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension) { UNREFERENCED_PARAMETER (DeviceObject); /* Remove compiler warning */ if (Extension->hDeviceFile != NULL) { if (Extension->bRawDevice == FALSE && Extension->bTimeStampValid) { RestoreTimeStamp (Extension); } ZwClose (Extension->hDeviceFile); } ObDereferenceObject (Extension->pfoDeviceFile); if (Extension->cryptoInfo) { crypto_close (Extension->cryptoInfo); Extension->cryptoInfo = NULL; } } typedef struct { PDEVICE_OBJECT deviceObject; PEXTENSION Extension; ULONG ioControlCode; void *inputBuffer; int inputBufferSize; void *outputBuffer; int outputBufferSize; NTSTATUS Status; KEVENT WorkItemCompletedEvent; } TCSendHostDeviceIoControlRequestExWorkItemArgs; static VOID TCSendHostDeviceIoControlRequestExWorkItemRoutine (PDEVICE_OBJECT rootDeviceObject, TCSendHostDeviceIoControlRequestExWorkItemArgs *arg) { + UNREFERENCED_PARAMETER(rootDeviceObject); /* Remove compiler warning */ arg->Status = TCSendHostDeviceIoControlRequestEx (arg->deviceObject, arg->Extension, arg->ioControlCode, arg->inputBuffer, arg->inputBufferSize, arg->outputBuffer, arg->outputBufferSize); KeSetEvent (&arg->WorkItemCompletedEvent, IO_NO_INCREMENT, FALSE); } NTSTATUS TCSendHostDeviceIoControlRequestEx (PDEVICE_OBJECT DeviceObject, PEXTENSION Extension, ULONG IoControlCode, void *InputBuffer, ULONG InputBufferSize, void *OutputBuffer, ULONG OutputBufferSize) { IO_STATUS_BLOCK IoStatusBlock; NTSTATUS ntStatus; PIRP Irp; UNREFERENCED_PARAMETER(DeviceObject); /* Remove compiler warning */ if ((KeGetCurrentIrql() >= APC_LEVEL) || VC_KeAreAllApcsDisabled()) { TCSendHostDeviceIoControlRequestExWorkItemArgs args; PIO_WORKITEM workItem = IoAllocateWorkItem (RootDeviceObject); if (!workItem) return STATUS_INSUFFICIENT_RESOURCES; args.deviceObject = DeviceObject; args.Extension = Extension; args.ioControlCode = IoControlCode; args.inputBuffer = InputBuffer; diff --git a/src/Driver/VolumeFilter.c b/src/Driver/VolumeFilter.c index 29d02673..b4bc8d2e 100644 --- a/src/Driver/VolumeFilter.c +++ b/src/Driver/VolumeFilter.c @@ -128,60 +128,61 @@ static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP static BOOL IsSystemVolumePartition (VolumeFilterExtension *Extension) { NTSTATUS status; BOOL bRet = FALSE; DriveFilterExtension *bootDriveExtension = GetBootDriveFilterExtension(); STORAGE_DEVICE_NUMBER storageDeviceNumber; if (!bootDriveExtension->SystemStorageDeviceNumberValid) TC_BUG_CHECK (STATUS_INVALID_PARAMETER); status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof (storageDeviceNumber)); if (NT_SUCCESS (status) && bootDriveExtension->SystemStorageDeviceNumber == storageDeviceNumber.DeviceNumber) { PARTITION_INFORMATION_EX partition; status = SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partition, sizeof (partition)); if (NT_SUCCESS (status) && partition.StartingOffset.QuadPart == bootDriveExtension->ConfiguredEncryptedAreaStart) { bRet = TRUE; } } return bRet; } static NTSTATUS DispatchControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { NTSTATUS status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); + UNREFERENCED_PARAMETER(DeviceObject); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); if (IsHiddenSystemRunning()) { switch (irpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_DISK_IS_WRITABLE: { // All volumes except the system volume must be read-only if (IsSystemVolumePartition(Extension)) { IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return TCCompleteDiskIrp (Irp, STATUS_SUCCESS, 0); } IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); ++HiddenSysLeakProtectionCount; return TCCompleteDiskIrp (Irp, STATUS_MEDIA_WRITE_PROTECTED, 0); } case TC_IOCTL_DISK_IS_WRITABLE: Dump ("TC_IOCTL_DISK_IS_WRITABLE pdo=%p\n", Extension->Pdo); if (!ProbingHostDeviceForWrite) break; // Probe the real state of the device as the user is mounting a TrueCrypt volume. @@ -243,77 +244,78 @@ static NTSTATUS DispatchPnp (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilter if (attachedDevice == DeviceObject || (attachedDevice->Flags & DO_POWER_PAGABLE)) DeviceObject->Flags |= DO_POWER_PAGABLE; ObDereferenceObject (attachedDevice); } return PassFilteredIrp (Extension->LowerDeviceObject, Irp, OnDeviceUsageNotificationCompleted, Extension); case IRP_MN_REMOVE_DEVICE: Dump ("IRP_MN_REMOVE_DEVICE volume pdo=%p\n", Extension->Pdo); IoReleaseRemoveLockAndWait (&Extension->Queue.RemoveLock, Irp); status = PassIrp (Extension->LowerDeviceObject, Irp); IoDetachDevice (Extension->LowerDeviceObject); IoDeleteDevice (DeviceObject); return status; default: status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); } return status; } -static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) +static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension) { NTSTATUS status; + UNREFERENCED_PARAMETER(DeviceObject); PoStartNextPowerIrp (Irp); status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); IoSkipCurrentIrpStackLocation (Irp); status = PoCallDriver (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } NTSTATUS VolumeFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) { VolumeFilterExtension *Extension = (VolumeFilterExtension *) DeviceObject->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); NTSTATUS status; ASSERT (!Extension->bRootDevice && Extension->IsVolumeFilterDevice); switch (irpSp->MajorFunction) { case IRP_MJ_DEVICE_CONTROL: return DispatchControl (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_PNP: return DispatchPnp (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_POWER: - return DispatchPower (DeviceObject, Irp, Extension, irpSp); + return DispatchPower (DeviceObject, Irp, Extension); default: status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } } diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c index 361b8aeb..2a5dc6a3 100644 --- a/src/Format/InPlace.c +++ b/src/Format/InPlace.c @@ -348,79 +348,79 @@ BOOL CheckRequirementsForNonSysInPlaceDec (HWND hwndDlg, const wchar_t *devicePa /* Admin rights */ if (!IsAdmin()) { // We rely on the wizard process to call us only when the whole wizard process has been elevated (so UAC // status can be ignored). In case the IsAdmin() detection somehow fails, we allow the user to continue. if (!silent) Warning ("ADMIN_PRIVILEGES_WARN_DEVICES", hwndDlg); } /* ---------- Checks that may require admin rights ----------- */ // [Currently none] return TRUE; } int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, volatile HANDLE *outHandle, WipeAlgorithmId wipeAlgorithm) { SHRINK_VOLUME_INFORMATION shrinkVolInfo; signed __int64 sizeToShrinkTo; int nStatus = ERR_SUCCESS; PCRYPTO_INFO cryptoInfo = NULL; PCRYPTO_INFO cryptoInfo2 = NULL; HANDLE dev = INVALID_HANDLE_VALUE; DWORD dwError; - char *header; + unsigned char *header; WCHAR dosDev[TC_MAX_PATH] = {0}; WCHAR devName[MAX_PATH] = {0}; int driveLetter = -1; WCHAR deviceName[MAX_PATH]; uint64 dataAreaSize; __int64 deviceSize; LARGE_INTEGER offset; DWORD dwResult; HWND hwndDlg = volParams->hwndDlg; SetNonSysInplaceEncUIStatus (NONSYS_INPLACE_ENC_STATUS_PREPARING); if (!CheckRequirementsForNonSysInPlaceEnc (hwndDlg, volParams->volumePath, FALSE)) return ERR_DONT_REPORT; - header = (char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); + header = (unsigned char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (!header) return ERR_OUTOFMEMORY; VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); deviceSize = GetDeviceSize (volParams->volumePath); if (deviceSize < 0) { // Cannot determine the size of the partition nStatus = ERR_PARAMETER_INCORRECT; goto closing_seq; } if (deviceSize < TC_NONSYS_INPLACE_ENC_MIN_VOL_SIZE) { ShowInPlaceEncErrMsgWAltSteps (hwndDlg, "PARTITION_TOO_SMALL_FOR_NONSYS_INPLACE_ENC", TRUE); nStatus = ERR_DONT_REPORT; goto closing_seq; } dataAreaSize = GetVolumeDataAreaSize (volParams->hiddenVol, deviceSize); StringCchCopyW (deviceName, ARRAYSIZE(deviceName), volParams->volumePath); driveLetter = GetDiskDeviceDriveLetter (deviceName); if (FakeDosNameForDevice (volParams->volumePath, dosDev, sizeof(dosDev),devName, sizeof(devName),FALSE) != 0) { nStatus = ERR_OS_ERROR; @@ -573,61 +573,61 @@ int EncryptPartitionInPlaceBegin (volatile FORMAT_VOL_PARAMETERS *volParams, vol nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, header, volParams->ea, FIRST_MODE_OF_OPERATION_ID, volParams->password, volParams->pkcs5, volParams->pim, wipePass == 0 ? NULL : (char *) cryptoInfo->master_keydata, &cryptoInfo, dataAreaSize, 0, TC_VOLUME_DATA_OFFSET + dataAreaSize, // Start of the encrypted area = the first byte of the backup heeader (encrypting from the end) 0, // No data is encrypted yet 0, volParams->headerFlags | TC_HEADER_FLAG_NONSYS_INPLACE_ENC, volParams->sectorSize, wipeAlgorithm == TC_WIPE_NONE ? FALSE : (wipePass < PRAND_HEADER_WIPE_PASSES - 1)); if (nStatus != 0) goto closing_seq; offset.QuadPart = TC_VOLUME_DATA_OFFSET + dataAreaSize; if (!MoveFilePointer (dev, offset)) { nStatus = ERR_OS_ERROR; goto closing_seq; } // Write the backup header to the partition - if (!WriteEffectiveVolumeHeader (TRUE, dev, (uint8 *) header)) + if (!WriteEffectiveVolumeHeader (TRUE, dev, header)) { nStatus = ERR_OS_ERROR; goto closing_seq; } // Fill the reserved sectors of the backup header area with random data nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, TRUE); if (nStatus != ERR_SUCCESS) goto closing_seq; // write fake hidden volume header to protect against attacks that use statistical entropy // analysis to detect presence of hidden volumes nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE, header, volParams->ea, FIRST_MODE_OF_OPERATION_ID, NULL, 0, 0, NULL, &dummyInfo, dataAreaSize, dataAreaSize, TC_VOLUME_DATA_OFFSET + dataAreaSize, // Start of the encrypted area = the first byte of the backup heeader (encrypting from the end) dataAreaSize, // No data is encrypted yet 0, volParams->headerFlags | TC_HEADER_FLAG_NONSYS_INPLACE_ENC, volParams->sectorSize, wipeAlgorithm == TC_WIPE_NONE ? FALSE : (wipePass < PRAND_HEADER_WIPE_PASSES - 1)); @@ -726,98 +726,98 @@ closing_seq: if (cryptoInfo2 != NULL) { crypto_close (cryptoInfo2); cryptoInfo2 = NULL; } burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); TCfree (header); if (dosDev[0]) RemoveFakeDosName (volParams->volumePath, dosDev); *outHandle = dev; if (nStatus != ERR_SUCCESS) SetLastError (dwError); return nStatus; } int EncryptPartitionInPlaceResume (HANDLE dev, volatile FORMAT_VOL_PARAMETERS *volParams, WipeAlgorithmId wipeAlgorithm, volatile BOOL *bTryToCorrectReadErrors) { PCRYPTO_INFO masterCryptoInfo = NULL, headerCryptoInfo = NULL, tmpCryptoInfo = NULL; UINT64_STRUCT unitNo; - char *buf = NULL, *header = NULL; + unsigned char *buf = NULL, *header = NULL; uint8 *wipeBuffer = NULL; uint8 wipeRandChars [TC_WIPE_RAND_CHAR_COUNT]; uint8 wipeRandCharsUpdate [TC_WIPE_RAND_CHAR_COUNT]; WCHAR dosDev[TC_MAX_PATH] = {0}; WCHAR devName[MAX_PATH] = {0}; WCHAR deviceName[MAX_PATH]; int nStatus = ERR_SUCCESS; __int64 deviceSize; uint64 remainingBytes, lastHeaderUpdateDistance = 0, zeroedSectorCount = 0; uint32 workChunkSize; DWORD dwError, dwResult; BOOL bPause = FALSE, bEncryptedAreaSizeChanged = FALSE; LARGE_INTEGER offset; int sectorSize; int i; DWORD n; WCHAR *devicePath = volParams->volumePath; Password *password = volParams->password; int pkcs5_prf = volParams->pkcs5; int pim = volParams->pim; DISK_GEOMETRY driveGeometry; HWND hwndDlg = volParams->hwndDlg; #ifdef _WIN64 BOOL bIsRamEncryptionEnabled = IsRamEncryptionEnabled(); #endif bInPlaceEncNonSysResumed = TRUE; - buf = (char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); + buf = (unsigned char *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); if (!buf) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } - header = (char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); + header = (unsigned char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (!header) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (wipeAlgorithm != TC_WIPE_NONE) { wipeBuffer = (uint8 *) TCalloc (TC_MAX_NONSYS_INPLACE_ENC_WORK_CHUNK_SIZE); if (!wipeBuffer) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } } headerCryptoInfo = crypto_open(); if (headerCryptoInfo == NULL) { nStatus = ERR_OUTOFMEMORY; goto closing_seq; } deviceSize = GetDeviceSize (devicePath); if (deviceSize < 0) { // Cannot determine the size of the partition @@ -2274,75 +2274,75 @@ int ZeroUnreadableSectors (HANDLE dev, LARGE_INTEGER startOffset, int64 size, in nStatus = ERR_OS_ERROR; goto closing_seq; } ++(*zeroedSectorCount); } workOffset.QuadPart += n; } nStatus = ERR_SUCCESS; closing_seq: dwError = GetLastError(); if (sectorBuffer != NULL) TCfree (sectorBuffer); if (nStatus != ERR_SUCCESS) SetLastError (dwError); return nStatus; } static int OpenBackupHeader (HANDLE dev, const wchar_t *devicePath, Password *password, int pkcs5, int pim, PCRYPTO_INFO *retMasterCryptoInfo, CRYPTO_INFO *headerCryptoInfo, __int64 deviceSize) { LARGE_INTEGER offset; DWORD n; int nStatus = ERR_SUCCESS; - char *header; + unsigned char *header; DWORD dwError; - header = (char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); + header = (unsigned char *) TCalloc (TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (!header) return ERR_OUTOFMEMORY; VirtualLock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); offset.QuadPart = deviceSize - TC_VOLUME_HEADER_GROUP_SIZE; if (MoveFilePointer (dev, offset) == 0 - || !ReadEffectiveVolumeHeader (TRUE, dev, (uint8 *) header, &n) || n < TC_VOLUME_HEADER_EFFECTIVE_SIZE) + || !ReadEffectiveVolumeHeader (TRUE, dev, header, &n) || n < TC_VOLUME_HEADER_EFFECTIVE_SIZE) { nStatus = ERR_OS_ERROR; goto closing_seq; } nStatus = ReadVolumeHeader (FALSE, header, password, pkcs5, pim, retMasterCryptoInfo, headerCryptoInfo); if (nStatus != ERR_SUCCESS) goto closing_seq; closing_seq: dwError = GetLastError(); burn (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); VirtualUnlock (header, TC_VOLUME_HEADER_EFFECTIVE_SIZE); TCfree (header); dwError = GetLastError(); if (nStatus != ERR_SUCCESS) SetLastError (dwError); return nStatus; } static BOOL GetFreeClusterBeforeThreshold (HANDLE volumeHandle, int64 *freeCluster, int64 clusterThreshold) { diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index a851ebef..6ae6e417 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -4215,79 +4215,79 @@ BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP s = GetString ("UISTR_YES"); else if (prop.hiddenVolProtection == HIDVOL_PROT_STATUS_ACTION_TAKEN) s = GetString ("HID_VOL_DAMAGE_PREVENTED"); ListSubItemSet (list, i++, 1, s); } // Encryption algorithm ListItemAdd (list, i, GetString ("ENCRYPTION_ALGORITHM")); if (prop.ea < EAGetFirst() || prop.ea > EAGetCount ()) { ListSubItemSet (list, i, 1, L"?"); return 1; } EAGetName (szTmp, ARRAYSIZE(szTmp), prop.ea, 1); ListSubItemSet (list, i++, 1, szTmp); // Key size(s) { wchar_t name[128]; int size = EAGetKeySize (prop.ea); EAGetName (name, ARRAYSIZE(name), prop.ea, 1); // Primary key ListItemAdd (list, i, GetString ("KEY_SIZE")); StringCbPrintfW (sw, sizeof(sw), L"%d %s", size * 8, GetString ("BITS")); ListSubItemSet (list, i++, 1, sw); - if (wcscmp (EAGetModeName (prop.ea, prop.mode, TRUE), L"XTS") == 0) + if (wcscmp (EAGetModeName (prop.mode), L"XTS") == 0) { // Secondary key (XTS) ListItemAdd (list, i, GetString ("SECONDARY_KEY_SIZE_XTS")); ListSubItemSet (list, i++, 1, sw); } } // Block size ListItemAdd (list, i, GetString ("BLOCK_SIZE")); StringCbPrintfW (sw, sizeof(sw), L"%d ", CipherGetBlockSize (EAGetFirstCipher(prop.ea))*8); StringCbCatW (sw, sizeof(sw), GetString ("BITS")); ListSubItemSet (list, i++, 1, sw); // Mode ListItemAdd (list, i, GetString ("MODE_OF_OPERATION")); - ListSubItemSet (list, i++, 1, EAGetModeName (prop.ea, prop.mode, TRUE)); + ListSubItemSet (list, i++, 1, EAGetModeName (prop.mode)); // PKCS 5 PRF ListItemAdd (list, i, GetString ("PKCS5_PRF")); if (prop.volumePim == 0) ListSubItemSet (list, i++, 1, get_pkcs5_prf_name (prop.pkcs5)); else { StringCbPrintfW (szTmp, sizeof(szTmp), L"%s (Dynamic)", get_pkcs5_prf_name (prop.pkcs5)); ListSubItemSet (list, i++, 1, szTmp); } #if 0 // PCKS 5 iterations ListItemAdd (list, i, GetString ("PKCS5_ITERATIONS")); sprintf (szTmp, "%d", prop.pkcs5Iterations); ListSubItemSet (list, i++, 1, szTmp); #endif #if 0 { // Legacy FILETIME ft, curFt; LARGE_INTEGER ft64, curFt64; SYSTEMTIME st; wchar_t date[128]; memset (date, 0, sizeof (date)); // Volume date ListItemAdd (list, i, GetString ("VOLUME_CREATE_DATE")); @@ -11020,67 +11020,67 @@ noHidden: SetRandomPoolEnrichedByUserStatus (FALSE); NormalCursor(); UserEnrichRandomPool (hwndDlg); WaitCursor(); // Temporary keys if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (volume.CryptoInfo->ea), TRUE) || !RandgetBytes (hwndDlg, volume.CryptoInfo->k2, sizeof (volume.CryptoInfo->k2), FALSE)) { nStatus = ERR_PARAMETER_INCORRECT; goto error; } if (EAInit (volume.CryptoInfo->ea, temporaryKey, volume.CryptoInfo->ks) != ERR_SUCCESS || !EAInitMode (volume.CryptoInfo, volume.CryptoInfo->k2)) { nStatus = ERR_PARAMETER_INCORRECT; goto error; } EncryptBuffer (backup, backupFileSize, volume.CryptoInfo); memcpy (volume.CryptoInfo->k2, originalK2, sizeof (volume.CryptoInfo->k2)); if (EAInit (volume.CryptoInfo->ea, volume.CryptoInfo->master_keydata, volume.CryptoInfo->ks) != ERR_SUCCESS || !EAInitMode (volume.CryptoInfo, volume.CryptoInfo->k2)) { nStatus = ERR_PARAMETER_INCORRECT; goto error; } // Store header encrypted with a new key - nStatus = ReEncryptVolumeHeader (hwndDlg, (char *) backup, FALSE, volume.CryptoInfo, &VolumePassword, VolumePim, FALSE); + nStatus = ReEncryptVolumeHeader (hwndDlg, backup, FALSE, volume.CryptoInfo, &VolumePassword, VolumePim, FALSE); if (nStatus != ERR_SUCCESS) goto error; if (hiddenVolume.VolumeIsOpen) { - nStatus = ReEncryptVolumeHeader (hwndDlg, (char *) backup + (legacyVolume ? TC_VOLUME_HEADER_SIZE_LEGACY : TC_VOLUME_HEADER_SIZE), + nStatus = ReEncryptVolumeHeader (hwndDlg, backup + (legacyVolume ? TC_VOLUME_HEADER_SIZE_LEGACY : TC_VOLUME_HEADER_SIZE), FALSE, hiddenVolume.CryptoInfo, &hiddenVolPassword, hiddenVolPim, FALSE); if (nStatus != ERR_SUCCESS) goto error; } if (_write (fBackup, backup, backupFileSize) == -1) { nStatus = ERR_OS_ERROR; goto error; } /* Backup has been successfully created */ Warning("VOL_HEADER_BACKED_UP", hwndDlg); ret: nStatus = ERR_SUCCESS; error: DWORD dwError = GetLastError (); CloseVolume (&volume); CloseVolume (&hiddenVolume); if (fBackup != -1) _close (fBackup); SetLastError (dwError); if (nStatus != 0) handleError (hwndDlg, nStatus, SRC_POS); @@ -11211,61 +11211,61 @@ int RestoreVolumeHeader (HWND hwndDlg, const wchar_t *lpszVolume) burn (&GuiPkcs5, sizeof (GuiPkcs5)); burn (&GuiPim, sizeof (GuiPim)); } WaitCursor(); if (KeyFilesEnable && FirstKeyFile) KeyFilesApply (hwndDlg, &VolumePassword, FirstKeyFile, lpszVolume); nStatus = OpenVolume (&volume, lpszVolume, &VolumePassword, VolumePkcs5, VolumePim,TRUE, bPreserveTimestamp, TRUE); NormalCursor(); if (nStatus == ERR_SUCCESS) break; if (nStatus != ERR_PASSWORD_WRONG) goto error; handleError (hwndDlg, nStatus, SRC_POS); } if (volume.CryptoInfo->LegacyVolume) { Error ("VOLUME_HAS_NO_BACKUP_HEADER", hwndDlg); nStatus = ERROR_SUCCESS; goto error; } // Create a new header with a new salt - char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; + unsigned char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE]; nStatus = ReEncryptVolumeHeader (hwndDlg, buffer, FALSE, volume.CryptoInfo, &VolumePassword, VolumePim, FALSE); if (nStatus != 0) goto error; headerOffset.QuadPart = volume.CryptoInfo->hiddenVolume ? TC_HIDDEN_VOLUME_HEADER_OFFSET : TC_VOLUME_HEADER_OFFSET; if (!SetFilePointerEx (volume.HostFileHandle, headerOffset, NULL, FILE_BEGIN)) { nStatus = ERR_OS_ERROR; goto error; } if (!WriteEffectiveVolumeHeader (volume.IsDevice, volume.HostFileHandle, (uint8 *) buffer)) { nStatus = ERR_OS_ERROR; goto error; } } else { // Restore header from an external backup StringCbPrintfW (szTmp, sizeof(szTmp), GetString ("CONFIRM_VOL_HEADER_RESTORE"), lpszVolume); if (MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2) == IDNO) { nStatus = ERR_SUCCESS; goto ret; } @@ -11371,61 +11371,61 @@ int RestoreVolumeHeader (HWND hwndDlg, const wchar_t *lpszVolume) } else { goto error; } } else hostSize = ((PDISK_GEOMETRY_EX) dgBuffer)->DiskSize.QuadPart; } if (hostSize == 0) { nStatus = ERR_VOL_SIZE_WRONG; goto error; } } else { LARGE_INTEGER fileSize; if (!GetFileSizeEx (dev, &fileSize)) { nStatus = ERR_OS_ERROR; goto error; } hostSize = fileSize.QuadPart; } /* Read the volume header from the backup file */ - char buffer[TC_VOLUME_HEADER_GROUP_SIZE]; + unsigned char buffer[TC_VOLUME_HEADER_GROUP_SIZE]; DWORD bytesRead; if (!ReadFile (fBackup, buffer, sizeof (buffer), &bytesRead, NULL)) { nStatus = ERR_OS_ERROR; goto error; } if (bytesRead != backupSize.QuadPart) { nStatus = ERR_VOL_SIZE_WRONG; goto error; } LARGE_INTEGER headerOffset; LARGE_INTEGER headerBackupOffset; bool legacyBackup; int headerOffsetBackupFile; // Determine the format of the backup file switch (backupSize.QuadPart) { case TC_VOLUME_HEADER_GROUP_SIZE: legacyBackup = false; break; case TC_VOLUME_HEADER_SIZE_LEGACY * 2: legacyBackup = true; break; diff --git a/src/Volume/Pkcs5Kdf.cpp b/src/Volume/Pkcs5Kdf.cpp index 820f1121..e7392d0c 100644 --- a/src/Volume/Pkcs5Kdf.cpp +++ b/src/Volume/Pkcs5Kdf.cpp @@ -47,78 +47,78 @@ namespace VeraCrypt return kdf; } throw ParameterIncorrect (SRC_POS); } Pkcs5KdfList Pkcs5Kdf::GetAvailableAlgorithms () { Pkcs5KdfList l; l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacSha512 ())); l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacSha256 ())); #ifndef WOLFCRYPT_BACKEND l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacBlake2s ())); l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacWhirlpool ())); l.push_back (shared_ptr <Pkcs5Kdf> (new Pkcs5HmacStreebog ())); #endif return l; } void Pkcs5Kdf::ValidateParameters (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { if (key.Size() < 1 || password.Size() < 1 || salt.Size() < 1 || iterationCount < 1) throw ParameterIncorrect (SRC_POS); } #ifndef WOLFCRYPT_BACKEND void Pkcs5HmacBlake2s_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_blake2s ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } void Pkcs5HmacBlake2s::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_blake2s ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_blake2s (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } #endif void Pkcs5HmacSha256_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_sha256 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } void Pkcs5HmacSha256::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_sha256 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_sha256 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } void Pkcs5HmacSha512::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_sha512 ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_sha512 (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } #ifndef WOLFCRYPT_BACKEND void Pkcs5HmacWhirlpool::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_whirlpool ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_whirlpool (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } void Pkcs5HmacStreebog::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_streebog ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } void Pkcs5HmacStreebog_Boot::DeriveKey (const BufferPtr &key, const VolumePassword &password, const ConstBufferPtr &salt, int iterationCount) const { ValidateParameters (key, password, salt, iterationCount); - derive_key_streebog ((char *) password.DataPtr(), (int) password.Size(), (char *) salt.Get(), (int) salt.Size(), iterationCount, (char *) key.Get(), (int) key.Size()); + derive_key_streebog (password.DataPtr(), (int) password.Size(), salt.Get(), (int) salt.Size(), iterationCount, key.Get(), (int) key.Size()); } #endif } |