From 246233c40262c5be2edfa916cf841dd4bce6598e Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 9 Aug 2016 22:08:47 +0200 Subject: Windows EFI Bootloader: modifications to prepare EFI system encryption support (common files with DcsBoot) --- src/Boot/Windows/BootCommon.h | 101 +++++++++++++++++++++++++++++++++++++++++- src/Boot/Windows/BootDefs.h | 9 ++++ src/Common/Common.rc | 10 +++-- src/Common/Crypto.c | 86 ++++++++++++++++++----------------- src/Common/Crypto.h | 24 +++++----- src/Common/Endian.h | 14 +++--- src/Common/Password.h | 16 +++---- src/Common/Pkcs5.c | 59 ++++++++++++------------ src/Common/Resource.h | 8 +++- src/Common/Tcdefs.h | 91 +++++++++++++++++++++++++++++++++++-- src/Common/Volumes.c | 58 +++++++++++++++++------- src/Common/Volumes.h | 22 +++++---- src/Common/Xml.c | 18 +++++--- src/Common/Xml.h | 13 +++--- src/Crypto/Rmd160.c | 12 ++--- src/Crypto/Serpent.c | 2 + src/Crypto/Sha2.c | 6 ++- src/Crypto/Whirlpool.c | 24 +++++----- src/Crypto/cpu.c | 20 ++++++--- src/Crypto/cpu.h | 8 ++-- src/Crypto/misc.h | 14 +++--- src/Driver/DriveFilter.c | 92 ++++++++++++++++++++------------------ 22 files changed, 491 insertions(+), 216 deletions(-) diff --git a/src/Boot/Windows/BootCommon.h b/src/Boot/Windows/BootCommon.h index 0d4f710d..bc1300b9 100644 --- a/src/Boot/Windows/BootCommon.h +++ b/src/Boot/Windows/BootCommon.h @@ -3,7 +3,7 @@ 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) + Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2016 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 @@ -78,5 +78,104 @@ typedef struct #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(TC_WINDOWS_BOOT) + +#define DCS_DISK_ENTRY_LIST_HEADER_ID SIGNATURE_64 ('D','C','S','D','E','L','S','T') + +#define DE_IDX_CRYPTOHEADER 0 +#define DE_IDX_LIST 1 +#define DE_IDX_DISKID 2 +#define DE_IDX_MAINGPTHDR 3 +#define DE_IDX_MAINGPTENTRYS 4 +#define DE_IDX_ALTGPTHDR 5 +#define DE_IDX_ALTGPTENTRYS 6 +#define DE_IDX_EXECPARAMS 7 +#define DE_IDX_PWDCACHE 8 +#define DE_IDX_TOTAL 9 + +enum DcsDiskEntryTypes { + DE_Unused = 0, + DE_Sectors, + DE_List, + DE_DISKID, + DE_ExecParams, + DE_PwdCache +}; + +#pragma pack(1) +typedef struct _SECREGION_BOOT_PARAMS { + uint64 Ptr; + uint32 Size; + uint32 Crc; +} SECREGION_BOOT_PARAMS; + +typedef struct _DCS_DISK_ENTRY_SECTORS { + uint32 Type; + uint32 Offset; + uint64 Reserved; + uint64 Start; + uint64 Length; +} DCS_DISK_ENTRY_SECTORS; + +typedef struct { + uint32 Data1; + uint16 Data2; + uint16 Data3; + byte Data4[8]; +} DCS_GUID; + +typedef struct _DCS_DISK_ENTRY_DISKID { + uint32 Type; + uint32 MbrID; + uint64 ReservedDiskId; + DCS_GUID GptID; +} DCS_DISK_ENTRY_DISKID; + +typedef struct _DCS_DISK_ENTRY_EXEC_PARAMS { + DCS_GUID ExecPartGuid; + uint16 ExecCmd[248]; +} DCS_DISK_ENTRY_EXEC_PARAMS; +static_assert(sizeof(DCS_DISK_ENTRY_EXEC_PARAMS) == 512, "Wrong size DCS_DISK_ENTRY_EXEC_PARAMS"); + +#define DCS_DISK_ENTRY_PWD_CACHE_ID SIGNATURE_64 ('P','W','D','C','A','C','H','E') +typedef struct _DCS_DISK_ENTRY_PWD_CACHE { + uint64 Sign; + uint32 CRC; + uint32 Count; + Password Pwd[4]; + int32 Pim[4]; + byte pad[512 -8 - 4 - 4 - (sizeof(Password) + 4) * 4]; +} DCS_DISK_ENTRY_PWD_CACHE; +static_assert(sizeof(DCS_DISK_ENTRY_PWD_CACHE) == 512, "Wrong size DCS_DISK_ENTRY_PWD_CACHE"); + +#pragma warning(disable:4201) +typedef struct _DCS_DISK_ENTRY { + union { + struct { + uint32 Type; + byte Data[28]; + }; + DCS_DISK_ENTRY_SECTORS Sectors; + DCS_DISK_ENTRY_DISKID DiskId; + }; +} DCS_DISK_ENTRY; +#pragma warning(default:4201) + +typedef struct _DCS_DISK_ENTRY_LIST { + // EFI_TABLE_HEADER + uint64 Signature; + uint32 Revision; + uint32 HeaderSize; //< The size, in bytes, of the entire table including the EFI_TABLE_HEADER. + uint32 CRC32; //< The 32-bit CRC for the entire table. This value is computed by setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes. + uint32 Reserved; //< Reserved field that must be set to 0. + // + uint32 Count; + uint32 DataSize; + // + DCS_DISK_ENTRY DE[31]; +} DCS_DISK_ENTRY_LIST; +#pragma pack() + +#endif #endif // TC_HEADER_Boot_BootCommon diff --git a/src/Boot/Windows/BootDefs.h b/src/Boot/Windows/BootDefs.h index fe245a89..3db227fd 100644 --- a/src/Boot/Windows/BootDefs.h +++ b/src/Boot/Windows/BootDefs.h @@ -102,6 +102,7 @@ #define TC__BOOT_USER_CFG_FLAG_DISABLE_ESC TC_HEX (02) #define TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC_HEX (04) #define TC__BOOT_USER_CFG_FLAG_DISABLE_PIM TC_HEX (08) +#define TC__BOOT_USER_CFG_FLAG_STORE_HASH TC_HEX (10) // The following items are treated as a 2-bit value (apply TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE to obtain the value) #define TC__HIDDEN_OS_CREATION_PHASE_NONE 0 @@ -191,6 +192,7 @@ TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED #define TC_BOOT_USER_CFG_FLAG_DISABLE_ESC TC__BOOT_USER_CFG_FLAG_DISABLE_ESC #define TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION TC__BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION #define TC_BOOT_USER_CFG_FLAG_DISABLE_PIM TC__BOOT_USER_CFG_FLAG_DISABLE_PIM +#define TC_BOOT_USER_CFG_FLAG_STORE_HASH TC__BOOT_USER_CFG_FLAG_STORE_HASH #define TC_HIDDEN_OS_CREATION_PHASE_NONE TC__HIDDEN_OS_CREATION_PHASE_NONE #define TC_HIDDEN_OS_CREATION_PHASE_CLONING TC__HIDDEN_OS_CREATION_PHASE_CLONING #define TC_HIDDEN_OS_CREATION_PHASE_WIPING TC__HIDDEN_OS_CREATION_PHASE_WIPING @@ -198,4 +200,11 @@ TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED #endif // TC_ASM_PREPROCESS +#define EFI_BOOTARGS_REGIONS_LOW 0x90000, 0x88000, 0x80000 +#define EFI_BOOTARGS_REGIONS_HIGH \ +0x100000, 0x200000, 0x300000, 0x400000, 0x500000, 0x600000, 0x700000, 0x800000, \ +0x900000, 0xA00000, 0xB00000, 0xC00000, 0xD00000, 0xE00000, 0xF00000, 0x1000000 + +#define EFI_BOOTARGS_REGIONS EFI_BOOTARGS_REGIONS_LOW, EFI_BOOTARGS_REGIONS_HIGH + #endif // TC_HEADER_Boot_BootDefs diff --git a/src/Common/Common.rc b/src/Common/Common.rc index c87dcb75..d082dc3e 100644 --- a/src/Common/Common.rc +++ b/src/Common/Common.rc @@ -532,6 +532,10 @@ IDR_RESCUE_LOADER_AES_SHA2 BIN "..\\Boot\\Windows\\Rescue_AE IDR_RESCUE_LOADER_SERPENT_SHA2 BIN "..\\Boot\\Windows\\Rescue_Serpent_SHA2\\BootLoader.com.gz" IDR_RESCUE_LOADER_TWOFISH_SHA2 BIN "..\\Boot\\Windows\\Rescue_Twofish_SHA2\\BootLoader.com.gz" IDR_RESCUE_LOADER_CAMELLIA_SHA2 BIN "..\\Boot\\Windows\\Rescue_Camellia_SHA2\\BootLoader.com.gz" +IDR_EFI_DCSBOOT BIN "..\\Boot\\EFI\\DcsBoot.efi" +IDR_EFI_DCSINT BIN "..\\Boot\\EFI\\DcsInt.efi" +IDR_EFI_DCSCFG BIN "..\\Boot\\EFI\\DcsCfg.efi" +IDR_EFI_LEGACYSPEAKER BIN "..\\Boot\\EFI\\LegacySpeaker.efi" ///////////////////////////////////////////////////////////////////////////// // @@ -560,18 +564,18 @@ IDR_LICENSE TEXT "..\\Resources\\Texts\\License.r // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "\r\n" "\0" diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index 69d5b5dc..e9a3da68 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -1,11 +1,11 @@ /* 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 + 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 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-2016 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 @@ -16,10 +16,12 @@ #include "Xts.h" #include "Crc.h" #include "Common/Endian.h" +#if !defined(_UEFI) #include #ifndef TC_WINDOWS_BOOT #include "EncryptionThreadPool.h" #endif +#endif #include "Volumes.h" #include "cpu.h" @@ -71,21 +73,21 @@ static EncryptionAlgorithm EncryptionAlgorithms[] = #ifndef TC_WINDOWS_BOOT - { { 0, 0 }, { 0, 0}, 0 }, // Must be all-zero - { { AES, 0 }, { XTS, 0 }, 1 }, - { { SERPENT, 0 }, { XTS, 0 }, 1 }, - { { TWOFISH, 0 }, { XTS, 0 }, 1 }, - { { CAMELLIA, 0 }, { XTS, 0 }, 1 }, + { { 0, 0 }, { 0, 0}, 0 }, // Must be all-zero + { { AES, 0 }, { XTS, 0 }, 1 }, + { { SERPENT, 0 }, { XTS, 0 }, 1 }, + { { TWOFISH, 0 }, { XTS, 0 }, 1 }, + { { CAMELLIA, 0 }, { XTS, 0 }, 1 }, #if defined(CIPHER_GOST89) - { { GOST89, 0 }, { XTS, 0 }, 1 }, + { { GOST89, 0 }, { XTS, 0 }, 1 }, #endif // defined(CIPHER_GOST89) { { KUZNYECHIK, 0 }, { XTS, 0 }, 1 }, - { { TWOFISH, AES, 0 }, { XTS, 0 }, 1 }, + { { TWOFISH, AES, 0 }, { XTS, 0 }, 1 }, { { SERPENT, TWOFISH, AES, 0 }, { XTS, 0 }, 1 }, - { { AES, SERPENT, 0 }, { XTS, 0 }, 1 }, + { { AES, SERPENT, 0 }, { XTS, 0 }, 1 }, { { AES, TWOFISH, SERPENT, 0 }, { XTS, 0 }, 1 }, { { SERPENT, TWOFISH, 0 }, { XTS, 0 }, 1 }, - { { 0, 0 }, { 0, 0}, 0 } // Must be all-zero + { { 0, 0 }, { 0, 0}, 0 } // Must be all-zero #else // TC_WINDOWS_BOOT @@ -109,11 +111,11 @@ static EncryptionAlgorithm EncryptionAlgorithms[] = #ifndef TC_WINDOWS_BOOT // Hash algorithms static Hash Hashes[] = -{ // ID Name Deprecated System Encryption - { SHA512, L"SHA-512", FALSE, FALSE }, - { WHIRLPOOL, L"Whirlpool", FALSE, FALSE }, - { SHA256, L"SHA-256", FALSE, TRUE }, - { RIPEMD160, L"RIPEMD-160", TRUE, TRUE }, +{ // ID Name Deprecated System Encryption + { SHA512, L"SHA-512", FALSE, FALSE }, + { WHIRLPOOL, L"Whirlpool", FALSE, FALSE }, + { SHA256, L"SHA-256", FALSE, TRUE }, + { RIPEMD160, L"RIPEMD-160", TRUE, TRUE }, { STREEBOG, L"Streebog", FALSE, FALSE }, { 0, 0, 0 } }; @@ -142,11 +144,11 @@ int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks) case SERPENT: serpent_set_key (key, ks); break; - + case TWOFISH: twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key); break; - + #if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA) case CAMELLIA: camellia_set_key (key, ks); @@ -176,7 +178,7 @@ void EncipherBlock(int cipher, void *data, void *ks) { switch (cipher) { - case AES: + case AES: // In 32-bit kernel mode, due to KeSaveFloatingPointState() overhead, AES instructions can be used only when processing the whole data unit. #if (defined (_WIN64) || !defined (TC_WINDOWS_DRIVER)) && !defined (TC_WINDOWS_BOOT) if (IsAesHwCpuSupported()) @@ -456,11 +458,11 @@ BOOL EAInitMode (PCRYPTO_INFO ci) /* Note: XTS mode could potentially be initialized with a weak key causing all blocks in one data unit on the volume to be tweaked with zero tweaks (i.e. 512 bytes of the volume would be encrypted in ECB mode). However, to create a TrueCrypt volume with such a weak key, each human being on Earth would have - to create approximately 11,378,125,361,078,862 (about eleven quadrillion) TrueCrypt volumes (provided + to create approximately 11,378,125,361,078,862 (about eleven quadrillion) TrueCrypt volumes (provided that the size of each of the volumes is 1024 terabytes). */ break; - default: + default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } @@ -507,8 +509,12 @@ int EAGetByName (wchar_t *name) do { - EAGetName (n, ea, 1); - if (_wcsicmp (n, name) == 0) + EAGetName(n, ea, 1); +#if defined(_UEFI) + if (wcscmp(n, name) == 0) +#else + if (_wcsicmp(n, name) == 0) +#endif return ea; } while (ea = EAGetNext (ea)); @@ -545,7 +551,7 @@ int EAGetNextMode (int ea, int previousModeId) int c, i = 0; while (c = EncryptionAlgorithms[ea].Modes[i++]) { - if (c == previousModeId) + if (c == previousModeId) return EncryptionAlgorithms[ea].Modes[i]; } @@ -648,7 +654,7 @@ int EAGetNextCipher (int ea, int previousCipherId) int c, i = 0; while (c = EncryptionAlgorithms[ea].Ciphers[i++]) { - if (c == previousCipherId) + if (c == previousCipherId) return EncryptionAlgorithms[ea].Ciphers[i]; } @@ -665,7 +671,7 @@ int EAGetPreviousCipher (int ea, int previousCipherId) while (c = EncryptionAlgorithms[ea].Ciphers[i++]) { - if (c == previousCipherId) + if (c == previousCipherId) return EncryptionAlgorithms[ea].Ciphers[i - 2]; } @@ -777,7 +783,7 @@ PCRYPTO_INFO crypto_open () memset (cryptoInfo, 0, sizeof (CRYPTO_INFO)); -#ifndef DEVICE_DRIVER +#if !defined(DEVICE_DRIVER) && !defined(_UEFI) VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO)); #endif @@ -812,7 +818,7 @@ void crypto_close (PCRYPTO_INFO cryptoInfo) if (cryptoInfo != NULL) { burn (cryptoInfo, sizeof (CRYPTO_INFO)); -#ifndef DEVICE_DRIVER +#if !defined(DEVICE_DRIVER) && !defined(_UEFI) VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO)); #endif TCfree (cryptoInfo); @@ -834,7 +840,7 @@ void crypto_close (PCRYPTO_INFO cryptoInfo) // EncryptBuffer // // buf: data to be encrypted; the start of the buffer is assumed to be aligned with the start of a data unit. -// len: number of bytes to encrypt; must be divisible by the block size (for cascaded ciphers, divisible +// len: number of bytes to encrypt; must be divisible by the block size (for cascaded ciphers, divisible // by the largest block size used within the cascade) void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo) { @@ -865,7 +871,7 @@ void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_ } break; - default: + default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } @@ -876,7 +882,7 @@ void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_ // unitNo: sequential number of the data unit with which the buffer starts // nbrUnits: number of data units in the buffer void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci) -#ifndef TC_WINDOWS_BOOT +#if !defined(TC_WINDOWS_BOOT) && !defined(_UEFI) { EncryptionThreadPoolDoWork (EncryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci); } @@ -907,7 +913,7 @@ void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *s } break; - default: + default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } @@ -916,7 +922,7 @@ void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *s // DecryptBuffer // // buf: data to be decrypted; the start of the buffer is assumed to be aligned with the start of a data unit. -// len: number of bytes to decrypt; must be divisible by the block size (for cascaded ciphers, divisible +// len: number of bytes to decrypt; must be divisible by the block size (for cascaded ciphers, divisible // by the largest block size used within the cascade) void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo) { @@ -947,7 +953,7 @@ void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_ } break; - default: + default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } @@ -957,7 +963,7 @@ void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_ // unitNo: sequential number of the data unit with which the buffer starts // nbrUnits: number of data units in the buffer void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci) -#ifndef TC_WINDOWS_BOOT +#if !defined(TC_WINDOWS_BOOT) && !defined(_UEFI) { EncryptionThreadPoolDoWork (DecryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci); } @@ -992,7 +998,7 @@ void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *s } break; - default: + default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } @@ -1012,7 +1018,7 @@ void EncipherBlock(int cipher, void *data, void *ks) if (IsAesHwCpuSupported()) aes_hw_cpu_encrypt ((byte *) ks, data); else - aes_encrypt (data, data, ks); + aes_encrypt (data, data, ks); #elif defined (TC_WINDOWS_BOOT_SERPENT) serpent_encrypt (data, data, ks); #elif defined (TC_WINDOWS_BOOT_TWOFISH) @@ -1028,7 +1034,7 @@ void DecipherBlock(int cipher, void *data, void *ks) if (IsAesHwCpuSupported()) aes_hw_cpu_decrypt ((byte *) ks + sizeof (aes_encrypt_ctx) + 14 * 16, data); else - aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx))); + aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx))); #elif defined (TC_WINDOWS_BOOT_SERPENT) serpent_decrypt (data, data, ks); #elif defined (TC_WINDOWS_BOOT_TWOFISH) diff --git a/src/Common/Crypto.h b/src/Common/Crypto.h index abcdfa5b..c4bc4fa9 100644 --- a/src/Common/Crypto.h +++ b/src/Common/Crypto.h @@ -1,11 +1,11 @@ /* 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 + 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 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-2016 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 @@ -45,9 +45,9 @@ extern "C" { #define MASTER_KEYDATA_SIZE 256 // The first PRF to try when mounting -#define FIRST_PRF_ID 1 +#define FIRST_PRF_ID 1 -// Hash algorithms (pseudorandom functions). +// Hash algorithms (pseudorandom functions). enum { SHA512 = FIRST_PRF_ID, @@ -59,7 +59,7 @@ enum }; // The last PRF to try when mounting and also the number of implemented PRFs -#define LAST_PRF_ID (HASH_ENUM_END_ID - 1) +#define LAST_PRF_ID (HASH_ENUM_END_ID - 1) #define RIPEMD160_BLOCKSIZE 64 #define RIPEMD160_DIGESTSIZE 20 @@ -109,7 +109,7 @@ enum { NONE = 0, AES, - SERPENT, + SERPENT, TWOFISH, CAMELLIA, GOST89, @@ -238,12 +238,12 @@ typedef struct CRYPTO_INFO_t #ifndef TC_WINDOWS_BOOT uint16 HeaderVersion; - GfCtx gf_ctx; + GfCtx gf_ctx; 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. */ unsigned __int8 salt[PKCS5_SALT_SIZE]; - int noIterations; + int noIterations; BOOL bTrueCryptMode; int volumePim; @@ -252,7 +252,7 @@ typedef struct CRYPTO_INFO_t 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). - + uint64 volDataAreaOffset; // Absolute position, in bytes, of the first data sector of the volume. uint64 hiddenVolumeSize; // Size of the hidden volume excluding the header (in bytes). Set to 0 for standard volumes. @@ -279,7 +279,7 @@ typedef struct CRYPTO_INFO_t } CRYPTO_INFO, *PCRYPTO_INFO; -#ifdef _WIN32 +#if defined(_WIN32) || defined(_UEFI) #pragma pack (push) #pragma pack(1) diff --git a/src/Common/Endian.h b/src/Common/Endian.h index 00fed048..fd4c901c 100644 --- a/src/Common/Endian.h +++ b/src/Common/Endian.h @@ -1,11 +1,11 @@ /* 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 + 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 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-2016 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 @@ -21,7 +21,7 @@ extern "C" { #endif -#ifdef _WIN32 +#if defined(_WIN32) || defined(_UEFI) # ifndef LITTLE_ENDIAN # define LITTLE_ENDIAN 1234 @@ -110,7 +110,7 @@ extern "C" ( ( unsigned __int32 ) memPtr[ -2 ] << 8 ) | ( unsigned __int32 ) memPtr[ -1 ] ) #define mgetWord(memPtr) \ - ( memPtr += 2, ((( unsigned short ) memPtr[ -2 ] << 8 ) | ( ( unsigned short ) memPtr[ -1 ] )) ) + ( memPtr += 2, ((( unsigned short ) memPtr[ -2 ] << 8 ) | ( ( unsigned short ) memPtr[ -1 ] )) ) #define mgetByte(memPtr) \ ( ( unsigned char ) *memPtr++ ) @@ -139,7 +139,7 @@ unsigned __int16 MirrorBytes16 (unsigned __int16 x); unsigned __int32 MirrorBytes32 (unsigned __int32 x); #ifndef TC_NO_COMPILER_INT64 uint64 MirrorBytes64 (uint64 x); -#endif +#endif void LongReverse ( unsigned __int32 *buffer , unsigned byteCount ); #if defined(__cplusplus) diff --git a/src/Common/Password.h b/src/Common/Password.h index 8818804e..9ef2f035 100644 --- a/src/Common/Password.h +++ b/src/Common/Password.h @@ -1,11 +1,11 @@ /* 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 + 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 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-2016 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 @@ -36,14 +36,14 @@ typedef struct char Pad[3]; // keep 64-bit alignment } Password; -#if defined(_WIN32) && !defined(TC_WINDOWS_DRIVER) +#if defined(_WIN32) && !defined(TC_WINDOWS_DRIVER) && !defined(_UEFI) void VerifyPasswordAndUpdate ( HWND hwndDlg , HWND hButton , HWND hPassword , HWND hVerify , unsigned char *szPassword , char *szVerify, BOOL keyFilesEnabled ); -BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim, BOOL bForBoot, BOOL bSkipPasswordWarning, BOOL bSkipPimWarning); -BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw); +BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim, BOOL bForBoot, BOOL bSkipPasswordWarning, BOOL bSkipPimWarning); +BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw); int ChangePwd (const wchar_t *lpszVolume, Password *oldPassword, int old_pkcs5, int old_pim, BOOL truecryptMode, Password *newPassword, int pkcs5, int pim, int wipePassCount, HWND hwndDlg); -#endif // defined(_WIN32) && !defined(TC_WINDOWS_DRIVER) +#endif // defined(_WIN32) && !defined(TC_WINDOWS_DRIVER) && !defined(_UEFI) #ifdef __cplusplus } diff --git a/src/Common/Pkcs5.c b/src/Common/Pkcs5.c index 2ce475ef..3dbfd322 100644 --- a/src/Common/Pkcs5.c +++ b/src/Common/Pkcs5.c @@ -1,20 +1,21 @@ /* 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 + 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 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-2016 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" - +#if !defined(_UEFI) #include #include +#endif #include "Rmd160.h" #ifndef TC_WINDOWS_BOOT #include "Sha2.h" @@ -151,7 +152,7 @@ static void derive_u_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, u char* k = hmac->k; char* u = hmac->u; uint32 c; - int i; + int i; #ifdef TC_WINDOWS_BOOT /* In bootloader mode, least significant bit of iterations is a boolean (TRUE for boot derivation mode, FALSE otherwise) @@ -170,7 +171,7 @@ static void derive_u_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, u /* iteration 1 */ memcpy (k, salt, salt_len); /* salt */ - + /* big-endian block number */ memset (&k[salt_len], 0, 3); k[salt_len + 3] = (char) b; @@ -192,7 +193,7 @@ static void derive_u_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, u void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) -{ +{ hmac_sha256_ctx hmac; sha256_ctx* ctx; char* buf = hmac.k; @@ -316,7 +317,7 @@ void hmac_sha512 char *k, /* secret key */ int lk, /* length of the key in bytes */ char *d, /* data and also output buffer of at least 64 bytes */ - int ld /* length of data in bytes */ + int ld /* length of data in bytes */ ) { hmac_sha512_ctx hmac; @@ -522,7 +523,7 @@ void hmac_ripemd160 (char *key, int keylen, char *input_digest, int len) /* If the key is longer than the hash algorithm block size, let key = ripemd160(key), as per HMAC specifications. */ - if (keylen > RIPEMD160_BLOCKSIZE) + if (keylen > RIPEMD160_BLOCKSIZE) { RMD160_CTX tctx; @@ -534,14 +535,14 @@ void hmac_ripemd160 (char *key, int keylen, char *input_digest, int len) keylen = RIPEMD160_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks - } + } /* perform inner RIPEMD-160 */ ctx = &(hmac.inner_digest_ctx); /* start out by storing key in pads */ memset(k_pad, 0x36, 64); /* XOR key with ipad and opad values */ - for (i=0; i RIPEMD160_BLOCKSIZE) + if (pwd_len > RIPEMD160_BLOCKSIZE) { RMD160_CTX tctx; @@ -653,7 +654,7 @@ void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, uin /* start out by storing key in pads */ memset(k_pad, 0x36, 64); /* XOR key with ipad and opad values */ - for (b=0; b +#include +#include + +void* VeraCryptMemAlloc(IN UINTN size); +void VeraCryptMemFree(IN VOID* ptr); + +#define BOOL int +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#define max(a,b) ((a)>(b))?(a):(b) +#define min(a,b) ((a)<(b))?(a):(b) + +#ifdef __cplusplus +extern "C" { +#endif +extern unsigned __int64 __cdecl _rotl64(unsigned __int64,int); +extern unsigned __int64 __cdecl _rotr64(unsigned __int64,int); +extern unsigned int __cdecl _rotl(unsigned int,int); +extern unsigned int __cdecl _rotr(unsigned int,int); +extern unsigned char _rotr8(unsigned char value, unsigned char shift); +extern unsigned short _rotr16(unsigned short value, unsigned char shift); +extern unsigned char _rotl8(unsigned char value, unsigned char shift); +extern unsigned short _rotl16(unsigned short value, unsigned char shift); +#ifdef __cplusplus +} +#endif + +#endif // defined(_UEFI) + #define TC_APP_NAME "VeraCrypt" // Version displayed to user @@ -55,6 +93,9 @@ typedef unsigned __int64 uint64; #define LL(x) x##ui64 #endif +#pragma warning( disable : 4201 ) // disable: 4201 nonstandard extension used : nameless struct/union +#pragma warning( disable : 4324 ) // disable: 4324 structure was padded due to __declspec(align()) + #else // !_MSC_VER #include @@ -123,6 +164,41 @@ typedef union #define __has_builtin(x) 0 // Compatibility with non-clang compilers #endif +#if defined(_UEFI) +typedef UINTN size_t; +typedef uint64 uint_64t; +typedef CHAR16 wchar_t; +typedef int LONG; + +#define wcscpy StrCpy +#define wcslen StrLen +#define wcscmp StrCmp +#define wcscat StrCat + +#define memcpy(dest,source,count) CopyMem(dest,source,(UINTN)(count)) +#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch)) +#define memchr(buf,ch,count) ScanMem8(buf,(UINTN)(count),(UINT8)ch) +#define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count))) + +#define MAX_STRING_SIZE 0x1000 +#define strcat(strDest,strSource) AsciiStrCatS(strDest,MAX_STRING_SIZE,strSource) +#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch) +#define strcmp AsciiStrCmp +#define strncmp(string1,string2,count) (int)(AsciiStrnCmp(string1,string2,(UINTN)(count))) +#define strcpy(strDest,strSource) AsciiStrCpyS(strDest,MAX_STRING_SIZE,strSource) +#define strncpy(strDest,strSource,count) AsciiStrnCpyS(strDest,MAX_STRING_SIZE,strSource,(UINTN)count) +#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE)) +#define strstr AsciiStrStr + +// #define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) +// #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) +// #define rotr64(x,n) (((x) >> n) | ((x) << (64 - n))) +// #define rotl64(x,n) (((x) << n) | ((x) >> (64 - n))) +// #define bswap_32(x) (rotl32((((x) & 0xFF00FF00) >> 8) | (((x) & 0x00FF00FF) << 8), 16U)) +// #define bswap_64(x) rotl64(((((((x & LL(0xFF00FF00FF00FF00)) >> 8) | ((x & LL(0x00FF00FF00FF00FF)) << 8)) & LL(0xFFFF0000FFFF0000)) >> 16) | (((((x & LL(0xFF00FF00FF00FF00)) >> 8) | ((x & LL(0x00FF00FF00FF00FF)) << 8)) & LL(0x0000FFFF0000FFFF)) << 16)), 32U) + +#endif + #ifdef TC_WINDOWS_BOOT # ifdef __cplusplus @@ -133,6 +209,9 @@ 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)) @@ -170,9 +249,13 @@ typedef int BOOL; #endif #else /* !TC_WINDOWS_DRIVER */ - +#if !defined(_UEFI) #define TCalloc malloc #define TCfree free +#else +#define TCalloc VeraCryptMemAlloc +#define TCfree VeraCryptMemFree +#endif //!defined(_UEFI) #ifdef _WIN32 @@ -217,6 +300,8 @@ typedef int BOOL; # define trace_msg Dump # elif defined (_WIN32) # define trace_msg(...) do { char msg[2048]; StringCbPrintfA (msg, sizeof (msg), __VA_ARGS__); OutputDebugString (msg); } while (0) +# else +# define trace_msg(...) # endif # define trace_point trace_msg (__FUNCTION__ ":" TC_TO_STRING(__LINE__) "\n") # else @@ -233,7 +318,7 @@ typedef int BOOL; # define TC_WAIT_EVENT(EVENT) WaitForSingleObject (EVENT, INFINITE) #endif -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UEFI) #define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); size_t burnc = size; RtlSecureZeroMemory (mem, size); while (burnc--) *burnm++ = 0; } while (0) #else #define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); int burnc = size; while (burnc--) *burnm++ = 0; } while (0) @@ -251,7 +336,7 @@ typedef int BOOL; # define max(a,b) (((a) > (b)) ? (a) : (b)) # endif -# ifdef __cplusplus +# if defined(__cplusplus) && !defined(_UEFI) extern "C" # endif void EraseMemory (void *memory, int size); diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c index 21b34f6d..35ba5bd2 100644 --- a/src/Common/Volumes.c +++ b/src/Common/Volumes.c @@ -12,8 +12,8 @@ code distribution packages. */ #include "Tcdefs.h" - -#ifndef TC_WINDOWS_BOOT +#if !defined(_UEFI) +#if !defined(TC_WINDOWS_BOOT) #include #include #include @@ -28,6 +28,7 @@ #ifndef DEVICE_DRIVER #include "Random.h" #endif +#endif // !defined(_UEFI) #include "Crc.h" #include "Crypto.h" @@ -35,7 +36,7 @@ #include "Volumes.h" #include "Pkcs5.h" -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UEFI) #include #include "../Boot/Windows/BootCommon.h" #endif @@ -176,16 +177,17 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int uint16 headerVersion; int status = ERR_PARAMETER_INCORRECT; int primaryKeyOffset; - + int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1; +#if !defined(_UEFI) TC_EVENT keyDerivationCompletedEvent; TC_EVENT noOutstandingWorkItemEvent; KeyDerivationWorkItem *keyDerivationWorkItems; KeyDerivationWorkItem *item; - int pkcs5PrfCount = LAST_PRF_ID - FIRST_PRF_ID + 1; size_t encryptionThreadCount = GetEncryptionThreadCount(); - size_t queuedWorkItems = 0; LONG outstandingWorkItemCount = 0; int i; +#endif + size_t queuedWorkItems = 0; // if no PIM specified, use default value if (pim < 0) @@ -212,7 +214,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int if (cryptoInfo == NULL) return ERR_OUTOFMEMORY; } - +#if !defined(_UEFI) /* use thread pool only if no PRF was specified */ if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { @@ -244,10 +246,11 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int #endif } -#ifndef DEVICE_DRIVER +#if !defined(DEVICE_DRIVER) VirtualLock (&keyInfo, sizeof (keyInfo)); VirtualLock (&dk, sizeof (dk)); #endif +#endif // !defined(_UEFI) crypto_loadkey (&keyInfo, password->Text, (int) password->Length); @@ -264,7 +267,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int // skip SHA-256 in case of TrueCrypt mode if (truecryptMode && (enqPkcs5Prf == SHA256)) continue; - +#if !defined(_UEFI) if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { // Enqueue key derivation on thread pool @@ -319,6 +322,7 @@ int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int KeyReady: ; } else +#endif // !defined(_UEFI) { pkcs5_prf = enqPkcs5Prf; keyInfo.noIterations = get_pkcs5_iteration_count (enqPkcs5Prf, pim, truecryptMode, bBoot); @@ -568,11 +572,12 @@ ret: burn (&keyInfo, sizeof (keyInfo)); burn (dk, sizeof(dk)); -#ifndef DEVICE_DRIVER +#if !defined(DEVICE_DRIVER) && !defined(_UEFI) VirtualUnlock (&keyInfo, sizeof (keyInfo)); VirtualUnlock (&dk, sizeof (dk)); #endif +#if !defined(_UEFI) if ((selected_pkcs5_prf == 0) && (encryptionThreadCount > 1)) { TC_WAIT_EVENT (noOutstandingWorkItemEvent); @@ -580,16 +585,16 @@ ret: burn (keyDerivationWorkItems, sizeof (KeyDerivationWorkItem) * pkcs5PrfCount); TCfree (keyDerivationWorkItems); -#ifndef DEVICE_DRIVER +#if !defined(DEVICE_DRIVER) CloseHandle (keyDerivationCompletedEvent); CloseHandle (noOutstandingWorkItemEvent); #endif } - +#endif return status; } -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UEFI) void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint) { // compute Whirlpool+SHA512 fingerprint of bootloader including MBR @@ -805,10 +810,17 @@ ret: #endif // Creates a volume header in memory +#if defined(_UEFI) +int CreateVolumeHeaderInMemory(BOOL bBoot, 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 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; static CRYPTOPP_ALIGN_DATA(16) KEY_INFO keyInfo; @@ -828,9 +840,10 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, 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 */ @@ -847,7 +860,11 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, bytesNeeded = EAGetKeySize (ea) * 2; // Size of primary + secondary key(s) } +#if !defined(_UEFI) if (!RandgetBytes (hwndDlg, keyInfo.master_keydata, bytesNeeded, TRUE)) +#else + if (!RandgetBytes(keyInfo.master_keydata, bytesNeeded, TRUE)) +#endif { crypto_close (cryptoInfo); return ERR_CIPHER_INIT_WEAK_KEY; @@ -885,7 +902,11 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, cryptoInfo->mode = mode; // Salt for header key derivation - if (!RandgetBytes (hwndDlg, keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode)) +#if !defined(_UEFI) + if (!RandgetBytes(hwndDlg, keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode)) +#else + if (!RandgetBytes(keyInfo.salt, PKCS5_SALT_SIZE, !bWipeMode)) +#endif { crypto_close (cryptoInfo); return ERR_CIPHER_INIT_WEAK_KEY; @@ -930,7 +951,11 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, else { // generate a random key +#if !defined(_UEFI) if (!RandgetBytes(hwndDlg, dk, GetMaxPkcs5OutSize(), !bWipeMode)) +#else + if (!RandgetBytes(dk, GetMaxPkcs5OutSize(), !bWipeMode)) +#endif { crypto_close (cryptoInfo); return ERR_CIPHER_INIT_WEAK_KEY; @@ -1111,7 +1136,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea, return 0; } - +#if !defined(_UEFI) BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead) { #if TC_VOLUME_HEADER_EFFECTIVE_SIZE > TC_MAX_VOLUME_SECTOR_SIZE @@ -1324,4 +1349,5 @@ final_seq: return nStatus; } +#endif // !defined(_UEFI) #endif // !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT) diff --git a/src/Common/Volumes.h b/src/Common/Volumes.h index fdd1444f..3fe3a450 100644 --- a/src/Common/Volumes.h +++ b/src/Common/Volumes.h @@ -1,11 +1,11 @@ /* 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 + 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 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-2016 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 @@ -19,7 +19,7 @@ extern "C" { #endif // Volume header version -#define VOLUME_HEADER_VERSION 0x0005 +#define VOLUME_HEADER_VERSION 0x0005 // Version number written to volume header during format; // specifies the minimum program version required to mount the volume @@ -101,7 +101,7 @@ extern "C" { #define HEADER_SALT_OFFSET 0 #define HEADER_ENCRYPTED_DATA_OFFSET PKCS5_SALT_SIZE #define HEADER_MASTER_KEYDATA_OFFSET 256 - + #define TC_HEADER_OFFSET_MAGIC 64 #define TC_HEADER_OFFSET_VERSION 68 #define TC_HEADER_OFFSET_REQUIRED_VERSION 70 @@ -130,16 +130,20 @@ extern BOOL ReadVolumeHeaderRecoveryMode; uint16 GetHeaderField16 (byte *header, int offset); uint32 GetHeaderField32 (byte *header, int offset); UINT64_STRUCT GetHeaderField64 (byte *header, int offset); -#ifdef TC_WINDOWS_BOOT +#if defined(TC_WINDOWS_BOOT) int ReadVolumeHeader (BOOL bBoot, 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, BOOL truecryptMode, 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); +BOOL RandgetBytes(unsigned char *buf, int len, BOOL forceSlowPoll); #else int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, int pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo); -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UEFI) void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint); #endif #endif -#if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT) +#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); BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead); BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header); diff --git a/src/Common/Xml.c b/src/Common/Xml.c index 6e6f8724..6abbed6d 100644 --- a/src/Common/Xml.c +++ b/src/Common/Xml.c @@ -9,9 +9,13 @@ contained in the file License.txt included in VeraCrypt binary and source code distribution packages. */ - +#if !defined(_UEFI) #include #include +#else +#include "Tcdefs.h" +#pragma warning( disable : 4706 ) // assignment within conditional expression +#endif #include "Xml.h" @@ -59,7 +63,7 @@ char *XmlFindElement (char *xmlNode, char *nodeName) } -char *XmlFindElementByAttributeValue (char *xml, char *nodeName, char *attrName, char *attrValue) +char *XmlFindElementByAttributeValue (char *xml, char *nodeName, const char *attrName, const char *attrValue) { char attr[2048]; @@ -76,7 +80,7 @@ char *XmlFindElementByAttributeValue (char *xml, char *nodeName, char *attrName, } -char *XmlGetAttributeText (char *xmlNode, char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize) +char *XmlGetAttributeText (char *xmlNode, const char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize) { char *t = xmlNode; char *e = xmlNode; @@ -105,7 +109,7 @@ char *XmlGetAttributeText (char *xmlNode, char *xmlAttrName, char *xmlAttrValue, if (t == NULL || t > e) return NULL; - t = strchr (t, '"') + 1; + t = ((char*)strchr (t, '"')) + 1; e = strchr (t, '"'); l = (int)(e - t); if (e == NULL || l > xmlAttrValueSize) return NULL; @@ -128,7 +132,7 @@ char *XmlGetNodeText (char *xmlNode, char *xmlText, int xmlTextSize) if (t[0] != '<') return NULL; - t = strchr (t, '>'); + t = (char*) strchr (t, '>'); if (t == NULL) return NULL; t++; @@ -256,7 +260,8 @@ wchar_t *XmlQuoteTextW (const wchar_t *textSrc, wchar_t *textDst, int textDstMax return textDst; } - +#if !defined(_UEFI) +#pragma warning( default : 4706 ) int XmlWriteHeader (FILE *file) { return fputws (L"\n", file); @@ -267,3 +272,4 @@ int XmlWriteFooter (FILE *file) { return fputws (L"\n", file); } +#endif !defined(_UEFI) diff --git a/src/Common/Xml.h b/src/Common/Xml.h index 3dfb58e1..ceae2bf1 100644 --- a/src/Common/Xml.h +++ b/src/Common/Xml.h @@ -3,7 +3,7 @@ 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) + Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2016 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 @@ -16,14 +16,17 @@ extern "C" { char *XmlNextNode (char *xmlNode); char *XmlFindElement (char *xmlNode, char *nodeName); -char *XmlGetAttributeText (char *xmlNode, char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize); +char *XmlGetAttributeText (char *xmlNode, const char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize); char *XmlGetNodeText (char *xmlNode, char *xmlText, int xmlTextSize); -int XmlWriteHeader (FILE *file); -int XmlWriteFooter (FILE *file); -char *XmlFindElementByAttributeValue (char *xml, char *nodeName, char *attrName, char *attrValue); +char *XmlFindElementByAttributeValue (char *xml, char *nodeName, const char *attrName, const char *attrValue); char *XmlQuoteText (const char *textSrc, char *textDst, int textDstMaxSize); wchar_t *XmlQuoteTextW (const wchar_t *textSrc, wchar_t *textDst, int textDstMaxSize); +#if !defined(_UEFI) +int XmlWriteHeader (FILE *file); +int XmlWriteFooter (FILE *file); +#endif !defined(_UEFI) + #ifdef __cplusplus } #endif diff --git a/src/Crypto/Rmd160.c b/src/Crypto/Rmd160.c index 9387f9ba..386a1a80 100644 --- a/src/Crypto/Rmd160.c +++ b/src/Crypto/Rmd160.c @@ -9,13 +9,15 @@ /* Adapted for TrueCrypt */ /* Adapted for VeraCrypt */ - +#if !defined(_UEFI) #include +#endif !defined(_UEFI) + #include "Common/Tcdefs.h" #include "Common/Endian.h" #include "Rmd160.h" -#define F(x, y, z) (x ^ y ^ z) +#define F(x, y, z) (x ^ y ^ z) #define G(x, y, z) (z ^ (x & (y^z))) #define H(x, y, z) (z ^ (x | ~y)) #define I(x, y, z) (y ^ (z & (x^y))) @@ -300,7 +302,7 @@ void RMD160Transform (unsigned __int32 *digest, const unsigned __int32 *data) Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); - Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); @@ -383,7 +385,7 @@ void RMD160Transform (unsigned __int32 *digest, const unsigned __int32 *data) 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) + Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2016 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 @@ -454,7 +456,7 @@ void RMD160Transform (unsigned __int32 *state, const unsigned __int32 *data) for (pos = 0; pos < 160; ++pos) { tmp = a + data[OrderTab[pos]] + KTab[pos >> 4]; - + switch (pos >> 4) { case 0: case 9: tmp += F (b, c, d); break; diff --git a/src/Crypto/Serpent.c b/src/Crypto/Serpent.c index 23c1c504..25bcea96 100644 --- a/src/Crypto/Serpent.c +++ b/src/Crypto/Serpent.c @@ -19,7 +19,9 @@ #include "Crypto/misc.h" #endif +#if !defined(_UEFI) #include +#endif !defined(_UEFI) // linear transformation #define LT(i,a,b,c,d,e) {\ diff --git a/src/Crypto/Sha2.c b/src/Crypto/Sha2.c index 02680eb5..6bc0bd84 100644 --- a/src/Crypto/Sha2.c +++ b/src/Crypto/Sha2.c @@ -69,7 +69,9 @@ */ #include "Common/Endian.h" +#include "Common/Tcdefs.h" #include "Crypto/misc.h" + #define PLATFORM_BYTE_ORDER BYTE_ORDER #define IS_LITTLE_ENDIAN LITTLE_ENDIAN @@ -77,7 +79,9 @@ #define UNROLL_SHA2 /* for SHA2 loop unroll */ #endif +#if !defined(_UEFI) #include /* for memcpy() etc. */ +#endif !defined(_UEFI) #include "Sha2.h" @@ -86,7 +90,7 @@ extern "C" { #endif -#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) && !defined(_UEFI) #pragma intrinsic(memcpy) #endif diff --git a/src/Crypto/Whirlpool.c b/src/Crypto/Whirlpool.c index 19cfad2a..86b3ebf6 100644 --- a/src/Crypto/Whirlpool.c +++ b/src/Crypto/Whirlpool.c @@ -26,7 +26,7 @@ * ``The Whirlpool hashing function,'' * NESSIE submission, 2000 (tweaked version, 2001), * - * + * * @author Paulo S.L.M. Barreto * @author Vincent Rijmen. * @@ -68,14 +68,16 @@ * */ -#include -#include -#include -#include +#include "Common/Tcdefs.h" #include "Common/Endian.h" +#if !defined(_UEFI) +#include +#include +#endif + #include "cpu.h" -#include "misc.h" +#include "misc.h" #include "Whirlpool.h" /* @@ -656,7 +658,7 @@ void WhirlpoolTransform(uint64 *digest, const uint64 *block) AS2( and esp, -16) AS2( sub esp, 16*8) AS_PUSH_IF86( ax) - + #if CRYPTOPP_BOOL_X86 #define SSE2_workspace esp+WORD_SZ #elif CRYPTOPP_BOOL_X32 @@ -899,7 +901,7 @@ void WHIRLPOOL_init(WHIRLPOOL_CTX * const ctx) { */ void WHIRLPOOL_add(const unsigned char * input, unsigned __int32 sourceBytes, - WHIRLPOOL_CTX * const ctx) + WHIRLPOOL_CTX * const ctx) { uint64 num, oldCountLo = ctx->countLo, oldCountHi = ctx->countHi; uint64 len = sourceBytes; @@ -911,7 +913,7 @@ void WHIRLPOOL_add(const unsigned char * input, else { uint64* dataBuf = ctx->data; - byte* data = (byte *)dataBuf; + byte* data = (byte *)dataBuf; num = oldCountLo & 63; if (num != 0) // process left over data @@ -963,11 +965,11 @@ void WHIRLPOOL_add(const unsigned char * input, /** * 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 char * result) { unsigned int num = ctx->countLo & 63; uint64* dataBuf = ctx->data; diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index 21c6c194..c358088d 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -60,8 +60,10 @@ static void SigIllHandlerSSE2(int p) int CpuId(uint32 input, uint32 output[4]) { #ifdef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY +#ifndef _UEFI __try { +#endif __asm { mov eax, input @@ -73,11 +75,13 @@ int CpuId(uint32 input, uint32 output[4]) mov [edi+8], ecx mov [edi+12], edx } - } - __except (EXCEPTION_EXECUTE_HANDLER) +#ifndef _UEFI + } + __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } +#endif // function 0 returns the highest basic function understood in EAX if(input == 0) @@ -123,7 +127,7 @@ static int TrySSE2() { #if CRYPTOPP_BOOL_X64 return 1; -#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) +#elif defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) && !defined(_UEFI) volatile int result = 1; #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64) KFLOATING_SAVE floatingPointState; @@ -150,7 +154,7 @@ static int TrySSE2() return 0; #endif return result; -#else +#elif !defined(_UEFI) // longjmp and clobber warnings. Volatile is required. // http://github.com/weidai11/cryptopp/issues/24 // http://stackoverflow.com/q/7721854 @@ -174,6 +178,8 @@ static int TrySSE2() signal(SIGILL, oldHandler); return result; +#else + return 1; #endif } @@ -198,7 +204,7 @@ VC_INLINE int IsAMD(const uint32 output[4]) (output[3] /*EDX*/ == 0x444D4163); } -#if (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE +#if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) static int TryAESNI () { @@ -289,7 +295,7 @@ void DetectX86Features() g_hasAESNI = g_hasSSE2 && (cpuid1[2] & (1<<25)); g_hasCLMUL = g_hasSSE2 && (cpuid1[2] & (1<<1)); -#if (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE +#if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) // Hypervisor = bit 31 of ECX of CPUID leaf 0x1 // reference: http://artemonsecurity.com/vmde.pdf if (!g_hasAESNI && (cpuid1[2] & (1<<31))) @@ -337,7 +343,7 @@ int is_aes_hw_cpu_supported () { if (cpuid[2] & (1<<25)) bHasAESNI = 1; -#if (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE +#if !defined (_UEFI) && ((defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE) // Hypervisor = bit 31 of ECX of CPUID leaf 0x1 // reference: http://artemonsecurity.com/vmde.pdf if (!bHasAESNI && (cpuid[2] & (1<<31))) diff --git a/src/Crypto/cpu.h b/src/Crypto/cpu.h index df7ec18e..2d26e927 100644 --- a/src/Crypto/cpu.h +++ b/src/Crypto/cpu.h @@ -13,7 +13,7 @@ #else #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE -#if defined(TC_WINDOWS_DRIVER) +#if defined(TC_WINDOWS_DRIVER) || defined (_UEFI) #if defined(__cplusplus) extern "C" { #endif @@ -82,7 +82,7 @@ extern __m128i _mm_setr_epi32(int _I0, int _I1, int _I2, int _I3); #if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE #if defined(__SSSE3__) || defined(__INTEL_COMPILER) -#if defined(TC_WINDOWS_DRIVER) +#if defined(TC_WINDOWS_DRIVER) || defined (_UEFI) #if defined(__cplusplus) extern "C" { #endif @@ -96,7 +96,7 @@ extern __m128i _mm_shuffle_epi8 (__m128i a, __m128i b); #endif #if defined(__SSE4_1__) || defined(__INTEL_COMPILER) || defined(_MSC_VER) -#if defined(TC_WINDOWS_DRIVER) +#if defined(TC_WINDOWS_DRIVER) || defined (_UEFI) #if defined(__cplusplus) extern "C" { #endif @@ -114,7 +114,7 @@ extern __m128i _mm_insert_epi64(__m128i dst, __int64 s, const int ndx); #endif #if (defined(__AES__) && defined(__PCLMUL__)) || defined(__INTEL_COMPILER) || CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE -#if defined(TC_WINDOWS_DRIVER) +#if defined(TC_WINDOWS_DRIVER) || defined (_UEFI) #if defined(__cplusplus) extern "C" { #endif diff --git a/src/Crypto/misc.h b/src/Crypto/misc.h index e4570664..e7391764 100644 --- a/src/Crypto/misc.h +++ b/src/Crypto/misc.h @@ -2,15 +2,19 @@ #define CRYPTOPP_MISC_H #include "config.h" +#if !defined(_UEFI) #include // for memcpy and memmove #ifndef _WIN32 #include // for strcasecmp #define _stricmp strcasecmp #endif +#else +#include "Tcdefs.h" +#endif // !defined(_UEFI) -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(_UEFI) #if _MSC_VER >= 1400 - #ifndef TC_WINDOWS_DRIVER + #if !defined(TC_WINDOWS_DRIVER) && !defined(_UEFI) // VC2005 workaround: disable declarations that conflict with winnt.h #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1 #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2 @@ -23,7 +27,7 @@ #undef _interlockedbittestandreset64 #endif #define CRYPTOPP_FAST_ROTATE(x) 1 - #elif _MSC_VER >= 1300 + #elif !defined(_UEFI) && _MSC_VER >= 1300 #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) #else #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) @@ -37,7 +41,7 @@ #define CRYPTOPP_FAST_ROTATE(x) 0 #endif -#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) +#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) && !defined(_UEFI) #pragma intrinsic(memcpy,memset) #endif @@ -80,7 +84,7 @@ #if defined(__GNUC__) && defined(__linux__) #define CRYPTOPP_BYTESWAP_AVAILABLE #include -#elif defined(_MSC_VER) && _MSC_VER >= 1300 +#elif defined(_MSC_VER) && _MSC_VER >= 1300 && !defined(_UEFI) #define CRYPTOPP_BYTESWAP_AVAILABLE #define bswap_32(x) _byteswap_ulong(x) #define bswap_64(x) _byteswap_uint64(x) diff --git a/src/Driver/DriveFilter.c b/src/Driver/DriveFilter.c index 492c467a..a3d76b3a 100644 --- a/src/Driver/DriveFilter.c +++ b/src/Driver/DriveFilter.c @@ -3,7 +3,7 @@ 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) + Modifications and additions to the original source code (contained in this file) and all other portions of this file are Copyright (c) 2013-2016 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 @@ -33,7 +33,7 @@ static BOOL DeviceFilterActive = FALSE; BOOL BootArgsValid = FALSE; BootArguments BootArgs; -static uint16 BootLoaderSegment; +static uint64 BootLoaderArgsPtr; static BOOL BootDriveSignatureValid = FALSE; static KMUTEX MountMutex; @@ -69,21 +69,22 @@ static int64 DecoySystemWipedAreaEnd; PKTHREAD DecoySystemWipeThread = NULL; static NTSTATUS DecoySystemWipeResult; +uint64 BootArgsRegions[] = { EFI_BOOTARGS_REGIONS }; NTSTATUS LoadBootArguments () { NTSTATUS status = STATUS_UNSUCCESSFUL; PHYSICAL_ADDRESS bootArgsAddr; byte *mappedBootArgs; - uint16 bootLoaderSegment; + uint16 bootLoaderArgsIndex; KeInitializeMutex (&MountMutex, 0); - for (bootLoaderSegment = TC_BOOT_LOADER_SEGMENT; - bootLoaderSegment >= TC_BOOT_LOADER_SEGMENT - 64 * 1024 / 16 && status != STATUS_SUCCESS; - bootLoaderSegment -= 32 * 1024 / 16) + for (bootLoaderArgsIndex = 0; + bootLoaderArgsIndex < sizeof(BootArgsRegions)/ sizeof(BootArgsRegions[1]) && status != STATUS_SUCCESS; + ++bootLoaderArgsIndex) { - bootArgsAddr.QuadPart = (bootLoaderSegment << 4) + TC_BOOT_LOADER_ARGS_OFFSET; + bootArgsAddr.QuadPart = BootArgsRegions[bootLoaderArgsIndex] + TC_BOOT_LOADER_ARGS_OFFSET; Dump ("Checking BootArguments at 0x%x\n", bootArgsAddr.LowPart); mappedBootArgs = MmMapIoSpace (bootArgsAddr, sizeof (BootArguments), MmCached); @@ -107,7 +108,7 @@ NTSTATUS LoadBootArguments () // Sanity check: for valid boot argument, the password is less than 64 bytes long if (bootArguments->BootPassword.Length <= MAX_PASSWORD) { - BootLoaderSegment = bootLoaderSegment; + BootLoaderArgsPtr = BootArgsRegions[bootLoaderArgsIndex]; BootArgs = *bootArguments; BootArgsValid = TRUE; @@ -168,7 +169,7 @@ NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) Extension = (DriveFilterExtension *) filterDeviceObject->DeviceExtension; memset (Extension, 0, sizeof (DriveFilterExtension)); - status = IoAttachDeviceToDeviceStackSafe (filterDeviceObject, pdo, &(Extension->LowerDeviceObject)); + status = IoAttachDeviceToDeviceStackSafe (filterDeviceObject, pdo, &(Extension->LowerDeviceObject)); if (!NT_SUCCESS (status)) { goto err; @@ -183,7 +184,7 @@ NTSTATUS DriveFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) Extension->IsDriveFilterDevice = Extension->Queue.IsFilterDevice = TRUE; Extension->DeviceObject = Extension->Queue.DeviceObject = filterDeviceObject; Extension->Pdo = pdo; - + Extension->Queue.LowerDeviceObject = Extension->LowerDeviceObject; IoInitializeRemoveLock (&Extension->Queue.RemoveLock, 'LRCV', 0, 0); @@ -216,7 +217,7 @@ static void DismountDrive (DriveFilterExtension *Extension, BOOL stopIoQueue) { Dump ("Dismounting drive\n"); ASSERT (Extension->DriveMounted); - + if (stopIoQueue && EncryptedIoQueueIsRunning (&Extension->Queue)) EncryptedIoQueueStop (&Extension->Queue); @@ -250,7 +251,7 @@ static void ComputeBootLoaderFingerprint(PDEVICE_OBJECT LowerDeviceObject, byte* // 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 @@ -322,6 +323,8 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, char *header; int pkcs5_prf = 0, pim = 0; byte *mappedCryptoInfo = NULL; + PARTITION_INFORMATION_EX pi; + BOOL bIsGPT = FALSE; Dump ("MountDrive pdo=%p\n", Extension->Pdo); ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL); @@ -372,11 +375,16 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, goto ret; } - if (BootArgs.CryptoInfoLength > 0) + if (NT_SUCCESS(SendDeviceIoControlRequest (Extension->LowerDeviceObject, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pi, sizeof (pi)))) { - PHYSICAL_ADDRESS cryptoInfoAddress; + bIsGPT = (pi.PartitionStyle == PARTITION_STYLE_GPT)? TRUE : FALSE; + } - cryptoInfoAddress.QuadPart = (BootLoaderSegment << 4) + BootArgs.CryptoInfoOffset; + if (BootArgs.CryptoInfoLength > 0) + { + PHYSICAL_ADDRESS cryptoInfoAddress; + + cryptoInfoAddress.QuadPart = BootLoaderArgsPtr + BootArgs.CryptoInfoOffset; #ifdef DEBUG Dump ("Wiping memory %x %d\n", cryptoInfoAddress.LowPart, BootArgs.CryptoInfoLength); #endif @@ -386,7 +394,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, /* Get the parameters used for booting to speed up driver startup and avoid testing irrelevant PRFs */ BOOT_CRYPTO_HEADER* pBootCryptoInfo = (BOOT_CRYPTO_HEADER*) mappedCryptoInfo; Hash* pHash = HashGet(pBootCryptoInfo->pkcs5); - if (pHash && pHash->SystemEncryption) + if (pHash && (bIsGPT || pHash->SystemEncryption)) pkcs5_prf = pBootCryptoInfo->pkcs5; } } @@ -401,20 +409,20 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, // calculate Fingerprint ComputeBootLoaderFingerprint (Extension->LowerDeviceObject, header); - + if (Extension->Queue.CryptoInfo->hiddenVolume) { int64 hiddenPartitionOffset = BootArgs.HiddenSystemPartitionStart; Dump ("Hidden volume start offset = %I64d\n", Extension->Queue.CryptoInfo->EncryptedAreaStart.Value + hiddenPartitionOffset); - + Extension->HiddenSystem = TRUE; Extension->Queue.RemapEncryptedArea = TRUE; Extension->Queue.RemappedAreaOffset = hiddenPartitionOffset + Extension->Queue.CryptoInfo->EncryptedAreaStart.Value - BootArgs.DecoySystemPartitionStart; Extension->Queue.RemappedAreaDataUnitOffset = Extension->Queue.CryptoInfo->EncryptedAreaStart.Value / ENCRYPTION_DATA_UNIT_SIZE - BootArgs.DecoySystemPartitionStart / ENCRYPTION_DATA_UNIT_SIZE; - + Extension->Queue.CryptoInfo->EncryptedAreaStart.Value = BootArgs.DecoySystemPartitionStart; - + if (Extension->Queue.CryptoInfo->VolumeSize.Value > hiddenPartitionOffset - BootArgs.DecoySystemPartitionStart) TC_THROW_FATAL_EXCEPTION; @@ -473,7 +481,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, } 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); @@ -482,7 +490,7 @@ static NTSTATUS MountDrive (DriveFilterExtension *Extension, Password *password, } else Extension->Queue.MaxReadAheadOffset = BootDriveLength; - + status = EncryptedIoQueueStart (&Extension->Queue); if (!NT_SUCCESS (status)) TC_BUG_CHECK (status); @@ -538,7 +546,7 @@ static NTSTATUS SaveDriveVolumeHeader (DriveFilterExtension *Extension) Dump ("Saving: ConfiguredEncryptedAreaStart=%I64d (%I64d) ConfiguredEncryptedAreaEnd=%I64d (%I64d)\n", Extension->ConfiguredEncryptedAreaStart / 1024 / 1024, Extension->ConfiguredEncryptedAreaStart, Extension->ConfiguredEncryptedAreaEnd / 1024 / 1024, Extension->ConfiguredEncryptedAreaEnd); Dump ("Saving: EncryptedAreaStart=%I64d (%I64d) EncryptedAreaEnd=%I64d (%I64d)\n", Extension->Queue.EncryptedAreaStart / 1024 / 1024, Extension->Queue.EncryptedAreaStart, Extension->Queue.EncryptedAreaEnd / 1024 / 1024, Extension->Queue.EncryptedAreaEnd); - + if (Extension->Queue.EncryptedAreaStart == -1 || Extension->Queue.EncryptedAreaEnd == -1 || Extension->Queue.EncryptedAreaEnd <= Extension->Queue.EncryptedAreaStart) { @@ -690,7 +698,7 @@ static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP } KeInitializeEvent (&Extension->MountWorkItemCompletedEvent, SynchronizationEvent, FALSE); - IoQueueWorkItem (workItem, MountDriveWorkItemRoutine, DelayedWorkQueue, Extension); + IoQueueWorkItem (workItem, MountDriveWorkItemRoutine, DelayedWorkQueue, Extension); KeWaitForSingleObject (&Extension->MountWorkItemCompletedEvent, Executive, KernelMode, FALSE, NULL); IoFreeWorkItem (workItem); @@ -829,7 +837,7 @@ NTSTATUS DriveFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) if (Extension->BootDrive) { status = EncryptedIoQueueAddIrp (&Extension->Queue, Irp); - + if (status != STATUS_PENDING) TCCompleteDiskIrp (Irp, status, 0); @@ -907,7 +915,7 @@ void ReopenBootVolumeHeader (PIRP irp, PIO_STACK_LOCATION irpSp) { Dump ("Header reopened\n"); ComputeBootLoaderFingerprint (BootDriveFilterExtension->LowerDeviceObject, header); - + BootDriveFilterExtension->Queue.CryptoInfo->header_creation_time = BootDriveFilterExtension->HeaderCryptoInfo->header_creation_time; BootDriveFilterExtension->Queue.CryptoInfo->pkcs5 = BootDriveFilterExtension->HeaderCryptoInfo->pkcs5; BootDriveFilterExtension->Queue.CryptoInfo->noIterations = BootDriveFilterExtension->HeaderCryptoInfo->noIterations; @@ -1037,7 +1045,7 @@ static NTSTATUS HiberDriverWriteFunctionFilter (int filterNumber, PLARGE_INTEGER if (writeB) return (*OriginalHiberDriverWriteFunctionsB[filterNumber]) (writeOffset, encryptedDataMdl); - + return (*OriginalHiberDriverWriteFunctionsA[filterNumber]) (arg0WriteA, writeOffset, encryptedDataMdl, arg3WriteA); } @@ -1281,11 +1289,11 @@ static VOID SetupThreadProc (PVOID threadArg) byte *wipeBuffer = NULL; byte wipeRandChars[TC_WIPE_RAND_CHAR_COUNT]; byte wipeRandCharsUpdate[TC_WIPE_RAND_CHAR_COUNT]; - + KIRQL irql; NTSTATUS status; - // generate real random values for wipeRandChars and + // generate real random values for wipeRandChars and // wipeRandCharsUpdate instead of relying on uninitialized stack memory LARGE_INTEGER iSeed; KeQuerySystemTime( &iSeed ); @@ -1312,7 +1320,7 @@ static VOID SetupThreadProc (PVOID threadArg) burn (digest, SHA512_DIGESTSIZE); burn (&tctx, sizeof (tctx)); } - + burn (&iSeed, sizeof(iSeed)); SetupResult = STATUS_UNSUCCESSFUL; @@ -1388,7 +1396,7 @@ static VOID SetupThreadProc (PVOID threadArg) } EncryptedIoQueueResumeFromHold (&Extension->Queue); - + Dump ("EncryptedAreaStart=%I64d\n", Extension->Queue.EncryptedAreaStart); Dump ("EncryptedAreaEnd=%I64d\n", Extension->Queue.EncryptedAreaEnd); Dump ("ConfiguredEncryptedAreaStart=%I64d\n", Extension->ConfiguredEncryptedAreaStart); @@ -1497,7 +1505,7 @@ static VOID SetupThreadProc (PVOID threadArg) } EncryptDataUnits (wipeBuffer, &dataUnit, setupBlockSize / ENCRYPTION_DATA_UNIT_SIZE, Extension->Queue.CryptoInfo); - memcpy (wipeRandCharsUpdate, wipeBuffer, sizeof (wipeRandCharsUpdate)); + memcpy (wipeRandCharsUpdate, wipeBuffer, sizeof (wipeRandCharsUpdate)); } status = TCWriteDevice (BootDriveFilterExtension->LowerDeviceObject, wipeBuffer, offset, setupBlockSize); @@ -1512,7 +1520,7 @@ static VOID SetupThreadProc (PVOID threadArg) } } - memcpy (wipeRandChars, wipeRandCharsUpdate, sizeof (wipeRandCharsUpdate)); + memcpy (wipeRandChars, wipeRandCharsUpdate, sizeof (wipeRandCharsUpdate)); } } else @@ -1658,7 +1666,7 @@ NTSTATUS StartBootEncryptionSetup (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_ST SetupInProgress = TRUE; status = TCStartThread (SetupThreadProc, DeviceObject, &EncryptionSetupThread); - + if (!NT_SUCCESS (status)) SetupInProgress = FALSE; @@ -1754,7 +1762,7 @@ void GetBootEncryptionStatus (PIRP irp, PIO_STACK_LOCATION irpSp) bootEncStatus->HiddenSysLeakProtectionCount = HiddenSysLeakProtectionCount; bootEncStatus->HiddenSystem = Extension->HiddenSystem; - + if (Extension->HiddenSystem) bootEncStatus->HiddenSystemPartitionStart = BootArgs.HiddenSystemPartitionStart; } @@ -1790,7 +1798,7 @@ void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp) irp->IoStatus.Information = 0; if (BootArgsValid && BootDriveFound && BootDriveFilterExtension && BootDriveFilterExtension->DriveMounted && BootDriveFilterExtension->HeaderCryptoInfo) { - BootLoaderFingerprintRequest *bootLoaderFingerprint = (BootLoaderFingerprintRequest *) irp->AssociatedIrp.SystemBuffer; + 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); @@ -1820,7 +1828,7 @@ void GetBootLoaderFingerprint (PIRP irp, PIO_STACK_LOCATION irpSp) } else { - irp->IoStatus.Status = STATUS_INVALID_PARAMETER; + irp->IoStatus.Status = STATUS_INVALID_PARAMETER; } } } @@ -1931,7 +1939,7 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg) DecoySystemWipeResult = STATUS_INSUFFICIENT_RESOURCES; goto ret; } - + wipeRandBuffer = TCalloc (TC_ENCRYPTION_SETUP_IO_BLOCK_SIZE); if (!wipeRandBuffer) { @@ -1956,7 +1964,7 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg) } memcpy (wipeCryptoInfo->k2, WipeDecoyRequest.WipeKey + EAGetKeySize (ea), EAGetKeySize (ea)); - + if (!EAInitMode (wipeCryptoInfo)) { DecoySystemWipeResult = STATUS_INVALID_PARAMETER; @@ -1969,7 +1977,7 @@ static VOID DecoySystemWipeThreadProc (PVOID threadArg) burn (WipeDecoyRequest.WipeKey, sizeof (WipeDecoyRequest.WipeKey)); offset.QuadPart = Extension->ConfiguredEncryptedAreaStart; - + Dump ("Wiping decoy system: start offset = %I64d\n", offset.QuadPart); while (!DecoySystemWipeThreadAbortRequested) @@ -2073,7 +2081,7 @@ NTSTATUS StartDecoySystemWipe (PDEVICE_OBJECT DeviceObject, PIRP irp, PIO_STACK_ DecoySystemWipeInProgress = TRUE; status = TCStartThread (DecoySystemWipeThreadProc, DeviceObject, &DecoySystemWipeThread); - + if (!NT_SUCCESS (status)) DecoySystemWipeInProgress = FALSE; @@ -2112,7 +2120,7 @@ void GetDecoySystemWipeStatus (PIRP irp, PIO_STACK_LOCATION irpSp) } else wipeStatus->WipedAreaEnd = DecoySystemWipedAreaEnd; - + irp->IoStatus.Information = sizeof (DecoySystemWipeStatus); irp->IoStatus.Status = STATUS_SUCCESS; } -- cgit v1.2.3