VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Boot/Windows/Bios.h64
-rw-r--r--src/Boot/Windows/Boot.vcproj492
-rw-r--r--src/Boot/Windows/BootCommon.h164
-rw-r--r--src/Boot/Windows/BootConfig.cpp204
-rw-r--r--src/Boot/Windows/BootConfig.h92
-rw-r--r--src/Boot/Windows/BootConsoleIo.cpp678
-rw-r--r--src/Boot/Windows/BootConsoleIo.h144
-rw-r--r--src/Boot/Windows/BootCrt.asm54
-rw-r--r--src/Boot/Windows/BootDebug.cpp362
-rw-r--r--src/Boot/Windows/BootDebug.h120
-rw-r--r--src/Boot/Windows/BootDefs.h398
-rw-r--r--src/Boot/Windows/BootDiskIo.cpp982
-rw-r--r--src/Boot/Windows/BootDiskIo.h240
-rw-r--r--src/Boot/Windows/BootEncryptedIo.cpp264
-rw-r--r--src/Boot/Windows/BootEncryptedIo.h44
-rw-r--r--src/Boot/Windows/BootMain.cpp2538
-rw-r--r--src/Boot/Windows/BootMain.h68
-rw-r--r--src/Boot/Windows/BootMemory.cpp172
-rw-r--r--src/Boot/Windows/BootMemory.h56
-rw-r--r--src/Boot/Windows/BootSector.asm488
-rw-r--r--src/Boot/Windows/BootStrings.h40
-rw-r--r--src/Boot/Windows/Decompressor.c130
-rw-r--r--src/Boot/Windows/IntFilter.cpp1290
-rw-r--r--src/Boot/Windows/IntFilter.h40
-rw-r--r--src/Boot/Windows/Makefile404
-rw-r--r--src/Boot/Windows/Platform.cpp460
-rw-r--r--src/Boot/Windows/Platform.h232
-rwxr-xr-xsrc/Build/Tools/MacOSX/nasmbin1818752 -> 1818750 bytes
-rw-r--r--src/Common/Apidrvr.h688
-rw-r--r--src/Common/BaseCom.cpp492
-rw-r--r--src/Common/BaseCom.h238
-rw-r--r--src/Common/BootEncryption.cpp5626
-rw-r--r--src/Common/BootEncryption.h510
-rw-r--r--src/Common/Cache.c230
-rw-r--r--src/Common/Cache.h50
-rw-r--r--src/Common/Cmdline.c368
-rw-r--r--src/Common/Cmdline.h86
-rw-r--r--src/Common/Combo.c516
-rw-r--r--src/Common/Combo.h58
-rw-r--r--src/Common/Common.h190
-rw-r--r--src/Common/Common.rc1206
-rw-r--r--src/Common/Crc.c270
-rw-r--r--src/Common/Crc.h74
-rw-r--r--src/Common/Crypto.c2116
-rw-r--r--src/Common/Crypto.h726
-rw-r--r--src/Common/Dictionary.c174
-rw-r--r--src/Common/Dictionary.h68
-rw-r--r--src/Common/Dlgcode.c23780
-rw-r--r--src/Common/Dlgcode.h1186
-rw-r--r--src/Common/EncryptionThreadPool.c1022
-rw-r--r--src/Common/EncryptionThreadPool.h84
-rw-r--r--src/Common/Endian.c118
-rw-r--r--src/Common/Endian.h298
-rw-r--r--src/Common/Exception.h246
-rw-r--r--src/Common/Fat.c898
-rw-r--r--src/Common/Fat.h138
-rw-r--r--src/Common/Format.c2108
-rw-r--r--src/Common/Format.h152
-rw-r--r--src/Common/GfMul.c1536
-rw-r--r--src/Common/GfMul.h148
-rw-r--r--src/Common/Inflate.c2642
-rw-r--r--src/Common/Inflate.h102
-rw-r--r--src/Common/Keyfiles.c1556
-rw-r--r--src/Common/Keyfiles.h108
-rw-r--r--src/Common/Language.c1166
-rw-r--r--src/Common/Language.h86
-rw-r--r--src/Common/Language.xml2912
-rw-r--r--src/Common/Makefile2
-rw-r--r--src/Common/Password.c982
-rw-r--r--src/Common/Password.h104
-rw-r--r--src/Common/Pkcs5.c1918
-rw-r--r--src/Common/Pkcs5.h96
-rw-r--r--src/Common/Progress.c268
-rw-r--r--src/Common/Progress.h66
-rw-r--r--src/Common/Random.c1796
-rw-r--r--src/Common/Random.h152
-rw-r--r--src/Common/Registry.c598
-rw-r--r--src/Common/Registry.h74
-rw-r--r--src/Common/Resource.h422
-rw-r--r--src/Common/SecurityToken.cpp1570
-rw-r--r--src/Common/SecurityToken.h452
-rw-r--r--src/Common/Sources34
-rw-r--r--src/Common/Tcdefs.h646
-rw-r--r--src/Common/Tests.c2310
-rw-r--r--src/Common/Tests.h62
-rw-r--r--src/Common/Volumes.c2540
-rw-r--r--src/Common/Volumes.h310
-rw-r--r--src/Common/Wipe.c396
-rw-r--r--src/Common/Wipe.h90
-rw-r--r--src/Common/Xml.c536
-rw-r--r--src/Common/Xml.h58
-rw-r--r--src/Common/Xts.c1500
-rw-r--r--src/Common/Xts.h168
-rw-r--r--src/Crypto/Aes.h430
-rw-r--r--src/Crypto/AesSmall.c1906
-rw-r--r--src/Crypto/AesSmall.h338
-rw-r--r--src/Crypto/AesSmall_x86.asm2888
-rw-r--r--src/Crypto/Aes_hw_cpu.asm660
-rw-r--r--src/Crypto/Aes_hw_cpu.h48
-rw-r--r--src/Crypto/Aes_x64.asm1814
-rw-r--r--src/Crypto/Aes_x86.asm1292
-rw-r--r--src/Crypto/Aescrypt.c622
-rw-r--r--src/Crypto/Aeskey.c1146
-rw-r--r--src/Crypto/Aesopt.h1468
-rw-r--r--src/Crypto/Aestab.c856
-rw-r--r--src/Crypto/Aestab.h348
-rw-r--r--src/Crypto/Crypto.vcproj1034
-rw-r--r--src/Crypto/Makefile2
-rw-r--r--src/Crypto/Makefile.inc30
-rw-r--r--src/Crypto/Rmd160.c996
-rw-r--r--src/Crypto/Rmd160.h66
-rw-r--r--src/Crypto/Serpent.c1876
-rw-r--r--src/Crypto/Serpent.h40
-rw-r--r--src/Crypto/Sha2.c1506
-rw-r--r--src/Crypto/Sha2.h310
-rw-r--r--src/Crypto/Sha2Small.c468
-rw-r--r--src/Crypto/Sha2Small.h26
-rw-r--r--src/Crypto/Sources40
-rw-r--r--src/Crypto/Twofish.c1098
-rw-r--r--src/Crypto/Twofish.h112
-rw-r--r--src/Crypto/Whirlpool.h54
-rw-r--r--src/Crypto/cpu.c462
-rw-r--r--src/Crypto/cpu.h616
-rw-r--r--src/Driver/BuildDriver.cmd332
-rw-r--r--src/Driver/DriveFilter.c4306
-rw-r--r--src/Driver/DriveFilter.h180
-rw-r--r--src/Driver/Driver.rc202
-rw-r--r--src/Driver/Driver.vcproj796
-rw-r--r--src/Driver/DumpFilter.c496
-rw-r--r--src/Driver/DumpFilter.h50
-rw-r--r--src/Driver/EncryptedIoQueue.c2098
-rw-r--r--src/Driver/EncryptedIoQueue.h330
-rw-r--r--src/Driver/Makefile2
-rw-r--r--src/Driver/Ntdriver.c7126
-rw-r--r--src/Driver/Ntdriver.h378
-rw-r--r--src/Driver/Ntvol.c1800
-rw-r--r--src/Driver/Ntvol.h44
-rw-r--r--src/Driver/Resource.h32
-rw-r--r--src/Driver/Sources42
-rw-r--r--src/Driver/VolumeFilter.c598
-rw-r--r--src/Driver/VolumeFilter.h46
-rw-r--r--src/ExpandVolume/DlgExpandVolume.cpp1552
-rw-r--r--src/ExpandVolume/ExpandVolume.c42
-rw-r--r--src/ExpandVolume/ExpandVolume.rc596
-rw-r--r--src/ExpandVolume/ExpandVolume.vcproj1954
-rw-r--r--src/ExpandVolume/InitDataArea.c30
-rw-r--r--src/ExpandVolume/InitDataArea.h24
-rw-r--r--src/ExpandVolume/WinMain.cpp846
-rw-r--r--src/ExpandVolume/resource.h294
-rw-r--r--src/Format/Format.manifest64
-rw-r--r--src/Format/Format.rc1494
-rw-r--r--src/Format/Format.vcproj2056
-rw-r--r--src/Format/FormatCom.cpp496
-rw-r--r--src/Format/FormatCom.h72
-rw-r--r--src/Format/FormatCom.idl106
-rw-r--r--src/Format/InPlace.c4586
-rw-r--r--src/Format/InPlace.h104
-rw-r--r--src/Format/Resource.h318
-rw-r--r--src/Format/Tcformat.c20466
-rw-r--r--src/Format/Tcformat.h218
-rw-r--r--src/License.html358
-rw-r--r--src/License.txt1404
-rw-r--r--src/Main/Forms/Forms.cpp7050
-rw-r--r--src/Main/Forms/Forms.h2194
-rw-r--r--src/Main/Forms/TrueCrypt.fbp57476
-rw-r--r--src/Mount/Favorites.cpp2048
-rw-r--r--src/Mount/Favorites.h174
-rw-r--r--src/Mount/Hotkeys.c1222
-rw-r--r--src/Mount/Hotkeys.h104
-rw-r--r--src/Mount/MainCom.cpp588
-rw-r--r--src/Mount/MainCom.h70
-rw-r--r--src/Mount/MainCom.idl114
-rw-r--r--src/Mount/Mount.c22048
-rw-r--r--src/Mount/Mount.h266
-rw-r--r--src/Mount/Mount.manifest64
-rw-r--r--src/Mount/Mount.rc1426
-rw-r--r--src/Mount/Mount.vcproj2054
-rw-r--r--src/Mount/Resource.h526
-rw-r--r--src/PKCS11/cryptoki.h132
-rw-r--r--src/PKCS11/pkcs11.h598
-rw-r--r--src/PKCS11/pkcs11f.h1824
-rw-r--r--src/PKCS11/pkcs11t.h3770
-rw-r--r--src/Platform/Buffer.cpp280
-rw-r--r--src/Platform/Buffer.h218
-rw-r--r--src/Platform/Directory.h46
-rw-r--r--src/Platform/Event.cpp82
-rw-r--r--src/Platform/Event.h160
-rw-r--r--src/Platform/Exception.cpp92
-rw-r--r--src/Platform/Exception.h208
-rw-r--r--src/Platform/File.h208
-rw-r--r--src/Platform/FileCommon.cpp162
-rw-r--r--src/Platform/FileStream.h104
-rw-r--r--src/Platform/FilesystemPath.h134
-rw-r--r--src/Platform/Finally.h80
-rw-r--r--src/Platform/ForEach.h224
-rw-r--r--src/Platform/Functor.h46
-rw-r--r--src/Platform/Memory.cpp104
-rw-r--r--src/Platform/Memory.h336
-rw-r--r--src/Platform/MemoryStream.cpp82
-rw-r--r--src/Platform/MemoryStream.h60
-rw-r--r--src/Platform/Mutex.h110
-rw-r--r--src/Platform/Platform.h44
-rw-r--r--src/Platform/Platform.make78
-rw-r--r--src/Platform/PlatformBase.h256
-rw-r--r--src/Platform/PlatformTest.cpp688
-rw-r--r--src/Platform/PlatformTest.h74
-rw-r--r--src/Platform/Serializable.cpp66
-rw-r--r--src/Platform/Serializable.h152
-rw-r--r--src/Platform/Serializer.cpp586
-rw-r--r--src/Platform/Serializer.h136
-rw-r--r--src/Platform/SerializerFactory.cpp96
-rw-r--r--src/Platform/SerializerFactory.h174
-rw-r--r--src/Platform/SharedPtr.h312
-rw-r--r--src/Platform/SharedVal.h130
-rw-r--r--src/Platform/Stream.h56
-rw-r--r--src/Platform/StringConverter.cpp810
-rw-r--r--src/Platform/StringConverter.h112
-rw-r--r--src/Platform/SyncEvent.h82
-rw-r--r--src/Platform/System.h20
-rw-r--r--src/Platform/SystemException.h80
-rw-r--r--src/Platform/SystemInfo.h44
-rw-r--r--src/Platform/SystemLog.h72
-rw-r--r--src/Platform/TextReader.cpp62
-rw-r--r--src/Platform/TextReader.h58
-rw-r--r--src/Platform/Thread.h136
-rw-r--r--src/Platform/Time.h48
-rw-r--r--src/Platform/User.h52
-rw-r--r--src/Readme.txt530
-rw-r--r--src/Release/Setup Files/LICENSE378
-rw-r--r--src/Release/Setup Files/License.txt1404
-rw-r--r--src/Release/Setup Files/NOTICE268
-rw-r--r--src/Resources/Icons/VeraCrypt-128x128.xpm2592
-rw-r--r--src/Resources/Icons/VeraCrypt-16x16.xpm210
-rw-r--r--src/Resources/Icons/VeraCrypt-256x256.xpm4058
-rw-r--r--src/Resources/Icons/VeraCrypt-48x48.xpm972
-rw-r--r--src/Setup/ComSetup.cpp206
-rw-r--r--src/Setup/ComSetup.h24
-rw-r--r--src/Setup/ComSetup.rgs182
-rw-r--r--src/Setup/Dir.c220
-rw-r--r--src/Setup/Dir.h46
-rw-r--r--src/Setup/Resource.h128
-rw-r--r--src/Setup/SelfExtract.c1576
-rw-r--r--src/Setup/SelfExtract.h86
-rw-r--r--src/Setup/Setup.c5264
-rw-r--r--src/Setup/Setup.h380
-rw-r--r--src/Setup/Setup.manifest64
-rw-r--r--src/Setup/Setup.rc654
-rw-r--r--src/Setup/Setup.vcproj968
-rw-r--r--src/Setup/Wizard.c2390
-rw-r--r--src/Setup/Wizard.h62
-rw-r--r--src/Signing/GlobalSign_R1Cross.cer52
-rw-r--r--src/Signing/GlobalSign_Root_CA_MS_Cross_Cert.crt60
-rw-r--r--src/Signing/Thawt_CodeSigning_CA.crt52
-rw-r--r--src/Signing/sign.bat54
-rw-r--r--src/Signing/sign_test.bat62
-rw-r--r--src/Signing/thawte_Primary_MS_Cross_Cert.cer64
-rw-r--r--src/VeraCrypt.sln948
257 files changed, 147347 insertions, 147347 deletions
diff --git a/src/Boot/Windows/Bios.h b/src/Boot/Windows/Bios.h
index 314b1a6..dd2da6b 100644
--- a/src/Boot/Windows/Bios.h
+++ b/src/Boot/Windows/Bios.h
@@ -1,32 +1,32 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_Bios
-#define TC_HEADER_Boot_Bios
-
-#include "Platform.h"
-
-#define TC_LB_SIZE_BIT_SHIFT_DIVISOR 9
-
-#define TC_FIRST_BIOS_DRIVE 0x80
-#define TC_LAST_BIOS_DRIVE 0x8f
-#define TC_INVALID_BIOS_DRIVE (TC_FIRST_BIOS_DRIVE - 1)
-
-enum
-{
- BiosResultSuccess = 0x00,
- BiosResultInvalidFunction = 0x01
-};
-
-typedef byte BiosResult;
-
-#endif // TC_HEADER_Boot_Bios
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_Bios
+#define TC_HEADER_Boot_Bios
+
+#include "Platform.h"
+
+#define TC_LB_SIZE_BIT_SHIFT_DIVISOR 9
+
+#define TC_FIRST_BIOS_DRIVE 0x80
+#define TC_LAST_BIOS_DRIVE 0x8f
+#define TC_INVALID_BIOS_DRIVE (TC_FIRST_BIOS_DRIVE - 1)
+
+enum
+{
+ BiosResultSuccess = 0x00,
+ BiosResultInvalidFunction = 0x01
+};
+
+typedef byte BiosResult;
+
+#endif // TC_HEADER_Boot_Bios
diff --git a/src/Boot/Windows/Boot.vcproj b/src/Boot/Windows/Boot.vcproj
index d0b40f1..64ad48e 100644
--- a/src/Boot/Windows/Boot.vcproj
+++ b/src/Boot/Windows/Boot.vcproj
@@ -1,246 +1,246 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9.00"
- Name="Boot"
- ProjectGUID="{8B7F059F-E4C7-4E11-88F5-EE8B8433072E}"
- RootNamespace="Boot"
- Keyword="MakeFileProj"
- TargetFrameworkVersion="131072"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Release|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
- ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue &gt;NUL:&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES &gt;NUL:&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
- CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish &gt;NUL:&#x0D;&#x0A;del /q /s Release_SHA2 Release_AES_SHA2 Release_Serpent_SHA2 Release_Twofish_SHA2 Rescue_SHA2 Rescue_AES_SHA2 Rescue_Serpent_SHA2 Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;"
- Output="Release\BootLoader.com"
- PreprocessorDefinitions="WIN32;NDEBUG"
- IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release Loader|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
- ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
- CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish &gt;NUL:"
- Output="Release\BootLoader.com"
- PreprocessorDefinitions="WIN32;NDEBUG"
- IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
- UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
- >
- <File
- RelativePath=".\BootConfig.cpp"
- >
- </File>
- <File
- RelativePath=".\BootConsoleIo.cpp"
- >
- </File>
- <File
- RelativePath=".\BootCrt.asm"
- >
- </File>
- <File
- RelativePath=".\BootDebug.cpp"
- >
- </File>
- <File
- RelativePath=".\BootDiskIo.cpp"
- >
- </File>
- <File
- RelativePath=".\BootEncryptedIo.cpp"
- >
- </File>
- <File
- RelativePath=".\BootMain.cpp"
- >
- </File>
- <File
- RelativePath=".\BootMemory.cpp"
- >
- </File>
- <File
- RelativePath=".\BootSector.asm"
- >
- </File>
- <File
- RelativePath=".\Decompressor.c"
- >
- </File>
- <File
- RelativePath=".\IntFilter.cpp"
- >
- </File>
- <File
- RelativePath=".\Platform.cpp"
- >
- </File>
- <Filter
- Name="Common"
- >
- <File
- RelativePath="..\..\Common\Crc.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Crypto.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Endian.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Pkcs5.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Volumes.c"
- >
- </File>
- <File
- RelativePath="..\..\Common\Xts.c"
- >
- </File>
- </Filter>
- <Filter
- Name="Crypto"
- >
- <File
- RelativePath="..\..\Crypto\Aes_hw_cpu.asm"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\AesSmall.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\AesSmall_x86.asm"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Rmd160.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Serpent.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Sha2Small.c"
- >
- </File>
- <File
- RelativePath="..\..\Crypto\Twofish.c"
- >
- </File>
- </Filter>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl;inc;xsd"
- UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
- >
- <File
- RelativePath=".\Bios.h"
- >
- </File>
- <File
- RelativePath=".\BootCommon.h"
- >
- </File>
- <File
- RelativePath=".\BootConfig.h"
- >
- </File>
- <File
- RelativePath=".\BootConsoleIo.h"
- >
- </File>
- <File
- RelativePath=".\BootDebug.h"
- >
- </File>
- <File
- RelativePath=".\BootDefs.h"
- >
- </File>
- <File
- RelativePath=".\BootDiskIo.h"
- >
- </File>
- <File
- RelativePath=".\BootEncryptedIo.h"
- >
- </File>
- <File
- RelativePath=".\BootMain.h"
- >
- </File>
- <File
- RelativePath=".\BootMemory.h"
- >
- </File>
- <File
- RelativePath=".\BootStrings.h"
- >
- </File>
- <File
- RelativePath=".\IntFilter.h"
- >
- </File>
- <File
- RelativePath=".\Platform.h"
- >
- </File>
- </Filter>
- <Filter
- Name="Build Files"
- >
- <File
- RelativePath=".\Makefile"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="Boot"
+ ProjectGUID="{8B7F059F-E4C7-4E11-88F5-EE8B8433072E}"
+ RootNamespace="Boot"
+ Keyword="MakeFileProj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
+ ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Release_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue &gt;NUL:&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES &gt;NUL:&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_AES_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish_SHA2 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
+ CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish &gt;NUL:&#x0D;&#x0A;del /q /s Release_SHA2 Release_AES_SHA2 Release_Serpent_SHA2 Release_Twofish_SHA2 Rescue_SHA2 Rescue_AES_SHA2 Rescue_Serpent_SHA2 Rescue_Twofish_SHA2 &gt;NUL:&#x0D;&#x0A;"
+ Output="Release\BootLoader.com"
+ PreprocessorDefinitions="WIN32;NDEBUG"
+ IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Loader|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="0"
+ >
+ <Tool
+ Name="VCNMakeTool"
+ BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
+ ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
+ CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish &gt;NUL:"
+ Output="Release\BootLoader.com"
+ PreprocessorDefinitions="WIN32;NDEBUG"
+ IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
+ ForcedIncludes=""
+ AssemblySearchPath=""
+ ForcedUsingAssemblies=""
+ CompileAsManaged=""
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\BootConfig.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootConsoleIo.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootCrt.asm"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDebug.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDiskIo.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootEncryptedIo.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMain.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMemory.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BootSector.asm"
+ >
+ </File>
+ <File
+ RelativePath=".\Decompressor.c"
+ >
+ </File>
+ <File
+ RelativePath=".\IntFilter.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Platform.cpp"
+ >
+ </File>
+ <Filter
+ Name="Common"
+ >
+ <File
+ RelativePath="..\..\Common\Crc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Crypto.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Endian.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Pkcs5.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Volumes.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Common\Xts.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Crypto"
+ >
+ <File
+ RelativePath="..\..\Crypto\Aes_hw_cpu.asm"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\AesSmall.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\AesSmall_x86.asm"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Rmd160.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Serpent.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Sha2Small.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Crypto\Twofish.c"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Bios.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootCommon.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootConfig.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootConsoleIo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDebug.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDefs.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootDiskIo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootEncryptedIo.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMain.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootMemory.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BootStrings.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IntFilter.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Platform.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Build Files"
+ >
+ <File
+ RelativePath=".\Makefile"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/Boot/Windows/BootCommon.h b/src/Boot/Windows/BootCommon.h
index 4d91981..1dc8656 100644
--- a/src/Boot/Windows/BootCommon.h
+++ b/src/Boot/Windows/BootCommon.h
@@ -1,82 +1,82 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootCommon
-#define TC_HEADER_Boot_BootCommon
-
-#include "Common/Password.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 0x0117
-
-#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
-{
- byte 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;
- Password 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)
-
-
-#endif // TC_HEADER_Boot_BootCommon
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootCommon
+#define TC_HEADER_Boot_BootCommon
+
+#include "Common/Password.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 0x0117
+
+#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
+{
+ byte 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;
+ Password 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)
+
+
+#endif // TC_HEADER_Boot_BootCommon
diff --git a/src/Boot/Windows/BootConfig.cpp b/src/Boot/Windows/BootConfig.cpp
index 63ebaf5..75baf19 100644
--- a/src/Boot/Windows/BootConfig.cpp
+++ b/src/Boot/Windows/BootConfig.cpp
@@ -1,102 +1,102 @@
-/*
- 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-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 "BootConfig.h"
-
-byte BootSectorFlags;
-
-byte BootLoaderDrive;
-byte BootDrive;
-bool BootDriveGeometryValid = false;
-bool PreventNormalSystemBoot = false;
-bool PreventBootMenu = false;
-char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
-uint32 OuterVolumeBackupHeaderCrc;
-
-bool BootStarted = false;
-
-DriveGeometry BootDriveGeometry;
-
-CRYPTO_INFO *BootCryptoInfo;
-Partition EncryptedVirtualPartition;
-
-Partition ActivePartition;
-Partition PartitionFollowingActive;
-bool ExtraBootPartitionPresent = false;
-uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
-uint64 HiddenVolumeStartSector;
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-void ReadBootSectorUserConfiguration ()
-{
- byte userConfig;
-
- AcquireSectorBuffer();
-
- if (ReadWriteMBR (false, BootLoaderDrive, true) != BiosResultSuccess)
- goto ret;
-
- userConfig = SectorBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
-
-#ifdef TC_WINDOWS_BOOT_AES
- EnableHwEncryption (!(userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION));
-#endif
-
- PreventBootMenu = (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC);
-
- memcpy (CustomUserMessage, SectorBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
- CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0;
-
- if (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE)
- {
- if (CustomUserMessage[0])
- {
- InitVideoMode();
- Print (CustomUserMessage);
- }
-
- DisableScreenOutput();
- }
-
- if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
- {
- PimValueOrHiddenVolumeStartUnitNo.LowPart = 0;
- memcpy (&PimValueOrHiddenVolumeStartUnitNo.LowPart, SectorBuffer + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
- }
- else
- PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
-
- OuterVolumeBackupHeaderCrc = *(uint32 *) (SectorBuffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET);
-
-ret:
- ReleaseSectorBuffer();
-}
-
-
-BiosResult UpdateBootSectorConfiguration (byte drive)
-{
- AcquireSectorBuffer();
-
- BiosResult result = ReadWriteMBR (false, drive);
- if (result != BiosResultSuccess)
- goto ret;
-
- SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] = BootSectorFlags;
- result = ReadWriteMBR (true, drive);
-
-ret:
- ReleaseSectorBuffer();
- return result;
-}
-
-#endif // !TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+/*
+ 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-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 "BootConfig.h"
+
+byte BootSectorFlags;
+
+byte BootLoaderDrive;
+byte BootDrive;
+bool BootDriveGeometryValid = false;
+bool PreventNormalSystemBoot = false;
+bool PreventBootMenu = false;
+char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
+uint32 OuterVolumeBackupHeaderCrc;
+
+bool BootStarted = false;
+
+DriveGeometry BootDriveGeometry;
+
+CRYPTO_INFO *BootCryptoInfo;
+Partition EncryptedVirtualPartition;
+
+Partition ActivePartition;
+Partition PartitionFollowingActive;
+bool ExtraBootPartitionPresent = false;
+uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
+uint64 HiddenVolumeStartSector;
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+void ReadBootSectorUserConfiguration ()
+{
+ byte userConfig;
+
+ AcquireSectorBuffer();
+
+ if (ReadWriteMBR (false, BootLoaderDrive, true) != BiosResultSuccess)
+ goto ret;
+
+ userConfig = SectorBuffer[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
+
+#ifdef TC_WINDOWS_BOOT_AES
+ EnableHwEncryption (!(userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_HW_ENCRYPTION));
+#endif
+
+ PreventBootMenu = (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_ESC);
+
+ memcpy (CustomUserMessage, SectorBuffer + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
+ CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0;
+
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_SILENT_MODE)
+ {
+ if (CustomUserMessage[0])
+ {
+ InitVideoMode();
+ Print (CustomUserMessage);
+ }
+
+ DisableScreenOutput();
+ }
+
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ {
+ PimValueOrHiddenVolumeStartUnitNo.LowPart = 0;
+ memcpy (&PimValueOrHiddenVolumeStartUnitNo.LowPart, SectorBuffer + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
+ else
+ PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
+
+ OuterVolumeBackupHeaderCrc = *(uint32 *) (SectorBuffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET);
+
+ret:
+ ReleaseSectorBuffer();
+}
+
+
+BiosResult UpdateBootSectorConfiguration (byte drive)
+{
+ AcquireSectorBuffer();
+
+ BiosResult result = ReadWriteMBR (false, drive);
+ if (result != BiosResultSuccess)
+ goto ret;
+
+ SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] = BootSectorFlags;
+ result = ReadWriteMBR (true, drive);
+
+ret:
+ ReleaseSectorBuffer();
+ return result;
+}
+
+#endif // !TC_WINDOWS_BOOT_RESCUE_DISK_MODE
diff --git a/src/Boot/Windows/BootConfig.h b/src/Boot/Windows/BootConfig.h
index 0c5eee7..0a06a98 100644
--- a/src/Boot/Windows/BootConfig.h
+++ b/src/Boot/Windows/BootConfig.h
@@ -1,46 +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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootConfig
-#define TC_HEADER_Boot_BootConfig
-
-#include "Crypto.h"
-#include "Platform.h"
-#include "BootDiskIo.h"
-
-extern byte BootSectorFlags;
-
-extern byte BootLoaderDrive;
-extern byte BootDrive;
-extern bool BootDriveGeometryValid;
-extern DriveGeometry BootDriveGeometry;
-extern bool PreventNormalSystemBoot;
-extern bool PreventBootMenu;
-extern char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
-extern uint32 OuterVolumeBackupHeaderCrc;
-
-extern bool BootStarted;
-
-extern CRYPTO_INFO *BootCryptoInfo;
-extern Partition EncryptedVirtualPartition;
-
-extern Partition ActivePartition;
-extern Partition PartitionFollowingActive;
-extern bool ExtraBootPartitionPresent;
-extern uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
-extern uint64 HiddenVolumeStartSector;
-
-
-void ReadBootSectorUserConfiguration ();
-BiosResult UpdateBootSectorConfiguration (byte drive);
-
-#endif // TC_HEADER_Boot_BootConfig
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootConfig
+#define TC_HEADER_Boot_BootConfig
+
+#include "Crypto.h"
+#include "Platform.h"
+#include "BootDiskIo.h"
+
+extern byte BootSectorFlags;
+
+extern byte BootLoaderDrive;
+extern byte BootDrive;
+extern bool BootDriveGeometryValid;
+extern DriveGeometry BootDriveGeometry;
+extern bool PreventNormalSystemBoot;
+extern bool PreventBootMenu;
+extern char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
+extern uint32 OuterVolumeBackupHeaderCrc;
+
+extern bool BootStarted;
+
+extern CRYPTO_INFO *BootCryptoInfo;
+extern Partition EncryptedVirtualPartition;
+
+extern Partition ActivePartition;
+extern Partition PartitionFollowingActive;
+extern bool ExtraBootPartitionPresent;
+extern uint64 PimValueOrHiddenVolumeStartUnitNo; // reuse this variable for stored PIM value to reduce memory usage
+extern uint64 HiddenVolumeStartSector;
+
+
+void ReadBootSectorUserConfiguration ();
+BiosResult UpdateBootSectorConfiguration (byte drive);
+
+#endif // TC_HEADER_Boot_BootConfig
diff --git a/src/Boot/Windows/BootConsoleIo.cpp b/src/Boot/Windows/BootConsoleIo.cpp
index 31b6667..8b5a190 100644
--- a/src/Boot/Windows/BootConsoleIo.cpp
+++ b/src/Boot/Windows/BootConsoleIo.cpp
@@ -1,339 +1,339 @@
-/*
- 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-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 "Platform.h"
-#include "Bios.h"
-#include "BootConsoleIo.h"
-#include "BootDebug.h"
-#include "BootStrings.h"
-
-
-static int ScreenOutputDisabled = 0;
-
-void DisableScreenOutput ()
-{
- ++ScreenOutputDisabled;
-}
-
-
-void EnableScreenOutput ()
-{
- --ScreenOutputDisabled;
-}
-
-
-void PrintChar (char c)
-{
-#ifdef TC_BOOT_TRACING_ENABLED
- WriteDebugPort (c);
-#endif
-
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- mov bx, 7
- mov al, c
- mov ah, 0xe
- int 0x10
- }
-}
-
-
-void PrintCharAtCursor (char c)
-{
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- mov bx, 7
- mov al, c
- mov cx, 1
- mov ah, 0xa
- int 0x10
- }
-}
-
-
-void Print (const char *str)
-{
- char c;
- while (c = *str++)
- PrintChar (c);
-}
-
-
-void Print (uint32 number)
-{
- char str[12];
- int pos = 0;
- while (number >= 10)
- {
- str[pos++] = (char) (number % 10) + '0';
- number /= 10;
- }
- str[pos] = (char) (number % 10) + '0';
-
- while (pos >= 0)
- PrintChar (str[pos--]);
-}
-
-
-void Print (const uint64 &number)
-{
- if (number.HighPart == 0)
- Print (number.LowPart);
- else
- PrintHex (number);
-}
-
-
-void PrintHex (byte b)
-{
- PrintChar (((b >> 4) >= 0xA ? 'A' - 0xA : '0') + (b >> 4));
- PrintChar (((b & 0xF) >= 0xA ? 'A' - 0xA : '0') + (b & 0xF));
-}
-
-
-void PrintHex (uint16 data)
-{
- PrintHex (byte (data >> 8));
- PrintHex (byte (data));
-}
-
-
-void PrintHex (uint32 data)
-{
- PrintHex (uint16 (data >> 16));
- PrintHex (uint16 (data));
-}
-
-
-void PrintHex (const uint64 &data)
-{
- PrintHex (data.HighPart);
- PrintHex (data.LowPart);
-}
-
-void PrintRepeatedChar (char c, int n)
-{
- while (n-- > 0)
- PrintChar (c);
-}
-
-
-void PrintEndl ()
-{
- Print ("\r\n");
-}
-
-
-void PrintEndl (int cnt)
-{
- while (cnt-- > 0)
- PrintEndl ();
-}
-
-
-void Beep ()
-{
- PrintChar (7);
-}
-
-
-void InitVideoMode ()
-{
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- // Text mode 80x25
- mov ax, 3
- int 0x10
-
- // Page 0
- mov ax, 0x500
- int 0x10
- }
-}
-
-
-void ClearScreen ()
-{
- if (ScreenOutputDisabled)
- return;
-
- __asm
- {
- // White text on black
- mov bh, 7
- xor cx, cx
- mov dx, 0x184f
- mov ax, 0x600
- int 0x10
-
- // Cursor at 0,0
- xor bh, bh
- xor dx, dx
- mov ah, 2
- int 0x10
- }
-}
-
-
-void PrintBackspace ()
-{
- PrintChar (TC_BIOS_CHAR_BACKSPACE);
- PrintCharAtCursor (' ');
-}
-
-
-void PrintError (const char *message)
-{
- Print (TC_BOOT_STR_ERROR);
- Print (message);
- PrintEndl();
- Beep();
-}
-
-
-void PrintErrorNoEndl (const char *message)
-{
- Print (TC_BOOT_STR_ERROR);
- Print (message);
- Beep();
-}
-
-
-byte GetShiftFlags ()
-{
- byte flags;
- __asm
- {
- mov ah, 2
- int 0x16
- mov flags, al
- }
-
- return flags;
-}
-
-
-byte GetKeyboardChar ()
-{
- return GetKeyboardChar (nullptr);
-}
-
-
-byte GetKeyboardChar (byte *scanCode)
-{
- // Work around potential BIOS bugs (Windows boot manager polls the keystroke buffer)
- while (!IsKeyboardCharAvailable());
-
- byte asciiCode;
- byte scan;
- __asm
- {
- mov ah, 0
- int 0x16
- mov asciiCode, al
- mov scan, ah
- }
-
- if (scanCode)
- *scanCode = scan;
-
- return asciiCode;
-}
-
-
-bool IsKeyboardCharAvailable ()
-{
- bool available = false;
- __asm
- {
- mov ah, 1
- int 0x16
- jz not_avail
- mov available, true
- not_avail:
- }
-
- return available;
-}
-
-
-bool EscKeyPressed ()
-{
- if (IsKeyboardCharAvailable ())
- {
- byte keyScanCode;
- GetKeyboardChar (&keyScanCode);
- return keyScanCode == TC_BIOS_KEY_ESC;
- }
-
- return false;
-}
-
-
-void ClearBiosKeystrokeBuffer ()
-{
- __asm
- {
- push es
- xor ax, ax
- mov es, ax
- mov di, 0x41e
- mov cx, 32
- cld
- rep stosb
- pop es
- }
-}
-
-
-bool IsPrintable (char c)
-{
- return c >= ' ' && c <= '~';
-}
-
-bool IsDigit (char c)
-{
- return c >= '0' && c <= '9';
-}
-
-
-int GetString (char *buffer, size_t bufferSize)
-{
- byte c;
- byte scanCode;
- size_t pos = 0;
-
- while (pos < bufferSize)
- {
- c = GetKeyboardChar (&scanCode);
-
- if (scanCode == TC_BIOS_KEY_ENTER)
- break;
-
- if (scanCode == TC_BIOS_KEY_ESC)
- return 0;
-
- buffer[pos++] = c;
- PrintChar (IsPrintable (c) ? c : ' ');
- }
-
- return pos;
-}
+/*
+ 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-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 "Platform.h"
+#include "Bios.h"
+#include "BootConsoleIo.h"
+#include "BootDebug.h"
+#include "BootStrings.h"
+
+
+static int ScreenOutputDisabled = 0;
+
+void DisableScreenOutput ()
+{
+ ++ScreenOutputDisabled;
+}
+
+
+void EnableScreenOutput ()
+{
+ --ScreenOutputDisabled;
+}
+
+
+void PrintChar (char c)
+{
+#ifdef TC_BOOT_TRACING_ENABLED
+ WriteDebugPort (c);
+#endif
+
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ mov bx, 7
+ mov al, c
+ mov ah, 0xe
+ int 0x10
+ }
+}
+
+
+void PrintCharAtCursor (char c)
+{
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ mov bx, 7
+ mov al, c
+ mov cx, 1
+ mov ah, 0xa
+ int 0x10
+ }
+}
+
+
+void Print (const char *str)
+{
+ char c;
+ while (c = *str++)
+ PrintChar (c);
+}
+
+
+void Print (uint32 number)
+{
+ char str[12];
+ int pos = 0;
+ while (number >= 10)
+ {
+ str[pos++] = (char) (number % 10) + '0';
+ number /= 10;
+ }
+ str[pos] = (char) (number % 10) + '0';
+
+ while (pos >= 0)
+ PrintChar (str[pos--]);
+}
+
+
+void Print (const uint64 &number)
+{
+ if (number.HighPart == 0)
+ Print (number.LowPart);
+ else
+ PrintHex (number);
+}
+
+
+void PrintHex (byte b)
+{
+ PrintChar (((b >> 4) >= 0xA ? 'A' - 0xA : '0') + (b >> 4));
+ PrintChar (((b & 0xF) >= 0xA ? 'A' - 0xA : '0') + (b & 0xF));
+}
+
+
+void PrintHex (uint16 data)
+{
+ PrintHex (byte (data >> 8));
+ PrintHex (byte (data));
+}
+
+
+void PrintHex (uint32 data)
+{
+ PrintHex (uint16 (data >> 16));
+ PrintHex (uint16 (data));
+}
+
+
+void PrintHex (const uint64 &data)
+{
+ PrintHex (data.HighPart);
+ PrintHex (data.LowPart);
+}
+
+void PrintRepeatedChar (char c, int n)
+{
+ while (n-- > 0)
+ PrintChar (c);
+}
+
+
+void PrintEndl ()
+{
+ Print ("\r\n");
+}
+
+
+void PrintEndl (int cnt)
+{
+ while (cnt-- > 0)
+ PrintEndl ();
+}
+
+
+void Beep ()
+{
+ PrintChar (7);
+}
+
+
+void InitVideoMode ()
+{
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ // Text mode 80x25
+ mov ax, 3
+ int 0x10
+
+ // Page 0
+ mov ax, 0x500
+ int 0x10
+ }
+}
+
+
+void ClearScreen ()
+{
+ if (ScreenOutputDisabled)
+ return;
+
+ __asm
+ {
+ // White text on black
+ mov bh, 7
+ xor cx, cx
+ mov dx, 0x184f
+ mov ax, 0x600
+ int 0x10
+
+ // Cursor at 0,0
+ xor bh, bh
+ xor dx, dx
+ mov ah, 2
+ int 0x10
+ }
+}
+
+
+void PrintBackspace ()
+{
+ PrintChar (TC_BIOS_CHAR_BACKSPACE);
+ PrintCharAtCursor (' ');
+}
+
+
+void PrintError (const char *message)
+{
+ Print (TC_BOOT_STR_ERROR);
+ Print (message);
+ PrintEndl();
+ Beep();
+}
+
+
+void PrintErrorNoEndl (const char *message)
+{
+ Print (TC_BOOT_STR_ERROR);
+ Print (message);
+ Beep();
+}
+
+
+byte GetShiftFlags ()
+{
+ byte flags;
+ __asm
+ {
+ mov ah, 2
+ int 0x16
+ mov flags, al
+ }
+
+ return flags;
+}
+
+
+byte GetKeyboardChar ()
+{
+ return GetKeyboardChar (nullptr);
+}
+
+
+byte GetKeyboardChar (byte *scanCode)
+{
+ // Work around potential BIOS bugs (Windows boot manager polls the keystroke buffer)
+ while (!IsKeyboardCharAvailable());
+
+ byte asciiCode;
+ byte scan;
+ __asm
+ {
+ mov ah, 0
+ int 0x16
+ mov asciiCode, al
+ mov scan, ah
+ }
+
+ if (scanCode)
+ *scanCode = scan;
+
+ return asciiCode;
+}
+
+
+bool IsKeyboardCharAvailable ()
+{
+ bool available = false;
+ __asm
+ {
+ mov ah, 1
+ int 0x16
+ jz not_avail
+ mov available, true
+ not_avail:
+ }
+
+ return available;
+}
+
+
+bool EscKeyPressed ()
+{
+ if (IsKeyboardCharAvailable ())
+ {
+ byte keyScanCode;
+ GetKeyboardChar (&keyScanCode);
+ return keyScanCode == TC_BIOS_KEY_ESC;
+ }
+
+ return false;
+}
+
+
+void ClearBiosKeystrokeBuffer ()
+{
+ __asm
+ {
+ push es
+ xor ax, ax
+ mov es, ax
+ mov di, 0x41e
+ mov cx, 32
+ cld
+ rep stosb
+ pop es
+ }
+}
+
+
+bool IsPrintable (char c)
+{
+ return c >= ' ' && c <= '~';
+}
+
+bool IsDigit (char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+
+int GetString (char *buffer, size_t bufferSize)
+{
+ byte c;
+ byte scanCode;
+ size_t pos = 0;
+
+ while (pos < bufferSize)
+ {
+ c = GetKeyboardChar (&scanCode);
+
+ if (scanCode == TC_BIOS_KEY_ENTER)
+ break;
+
+ if (scanCode == TC_BIOS_KEY_ESC)
+ return 0;
+
+ buffer[pos++] = c;
+ PrintChar (IsPrintable (c) ? c : ' ');
+ }
+
+ return pos;
+}
diff --git a/src/Boot/Windows/BootConsoleIo.h b/src/Boot/Windows/BootConsoleIo.h
index 6af75c0..b95036d 100644
--- a/src/Boot/Windows/BootConsoleIo.h
+++ b/src/Boot/Windows/BootConsoleIo.h
@@ -1,72 +1,72 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootConsoleIo
-#define TC_HEADER_Boot_BootConsoleIo
-
-#include "Platform.h"
-
-#define TC_DEBUG_PORT 0
-
-#define TC_BIOS_KEY_ESC 1
-#define TC_BIOS_KEY_BACKSPACE 14
-#define TC_BIOS_KEY_ENTER 28
-#define TC_BIOS_KEY_F1 0x3b
-#define TC_BIOS_KEY_F2 0x3c
-#define TC_BIOS_KEY_F3 0x3d
-#define TC_BIOS_KEY_F4 0x3e
-#define TC_BIOS_KEY_F5 0x3f
-#define TC_BIOS_KEY_F6 0x40
-#define TC_BIOS_KEY_F7 0x41
-#define TC_BIOS_KEY_F8 0x42
-#define TC_BIOS_KEY_F9 0x43
-#define TC_BIOS_KEY_F10 0x44
-
-#define TC_BIOS_SHIFTMASK_CAPSLOCK (1 << 6)
-#define TC_BIOS_SHIFTMASK_LSHIFT (1 << 1)
-#define TC_BIOS_SHIFTMASK_RSHIFT (1 << 0)
-
-#define TC_BIOS_CHAR_BACKSPACE 8
-
-#define TC_BIOS_MAX_CHARS_PER_LINE 80
-
-void Beep ();
-void ClearBiosKeystrokeBuffer ();
-void ClearScreen ();
-void DisableScreenOutput ();
-void EnableScreenOutput ();
-bool EscKeyPressed ();
-byte GetKeyboardChar ();
-byte GetKeyboardChar (byte *scanCode);
-byte GetShiftFlags ();
-int GetString (char *buffer, size_t bufferSize);
-void InitVideoMode ();
-bool IsKeyboardCharAvailable ();
-bool IsPrintable (char c);
-bool IsDigit (char c);
-void Print (const char *str);
-void Print (uint32 number);
-void Print (const uint64 &number);
-void PrintBackspace ();
-void PrintChar (char c);
-void PrintCharAtCursor (char c);
-void PrintEndl ();
-void PrintEndl (int cnt);
-void PrintRepeatedChar (char c, int n);
-void PrintError (const char *message);
-void PrintErrorNoEndl (const char *message);
-void PrintHex (byte b);
-void PrintHex (uint16 data);
-void PrintHex (uint32 data);
-void PrintHex (const uint64 &data);
-
-#endif // TC_HEADER_Boot_BootConsoleIo
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootConsoleIo
+#define TC_HEADER_Boot_BootConsoleIo
+
+#include "Platform.h"
+
+#define TC_DEBUG_PORT 0
+
+#define TC_BIOS_KEY_ESC 1
+#define TC_BIOS_KEY_BACKSPACE 14
+#define TC_BIOS_KEY_ENTER 28
+#define TC_BIOS_KEY_F1 0x3b
+#define TC_BIOS_KEY_F2 0x3c
+#define TC_BIOS_KEY_F3 0x3d
+#define TC_BIOS_KEY_F4 0x3e
+#define TC_BIOS_KEY_F5 0x3f
+#define TC_BIOS_KEY_F6 0x40
+#define TC_BIOS_KEY_F7 0x41
+#define TC_BIOS_KEY_F8 0x42
+#define TC_BIOS_KEY_F9 0x43
+#define TC_BIOS_KEY_F10 0x44
+
+#define TC_BIOS_SHIFTMASK_CAPSLOCK (1 << 6)
+#define TC_BIOS_SHIFTMASK_LSHIFT (1 << 1)
+#define TC_BIOS_SHIFTMASK_RSHIFT (1 << 0)
+
+#define TC_BIOS_CHAR_BACKSPACE 8
+
+#define TC_BIOS_MAX_CHARS_PER_LINE 80
+
+void Beep ();
+void ClearBiosKeystrokeBuffer ();
+void ClearScreen ();
+void DisableScreenOutput ();
+void EnableScreenOutput ();
+bool EscKeyPressed ();
+byte GetKeyboardChar ();
+byte GetKeyboardChar (byte *scanCode);
+byte GetShiftFlags ();
+int GetString (char *buffer, size_t bufferSize);
+void InitVideoMode ();
+bool IsKeyboardCharAvailable ();
+bool IsPrintable (char c);
+bool IsDigit (char c);
+void Print (const char *str);
+void Print (uint32 number);
+void Print (const uint64 &number);
+void PrintBackspace ();
+void PrintChar (char c);
+void PrintCharAtCursor (char c);
+void PrintEndl ();
+void PrintEndl (int cnt);
+void PrintRepeatedChar (char c, int n);
+void PrintError (const char *message);
+void PrintErrorNoEndl (const char *message);
+void PrintHex (byte b);
+void PrintHex (uint16 data);
+void PrintHex (uint32 data);
+void PrintHex (const uint64 &data);
+
+#endif // TC_HEADER_Boot_BootConsoleIo
diff --git a/src/Boot/Windows/BootCrt.asm b/src/Boot/Windows/BootCrt.asm
index e309fcb..fd2c2ef 100644
--- a/src/Boot/Windows/BootCrt.asm
+++ b/src/Boot/Windows/BootCrt.asm
@@ -1,27 +1,27 @@
-;
-; 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-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.
-;
-
-.MODEL tiny, C
-.386
-
-INCLUDE BootDefs.i
-
-EXTERNDEF main:NEAR
-
-_TEXT SEGMENT
-ORG TC_COM_EXECUTABLE_OFFSET
-
-start:
- jmp main
-
-_TEXT ENDS
-END start
+;
+; 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-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.
+;
+
+.MODEL tiny, C
+.386
+
+INCLUDE BootDefs.i
+
+EXTERNDEF main:NEAR
+
+_TEXT SEGMENT
+ORG TC_COM_EXECUTABLE_OFFSET
+
+start:
+ jmp main
+
+_TEXT ENDS
+END start
diff --git a/src/Boot/Windows/BootDebug.cpp b/src/Boot/Windows/BootDebug.cpp
index 0f33ed5..2c79643 100644
--- a/src/Boot/Windows/BootDebug.cpp
+++ b/src/Boot/Windows/BootDebug.cpp
@@ -1,181 +1,181 @@
-/*
- 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-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 "Platform.h"
-#include "Bios.h"
-#include "BootConsoleIo.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootDebug.h"
-
-
-#ifdef TC_BOOT_TRACING_ENABLED
-
-void InitDebugPort ()
-{
- __asm
- {
- mov dx, TC_DEBUG_PORT
- mov ah, 1
- int 0x17
- mov dx, TC_DEBUG_PORT
- mov ah, 0xe2
- int 0x17
- }
-}
-
-
-void WriteDebugPort (byte dataByte)
-{
- __asm
- {
- mov al, dataByte
- mov dx, TC_DEBUG_PORT
- mov ah, 0
- int 0x17
- }
-}
-
-#endif // TC_BOOT_TRACING_ENABLED
-
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-
-extern "C" void PrintDebug (uint32 debugVal)
-{
- Print (debugVal);
- PrintEndl();
-}
-
-
-void PrintVal (const char *message, const uint32 value, bool newLine, bool hex)
-{
- Print (message);
- Print (": ");
-
- if (hex)
- PrintHex (value);
- else
- Print (value);
-
- if (newLine)
- PrintEndl();
-}
-
-
-void PrintVal (const char *message, const uint64 &value, bool newLine, bool hex)
-{
- Print (message);
- Print (": ");
- PrintHex (value);
- if (newLine)
- PrintEndl();
-}
-
-
-void PrintHexDump (byte *mem, size_t size, uint16 *memSegment)
-{
- const size_t width = 16;
- for (size_t pos = 0; pos < size; )
- {
- for (int pass = 1; pass <= 2; ++pass)
- {
- size_t i;
- for (i = 0; i < width && pos < size; ++i)
- {
- byte dataByte;
- if (memSegment)
- {
- __asm
- {
- push es
- mov si, ss:memSegment
- mov es, ss:[si]
- mov si, ss:mem
- add si, pos
- mov al, es:[si]
- mov dataByte, al
- pop es
- }
- pos++;
- }
- else
- dataByte = mem[pos++];
-
- if (pass == 1)
- {
- PrintHex (dataByte);
- PrintChar (' ');
- }
- else
- PrintChar (IsPrintable (dataByte) ? dataByte : '.');
- }
-
- if (pass == 1)
- {
- pos -= i;
- PrintChar (' ');
- }
- }
-
- PrintEndl ();
- }
-}
-
-
-void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size)
-{
- PrintHexDump ((byte *) memOffset, size, &memSegment);
-}
-
-#endif // TC_BOOT_DEBUG_ENABLED
-
-
-#ifdef TC_BOOT_STACK_CHECKING_ENABLED
-
-extern "C" char end[];
-
-static void PrintStackInfo ()
-{
- uint16 spReg;
- __asm mov spReg, sp
-
- Print ("Stack: "); Print (TC_BOOT_LOADER_STACK_TOP - spReg);
- Print ("/"); Print (TC_BOOT_LOADER_STACK_TOP - (uint16) end);
-}
-
-
-void CheckStack ()
-{
- uint16 spReg;
- __asm mov spReg, sp
-
- if (*(uint32 *) end != 0x12345678UL || spReg < (uint16) end)
- {
- __asm cli
- __asm mov sp, TC_BOOT_LOADER_STACK_TOP
-
- PrintError ("Stack overflow");
- TC_THROW_FATAL_EXCEPTION;
- }
-}
-
-
-void InitStackChecker ()
-{
- *(uint32 *) end = 0x12345678UL;
-
- PrintStackInfo();
- PrintEndl();
-}
-
-#endif // TC_BOOT_STACK_CHECKING_ENABLED
+/*
+ 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-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 "Platform.h"
+#include "Bios.h"
+#include "BootConsoleIo.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootDebug.h"
+
+
+#ifdef TC_BOOT_TRACING_ENABLED
+
+void InitDebugPort ()
+{
+ __asm
+ {
+ mov dx, TC_DEBUG_PORT
+ mov ah, 1
+ int 0x17
+ mov dx, TC_DEBUG_PORT
+ mov ah, 0xe2
+ int 0x17
+ }
+}
+
+
+void WriteDebugPort (byte dataByte)
+{
+ __asm
+ {
+ mov al, dataByte
+ mov dx, TC_DEBUG_PORT
+ mov ah, 0
+ int 0x17
+ }
+}
+
+#endif // TC_BOOT_TRACING_ENABLED
+
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+
+extern "C" void PrintDebug (uint32 debugVal)
+{
+ Print (debugVal);
+ PrintEndl();
+}
+
+
+void PrintVal (const char *message, const uint32 value, bool newLine, bool hex)
+{
+ Print (message);
+ Print (": ");
+
+ if (hex)
+ PrintHex (value);
+ else
+ Print (value);
+
+ if (newLine)
+ PrintEndl();
+}
+
+
+void PrintVal (const char *message, const uint64 &value, bool newLine, bool hex)
+{
+ Print (message);
+ Print (": ");
+ PrintHex (value);
+ if (newLine)
+ PrintEndl();
+}
+
+
+void PrintHexDump (byte *mem, size_t size, uint16 *memSegment)
+{
+ const size_t width = 16;
+ for (size_t pos = 0; pos < size; )
+ {
+ for (int pass = 1; pass <= 2; ++pass)
+ {
+ size_t i;
+ for (i = 0; i < width && pos < size; ++i)
+ {
+ byte dataByte;
+ if (memSegment)
+ {
+ __asm
+ {
+ push es
+ mov si, ss:memSegment
+ mov es, ss:[si]
+ mov si, ss:mem
+ add si, pos
+ mov al, es:[si]
+ mov dataByte, al
+ pop es
+ }
+ pos++;
+ }
+ else
+ dataByte = mem[pos++];
+
+ if (pass == 1)
+ {
+ PrintHex (dataByte);
+ PrintChar (' ');
+ }
+ else
+ PrintChar (IsPrintable (dataByte) ? dataByte : '.');
+ }
+
+ if (pass == 1)
+ {
+ pos -= i;
+ PrintChar (' ');
+ }
+ }
+
+ PrintEndl ();
+ }
+}
+
+
+void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size)
+{
+ PrintHexDump ((byte *) memOffset, size, &memSegment);
+}
+
+#endif // TC_BOOT_DEBUG_ENABLED
+
+
+#ifdef TC_BOOT_STACK_CHECKING_ENABLED
+
+extern "C" char end[];
+
+static void PrintStackInfo ()
+{
+ uint16 spReg;
+ __asm mov spReg, sp
+
+ Print ("Stack: "); Print (TC_BOOT_LOADER_STACK_TOP - spReg);
+ Print ("/"); Print (TC_BOOT_LOADER_STACK_TOP - (uint16) end);
+}
+
+
+void CheckStack ()
+{
+ uint16 spReg;
+ __asm mov spReg, sp
+
+ if (*(uint32 *) end != 0x12345678UL || spReg < (uint16) end)
+ {
+ __asm cli
+ __asm mov sp, TC_BOOT_LOADER_STACK_TOP
+
+ PrintError ("Stack overflow");
+ TC_THROW_FATAL_EXCEPTION;
+ }
+}
+
+
+void InitStackChecker ()
+{
+ *(uint32 *) end = 0x12345678UL;
+
+ PrintStackInfo();
+ PrintEndl();
+}
+
+#endif // TC_BOOT_STACK_CHECKING_ENABLED
diff --git a/src/Boot/Windows/BootDebug.h b/src/Boot/Windows/BootDebug.h
index 138dcf6..a10c7fe 100644
--- a/src/Boot/Windows/BootDebug.h
+++ b/src/Boot/Windows/BootDebug.h
@@ -1,60 +1,60 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootDebug
-#define TC_HEADER_Boot_BootDebug
-
-#include "Platform.h"
-#include "BootConsoleIo.h"
-
-#if 0
-# define TC_BOOT_DEBUG_ENABLED
-#endif
-
-#if 0 || defined (TC_BOOT_DEBUG_ENABLED)
-# define TC_BOOT_STACK_CHECKING_ENABLED
- extern "C" void CheckStack ();
-#else
-# define CheckStack()
-#endif
-
-#if 0
-# define TC_BOOT_TRACING_ENABLED
-# if 1
-# define TC_TRACE_INT13
-# endif
-# if 0
-# define TC_TRACE_INT15
-# endif
-#endif
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-# define trace_point do { Print(__FILE__); PrintChar (':'); Print (TC_TO_STRING (__LINE__)); PrintEndl(); } while (false)
-# define trace_val(VAL) PrintVal (#VAL, VAL);
-# define trace_hex(VAL) do { Print (#VAL), PrintChar (':'); PrintHex (VAL); PrintEndl(); } while (false)
-# define assert(COND) do { if (!(COND)) { trace_point; __asm jmp $ } } while (false)
-#else
-# define trace_point
-# define trace_val(VAL)
-# define trace_hex(VAL)
-# define assert(COND)
-#endif
-
-void InitDebugPort ();
-void InitStackChecker ();
-void WriteDebugPort (byte dataByte);
-void PrintHexDump (byte *mem, size_t size, uint16 *memSegment = nullptr);
-void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size);
-void PrintVal (const char *message, const uint32 value, bool newLine = true, bool hex = false);
-void PrintVal (const char *message, const uint64 &value, bool newLine = true, bool hex = false);
-
-#endif // TC_HEADER_Boot_BootDebug
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootDebug
+#define TC_HEADER_Boot_BootDebug
+
+#include "Platform.h"
+#include "BootConsoleIo.h"
+
+#if 0
+# define TC_BOOT_DEBUG_ENABLED
+#endif
+
+#if 0 || defined (TC_BOOT_DEBUG_ENABLED)
+# define TC_BOOT_STACK_CHECKING_ENABLED
+ extern "C" void CheckStack ();
+#else
+# define CheckStack()
+#endif
+
+#if 0
+# define TC_BOOT_TRACING_ENABLED
+# if 1
+# define TC_TRACE_INT13
+# endif
+# if 0
+# define TC_TRACE_INT15
+# endif
+#endif
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+# define trace_point do { Print(__FILE__); PrintChar (':'); Print (TC_TO_STRING (__LINE__)); PrintEndl(); } while (false)
+# define trace_val(VAL) PrintVal (#VAL, VAL);
+# define trace_hex(VAL) do { Print (#VAL), PrintChar (':'); PrintHex (VAL); PrintEndl(); } while (false)
+# define assert(COND) do { if (!(COND)) { trace_point; __asm jmp $ } } while (false)
+#else
+# define trace_point
+# define trace_val(VAL)
+# define trace_hex(VAL)
+# define assert(COND)
+#endif
+
+void InitDebugPort ();
+void InitStackChecker ();
+void WriteDebugPort (byte dataByte);
+void PrintHexDump (byte *mem, size_t size, uint16 *memSegment = nullptr);
+void PrintHexDump (uint16 memSegment, uint16 memOffset, size_t size);
+void PrintVal (const char *message, const uint32 value, bool newLine = true, bool hex = false);
+void PrintVal (const char *message, const uint64 &value, bool newLine = true, bool hex = false);
+
+#endif // TC_HEADER_Boot_BootDebug
diff --git a/src/Boot/Windows/BootDefs.h b/src/Boot/Windows/BootDefs.h
index 69c57db..2e69d5a 100644
--- a/src/Boot/Windows/BootDefs.h
+++ b/src/Boot/Windows/BootDefs.h
@@ -1,199 +1,199 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootDefs
-#define TC_HEADER_Boot_BootDefs
-
-// Total memory required (CODE + DATA + BSS + STACK + 0x100) in KBytes - determined from linker map.
-#define TC__BOOT_MEMORY_REQUIRED 43
-
-#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
-# undef TC__BOOT_MEMORY_REQUIRED
-
-# ifdef TC_WINDOWS_BOOT_AES
-# ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-# define TC__BOOT_MEMORY_REQUIRED 31
-# else
-# define TC__BOOT_MEMORY_REQUIRED 29
-# endif
-# elif defined (TC_WINDOWS_BOOT_SERPENT)
-# define TC__BOOT_MEMORY_REQUIRED 33
-# elif defined (TC_WINDOWS_BOOT_TWOFISH)
-# define TC__BOOT_MEMORY_REQUIRED 41
-# endif
-
-#if 0
-# undef TC__BOOT_MEMORY_REQUIRED
-# define TC__BOOT_MEMORY_REQUIRED 60
-#endif
-
-#endif
-
-// Modifying this value can introduce incompatibility with previous versions
-#define TC__BOOT_LOADER_SEGMENT TC_HEX (9000) // Some buggy BIOS routines fail if CS bits 0-10 are not zero
-
-#if TC__BOOT_MEMORY_REQUIRED <= 32
-# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 32 * 1024 / 16)
-#else
-# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 64 * 1024 / 16)
-#endif
-
-#define TC__COM_EXECUTABLE_OFFSET TC_HEX (100)
-
-#define TC__BOOT_LOADER_LOWMEM_SEGMENT TC_HEX (2000)
-#define TC__BOOT_LOADER_BUFFER_SEGMENT TC_HEX (4000)
-#define TC__BOOT_LOADER_ALT_SEGMENT TC_HEX (6000)
-
-#define TC__BOOT_LOADER_STACK_TOP (TC_BOOT_MEMORY_REQUIRED * TC_UNSIGNED (1024) - 4)
-
-#define TC__LB_SIZE 512
-#define TC__BOOT_LOADER_AREA_SECTOR_COUNT 63
-
-#define TC__BOOT_SECTOR_VERSION_OFFSET 430
-#define TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET 432
-#define TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET 434
-#define TC__BOOT_SECTOR_USER_CONFIG_OFFSET 438
-#define TC__BOOT_SECTOR_CONFIG_OFFSET 439 // The last byte that is reserved for the boot loader
-
-#define TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH 24
-#define TC__BOOT_SECTOR_USER_MESSAGE_OFFSET (TC__BOOT_SECTOR_VERSION_OFFSET - TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)
-
-#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE 4
-#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET (TC__BOOT_SECTOR_USER_MESSAGE_OFFSET - TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE)
-
-#define TC__BOOT_SECTOR_PIM_VALUE_SIZE 2
-#define TC__BOOT_SECTOR_PIM_VALUE_OFFSET (TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET - TC__BOOT_SECTOR_PIM_VALUE_SIZE)
-
-#define TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR 2
-#define TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT 4
-#define TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE 32768
-#define TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET (TC_COM_EXECUTABLE_OFFSET + 3072)
-
-#define TC__BOOT_LOADER_START_SECTOR (TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT)
-#define TC__MAX_BOOT_LOADER_SECTOR_COUNT (TC_BOOT_LOADER_AREA_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - 2)
-#define TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE ((TC_BOOT_LOADER_AREA_SECTOR_COUNT - 2) * TC_LB_SIZE)
-
-#define TC__BOOT_LOADER_BACKUP_SECTOR_COUNT 30
-
-#define TC__GZIP_HEADER_SIZE 10
-
-#define TC__BOOT_CFG_FLAG_AREA_SIZE 1 // In bytes
-
-// If you add more flags, revise TC__BOOT_CFG_FLAG_AREA_SIZE
-#define TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC_HEX (02)
-#define TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC_HEX (04)
-#define TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC_HEX (10)
-#define TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC_HEX (20)
-#define TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE (TC_HEX (40) + TC_HEX (80))
-
-// Modifying the following values can introduce incompatibility with previous versions
-#define TC__BOOT_USER_CFG_FLAG_SILENT_MODE TC_HEX (01)
-#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)
-
-// 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
-#define TC__HIDDEN_OS_CREATION_PHASE_CLONING TC_HEX (40) // The boot loader is to copy the content of the system partition to the hidden volume
-#define TC__HIDDEN_OS_CREATION_PHASE_WIPING TC_HEX (80) // The boot loader has successfully copied the content of the system partition to the hidden volume. The original OS is to be wiped now.
-#define TC__HIDDEN_OS_CREATION_PHASE_WIPED (TC_HEX (40) + TC_HEX (80)) // The original OS has been wiped. The user is required to install a new OS (decoy OS) on the system partition now.
-
-
-#ifdef TC_ASM_PREPROCESS
-
-#define TC_HEX(N) 0##N##h
-#define TC_UNSIGNED(N) N
-
-TC_BOOT_MEMORY_REQUIRED = TC__BOOT_MEMORY_REQUIRED
-TC_BOOT_LOADER_SEGMENT = TC__BOOT_LOADER_SEGMENT
-TC_BOOT_LOADER_SEGMENT_LOW = TC__BOOT_LOADER_SEGMENT_LOW
-TC_COM_EXECUTABLE_OFFSET = TC__COM_EXECUTABLE_OFFSET
-TC_BOOT_LOADER_LOWMEM_SEGMENT = TC__BOOT_LOADER_LOWMEM_SEGMENT
-TC_BOOT_LOADER_BUFFER_SEGMENT = TC__BOOT_LOADER_BUFFER_SEGMENT
-TC_BOOT_LOADER_ALT_SEGMENT = TC__BOOT_LOADER_ALT_SEGMENT
-TC_BOOT_LOADER_STACK_TOP = TC__BOOT_LOADER_STACK_TOP
-TC_LB_SIZE = TC__LB_SIZE
-TC_BOOT_LOADER_AREA_SECTOR_COUNT = TC__BOOT_LOADER_AREA_SECTOR_COUNT
-TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET = TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
-TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET = TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
-TC_BOOT_SECTOR_CONFIG_OFFSET = TC__BOOT_SECTOR_CONFIG_OFFSET
-TC_BOOT_SECTOR_USER_CONFIG_OFFSET = TC__BOOT_SECTOR_USER_CONFIG_OFFSET
-TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR = TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
-TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT = TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
-TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE = TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
-TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET = TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
-TC_BOOT_LOADER_START_SECTOR = TC__BOOT_LOADER_START_SECTOR
-TC_MAX_BOOT_LOADER_SECTOR_COUNT = TC__MAX_BOOT_LOADER_SECTOR_COUNT
-TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE = TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
-TC_BOOT_LOADER_BACKUP_SECTOR_COUNT = TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
-TC_GZIP_HEADER_SIZE = TC__GZIP_HEADER_SIZE
-TC_BOOT_CFG_FLAG_AREA_SIZE = TC__BOOT_CFG_FLAG_AREA_SIZE
-TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE = TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
-TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER = TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
-TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER = TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
-TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE = TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
-TC_BOOT_USER_CFG_FLAG_SILENT_MODE = TC__BOOT_USER_CFG_FLAG_SILENT_MODE
-TC_HIDDEN_OS_CREATION_PHASE_NONE = TC__HIDDEN_OS_CREATION_PHASE_NONE
-TC_HIDDEN_OS_CREATION_PHASE_CLONING = TC__HIDDEN_OS_CREATION_PHASE_CLONING
-TC_HIDDEN_OS_CREATION_PHASE_WIPING = TC__HIDDEN_OS_CREATION_PHASE_WIPING
-TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED
-
-#else // TC_ASM_PREPROCESS
-
-#define TC_HEX(N) 0x##N
-#define TC_UNSIGNED(N) N##U
-
-#define TC_BOOT_MEMORY_REQUIRED TC__BOOT_MEMORY_REQUIRED
-#define TC_BOOT_LOADER_SEGMENT TC__BOOT_LOADER_SEGMENT
-#define TC_COM_EXECUTABLE_OFFSET TC__COM_EXECUTABLE_OFFSET
-#define TC_BOOT_LOADER_LOWMEM_SEGMENT TC__BOOT_LOADER_LOWMEM_SEGMENT
-#define TC_BOOT_LOADER_BUFFER_SEGMENT TC__BOOT_LOADER_BUFFER_SEGMENT
-#define TC_BOOT_LOADER_ALT_SEGMENT TC__BOOT_LOADER_ALT_SEGMENT
-#define TC_BOOT_LOADER_STACK_TOP (TC__BOOT_LOADER_STACK_TOP)
-#define TC_BOOT_LOADER_AREA_SECTOR_COUNT TC__BOOT_LOADER_AREA_SECTOR_COUNT
-#define TC_BOOT_SECTOR_USER_MESSAGE_OFFSET TC__BOOT_SECTOR_USER_MESSAGE_OFFSET
-#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE
-#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET
-#define TC_BOOT_SECTOR_PIM_VALUE_SIZE TC__BOOT_SECTOR_PIM_VALUE_SIZE
-#define TC_BOOT_SECTOR_PIM_VALUE_OFFSET TC__BOOT_SECTOR_PIM_VALUE_OFFSET
-#define TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH
-#define TC_BOOT_SECTOR_VERSION_OFFSET TC__BOOT_SECTOR_VERSION_OFFSET
-#define TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
-#define TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
-#define TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
-#define TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
-#define TC_BOOT_SECTOR_CONFIG_OFFSET TC__BOOT_SECTOR_CONFIG_OFFSET
-#define TC_BOOT_SECTOR_USER_CONFIG_OFFSET TC__BOOT_SECTOR_USER_CONFIG_OFFSET
-#define TC_BOOT_LOADER_START_SECTOR TC__BOOT_LOADER_START_SECTOR
-#define TC_LB_SIZE TC__LB_SIZE
-#define TC_MAX_BOOT_LOADER_SECTOR_COUNT TC__MAX_BOOT_LOADER_SECTOR_COUNT
-#define TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
-#define TC_BOOT_LOADER_BACKUP_SECTOR_COUNT TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
-#define TC_GZIP_HEADER_SIZE TC__GZIP_HEADER_SIZE
-#define TC_BOOT_CFG_FLAG_AREA_SIZE TC__BOOT_CFG_FLAG_AREA_SIZE
-#define TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
-#define TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
-#define TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
-#define TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION
-#define TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
-#define TC_BOOT_USER_CFG_FLAG_SILENT_MODE TC__BOOT_USER_CFG_FLAG_SILENT_MODE
-#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_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
-#define TC_HIDDEN_OS_CREATION_PHASE_WIPED TC__HIDDEN_OS_CREATION_PHASE_WIPED
-
-#endif // TC_ASM_PREPROCESS
-
-#endif // TC_HEADER_Boot_BootDefs
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootDefs
+#define TC_HEADER_Boot_BootDefs
+
+// Total memory required (CODE + DATA + BSS + STACK + 0x100) in KBytes - determined from linker map.
+#define TC__BOOT_MEMORY_REQUIRED 43
+
+#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
+# undef TC__BOOT_MEMORY_REQUIRED
+
+# ifdef TC_WINDOWS_BOOT_AES
+# ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+# define TC__BOOT_MEMORY_REQUIRED 31
+# else
+# define TC__BOOT_MEMORY_REQUIRED 29
+# endif
+# elif defined (TC_WINDOWS_BOOT_SERPENT)
+# define TC__BOOT_MEMORY_REQUIRED 33
+# elif defined (TC_WINDOWS_BOOT_TWOFISH)
+# define TC__BOOT_MEMORY_REQUIRED 41
+# endif
+
+#if 0
+# undef TC__BOOT_MEMORY_REQUIRED
+# define TC__BOOT_MEMORY_REQUIRED 60
+#endif
+
+#endif
+
+// Modifying this value can introduce incompatibility with previous versions
+#define TC__BOOT_LOADER_SEGMENT TC_HEX (9000) // Some buggy BIOS routines fail if CS bits 0-10 are not zero
+
+#if TC__BOOT_MEMORY_REQUIRED <= 32
+# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 32 * 1024 / 16)
+#else
+# define TC__BOOT_LOADER_SEGMENT_LOW (TC__BOOT_LOADER_SEGMENT - 64 * 1024 / 16)
+#endif
+
+#define TC__COM_EXECUTABLE_OFFSET TC_HEX (100)
+
+#define TC__BOOT_LOADER_LOWMEM_SEGMENT TC_HEX (2000)
+#define TC__BOOT_LOADER_BUFFER_SEGMENT TC_HEX (4000)
+#define TC__BOOT_LOADER_ALT_SEGMENT TC_HEX (6000)
+
+#define TC__BOOT_LOADER_STACK_TOP (TC_BOOT_MEMORY_REQUIRED * TC_UNSIGNED (1024) - 4)
+
+#define TC__LB_SIZE 512
+#define TC__BOOT_LOADER_AREA_SECTOR_COUNT 63
+
+#define TC__BOOT_SECTOR_VERSION_OFFSET 430
+#define TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET 432
+#define TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET 434
+#define TC__BOOT_SECTOR_USER_CONFIG_OFFSET 438
+#define TC__BOOT_SECTOR_CONFIG_OFFSET 439 // The last byte that is reserved for the boot loader
+
+#define TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH 24
+#define TC__BOOT_SECTOR_USER_MESSAGE_OFFSET (TC__BOOT_SECTOR_VERSION_OFFSET - TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)
+
+#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE 4
+#define TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET (TC__BOOT_SECTOR_USER_MESSAGE_OFFSET - TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE)
+
+#define TC__BOOT_SECTOR_PIM_VALUE_SIZE 2
+#define TC__BOOT_SECTOR_PIM_VALUE_OFFSET (TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET - TC__BOOT_SECTOR_PIM_VALUE_SIZE)
+
+#define TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR 2
+#define TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT 4
+#define TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE 32768
+#define TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET (TC_COM_EXECUTABLE_OFFSET + 3072)
+
+#define TC__BOOT_LOADER_START_SECTOR (TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT)
+#define TC__MAX_BOOT_LOADER_SECTOR_COUNT (TC_BOOT_LOADER_AREA_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT - 2)
+#define TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE ((TC_BOOT_LOADER_AREA_SECTOR_COUNT - 2) * TC_LB_SIZE)
+
+#define TC__BOOT_LOADER_BACKUP_SECTOR_COUNT 30
+
+#define TC__GZIP_HEADER_SIZE 10
+
+#define TC__BOOT_CFG_FLAG_AREA_SIZE 1 // In bytes
+
+// If you add more flags, revise TC__BOOT_CFG_FLAG_AREA_SIZE
+#define TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC_HEX (02)
+#define TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC_HEX (04)
+#define TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC_HEX (10)
+#define TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC_HEX (20)
+#define TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE (TC_HEX (40) + TC_HEX (80))
+
+// Modifying the following values can introduce incompatibility with previous versions
+#define TC__BOOT_USER_CFG_FLAG_SILENT_MODE TC_HEX (01)
+#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)
+
+// 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
+#define TC__HIDDEN_OS_CREATION_PHASE_CLONING TC_HEX (40) // The boot loader is to copy the content of the system partition to the hidden volume
+#define TC__HIDDEN_OS_CREATION_PHASE_WIPING TC_HEX (80) // The boot loader has successfully copied the content of the system partition to the hidden volume. The original OS is to be wiped now.
+#define TC__HIDDEN_OS_CREATION_PHASE_WIPED (TC_HEX (40) + TC_HEX (80)) // The original OS has been wiped. The user is required to install a new OS (decoy OS) on the system partition now.
+
+
+#ifdef TC_ASM_PREPROCESS
+
+#define TC_HEX(N) 0##N##h
+#define TC_UNSIGNED(N) N
+
+TC_BOOT_MEMORY_REQUIRED = TC__BOOT_MEMORY_REQUIRED
+TC_BOOT_LOADER_SEGMENT = TC__BOOT_LOADER_SEGMENT
+TC_BOOT_LOADER_SEGMENT_LOW = TC__BOOT_LOADER_SEGMENT_LOW
+TC_COM_EXECUTABLE_OFFSET = TC__COM_EXECUTABLE_OFFSET
+TC_BOOT_LOADER_LOWMEM_SEGMENT = TC__BOOT_LOADER_LOWMEM_SEGMENT
+TC_BOOT_LOADER_BUFFER_SEGMENT = TC__BOOT_LOADER_BUFFER_SEGMENT
+TC_BOOT_LOADER_ALT_SEGMENT = TC__BOOT_LOADER_ALT_SEGMENT
+TC_BOOT_LOADER_STACK_TOP = TC__BOOT_LOADER_STACK_TOP
+TC_LB_SIZE = TC__LB_SIZE
+TC_BOOT_LOADER_AREA_SECTOR_COUNT = TC__BOOT_LOADER_AREA_SECTOR_COUNT
+TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET = TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
+TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET = TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
+TC_BOOT_SECTOR_CONFIG_OFFSET = TC__BOOT_SECTOR_CONFIG_OFFSET
+TC_BOOT_SECTOR_USER_CONFIG_OFFSET = TC__BOOT_SECTOR_USER_CONFIG_OFFSET
+TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR = TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
+TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT = TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE = TC__BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
+TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET = TC__BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
+TC_BOOT_LOADER_START_SECTOR = TC__BOOT_LOADER_START_SECTOR
+TC_MAX_BOOT_LOADER_SECTOR_COUNT = TC__MAX_BOOT_LOADER_SECTOR_COUNT
+TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE = TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
+TC_BOOT_LOADER_BACKUP_SECTOR_COUNT = TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
+TC_GZIP_HEADER_SIZE = TC__GZIP_HEADER_SIZE
+TC_BOOT_CFG_FLAG_AREA_SIZE = TC__BOOT_CFG_FLAG_AREA_SIZE
+TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE = TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
+TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER = TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
+TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER = TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
+TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE = TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
+TC_BOOT_USER_CFG_FLAG_SILENT_MODE = TC__BOOT_USER_CFG_FLAG_SILENT_MODE
+TC_HIDDEN_OS_CREATION_PHASE_NONE = TC__HIDDEN_OS_CREATION_PHASE_NONE
+TC_HIDDEN_OS_CREATION_PHASE_CLONING = TC__HIDDEN_OS_CREATION_PHASE_CLONING
+TC_HIDDEN_OS_CREATION_PHASE_WIPING = TC__HIDDEN_OS_CREATION_PHASE_WIPING
+TC_HIDDEN_OS_CREATION_PHASE_WIPED = TC__HIDDEN_OS_CREATION_PHASE_WIPED
+
+#else // TC_ASM_PREPROCESS
+
+#define TC_HEX(N) 0x##N
+#define TC_UNSIGNED(N) N##U
+
+#define TC_BOOT_MEMORY_REQUIRED TC__BOOT_MEMORY_REQUIRED
+#define TC_BOOT_LOADER_SEGMENT TC__BOOT_LOADER_SEGMENT
+#define TC_COM_EXECUTABLE_OFFSET TC__COM_EXECUTABLE_OFFSET
+#define TC_BOOT_LOADER_LOWMEM_SEGMENT TC__BOOT_LOADER_LOWMEM_SEGMENT
+#define TC_BOOT_LOADER_BUFFER_SEGMENT TC__BOOT_LOADER_BUFFER_SEGMENT
+#define TC_BOOT_LOADER_ALT_SEGMENT TC__BOOT_LOADER_ALT_SEGMENT
+#define TC_BOOT_LOADER_STACK_TOP (TC__BOOT_LOADER_STACK_TOP)
+#define TC_BOOT_LOADER_AREA_SECTOR_COUNT TC__BOOT_LOADER_AREA_SECTOR_COUNT
+#define TC_BOOT_SECTOR_USER_MESSAGE_OFFSET TC__BOOT_SECTOR_USER_MESSAGE_OFFSET
+#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE
+#define TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET TC__BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET
+#define TC_BOOT_SECTOR_PIM_VALUE_SIZE TC__BOOT_SECTOR_PIM_VALUE_SIZE
+#define TC_BOOT_SECTOR_PIM_VALUE_OFFSET TC__BOOT_SECTOR_PIM_VALUE_OFFSET
+#define TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH TC__BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH
+#define TC_BOOT_SECTOR_VERSION_OFFSET TC__BOOT_SECTOR_VERSION_OFFSET
+#define TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET TC__BOOT_SECTOR_LOADER_LENGTH_OFFSET
+#define TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET TC__BOOT_SECTOR_LOADER_CHECKSUM_OFFSET
+#define TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR TC__BOOT_LOADER_DECOMPRESSOR_START_SECTOR
+#define TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT TC__BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+#define TC_BOOT_SECTOR_CONFIG_OFFSET TC__BOOT_SECTOR_CONFIG_OFFSET
+#define TC_BOOT_SECTOR_USER_CONFIG_OFFSET TC__BOOT_SECTOR_USER_CONFIG_OFFSET
+#define TC_BOOT_LOADER_START_SECTOR TC__BOOT_LOADER_START_SECTOR
+#define TC_LB_SIZE TC__LB_SIZE
+#define TC_MAX_BOOT_LOADER_SECTOR_COUNT TC__MAX_BOOT_LOADER_SECTOR_COUNT
+#define TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE TC__MAX_BOOT_LOADER_DECOMPRESSED_SIZE
+#define TC_BOOT_LOADER_BACKUP_SECTOR_COUNT TC__BOOT_LOADER_BACKUP_SECTOR_COUNT
+#define TC_GZIP_HEADER_SIZE TC__GZIP_HEADER_SIZE
+#define TC_BOOT_CFG_FLAG_AREA_SIZE TC__BOOT_CFG_FLAG_AREA_SIZE
+#define TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE TC__BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE
+#define TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER TC__BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER
+#define TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER TC__BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER
+#define TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION TC__BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION
+#define TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE TC__BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE
+#define TC_BOOT_USER_CFG_FLAG_SILENT_MODE TC__BOOT_USER_CFG_FLAG_SILENT_MODE
+#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_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
+#define TC_HIDDEN_OS_CREATION_PHASE_WIPED TC__HIDDEN_OS_CREATION_PHASE_WIPED
+
+#endif // TC_ASM_PREPROCESS
+
+#endif // TC_HEADER_Boot_BootDefs
diff --git a/src/Boot/Windows/BootDiskIo.cpp b/src/Boot/Windows/BootDiskIo.cpp
index 31917a6..bf3fe9f 100644
--- a/src/Boot/Windows/BootDiskIo.cpp
+++ b/src/Boot/Windows/BootDiskIo.cpp
@@ -1,491 +1,491 @@
-/*
- 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-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 "Bios.h"
-#include "BootConsoleIo.h"
-#include "BootConfig.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootStrings.h"
-
-
-byte SectorBuffer[TC_LB_SIZE];
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-static bool SectorBufferInUse = false;
-
-void AcquireSectorBuffer ()
-{
- if (SectorBufferInUse)
- TC_THROW_FATAL_EXCEPTION;
-
- SectorBufferInUse = true;
-}
-
-
-void ReleaseSectorBuffer ()
-{
- SectorBufferInUse = false;
-}
-
-#endif
-
-
-bool IsLbaSupported (byte drive)
-{
- static byte CachedDrive = TC_INVALID_BIOS_DRIVE;
- static bool CachedStatus;
- uint16 result = 0;
-
- if (CachedDrive == drive)
- goto ret;
-
- __asm
- {
- mov bx, 0x55aa
- mov dl, drive
- mov ah, 0x41
- int 0x13
- jc err
- mov result, bx
- err:
- }
-
- CachedDrive = drive;
- CachedStatus = (result == 0xaa55);
-ret:
- return CachedStatus;
-}
-
-
-void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs)
-{
- PrintEndl();
- Print (write ? "Write" : "Read"); Print (" error:");
- Print (error);
- Print (" Drive:");
- Print (drive ^ 0x80);
-
- if (sector)
- {
- Print (" Sector:");
- Print (*sector);
- }
-
- if (chs)
- {
- Print (" CHS:");
- Print (*chs);
- }
-
- PrintEndl();
- Beep();
-}
-
-
-void Print (const ChsAddress &chs)
-{
- Print (chs.Cylinder);
- PrintChar ('/');
- Print (chs.Head);
- PrintChar ('/');
- Print (chs.Sector);
-}
-
-
-void PrintSectorCountInMB (const uint64 &sectorCount)
-{
- Print (sectorCount >> (TC_LB_SIZE_BIT_SHIFT_DIVISOR + 2)); Print (" MB ");
-}
-
-
-BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- CheckStack();
-
- byte cylinderLow = (byte) chs.Cylinder;
- byte sector = chs.Sector;
- sector |= byte (chs.Cylinder >> 2) & 0xc0;
- byte function = write ? 0x03 : 0x02;
-
- BiosResult result;
- byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
-
- do
- {
- result = BiosResultSuccess;
-
- __asm
- {
- push es
- mov ax, bufferSegment
- mov es, ax
- mov bx, bufferOffset
- mov dl, drive
- mov ch, cylinderLow
- mov si, chs
- mov dh, [si].Head
- mov cl, sector
- mov al, sectorCount
- mov ah, function
- int 0x13
- jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
- mov result, ah
- ok:
- pop es
- }
-
- if (result == BiosResultEccCorrected)
- result = BiosResultSuccess;
-
- // Some BIOSes report I/O errors prematurely in some cases
- } while (result != BiosResultSuccess && --tryCount != 0);
-
- if (!silent && result != BiosResultSuccess)
- PrintDiskError (result, write, drive, nullptr, &chs);
-
- return result;
-}
-
-
-BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- uint16 codeSeg;
- __asm mov codeSeg, cs
- return ReadWriteSectors (write, codeSeg, (uint16) buffer, drive, chs, sectorCount, silent);
-}
-
-
-BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent);
-}
-
-
-BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
-{
- return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent);
-}
-
-
-static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- CheckStack();
-
- if (!IsLbaSupported (drive))
- {
- DriveGeometry geometry;
-
- BiosResult result = GetDriveGeometry (drive, geometry, silent);
- if (result != BiosResultSuccess)
- return result;
-
- ChsAddress chs;
- LbaToChs (geometry, sector, chs);
- return ReadWriteSectors (write, (uint16) (dapPacket.Buffer >> 16), (uint16) dapPacket.Buffer, drive, chs, sectorCount, silent);
- }
-
- dapPacket.Size = sizeof (dapPacket);
- dapPacket.Reserved = 0;
- dapPacket.SectorCount = sectorCount;
- dapPacket.Sector = sector;
-
- byte function = write ? 0x43 : 0x42;
-
- BiosResult result;
- byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
-
- do
- {
- result = BiosResultSuccess;
-
- __asm
- {
- mov bx, 0x55aa
- mov dl, drive
- mov si, [dapPacket]
- mov ah, function
- xor al, al
- int 0x13
- jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
- mov result, ah
- ok:
- }
-
- if (result == BiosResultEccCorrected)
- result = BiosResultSuccess;
-
- // Some BIOSes report I/O errors prematurely in some cases
- } while (result != BiosResultSuccess && --tryCount != 0);
-
- if (!silent && result != BiosResultSuccess)
- PrintDiskError (result, write, drive, &sector);
-
- return result;
-}
-
-
-static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- BiosLbaPacket dapPacket;
- dapPacket.Buffer = (uint32) buffer;
- return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
-}
-
-
-BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- BiosLbaPacket dapPacket;
- dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset;
- return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
-}
-
-BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent);
-}
-
-
-BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- BiosResult result;
- uint16 codeSeg;
- __asm mov codeSeg, cs
-
- result = ReadSectors (BootStarted ? codeSeg : TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, drive, sector, sectorCount, silent);
-
- // Alternative segment is used to prevent memory corruption caused by buggy BIOSes
- if (!BootStarted)
- CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, buffer, sectorCount * TC_LB_SIZE);
-
- return result;
-}
-
-
-BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
-{
- return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent);
-}
-
-
-BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent)
-{
- CheckStack();
-
- byte maxCylinderLow, maxHead, maxSector;
- BiosResult result;
- __asm
- {
- push es
- mov dl, drive
- mov ah, 0x08
- int 0x13
-
- mov result, ah
- mov maxCylinderLow, ch
- mov maxSector, cl
- mov maxHead, dh
- pop es
- }
-
- if (result == BiosResultSuccess)
- {
- geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1;
- geometry.Heads = maxHead + 1;
- geometry.Sectors = maxSector & ~0xc0;
- }
- else if (!silent)
- {
- Print ("Drive ");
- Print (drive ^ 0x80);
- Print (" not found: ");
- PrintErrorNoEndl ("");
- Print (result);
- PrintEndl();
- }
-
- return result;
-}
-
-
-void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba)
-{
- lba.HighPart = 0;
- lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1;
-}
-
-
-void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs)
-{
- chs.Sector = (byte) ((lba.LowPart % geometry.Sectors) + 1);
- uint32 ch = lba.LowPart / geometry.Sectors;
- chs.Head = (byte) (ch % geometry.Heads);
- chs.Cylinder = (uint16) (ch / geometry.Heads);
-}
-
-
-void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition)
-{
- partition.Active = partEntry.BootIndicator == 0x80;
- partition.EndSector.HighPart = 0;
- partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1;
- partition.SectorCount.HighPart = 0;
- partition.SectorCount.LowPart = partEntry.SectorCountLBA;
- partition.StartSector.HighPart = 0;
- partition.StartSector.LowPart = partEntry.StartLBA;
- partition.Type = partEntry.Type;
-}
-
-
-BiosResult ReadWriteMBR (bool write, byte drive, bool silent)
-{
- uint64 mbrSector;
- mbrSector.HighPart = 0;
- mbrSector.LowPart = 0;
-
- if (write)
- return WriteSectors (SectorBuffer, drive, mbrSector, 1, silent);
-
- return ReadSectors (SectorBuffer, drive, mbrSector, 1, silent); // Uses alternative segment
-}
-
-
-BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, Partition *findPartitionFollowingThis, bool silent)
-{
- Partition *followingPartition;
- Partition tmpPartition;
-
- if (findPartitionFollowingThis)
- {
- assert (partitionArrayCapacity == 1);
- partitionArrayCapacity = 0xff;
- followingPartition = partitionArray;
- partitionArray = &tmpPartition;
-
- followingPartition->Drive = TC_INVALID_BIOS_DRIVE;
- followingPartition->StartSector.LowPart = 0xFFFFffffUL;
- }
-
- AcquireSectorBuffer();
- BiosResult result = ReadWriteMBR (false, drive, silent);
- ReleaseSectorBuffer();
-
- partitionCount = 0;
-
- MBR *mbr = (MBR *) SectorBuffer;
- if (result != BiosResultSuccess || mbr->Signature != 0xaa55)
- return result;
-
- PartitionEntryMBR mbrPartitions[4];
- memcpy (mbrPartitions, mbr->Partitions, sizeof (mbrPartitions));
- size_t partitionArrayPos = 0, partitionNumber;
-
- for (partitionNumber = 0;
- partitionNumber < array_capacity (mbrPartitions) && partitionArrayPos < partitionArrayCapacity;
- ++partitionNumber)
- {
- const PartitionEntryMBR &partEntry = mbrPartitions[partitionNumber];
-
- if (partEntry.SectorCountLBA > 0)
- {
- Partition &partition = partitionArray[partitionArrayPos];
- PartitionEntryMBRToPartition (partEntry, partition);
-
- if (activeOnly && !partition.Active)
- continue;
-
- partition.Drive = drive;
- partition.Number = partitionArrayPos;
-
- if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition
- {
- if (IsLbaSupported (drive))
- {
- // Find all extended partitions
- uint64 firstExtStartLBA = partition.StartSector;
- uint64 extStartLBA = partition.StartSector;
- MBR *extMbr = (MBR *) SectorBuffer;
-
- while (partitionArrayPos < partitionArrayCapacity &&
- (result = ReadSectors ((byte *) extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess
- && extMbr->Signature == 0xaa55)
- {
- if (extMbr->Partitions[0].SectorCountLBA > 0)
- {
- Partition &logPart = partitionArray[partitionArrayPos];
- PartitionEntryMBRToPartition (extMbr->Partitions[0], logPart);
- logPart.Drive = drive;
-
- logPart.Number = partitionArrayPos;
- logPart.Primary = false;
-
- logPart.StartSector.LowPart += extStartLBA.LowPart;
- logPart.EndSector.LowPart += extStartLBA.LowPart;
-
- if (findPartitionFollowingThis)
- {
- if (logPart.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
- && logPart.StartSector.LowPart < followingPartition->StartSector.LowPart)
- {
- *followingPartition = logPart;
- }
- }
- else
- ++partitionArrayPos;
- }
-
- // Secondary extended
- if (extMbr->Partitions[1].Type != 0x5 && extMbr->Partitions[1].Type == 0xf
- || extMbr->Partitions[1].SectorCountLBA == 0)
- break;
-
- extStartLBA.LowPart = extMbr->Partitions[1].StartLBA + firstExtStartLBA.LowPart;
- }
- }
- }
- else
- {
- partition.Primary = true;
-
- if (findPartitionFollowingThis)
- {
- if (partition.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
- && partition.StartSector.LowPart < followingPartition->StartSector.LowPart)
- {
- *followingPartition = partition;
- }
- }
- else
- ++partitionArrayPos;
- }
- }
- }
-
- partitionCount = partitionArrayPos;
- return result;
-}
-
-
-bool GetActivePartition (byte drive)
-{
- size_t partCount;
-
- if (GetDrivePartitions (drive, &ActivePartition, 1, partCount, true) != BiosResultSuccess || partCount < 1)
- {
- ActivePartition.Drive = TC_INVALID_BIOS_DRIVE;
- PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
- return false;
- }
-
- return true;
-}
+/*
+ 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-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 "Bios.h"
+#include "BootConsoleIo.h"
+#include "BootConfig.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootStrings.h"
+
+
+byte SectorBuffer[TC_LB_SIZE];
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+static bool SectorBufferInUse = false;
+
+void AcquireSectorBuffer ()
+{
+ if (SectorBufferInUse)
+ TC_THROW_FATAL_EXCEPTION;
+
+ SectorBufferInUse = true;
+}
+
+
+void ReleaseSectorBuffer ()
+{
+ SectorBufferInUse = false;
+}
+
+#endif
+
+
+bool IsLbaSupported (byte drive)
+{
+ static byte CachedDrive = TC_INVALID_BIOS_DRIVE;
+ static bool CachedStatus;
+ uint16 result = 0;
+
+ if (CachedDrive == drive)
+ goto ret;
+
+ __asm
+ {
+ mov bx, 0x55aa
+ mov dl, drive
+ mov ah, 0x41
+ int 0x13
+ jc err
+ mov result, bx
+ err:
+ }
+
+ CachedDrive = drive;
+ CachedStatus = (result == 0xaa55);
+ret:
+ return CachedStatus;
+}
+
+
+void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs)
+{
+ PrintEndl();
+ Print (write ? "Write" : "Read"); Print (" error:");
+ Print (error);
+ Print (" Drive:");
+ Print (drive ^ 0x80);
+
+ if (sector)
+ {
+ Print (" Sector:");
+ Print (*sector);
+ }
+
+ if (chs)
+ {
+ Print (" CHS:");
+ Print (*chs);
+ }
+
+ PrintEndl();
+ Beep();
+}
+
+
+void Print (const ChsAddress &chs)
+{
+ Print (chs.Cylinder);
+ PrintChar ('/');
+ Print (chs.Head);
+ PrintChar ('/');
+ Print (chs.Sector);
+}
+
+
+void PrintSectorCountInMB (const uint64 &sectorCount)
+{
+ Print (sectorCount >> (TC_LB_SIZE_BIT_SHIFT_DIVISOR + 2)); Print (" MB ");
+}
+
+
+BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ CheckStack();
+
+ byte cylinderLow = (byte) chs.Cylinder;
+ byte sector = chs.Sector;
+ sector |= byte (chs.Cylinder >> 2) & 0xc0;
+ byte function = write ? 0x03 : 0x02;
+
+ BiosResult result;
+ byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
+
+ do
+ {
+ result = BiosResultSuccess;
+
+ __asm
+ {
+ push es
+ mov ax, bufferSegment
+ mov es, ax
+ mov bx, bufferOffset
+ mov dl, drive
+ mov ch, cylinderLow
+ mov si, chs
+ mov dh, [si].Head
+ mov cl, sector
+ mov al, sectorCount
+ mov ah, function
+ int 0x13
+ jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
+ mov result, ah
+ ok:
+ pop es
+ }
+
+ if (result == BiosResultEccCorrected)
+ result = BiosResultSuccess;
+
+ // Some BIOSes report I/O errors prematurely in some cases
+ } while (result != BiosResultSuccess && --tryCount != 0);
+
+ if (!silent && result != BiosResultSuccess)
+ PrintDiskError (result, write, drive, nullptr, &chs);
+
+ return result;
+}
+
+
+BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+ return ReadWriteSectors (write, codeSeg, (uint16) buffer, drive, chs, sectorCount, silent);
+}
+
+
+BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent);
+}
+
+
+BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
+{
+ return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent);
+}
+
+
+static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ CheckStack();
+
+ if (!IsLbaSupported (drive))
+ {
+ DriveGeometry geometry;
+
+ BiosResult result = GetDriveGeometry (drive, geometry, silent);
+ if (result != BiosResultSuccess)
+ return result;
+
+ ChsAddress chs;
+ LbaToChs (geometry, sector, chs);
+ return ReadWriteSectors (write, (uint16) (dapPacket.Buffer >> 16), (uint16) dapPacket.Buffer, drive, chs, sectorCount, silent);
+ }
+
+ dapPacket.Size = sizeof (dapPacket);
+ dapPacket.Reserved = 0;
+ dapPacket.SectorCount = sectorCount;
+ dapPacket.Sector = sector;
+
+ byte function = write ? 0x43 : 0x42;
+
+ BiosResult result;
+ byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
+
+ do
+ {
+ result = BiosResultSuccess;
+
+ __asm
+ {
+ mov bx, 0x55aa
+ mov dl, drive
+ mov si, [dapPacket]
+ mov ah, function
+ xor al, al
+ int 0x13
+ jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
+ mov result, ah
+ ok:
+ }
+
+ if (result == BiosResultEccCorrected)
+ result = BiosResultSuccess;
+
+ // Some BIOSes report I/O errors prematurely in some cases
+ } while (result != BiosResultSuccess && --tryCount != 0);
+
+ if (!silent && result != BiosResultSuccess)
+ PrintDiskError (result, write, drive, &sector);
+
+ return result;
+}
+
+
+static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ BiosLbaPacket dapPacket;
+ dapPacket.Buffer = (uint32) buffer;
+ return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
+}
+
+
+BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ BiosLbaPacket dapPacket;
+ dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset;
+ return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
+}
+
+BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent);
+}
+
+
+BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ BiosResult result;
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+
+ result = ReadSectors (BootStarted ? codeSeg : TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, drive, sector, sectorCount, silent);
+
+ // Alternative segment is used to prevent memory corruption caused by buggy BIOSes
+ if (!BootStarted)
+ CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, buffer, sectorCount * TC_LB_SIZE);
+
+ return result;
+}
+
+
+BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
+{
+ return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent);
+}
+
+
+BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent)
+{
+ CheckStack();
+
+ byte maxCylinderLow, maxHead, maxSector;
+ BiosResult result;
+ __asm
+ {
+ push es
+ mov dl, drive
+ mov ah, 0x08
+ int 0x13
+
+ mov result, ah
+ mov maxCylinderLow, ch
+ mov maxSector, cl
+ mov maxHead, dh
+ pop es
+ }
+
+ if (result == BiosResultSuccess)
+ {
+ geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1;
+ geometry.Heads = maxHead + 1;
+ geometry.Sectors = maxSector & ~0xc0;
+ }
+ else if (!silent)
+ {
+ Print ("Drive ");
+ Print (drive ^ 0x80);
+ Print (" not found: ");
+ PrintErrorNoEndl ("");
+ Print (result);
+ PrintEndl();
+ }
+
+ return result;
+}
+
+
+void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba)
+{
+ lba.HighPart = 0;
+ lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1;
+}
+
+
+void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs)
+{
+ chs.Sector = (byte) ((lba.LowPart % geometry.Sectors) + 1);
+ uint32 ch = lba.LowPart / geometry.Sectors;
+ chs.Head = (byte) (ch % geometry.Heads);
+ chs.Cylinder = (uint16) (ch / geometry.Heads);
+}
+
+
+void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition)
+{
+ partition.Active = partEntry.BootIndicator == 0x80;
+ partition.EndSector.HighPart = 0;
+ partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1;
+ partition.SectorCount.HighPart = 0;
+ partition.SectorCount.LowPart = partEntry.SectorCountLBA;
+ partition.StartSector.HighPart = 0;
+ partition.StartSector.LowPart = partEntry.StartLBA;
+ partition.Type = partEntry.Type;
+}
+
+
+BiosResult ReadWriteMBR (bool write, byte drive, bool silent)
+{
+ uint64 mbrSector;
+ mbrSector.HighPart = 0;
+ mbrSector.LowPart = 0;
+
+ if (write)
+ return WriteSectors (SectorBuffer, drive, mbrSector, 1, silent);
+
+ return ReadSectors (SectorBuffer, drive, mbrSector, 1, silent); // Uses alternative segment
+}
+
+
+BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, Partition *findPartitionFollowingThis, bool silent)
+{
+ Partition *followingPartition;
+ Partition tmpPartition;
+
+ if (findPartitionFollowingThis)
+ {
+ assert (partitionArrayCapacity == 1);
+ partitionArrayCapacity = 0xff;
+ followingPartition = partitionArray;
+ partitionArray = &tmpPartition;
+
+ followingPartition->Drive = TC_INVALID_BIOS_DRIVE;
+ followingPartition->StartSector.LowPart = 0xFFFFffffUL;
+ }
+
+ AcquireSectorBuffer();
+ BiosResult result = ReadWriteMBR (false, drive, silent);
+ ReleaseSectorBuffer();
+
+ partitionCount = 0;
+
+ MBR *mbr = (MBR *) SectorBuffer;
+ if (result != BiosResultSuccess || mbr->Signature != 0xaa55)
+ return result;
+
+ PartitionEntryMBR mbrPartitions[4];
+ memcpy (mbrPartitions, mbr->Partitions, sizeof (mbrPartitions));
+ size_t partitionArrayPos = 0, partitionNumber;
+
+ for (partitionNumber = 0;
+ partitionNumber < array_capacity (mbrPartitions) && partitionArrayPos < partitionArrayCapacity;
+ ++partitionNumber)
+ {
+ const PartitionEntryMBR &partEntry = mbrPartitions[partitionNumber];
+
+ if (partEntry.SectorCountLBA > 0)
+ {
+ Partition &partition = partitionArray[partitionArrayPos];
+ PartitionEntryMBRToPartition (partEntry, partition);
+
+ if (activeOnly && !partition.Active)
+ continue;
+
+ partition.Drive = drive;
+ partition.Number = partitionArrayPos;
+
+ if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition
+ {
+ if (IsLbaSupported (drive))
+ {
+ // Find all extended partitions
+ uint64 firstExtStartLBA = partition.StartSector;
+ uint64 extStartLBA = partition.StartSector;
+ MBR *extMbr = (MBR *) SectorBuffer;
+
+ while (partitionArrayPos < partitionArrayCapacity &&
+ (result = ReadSectors ((byte *) extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess
+ && extMbr->Signature == 0xaa55)
+ {
+ if (extMbr->Partitions[0].SectorCountLBA > 0)
+ {
+ Partition &logPart = partitionArray[partitionArrayPos];
+ PartitionEntryMBRToPartition (extMbr->Partitions[0], logPart);
+ logPart.Drive = drive;
+
+ logPart.Number = partitionArrayPos;
+ logPart.Primary = false;
+
+ logPart.StartSector.LowPart += extStartLBA.LowPart;
+ logPart.EndSector.LowPart += extStartLBA.LowPart;
+
+ if (findPartitionFollowingThis)
+ {
+ if (logPart.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
+ && logPart.StartSector.LowPart < followingPartition->StartSector.LowPart)
+ {
+ *followingPartition = logPart;
+ }
+ }
+ else
+ ++partitionArrayPos;
+ }
+
+ // Secondary extended
+ if (extMbr->Partitions[1].Type != 0x5 && extMbr->Partitions[1].Type == 0xf
+ || extMbr->Partitions[1].SectorCountLBA == 0)
+ break;
+
+ extStartLBA.LowPart = extMbr->Partitions[1].StartLBA + firstExtStartLBA.LowPart;
+ }
+ }
+ }
+ else
+ {
+ partition.Primary = true;
+
+ if (findPartitionFollowingThis)
+ {
+ if (partition.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
+ && partition.StartSector.LowPart < followingPartition->StartSector.LowPart)
+ {
+ *followingPartition = partition;
+ }
+ }
+ else
+ ++partitionArrayPos;
+ }
+ }
+ }
+
+ partitionCount = partitionArrayPos;
+ return result;
+}
+
+
+bool GetActivePartition (byte drive)
+{
+ size_t partCount;
+
+ if (GetDrivePartitions (drive, &ActivePartition, 1, partCount, true) != BiosResultSuccess || partCount < 1)
+ {
+ ActivePartition.Drive = TC_INVALID_BIOS_DRIVE;
+ PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/Boot/Windows/BootDiskIo.h b/src/Boot/Windows/BootDiskIo.h
index d1c1ccf..b09220a 100644
--- a/src/Boot/Windows/BootDiskIo.h
+++ b/src/Boot/Windows/BootDiskIo.h
@@ -1,120 +1,120 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootDiskIo
-#define TC_HEADER_Boot_BootDiskIo
-
-#include "Bios.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-
-#define TC_MAX_BIOS_DISK_IO_RETRIES 5
-
-enum
-{
- BiosResultEccCorrected = 0x11
-};
-
-#pragma pack(1)
-
-struct PartitionEntryMBR
-{
- byte BootIndicator;
-
- byte StartHead;
- byte StartCylSector;
- byte StartCylinder;
-
- byte Type;
-
- byte EndHead;
- byte EndSector;
- byte EndCylinder;
-
- uint32 StartLBA;
- uint32 SectorCountLBA;
-};
-
-struct MBR
-{
- byte Code[446];
- PartitionEntryMBR Partitions[4];
- uint16 Signature;
-};
-
-struct BiosLbaPacket
-{
- byte Size;
- byte Reserved;
- uint16 SectorCount;
- uint32 Buffer;
- uint64 Sector;
-};
-
-#pragma pack()
-
-
-struct ChsAddress
-{
- uint16 Cylinder;
- byte Head;
- byte Sector;
-};
-
-struct Partition
-{
- byte Number;
- byte Drive;
- bool Active;
- uint64 EndSector;
- bool Primary;
- uint64 SectorCount;
- uint64 StartSector;
- byte Type;
-};
-
-struct DriveGeometry
-{
- uint16 Cylinders;
- byte Heads;
- byte Sectors;
-};
-
-
-#ifdef TC_BOOT_DEBUG_ENABLED
-void AcquireSectorBuffer ();
-void ReleaseSectorBuffer ();
-#else
-# define AcquireSectorBuffer()
-# define ReleaseSectorBuffer()
-#endif
-
-void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba);
-bool GetActivePartition (byte drive);
-BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent = false);
-BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly = false, Partition *findPartitionFollowingThis = nullptr, bool silent = false);
-bool IsLbaSupported (byte drive);
-void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs);
-void Print (const ChsAddress &chs);
-void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs = nullptr);
-void PrintSectorCountInMB (const uint64 &sectorCount);
-BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false);
-BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
-BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
-BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
-BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent);
-BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
-BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
-
-extern byte SectorBuffer[TC_LB_SIZE];
-
-#endif // TC_HEADER_Boot_BootDiskIo
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootDiskIo
+#define TC_HEADER_Boot_BootDiskIo
+
+#include "Bios.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+
+#define TC_MAX_BIOS_DISK_IO_RETRIES 5
+
+enum
+{
+ BiosResultEccCorrected = 0x11
+};
+
+#pragma pack(1)
+
+struct PartitionEntryMBR
+{
+ byte BootIndicator;
+
+ byte StartHead;
+ byte StartCylSector;
+ byte StartCylinder;
+
+ byte Type;
+
+ byte EndHead;
+ byte EndSector;
+ byte EndCylinder;
+
+ uint32 StartLBA;
+ uint32 SectorCountLBA;
+};
+
+struct MBR
+{
+ byte Code[446];
+ PartitionEntryMBR Partitions[4];
+ uint16 Signature;
+};
+
+struct BiosLbaPacket
+{
+ byte Size;
+ byte Reserved;
+ uint16 SectorCount;
+ uint32 Buffer;
+ uint64 Sector;
+};
+
+#pragma pack()
+
+
+struct ChsAddress
+{
+ uint16 Cylinder;
+ byte Head;
+ byte Sector;
+};
+
+struct Partition
+{
+ byte Number;
+ byte Drive;
+ bool Active;
+ uint64 EndSector;
+ bool Primary;
+ uint64 SectorCount;
+ uint64 StartSector;
+ byte Type;
+};
+
+struct DriveGeometry
+{
+ uint16 Cylinders;
+ byte Heads;
+ byte Sectors;
+};
+
+
+#ifdef TC_BOOT_DEBUG_ENABLED
+void AcquireSectorBuffer ();
+void ReleaseSectorBuffer ();
+#else
+# define AcquireSectorBuffer()
+# define ReleaseSectorBuffer()
+#endif
+
+void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba);
+bool GetActivePartition (byte drive);
+BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent = false);
+BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly = false, Partition *findPartitionFollowingThis = nullptr, bool silent = false);
+bool IsLbaSupported (byte drive);
+void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs);
+void Print (const ChsAddress &chs);
+void PrintDiskError (BiosResult error, bool write, byte drive, const uint64 *sector, const ChsAddress *chs = nullptr);
+void PrintSectorCountInMB (const uint64 &sectorCount);
+BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false);
+BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
+BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
+BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
+BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent);
+BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
+BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
+
+extern byte SectorBuffer[TC_LB_SIZE];
+
+#endif // TC_HEADER_Boot_BootDiskIo
diff --git a/src/Boot/Windows/BootEncryptedIo.cpp b/src/Boot/Windows/BootEncryptedIo.cpp
index d130534..84a4bf1 100644
--- a/src/Boot/Windows/BootEncryptedIo.cpp
+++ b/src/Boot/Windows/BootEncryptedIo.cpp
@@ -1,132 +1,132 @@
-/*
- 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-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 "Crypto.h"
-#include "Platform.h"
-#include "BootConfig.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootEncryptedIo.h"
-
-
-BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount)
-{
- BiosResult result;
- bool decrypt = true;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
- return BiosResultInvalidFunction;
-
- if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
- {
- // Remap the request to the hidden volume
- sector -= EncryptedVirtualPartition.StartSector;
- sector += HiddenVolumeStartSector;
- }
- else
- decrypt = false;
- }
-
- result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount);
-
- if (result != BiosResultSuccess || !decrypt)
- return result;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- // Convert sector number to data unit number of the hidden volume
- sector -= HiddenVolumeStartSector;
- sector += PimValueOrHiddenVolumeStartUnitNo;
- }
-
- if (drive == EncryptedVirtualPartition.Drive)
- {
- while (sectorCount-- > 0)
- {
- if (BootCryptoInfo->hiddenVolume
- || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector))
- {
- AcquireSectorBuffer();
- CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE);
-
- DecryptDataUnits (SectorBuffer, &sector, 1, BootCryptoInfo);
-
- CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE);
- ReleaseSectorBuffer();
- }
-
- ++sector;
- destOffset += TC_LB_SIZE;
- }
- }
-
- return result;
-}
-
-
-BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount)
-{
- BiosResult result = BiosResultSuccess;
- AcquireSectorBuffer();
- uint64 dataUnitNo;
- uint64 writeOffset;
-
- dataUnitNo = sector;
- writeOffset.HighPart = 0;
- writeOffset.LowPart = 0;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
- return BiosResultInvalidFunction;
-
- // Remap the request to the hidden volume
- writeOffset = HiddenVolumeStartSector;
- writeOffset -= EncryptedVirtualPartition.StartSector;
- dataUnitNo -= EncryptedVirtualPartition.StartSector;
- dataUnitNo += PimValueOrHiddenVolumeStartUnitNo;
- }
-
- while (sectorCount-- > 0)
- {
- CopyMemory (sourceSegment, sourceOffset, SectorBuffer, TC_LB_SIZE);
-
- if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
- {
- EncryptDataUnits (SectorBuffer, &dataUnitNo, 1, BootCryptoInfo);
- }
-
- result = WriteSectors (SectorBuffer, drive, sector + writeOffset, 1);
-
- if (result != BiosResultSuccess)
- break;
-
- ++sector;
- ++dataUnitNo;
- sourceOffset += TC_LB_SIZE;
- }
-
- ReleaseSectorBuffer();
- return result;
-}
-
-
-static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount)
-{
- uint64 readWriteEnd = sector + --sectorCount;
-
- return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector)
- || (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector));
-}
+/*
+ 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-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 "Crypto.h"
+#include "Platform.h"
+#include "BootConfig.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootEncryptedIo.h"
+
+
+BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount)
+{
+ BiosResult result;
+ bool decrypt = true;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
+ return BiosResultInvalidFunction;
+
+ if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
+ {
+ // Remap the request to the hidden volume
+ sector -= EncryptedVirtualPartition.StartSector;
+ sector += HiddenVolumeStartSector;
+ }
+ else
+ decrypt = false;
+ }
+
+ result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount);
+
+ if (result != BiosResultSuccess || !decrypt)
+ return result;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ // Convert sector number to data unit number of the hidden volume
+ sector -= HiddenVolumeStartSector;
+ sector += PimValueOrHiddenVolumeStartUnitNo;
+ }
+
+ if (drive == EncryptedVirtualPartition.Drive)
+ {
+ while (sectorCount-- > 0)
+ {
+ if (BootCryptoInfo->hiddenVolume
+ || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector))
+ {
+ AcquireSectorBuffer();
+ CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE);
+
+ DecryptDataUnits (SectorBuffer, &sector, 1, BootCryptoInfo);
+
+ CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE);
+ ReleaseSectorBuffer();
+ }
+
+ ++sector;
+ destOffset += TC_LB_SIZE;
+ }
+ }
+
+ return result;
+}
+
+
+BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount)
+{
+ BiosResult result = BiosResultSuccess;
+ AcquireSectorBuffer();
+ uint64 dataUnitNo;
+ uint64 writeOffset;
+
+ dataUnitNo = sector;
+ writeOffset.HighPart = 0;
+ writeOffset.LowPart = 0;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount))
+ return BiosResultInvalidFunction;
+
+ // Remap the request to the hidden volume
+ writeOffset = HiddenVolumeStartSector;
+ writeOffset -= EncryptedVirtualPartition.StartSector;
+ dataUnitNo -= EncryptedVirtualPartition.StartSector;
+ dataUnitNo += PimValueOrHiddenVolumeStartUnitNo;
+ }
+
+ while (sectorCount-- > 0)
+ {
+ CopyMemory (sourceSegment, sourceOffset, SectorBuffer, TC_LB_SIZE);
+
+ if (drive == EncryptedVirtualPartition.Drive && sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)
+ {
+ EncryptDataUnits (SectorBuffer, &dataUnitNo, 1, BootCryptoInfo);
+ }
+
+ result = WriteSectors (SectorBuffer, drive, sector + writeOffset, 1);
+
+ if (result != BiosResultSuccess)
+ break;
+
+ ++sector;
+ ++dataUnitNo;
+ sourceOffset += TC_LB_SIZE;
+ }
+
+ ReleaseSectorBuffer();
+ return result;
+}
+
+
+static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount)
+{
+ uint64 readWriteEnd = sector + --sectorCount;
+
+ return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector)
+ || (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector));
+}
diff --git a/src/Boot/Windows/BootEncryptedIo.h b/src/Boot/Windows/BootEncryptedIo.h
index 6cc375f..6402e70 100644
--- a/src/Boot/Windows/BootEncryptedIo.h
+++ b/src/Boot/Windows/BootEncryptedIo.h
@@ -1,22 +1,22 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootEncryptionIo
-#define TC_HEADER_Boot_BootEncryptionIo
-
-#include "Platform.h"
-
-BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount);
-BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount);
-static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount);
-
-#endif // TC_HEADER_Boot_BootEncryptionIo
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootEncryptionIo
+#define TC_HEADER_Boot_BootEncryptionIo
+
+#include "Platform.h"
+
+BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount);
+BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount);
+static bool ReadWritePartiallyCoversEncryptedArea (const uint64 &sector, uint16 sectorCount);
+
+#endif // TC_HEADER_Boot_BootEncryptionIo
diff --git a/src/Boot/Windows/BootMain.cpp b/src/Boot/Windows/BootMain.cpp
index 275c576..24acd23 100644
--- a/src/Boot/Windows/BootMain.cpp
+++ b/src/Boot/Windows/BootMain.cpp
@@ -1,1269 +1,1269 @@
-/*
- 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-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 "Crc.h"
-#include "Crypto.h"
-#include "Password.h"
-#include "Volumes.h"
-
-#include "Platform.h"
-#include "Bios.h"
-#include "BootConfig.h"
-#include "BootMain.h"
-#include "BootDefs.h"
-#include "BootCommon.h"
-#include "BootConsoleIo.h"
-#include "BootDebug.h"
-#include "BootDiskIo.h"
-#include "BootEncryptedIo.h"
-#include "BootMemory.h"
-#include "BootStrings.h"
-#include "IntFilter.h"
-
-
-static void InitScreen ()
-{
- ClearScreen();
-
- const char *title =
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- " VeraCrypt Boot Loader "
-#else
- " VeraCrypt Rescue Disk "
-#endif
- VERSION_STRING "\r\n";
-
- Print (title);
-
- PrintRepeatedChar ('\xDC', TC_BIOS_MAX_CHARS_PER_LINE);
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- if (CustomUserMessage[0])
- {
- PrintEndl();
- Print (CustomUserMessage);
- }
-#endif
-
- PrintEndl (2);
-}
-
-
-static void PrintMainMenu ()
-{
- if (PreventBootMenu)
- return;
-
- Print (" Keyboard Controls:\r\n");
- Print (" [F5] Hide/Show Password and PIM\r\n");
- Print (" [Esc] ");
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- Print ((BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE
- ? "Boot Non-Hidden System (Boot Manager)"
- : "Skip Authentication (Boot Manager)");
-
-#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- Print ("Skip Authentication (Boot Manager)");
- Print ("\r\n [F8] "); Print ("Repair Options");
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- PrintEndl (3);
-}
-
-
-static bool IsMenuKey (byte scanCode)
-{
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- return scanCode == TC_MENU_KEY_REPAIR;
-#else
- return false;
-#endif
-}
-
-
-static bool AskYesNo (const char *message)
-{
- Print (message);
- Print ("? (y/n): ");
- while (true)
- {
- switch (GetKeyboardChar())
- {
- case 'y':
- case 'Y':
- case 'z':
- case 'Z':
- Print ("y\r\n");
- return true;
-
- case 'n':
- case 'N':
- Print ("n\r\n");
- return false;
-
- default:
- Beep();
- }
- }
-}
-
-
-static int AskSelection (const char *options[], size_t optionCount)
-{
- for (int i = 0; i < optionCount; ++i)
- {
- Print ("["); Print (i + 1); Print ("] ");
- Print (options[i]);
- PrintEndl();
- }
- Print ("[Esc] Cancel\r\n\r\n");
-
- Print ("To select, press 1-9: ");
-
- char str;
-
- while (true)
- {
- if (GetString (&str, 1) == 0)
- return 0;
-
- if (str >= '1' && str <= optionCount + '0')
- return str - '0';
-
- Beep();
- PrintBackspace();
- }
-}
-
-
-static byte AskPassword (Password &password, int& pim)
-{
- size_t pos = 0;
- byte scanCode;
- byte asciiCode;
- byte hidePassword = 1;
-
- pim = 0;
-
- Print ("Enter password");
- Print (PreventNormalSystemBoot ? " for hidden system:\r\n" : ": ");
-
- while (true)
- {
- asciiCode = GetKeyboardChar (&scanCode);
-
- switch (scanCode)
- {
- case TC_BIOS_KEY_ENTER:
- password.Length = pos;
- Print ("\r");
- if (!PreventNormalSystemBoot)
- Print ("Enter password: ");
- pos = 0;
- while (pos < MAX_PASSWORD)
- {
- pos++;
- if (pos < MAX_PASSWORD)
- PrintChar ('*');
- else
- PrintCharAtCursor ('*');
- }
-
- ClearBiosKeystrokeBuffer();
- PrintEndl();
-
- break;
-
- case TC_BIOS_KEY_BACKSPACE:
- if (pos > 0)
- {
- if (pos < MAX_PASSWORD)
- PrintBackspace();
- else
- PrintCharAtCursor (' ');
-
- --pos;
- }
- continue;
-
- case TC_BIOS_KEY_F5:
- hidePassword ^= 0x01;
- continue;
-
- default:
- if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
- {
- burn (password.Text, sizeof (password.Text));
- ClearBiosKeystrokeBuffer();
-
- PrintEndl();
- return scanCode;
- }
- }
-
- if (TC_BIOS_KEY_ENTER == scanCode)
- break;
-
- if (!IsPrintable (asciiCode) || pos == MAX_PASSWORD)
- {
- Beep();
- continue;
- }
-
- password.Text[pos++] = asciiCode;
- if (hidePassword) asciiCode = '*';
- if (pos < MAX_PASSWORD)
- PrintChar (asciiCode);
- else
- PrintCharAtCursor (asciiCode);
- }
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- if (PimValueOrHiddenVolumeStartUnitNo.LowPart != -1)
- {
- pim = (int) PimValueOrHiddenVolumeStartUnitNo.LowPart;
- // reset stored PIM value to allow requesting PIM next time in case the stored value is wrong
- PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
- return TC_BIOS_KEY_ENTER;
- }
- else
-#endif
- {
- pos = 0;
- Print ("PIM: ");
-
- while (true)
- {
- asciiCode = GetKeyboardChar (&scanCode);
-
- switch (scanCode)
- {
- case TC_BIOS_KEY_ENTER:
- Print ("\rPIM: ");
- pos =0;
- while (pos < MAX_PIM)
- {
- PrintChar ('*');
- pos++;
- }
-
- ClearBiosKeystrokeBuffer();
- PrintEndl();
-
- return TC_BIOS_KEY_ENTER;
-
- case TC_BIOS_KEY_BACKSPACE:
- if (pos > 0)
- {
- if (pos < MAX_PIM)
- PrintBackspace();
- else
- PrintCharAtCursor (' ');
-
- --pos;
- pim /= 10;
- }
- continue;
-
- case TC_BIOS_KEY_F5:
- hidePassword ^= 0x01;
- continue;
-
- default:
- if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
- {
- burn (password.Text, sizeof (password.Text));
- ClearBiosKeystrokeBuffer();
-
- PrintEndl();
- return scanCode;
- }
- }
-
- if (!IsDigit (asciiCode) || pos == MAX_PIM)
- {
- Beep();
- continue;
- }
-
- pim = 10*pim + (asciiCode - '0');
- pos++;
-
- if (hidePassword) asciiCode = '*';
- if (pos < MAX_PIM)
- PrintChar (asciiCode);
- else
- PrintCharAtCursor (asciiCode);
- }
- }
-}
-
-
-static void ExecuteBootSector (byte drive, byte *sectorBuffer)
-{
- Print ("Booting...\r\n");
- CopyMemory (sectorBuffer, 0x0000, 0x7c00, TC_LB_SIZE);
-
- BootStarted = true;
-
- uint32 addr = 0x7c00;
- __asm
- {
- cli
- mov dl, drive // Boot drive
- mov dh, 0
- xor ax, ax
- mov si, ax
- mov ds, ax
- mov es, ax
- mov ss, ax
- mov sp, 0x7c00
- sti
-
- jmp cs:addr
- }
-}
-
-
-static bool OpenVolume (byte drive, Password &password, int pim, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden)
-{
- int volumeType;
- bool hiddenVolume;
- uint64 headerSec;
-
- AcquireSectorBuffer();
-
- for (volumeType = 1; volumeType <= 2; ++volumeType)
- {
- hiddenVolume = (volumeType == 2);
-
- if (hiddenVolume)
- {
- if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount)
- continue;
-
- headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE;
- }
- else
- {
- if (skipNormal)
- continue;
-
- headerSec.HighPart = 0;
- headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
- }
-
- if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess)
- continue;
-
- if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, pim, cryptoInfo, nullptr) == ERR_SUCCESS)
- {
- // Prevent opening a non-system hidden volume
- if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM))
- {
- crypto_close (*cryptoInfo);
- continue;
- }
-
- if (headerSaltCrc32)
- *headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE);
-
- break;
- }
- }
-
- ReleaseSectorBuffer();
- return volumeType != 3;
-}
-
-
-static bool CheckMemoryRequirements ()
-{
- uint16 codeSeg;
- __asm mov codeSeg, cs
- if (codeSeg == TC_BOOT_LOADER_LOWMEM_SEGMENT)
- {
- PrintErrorNoEndl ("BIOS reserved too much memory: ");
-
- uint16 memFree;
- __asm
- {
- push es
- xor ax, ax
- mov es, ax
- mov ax, es:[0x413]
- mov memFree, ax
- pop es
- }
-
- Print (memFree);
- PrintEndl();
- Print (TC_BOOT_STR_UPGRADE_BIOS);
-
- return false;
- }
-
- return true;
-}
-
-
-static bool MountVolume (byte drive, byte &exitKey, bool skipNormal, bool skipHidden)
-{
- BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
- int incorrectPasswordCount = 0, pim = 0;
-
- EraseMemory (bootArguments, sizeof (*bootArguments));
-
- // Open volume header
- while (true)
- {
- exitKey = AskPassword (bootArguments->BootPassword, pim);
-
- if (exitKey != TC_BIOS_KEY_ENTER)
- return false;
-
- Print ("Verifying password...");
-
- if (OpenVolume (BootDrive, bootArguments->BootPassword, pim, &BootCryptoInfo, &bootArguments->HeaderSaltCrc32, skipNormal, skipHidden))
- {
- Print ("OK\r\n");
- break;
- }
- if (GetShiftFlags() & TC_BIOS_SHIFTMASK_CAPSLOCK)
- Print ("Warning: Caps Lock is on.\r\n");
-
- Print ("Incorrect password.\r\n\r\n");
-
- if (++incorrectPasswordCount == 4)
- {
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- Print ("If you are sure the password is correct, the key data may be damaged.\r\n"
- "If so, use 'Repair Options' > 'Restore key data'.\r\n\r\n");
-#else
- Print ("If you are sure the password is correct, the key data may be damaged. Boot your\r\n"
- "VeraCrypt Rescue Disk and select 'Repair Options' > 'Restore key data'.\r\n\r\n");
-#endif
- }
- }
-
- // Setup boot arguments
- bootArguments->BootLoaderVersion = VERSION_NUM;
- bootArguments->CryptoInfoOffset = (uint16) BootCryptoInfo;
- bootArguments->CryptoInfoLength = sizeof (*BootCryptoInfo);
- bootArguments->Flags = (((uint32)pim) << 16);
-
- if (BootCryptoInfo->hiddenVolume)
- bootArguments->HiddenSystemPartitionStart = PartitionFollowingActive.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- if (ExtraBootPartitionPresent)
- bootArguments->Flags |= TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION;
-
- TC_SET_BOOT_ARGUMENTS_SIGNATURE (bootArguments->Signature);
-
- // Setup virtual encrypted partition
- if (BootCryptoInfo->EncryptedAreaLength.HighPart != 0 || BootCryptoInfo->EncryptedAreaLength.LowPart != 0)
- {
- EncryptedVirtualPartition.Drive = BootDrive;
-
- EncryptedVirtualPartition.StartSector = BootCryptoInfo->EncryptedAreaStart >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- PimValueOrHiddenVolumeStartUnitNo = EncryptedVirtualPartition.StartSector;
- HiddenVolumeStartSector = PartitionFollowingActive.StartSector;
- HiddenVolumeStartSector += EncryptedVirtualPartition.StartSector;
-
- EncryptedVirtualPartition.SectorCount = BootCryptoInfo->EncryptedAreaLength >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- EncryptedVirtualPartition.EndSector = EncryptedVirtualPartition.SectorCount - 1;
- EncryptedVirtualPartition.EndSector += EncryptedVirtualPartition.StartSector;
- }
- else
- {
- // Drive not encrypted
- EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
- }
-
- return true;
-}
-
-
-static bool GetSystemPartitions (byte drive)
-{
- size_t partCount;
-
- if (!GetActivePartition (drive))
- return false;
-
- // Find partition following the active one
- GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
-
- // If there is an extra boot partition, use the partitions following it.
- // The real boot partition is determined in BootEncryptedDrive().
- if (ActivePartition.SectorCount.HighPart == 0 && ActivePartition.SectorCount.LowPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE / TC_LB_SIZE
- && PartitionFollowingActive.Drive != TC_INVALID_BIOS_DRIVE)
- {
- ExtraBootPartitionPresent = true;
-
- ActivePartition = PartitionFollowingActive;
- GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
- }
-
- return true;
-}
-
-
-static byte BootEncryptedDrive ()
-{
- BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
- byte exitKey;
- BootCryptoInfo = NULL;
-
- if (!GetSystemPartitions (BootDrive))
- goto err;
-
- if (!MountVolume (BootDrive, exitKey, PreventNormalSystemBoot, false))
- return exitKey;
-
- if (!CheckMemoryRequirements ())
- goto err;
-
- if (BootCryptoInfo->hiddenVolume)
- {
- EncryptedVirtualPartition = ActivePartition;
- bootArguments->DecoySystemPartitionStart = ActivePartition.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
- }
-
- if (ExtraBootPartitionPresent && !GetActivePartition (BootDrive))
- goto err;
-
- if (ReadWriteMBR (false, ActivePartition.Drive) != BiosResultSuccess)
- goto err;
-
- bootArguments->BootDriveSignature = *(uint32 *) (SectorBuffer + 0x1b8);
-
- if (!InstallInterruptFilters())
- goto err;
-
- bootArguments->BootArgumentsCrc32 = GetCrc32 ((byte *) bootArguments, (byte *) &bootArguments->BootArgumentsCrc32 - (byte *) bootArguments);
-
- while (true)
- {
- // Execute boot sector of the active partition
- if (ReadSectors (SectorBuffer, ActivePartition.Drive, ActivePartition.StartSector, 1) == BiosResultSuccess)
- {
- if (*(uint16 *) (SectorBuffer + 510) != 0xaa55)
- {
- PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
- GetKeyboardChar();
- }
-
- ExecuteBootSector (ActivePartition.Drive, SectorBuffer);
- }
-
- GetKeyboardChar();
- }
-
-err:
- if (BootCryptoInfo)
- {
- crypto_close (BootCryptoInfo);
- BootCryptoInfo = NULL;
- }
-
- EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
- EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
-
- byte scanCode;
- GetKeyboardChar (&scanCode);
- return scanCode;
-}
-
-
-static void BootMenu ()
-{
- BiosResult result;
- Partition partitions[16];
- Partition bootablePartitions[9];
- size_t partitionCount;
- size_t bootablePartitionCount = 0;
-
- for (byte drive = TC_FIRST_BIOS_DRIVE; drive <= TC_LAST_BIOS_DRIVE; ++drive)
- {
- if (GetDrivePartitions (drive, partitions, array_capacity (partitions), partitionCount, false, nullptr, true) == BiosResultSuccess)
- {
- for (size_t i = 0; i < partitionCount; ++i)
- {
- const Partition &partition = partitions[i];
- result = ReadSectors (SectorBuffer, drive, partition.StartSector, 1);
-
- if (result == BiosResultSuccess && *(uint16 *) (SectorBuffer + TC_LB_SIZE - 2) == 0xaa55)
- {
- // Windows writes boot loader on all NTFS/FAT filesytems it creates and, therefore,
- // NTFS/FAT partitions must have the boot indicator set to be considered bootable.
- if (!partition.Active
- && (*(uint32 *) (SectorBuffer + 3) == 0x5346544e // 'NTFS'
- || *(uint32 *) (SectorBuffer + 3) == 0x41465845 && SectorBuffer[7] == 'T' // 'exFAT'
- || *(uint16 *) (SectorBuffer + 54) == 0x4146 && SectorBuffer[56] == 'T' // 'FAT'
- || *(uint16 *) (SectorBuffer + 82) == 0x4146 && SectorBuffer[84] == 'T'))
- {
- continue;
- }
-
- // Bootable sector found
- if (bootablePartitionCount < array_capacity (bootablePartitions))
- bootablePartitions[bootablePartitionCount++] = partition;
- }
- }
- }
- }
-
- if (bootablePartitionCount < 1)
- {
- PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
- GetKeyboardChar();
- return;
- }
-
- char partChar;
- while (true)
- {
- InitScreen();
- Print ("Bootable Partitions:\r\n");
- PrintRepeatedChar ('\xC4', 20);
- Print ("\r\n");
-
- for (size_t i = 0; i < bootablePartitionCount; ++i)
- {
- const Partition &partition = bootablePartitions[i];
- Print ("["); Print (i + 1); Print ("] ");
- Print ("Drive: "); Print (partition.Drive - TC_FIRST_BIOS_DRIVE);
- Print (", Partition: "); Print (partition.Number + 1);
- Print (", Size: "); PrintSectorCountInMB (partition.SectorCount); PrintEndl();
- }
-
- if (bootablePartitionCount == 1)
- {
- // There's only one bootable partition so we'll boot it directly instead of showing boot manager
- partChar = '1';
- }
- else
- {
- Print ("[Esc] Cancel\r\n\r\n");
- Print ("Press 1-9 to select partition: ");
-
- if (GetString (&partChar, 1) == 0)
- return;
-
- PrintEndl();
-
- if (partChar < '1' || partChar > '0' + bootablePartitionCount)
- {
- Beep();
- continue;
- }
- }
-
- const Partition &partition = bootablePartitions[partChar - '0' - 1];
-
- if (ReadSectors (SectorBuffer, partition.Drive, partition.StartSector, 1) == BiosResultSuccess)
- {
- ExecuteBootSector (partition.Drive, SectorBuffer);
- }
- }
-}
-
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-static bool CopySystemPartitionToHiddenVolume (byte drive, byte &exitKey)
-{
- bool status = false;
-
- uint64 sectorsRemaining;
- uint64 sectorOffset;
- sectorOffset.LowPart = 0;
- sectorOffset.HighPart = 0;
-
- int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
- int statCount = 0;
-
- if (!CheckMemoryRequirements ())
- goto err;
-
- if (!GetSystemPartitions (drive))
- goto err;
-
- if (PartitionFollowingActive.Drive == TC_INVALID_BIOS_DRIVE)
- TC_THROW_FATAL_EXCEPTION;
-
- // Check if BIOS can read the last sector of the hidden system
- AcquireSectorBuffer();
-
- if (ReadSectors (SectorBuffer, PartitionFollowingActive.Drive, PartitionFollowingActive.EndSector - (TC_VOLUME_HEADER_GROUP_SIZE / TC_LB_SIZE - 2), 1) != BiosResultSuccess
- || GetCrc32 (SectorBuffer, sizeof (SectorBuffer)) != OuterVolumeBackupHeaderCrc)
- {
- PrintErrorNoEndl ("Your BIOS does not support large drives");
- Print (IsLbaSupported (PartitionFollowingActive.Drive) ? " due to a bug" : "\r\n- Enable LBA in BIOS");
- PrintEndl();
- Print (TC_BOOT_STR_UPGRADE_BIOS);
-
- ReleaseSectorBuffer();
- goto err;
- }
-
- ReleaseSectorBuffer();
-
- if (!MountVolume (drive, exitKey, true, false))
- return false;
-
- sectorsRemaining = EncryptedVirtualPartition.SectorCount;
-
- if (!(sectorsRemaining == ActivePartition.SectorCount))
- TC_THROW_FATAL_EXCEPTION;
-
- InitScreen();
- Print ("\r\nCopying system to hidden volume. To abort, press Esc.\r\n\r\n");
-
- while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
- {
- if (EscKeyPressed())
- {
- Print ("\rIf aborted, copying will have to start from the beginning (if attempted again).\r\n");
- if (AskYesNo ("Abort"))
- break;
- }
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
- fragmentSectorCount = (int) sectorsRemaining.LowPart;
-
- if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, ActivePartition.StartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
- {
- Print ("To fix bad sectors: 1) Terminate 2) Encrypt and decrypt sys partition 3) Retry\r\n");
- crypto_close (BootCryptoInfo);
- goto err;
- }
-
- AcquireSectorBuffer();
-
- for (int i = 0; i < fragmentSectorCount; ++i)
- {
- CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
-
- uint64 s = PimValueOrHiddenVolumeStartUnitNo + sectorOffset + i;
- EncryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
-
- CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
- }
-
- ReleaseSectorBuffer();
-
- if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, HiddenVolumeStartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
- {
- crypto_close (BootCryptoInfo);
- goto err;
- }
-
- sectorsRemaining = sectorsRemaining - fragmentSectorCount;
- sectorOffset = sectorOffset + fragmentSectorCount;
-
- if (!(statCount++ & 0xf))
- {
- Print ("\rRemaining: ");
- PrintSectorCountInMB (sectorsRemaining);
- }
- }
-
- crypto_close (BootCryptoInfo);
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
- {
- status = true;
- Print ("\rCopying completed.");
- }
-
- PrintEndl (2);
- goto ret;
-
-err:
- exitKey = TC_BIOS_KEY_ESC;
- GetKeyboardChar();
-
-ret:
- EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
- return status;
-}
-
-
-#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-
-static void DecryptDrive (byte drive)
-{
- byte exitKey;
- if (!MountVolume (drive, exitKey, false, true))
- return;
-
- BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
-
- bool headerUpdateRequired = false;
- uint64 sectorsRemaining = EncryptedVirtualPartition.EndSector + 1 - EncryptedVirtualPartition.StartSector;
- uint64 sector = EncryptedVirtualPartition.EndSector + 1;
-
- int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
- int statCount = 0;
-
- bool skipBadSectors = false;
-
- Print ("\r\nUse only if Windows cannot start. Decryption under Windows is much faster\r\n"
- "(in VeraCrypt, select 'System' > 'Permanently Decrypt').\r\n\r\n");
-
- if (!AskYesNo ("Decrypt now"))
- {
- crypto_close (BootCryptoInfo);
- goto ret;
- }
-
- if (EncryptedVirtualPartition.Drive == TC_INVALID_BIOS_DRIVE)
- {
- // Drive already decrypted
- sectorsRemaining.HighPart = 0;
- sectorsRemaining.LowPart = 0;
- }
- else
- {
- Print ("\r\nTo safely interrupt and defer decryption, press Esc.\r\n"
- "WARNING: You can turn off power only after you press Esc.\r\n\r\n");
- }
-
- while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
- {
- if (EscKeyPressed())
- break;
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
- fragmentSectorCount = (int) sectorsRemaining.LowPart;
-
- sector = sector - fragmentSectorCount;
-
- if (!(statCount++ & 0xf))
- {
- Print ("\rRemaining: ");
- PrintSectorCountInMB (sectorsRemaining);
- }
-
- if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) == BiosResultSuccess)
- {
- AcquireSectorBuffer();
-
- for (int i = 0; i < fragmentSectorCount; ++i)
- {
- CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
-
- uint64 s = sector + i;
- DecryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
-
- CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
- }
-
- ReleaseSectorBuffer();
-
- if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) != BiosResultSuccess && !skipBadSectors)
- goto askBadSectorSkip;
- }
- else if (!skipBadSectors)
- goto askBadSectorSkip;
-
- sectorsRemaining = sectorsRemaining - fragmentSectorCount;
- headerUpdateRequired = true;
- continue;
-
-askBadSectorSkip:
- if (!AskYesNo ("Skip all bad sectors"))
- break;
-
- skipBadSectors = true;
- sector = sector + fragmentSectorCount;
- fragmentSectorCount = 1;
- }
-
- crypto_close (BootCryptoInfo);
-
- if (headerUpdateRequired)
- {
- Print ("\rUpdating header...");
-
- AcquireSectorBuffer();
- uint64 headerSector;
- headerSector.HighPart = 0;
- headerSector.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
-
- // Update encrypted area size in volume header
-
- CRYPTO_INFO *headerCryptoInfo = crypto_open();
- while (ReadSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
-
- if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &bootArguments->BootPassword, (int) (bootArguments->Flags >> 16), NULL, headerCryptoInfo) == 0)
- {
- DecryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
-
- uint64 encryptedAreaLength = sectorsRemaining << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
-
- for (int i = 7; i >= 0; --i)
- {
- SectorBuffer[TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH + i] = (byte) encryptedAreaLength.LowPart;
- encryptedAreaLength = encryptedAreaLength >> 8;
- }
-
- uint32 headerCrc32 = GetCrc32 (SectorBuffer + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
-
- for (i = 3; i >= 0; --i)
- {
- SectorBuffer[TC_HEADER_OFFSET_HEADER_CRC + i] = (byte) headerCrc32;
- headerCrc32 >>= 8;
- }
-
- EncryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
- }
-
- crypto_close (headerCryptoInfo);
-
- while (WriteSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
- ReleaseSectorBuffer();
-
- Print ("Done!\r\n");
- }
-
- if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
- Print ("\rDrive decrypted.\r\n");
- else
- Print ("\r\nDecryption deferred.\r\n");
-
- GetKeyboardChar();
-ret:
- EraseMemory (bootArguments, sizeof (*bootArguments));
-}
-
-
-static void RepairMenu ()
-{
- DriveGeometry bootLoaderDriveGeometry;
-
- if (GetDriveGeometry (BootLoaderDrive, bootLoaderDriveGeometry, true) != BiosResultSuccess)
- {
- // Some BIOSes may fail to get the geometry of an emulated floppy drive
- bootLoaderDriveGeometry.Cylinders = 80;
- bootLoaderDriveGeometry.Heads = 2;
- bootLoaderDriveGeometry.Sectors = 18;
- }
-
- while (true)
- {
- InitScreen();
- Print ("Available "); Print ("Repair Options"); Print (":\r\n");
- PrintRepeatedChar ('\xC4', 25);
- PrintEndl();
-
- enum
- {
- RestoreNone = 0,
- DecryptVolume,
- RestoreTrueCryptLoader,
- RestoreVolumeHeader,
- RestoreOriginalSystemLoader
- };
-
- static const char *options[] = { "Permanently decrypt system partition/drive", "Restore VeraCrypt Boot Loader", "Restore key data (volume header)", "Restore original system loader" };
-
- int selection = AskSelection (options,
- (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER) ? array_capacity (options) : array_capacity (options) - 1);
-
- PrintEndl();
-
- switch (selection)
- {
- case RestoreNone:
- return;
-
- case DecryptVolume:
- DecryptDrive (BootDrive);
- continue;
-
- case RestoreOriginalSystemLoader:
- if (!AskYesNo ("Is the system partition/drive decrypted"))
- {
- Print ("Please decrypt it first.\r\n");
- GetKeyboardChar();
- continue;
- }
- break;
- }
-
- bool writeConfirmed = false;
- BiosResult result;
-
- uint64 sector;
- sector.HighPart = 0;
- ChsAddress chs;
-
- byte mbrPartTable[TC_LB_SIZE - TC_MAX_MBR_BOOT_CODE_SIZE];
- AcquireSectorBuffer();
-
- for (int i = (selection == RestoreVolumeHeader ? TC_BOOT_VOLUME_HEADER_SECTOR : TC_MBR_SECTOR);
- i < TC_BOOT_LOADER_AREA_SECTOR_COUNT; ++i)
- {
- sector.LowPart = i;
-
- if (selection == RestoreOriginalSystemLoader)
- sector.LowPart += TC_ORIG_BOOT_LOADER_BACKUP_SECTOR;
- else if (selection == RestoreTrueCryptLoader)
- sector.LowPart += TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR;
-
- // The backup medium may be a floppy-emulated bootable CD. The emulation may fail if LBA addressing is used.
- // Therefore, only CHS addressing can be used.
- LbaToChs (bootLoaderDriveGeometry, sector, chs);
- sector.LowPart = i;
-
- if (i == TC_MBR_SECTOR)
- {
- // Read current partition table
- result = ReadSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1);
- if (result != BiosResultSuccess)
- goto err;
-
- memcpy (mbrPartTable, SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbrPartTable));
- }
-
- result = ReadSectors (SectorBuffer, BootLoaderDrive, chs, 1);
- if (result != BiosResultSuccess)
- goto err;
-
- if (i == TC_MBR_SECTOR)
- {
- // Preserve current partition table
- memcpy (SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, mbrPartTable, sizeof (mbrPartTable));
- }
-
- // Volume header
- if (i == TC_BOOT_VOLUME_HEADER_SECTOR)
- {
- if (selection == RestoreTrueCryptLoader)
- continue;
-
- if (selection == RestoreVolumeHeader)
- {
- while (true)
- {
- bool validHeaderPresent = false;
- uint32 masterKeyScheduleCrc;
-
- Password password;
- int pim;
- byte exitKey = AskPassword (password, pim);
-
- if (exitKey != TC_BIOS_KEY_ENTER)
- goto abort;
-
- CRYPTO_INFO *cryptoInfo;
-
- CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, TC_LB_SIZE);
- ReleaseSectorBuffer();
-
- // Restore volume header only if the current one cannot be used
- if (OpenVolume (TC_FIRST_BIOS_DRIVE, password, pim, &cryptoInfo, nullptr, false, true))
- {
- validHeaderPresent = true;
- masterKeyScheduleCrc = GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks));
- crypto_close (cryptoInfo);
- }
-
- AcquireSectorBuffer();
- CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, 0, SectorBuffer, TC_LB_SIZE);
-
- if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &password, pim, &cryptoInfo, nullptr) == 0)
- {
- if (validHeaderPresent)
- {
- if (masterKeyScheduleCrc == GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks)))
- {
- Print ("Original header preserved.\r\n");
- goto err;
- }
-
- Print ("WARNING: Drive 0 contains a valid header!\r\n");
- }
-
- crypto_close (cryptoInfo);
- break;
- }
-
- Print ("Incorrect password.\r\n\r\n");
- }
- }
- }
-
- if (!writeConfirmed && !AskYesNo ("Modify drive 0"))
- goto abort;
- writeConfirmed = true;
-
- if (WriteSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1) != BiosResultSuccess)
- goto err;
- }
-done:
- switch (selection)
- {
- case RestoreTrueCryptLoader:
- Print ("VeraCrypt Boot Loader");
- break;
-
- case RestoreVolumeHeader:
- Print ("Header");
- break;
-
- case RestoreOriginalSystemLoader:
- Print ("System loader");
- break;
- }
- Print (" restored.\r\n");
-
-err: GetKeyboardChar();
-abort: ReleaseSectorBuffer();
- }
-}
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-
-#ifndef DEBUG
-extern "C" void _acrtused () { } // Required by linker
-#endif
-
-
-void main ()
-{
- __asm mov BootLoaderDrive, dl
- __asm mov BootSectorFlags, dh
-
-#ifdef TC_BOOT_TRACING_ENABLED
- InitDebugPort();
-#endif
-
-#ifdef TC_BOOT_STACK_CHECKING_ENABLED
- InitStackChecker();
-#endif
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- ReadBootSectorUserConfiguration();
-#elif defined (TC_WINDOWS_BOOT_AES)
- EnableHwEncryption (!(BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION));
-#endif
-
- InitVideoMode();
- InitScreen();
-
- // Determine boot drive
- BootDrive = BootLoaderDrive;
- if (BootDrive < TC_FIRST_BIOS_DRIVE)
- BootDrive = TC_FIRST_BIOS_DRIVE;
-
- // Query boot drive geometry
- if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
- {
- BootDrive = TC_FIRST_BIOS_DRIVE;
- if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
- {
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
- Print ("- Connect system drive to (SATA) port 1\r\n");
-#endif
- GetKeyboardChar();
- }
- else
- BootDriveGeometryValid = true;
- }
- else
- BootDriveGeometryValid = true;
-
-#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- // Check whether the user is not using the Rescue Disk to create a hidden system
-
- if (ReadWriteMBR (false, BootDrive, true) == BiosResultSuccess
- && *(uint32 *) (SectorBuffer + 6) == 0x61726556
- && *(uint32 *) (SectorBuffer + 10) == 0x70797243
- && (SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE)
- {
- PrintError ("It appears you are creating a hidden OS.");
- if (AskYesNo ("Is this correct"))
- {
- Print ("Please remove the Rescue Disk from the drive and restart.");
- while (true);
- }
- }
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-
- // Main menu
-
- while (true)
- {
- byte exitKey;
- InitScreen();
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- // Hidden system setup
- byte hiddenSystemCreationPhase = BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
-
- if (hiddenSystemCreationPhase != TC_HIDDEN_OS_CREATION_PHASE_NONE)
- {
- PreventNormalSystemBoot = true;
- PrintMainMenu();
-
- if (hiddenSystemCreationPhase == TC_HIDDEN_OS_CREATION_PHASE_CLONING)
- {
- if (CopySystemPartitionToHiddenVolume (BootDrive, exitKey))
- {
- BootSectorFlags = (BootSectorFlags & ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) | TC_HIDDEN_OS_CREATION_PHASE_WIPING;
- UpdateBootSectorConfiguration (BootLoaderDrive);
- }
- else if (exitKey == TC_BIOS_KEY_ESC)
- goto bootMenu;
- else
- continue;
- }
- }
- else
- PrintMainMenu();
-
- exitKey = BootEncryptedDrive();
-
-#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- PrintMainMenu();
- exitKey = BootEncryptedDrive();
-
- if (exitKey == TC_MENU_KEY_REPAIR)
- {
- RepairMenu();
- continue;
- }
-
-#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
-bootMenu:
- if (!PreventBootMenu)
- BootMenu();
- }
-}
+/*
+ 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-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 "Crc.h"
+#include "Crypto.h"
+#include "Password.h"
+#include "Volumes.h"
+
+#include "Platform.h"
+#include "Bios.h"
+#include "BootConfig.h"
+#include "BootMain.h"
+#include "BootDefs.h"
+#include "BootCommon.h"
+#include "BootConsoleIo.h"
+#include "BootDebug.h"
+#include "BootDiskIo.h"
+#include "BootEncryptedIo.h"
+#include "BootMemory.h"
+#include "BootStrings.h"
+#include "IntFilter.h"
+
+
+static void InitScreen ()
+{
+ ClearScreen();
+
+ const char *title =
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ " VeraCrypt Boot Loader "
+#else
+ " VeraCrypt Rescue Disk "
+#endif
+ VERSION_STRING "\r\n";
+
+ Print (title);
+
+ PrintRepeatedChar ('\xDC', TC_BIOS_MAX_CHARS_PER_LINE);
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ if (CustomUserMessage[0])
+ {
+ PrintEndl();
+ Print (CustomUserMessage);
+ }
+#endif
+
+ PrintEndl (2);
+}
+
+
+static void PrintMainMenu ()
+{
+ if (PreventBootMenu)
+ return;
+
+ Print (" Keyboard Controls:\r\n");
+ Print (" [F5] Hide/Show Password and PIM\r\n");
+ Print (" [Esc] ");
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ Print ((BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE
+ ? "Boot Non-Hidden System (Boot Manager)"
+ : "Skip Authentication (Boot Manager)");
+
+#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ Print ("Skip Authentication (Boot Manager)");
+ Print ("\r\n [F8] "); Print ("Repair Options");
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ PrintEndl (3);
+}
+
+
+static bool IsMenuKey (byte scanCode)
+{
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ return scanCode == TC_MENU_KEY_REPAIR;
+#else
+ return false;
+#endif
+}
+
+
+static bool AskYesNo (const char *message)
+{
+ Print (message);
+ Print ("? (y/n): ");
+ while (true)
+ {
+ switch (GetKeyboardChar())
+ {
+ case 'y':
+ case 'Y':
+ case 'z':
+ case 'Z':
+ Print ("y\r\n");
+ return true;
+
+ case 'n':
+ case 'N':
+ Print ("n\r\n");
+ return false;
+
+ default:
+ Beep();
+ }
+ }
+}
+
+
+static int AskSelection (const char *options[], size_t optionCount)
+{
+ for (int i = 0; i < optionCount; ++i)
+ {
+ Print ("["); Print (i + 1); Print ("] ");
+ Print (options[i]);
+ PrintEndl();
+ }
+ Print ("[Esc] Cancel\r\n\r\n");
+
+ Print ("To select, press 1-9: ");
+
+ char str;
+
+ while (true)
+ {
+ if (GetString (&str, 1) == 0)
+ return 0;
+
+ if (str >= '1' && str <= optionCount + '0')
+ return str - '0';
+
+ Beep();
+ PrintBackspace();
+ }
+}
+
+
+static byte AskPassword (Password &password, int& pim)
+{
+ size_t pos = 0;
+ byte scanCode;
+ byte asciiCode;
+ byte hidePassword = 1;
+
+ pim = 0;
+
+ Print ("Enter password");
+ Print (PreventNormalSystemBoot ? " for hidden system:\r\n" : ": ");
+
+ while (true)
+ {
+ asciiCode = GetKeyboardChar (&scanCode);
+
+ switch (scanCode)
+ {
+ case TC_BIOS_KEY_ENTER:
+ password.Length = pos;
+ Print ("\r");
+ if (!PreventNormalSystemBoot)
+ Print ("Enter password: ");
+ pos = 0;
+ while (pos < MAX_PASSWORD)
+ {
+ pos++;
+ if (pos < MAX_PASSWORD)
+ PrintChar ('*');
+ else
+ PrintCharAtCursor ('*');
+ }
+
+ ClearBiosKeystrokeBuffer();
+ PrintEndl();
+
+ break;
+
+ case TC_BIOS_KEY_BACKSPACE:
+ if (pos > 0)
+ {
+ if (pos < MAX_PASSWORD)
+ PrintBackspace();
+ else
+ PrintCharAtCursor (' ');
+
+ --pos;
+ }
+ continue;
+
+ case TC_BIOS_KEY_F5:
+ hidePassword ^= 0x01;
+ continue;
+
+ default:
+ if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
+ {
+ burn (password.Text, sizeof (password.Text));
+ ClearBiosKeystrokeBuffer();
+
+ PrintEndl();
+ return scanCode;
+ }
+ }
+
+ if (TC_BIOS_KEY_ENTER == scanCode)
+ break;
+
+ if (!IsPrintable (asciiCode) || pos == MAX_PASSWORD)
+ {
+ Beep();
+ continue;
+ }
+
+ password.Text[pos++] = asciiCode;
+ if (hidePassword) asciiCode = '*';
+ if (pos < MAX_PASSWORD)
+ PrintChar (asciiCode);
+ else
+ PrintCharAtCursor (asciiCode);
+ }
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ if (PimValueOrHiddenVolumeStartUnitNo.LowPart != -1)
+ {
+ pim = (int) PimValueOrHiddenVolumeStartUnitNo.LowPart;
+ // reset stored PIM value to allow requesting PIM next time in case the stored value is wrong
+ PimValueOrHiddenVolumeStartUnitNo.LowPart = -1;
+ return TC_BIOS_KEY_ENTER;
+ }
+ else
+#endif
+ {
+ pos = 0;
+ Print ("PIM: ");
+
+ while (true)
+ {
+ asciiCode = GetKeyboardChar (&scanCode);
+
+ switch (scanCode)
+ {
+ case TC_BIOS_KEY_ENTER:
+ Print ("\rPIM: ");
+ pos =0;
+ while (pos < MAX_PIM)
+ {
+ PrintChar ('*');
+ pos++;
+ }
+
+ ClearBiosKeystrokeBuffer();
+ PrintEndl();
+
+ return TC_BIOS_KEY_ENTER;
+
+ case TC_BIOS_KEY_BACKSPACE:
+ if (pos > 0)
+ {
+ if (pos < MAX_PIM)
+ PrintBackspace();
+ else
+ PrintCharAtCursor (' ');
+
+ --pos;
+ pim /= 10;
+ }
+ continue;
+
+ case TC_BIOS_KEY_F5:
+ hidePassword ^= 0x01;
+ continue;
+
+ default:
+ if (scanCode == TC_BIOS_KEY_ESC || IsMenuKey (scanCode))
+ {
+ burn (password.Text, sizeof (password.Text));
+ ClearBiosKeystrokeBuffer();
+
+ PrintEndl();
+ return scanCode;
+ }
+ }
+
+ if (!IsDigit (asciiCode) || pos == MAX_PIM)
+ {
+ Beep();
+ continue;
+ }
+
+ pim = 10*pim + (asciiCode - '0');
+ pos++;
+
+ if (hidePassword) asciiCode = '*';
+ if (pos < MAX_PIM)
+ PrintChar (asciiCode);
+ else
+ PrintCharAtCursor (asciiCode);
+ }
+ }
+}
+
+
+static void ExecuteBootSector (byte drive, byte *sectorBuffer)
+{
+ Print ("Booting...\r\n");
+ CopyMemory (sectorBuffer, 0x0000, 0x7c00, TC_LB_SIZE);
+
+ BootStarted = true;
+
+ uint32 addr = 0x7c00;
+ __asm
+ {
+ cli
+ mov dl, drive // Boot drive
+ mov dh, 0
+ xor ax, ax
+ mov si, ax
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov sp, 0x7c00
+ sti
+
+ jmp cs:addr
+ }
+}
+
+
+static bool OpenVolume (byte drive, Password &password, int pim, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden)
+{
+ int volumeType;
+ bool hiddenVolume;
+ uint64 headerSec;
+
+ AcquireSectorBuffer();
+
+ for (volumeType = 1; volumeType <= 2; ++volumeType)
+ {
+ hiddenVolume = (volumeType == 2);
+
+ if (hiddenVolume)
+ {
+ if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount)
+ continue;
+
+ headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE;
+ }
+ else
+ {
+ if (skipNormal)
+ continue;
+
+ headerSec.HighPart = 0;
+ headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
+ }
+
+ if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess)
+ continue;
+
+ if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, pim, cryptoInfo, nullptr) == ERR_SUCCESS)
+ {
+ // Prevent opening a non-system hidden volume
+ if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM))
+ {
+ crypto_close (*cryptoInfo);
+ continue;
+ }
+
+ if (headerSaltCrc32)
+ *headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE);
+
+ break;
+ }
+ }
+
+ ReleaseSectorBuffer();
+ return volumeType != 3;
+}
+
+
+static bool CheckMemoryRequirements ()
+{
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+ if (codeSeg == TC_BOOT_LOADER_LOWMEM_SEGMENT)
+ {
+ PrintErrorNoEndl ("BIOS reserved too much memory: ");
+
+ uint16 memFree;
+ __asm
+ {
+ push es
+ xor ax, ax
+ mov es, ax
+ mov ax, es:[0x413]
+ mov memFree, ax
+ pop es
+ }
+
+ Print (memFree);
+ PrintEndl();
+ Print (TC_BOOT_STR_UPGRADE_BIOS);
+
+ return false;
+ }
+
+ return true;
+}
+
+
+static bool MountVolume (byte drive, byte &exitKey, bool skipNormal, bool skipHidden)
+{
+ BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
+ int incorrectPasswordCount = 0, pim = 0;
+
+ EraseMemory (bootArguments, sizeof (*bootArguments));
+
+ // Open volume header
+ while (true)
+ {
+ exitKey = AskPassword (bootArguments->BootPassword, pim);
+
+ if (exitKey != TC_BIOS_KEY_ENTER)
+ return false;
+
+ Print ("Verifying password...");
+
+ if (OpenVolume (BootDrive, bootArguments->BootPassword, pim, &BootCryptoInfo, &bootArguments->HeaderSaltCrc32, skipNormal, skipHidden))
+ {
+ Print ("OK\r\n");
+ break;
+ }
+ if (GetShiftFlags() & TC_BIOS_SHIFTMASK_CAPSLOCK)
+ Print ("Warning: Caps Lock is on.\r\n");
+
+ Print ("Incorrect password.\r\n\r\n");
+
+ if (++incorrectPasswordCount == 4)
+ {
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ Print ("If you are sure the password is correct, the key data may be damaged.\r\n"
+ "If so, use 'Repair Options' > 'Restore key data'.\r\n\r\n");
+#else
+ Print ("If you are sure the password is correct, the key data may be damaged. Boot your\r\n"
+ "VeraCrypt Rescue Disk and select 'Repair Options' > 'Restore key data'.\r\n\r\n");
+#endif
+ }
+ }
+
+ // Setup boot arguments
+ bootArguments->BootLoaderVersion = VERSION_NUM;
+ bootArguments->CryptoInfoOffset = (uint16) BootCryptoInfo;
+ bootArguments->CryptoInfoLength = sizeof (*BootCryptoInfo);
+ bootArguments->Flags = (((uint32)pim) << 16);
+
+ if (BootCryptoInfo->hiddenVolume)
+ bootArguments->HiddenSystemPartitionStart = PartitionFollowingActive.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ if (ExtraBootPartitionPresent)
+ bootArguments->Flags |= TC_BOOT_ARGS_FLAG_EXTRA_BOOT_PARTITION;
+
+ TC_SET_BOOT_ARGUMENTS_SIGNATURE (bootArguments->Signature);
+
+ // Setup virtual encrypted partition
+ if (BootCryptoInfo->EncryptedAreaLength.HighPart != 0 || BootCryptoInfo->EncryptedAreaLength.LowPart != 0)
+ {
+ EncryptedVirtualPartition.Drive = BootDrive;
+
+ EncryptedVirtualPartition.StartSector = BootCryptoInfo->EncryptedAreaStart >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ PimValueOrHiddenVolumeStartUnitNo = EncryptedVirtualPartition.StartSector;
+ HiddenVolumeStartSector = PartitionFollowingActive.StartSector;
+ HiddenVolumeStartSector += EncryptedVirtualPartition.StartSector;
+
+ EncryptedVirtualPartition.SectorCount = BootCryptoInfo->EncryptedAreaLength >> TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ EncryptedVirtualPartition.EndSector = EncryptedVirtualPartition.SectorCount - 1;
+ EncryptedVirtualPartition.EndSector += EncryptedVirtualPartition.StartSector;
+ }
+ else
+ {
+ // Drive not encrypted
+ EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
+ }
+
+ return true;
+}
+
+
+static bool GetSystemPartitions (byte drive)
+{
+ size_t partCount;
+
+ if (!GetActivePartition (drive))
+ return false;
+
+ // Find partition following the active one
+ GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
+
+ // If there is an extra boot partition, use the partitions following it.
+ // The real boot partition is determined in BootEncryptedDrive().
+ if (ActivePartition.SectorCount.HighPart == 0 && ActivePartition.SectorCount.LowPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE / TC_LB_SIZE
+ && PartitionFollowingActive.Drive != TC_INVALID_BIOS_DRIVE)
+ {
+ ExtraBootPartitionPresent = true;
+
+ ActivePartition = PartitionFollowingActive;
+ GetDrivePartitions (drive, &PartitionFollowingActive, 1, partCount, false, &ActivePartition);
+ }
+
+ return true;
+}
+
+
+static byte BootEncryptedDrive ()
+{
+ BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
+ byte exitKey;
+ BootCryptoInfo = NULL;
+
+ if (!GetSystemPartitions (BootDrive))
+ goto err;
+
+ if (!MountVolume (BootDrive, exitKey, PreventNormalSystemBoot, false))
+ return exitKey;
+
+ if (!CheckMemoryRequirements ())
+ goto err;
+
+ if (BootCryptoInfo->hiddenVolume)
+ {
+ EncryptedVirtualPartition = ActivePartition;
+ bootArguments->DecoySystemPartitionStart = ActivePartition.StartSector << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+ }
+
+ if (ExtraBootPartitionPresent && !GetActivePartition (BootDrive))
+ goto err;
+
+ if (ReadWriteMBR (false, ActivePartition.Drive) != BiosResultSuccess)
+ goto err;
+
+ bootArguments->BootDriveSignature = *(uint32 *) (SectorBuffer + 0x1b8);
+
+ if (!InstallInterruptFilters())
+ goto err;
+
+ bootArguments->BootArgumentsCrc32 = GetCrc32 ((byte *) bootArguments, (byte *) &bootArguments->BootArgumentsCrc32 - (byte *) bootArguments);
+
+ while (true)
+ {
+ // Execute boot sector of the active partition
+ if (ReadSectors (SectorBuffer, ActivePartition.Drive, ActivePartition.StartSector, 1) == BiosResultSuccess)
+ {
+ if (*(uint16 *) (SectorBuffer + 510) != 0xaa55)
+ {
+ PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
+ GetKeyboardChar();
+ }
+
+ ExecuteBootSector (ActivePartition.Drive, SectorBuffer);
+ }
+
+ GetKeyboardChar();
+ }
+
+err:
+ if (BootCryptoInfo)
+ {
+ crypto_close (BootCryptoInfo);
+ BootCryptoInfo = NULL;
+ }
+
+ EncryptedVirtualPartition.Drive = TC_INVALID_BIOS_DRIVE;
+ EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
+
+ byte scanCode;
+ GetKeyboardChar (&scanCode);
+ return scanCode;
+}
+
+
+static void BootMenu ()
+{
+ BiosResult result;
+ Partition partitions[16];
+ Partition bootablePartitions[9];
+ size_t partitionCount;
+ size_t bootablePartitionCount = 0;
+
+ for (byte drive = TC_FIRST_BIOS_DRIVE; drive <= TC_LAST_BIOS_DRIVE; ++drive)
+ {
+ if (GetDrivePartitions (drive, partitions, array_capacity (partitions), partitionCount, false, nullptr, true) == BiosResultSuccess)
+ {
+ for (size_t i = 0; i < partitionCount; ++i)
+ {
+ const Partition &partition = partitions[i];
+ result = ReadSectors (SectorBuffer, drive, partition.StartSector, 1);
+
+ if (result == BiosResultSuccess && *(uint16 *) (SectorBuffer + TC_LB_SIZE - 2) == 0xaa55)
+ {
+ // Windows writes boot loader on all NTFS/FAT filesytems it creates and, therefore,
+ // NTFS/FAT partitions must have the boot indicator set to be considered bootable.
+ if (!partition.Active
+ && (*(uint32 *) (SectorBuffer + 3) == 0x5346544e // 'NTFS'
+ || *(uint32 *) (SectorBuffer + 3) == 0x41465845 && SectorBuffer[7] == 'T' // 'exFAT'
+ || *(uint16 *) (SectorBuffer + 54) == 0x4146 && SectorBuffer[56] == 'T' // 'FAT'
+ || *(uint16 *) (SectorBuffer + 82) == 0x4146 && SectorBuffer[84] == 'T'))
+ {
+ continue;
+ }
+
+ // Bootable sector found
+ if (bootablePartitionCount < array_capacity (bootablePartitions))
+ bootablePartitions[bootablePartitionCount++] = partition;
+ }
+ }
+ }
+ }
+
+ if (bootablePartitionCount < 1)
+ {
+ PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
+ GetKeyboardChar();
+ return;
+ }
+
+ char partChar;
+ while (true)
+ {
+ InitScreen();
+ Print ("Bootable Partitions:\r\n");
+ PrintRepeatedChar ('\xC4', 20);
+ Print ("\r\n");
+
+ for (size_t i = 0; i < bootablePartitionCount; ++i)
+ {
+ const Partition &partition = bootablePartitions[i];
+ Print ("["); Print (i + 1); Print ("] ");
+ Print ("Drive: "); Print (partition.Drive - TC_FIRST_BIOS_DRIVE);
+ Print (", Partition: "); Print (partition.Number + 1);
+ Print (", Size: "); PrintSectorCountInMB (partition.SectorCount); PrintEndl();
+ }
+
+ if (bootablePartitionCount == 1)
+ {
+ // There's only one bootable partition so we'll boot it directly instead of showing boot manager
+ partChar = '1';
+ }
+ else
+ {
+ Print ("[Esc] Cancel\r\n\r\n");
+ Print ("Press 1-9 to select partition: ");
+
+ if (GetString (&partChar, 1) == 0)
+ return;
+
+ PrintEndl();
+
+ if (partChar < '1' || partChar > '0' + bootablePartitionCount)
+ {
+ Beep();
+ continue;
+ }
+ }
+
+ const Partition &partition = bootablePartitions[partChar - '0' - 1];
+
+ if (ReadSectors (SectorBuffer, partition.Drive, partition.StartSector, 1) == BiosResultSuccess)
+ {
+ ExecuteBootSector (partition.Drive, SectorBuffer);
+ }
+ }
+}
+
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+static bool CopySystemPartitionToHiddenVolume (byte drive, byte &exitKey)
+{
+ bool status = false;
+
+ uint64 sectorsRemaining;
+ uint64 sectorOffset;
+ sectorOffset.LowPart = 0;
+ sectorOffset.HighPart = 0;
+
+ int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
+ int statCount = 0;
+
+ if (!CheckMemoryRequirements ())
+ goto err;
+
+ if (!GetSystemPartitions (drive))
+ goto err;
+
+ if (PartitionFollowingActive.Drive == TC_INVALID_BIOS_DRIVE)
+ TC_THROW_FATAL_EXCEPTION;
+
+ // Check if BIOS can read the last sector of the hidden system
+ AcquireSectorBuffer();
+
+ if (ReadSectors (SectorBuffer, PartitionFollowingActive.Drive, PartitionFollowingActive.EndSector - (TC_VOLUME_HEADER_GROUP_SIZE / TC_LB_SIZE - 2), 1) != BiosResultSuccess
+ || GetCrc32 (SectorBuffer, sizeof (SectorBuffer)) != OuterVolumeBackupHeaderCrc)
+ {
+ PrintErrorNoEndl ("Your BIOS does not support large drives");
+ Print (IsLbaSupported (PartitionFollowingActive.Drive) ? " due to a bug" : "\r\n- Enable LBA in BIOS");
+ PrintEndl();
+ Print (TC_BOOT_STR_UPGRADE_BIOS);
+
+ ReleaseSectorBuffer();
+ goto err;
+ }
+
+ ReleaseSectorBuffer();
+
+ if (!MountVolume (drive, exitKey, true, false))
+ return false;
+
+ sectorsRemaining = EncryptedVirtualPartition.SectorCount;
+
+ if (!(sectorsRemaining == ActivePartition.SectorCount))
+ TC_THROW_FATAL_EXCEPTION;
+
+ InitScreen();
+ Print ("\r\nCopying system to hidden volume. To abort, press Esc.\r\n\r\n");
+
+ while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
+ {
+ if (EscKeyPressed())
+ {
+ Print ("\rIf aborted, copying will have to start from the beginning (if attempted again).\r\n");
+ if (AskYesNo ("Abort"))
+ break;
+ }
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
+ fragmentSectorCount = (int) sectorsRemaining.LowPart;
+
+ if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, ActivePartition.StartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
+ {
+ Print ("To fix bad sectors: 1) Terminate 2) Encrypt and decrypt sys partition 3) Retry\r\n");
+ crypto_close (BootCryptoInfo);
+ goto err;
+ }
+
+ AcquireSectorBuffer();
+
+ for (int i = 0; i < fragmentSectorCount; ++i)
+ {
+ CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
+
+ uint64 s = PimValueOrHiddenVolumeStartUnitNo + sectorOffset + i;
+ EncryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
+
+ CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
+ }
+
+ ReleaseSectorBuffer();
+
+ if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, HiddenVolumeStartSector + sectorOffset, fragmentSectorCount, false) != BiosResultSuccess)
+ {
+ crypto_close (BootCryptoInfo);
+ goto err;
+ }
+
+ sectorsRemaining = sectorsRemaining - fragmentSectorCount;
+ sectorOffset = sectorOffset + fragmentSectorCount;
+
+ if (!(statCount++ & 0xf))
+ {
+ Print ("\rRemaining: ");
+ PrintSectorCountInMB (sectorsRemaining);
+ }
+ }
+
+ crypto_close (BootCryptoInfo);
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
+ {
+ status = true;
+ Print ("\rCopying completed.");
+ }
+
+ PrintEndl (2);
+ goto ret;
+
+err:
+ exitKey = TC_BIOS_KEY_ESC;
+ GetKeyboardChar();
+
+ret:
+ EraseMemory ((void *) TC_BOOT_LOADER_ARGS_OFFSET, sizeof (BootArguments));
+ return status;
+}
+
+
+#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+
+static void DecryptDrive (byte drive)
+{
+ byte exitKey;
+ if (!MountVolume (drive, exitKey, false, true))
+ return;
+
+ BootArguments *bootArguments = (BootArguments *) TC_BOOT_LOADER_ARGS_OFFSET;
+
+ bool headerUpdateRequired = false;
+ uint64 sectorsRemaining = EncryptedVirtualPartition.EndSector + 1 - EncryptedVirtualPartition.StartSector;
+ uint64 sector = EncryptedVirtualPartition.EndSector + 1;
+
+ int fragmentSectorCount = 0x7f; // Maximum safe value supported by BIOS
+ int statCount = 0;
+
+ bool skipBadSectors = false;
+
+ Print ("\r\nUse only if Windows cannot start. Decryption under Windows is much faster\r\n"
+ "(in VeraCrypt, select 'System' > 'Permanently Decrypt').\r\n\r\n");
+
+ if (!AskYesNo ("Decrypt now"))
+ {
+ crypto_close (BootCryptoInfo);
+ goto ret;
+ }
+
+ if (EncryptedVirtualPartition.Drive == TC_INVALID_BIOS_DRIVE)
+ {
+ // Drive already decrypted
+ sectorsRemaining.HighPart = 0;
+ sectorsRemaining.LowPart = 0;
+ }
+ else
+ {
+ Print ("\r\nTo safely interrupt and defer decryption, press Esc.\r\n"
+ "WARNING: You can turn off power only after you press Esc.\r\n\r\n");
+ }
+
+ while (sectorsRemaining.HighPart != 0 || sectorsRemaining.LowPart != 0)
+ {
+ if (EscKeyPressed())
+ break;
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart < fragmentSectorCount)
+ fragmentSectorCount = (int) sectorsRemaining.LowPart;
+
+ sector = sector - fragmentSectorCount;
+
+ if (!(statCount++ & 0xf))
+ {
+ Print ("\rRemaining: ");
+ PrintSectorCountInMB (sectorsRemaining);
+ }
+
+ if (ReadWriteSectors (false, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) == BiosResultSuccess)
+ {
+ AcquireSectorBuffer();
+
+ for (int i = 0; i < fragmentSectorCount; ++i)
+ {
+ CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, SectorBuffer, TC_LB_SIZE);
+
+ uint64 s = sector + i;
+ DecryptDataUnits (SectorBuffer, &s, 1, BootCryptoInfo);
+
+ CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, i * TC_LB_SIZE, TC_LB_SIZE);
+ }
+
+ ReleaseSectorBuffer();
+
+ if (ReadWriteSectors (true, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, drive, sector, fragmentSectorCount, skipBadSectors) != BiosResultSuccess && !skipBadSectors)
+ goto askBadSectorSkip;
+ }
+ else if (!skipBadSectors)
+ goto askBadSectorSkip;
+
+ sectorsRemaining = sectorsRemaining - fragmentSectorCount;
+ headerUpdateRequired = true;
+ continue;
+
+askBadSectorSkip:
+ if (!AskYesNo ("Skip all bad sectors"))
+ break;
+
+ skipBadSectors = true;
+ sector = sector + fragmentSectorCount;
+ fragmentSectorCount = 1;
+ }
+
+ crypto_close (BootCryptoInfo);
+
+ if (headerUpdateRequired)
+ {
+ Print ("\rUpdating header...");
+
+ AcquireSectorBuffer();
+ uint64 headerSector;
+ headerSector.HighPart = 0;
+ headerSector.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR;
+
+ // Update encrypted area size in volume header
+
+ CRYPTO_INFO *headerCryptoInfo = crypto_open();
+ while (ReadSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
+
+ if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &bootArguments->BootPassword, (int) (bootArguments->Flags >> 16), NULL, headerCryptoInfo) == 0)
+ {
+ DecryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
+
+ uint64 encryptedAreaLength = sectorsRemaining << TC_LB_SIZE_BIT_SHIFT_DIVISOR;
+
+ for (int i = 7; i >= 0; --i)
+ {
+ SectorBuffer[TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH + i] = (byte) encryptedAreaLength.LowPart;
+ encryptedAreaLength = encryptedAreaLength >> 8;
+ }
+
+ uint32 headerCrc32 = GetCrc32 (SectorBuffer + TC_HEADER_OFFSET_MAGIC, TC_HEADER_OFFSET_HEADER_CRC - TC_HEADER_OFFSET_MAGIC);
+
+ for (i = 3; i >= 0; --i)
+ {
+ SectorBuffer[TC_HEADER_OFFSET_HEADER_CRC + i] = (byte) headerCrc32;
+ headerCrc32 >>= 8;
+ }
+
+ EncryptBuffer (SectorBuffer + HEADER_ENCRYPTED_DATA_OFFSET, HEADER_ENCRYPTED_DATA_SIZE, headerCryptoInfo);
+ }
+
+ crypto_close (headerCryptoInfo);
+
+ while (WriteSectors (SectorBuffer, drive, headerSector, 1) != BiosResultSuccess);
+ ReleaseSectorBuffer();
+
+ Print ("Done!\r\n");
+ }
+
+ if (sectorsRemaining.HighPart == 0 && sectorsRemaining.LowPart == 0)
+ Print ("\rDrive decrypted.\r\n");
+ else
+ Print ("\r\nDecryption deferred.\r\n");
+
+ GetKeyboardChar();
+ret:
+ EraseMemory (bootArguments, sizeof (*bootArguments));
+}
+
+
+static void RepairMenu ()
+{
+ DriveGeometry bootLoaderDriveGeometry;
+
+ if (GetDriveGeometry (BootLoaderDrive, bootLoaderDriveGeometry, true) != BiosResultSuccess)
+ {
+ // Some BIOSes may fail to get the geometry of an emulated floppy drive
+ bootLoaderDriveGeometry.Cylinders = 80;
+ bootLoaderDriveGeometry.Heads = 2;
+ bootLoaderDriveGeometry.Sectors = 18;
+ }
+
+ while (true)
+ {
+ InitScreen();
+ Print ("Available "); Print ("Repair Options"); Print (":\r\n");
+ PrintRepeatedChar ('\xC4', 25);
+ PrintEndl();
+
+ enum
+ {
+ RestoreNone = 0,
+ DecryptVolume,
+ RestoreTrueCryptLoader,
+ RestoreVolumeHeader,
+ RestoreOriginalSystemLoader
+ };
+
+ static const char *options[] = { "Permanently decrypt system partition/drive", "Restore VeraCrypt Boot Loader", "Restore key data (volume header)", "Restore original system loader" };
+
+ int selection = AskSelection (options,
+ (BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER) ? array_capacity (options) : array_capacity (options) - 1);
+
+ PrintEndl();
+
+ switch (selection)
+ {
+ case RestoreNone:
+ return;
+
+ case DecryptVolume:
+ DecryptDrive (BootDrive);
+ continue;
+
+ case RestoreOriginalSystemLoader:
+ if (!AskYesNo ("Is the system partition/drive decrypted"))
+ {
+ Print ("Please decrypt it first.\r\n");
+ GetKeyboardChar();
+ continue;
+ }
+ break;
+ }
+
+ bool writeConfirmed = false;
+ BiosResult result;
+
+ uint64 sector;
+ sector.HighPart = 0;
+ ChsAddress chs;
+
+ byte mbrPartTable[TC_LB_SIZE - TC_MAX_MBR_BOOT_CODE_SIZE];
+ AcquireSectorBuffer();
+
+ for (int i = (selection == RestoreVolumeHeader ? TC_BOOT_VOLUME_HEADER_SECTOR : TC_MBR_SECTOR);
+ i < TC_BOOT_LOADER_AREA_SECTOR_COUNT; ++i)
+ {
+ sector.LowPart = i;
+
+ if (selection == RestoreOriginalSystemLoader)
+ sector.LowPart += TC_ORIG_BOOT_LOADER_BACKUP_SECTOR;
+ else if (selection == RestoreTrueCryptLoader)
+ sector.LowPart += TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR;
+
+ // The backup medium may be a floppy-emulated bootable CD. The emulation may fail if LBA addressing is used.
+ // Therefore, only CHS addressing can be used.
+ LbaToChs (bootLoaderDriveGeometry, sector, chs);
+ sector.LowPart = i;
+
+ if (i == TC_MBR_SECTOR)
+ {
+ // Read current partition table
+ result = ReadSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1);
+ if (result != BiosResultSuccess)
+ goto err;
+
+ memcpy (mbrPartTable, SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbrPartTable));
+ }
+
+ result = ReadSectors (SectorBuffer, BootLoaderDrive, chs, 1);
+ if (result != BiosResultSuccess)
+ goto err;
+
+ if (i == TC_MBR_SECTOR)
+ {
+ // Preserve current partition table
+ memcpy (SectorBuffer + TC_MAX_MBR_BOOT_CODE_SIZE, mbrPartTable, sizeof (mbrPartTable));
+ }
+
+ // Volume header
+ if (i == TC_BOOT_VOLUME_HEADER_SECTOR)
+ {
+ if (selection == RestoreTrueCryptLoader)
+ continue;
+
+ if (selection == RestoreVolumeHeader)
+ {
+ while (true)
+ {
+ bool validHeaderPresent = false;
+ uint32 masterKeyScheduleCrc;
+
+ Password password;
+ int pim;
+ byte exitKey = AskPassword (password, pim);
+
+ if (exitKey != TC_BIOS_KEY_ENTER)
+ goto abort;
+
+ CRYPTO_INFO *cryptoInfo;
+
+ CopyMemory (SectorBuffer, TC_BOOT_LOADER_BUFFER_SEGMENT, 0, TC_LB_SIZE);
+ ReleaseSectorBuffer();
+
+ // Restore volume header only if the current one cannot be used
+ if (OpenVolume (TC_FIRST_BIOS_DRIVE, password, pim, &cryptoInfo, nullptr, false, true))
+ {
+ validHeaderPresent = true;
+ masterKeyScheduleCrc = GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks));
+ crypto_close (cryptoInfo);
+ }
+
+ AcquireSectorBuffer();
+ CopyMemory (TC_BOOT_LOADER_BUFFER_SEGMENT, 0, SectorBuffer, TC_LB_SIZE);
+
+ if (ReadVolumeHeader (TRUE, (char *) SectorBuffer, &password, pim, &cryptoInfo, nullptr) == 0)
+ {
+ if (validHeaderPresent)
+ {
+ if (masterKeyScheduleCrc == GetCrc32 (cryptoInfo->ks, sizeof (cryptoInfo->ks)))
+ {
+ Print ("Original header preserved.\r\n");
+ goto err;
+ }
+
+ Print ("WARNING: Drive 0 contains a valid header!\r\n");
+ }
+
+ crypto_close (cryptoInfo);
+ break;
+ }
+
+ Print ("Incorrect password.\r\n\r\n");
+ }
+ }
+ }
+
+ if (!writeConfirmed && !AskYesNo ("Modify drive 0"))
+ goto abort;
+ writeConfirmed = true;
+
+ if (WriteSectors (SectorBuffer, TC_FIRST_BIOS_DRIVE, sector, 1) != BiosResultSuccess)
+ goto err;
+ }
+done:
+ switch (selection)
+ {
+ case RestoreTrueCryptLoader:
+ Print ("VeraCrypt Boot Loader");
+ break;
+
+ case RestoreVolumeHeader:
+ Print ("Header");
+ break;
+
+ case RestoreOriginalSystemLoader:
+ Print ("System loader");
+ break;
+ }
+ Print (" restored.\r\n");
+
+err: GetKeyboardChar();
+abort: ReleaseSectorBuffer();
+ }
+}
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+
+#ifndef DEBUG
+extern "C" void _acrtused () { } // Required by linker
+#endif
+
+
+void main ()
+{
+ __asm mov BootLoaderDrive, dl
+ __asm mov BootSectorFlags, dh
+
+#ifdef TC_BOOT_TRACING_ENABLED
+ InitDebugPort();
+#endif
+
+#ifdef TC_BOOT_STACK_CHECKING_ENABLED
+ InitStackChecker();
+#endif
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ ReadBootSectorUserConfiguration();
+#elif defined (TC_WINDOWS_BOOT_AES)
+ EnableHwEncryption (!(BootSectorFlags & TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION));
+#endif
+
+ InitVideoMode();
+ InitScreen();
+
+ // Determine boot drive
+ BootDrive = BootLoaderDrive;
+ if (BootDrive < TC_FIRST_BIOS_DRIVE)
+ BootDrive = TC_FIRST_BIOS_DRIVE;
+
+ // Query boot drive geometry
+ if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
+ {
+ BootDrive = TC_FIRST_BIOS_DRIVE;
+ if (GetDriveGeometry (BootDrive, BootDriveGeometry) != BiosResultSuccess)
+ {
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+ Print ("- Connect system drive to (SATA) port 1\r\n");
+#endif
+ GetKeyboardChar();
+ }
+ else
+ BootDriveGeometryValid = true;
+ }
+ else
+ BootDriveGeometryValid = true;
+
+#ifdef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ // Check whether the user is not using the Rescue Disk to create a hidden system
+
+ if (ReadWriteMBR (false, BootDrive, true) == BiosResultSuccess
+ && *(uint32 *) (SectorBuffer + 6) == 0x61726556
+ && *(uint32 *) (SectorBuffer + 10) == 0x70797243
+ && (SectorBuffer[TC_BOOT_SECTOR_CONFIG_OFFSET] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) != TC_HIDDEN_OS_CREATION_PHASE_NONE)
+ {
+ PrintError ("It appears you are creating a hidden OS.");
+ if (AskYesNo ("Is this correct"))
+ {
+ Print ("Please remove the Rescue Disk from the drive and restart.");
+ while (true);
+ }
+ }
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+
+ // Main menu
+
+ while (true)
+ {
+ byte exitKey;
+ InitScreen();
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ // Hidden system setup
+ byte hiddenSystemCreationPhase = BootSectorFlags & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
+
+ if (hiddenSystemCreationPhase != TC_HIDDEN_OS_CREATION_PHASE_NONE)
+ {
+ PreventNormalSystemBoot = true;
+ PrintMainMenu();
+
+ if (hiddenSystemCreationPhase == TC_HIDDEN_OS_CREATION_PHASE_CLONING)
+ {
+ if (CopySystemPartitionToHiddenVolume (BootDrive, exitKey))
+ {
+ BootSectorFlags = (BootSectorFlags & ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE) | TC_HIDDEN_OS_CREATION_PHASE_WIPING;
+ UpdateBootSectorConfiguration (BootLoaderDrive);
+ }
+ else if (exitKey == TC_BIOS_KEY_ESC)
+ goto bootMenu;
+ else
+ continue;
+ }
+ }
+ else
+ PrintMainMenu();
+
+ exitKey = BootEncryptedDrive();
+
+#else // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ PrintMainMenu();
+ exitKey = BootEncryptedDrive();
+
+ if (exitKey == TC_MENU_KEY_REPAIR)
+ {
+ RepairMenu();
+ continue;
+ }
+
+#endif // TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+bootMenu:
+ if (!PreventBootMenu)
+ BootMenu();
+ }
+}
diff --git a/src/Boot/Windows/BootMain.h b/src/Boot/Windows/BootMain.h
index b6e75fa..2f212a1 100644
--- a/src/Boot/Windows/BootMain.h
+++ b/src/Boot/Windows/BootMain.h
@@ -1,34 +1,34 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootMain
-#define TC_HEADER_Boot_BootMain
-
-#include "TCdefs.h"
-#include "Platform.h"
-
-static byte AskPassword (Password &password, int& pim);
-static int AskSelection (const char *options[], size_t optionCount);
-static bool AskYesNo (const char *message);
-static byte BootEncryptedDrive ();
-static void BootMenu ();
-static void ExecuteBootSector (byte drive, byte *sectorBuffer);
-static void InitScreen ();
-static bool IsMenuKey (byte scanCode);
-static bool MountVolume (byte drive, byte &exitKey);
-static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32 = nullptr, bool skipNormal = false, bool skipHidden = false);
-static void PrintMainMenu ();
-static void RepairMenu ();
-
-#define TC_MENU_KEY_REPAIR TC_BIOS_KEY_F8
-
-#endif // TC_HEADER_Boot_BootMain
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootMain
+#define TC_HEADER_Boot_BootMain
+
+#include "TCdefs.h"
+#include "Platform.h"
+
+static byte AskPassword (Password &password, int& pim);
+static int AskSelection (const char *options[], size_t optionCount);
+static bool AskYesNo (const char *message);
+static byte BootEncryptedDrive ();
+static void BootMenu ();
+static void ExecuteBootSector (byte drive, byte *sectorBuffer);
+static void InitScreen ();
+static bool IsMenuKey (byte scanCode);
+static bool MountVolume (byte drive, byte &exitKey);
+static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32 = nullptr, bool skipNormal = false, bool skipHidden = false);
+static void PrintMainMenu ();
+static void RepairMenu ();
+
+#define TC_MENU_KEY_REPAIR TC_BIOS_KEY_F8
+
+#endif // TC_HEADER_Boot_BootMain
diff --git a/src/Boot/Windows/BootMemory.cpp b/src/Boot/Windows/BootMemory.cpp
index c1dd383..505b731 100644
--- a/src/Boot/Windows/BootMemory.cpp
+++ b/src/Boot/Windows/BootMemory.cpp
@@ -1,86 +1,86 @@
-/*
- 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-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 "BootDefs.h"
-#include "BootMemory.h"
-
-static uint32 MemoryMapContValue;
-
-static bool GetMemoryMapEntry (BiosMemoryMapEntry &entry)
-{
- static const uint32 function = 0x0000E820UL;
- static const uint32 magic = 0x534D4150UL;
- static const uint32 bufferSize = sizeof (BiosMemoryMapEntry);
-
- bool carry = false;
- uint32 resultMagic;
- uint32 resultSize;
-
- __asm
- {
- push es
-
- lea di, function
- TC_ASM_MOV_EAX_DI
- lea di, MemoryMapContValue
- TC_ASM_MOV_EBX_DI
- lea di, bufferSize
- TC_ASM_MOV_ECX_DI
- lea di, magic
- TC_ASM_MOV_EDX_DI
- lea di, MemoryMapContValue
- TC_ASM_MOV_DI_ECX
-
- // Use alternative segment to prevent memory corruption caused by buggy BIOSes
- push TC_BOOT_LOADER_ALT_SEGMENT
- pop es
- mov di, 0
-
- int 0x15
- jnc no_carry
- mov carry, true
- no_carry:
-
- lea di, resultMagic
- TC_ASM_MOV_DI_EAX
- lea di, MemoryMapContValue
- TC_ASM_MOV_DI_EBX
- lea di, resultSize
- TC_ASM_MOV_DI_ECX
-
- pop es
- }
-
- CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, 0, &entry, sizeof (entry));
-
- // BIOS may set CF at the end of the list
- if (carry)
- MemoryMapContValue = 0;
-
- return resultMagic == magic && resultSize == bufferSize;
-}
-
-
-bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
-{
- MemoryMapContValue = 0;
- return GetMemoryMapEntry (entry);
-}
-
-
-bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
-{
- if (MemoryMapContValue == 0)
- return false;
-
- return GetMemoryMapEntry (entry);
-}
+/*
+ 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-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 "BootDefs.h"
+#include "BootMemory.h"
+
+static uint32 MemoryMapContValue;
+
+static bool GetMemoryMapEntry (BiosMemoryMapEntry &entry)
+{
+ static const uint32 function = 0x0000E820UL;
+ static const uint32 magic = 0x534D4150UL;
+ static const uint32 bufferSize = sizeof (BiosMemoryMapEntry);
+
+ bool carry = false;
+ uint32 resultMagic;
+ uint32 resultSize;
+
+ __asm
+ {
+ push es
+
+ lea di, function
+ TC_ASM_MOV_EAX_DI
+ lea di, MemoryMapContValue
+ TC_ASM_MOV_EBX_DI
+ lea di, bufferSize
+ TC_ASM_MOV_ECX_DI
+ lea di, magic
+ TC_ASM_MOV_EDX_DI
+ lea di, MemoryMapContValue
+ TC_ASM_MOV_DI_ECX
+
+ // Use alternative segment to prevent memory corruption caused by buggy BIOSes
+ push TC_BOOT_LOADER_ALT_SEGMENT
+ pop es
+ mov di, 0
+
+ int 0x15
+ jnc no_carry
+ mov carry, true
+ no_carry:
+
+ lea di, resultMagic
+ TC_ASM_MOV_DI_EAX
+ lea di, MemoryMapContValue
+ TC_ASM_MOV_DI_EBX
+ lea di, resultSize
+ TC_ASM_MOV_DI_ECX
+
+ pop es
+ }
+
+ CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, 0, &entry, sizeof (entry));
+
+ // BIOS may set CF at the end of the list
+ if (carry)
+ MemoryMapContValue = 0;
+
+ return resultMagic == magic && resultSize == bufferSize;
+}
+
+
+bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
+{
+ MemoryMapContValue = 0;
+ return GetMemoryMapEntry (entry);
+}
+
+
+bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry)
+{
+ if (MemoryMapContValue == 0)
+ return false;
+
+ return GetMemoryMapEntry (entry);
+}
diff --git a/src/Boot/Windows/BootMemory.h b/src/Boot/Windows/BootMemory.h
index 0ed0470..d4ad156 100644
--- a/src/Boot/Windows/BootMemory.h
+++ b/src/Boot/Windows/BootMemory.h
@@ -1,28 +1,28 @@
-/*
- 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-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 "Platform.h"
-#include "Bios.h"
-
-#pragma pack(1)
-
-struct BiosMemoryMapEntry
-{
- uint64 BaseAddress;
- uint64 Length;
- uint32 Type;
-};
-
-#pragma pack()
-
-bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
-bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
+/*
+ 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-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 "Platform.h"
+#include "Bios.h"
+
+#pragma pack(1)
+
+struct BiosMemoryMapEntry
+{
+ uint64 BaseAddress;
+ uint64 Length;
+ uint32 Type;
+};
+
+#pragma pack()
+
+bool GetFirstBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
+bool GetNextBiosMemoryMapEntry (BiosMemoryMapEntry &entry);
diff --git a/src/Boot/Windows/BootSector.asm b/src/Boot/Windows/BootSector.asm
index e0049d2..0518414 100644
--- a/src/Boot/Windows/BootSector.asm
+++ b/src/Boot/Windows/BootSector.asm
@@ -1,244 +1,244 @@
-;
-; 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-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.
-;
-
-.MODEL tiny
-.386
-_TEXT SEGMENT USE16
-
-INCLUDE BootDefs.i
-
-ORG 7C00h ; Standard boot sector offset
-
-start:
- ; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address).
- ; Far jump to the next instruction sets IP to the standard offset 7C00.
- db 0EAh ; jmp 0:main
- dw main, 0
-
-loader_name_msg:
- db ' VeraCrypt Boot Loader', 13, 10, 0
-
-main:
- cli
- xor ax, ax
- mov ds, ax
- mov ss, ax
- mov sp, 7C00h
- sti
-
- ; Display boot loader name
- test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE
- jnz skip_loader_name_msg
-
- lea si, loader_name_msg
- call print
-skip_loader_name_msg:
-
- ; Determine boot loader segment
- mov ax, TC_BOOT_LOADER_SEGMENT
-
- ; Check available memory
- cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
- jge memory_ok
-
- mov ax, TC_BOOT_LOADER_SEGMENT_LOW
-
- cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT_LOW / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
- jge memory_ok
-
- ; Insufficient memory
- mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT
-
-memory_ok:
- mov es, ax
-
- ; Clear BSS section
- xor al, al
- mov di, TC_COM_EXECUTABLE_OFFSET
- mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1
- cld
- rep stosb
-
- mov ax, es
- sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment
- mov es, ax
-
- ; Load decompressor
- mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR
-retry_backup:
- mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
- mov bx, TC_COM_EXECUTABLE_OFFSET
- call read_sectors
-
- ; Decompressor checksum
- xor ebx, ebx
- mov si, TC_COM_EXECUTABLE_OFFSET
- mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE
- call checksum
- push ebx
-
- ; Load compressed boot loader
- mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
- mov cl, TC_BOOT_LOADER_START_SECTOR
- mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT
-
- test backup_loader_used, 1
- jz non_backup
- mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
- mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
-
-non_backup:
- call read_sectors
-
- ; Boot loader checksum
- pop ebx
- mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
- mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
- call checksum
-
- ; Verify checksum
- cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET]
- je checksum_ok
-
- ; Checksum incorrect - try using backup if available
- test backup_loader_used, 1
- jnz loader_damaged
-
- mov backup_loader_used, 1
- mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
-
- test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
- jnz retry_backup
-
-loader_damaged:
- lea si, loader_damaged_msg
- call print
- lea si, loader_name_msg
- call print
- jmp $
-checksum_ok:
-
- ; Set up decompressor segment
- mov ax, es
- mov ds, ax
- cli
- mov ss, ax
- mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
- sti
-
- push dx
-
- ; Decompress boot loader
- mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
- sub cx, TC_GZIP_HEADER_SIZE
- push cx ; Compressed data size
- push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data
- push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size
- push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer
-
- push cs
- push decompressor_ret
- push es
- push TC_COM_EXECUTABLE_OFFSET
- retf
-decompressor_ret:
-
- add sp, 8
- pop dx
-
- ; Restore boot sector segment
- push cs
- pop ds
-
- ; Check decompression result
- test ax, ax
- jz decompression_ok
-
- lea si, loader_damaged_msg
- call print
- jmp $
-decompression_ok:
-
- ; DH = boot sector flags
- mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
-
- ; Set up boot loader segment
- mov ax, es
- add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16
- mov es, ax
- mov ds, ax
- cli
- mov ss, ax
- mov sp, TC_BOOT_LOADER_STACK_TOP
- sti
-
- ; Execute boot loader
- push es
- push TC_COM_EXECUTABLE_OFFSET
- retf
-
- ; Print string
-print:
- xor bx, bx
- mov ah, 0eh
- cld
-
-@@: lodsb
- test al, al
- jz print_end
-
- int 10h
- jmp @B
-
-print_end:
- ret
-
- ; Read sectors of the first cylinder
-read_sectors:
- mov ch, 0 ; Cylinder
- mov dh, 0 ; Head
- ; DL = drive number passed from BIOS
- mov ah, 2
- int 13h
- jnc read_ok
-
- lea si, disk_error_msg
- call print
-read_ok:
- ret
-
- ; Calculate checksum
-checksum:
- push ds
- push es
- pop ds
- xor eax, eax
- cld
-
-@@: lodsb
- add ebx, eax
- rol ebx, 1
- loop @B
-
- pop ds
- ret
-
-backup_loader_used db 0
-
-disk_error_msg db 'Disk error', 13, 10, 7, 0
-loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0
-
-ORG 7C00h + 510
- dw 0AA55h ; Boot sector signature
-
-_TEXT ENDS
-END start
+;
+; 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-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.
+;
+
+.MODEL tiny
+.386
+_TEXT SEGMENT USE16
+
+INCLUDE BootDefs.i
+
+ORG 7C00h ; Standard boot sector offset
+
+start:
+ ; BIOS executes boot sector from 0:7C00 or 7C0:0000 (default CD boot loader address).
+ ; Far jump to the next instruction sets IP to the standard offset 7C00.
+ db 0EAh ; jmp 0:main
+ dw main, 0
+
+loader_name_msg:
+ db ' VeraCrypt Boot Loader', 13, 10, 0
+
+main:
+ cli
+ xor ax, ax
+ mov ds, ax
+ mov ss, ax
+ mov sp, 7C00h
+ sti
+
+ ; Display boot loader name
+ test byte ptr [start + TC_BOOT_SECTOR_USER_CONFIG_OFFSET], TC_BOOT_USER_CFG_FLAG_SILENT_MODE
+ jnz skip_loader_name_msg
+
+ lea si, loader_name_msg
+ call print
+skip_loader_name_msg:
+
+ ; Determine boot loader segment
+ mov ax, TC_BOOT_LOADER_SEGMENT
+
+ ; Check available memory
+ cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
+ jge memory_ok
+
+ mov ax, TC_BOOT_LOADER_SEGMENT_LOW
+
+ cmp word ptr [ds:413h], TC_BOOT_LOADER_SEGMENT_LOW / 1024 * 16 + TC_BOOT_MEMORY_REQUIRED
+ jge memory_ok
+
+ ; Insufficient memory
+ mov ax, TC_BOOT_LOADER_LOWMEM_SEGMENT
+
+memory_ok:
+ mov es, ax
+
+ ; Clear BSS section
+ xor al, al
+ mov di, TC_COM_EXECUTABLE_OFFSET
+ mov cx, TC_BOOT_MEMORY_REQUIRED * 1024 - TC_COM_EXECUTABLE_OFFSET - 1
+ cld
+ rep stosb
+
+ mov ax, es
+ sub ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16 ; Decompressor segment
+ mov es, ax
+
+ ; Load decompressor
+ mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR
+retry_backup:
+ mov al, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+ mov bx, TC_COM_EXECUTABLE_OFFSET
+ call read_sectors
+
+ ; Decompressor checksum
+ xor ebx, ebx
+ mov si, TC_COM_EXECUTABLE_OFFSET
+ mov cx, TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_LB_SIZE
+ call checksum
+ push ebx
+
+ ; Load compressed boot loader
+ mov bx, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
+ mov cl, TC_BOOT_LOADER_START_SECTOR
+ mov al, TC_MAX_BOOT_LOADER_SECTOR_COUNT
+
+ test backup_loader_used, 1
+ jz non_backup
+ mov al, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT - TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT
+ mov cl, TC_BOOT_LOADER_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
+
+non_backup:
+ call read_sectors
+
+ ; Boot loader checksum
+ pop ebx
+ mov si, TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET
+ mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
+ call checksum
+
+ ; Verify checksum
+ cmp ebx, dword ptr [start + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET]
+ je checksum_ok
+
+ ; Checksum incorrect - try using backup if available
+ test backup_loader_used, 1
+ jnz loader_damaged
+
+ mov backup_loader_used, 1
+ mov cl, TC_BOOT_LOADER_DECOMPRESSOR_START_SECTOR + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT
+
+ test TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
+ jnz retry_backup
+
+loader_damaged:
+ lea si, loader_damaged_msg
+ call print
+ lea si, loader_name_msg
+ call print
+ jmp $
+checksum_ok:
+
+ ; Set up decompressor segment
+ mov ax, es
+ mov ds, ax
+ cli
+ mov ss, ax
+ mov sp, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE
+ sti
+
+ push dx
+
+ ; Decompress boot loader
+ mov cx, word ptr [start + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET]
+ sub cx, TC_GZIP_HEADER_SIZE
+ push cx ; Compressed data size
+ push TC_BOOT_LOADER_COMPRESSED_BUFFER_OFFSET + TC_GZIP_HEADER_SIZE ; Compressed data
+ push TC_MAX_BOOT_LOADER_DECOMPRESSED_SIZE ; Output buffer size
+ push TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE + TC_COM_EXECUTABLE_OFFSET ; Output buffer
+
+ push cs
+ push decompressor_ret
+ push es
+ push TC_COM_EXECUTABLE_OFFSET
+ retf
+decompressor_ret:
+
+ add sp, 8
+ pop dx
+
+ ; Restore boot sector segment
+ push cs
+ pop ds
+
+ ; Check decompression result
+ test ax, ax
+ jz decompression_ok
+
+ lea si, loader_damaged_msg
+ call print
+ jmp $
+decompression_ok:
+
+ ; DH = boot sector flags
+ mov dh, byte ptr [start + TC_BOOT_SECTOR_CONFIG_OFFSET]
+
+ ; Set up boot loader segment
+ mov ax, es
+ add ax, TC_BOOT_LOADER_DECOMPRESSOR_MEMORY_SIZE / 16
+ mov es, ax
+ mov ds, ax
+ cli
+ mov ss, ax
+ mov sp, TC_BOOT_LOADER_STACK_TOP
+ sti
+
+ ; Execute boot loader
+ push es
+ push TC_COM_EXECUTABLE_OFFSET
+ retf
+
+ ; Print string
+print:
+ xor bx, bx
+ mov ah, 0eh
+ cld
+
+@@: lodsb
+ test al, al
+ jz print_end
+
+ int 10h
+ jmp @B
+
+print_end:
+ ret
+
+ ; Read sectors of the first cylinder
+read_sectors:
+ mov ch, 0 ; Cylinder
+ mov dh, 0 ; Head
+ ; DL = drive number passed from BIOS
+ mov ah, 2
+ int 13h
+ jnc read_ok
+
+ lea si, disk_error_msg
+ call print
+read_ok:
+ ret
+
+ ; Calculate checksum
+checksum:
+ push ds
+ push es
+ pop ds
+ xor eax, eax
+ cld
+
+@@: lodsb
+ add ebx, eax
+ rol ebx, 1
+ loop @B
+
+ pop ds
+ ret
+
+backup_loader_used db 0
+
+disk_error_msg db 'Disk error', 13, 10, 7, 0
+loader_damaged_msg db 7, 'Loader damaged! Repair with Rescue Disk', 0
+
+ORG 7C00h + 510
+ dw 0AA55h ; Boot sector signature
+
+_TEXT ENDS
+END start
diff --git a/src/Boot/Windows/BootStrings.h b/src/Boot/Windows/BootStrings.h
index dcf197a..99c4dc4 100644
--- a/src/Boot/Windows/BootStrings.h
+++ b/src/Boot/Windows/BootStrings.h
@@ -1,20 +1,20 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_BootStrings
-#define TC_HEADER_Boot_BootStrings
-
-#define TC_BOOT_STR_ERROR "Error: "
-#define TC_BOOT_STR_NO_BOOT_PARTITION "No bootable partition found"
-#define TC_BOOT_STR_UPGRADE_BIOS "- Upgrade BIOS\r\n- Use a different motherboard model/brand\r\n"
-
-#endif // TC_HEADER_Boot_BootStrings
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_BootStrings
+#define TC_HEADER_Boot_BootStrings
+
+#define TC_BOOT_STR_ERROR "Error: "
+#define TC_BOOT_STR_NO_BOOT_PARTITION "No bootable partition found"
+#define TC_BOOT_STR_UPGRADE_BIOS "- Upgrade BIOS\r\n- Use a different motherboard model/brand\r\n"
+
+#endif // TC_HEADER_Boot_BootStrings
diff --git a/src/Boot/Windows/Decompressor.c b/src/Boot/Windows/Decompressor.c
index 475a501..3bed8c6 100644
--- a/src/Boot/Windows/Decompressor.c
+++ b/src/Boot/Windows/Decompressor.c
@@ -83,7 +83,7 @@ local int stored(struct state *s)
s->bitbuf = 0;
s->bitcnt = 0;
- if (s->incnt + 4 > s->inlen)
+ if (s->incnt + 4 > s->inlen)
return 2; /* not enough input */
/* get length and check against its one's complement */
@@ -93,7 +93,7 @@ local int stored(struct state *s)
s->in[s->incnt++] != ((~len >> 8) & 0xff))
return -2; /* didn't match complement! */
- if (s->incnt + len > s->inlen)
+ if (s->incnt + len > s->inlen)
return 2; /* not enough input */
/* copy len bytes from in to out */
@@ -379,21 +379,21 @@ local int dynamic(struct state *s)
lengths[index++] = symbol;
else { /* repeat instruction */
len = 0; /* assume repeating zeros */
- switch(symbol)
- {
- case 16: { /* repeat last length 3..6 times */
- if (index == 0) return -5; /* no last length! */
- len = lengths[index - 1]; /* last length */
- symbol = 3 + bits(s, 2);
- break;
- }
- case 17: /* repeat zero 3..10 times */
- symbol = 3 + bits(s, 3);
- break;
- default: /* == 18, repeat zero 11..138 times */
- symbol = 11 + bits(s, 7);
- break;
- }
+ switch(symbol)
+ {
+ case 16: { /* repeat last length 3..6 times */
+ if (index == 0) return -5; /* no last length! */
+ len = lengths[index - 1]; /* last length */
+ symbol = 3 + bits(s, 2);
+ break;
+ }
+ case 17: /* repeat zero 3..10 times */
+ symbol = 3 + bits(s, 3);
+ break;
+ default: /* == 18, repeat zero 11..138 times */
+ symbol = 11 + bits(s, 7);
+ break;
+ }
if ((index + symbol > nlen + ndist))
return -6; /* too many lengths! */
while (symbol--) /* repeat last or zero symbol times */
@@ -401,8 +401,8 @@ local int dynamic(struct state *s)
}
}
- /* check for end-of-block code -- there better be one! */
- if (lengths[256] == 0)
+ /* check for end-of-block code -- there better be one! */
+ if (lengths[256] == 0)
return -9;
/* build huffman table for literal/length codes */
@@ -423,50 +423,50 @@ local int dynamic(struct state *s)
void _acrtused () { }
// Decompress deflated data
-int far main (
- unsigned char *dest, /* pointer to destination pointer */
- unsigned int destlen, /* amount of output space */
- unsigned char *source, /* pointer to source data pointer */
- unsigned int sourcelen)
-{
- struct state s; /* input/output state */
- int last, type; /* block information */
- int err; /* return value */
-
- /* initialize output state */
- s.out = dest;
- s.outlen = destlen; /* ignored if dest is NIL */
- s.outcnt = 0;
-
- /* initialize input state */
- s.in = source;
- s.inlen = sourcelen;
- s.incnt = 0;
- s.bitbuf = 0;
- s.bitcnt = 0;
-
- /* process blocks until last block or error */
- do {
- last = bits(&s, 1); /* one if last block */
- type = bits(&s, 2); /* block type 0..3 */
- switch(type)
- {
- case 0:
- err = stored(&s);
- break;
- case 1:
- err = fixed(&s);
- break;
- case 2:
- err = dynamic(&s);
- break;
- default:
- err = -1; /* type == 3, invalid */
- break;
- }
-
- if (err != 0) break; /* return with error */
- } while (!last);
-
- return err;
+int far main (
+ unsigned char *dest, /* pointer to destination pointer */
+ unsigned int destlen, /* amount of output space */
+ unsigned char *source, /* pointer to source data pointer */
+ unsigned int sourcelen)
+{
+ struct state s; /* input/output state */
+ int last, type; /* block information */
+ int err; /* return value */
+
+ /* initialize output state */
+ s.out = dest;
+ s.outlen = destlen; /* ignored if dest is NIL */
+ s.outcnt = 0;
+
+ /* initialize input state */
+ s.in = source;
+ s.inlen = sourcelen;
+ s.incnt = 0;
+ s.bitbuf = 0;
+ s.bitcnt = 0;
+
+ /* process blocks until last block or error */
+ do {
+ last = bits(&s, 1); /* one if last block */
+ type = bits(&s, 2); /* block type 0..3 */
+ switch(type)
+ {
+ case 0:
+ err = stored(&s);
+ break;
+ case 1:
+ err = fixed(&s);
+ break;
+ case 2:
+ err = dynamic(&s);
+ break;
+ default:
+ err = -1; /* type == 3, invalid */
+ break;
+ }
+
+ if (err != 0) break; /* return with error */
+ } while (!last);
+
+ return err;
}
diff --git a/src/Boot/Windows/IntFilter.cpp b/src/Boot/Windows/IntFilter.cpp
index 0671c4d..d9cd92d 100644
--- a/src/Boot/Windows/IntFilter.cpp
+++ b/src/Boot/Windows/IntFilter.cpp
@@ -1,645 +1,645 @@
-/*
- 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-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 "Platform.h"
-#include "BootMemory.h"
-#include "BootConfig.h"
-#include "BootConsoleIo.h"
-#include "BootDebug.h"
-#include "BootDefs.h"
-#include "BootDiskIo.h"
-#include "BootEncryptedIo.h"
-#include "BootStrings.h"
-#include "IntFilter.h"
-
-static uint32 OriginalInt13Handler;
-static uint32 OriginalInt15Handler;
-
-static Registers IntRegisters;
-
-
-bool Int13Filter ()
-{
- CheckStack();
-
- Registers regs;
- memcpy (&regs, &IntRegisters, sizeof (regs));
- __asm sti
-
- static int ReEntryCount = -1;
- ++ReEntryCount;
-
- byte function = (byte) (regs.AX >> 8);
-
-#ifdef TC_TRACE_INT13
- DisableScreenOutput();
-
- PrintHex (function);
-
- Print (" EN:"); Print (ReEntryCount);
- Print (" SS:"); PrintHex (regs.SS);
-
- uint16 spdbg;
- __asm mov spdbg, sp
- PrintChar (' ');
- PrintHex (spdbg);
- PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
-
-#endif
-
- bool passOriginalRequest = true;
-
- switch (function)
- {
- case 0x2: // Read sectors
- case 0x3: // Write sectors
- {
- byte drive = (byte) regs.DX;
-
- ChsAddress chs;
- chs.Cylinder = ((regs.CX << 2) & 0x300) | (regs.CX >> 8);
- chs.Head = regs.DX >> 8;
- chs.Sector = regs.CX & 0x3f;
-
- byte sectorCount = (byte) regs.AX;
-
-#ifdef TC_TRACE_INT13
- PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
- Print (" Chs: "); Print (chs);
-#endif
-
- uint64 sector;
- if (drive == BootDrive)
- {
- if (!BootDriveGeometryValid)
- TC_THROW_FATAL_EXCEPTION;
-
- ChsToLba (BootDriveGeometry, chs, sector);
-#ifdef TC_TRACE_INT13
- PrintVal (" Sec", sector.LowPart, false);
-#endif
- }
-
-#ifdef TC_TRACE_INT13
- PrintVal (" Count", sectorCount, false);
- Print (" Buf: "); PrintHex (regs.ES); PrintChar (':'); PrintHex (regs.BX);
- PrintEndl();
-#endif
-
- if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
- {
- BiosResult result;
-
- if (function == 0x3)
- result = WriteEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
- else
- result = ReadEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
-
- __asm cli
-
- memcpy (&IntRegisters, &regs, sizeof (regs));
- IntRegisters.AX = (uint16) result << 8;
-
- if (result == BiosResultSuccess)
- {
- IntRegisters.AX |= sectorCount;
- IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
- }
- else
- IntRegisters.Flags |= TC_X86_CARRY_FLAG;
-
- passOriginalRequest = false;
- }
- }
- break;
-
- case 0x42: // Read sectors LBA
- case 0x43: // Write sectors LBA
- {
- byte drive = (byte) regs.DX;
-
- BiosLbaPacket lba;
- CopyMemory (regs.DS, regs.SI, (byte *) &lba, sizeof (lba));
-
-#ifdef TC_TRACE_INT13
- PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
- PrintVal (" Sec", lba.Sector.LowPart, false);
- PrintVal (" Count", lba.SectorCount, false);
- PrintVal (" Buf", lba.Buffer, false, true);
- PrintEndl();
-#endif
-
- if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
- {
- BiosResult result;
-
- uint16 segment = (uint16) (lba.Buffer >> 16);
- uint16 offset = (uint16) lba.Buffer;
-
- if (function == 0x43)
- result = WriteEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
- else
- result = ReadEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
-
- __asm cli
-
- memcpy (&IntRegisters, &regs, sizeof (regs));
- IntRegisters.AX = (IntRegisters.AX & 0xff) | ((uint16) result << 8);
-
- if (result == BiosResultSuccess)
- IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
- else
- IntRegisters.Flags |= TC_X86_CARRY_FLAG;
-
- passOriginalRequest = false;
- }
- }
- break;
-
- default:
-#ifdef TC_TRACE_INT13
- PrintEndl();
-#endif
- break;
- }
-
-#ifdef TC_TRACE_INT13
- EnableScreenOutput();
-#endif
- --ReEntryCount;
-
- return passOriginalRequest;
-}
-
-
-#define TC_MAX_MEMORY_MAP_SIZE 80
-
-BiosMemoryMapEntry BiosMemoryMap[TC_MAX_MEMORY_MAP_SIZE];
-static size_t BiosMemoryMapSize;
-
-
-static void CreateBootLoaderMemoryMapEntry (BiosMemoryMapEntry *newMapEntry, uint32 bootLoaderStart)
-{
- newMapEntry->Type = 0x2;
- newMapEntry->BaseAddress.HighPart = 0;
- newMapEntry->BaseAddress.LowPart = bootLoaderStart;
- newMapEntry->Length.HighPart = 0;
- newMapEntry->Length.LowPart = TC_BOOT_MEMORY_REQUIRED * 1024UL;
-}
-
-
-static bool CreateNewBiosMemoryMap ()
-{
- // Create a new BIOS memory map presenting the memory area of the loader as reserved
-
- BiosMemoryMapSize = 0;
- BiosMemoryMapEntry entry;
- BiosMemoryMapEntry *newMapEntry = BiosMemoryMap;
-
- const BiosMemoryMapEntry *mapEnd = BiosMemoryMap + TC_MAX_MEMORY_MAP_SIZE;
-
- uint64 bootLoaderStart;
- bootLoaderStart.HighPart = 0;
-
- uint16 codeSeg;
- __asm mov codeSeg, cs
- bootLoaderStart.LowPart = GetLinearAddress (codeSeg, 0);
-
- uint64 bootLoaderEnd;
- bootLoaderEnd.HighPart = 0;
- bootLoaderEnd.LowPart = bootLoaderStart.LowPart + TC_BOOT_MEMORY_REQUIRED * 1024UL;
-
- bool loaderEntryInserted = false;
-
- if (GetFirstBiosMemoryMapEntry (entry))
- {
- do
- {
- uint64 entryEnd = entry.BaseAddress + entry.Length;
-
- if (entry.Type == 0x1 && RegionsIntersect (bootLoaderStart, TC_BOOT_MEMORY_REQUIRED * 1024UL, entry.BaseAddress, entryEnd - 1))
- {
- // Free map entry covers the boot loader area
-
- if (entry.BaseAddress < bootLoaderStart)
- {
- // Create free entry below the boot loader area
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- *newMapEntry = entry;
- newMapEntry->Length = bootLoaderStart - entry.BaseAddress;
- ++newMapEntry;
- }
-
- if (!loaderEntryInserted)
- {
- // Create reserved entry for the boot loader if it has not been done yet
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
- ++newMapEntry;
- loaderEntryInserted = true;
- }
-
- if (bootLoaderEnd < entryEnd)
- {
- // Create free entry above the boot loader area
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- newMapEntry->Type = 0x1;
- newMapEntry->BaseAddress = bootLoaderEnd;
- newMapEntry->Length = entryEnd - bootLoaderEnd;
- ++newMapEntry;
- }
- }
- else
- {
- if (newMapEntry >= mapEnd)
- goto mapOverflow;
-
- if (!loaderEntryInserted && entry.BaseAddress > bootLoaderStart)
- {
- // Create reserved entry for the boot loader if it has not been done yet
- CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
- ++newMapEntry;
- loaderEntryInserted = true;
- }
-
- // Copy map entry
- *newMapEntry++ = entry;
- }
-
- } while (GetNextBiosMemoryMapEntry (entry));
- }
-
- BiosMemoryMapSize = newMapEntry - BiosMemoryMap;
- return true;
-
-mapOverflow:
- size_t overSize = 0;
- while (GetNextBiosMemoryMapEntry (entry))
- {
- ++overSize;
- }
-
- PrintErrorNoEndl ("MMP:");
- Print (overSize);
- PrintEndl();
-
- return false;
-}
-
-
-bool Int15Filter ()
-{
- CheckStack();
-
-#ifdef TC_TRACE_INT15
- DisableScreenOutput();
-
- Print ("15-");
- PrintHex (IntRegisters.AX);
-
- Print (" SS:"); PrintHex (IntRegisters.SS);
-
- uint16 spdbg;
- __asm mov spdbg, sp
- PrintChar (' ');
- PrintHex (spdbg);
- PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
-
- Print (" EAX:"); PrintHex (IntRegisters.EAX);
- Print (" EBX:"); PrintHex (IntRegisters.EBX);
- Print (" ECX:"); PrintHex (IntRegisters.ECX);
- Print (" EDX:"); PrintHex (IntRegisters.EDX);
- Print (" DI:"); PrintHex (IntRegisters.DI);
- PrintEndl();
-
-#endif
-
- if (IntRegisters.EBX >= BiosMemoryMapSize)
- {
- IntRegisters.Flags |= TC_X86_CARRY_FLAG;
- IntRegisters.EBX = 0;
- IntRegisters.AX = -1;
- }
- else
- {
- CopyMemory ((byte *) &BiosMemoryMap[IntRegisters.EBX], IntRegisters.ES, IntRegisters.DI, sizeof (BiosMemoryMap[0]));
-
- IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
- IntRegisters.EAX = 0x534D4150UL;
-
- ++IntRegisters.EBX;
- if (IntRegisters.EBX >= BiosMemoryMapSize)
- IntRegisters.EBX = 0;
-
- IntRegisters.ECX = sizeof (BiosMemoryMap[0]);
- }
-
- if (IntRegisters.EBX == 0 && !(BootSectorFlags & TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER))
- {
- // Uninstall filter when the modified map has been issued three times to prevent
- // problems with hardware drivers on some notebooks running Windows XP.
-
- static int CompleteMapIssueCount = 0;
- if (++CompleteMapIssueCount >= 3)
- {
- __asm
- {
- cli
- push es
-
- lea si, OriginalInt15Handler
- xor ax, ax
- mov es, ax
- mov di, 0x15 * 4
-
- mov ax, [si]
- mov es:[di], ax
- mov ax, [si + 2]
- mov es:[di + 2], ax
-
- pop es
- sti
- }
- }
- }
-
-#ifdef TC_TRACE_INT15
- BiosMemoryMapEntry entry;
- CopyMemory (IntRegisters.ES, IntRegisters.DI, (byte *) &entry, sizeof (entry));
- PrintHex (entry.Type); PrintChar (' ');
- PrintHex (entry.BaseAddress); PrintChar (' ');
- PrintHex (entry.Length); PrintChar (' ');
- PrintHex (entry.BaseAddress + entry.Length); PrintEndl();
-
- Print ("EAX:"); PrintHex (IntRegisters.EAX);
- Print (" EBX:"); PrintHex (IntRegisters.EBX);
- Print (" ECX:"); PrintHex (IntRegisters.ECX);
- Print (" EDX:"); PrintHex (IntRegisters.EDX);
- Print (" DI:"); PrintHex (IntRegisters.DI);
- Print (" FL:"); PrintHex (IntRegisters.Flags);
- PrintEndl (2);
-#endif
-
-#ifdef TC_TRACE_INT15
- EnableScreenOutput();
-#endif
- return false;
-}
-
-
-void IntFilterEntry ()
-{
- // No automatic variables should be used in this scope as SS may change
- static uint16 OrigStackPointer;
- static uint16 OrigStackSegment;
-
- __asm
- {
- pushf
- pushad
-
- cli
- mov cs:IntRegisters.DI, di
-
- lea di, cs:IntRegisters.EAX
- TC_ASM_EMIT4 (66,2E,89,05) // mov [cs:di], eax
- lea di, cs:IntRegisters.EBX
- TC_ASM_EMIT4 (66,2E,89,1D) // mov [cs:di], ebx
- lea di, cs:IntRegisters.ECX
- TC_ASM_EMIT4 (66,2E,89,0D) // mov [cs:di], ecx
- lea di, cs:IntRegisters.EDX
- TC_ASM_EMIT4 (66,2E,89,15) // mov [cs:di], edx
-
- mov ax, [bp + 8]
- mov cs:IntRegisters.Flags, ax
-
- mov cs:IntRegisters.SI, si
- mov si, [bp + 2] // Int number
-
- mov cs:IntRegisters.DS, ds
- mov cs:IntRegisters.ES, es
- mov cs:IntRegisters.SS, ss
-
- // Compiler assumes SS == DS - use our stack if this condition is not met
- mov ax, ss
- mov bx, cs
- cmp ax, bx
- jz stack_ok
-
- mov cs:OrigStackPointer, sp
- mov cs:OrigStackSegment, ss
- mov ax, cs
- mov ss, ax
- mov sp, TC_BOOT_LOADER_STACK_TOP
-
- stack_ok:
- // DS = CS
- push ds
- push es
- mov ax, cs
- mov ds, ax
- mov es, ax
-
- push si // Int number
-
- // Filter request
- cmp si, 0x15
- je filter15
- cmp si, 0x13
- jne $
-
- call Int13Filter
- jmp s0
-
- filter15:
- call Int15Filter
-
- s0:
- pop si // Int number
- pop es
- pop ds
-
- // Restore original SS:SP if our stack is empty
- cli
- mov bx, TC_BOOT_LOADER_STACK_TOP
- cmp bx, sp
- jnz stack_in_use
-
- mov ss, cs:OrigStackSegment
- mov sp, cs:OrigStackPointer
- stack_in_use:
-
- test ax, ax // passOriginalRequest
- jnz pass_request
-
- // Return results of filtered request
- popad
- popf
- mov ax, cs:IntRegisters.Flags
- mov [bp + 8], ax
- leave
-
- lea di, cs:IntRegisters.EAX
- TC_ASM_EMIT4 (66,2E,8B,05) // mov eax, [cs:di]
- lea di, cs:IntRegisters.EBX
- TC_ASM_EMIT4 (66,2E,8B,1D) // mov ebx, [cs:di]
- lea di, cs:IntRegisters.ECX
- TC_ASM_EMIT4 (66,2E,8B,0D) // mov ecx, [cs:di]
- lea di, cs:IntRegisters.EDX
- TC_ASM_EMIT4 (66,2E,8B,15) // mov edx, [cs:di]
-
- mov di, cs:IntRegisters.DI
- mov si, cs:IntRegisters.SI
- mov es, cs:IntRegisters.ES
- mov ds, cs:IntRegisters.DS
-
- sti
- add sp, 2
- iret
-
- // Pass original request
- pass_request:
- sti
- cmp si, 0x15
- je pass15
- cmp si, 0x13
- jne $
-
- popad
- popf
- leave
- add sp, 2
- jmp cs:OriginalInt13Handler
-
- pass15:
- popad
- popf
- leave
- add sp, 2
- jmp cs:OriginalInt15Handler
- }
-}
-
-
-void Int13FilterEntry ()
-{
- __asm
- {
- leave
- push 0x13
- jmp IntFilterEntry
- }
-}
-
-
-static void Int15FilterEntry ()
-{
- __asm
- {
- pushf
- cmp ax, 0xe820 // Get system memory map
- je filter
-
- popf
- leave
- jmp cs:OriginalInt15Handler
-
- filter:
- leave
- push 0x15
- jmp IntFilterEntry
- }
-}
-
-
-bool InstallInterruptFilters ()
-{
-
-#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-
- // If the filters have already been installed, it usually indicates stack corruption
- // and a consequent reentry of this routine without a system reset.
-
- uint32 currentInt13Handler;
- CopyMemory (0, 0x13 * 4, &currentInt13Handler, sizeof (currentInt13Handler));
-
- if (currentInt13Handler == (uint32) Int13FilterEntry)
- {
- PrintError ("Memory corrupted");
- Print (TC_BOOT_STR_UPGRADE_BIOS);
-
- GetKeyboardChar();
- return true;
- }
-
-#endif
-
- if (!CreateNewBiosMemoryMap())
- return false;
-
- __asm
- {
- cli
- push es
-
- // Save original INT 13 handler
- xor ax, ax
- mov es, ax
-
- mov si, 0x13 * 4
- lea di, OriginalInt13Handler
-
- mov ax, es:[si]
- mov [di], ax
- mov ax, es:[si + 2]
- mov [di + 2], ax
-
- // Install INT 13 filter
- lea ax, Int13FilterEntry
- mov es:[si], ax
- mov es:[si + 2], cs
-
- // Save original INT 15 handler
- mov si, 0x15 * 4
- lea di, OriginalInt15Handler
-
- mov ax, es:[si]
- mov [di], ax
- mov ax, es:[si + 2]
- mov [di + 2], ax
-
- // Install INT 15 filter
- lea ax, Int15FilterEntry
- mov es:[si], ax
- mov es:[si + 2], cs
-
- // If the BIOS does not support system memory map (INT15 0xe820),
- // set amount of available memory to CS:0000 - 0:0000
- cmp BiosMemoryMapSize, 1
- jg mem_map_ok
- mov ax, cs
- shr ax, 10 - 4 // CS * 16 / 1024
- mov es:[0x413], ax // = KBytes available
- mem_map_ok:
-
- pop es
- sti
- }
-
- return true;
-}
+/*
+ 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-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 "Platform.h"
+#include "BootMemory.h"
+#include "BootConfig.h"
+#include "BootConsoleIo.h"
+#include "BootDebug.h"
+#include "BootDefs.h"
+#include "BootDiskIo.h"
+#include "BootEncryptedIo.h"
+#include "BootStrings.h"
+#include "IntFilter.h"
+
+static uint32 OriginalInt13Handler;
+static uint32 OriginalInt15Handler;
+
+static Registers IntRegisters;
+
+
+bool Int13Filter ()
+{
+ CheckStack();
+
+ Registers regs;
+ memcpy (&regs, &IntRegisters, sizeof (regs));
+ __asm sti
+
+ static int ReEntryCount = -1;
+ ++ReEntryCount;
+
+ byte function = (byte) (regs.AX >> 8);
+
+#ifdef TC_TRACE_INT13
+ DisableScreenOutput();
+
+ PrintHex (function);
+
+ Print (" EN:"); Print (ReEntryCount);
+ Print (" SS:"); PrintHex (regs.SS);
+
+ uint16 spdbg;
+ __asm mov spdbg, sp
+ PrintChar (' ');
+ PrintHex (spdbg);
+ PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
+
+#endif
+
+ bool passOriginalRequest = true;
+
+ switch (function)
+ {
+ case 0x2: // Read sectors
+ case 0x3: // Write sectors
+ {
+ byte drive = (byte) regs.DX;
+
+ ChsAddress chs;
+ chs.Cylinder = ((regs.CX << 2) & 0x300) | (regs.CX >> 8);
+ chs.Head = regs.DX >> 8;
+ chs.Sector = regs.CX & 0x3f;
+
+ byte sectorCount = (byte) regs.AX;
+
+#ifdef TC_TRACE_INT13
+ PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
+ Print (" Chs: "); Print (chs);
+#endif
+
+ uint64 sector;
+ if (drive == BootDrive)
+ {
+ if (!BootDriveGeometryValid)
+ TC_THROW_FATAL_EXCEPTION;
+
+ ChsToLba (BootDriveGeometry, chs, sector);
+#ifdef TC_TRACE_INT13
+ PrintVal (" Sec", sector.LowPart, false);
+#endif
+ }
+
+#ifdef TC_TRACE_INT13
+ PrintVal (" Count", sectorCount, false);
+ Print (" Buf: "); PrintHex (regs.ES); PrintChar (':'); PrintHex (regs.BX);
+ PrintEndl();
+#endif
+
+ if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
+ {
+ BiosResult result;
+
+ if (function == 0x3)
+ result = WriteEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
+ else
+ result = ReadEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
+
+ __asm cli
+
+ memcpy (&IntRegisters, &regs, sizeof (regs));
+ IntRegisters.AX = (uint16) result << 8;
+
+ if (result == BiosResultSuccess)
+ {
+ IntRegisters.AX |= sectorCount;
+ IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
+ }
+ else
+ IntRegisters.Flags |= TC_X86_CARRY_FLAG;
+
+ passOriginalRequest = false;
+ }
+ }
+ break;
+
+ case 0x42: // Read sectors LBA
+ case 0x43: // Write sectors LBA
+ {
+ byte drive = (byte) regs.DX;
+
+ BiosLbaPacket lba;
+ CopyMemory (regs.DS, regs.SI, (byte *) &lba, sizeof (lba));
+
+#ifdef TC_TRACE_INT13
+ PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
+ PrintVal (" Sec", lba.Sector.LowPart, false);
+ PrintVal (" Count", lba.SectorCount, false);
+ PrintVal (" Buf", lba.Buffer, false, true);
+ PrintEndl();
+#endif
+
+ if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
+ {
+ BiosResult result;
+
+ uint16 segment = (uint16) (lba.Buffer >> 16);
+ uint16 offset = (uint16) lba.Buffer;
+
+ if (function == 0x43)
+ result = WriteEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
+ else
+ result = ReadEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
+
+ __asm cli
+
+ memcpy (&IntRegisters, &regs, sizeof (regs));
+ IntRegisters.AX = (IntRegisters.AX & 0xff) | ((uint16) result << 8);
+
+ if (result == BiosResultSuccess)
+ IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
+ else
+ IntRegisters.Flags |= TC_X86_CARRY_FLAG;
+
+ passOriginalRequest = false;
+ }
+ }
+ break;
+
+ default:
+#ifdef TC_TRACE_INT13
+ PrintEndl();
+#endif
+ break;
+ }
+
+#ifdef TC_TRACE_INT13
+ EnableScreenOutput();
+#endif
+ --ReEntryCount;
+
+ return passOriginalRequest;
+}
+
+
+#define TC_MAX_MEMORY_MAP_SIZE 80
+
+BiosMemoryMapEntry BiosMemoryMap[TC_MAX_MEMORY_MAP_SIZE];
+static size_t BiosMemoryMapSize;
+
+
+static void CreateBootLoaderMemoryMapEntry (BiosMemoryMapEntry *newMapEntry, uint32 bootLoaderStart)
+{
+ newMapEntry->Type = 0x2;
+ newMapEntry->BaseAddress.HighPart = 0;
+ newMapEntry->BaseAddress.LowPart = bootLoaderStart;
+ newMapEntry->Length.HighPart = 0;
+ newMapEntry->Length.LowPart = TC_BOOT_MEMORY_REQUIRED * 1024UL;
+}
+
+
+static bool CreateNewBiosMemoryMap ()
+{
+ // Create a new BIOS memory map presenting the memory area of the loader as reserved
+
+ BiosMemoryMapSize = 0;
+ BiosMemoryMapEntry entry;
+ BiosMemoryMapEntry *newMapEntry = BiosMemoryMap;
+
+ const BiosMemoryMapEntry *mapEnd = BiosMemoryMap + TC_MAX_MEMORY_MAP_SIZE;
+
+ uint64 bootLoaderStart;
+ bootLoaderStart.HighPart = 0;
+
+ uint16 codeSeg;
+ __asm mov codeSeg, cs
+ bootLoaderStart.LowPart = GetLinearAddress (codeSeg, 0);
+
+ uint64 bootLoaderEnd;
+ bootLoaderEnd.HighPart = 0;
+ bootLoaderEnd.LowPart = bootLoaderStart.LowPart + TC_BOOT_MEMORY_REQUIRED * 1024UL;
+
+ bool loaderEntryInserted = false;
+
+ if (GetFirstBiosMemoryMapEntry (entry))
+ {
+ do
+ {
+ uint64 entryEnd = entry.BaseAddress + entry.Length;
+
+ if (entry.Type == 0x1 && RegionsIntersect (bootLoaderStart, TC_BOOT_MEMORY_REQUIRED * 1024UL, entry.BaseAddress, entryEnd - 1))
+ {
+ // Free map entry covers the boot loader area
+
+ if (entry.BaseAddress < bootLoaderStart)
+ {
+ // Create free entry below the boot loader area
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ *newMapEntry = entry;
+ newMapEntry->Length = bootLoaderStart - entry.BaseAddress;
+ ++newMapEntry;
+ }
+
+ if (!loaderEntryInserted)
+ {
+ // Create reserved entry for the boot loader if it has not been done yet
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
+ ++newMapEntry;
+ loaderEntryInserted = true;
+ }
+
+ if (bootLoaderEnd < entryEnd)
+ {
+ // Create free entry above the boot loader area
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ newMapEntry->Type = 0x1;
+ newMapEntry->BaseAddress = bootLoaderEnd;
+ newMapEntry->Length = entryEnd - bootLoaderEnd;
+ ++newMapEntry;
+ }
+ }
+ else
+ {
+ if (newMapEntry >= mapEnd)
+ goto mapOverflow;
+
+ if (!loaderEntryInserted && entry.BaseAddress > bootLoaderStart)
+ {
+ // Create reserved entry for the boot loader if it has not been done yet
+ CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
+ ++newMapEntry;
+ loaderEntryInserted = true;
+ }
+
+ // Copy map entry
+ *newMapEntry++ = entry;
+ }
+
+ } while (GetNextBiosMemoryMapEntry (entry));
+ }
+
+ BiosMemoryMapSize = newMapEntry - BiosMemoryMap;
+ return true;
+
+mapOverflow:
+ size_t overSize = 0;
+ while (GetNextBiosMemoryMapEntry (entry))
+ {
+ ++overSize;
+ }
+
+ PrintErrorNoEndl ("MMP:");
+ Print (overSize);
+ PrintEndl();
+
+ return false;
+}
+
+
+bool Int15Filter ()
+{
+ CheckStack();
+
+#ifdef TC_TRACE_INT15
+ DisableScreenOutput();
+
+ Print ("15-");
+ PrintHex (IntRegisters.AX);
+
+ Print (" SS:"); PrintHex (IntRegisters.SS);
+
+ uint16 spdbg;
+ __asm mov spdbg, sp
+ PrintChar (' ');
+ PrintHex (spdbg);
+ PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
+
+ Print (" EAX:"); PrintHex (IntRegisters.EAX);
+ Print (" EBX:"); PrintHex (IntRegisters.EBX);
+ Print (" ECX:"); PrintHex (IntRegisters.ECX);
+ Print (" EDX:"); PrintHex (IntRegisters.EDX);
+ Print (" DI:"); PrintHex (IntRegisters.DI);
+ PrintEndl();
+
+#endif
+
+ if (IntRegisters.EBX >= BiosMemoryMapSize)
+ {
+ IntRegisters.Flags |= TC_X86_CARRY_FLAG;
+ IntRegisters.EBX = 0;
+ IntRegisters.AX = -1;
+ }
+ else
+ {
+ CopyMemory ((byte *) &BiosMemoryMap[IntRegisters.EBX], IntRegisters.ES, IntRegisters.DI, sizeof (BiosMemoryMap[0]));
+
+ IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
+ IntRegisters.EAX = 0x534D4150UL;
+
+ ++IntRegisters.EBX;
+ if (IntRegisters.EBX >= BiosMemoryMapSize)
+ IntRegisters.EBX = 0;
+
+ IntRegisters.ECX = sizeof (BiosMemoryMap[0]);
+ }
+
+ if (IntRegisters.EBX == 0 && !(BootSectorFlags & TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER))
+ {
+ // Uninstall filter when the modified map has been issued three times to prevent
+ // problems with hardware drivers on some notebooks running Windows XP.
+
+ static int CompleteMapIssueCount = 0;
+ if (++CompleteMapIssueCount >= 3)
+ {
+ __asm
+ {
+ cli
+ push es
+
+ lea si, OriginalInt15Handler
+ xor ax, ax
+ mov es, ax
+ mov di, 0x15 * 4
+
+ mov ax, [si]
+ mov es:[di], ax
+ mov ax, [si + 2]
+ mov es:[di + 2], ax
+
+ pop es
+ sti
+ }
+ }
+ }
+
+#ifdef TC_TRACE_INT15
+ BiosMemoryMapEntry entry;
+ CopyMemory (IntRegisters.ES, IntRegisters.DI, (byte *) &entry, sizeof (entry));
+ PrintHex (entry.Type); PrintChar (' ');
+ PrintHex (entry.BaseAddress); PrintChar (' ');
+ PrintHex (entry.Length); PrintChar (' ');
+ PrintHex (entry.BaseAddress + entry.Length); PrintEndl();
+
+ Print ("EAX:"); PrintHex (IntRegisters.EAX);
+ Print (" EBX:"); PrintHex (IntRegisters.EBX);
+ Print (" ECX:"); PrintHex (IntRegisters.ECX);
+ Print (" EDX:"); PrintHex (IntRegisters.EDX);
+ Print (" DI:"); PrintHex (IntRegisters.DI);
+ Print (" FL:"); PrintHex (IntRegisters.Flags);
+ PrintEndl (2);
+#endif
+
+#ifdef TC_TRACE_INT15
+ EnableScreenOutput();
+#endif
+ return false;
+}
+
+
+void IntFilterEntry ()
+{
+ // No automatic variables should be used in this scope as SS may change
+ static uint16 OrigStackPointer;
+ static uint16 OrigStackSegment;
+
+ __asm
+ {
+ pushf
+ pushad
+
+ cli
+ mov cs:IntRegisters.DI, di
+
+ lea di, cs:IntRegisters.EAX
+ TC_ASM_EMIT4 (66,2E,89,05) // mov [cs:di], eax
+ lea di, cs:IntRegisters.EBX
+ TC_ASM_EMIT4 (66,2E,89,1D) // mov [cs:di], ebx
+ lea di, cs:IntRegisters.ECX
+ TC_ASM_EMIT4 (66,2E,89,0D) // mov [cs:di], ecx
+ lea di, cs:IntRegisters.EDX
+ TC_ASM_EMIT4 (66,2E,89,15) // mov [cs:di], edx
+
+ mov ax, [bp + 8]
+ mov cs:IntRegisters.Flags, ax
+
+ mov cs:IntRegisters.SI, si
+ mov si, [bp + 2] // Int number
+
+ mov cs:IntRegisters.DS, ds
+ mov cs:IntRegisters.ES, es
+ mov cs:IntRegisters.SS, ss
+
+ // Compiler assumes SS == DS - use our stack if this condition is not met
+ mov ax, ss
+ mov bx, cs
+ cmp ax, bx
+ jz stack_ok
+
+ mov cs:OrigStackPointer, sp
+ mov cs:OrigStackSegment, ss
+ mov ax, cs
+ mov ss, ax
+ mov sp, TC_BOOT_LOADER_STACK_TOP
+
+ stack_ok:
+ // DS = CS
+ push ds
+ push es
+ mov ax, cs
+ mov ds, ax
+ mov es, ax
+
+ push si // Int number
+
+ // Filter request
+ cmp si, 0x15
+ je filter15
+ cmp si, 0x13
+ jne $
+
+ call Int13Filter
+ jmp s0
+
+ filter15:
+ call Int15Filter
+
+ s0:
+ pop si // Int number
+ pop es
+ pop ds
+
+ // Restore original SS:SP if our stack is empty
+ cli
+ mov bx, TC_BOOT_LOADER_STACK_TOP
+ cmp bx, sp
+ jnz stack_in_use
+
+ mov ss, cs:OrigStackSegment
+ mov sp, cs:OrigStackPointer
+ stack_in_use:
+
+ test ax, ax // passOriginalRequest
+ jnz pass_request
+
+ // Return results of filtered request
+ popad
+ popf
+ mov ax, cs:IntRegisters.Flags
+ mov [bp + 8], ax
+ leave
+
+ lea di, cs:IntRegisters.EAX
+ TC_ASM_EMIT4 (66,2E,8B,05) // mov eax, [cs:di]
+ lea di, cs:IntRegisters.EBX
+ TC_ASM_EMIT4 (66,2E,8B,1D) // mov ebx, [cs:di]
+ lea di, cs:IntRegisters.ECX
+ TC_ASM_EMIT4 (66,2E,8B,0D) // mov ecx, [cs:di]
+ lea di, cs:IntRegisters.EDX
+ TC_ASM_EMIT4 (66,2E,8B,15) // mov edx, [cs:di]
+
+ mov di, cs:IntRegisters.DI
+ mov si, cs:IntRegisters.SI
+ mov es, cs:IntRegisters.ES
+ mov ds, cs:IntRegisters.DS
+
+ sti
+ add sp, 2
+ iret
+
+ // Pass original request
+ pass_request:
+ sti
+ cmp si, 0x15
+ je pass15
+ cmp si, 0x13
+ jne $
+
+ popad
+ popf
+ leave
+ add sp, 2
+ jmp cs:OriginalInt13Handler
+
+ pass15:
+ popad
+ popf
+ leave
+ add sp, 2
+ jmp cs:OriginalInt15Handler
+ }
+}
+
+
+void Int13FilterEntry ()
+{
+ __asm
+ {
+ leave
+ push 0x13
+ jmp IntFilterEntry
+ }
+}
+
+
+static void Int15FilterEntry ()
+{
+ __asm
+ {
+ pushf
+ cmp ax, 0xe820 // Get system memory map
+ je filter
+
+ popf
+ leave
+ jmp cs:OriginalInt15Handler
+
+ filter:
+ leave
+ push 0x15
+ jmp IntFilterEntry
+ }
+}
+
+
+bool InstallInterruptFilters ()
+{
+
+#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+
+ // If the filters have already been installed, it usually indicates stack corruption
+ // and a consequent reentry of this routine without a system reset.
+
+ uint32 currentInt13Handler;
+ CopyMemory (0, 0x13 * 4, &currentInt13Handler, sizeof (currentInt13Handler));
+
+ if (currentInt13Handler == (uint32) Int13FilterEntry)
+ {
+ PrintError ("Memory corrupted");
+ Print (TC_BOOT_STR_UPGRADE_BIOS);
+
+ GetKeyboardChar();
+ return true;
+ }
+
+#endif
+
+ if (!CreateNewBiosMemoryMap())
+ return false;
+
+ __asm
+ {
+ cli
+ push es
+
+ // Save original INT 13 handler
+ xor ax, ax
+ mov es, ax
+
+ mov si, 0x13 * 4
+ lea di, OriginalInt13Handler
+
+ mov ax, es:[si]
+ mov [di], ax
+ mov ax, es:[si + 2]
+ mov [di + 2], ax
+
+ // Install INT 13 filter
+ lea ax, Int13FilterEntry
+ mov es:[si], ax
+ mov es:[si + 2], cs
+
+ // Save original INT 15 handler
+ mov si, 0x15 * 4
+ lea di, OriginalInt15Handler
+
+ mov ax, es:[si]
+ mov [di], ax
+ mov ax, es:[si + 2]
+ mov [di + 2], ax
+
+ // Install INT 15 filter
+ lea ax, Int15FilterEntry
+ mov es:[si], ax
+ mov es:[si + 2], cs
+
+ // If the BIOS does not support system memory map (INT15 0xe820),
+ // set amount of available memory to CS:0000 - 0:0000
+ cmp BiosMemoryMapSize, 1
+ jg mem_map_ok
+ mov ax, cs
+ shr ax, 10 - 4 // CS * 16 / 1024
+ mov es:[0x413], ax // = KBytes available
+ mem_map_ok:
+
+ pop es
+ sti
+ }
+
+ return true;
+}
diff --git a/src/Boot/Windows/IntFilter.h b/src/Boot/Windows/IntFilter.h
index af35480..1ef4251 100644
--- a/src/Boot/Windows/IntFilter.h
+++ b/src/Boot/Windows/IntFilter.h
@@ -1,20 +1,20 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_IntFilter
-#define TC_HEADER_Boot_IntFilter
-
-#include "Platform.h"
-
-bool InstallInterruptFilters ();
-
-#endif TC_HEADER_Boot_IntFilter
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_IntFilter
+#define TC_HEADER_Boot_IntFilter
+
+#include "Platform.h"
+
+bool InstallInterruptFilters ();
+
+#endif TC_HEADER_Boot_IntFilter
diff --git a/src/Boot/Windows/Makefile b/src/Boot/Windows/Makefile
index f985105..65e668c 100644
--- a/src/Boot/Windows/Makefile
+++ b/src/Boot/Windows/Makefile
@@ -1,202 +1,202 @@
-#
-# 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-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.
-
-PROJ = BootLoader
-.SILENT:
-
-!ifndef MSVC16_ROOT
-!error Environment variable MSVC16_ROOT must point to the installation directory of MS Visual C++ 1.5
-!endif
-
-ENVPATH = $(PATH)
-
-CC = $(MSVC16_ROOT)\bin\cl.exe
-LD = $(MSVC16_ROOT)\bin\link.exe
-
-AFLAGS = /nologo /omf
-
-CFLAGS = /nologo /W3 /Fc /I "$(MSVC16_ROOT)\Include" /I"..\..\.." /I"..\..\..\Common" /I"..\..\..\Crypto"
-CFLAGS = $(CFLAGS) /D __int8=char /D __int16=int /D __int32=long /D BOOL=char /D FALSE=0 /D TRUE=1
-CFLAGS = $(CFLAGS) /D LITTLE_ENDIAN=1234 /D BYTE_ORDER=1234 /D TC_WINDOWS_BOOT /D TC_MINIMIZE_CODE_SIZE /D TC_NO_COMPILER_INT64
-CFLAGS = $(CFLAGS) /D malloc=malloc_NA
-
-LFLAGS = /NOLOGO /ONERROR:NOEXE /NOI /BATCH
-
-OBJDIR = Release
-
-!ifdef RESCUE_DISK
-OBJDIR = Rescue
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RESCUE_DISK_MODE
-!endif
-
-!ifdef SINGLE_CIPHER
-OBJDIR = $(OBJDIR)_$(SINGLE_CIPHER)
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER)
-!endif
-
-!ifdef SINGLE_PRF
-OBJDIR = $(OBJDIR)_$(SINGLE_PRF)
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_$(SINGLE_PRF)
-!else
-CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RIPEMD160
-!endif
-
-OUTDIR = $(OBJDIR)
-TARGETEXT = com
-TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com
-CFLAGS = $(CFLAGS) /AT /Zl /f- /G3 /Oe /Os /Ob1 /OV0 /Gs /Gf /Gy /D NDEBUG
-LFLAGS = $(LFLAGS) /NOD /NOE /TINY
-OBJS = $(OUTDIR)\BootCrt.obj
-LIBS = slibce
-
-!if 1
-SRCDIR = ..
-!else
-SRCDIR = $(MAKEDIR)
-!endif
-
-TARGETS = $(TARGETS) $(OUTDIR)\$(PROJ).$(TARGETEXT)
-
-OBJS = $(OBJS) $(OUTDIR)\BootConfig.obj
-OBJS = $(OBJS) $(OUTDIR)\BootConsoleIo.obj
-OBJS = $(OBJS) $(OUTDIR)\BootDebug.obj
-OBJS = $(OBJS) $(OUTDIR)\BootDiskIo.obj
-OBJS = $(OBJS) $(OUTDIR)\BootEncryptedIo.obj
-OBJS = $(OBJS) $(OUTDIR)\BootMain.obj
-OBJS = $(OBJS) $(OUTDIR)\BootMemory.obj
-OBJS = $(OBJS) $(OUTDIR)\IntFilter.obj
-OBJS = $(OBJS) $(OUTDIR)\Platform.obj
-
-OBJS = $(OBJS) $(OUTDIR)\Crc.obj
-OBJS = $(OBJS) $(OUTDIR)\Crypto.obj
-OBJS = $(OBJS) $(OUTDIR)\Endian.obj
-OBJS = $(OBJS) $(OUTDIR)\Pkcs5.obj
-OBJS = $(OBJS) $(OUTDIR)\Volumes.obj
-OBJS = $(OBJS) $(OUTDIR)\Xts.obj
-
-!if "$(SINGLE_PRF)" == "SHA2"
-OBJS = $(OBJS) $(OUTDIR)\Sha2Small.obj
-!else
-OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj
-!endif
-
-!if !DEFINED (SINGLE_CIPHER)
-OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj
-!else if "$(SINGLE_CIPHER)" == "AES"
-OBJS = $(OBJS) $(OUTDIR)\Aes_hw_cpu.obj
-OBJS = $(OBJS) $(OUTDIR)\AesSmall_x86.obj
-OBJS = $(OBJS) $(OUTDIR)\Aestab.obj
-!endif
-
-!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "SERPENT"
-OBJS = $(OBJS) $(OUTDIR)\Serpent.obj
-!endif
-
-!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "TWOFISH"
-OBJS = $(OBJS) $(OUTDIR)\Twofish.obj
-!endif
-
-
-all: env $(TARGETS)
-
-env:
- set INCLUDE=.
- set LIB=.
- set LIBPATH=.
-
-clean:
- -del /q /s $(OBJDIR) >NUL:
-
-
-.asm{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- $(AS) $(AFLAGS) /c "$(SRCDIR)\$<"
- cd ..
-
-{..\..\Crypto}.asm{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- echo $(<F)
- nasm.exe -Xvc -f obj -Ox -o "$(<B).obj" -l "$(<B).lst" "$(SRCDIR)\$<"
- cd ..
-
-{..\..\Crypto}.c{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-{..\..\Common}.c{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-.c{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-.cpp{$(OUTDIR)}.obj:
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
- set PATH=$(ENVPATH)
- cd ..
-
-$(OUTDIR)\BootDefs.i: BootDefs.h
- cd $(OBJDIR)
- set PATH=.
- $(CC) $(CFLAGS) /D TC_ASM_PREPROCESS /P /EP "$(SRCDIR)\BootDefs.h"
- set PATH=$(ENVPATH)
- cd ..
-
-$(OUTDIR)\BootSector.bin: $(OUTDIR)\BootSector.obj
- cd $(OBJDIR)
- $(LD) $(LFLAGS) BootSector.obj,BootSector.bin,,,, >NUL:
- -dd.exe conv=notrunc bs=512 if=BootSector.bin of=$(PROJ).flp 2>NUL:
- cd ..
-
-$(OUTDIR)\Decompressor.com: $(OUTDIR)\BootCrt.obj $(OUTDIR)\Decompressor.obj
- cd $(OBJDIR)
- $(LD) $(LFLAGS) BootCrt.obj Decompressor.obj,Decompressor.com,Decompressor.map,$(MSVC16_ROOT)\lib\+slibce,,
- -dd.exe conv=notrunc,sync bs=512 seek=1 if=Decompressor.com of=$(PROJ).flp 2>NUL:
- cd ..
-
-$(OUTDIR)\$(PROJ).$(TARGETEXT): $(OBJS)
- @echo Linking...
- cd $(OBJDIR)
-
- echo >NUL: @<<$(PROJ).crf2
-
-$(PROJ).$(TARGETEXT)
-$(PROJ).map
-$(MSVC16_ROOT)\lib\+
-$(LIBS)
-;
-<<
- del $(PROJ).crf >NUL: 2>NUL:
- for %F in ($(**F)) do @echo %F + >>$(PROJ).crf
- type $(PROJ).crf2 >>$(PROJ).crf
-
- $(LD) $(LFLAGS) @$(PROJ).crf
- del $(PROJ).crf $(PROJ).crf2
-
-# Compress the Rescue Disk botloader for Cascades and Serpent since it is too big (size > 31232 bytes)
-!if DEFINED(RESCUE_DISK) && (!DEFINED (SINGLE_CIPHER) || ("$(SINGLE_CIPHER)" == "SERPENT"))
- upx $(PROJ).$(TARGETEXT)
-!endif
- gzip.exe -c -n --best $(PROJ).$(TARGETEXT) >$(PROJ).$(TARGETEXT).gz
- -dd.exe conv=notrunc,sync bs=512 seek=5 if=$(PROJ).$(TARGETEXT).gz of=$(PROJ).flp 2>NUL:
- cd ..
+#
+# 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-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.
+
+PROJ = BootLoader
+.SILENT:
+
+!ifndef MSVC16_ROOT
+!error Environment variable MSVC16_ROOT must point to the installation directory of MS Visual C++ 1.5
+!endif
+
+ENVPATH = $(PATH)
+
+CC = $(MSVC16_ROOT)\bin\cl.exe
+LD = $(MSVC16_ROOT)\bin\link.exe
+
+AFLAGS = /nologo /omf
+
+CFLAGS = /nologo /W3 /Fc /I "$(MSVC16_ROOT)\Include" /I"..\..\.." /I"..\..\..\Common" /I"..\..\..\Crypto"
+CFLAGS = $(CFLAGS) /D __int8=char /D __int16=int /D __int32=long /D BOOL=char /D FALSE=0 /D TRUE=1
+CFLAGS = $(CFLAGS) /D LITTLE_ENDIAN=1234 /D BYTE_ORDER=1234 /D TC_WINDOWS_BOOT /D TC_MINIMIZE_CODE_SIZE /D TC_NO_COMPILER_INT64
+CFLAGS = $(CFLAGS) /D malloc=malloc_NA
+
+LFLAGS = /NOLOGO /ONERROR:NOEXE /NOI /BATCH
+
+OBJDIR = Release
+
+!ifdef RESCUE_DISK
+OBJDIR = Rescue
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RESCUE_DISK_MODE
+!endif
+
+!ifdef SINGLE_CIPHER
+OBJDIR = $(OBJDIR)_$(SINGLE_CIPHER)
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE /D TC_WINDOWS_BOOT_$(SINGLE_CIPHER)
+!endif
+
+!ifdef SINGLE_PRF
+OBJDIR = $(OBJDIR)_$(SINGLE_PRF)
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_$(SINGLE_PRF)
+!else
+CFLAGS = $(CFLAGS) /D TC_WINDOWS_BOOT_RIPEMD160
+!endif
+
+OUTDIR = $(OBJDIR)
+TARGETEXT = com
+TARGETS = $(OUTDIR)\BootDefs.i $(OUTDIR)\BootSector.bin $(OUTDIR)\Decompressor.com
+CFLAGS = $(CFLAGS) /AT /Zl /f- /G3 /Oe /Os /Ob1 /OV0 /Gs /Gf /Gy /D NDEBUG
+LFLAGS = $(LFLAGS) /NOD /NOE /TINY
+OBJS = $(OUTDIR)\BootCrt.obj
+LIBS = slibce
+
+!if 1
+SRCDIR = ..
+!else
+SRCDIR = $(MAKEDIR)
+!endif
+
+TARGETS = $(TARGETS) $(OUTDIR)\$(PROJ).$(TARGETEXT)
+
+OBJS = $(OBJS) $(OUTDIR)\BootConfig.obj
+OBJS = $(OBJS) $(OUTDIR)\BootConsoleIo.obj
+OBJS = $(OBJS) $(OUTDIR)\BootDebug.obj
+OBJS = $(OBJS) $(OUTDIR)\BootDiskIo.obj
+OBJS = $(OBJS) $(OUTDIR)\BootEncryptedIo.obj
+OBJS = $(OBJS) $(OUTDIR)\BootMain.obj
+OBJS = $(OBJS) $(OUTDIR)\BootMemory.obj
+OBJS = $(OBJS) $(OUTDIR)\IntFilter.obj
+OBJS = $(OBJS) $(OUTDIR)\Platform.obj
+
+OBJS = $(OBJS) $(OUTDIR)\Crc.obj
+OBJS = $(OBJS) $(OUTDIR)\Crypto.obj
+OBJS = $(OBJS) $(OUTDIR)\Endian.obj
+OBJS = $(OBJS) $(OUTDIR)\Pkcs5.obj
+OBJS = $(OBJS) $(OUTDIR)\Volumes.obj
+OBJS = $(OBJS) $(OUTDIR)\Xts.obj
+
+!if "$(SINGLE_PRF)" == "SHA2"
+OBJS = $(OBJS) $(OUTDIR)\Sha2Small.obj
+!else
+OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj
+!endif
+
+!if !DEFINED (SINGLE_CIPHER)
+OBJS = $(OBJS) $(OUTDIR)\AesSmall.obj
+!else if "$(SINGLE_CIPHER)" == "AES"
+OBJS = $(OBJS) $(OUTDIR)\Aes_hw_cpu.obj
+OBJS = $(OBJS) $(OUTDIR)\AesSmall_x86.obj
+OBJS = $(OBJS) $(OUTDIR)\Aestab.obj
+!endif
+
+!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "SERPENT"
+OBJS = $(OBJS) $(OUTDIR)\Serpent.obj
+!endif
+
+!if !DEFINED (SINGLE_CIPHER) || "$(SINGLE_CIPHER)" == "TWOFISH"
+OBJS = $(OBJS) $(OUTDIR)\Twofish.obj
+!endif
+
+
+all: env $(TARGETS)
+
+env:
+ set INCLUDE=.
+ set LIB=.
+ set LIBPATH=.
+
+clean:
+ -del /q /s $(OBJDIR) >NUL:
+
+
+.asm{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ $(AS) $(AFLAGS) /c "$(SRCDIR)\$<"
+ cd ..
+
+{..\..\Crypto}.asm{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ echo $(<F)
+ nasm.exe -Xvc -f obj -Ox -o "$(<B).obj" -l "$(<B).lst" "$(SRCDIR)\$<"
+ cd ..
+
+{..\..\Crypto}.c{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+{..\..\Common}.c{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+.c{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+.cpp{$(OUTDIR)}.obj:
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /c "$(SRCDIR)\$<"
+ set PATH=$(ENVPATH)
+ cd ..
+
+$(OUTDIR)\BootDefs.i: BootDefs.h
+ cd $(OBJDIR)
+ set PATH=.
+ $(CC) $(CFLAGS) /D TC_ASM_PREPROCESS /P /EP "$(SRCDIR)\BootDefs.h"
+ set PATH=$(ENVPATH)
+ cd ..
+
+$(OUTDIR)\BootSector.bin: $(OUTDIR)\BootSector.obj
+ cd $(OBJDIR)
+ $(LD) $(LFLAGS) BootSector.obj,BootSector.bin,,,, >NUL:
+ -dd.exe conv=notrunc bs=512 if=BootSector.bin of=$(PROJ).flp 2>NUL:
+ cd ..
+
+$(OUTDIR)\Decompressor.com: $(OUTDIR)\BootCrt.obj $(OUTDIR)\Decompressor.obj
+ cd $(OBJDIR)
+ $(LD) $(LFLAGS) BootCrt.obj Decompressor.obj,Decompressor.com,Decompressor.map,$(MSVC16_ROOT)\lib\+slibce,,
+ -dd.exe conv=notrunc,sync bs=512 seek=1 if=Decompressor.com of=$(PROJ).flp 2>NUL:
+ cd ..
+
+$(OUTDIR)\$(PROJ).$(TARGETEXT): $(OBJS)
+ @echo Linking...
+ cd $(OBJDIR)
+
+ echo >NUL: @<<$(PROJ).crf2
+
+$(PROJ).$(TARGETEXT)
+$(PROJ).map
+$(MSVC16_ROOT)\lib\+
+$(LIBS)
+;
+<<
+ del $(PROJ).crf >NUL: 2>NUL:
+ for %F in ($(**F)) do @echo %F + >>$(PROJ).crf
+ type $(PROJ).crf2 >>$(PROJ).crf
+
+ $(LD) $(LFLAGS) @$(PROJ).crf
+ del $(PROJ).crf $(PROJ).crf2
+
+# Compress the Rescue Disk botloader for Cascades and Serpent since it is too big (size > 31232 bytes)
+!if DEFINED(RESCUE_DISK) && (!DEFINED (SINGLE_CIPHER) || ("$(SINGLE_CIPHER)" == "SERPENT"))
+ upx $(PROJ).$(TARGETEXT)
+!endif
+ gzip.exe -c -n --best $(PROJ).$(TARGETEXT) >$(PROJ).$(TARGETEXT).gz
+ -dd.exe conv=notrunc,sync bs=512 seek=5 if=$(PROJ).$(TARGETEXT).gz of=$(PROJ).flp 2>NUL:
+ cd ..
diff --git a/src/Boot/Windows/Platform.cpp b/src/Boot/Windows/Platform.cpp
index d9819cf..316e71b 100644
--- a/src/Boot/Windows/Platform.cpp
+++ b/src/Boot/Windows/Platform.cpp
@@ -1,230 +1,230 @@
-/*
- 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-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 "Platform.h"
-#include "BootConsoleIo.h"
-
-
-uint64 operator+ (const uint64 &a, const uint64 &b)
-{
- int carry = 0;
- uint64 r;
-
- r.LowPart = a.LowPart + b.LowPart;
- __asm
- {
- jnc nocarry
- mov carry, 1
- nocarry:
- }
-
- r.HighPart = a.HighPart + b.HighPart + carry;
-
- return r;
-}
-
-uint64 operator+ (const uint64 &a, uint32 b)
-{
- uint64 b64;
- b64.HighPart = 0;
- b64.LowPart = b;
- return a + b64;
-}
-
-uint64 &operator+= (uint64 &a, const uint64 &b)
-{
- return a = a + b;
-}
-
-uint64 operator- (const uint64 &a, const uint64 &b)
-{
- int carry = 0;
- uint64 r;
-
- r.LowPart = a.LowPart - b.LowPart;
- __asm
- {
- jnc nocarry
- mov carry, 1
- nocarry:
- }
-
- r.HighPart = a.HighPart - b.HighPart - carry;
-
- return r;
-}
-
-uint64 operator- (const uint64 &a, uint32 b)
-{
- uint64 b64;
- b64.HighPart = 0;
- b64.LowPart = b;
- return a - b64;
-}
-
-uint64 &operator-= (uint64 &a, const uint64 &b)
-{
- return a = a - b;
-}
-
-uint64 operator>> (const uint64 &a, int shiftCount)
-{
- uint64 r = a;
-
- while (shiftCount--)
- {
- r.LowPart >>= 1;
-
- if ((byte) r.HighPart & 1)
- r.LowPart |= 0x80000000UL;
-
- r.HighPart >>= 1;
- }
-
- return r;
-}
-
-uint64 operator<< (const uint64 &a, int shiftCount)
-{
- uint64 r = a;
-
- while (shiftCount--)
- r += r;
-
- return r;
-}
-
-uint64 &operator++ (uint64 &a)
-{
- uint64 b;
- b.HighPart = 0;
- b.LowPart = 1;
-
- return a += b;
-}
-
-bool operator== (const uint64 &a, const uint64 &b)
-{
- return a.HighPart == b.HighPart && a.LowPart == b.LowPart;
-}
-
-bool operator> (const uint64 &a, const uint64 &b)
-{
- return (a.HighPart > b.HighPart) || (a.HighPart == b.HighPart && a.LowPart > b.LowPart);
-}
-
-bool operator< (const uint64 &a, const uint64 &b)
-{
- return (a.HighPart < b.HighPart) || (a.HighPart == b.HighPart && a.LowPart < b.LowPart);
-}
-
-bool operator>= (const uint64 &a, const uint64 &b)
-{
- return a > b || a == b;
-}
-
-bool operator<= (const uint64 &a, const uint64 &b)
-{
- return a < b || a == b;
-}
-
-bool TestInt64 ()
-{
- uint64 a, b, c;
- a.HighPart = 0x00112233UL;
- a.LowPart = 0xabcd1234UL;
-
- b.HighPart = 0x00ffeeddUL;
- b.LowPart = 0xffffFFFFUL;
-
- a += b;
- a -= b;
-
- ++a;
-
- b = b + (uint32) 1UL;
-
- c = (a - ((a + b) >> 32) - (uint32) 1UL);
- if (c.HighPart != 0x112233UL || c.LowPart != 0xAABC0123UL)
- return false;
-
- c = c << 9;
- return c.HighPart == 0x22446755UL && c.LowPart == 0x78024600UL;
-}
-
-
-void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize)
-{
- __asm
- {
- push es
- mov si, ss:source
- mov es, ss:destSegment
- mov di, ss:destOffset
- mov cx, ss:blockSize
- cld
- rep movsb
- pop es
- }
-}
-
-
-void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize)
-{
- __asm
- {
- push ds
- push es
- mov ax, ds
- mov es, ax
- mov di, ss:destination
- mov si, ss:sourceOffset
- mov cx, ss:blockSize
- mov ds, ss:sourceSegment
- cld
- rep movsb
- pop es
- pop ds
- }
-}
-
-
-void EraseMemory (void *memory, int size)
-{
- memset (memory, 0, size);
-}
-
-
-uint32 GetLinearAddress (uint16 segment, uint16 offset)
-{
- return (uint32 (segment) << 4) + offset;
-}
-
-
-bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2)
-{
- uint64 end1 = start1 + length1 - 1UL;
- uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
-
- uint64 intersectStart = (start1 >= start2) ? start1 : start2;
- if (intersectStart > intersectEnd)
- return false;
-
- return (intersectEnd + 1UL - intersectStart).LowPart != 0;
-}
-
-
-void ThrowFatalException (int line)
-{
- PrintChar ('#'); Print (line);
- while (1);
-}
+/*
+ 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-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 "Platform.h"
+#include "BootConsoleIo.h"
+
+
+uint64 operator+ (const uint64 &a, const uint64 &b)
+{
+ int carry = 0;
+ uint64 r;
+
+ r.LowPart = a.LowPart + b.LowPart;
+ __asm
+ {
+ jnc nocarry
+ mov carry, 1
+ nocarry:
+ }
+
+ r.HighPart = a.HighPart + b.HighPart + carry;
+
+ return r;
+}
+
+uint64 operator+ (const uint64 &a, uint32 b)
+{
+ uint64 b64;
+ b64.HighPart = 0;
+ b64.LowPart = b;
+ return a + b64;
+}
+
+uint64 &operator+= (uint64 &a, const uint64 &b)
+{
+ return a = a + b;
+}
+
+uint64 operator- (const uint64 &a, const uint64 &b)
+{
+ int carry = 0;
+ uint64 r;
+
+ r.LowPart = a.LowPart - b.LowPart;
+ __asm
+ {
+ jnc nocarry
+ mov carry, 1
+ nocarry:
+ }
+
+ r.HighPart = a.HighPart - b.HighPart - carry;
+
+ return r;
+}
+
+uint64 operator- (const uint64 &a, uint32 b)
+{
+ uint64 b64;
+ b64.HighPart = 0;
+ b64.LowPart = b;
+ return a - b64;
+}
+
+uint64 &operator-= (uint64 &a, const uint64 &b)
+{
+ return a = a - b;
+}
+
+uint64 operator>> (const uint64 &a, int shiftCount)
+{
+ uint64 r = a;
+
+ while (shiftCount--)
+ {
+ r.LowPart >>= 1;
+
+ if ((byte) r.HighPart & 1)
+ r.LowPart |= 0x80000000UL;
+
+ r.HighPart >>= 1;
+ }
+
+ return r;
+}
+
+uint64 operator<< (const uint64 &a, int shiftCount)
+{
+ uint64 r = a;
+
+ while (shiftCount--)
+ r += r;
+
+ return r;
+}
+
+uint64 &operator++ (uint64 &a)
+{
+ uint64 b;
+ b.HighPart = 0;
+ b.LowPart = 1;
+
+ return a += b;
+}
+
+bool operator== (const uint64 &a, const uint64 &b)
+{
+ return a.HighPart == b.HighPart && a.LowPart == b.LowPart;
+}
+
+bool operator> (const uint64 &a, const uint64 &b)
+{
+ return (a.HighPart > b.HighPart) || (a.HighPart == b.HighPart && a.LowPart > b.LowPart);
+}
+
+bool operator< (const uint64 &a, const uint64 &b)
+{
+ return (a.HighPart < b.HighPart) || (a.HighPart == b.HighPart && a.LowPart < b.LowPart);
+}
+
+bool operator>= (const uint64 &a, const uint64 &b)
+{
+ return a > b || a == b;
+}
+
+bool operator<= (const uint64 &a, const uint64 &b)
+{
+ return a < b || a == b;
+}
+
+bool TestInt64 ()
+{
+ uint64 a, b, c;
+ a.HighPart = 0x00112233UL;
+ a.LowPart = 0xabcd1234UL;
+
+ b.HighPart = 0x00ffeeddUL;
+ b.LowPart = 0xffffFFFFUL;
+
+ a += b;
+ a -= b;
+
+ ++a;
+
+ b = b + (uint32) 1UL;
+
+ c = (a - ((a + b) >> 32) - (uint32) 1UL);
+ if (c.HighPart != 0x112233UL || c.LowPart != 0xAABC0123UL)
+ return false;
+
+ c = c << 9;
+ return c.HighPart == 0x22446755UL && c.LowPart == 0x78024600UL;
+}
+
+
+void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize)
+{
+ __asm
+ {
+ push es
+ mov si, ss:source
+ mov es, ss:destSegment
+ mov di, ss:destOffset
+ mov cx, ss:blockSize
+ cld
+ rep movsb
+ pop es
+ }
+}
+
+
+void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize)
+{
+ __asm
+ {
+ push ds
+ push es
+ mov ax, ds
+ mov es, ax
+ mov di, ss:destination
+ mov si, ss:sourceOffset
+ mov cx, ss:blockSize
+ mov ds, ss:sourceSegment
+ cld
+ rep movsb
+ pop es
+ pop ds
+ }
+}
+
+
+void EraseMemory (void *memory, int size)
+{
+ memset (memory, 0, size);
+}
+
+
+uint32 GetLinearAddress (uint16 segment, uint16 offset)
+{
+ return (uint32 (segment) << 4) + offset;
+}
+
+
+bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2)
+{
+ uint64 end1 = start1 + length1 - 1UL;
+ uint64 intersectEnd = (end1 <= end2) ? end1 : end2;
+
+ uint64 intersectStart = (start1 >= start2) ? start1 : start2;
+ if (intersectStart > intersectEnd)
+ return false;
+
+ return (intersectEnd + 1UL - intersectStart).LowPart != 0;
+}
+
+
+void ThrowFatalException (int line)
+{
+ PrintChar ('#'); Print (line);
+ while (1);
+}
diff --git a/src/Boot/Windows/Platform.h b/src/Boot/Windows/Platform.h
index 2fa532c..879b1c3 100644
--- a/src/Boot/Windows/Platform.h
+++ b/src/Boot/Windows/Platform.h
@@ -1,116 +1,116 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Boot_Platform
-#define TC_HEADER_Boot_Platform
-
-#pragma warning (disable: 4018 4102 4704 4769)
-
-#include "TCdefs.h"
-#include <memory.h>
-
-typedef char bool;
-#define false 0
-#define true 1
-
-#define nullptr 0
-#define NULL 0
-
-typedef UINT64_STRUCT uint64;
-
-#define array_capacity(arr) (sizeof (arr) / sizeof ((arr)[0]))
-
-#define TC_TO_STRING2(n) #n
-#define TC_TO_STRING(n) TC_TO_STRING2(n)
-
-
-#define TC_X86_CARRY_FLAG 0x1
-
-#define TC_ASM_EMIT(A,B) __asm _emit 0x##A __asm _emit 0x##B
-#define TC_ASM_EMIT3(A,B,C) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C
-#define TC_ASM_EMIT4(A,B,C,D) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C __asm _emit 0x##D
-
-#define TC_ASM_MOV_EAX_DI TC_ASM_EMIT3 (66, 8B, 05)
-#define TC_ASM_MOV_EBX_DI TC_ASM_EMIT3 (66, 8B, 1D)
-#define TC_ASM_MOV_ECX_DI TC_ASM_EMIT3 (66, 8B, 0D)
-#define TC_ASM_MOV_EDX_DI TC_ASM_EMIT3 (66, 8B, 15)
-
-#define TC_ASM_MOV_DI_EAX TC_ASM_EMIT3 (66, 89, 05)
-#define TC_ASM_MOV_DI_EBX TC_ASM_EMIT3 (66, 89, 1D)
-#define TC_ASM_MOV_DI_ECX TC_ASM_EMIT3 (66, 89, 0D)
-#define TC_ASM_MOV_DI_EDX TC_ASM_EMIT3 (66, 89, 15)
-
-
-#pragma pack(1)
-
-struct Registers
-{
- uint16 Flags;
-
- union
- {
- uint32 EAX;
- struct { uint16 AX; uint16 EAXH; };
- };
-
- union
- {
- uint32 EBX;
- struct { uint16 BX; uint16 EBXH; };
- };
-
- union
- {
- uint32 ECX;
- struct { uint16 CX; uint16 ECXH; };
- };
-
- union
- {
- uint32 EDX;
- struct { uint16 DX; uint16 EDXH; };
- };
-
- uint16 DI;
- uint16 SI;
- uint16 DS;
- uint16 ES;
- uint16 SS;
-};
-
-#pragma pack()
-
-
-uint64 operator+ (const uint64 &a, const uint64 &b);
-uint64 operator+ (const uint64 &a, uint32 b);
-uint64 &operator+= (uint64 &a, const uint64 &b);
-uint64 operator- (const uint64 &a, const uint64 &b);
-uint64 operator- (const uint64 &a, uint32 b);
-uint64 &operator-= (uint64 &a, const uint64 &b);
-uint64 operator>> (const uint64 &a, int shiftCount);
-uint64 operator<< (const uint64 &a, int shiftCount);
-uint64 &operator++ (uint64 &a);
-bool operator== (const uint64 &a, const uint64 &b);
-bool operator> (const uint64 &a, const uint64 &b);
-bool operator< (const uint64 &a, const uint64 &b);
-bool operator>= (const uint64 &a, const uint64 &b);
-bool operator<= (const uint64 &a, const uint64 &b);
-
-void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize);
-void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize);
-extern "C" void EraseMemory (void *memory, int size);
-uint32 GetLinearAddress (uint16 segment, uint16 offset);
-bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2);
-bool TestInt64 ();
-extern "C" void ThrowFatalException (int line);
-
-#endif // TC_HEADER_Boot_Platform
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Boot_Platform
+#define TC_HEADER_Boot_Platform
+
+#pragma warning (disable: 4018 4102 4704 4769)
+
+#include "TCdefs.h"
+#include <memory.h>
+
+typedef char bool;
+#define false 0
+#define true 1
+
+#define nullptr 0
+#define NULL 0
+
+typedef UINT64_STRUCT uint64;
+
+#define array_capacity(arr) (sizeof (arr) / sizeof ((arr)[0]))
+
+#define TC_TO_STRING2(n) #n
+#define TC_TO_STRING(n) TC_TO_STRING2(n)
+
+
+#define TC_X86_CARRY_FLAG 0x1
+
+#define TC_ASM_EMIT(A,B) __asm _emit 0x##A __asm _emit 0x##B
+#define TC_ASM_EMIT3(A,B,C) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C
+#define TC_ASM_EMIT4(A,B,C,D) __asm _emit 0x##A __asm _emit 0x##B __asm _emit 0x##C __asm _emit 0x##D
+
+#define TC_ASM_MOV_EAX_DI TC_ASM_EMIT3 (66, 8B, 05)
+#define TC_ASM_MOV_EBX_DI TC_ASM_EMIT3 (66, 8B, 1D)
+#define TC_ASM_MOV_ECX_DI TC_ASM_EMIT3 (66, 8B, 0D)
+#define TC_ASM_MOV_EDX_DI TC_ASM_EMIT3 (66, 8B, 15)
+
+#define TC_ASM_MOV_DI_EAX TC_ASM_EMIT3 (66, 89, 05)
+#define TC_ASM_MOV_DI_EBX TC_ASM_EMIT3 (66, 89, 1D)
+#define TC_ASM_MOV_DI_ECX TC_ASM_EMIT3 (66, 89, 0D)
+#define TC_ASM_MOV_DI_EDX TC_ASM_EMIT3 (66, 89, 15)
+
+
+#pragma pack(1)
+
+struct Registers
+{
+ uint16 Flags;
+
+ union
+ {
+ uint32 EAX;
+ struct { uint16 AX; uint16 EAXH; };
+ };
+
+ union
+ {
+ uint32 EBX;
+ struct { uint16 BX; uint16 EBXH; };
+ };
+
+ union
+ {
+ uint32 ECX;
+ struct { uint16 CX; uint16 ECXH; };
+ };
+
+ union
+ {
+ uint32 EDX;
+ struct { uint16 DX; uint16 EDXH; };
+ };
+
+ uint16 DI;
+ uint16 SI;
+ uint16 DS;
+ uint16 ES;
+ uint16 SS;
+};
+
+#pragma pack()
+
+
+uint64 operator+ (const uint64 &a, const uint64 &b);
+uint64 operator+ (const uint64 &a, uint32 b);
+uint64 &operator+= (uint64 &a, const uint64 &b);
+uint64 operator- (const uint64 &a, const uint64 &b);
+uint64 operator- (const uint64 &a, uint32 b);
+uint64 &operator-= (uint64 &a, const uint64 &b);
+uint64 operator>> (const uint64 &a, int shiftCount);
+uint64 operator<< (const uint64 &a, int shiftCount);
+uint64 &operator++ (uint64 &a);
+bool operator== (const uint64 &a, const uint64 &b);
+bool operator> (const uint64 &a, const uint64 &b);
+bool operator< (const uint64 &a, const uint64 &b);
+bool operator>= (const uint64 &a, const uint64 &b);
+bool operator<= (const uint64 &a, const uint64 &b);
+
+void CopyMemory (void *source, uint16 destSegment, uint16 destOffset, uint16 blockSize);
+void CopyMemory (uint16 sourceSegment, uint16 sourceOffset, void *destination, uint16 blockSize);
+extern "C" void EraseMemory (void *memory, int size);
+uint32 GetLinearAddress (uint16 segment, uint16 offset);
+bool RegionsIntersect (const uint64 &start1, uint32 length1, const uint64 &start2, const uint64 &end2);
+bool TestInt64 ();
+extern "C" void ThrowFatalException (int line);
+
+#endif // TC_HEADER_Boot_Platform
diff --git a/src/Build/Tools/MacOSX/nasm b/src/Build/Tools/MacOSX/nasm
index 7d2c38a..62a6702 100755
--- a/src/Build/Tools/MacOSX/nasm
+++ b/src/Build/Tools/MacOSX/nasm
Binary files differ
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h
index f584582..5ea8977 100644
--- a/src/Common/Apidrvr.h
+++ b/src/Common/Apidrvr.h
@@ -1,344 +1,344 @@
-/*
- 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-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. */
-
-#pragma once
-
-#include "Tcdefs.h"
-#include "Boot/Windows/BootDefs.h"
-#include "Common.h"
-#include "Crypto.h"
-#include "Volumes.h"
-#include "Wipe.h"
-
-#ifdef _WIN32
-
-/* WARNING: Modifying the following values or their meanings can introduce incompatibility with previous versions. */
-
-#define TC_IOCTL(CODE) (CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800 + (CODE), METHOD_BUFFERED, FILE_ANY_ACCESS))
-
-#define TC_IOCTL_GET_DRIVER_VERSION TC_IOCTL (1)
-#define TC_IOCTL_GET_BOOT_LOADER_VERSION TC_IOCTL (2)
-#define TC_IOCTL_MOUNT_VOLUME TC_IOCTL (3)
-#define TC_IOCTL_DISMOUNT_VOLUME TC_IOCTL (4)
-#define TC_IOCTL_DISMOUNT_ALL_VOLUMES TC_IOCTL (5)
-#define TC_IOCTL_GET_MOUNTED_VOLUMES TC_IOCTL (6)
-#define TC_IOCTL_GET_VOLUME_PROPERTIES TC_IOCTL (7)
-#define TC_IOCTL_GET_DEVICE_REFCOUNT TC_IOCTL (8)
-#define TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED TC_IOCTL (9)
-#define TC_IOCTL_IS_ANY_VOLUME_MOUNTED TC_IOCTL (10)
-#define TC_IOCTL_GET_PASSWORD_CACHE_STATUS TC_IOCTL (11)
-#define TC_IOCTL_WIPE_PASSWORD_CACHE TC_IOCTL (12)
-#define TC_IOCTL_OPEN_TEST TC_IOCTL (13)
-#define TC_IOCTL_GET_DRIVE_PARTITION_INFO TC_IOCTL (14)
-#define TC_IOCTL_GET_DRIVE_GEOMETRY TC_IOCTL (15)
-#define TC_IOCTL_PROBE_REAL_DRIVE_SIZE TC_IOCTL (16)
-#define TC_IOCTL_GET_RESOLVED_SYMLINK TC_IOCTL (17)
-#define TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS TC_IOCTL (18)
-#define TC_IOCTL_BOOT_ENCRYPTION_SETUP TC_IOCTL (19)
-#define TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP TC_IOCTL (20)
-#define TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT TC_IOCTL (21)
-#define TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES TC_IOCTL (22)
-#define TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER TC_IOCTL (23)
-#define TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME TC_IOCTL (24)
-#define TC_IOCTL_GET_PORTABLE_MODE_STATUS TC_IOCTL (25)
-#define TC_IOCTL_SET_PORTABLE_MODE_STATUS TC_IOCTL (26)
-#define TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING TC_IOCTL (27)
-#define TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG TC_IOCTL (28)
-#define TC_IOCTL_DISK_IS_WRITABLE TC_IOCTL (29)
-#define TC_IOCTL_START_DECOY_SYSTEM_WIPE TC_IOCTL (30)
-#define TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE TC_IOCTL (31)
-#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS TC_IOCTL (32)
-#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT TC_IOCTL (33)
-#define TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR TC_IOCTL (34)
-#define TC_IOCTL_GET_WARNING_FLAGS TC_IOCTL (35)
-#define TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY TC_IOCTL (36)
-#define TC_IOCTL_REREAD_DRIVER_CONFIG TC_IOCTL (37)
-#define TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG TC_IOCTL (38)
-#define VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT TC_IOCTL (39)
-
-// Legacy IOCTLs used before version 5.0
-#define TC_IOCTL_LEGACY_GET_DRIVER_VERSION 466968
-#define TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES 466948
-
-
-/* Start of driver interface structures, the size of these structures may
- change between versions; so make sure you first send DRIVER_VERSION to
- check that it's the correct device driver */
-
-#pragma pack (push)
-#pragma pack(1)
-
-typedef struct
-{
- int nReturnCode; /* Return code back from driver */
- BOOL FilesystemDirty;
- BOOL VolumeMountedReadOnlyAfterAccessDenied;
- BOOL VolumeMountedReadOnlyAfterDeviceWriteProtected;
-
- wchar_t wszVolume[TC_MAX_PATH]; /* Volume to be mounted */
- Password VolumePassword; /* User password */
- BOOL bCache; /* Cache passwords in driver */
- int nDosDriveNo; /* Drive number to mount */
- uint32 BytesPerSector;
- BOOL bMountReadOnly; /* Mount volume in read-only mode */
- BOOL bMountRemovable; /* Mount volume as removable media */
- BOOL bExclusiveAccess; /* Open host file/device in exclusive access mode */
- BOOL bMountManager; /* Announce volume to mount manager */
- BOOL bPreserveTimestamp; /* Preserve file container timestamp */
- BOOL bPartitionInInactiveSysEncScope; /* If TRUE, we are to attempt to mount a partition located on an encrypted system drive without pre-boot authentication. */
- int nPartitionInInactiveSysEncScopeDriveNo; /* If bPartitionInInactiveSysEncScope is TRUE, this contains the drive number of the system drive on which the partition is located. */
- BOOL SystemFavorite;
- // Hidden volume protection
- BOOL bProtectHiddenVolume; /* TRUE if the user wants the hidden volume within this volume to be protected against being overwritten (damaged) */
- Password ProtectedHidVolPassword; /* Password to the hidden volume to be protected against overwriting */
- BOOL UseBackupHeader;
- BOOL RecoveryMode;
- int pkcs5_prf;
- int ProtectedHidVolPkcs5Prf;
- BOOL bTrueCryptMode;
- uint32 BytesPerPhysicalSector;
- int VolumePim;
- int ProtectedHidVolPim;
- wchar_t wszLabel[33]; // maximum label length is 32 for NTFS and 11 for FAT32
- BOOL bIsNTFS; // output only
- BOOL bDriverSetLabel;
- BOOL bCachePim;
-} MOUNT_STRUCT;
-
-typedef struct
-{
- int nDosDriveNo; /* Drive letter to unmount */
- BOOL ignoreOpenFiles;
- BOOL HiddenVolumeProtectionTriggered;
- int nReturnCode; /* Return code back from driver */
-} UNMOUNT_STRUCT;
-
-typedef struct
-{
- unsigned __int32 ulMountedDrives; /* Bitfield of all mounted drive letters */
- wchar_t wszVolume[26][TC_MAX_PATH]; /* Volume names of mounted volumes */
- wchar_t wszLabel[26][33]; /* Labels of mounted volumes */
- wchar_t volumeID[26][VOLUME_ID_SIZE]; /* IDs of mounted volumes */
- unsigned __int64 diskLength[26];
- int ea[26];
- int volumeType[26]; /* Volume type (e.g. PROP_VOL_TYPE_OUTER, PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, etc.) */
- BOOL truecryptMode[26];
-} MOUNT_LIST_STRUCT;
-
-typedef struct
-{
- int driveNo;
- int uniqueId;
- wchar_t wszVolume[TC_MAX_PATH];
- unsigned __int64 diskLength;
- int ea;
- int mode;
- int pkcs5;
- int pkcs5Iterations;
- BOOL hiddenVolume;
- BOOL readOnly;
- BOOL removable;
- BOOL partitionInInactiveSysEncScope;
- uint32 volumeHeaderFlags;
- unsigned __int64 totalBytesRead;
- unsigned __int64 totalBytesWritten;
- int hiddenVolProtection; /* Hidden volume protection status (e.g. HIDVOL_PROT_STATUS_NONE, HIDVOL_PROT_STATUS_ACTIVE, etc.) */
- int volFormatVersion;
- int volumePim;
- wchar_t wszLabel[33];
- BOOL bDriverSetLabel;
- unsigned char volumeID[VOLUME_ID_SIZE];
-} VOLUME_PROPERTIES_STRUCT;
-
-typedef struct
-{
- WCHAR symLinkName[TC_MAX_PATH];
- WCHAR targetName[TC_MAX_PATH];
-} RESOLVE_SYMLINK_STRUCT;
-
-typedef struct
-{
- WCHAR deviceName[TC_MAX_PATH];
- PARTITION_INFORMATION partInfo;
- BOOL IsGPT;
- BOOL IsDynamic;
-}
-DISK_PARTITION_INFO_STRUCT;
-
-typedef struct
-{
- WCHAR deviceName[TC_MAX_PATH];
- DISK_GEOMETRY diskGeometry;
-}
-DISK_GEOMETRY_STRUCT;
-
-typedef struct
-{
- WCHAR DeviceName[TC_MAX_PATH];
- LARGE_INTEGER RealDriveSize;
- BOOL TimeOut;
-} ProbeRealDriveSizeRequest;
-
-typedef struct
-{
- wchar_t wszFileName[TC_MAX_PATH]; // Volume to be "open tested"
- BOOL bDetectTCBootLoader; // Whether the driver is to determine if the first sector contains a portion of the TrueCrypt Boot Loader
- BOOL TCBootLoaderDetected;
- BOOL DetectFilesystem;
- BOOL FilesystemDetected;
- BOOL bMatchVolumeID;
- unsigned char volumeID[VOLUME_ID_SIZE];
- BOOL VolumeIDMatched;
-} OPEN_TEST_STRUCT;
-
-
-typedef enum
-{
- SetupNone = 0,
- SetupEncryption,
- SetupDecryption
-} BootEncryptionSetupMode;
-
-
-typedef struct
-{
- // New fields must be added at the end of the structure to maintain compatibility with previous versions
- BOOL DeviceFilterActive;
-
- uint16 BootLoaderVersion;
-
- BOOL DriveMounted;
- BOOL VolumeHeaderPresent;
- BOOL DriveEncrypted;
-
- LARGE_INTEGER BootDriveLength;
-
- int64 ConfiguredEncryptedAreaStart;
- int64 ConfiguredEncryptedAreaEnd;
- int64 EncryptedAreaStart;
- int64 EncryptedAreaEnd;
-
- uint32 VolumeHeaderSaltCrc32;
-
- BOOL SetupInProgress;
- BootEncryptionSetupMode SetupMode;
- BOOL TransformWaitingForIdle;
-
- uint32 HibernationPreventionCount;
-
- BOOL HiddenSystem;
- int64 HiddenSystemPartitionStart;
-
- // Number of times the filter driver answered that an unencrypted volume
- // is read-only (or mounted an outer/normal TrueCrypt volume as read only)
- uint32 HiddenSysLeakProtectionCount;
-
-} BootEncryptionStatus;
-
-
-typedef struct
-{
- BootEncryptionSetupMode SetupMode;
- WipeAlgorithmId WipeAlgorithm;
- BOOL ZeroUnreadableSectors;
- BOOL DiscardUnreadableEncryptedSectors;
-} BootEncryptionSetupRequest;
-
-
-typedef struct
-{
- Password VolumePassword;
- int pkcs5_prf;
- int pim;
-} ReopenBootVolumeHeaderRequest;
-
-
-typedef struct
-{
- char BootEncryptionAlgorithmName[256];
- char BootPrfAlgorithmName[256];
-} GetBootEncryptionAlgorithmNameRequest;
-
-typedef struct
-{
- byte Fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
-} BootLoaderFingerprintRequest;
-
-typedef struct
-{
- wchar_t DevicePath[TC_MAX_PATH];
- byte Configuration;
- BOOL DriveIsDynamic;
- uint16 BootLoaderVersion;
- byte UserConfiguration;
- char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
-} GetSystemDriveConfigurationRequest;
-
-typedef struct
-{
- WipeAlgorithmId WipeAlgorithm;
- byte WipeKey[MASTER_KEYDATA_SIZE];
-} WipeDecoySystemRequest;
-
-typedef struct
-{
- BOOL WipeInProgress;
- WipeAlgorithmId WipeAlgorithm;
- int64 WipedAreaEnd;
-} DecoySystemWipeStatus;
-
-typedef struct
-{
- LARGE_INTEGER Offset;
- byte Data[TC_SECTOR_SIZE_BIOS];
-} WriteBootDriveSectorRequest;
-
-typedef struct
-{
- BOOL PagingFileCreationPrevented;
- BOOL SystemFavoriteVolumeDirty;
-} GetWarningFlagsRequest;
-
-typedef struct
-{
- struct _DriveFilterExtension *BootDriveFilterExtension;
- BOOL HwEncryptionEnabled;
-} GetSystemDriveDumpConfigRequest;
-
-#pragma pack (pop)
-
-#define DRIVER_STR WIDE
-
-#define TC_UNIQUE_ID_PREFIX "VeraCryptVolume"
-#define TC_MOUNT_PREFIX L"\\Device\\VeraCryptVolume"
-
-#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\VeraCryptVolume")
-#define NT_ROOT_PREFIX DRIVER_STR("\\Device\\VeraCrypt")
-#define DOS_MOUNT_PREFIX_DEFAULT DRIVER_STR("\\DosDevices\\")
-#define DOS_MOUNT_PREFIX_GLOBAL DRIVER_STR("\\GLOBAL??\\") // Use Global MS-DOS device names for sanity checks on drive letters
-#define DOS_ROOT_PREFIX DRIVER_STR("\\DosDevices\\VeraCrypt")
-#define WIN32_ROOT_PREFIX DRIVER_STR("\\\\.\\VeraCrypt")
-
-#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("VeraCryptConfig")
-#define TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME DRIVER_STR("VeraCryptEncryptionFreeCpuCount")
-
-// WARNING: Modifying the following values can introduce incompatibility with previous versions.
-#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
-#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
-#define TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS 0x4
-#define TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION 0x8
-#define TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL 0x10
-#define TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION 0x20
-#define TC_DRIVER_CONFIG_CACHE_BOOT_PIM 0x40
-
-#endif /* _WIN32 */
+/*
+ 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-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. */
+
+#pragma once
+
+#include "Tcdefs.h"
+#include "Boot/Windows/BootDefs.h"
+#include "Common.h"
+#include "Crypto.h"
+#include "Volumes.h"
+#include "Wipe.h"
+
+#ifdef _WIN32
+
+/* WARNING: Modifying the following values or their meanings can introduce incompatibility with previous versions. */
+
+#define TC_IOCTL(CODE) (CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800 + (CODE), METHOD_BUFFERED, FILE_ANY_ACCESS))
+
+#define TC_IOCTL_GET_DRIVER_VERSION TC_IOCTL (1)
+#define TC_IOCTL_GET_BOOT_LOADER_VERSION TC_IOCTL (2)
+#define TC_IOCTL_MOUNT_VOLUME TC_IOCTL (3)
+#define TC_IOCTL_DISMOUNT_VOLUME TC_IOCTL (4)
+#define TC_IOCTL_DISMOUNT_ALL_VOLUMES TC_IOCTL (5)
+#define TC_IOCTL_GET_MOUNTED_VOLUMES TC_IOCTL (6)
+#define TC_IOCTL_GET_VOLUME_PROPERTIES TC_IOCTL (7)
+#define TC_IOCTL_GET_DEVICE_REFCOUNT TC_IOCTL (8)
+#define TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED TC_IOCTL (9)
+#define TC_IOCTL_IS_ANY_VOLUME_MOUNTED TC_IOCTL (10)
+#define TC_IOCTL_GET_PASSWORD_CACHE_STATUS TC_IOCTL (11)
+#define TC_IOCTL_WIPE_PASSWORD_CACHE TC_IOCTL (12)
+#define TC_IOCTL_OPEN_TEST TC_IOCTL (13)
+#define TC_IOCTL_GET_DRIVE_PARTITION_INFO TC_IOCTL (14)
+#define TC_IOCTL_GET_DRIVE_GEOMETRY TC_IOCTL (15)
+#define TC_IOCTL_PROBE_REAL_DRIVE_SIZE TC_IOCTL (16)
+#define TC_IOCTL_GET_RESOLVED_SYMLINK TC_IOCTL (17)
+#define TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS TC_IOCTL (18)
+#define TC_IOCTL_BOOT_ENCRYPTION_SETUP TC_IOCTL (19)
+#define TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP TC_IOCTL (20)
+#define TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT TC_IOCTL (21)
+#define TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES TC_IOCTL (22)
+#define TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER TC_IOCTL (23)
+#define TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME TC_IOCTL (24)
+#define TC_IOCTL_GET_PORTABLE_MODE_STATUS TC_IOCTL (25)
+#define TC_IOCTL_SET_PORTABLE_MODE_STATUS TC_IOCTL (26)
+#define TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING TC_IOCTL (27)
+#define TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG TC_IOCTL (28)
+#define TC_IOCTL_DISK_IS_WRITABLE TC_IOCTL (29)
+#define TC_IOCTL_START_DECOY_SYSTEM_WIPE TC_IOCTL (30)
+#define TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE TC_IOCTL (31)
+#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS TC_IOCTL (32)
+#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT TC_IOCTL (33)
+#define TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR TC_IOCTL (34)
+#define TC_IOCTL_GET_WARNING_FLAGS TC_IOCTL (35)
+#define TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY TC_IOCTL (36)
+#define TC_IOCTL_REREAD_DRIVER_CONFIG TC_IOCTL (37)
+#define TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG TC_IOCTL (38)
+#define VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT TC_IOCTL (39)
+
+// Legacy IOCTLs used before version 5.0
+#define TC_IOCTL_LEGACY_GET_DRIVER_VERSION 466968
+#define TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES 466948
+
+
+/* Start of driver interface structures, the size of these structures may
+ change between versions; so make sure you first send DRIVER_VERSION to
+ check that it's the correct device driver */
+
+#pragma pack (push)
+#pragma pack(1)
+
+typedef struct
+{
+ int nReturnCode; /* Return code back from driver */
+ BOOL FilesystemDirty;
+ BOOL VolumeMountedReadOnlyAfterAccessDenied;
+ BOOL VolumeMountedReadOnlyAfterDeviceWriteProtected;
+
+ wchar_t wszVolume[TC_MAX_PATH]; /* Volume to be mounted */
+ Password VolumePassword; /* User password */
+ BOOL bCache; /* Cache passwords in driver */
+ int nDosDriveNo; /* Drive number to mount */
+ uint32 BytesPerSector;
+ BOOL bMountReadOnly; /* Mount volume in read-only mode */
+ BOOL bMountRemovable; /* Mount volume as removable media */
+ BOOL bExclusiveAccess; /* Open host file/device in exclusive access mode */
+ BOOL bMountManager; /* Announce volume to mount manager */
+ BOOL bPreserveTimestamp; /* Preserve file container timestamp */
+ BOOL bPartitionInInactiveSysEncScope; /* If TRUE, we are to attempt to mount a partition located on an encrypted system drive without pre-boot authentication. */
+ int nPartitionInInactiveSysEncScopeDriveNo; /* If bPartitionInInactiveSysEncScope is TRUE, this contains the drive number of the system drive on which the partition is located. */
+ BOOL SystemFavorite;
+ // Hidden volume protection
+ BOOL bProtectHiddenVolume; /* TRUE if the user wants the hidden volume within this volume to be protected against being overwritten (damaged) */
+ Password ProtectedHidVolPassword; /* Password to the hidden volume to be protected against overwriting */
+ BOOL UseBackupHeader;
+ BOOL RecoveryMode;
+ int pkcs5_prf;
+ int ProtectedHidVolPkcs5Prf;
+ BOOL bTrueCryptMode;
+ uint32 BytesPerPhysicalSector;
+ int VolumePim;
+ int ProtectedHidVolPim;
+ wchar_t wszLabel[33]; // maximum label length is 32 for NTFS and 11 for FAT32
+ BOOL bIsNTFS; // output only
+ BOOL bDriverSetLabel;
+ BOOL bCachePim;
+} MOUNT_STRUCT;
+
+typedef struct
+{
+ int nDosDriveNo; /* Drive letter to unmount */
+ BOOL ignoreOpenFiles;
+ BOOL HiddenVolumeProtectionTriggered;
+ int nReturnCode; /* Return code back from driver */
+} UNMOUNT_STRUCT;
+
+typedef struct
+{
+ unsigned __int32 ulMountedDrives; /* Bitfield of all mounted drive letters */
+ wchar_t wszVolume[26][TC_MAX_PATH]; /* Volume names of mounted volumes */
+ wchar_t wszLabel[26][33]; /* Labels of mounted volumes */
+ wchar_t volumeID[26][VOLUME_ID_SIZE]; /* IDs of mounted volumes */
+ unsigned __int64 diskLength[26];
+ int ea[26];
+ int volumeType[26]; /* Volume type (e.g. PROP_VOL_TYPE_OUTER, PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, etc.) */
+ BOOL truecryptMode[26];
+} MOUNT_LIST_STRUCT;
+
+typedef struct
+{
+ int driveNo;
+ int uniqueId;
+ wchar_t wszVolume[TC_MAX_PATH];
+ unsigned __int64 diskLength;
+ int ea;
+ int mode;
+ int pkcs5;
+ int pkcs5Iterations;
+ BOOL hiddenVolume;
+ BOOL readOnly;
+ BOOL removable;
+ BOOL partitionInInactiveSysEncScope;
+ uint32 volumeHeaderFlags;
+ unsigned __int64 totalBytesRead;
+ unsigned __int64 totalBytesWritten;
+ int hiddenVolProtection; /* Hidden volume protection status (e.g. HIDVOL_PROT_STATUS_NONE, HIDVOL_PROT_STATUS_ACTIVE, etc.) */
+ int volFormatVersion;
+ int volumePim;
+ wchar_t wszLabel[33];
+ BOOL bDriverSetLabel;
+ unsigned char volumeID[VOLUME_ID_SIZE];
+} VOLUME_PROPERTIES_STRUCT;
+
+typedef struct
+{
+ WCHAR symLinkName[TC_MAX_PATH];
+ WCHAR targetName[TC_MAX_PATH];
+} RESOLVE_SYMLINK_STRUCT;
+
+typedef struct
+{
+ WCHAR deviceName[TC_MAX_PATH];
+ PARTITION_INFORMATION partInfo;
+ BOOL IsGPT;
+ BOOL IsDynamic;
+}
+DISK_PARTITION_INFO_STRUCT;
+
+typedef struct
+{
+ WCHAR deviceName[TC_MAX_PATH];
+ DISK_GEOMETRY diskGeometry;
+}
+DISK_GEOMETRY_STRUCT;
+
+typedef struct
+{
+ WCHAR DeviceName[TC_MAX_PATH];
+ LARGE_INTEGER RealDriveSize;
+ BOOL TimeOut;
+} ProbeRealDriveSizeRequest;
+
+typedef struct
+{
+ wchar_t wszFileName[TC_MAX_PATH]; // Volume to be "open tested"
+ BOOL bDetectTCBootLoader; // Whether the driver is to determine if the first sector contains a portion of the TrueCrypt Boot Loader
+ BOOL TCBootLoaderDetected;
+ BOOL DetectFilesystem;
+ BOOL FilesystemDetected;
+ BOOL bMatchVolumeID;
+ unsigned char volumeID[VOLUME_ID_SIZE];
+ BOOL VolumeIDMatched;
+} OPEN_TEST_STRUCT;
+
+
+typedef enum
+{
+ SetupNone = 0,
+ SetupEncryption,
+ SetupDecryption
+} BootEncryptionSetupMode;
+
+
+typedef struct
+{
+ // New fields must be added at the end of the structure to maintain compatibility with previous versions
+ BOOL DeviceFilterActive;
+
+ uint16 BootLoaderVersion;
+
+ BOOL DriveMounted;
+ BOOL VolumeHeaderPresent;
+ BOOL DriveEncrypted;
+
+ LARGE_INTEGER BootDriveLength;
+
+ int64 ConfiguredEncryptedAreaStart;
+ int64 ConfiguredEncryptedAreaEnd;
+ int64 EncryptedAreaStart;
+ int64 EncryptedAreaEnd;
+
+ uint32 VolumeHeaderSaltCrc32;
+
+ BOOL SetupInProgress;
+ BootEncryptionSetupMode SetupMode;
+ BOOL TransformWaitingForIdle;
+
+ uint32 HibernationPreventionCount;
+
+ BOOL HiddenSystem;
+ int64 HiddenSystemPartitionStart;
+
+ // Number of times the filter driver answered that an unencrypted volume
+ // is read-only (or mounted an outer/normal TrueCrypt volume as read only)
+ uint32 HiddenSysLeakProtectionCount;
+
+} BootEncryptionStatus;
+
+
+typedef struct
+{
+ BootEncryptionSetupMode SetupMode;
+ WipeAlgorithmId WipeAlgorithm;
+ BOOL ZeroUnreadableSectors;
+ BOOL DiscardUnreadableEncryptedSectors;
+} BootEncryptionSetupRequest;
+
+
+typedef struct
+{
+ Password VolumePassword;
+ int pkcs5_prf;
+ int pim;
+} ReopenBootVolumeHeaderRequest;
+
+
+typedef struct
+{
+ char BootEncryptionAlgorithmName[256];
+ char BootPrfAlgorithmName[256];
+} GetBootEncryptionAlgorithmNameRequest;
+
+typedef struct
+{
+ byte Fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
+} BootLoaderFingerprintRequest;
+
+typedef struct
+{
+ wchar_t DevicePath[TC_MAX_PATH];
+ byte Configuration;
+ BOOL DriveIsDynamic;
+ uint16 BootLoaderVersion;
+ byte UserConfiguration;
+ char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
+} GetSystemDriveConfigurationRequest;
+
+typedef struct
+{
+ WipeAlgorithmId WipeAlgorithm;
+ byte WipeKey[MASTER_KEYDATA_SIZE];
+} WipeDecoySystemRequest;
+
+typedef struct
+{
+ BOOL WipeInProgress;
+ WipeAlgorithmId WipeAlgorithm;
+ int64 WipedAreaEnd;
+} DecoySystemWipeStatus;
+
+typedef struct
+{
+ LARGE_INTEGER Offset;
+ byte Data[TC_SECTOR_SIZE_BIOS];
+} WriteBootDriveSectorRequest;
+
+typedef struct
+{
+ BOOL PagingFileCreationPrevented;
+ BOOL SystemFavoriteVolumeDirty;
+} GetWarningFlagsRequest;
+
+typedef struct
+{
+ struct _DriveFilterExtension *BootDriveFilterExtension;
+ BOOL HwEncryptionEnabled;
+} GetSystemDriveDumpConfigRequest;
+
+#pragma pack (pop)
+
+#define DRIVER_STR WIDE
+
+#define TC_UNIQUE_ID_PREFIX "VeraCryptVolume"
+#define TC_MOUNT_PREFIX L"\\Device\\VeraCryptVolume"
+
+#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\VeraCryptVolume")
+#define NT_ROOT_PREFIX DRIVER_STR("\\Device\\VeraCrypt")
+#define DOS_MOUNT_PREFIX_DEFAULT DRIVER_STR("\\DosDevices\\")
+#define DOS_MOUNT_PREFIX_GLOBAL DRIVER_STR("\\GLOBAL??\\") // Use Global MS-DOS device names for sanity checks on drive letters
+#define DOS_ROOT_PREFIX DRIVER_STR("\\DosDevices\\VeraCrypt")
+#define WIN32_ROOT_PREFIX DRIVER_STR("\\\\.\\VeraCrypt")
+
+#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("VeraCryptConfig")
+#define TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME DRIVER_STR("VeraCryptEncryptionFreeCpuCount")
+
+// WARNING: Modifying the following values can introduce incompatibility with previous versions.
+#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
+#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
+#define TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS 0x4
+#define TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION 0x8
+#define TC_DRIVER_CONFIG_ENABLE_EXTENDED_IOCTL 0x10
+#define TC_DRIVER_CONFIG_DISABLE_EVIL_MAID_ATTACK_DETECTION 0x20
+#define TC_DRIVER_CONFIG_CACHE_BOOT_PIM 0x40
+
+#endif /* _WIN32 */
diff --git a/src/Common/BaseCom.cpp b/src/Common/BaseCom.cpp
index 8e7d39f..f6c5597 100644
--- a/src/Common/BaseCom.cpp
+++ b/src/Common/BaseCom.cpp
@@ -1,246 +1,246 @@
-/*
- 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-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 <atlcomcli.h>
-#include <atlconv.h>
-#include <comutil.h>
-#include <windows.h>
-#include "BaseCom.h"
-#include "BootEncryption.h"
-#include "Dlgcode.h"
-#include "Registry.h"
-
-using namespace VeraCrypt;
-
-HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv)
-{
- WCHAR monikerName[1024];
- WCHAR clsid[1024];
- BIND_OPTS3 bo;
-
- StringFromGUID2 (guid, clsid, sizeof (clsid) / 2);
- swprintf_s (monikerName, sizeof (monikerName) / 2, L"Elevation:Administrator!new:%s", clsid);
-
- memset (&bo, 0, sizeof (bo));
- bo.cbStruct = sizeof (bo);
- bo.hwnd = hwnd;
- bo.dwClassContext = CLSCTX_LOCAL_SERVER;
-
- // Prevent the GUI from being half-rendered when the UAC prompt "freezes" it
- ProcessPaintMessages (hwnd, 5000);
-
- return CoGetObject (monikerName, &bo, iid, ppv);
-}
-
-
-BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer)
-{
- BOOL r;
-
- if (IsUacSupported ())
- {
- while (true)
- {
- r = CreateElevatedComObject (hWnd, clsid, iid, tcServer) == S_OK;
- if (r)
- break;
- else
- {
- if (IDRETRY == ErrorRetryCancel ("UAC_INIT_ERROR", hWnd))
- continue;
- else
- break;
- }
- }
- }
- else
- {
- r = CoCreateInstance (clsid, NULL, CLSCTX_LOCAL_SERVER, iid, tcServer) == S_OK;
- if (!r)
- Error ("UAC_INIT_ERROR", hWnd);
- }
-
- return r;
-}
-
-
-DWORD BaseCom::CallDriver (DWORD ioctl, BSTR input, BSTR *output)
-{
- try
- {
- BootEncryption bootEnc (NULL);
- bootEnc.CallDriver (ioctl,
- (BYTE *) input, !(BYTE *) input ? 0 : ((DWORD *) ((BYTE *) input))[-1],
- (BYTE *) *output, !(BYTE *) *output ? 0 : ((DWORD *) ((BYTE *) *output))[-1]);
- }
- catch (SystemException &)
- {
- return GetLastError();
- }
- catch (Exception &e)
- {
- e.Show (NULL);
- return ERROR_EXCEPTION_IN_SERVICE;
- }
- catch (...)
- {
- return ERROR_EXCEPTION_IN_SERVICE;
- }
-
- return ERROR_SUCCESS;
-}
-
-
-DWORD BaseCom::CopyFile (BSTR sourceFile, BSTR destinationFile)
-{
-
- if (!::CopyFileW (sourceFile, destinationFile, FALSE))
- return GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-
-DWORD BaseCom::DeleteFile (BSTR file)
-{
-
- if (!::DeleteFileW (file))
- return GetLastError();
-
- return ERROR_SUCCESS;
-}
-
-
-BOOL BaseCom::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
-{
- return ::IsPagingFileActive (checkNonWindowsPartitionsOnly);
-}
-
-
-DWORD BaseCom::ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone)
-{
- try
- {
- auto_ptr <File> file (device ? new Device (filePath, !write) : new File (filePath, !write));
- file->CheckOpened (SRC_POS);
- file->SeekAt (offset);
-
- if (write)
- {
- file->Write ((BYTE *) *bufferBstr, size);
- *sizeDone = size;
- }
- else
- {
- *sizeDone = file->Read ((BYTE *) *bufferBstr, size);
- }
- }
- catch (SystemException &)
- {
- return GetLastError();
- }
- catch (Exception &e)
- {
- e.Show (NULL);
- return ERROR_EXCEPTION_IN_SERVICE;
- }
- catch (...)
- {
- return ERROR_EXCEPTION_IN_SERVICE;
- }
-
- return ERROR_SUCCESS;
-}
-
-
-DWORD BaseCom::RegisterFilterDriver (BOOL registerDriver, int filterType)
-{
- try
- {
- BootEncryption bootEnc (NULL);
- bootEnc.RegisterFilterDriver (registerDriver ? true : false, (BootEncryption::FilterType) filterType);
- }
- catch (SystemException &)
- {
- return GetLastError();
- }
- catch (Exception &e)
- {
- e.Show (NULL);
- return ERROR_EXCEPTION_IN_SERVICE;
- }
- catch (...)
- {
- return ERROR_EXCEPTION_IN_SERVICE;
- }
-
- return ERROR_SUCCESS;
-}
-
-
-DWORD BaseCom::RegisterSystemFavoritesService (BOOL registerService)
-{
- try
- {
- BootEncryption bootEnc (NULL);
- bootEnc.RegisterSystemFavoritesService (registerService);
- }
- catch (SystemException &)
- {
- return GetLastError();
- }
- catch (Exception &e)
- {
- e.Show (NULL);
- return ERROR_EXCEPTION_IN_SERVICE;
- }
- catch (...)
- {
- return ERROR_EXCEPTION_IN_SERVICE;
- }
-
- return ERROR_SUCCESS;
-}
-
-
-DWORD BaseCom::SetDriverServiceStartType (DWORD startType)
-{
- try
- {
- BootEncryption bootEnc (NULL);
- bootEnc.SetDriverServiceStartType (startType);
- }
- catch (SystemException &)
- {
- return GetLastError();
- }
- catch (Exception &e)
- {
- e.Show (NULL);
- return ERROR_EXCEPTION_IN_SERVICE;
- }
- catch (...)
- {
- return ERROR_EXCEPTION_IN_SERVICE;
- }
-
- return ERROR_SUCCESS;
-}
-
-
-DWORD BaseCom::WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value)
-{
- if (!::WriteLocalMachineRegistryDword (keyPath, valueName, value))
- return GetLastError();
-
- return ERROR_SUCCESS;
-}
+/*
+ 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-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 <atlcomcli.h>
+#include <atlconv.h>
+#include <comutil.h>
+#include <windows.h>
+#include "BaseCom.h"
+#include "BootEncryption.h"
+#include "Dlgcode.h"
+#include "Registry.h"
+
+using namespace VeraCrypt;
+
+HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv)
+{
+ WCHAR monikerName[1024];
+ WCHAR clsid[1024];
+ BIND_OPTS3 bo;
+
+ StringFromGUID2 (guid, clsid, sizeof (clsid) / 2);
+ swprintf_s (monikerName, sizeof (monikerName) / 2, L"Elevation:Administrator!new:%s", clsid);
+
+ memset (&bo, 0, sizeof (bo));
+ bo.cbStruct = sizeof (bo);
+ bo.hwnd = hwnd;
+ bo.dwClassContext = CLSCTX_LOCAL_SERVER;
+
+ // Prevent the GUI from being half-rendered when the UAC prompt "freezes" it
+ ProcessPaintMessages (hwnd, 5000);
+
+ return CoGetObject (monikerName, &bo, iid, ppv);
+}
+
+
+BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer)
+{
+ BOOL r;
+
+ if (IsUacSupported ())
+ {
+ while (true)
+ {
+ r = CreateElevatedComObject (hWnd, clsid, iid, tcServer) == S_OK;
+ if (r)
+ break;
+ else
+ {
+ if (IDRETRY == ErrorRetryCancel ("UAC_INIT_ERROR", hWnd))
+ continue;
+ else
+ break;
+ }
+ }
+ }
+ else
+ {
+ r = CoCreateInstance (clsid, NULL, CLSCTX_LOCAL_SERVER, iid, tcServer) == S_OK;
+ if (!r)
+ Error ("UAC_INIT_ERROR", hWnd);
+ }
+
+ return r;
+}
+
+
+DWORD BaseCom::CallDriver (DWORD ioctl, BSTR input, BSTR *output)
+{
+ try
+ {
+ BootEncryption bootEnc (NULL);
+ bootEnc.CallDriver (ioctl,
+ (BYTE *) input, !(BYTE *) input ? 0 : ((DWORD *) ((BYTE *) input))[-1],
+ (BYTE *) *output, !(BYTE *) *output ? 0 : ((DWORD *) ((BYTE *) *output))[-1]);
+ }
+ catch (SystemException &)
+ {
+ return GetLastError();
+ }
+ catch (Exception &e)
+ {
+ e.Show (NULL);
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+ catch (...)
+ {
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+DWORD BaseCom::CopyFile (BSTR sourceFile, BSTR destinationFile)
+{
+
+ if (!::CopyFileW (sourceFile, destinationFile, FALSE))
+ return GetLastError();
+
+ return ERROR_SUCCESS;
+}
+
+
+DWORD BaseCom::DeleteFile (BSTR file)
+{
+
+ if (!::DeleteFileW (file))
+ return GetLastError();
+
+ return ERROR_SUCCESS;
+}
+
+
+BOOL BaseCom::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
+{
+ return ::IsPagingFileActive (checkNonWindowsPartitionsOnly);
+}
+
+
+DWORD BaseCom::ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone)
+{
+ try
+ {
+ auto_ptr <File> file (device ? new Device (filePath, !write) : new File (filePath, !write));
+ file->CheckOpened (SRC_POS);
+ file->SeekAt (offset);
+
+ if (write)
+ {
+ file->Write ((BYTE *) *bufferBstr, size);
+ *sizeDone = size;
+ }
+ else
+ {
+ *sizeDone = file->Read ((BYTE *) *bufferBstr, size);
+ }
+ }
+ catch (SystemException &)
+ {
+ return GetLastError();
+ }
+ catch (Exception &e)
+ {
+ e.Show (NULL);
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+ catch (...)
+ {
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+DWORD BaseCom::RegisterFilterDriver (BOOL registerDriver, int filterType)
+{
+ try
+ {
+ BootEncryption bootEnc (NULL);
+ bootEnc.RegisterFilterDriver (registerDriver ? true : false, (BootEncryption::FilterType) filterType);
+ }
+ catch (SystemException &)
+ {
+ return GetLastError();
+ }
+ catch (Exception &e)
+ {
+ e.Show (NULL);
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+ catch (...)
+ {
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+DWORD BaseCom::RegisterSystemFavoritesService (BOOL registerService)
+{
+ try
+ {
+ BootEncryption bootEnc (NULL);
+ bootEnc.RegisterSystemFavoritesService (registerService);
+ }
+ catch (SystemException &)
+ {
+ return GetLastError();
+ }
+ catch (Exception &e)
+ {
+ e.Show (NULL);
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+ catch (...)
+ {
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+DWORD BaseCom::SetDriverServiceStartType (DWORD startType)
+{
+ try
+ {
+ BootEncryption bootEnc (NULL);
+ bootEnc.SetDriverServiceStartType (startType);
+ }
+ catch (SystemException &)
+ {
+ return GetLastError();
+ }
+ catch (Exception &e)
+ {
+ e.Show (NULL);
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+ catch (...)
+ {
+ return ERROR_EXCEPTION_IN_SERVICE;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+
+DWORD BaseCom::WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value)
+{
+ if (!::WriteLocalMachineRegistryDword (keyPath, valueName, value))
+ return GetLastError();
+
+ return ERROR_SUCCESS;
+}
diff --git a/src/Common/BaseCom.h b/src/Common/BaseCom.h
index 9f5b312..9700941 100644
--- a/src/Common/BaseCom.h
+++ b/src/Common/BaseCom.h
@@ -1,119 +1,119 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_BASE_COM
-#define TC_HEADER_BASE_COM
-
-#include <guiddef.h>
-
-template <class TClass>
-class TrueCryptFactory : public IClassFactory
-{
-
-public:
- TrueCryptFactory (DWORD messageThreadId) :
- RefCount (1), ServerLockCount (0), MessageThreadId (messageThreadId) { }
-
- ~TrueCryptFactory () { }
-
- virtual ULONG STDMETHODCALLTYPE AddRef ()
- {
- return InterlockedIncrement (&RefCount) - 1;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release ()
- {
- ULONG r = InterlockedDecrement (&RefCount) + 1;
-
- if (r == 0)
- delete this;
-
- return r;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **ppvObject)
- {
- if (riid == IID_IUnknown || riid == IID_IClassFactory)
- *ppvObject = this;
- else
- {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
-
- AddRef ();
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE CreateInstance (IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
- {
- if (pUnkOuter != NULL)
- return CLASS_E_NOAGGREGATION;
-
- TClass *tc = new TClass (MessageThreadId);
- if (tc == NULL)
- return E_OUTOFMEMORY;
-
- HRESULT hr = tc->QueryInterface (riid, ppvObject);
-
- if (hr)
- delete tc;
-
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE LockServer (BOOL fLock)
- {
- if (fLock)
- {
- InterlockedIncrement (&ServerLockCount);
- }
- else
- {
- if (!InterlockedDecrement (&ServerLockCount))
- PostThreadMessage (MessageThreadId, WM_APP, 0, 0);
- }
-
- return S_OK;
- }
-
- virtual bool IsServerLocked ()
- {
- return ServerLockCount > 0;
- }
-
-protected:
- DWORD MessageThreadId;
- LONG RefCount;
- LONG ServerLockCount;
-};
-
-
-class BaseCom
-{
-public:
- static DWORD CallDriver (DWORD ioctl, BSTR input, BSTR *output);
- static DWORD CopyFile (BSTR sourceFile, BSTR destinationFile);
- static DWORD DeleteFile (BSTR file);
- static BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
- static DWORD ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone);
- static DWORD RegisterFilterDriver (BOOL registerDriver, int filterType);
- static DWORD RegisterSystemFavoritesService (BOOL registerService);
- static DWORD SetDriverServiceStartType (DWORD startType);
- static DWORD WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value);
-};
-
-
-BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer);
-HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv);
-
-#endif // TC_HEADER_BASE_COM
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_BASE_COM
+#define TC_HEADER_BASE_COM
+
+#include <guiddef.h>
+
+template <class TClass>
+class TrueCryptFactory : public IClassFactory
+{
+
+public:
+ TrueCryptFactory (DWORD messageThreadId) :
+ RefCount (1), ServerLockCount (0), MessageThreadId (messageThreadId) { }
+
+ ~TrueCryptFactory () { }
+
+ virtual ULONG STDMETHODCALLTYPE AddRef ()
+ {
+ return InterlockedIncrement (&RefCount) - 1;
+ }
+
+ virtual ULONG STDMETHODCALLTYPE Release ()
+ {
+ ULONG r = InterlockedDecrement (&RefCount) + 1;
+
+ if (r == 0)
+ delete this;
+
+ return r;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **ppvObject)
+ {
+ if (riid == IID_IUnknown || riid == IID_IClassFactory)
+ *ppvObject = this;
+ else
+ {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+
+ AddRef ();
+ return S_OK;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE CreateInstance (IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
+ {
+ if (pUnkOuter != NULL)
+ return CLASS_E_NOAGGREGATION;
+
+ TClass *tc = new TClass (MessageThreadId);
+ if (tc == NULL)
+ return E_OUTOFMEMORY;
+
+ HRESULT hr = tc->QueryInterface (riid, ppvObject);
+
+ if (hr)
+ delete tc;
+
+ return hr;
+ }
+
+ virtual HRESULT STDMETHODCALLTYPE LockServer (BOOL fLock)
+ {
+ if (fLock)
+ {
+ InterlockedIncrement (&ServerLockCount);
+ }
+ else
+ {
+ if (!InterlockedDecrement (&ServerLockCount))
+ PostThreadMessage (MessageThreadId, WM_APP, 0, 0);
+ }
+
+ return S_OK;
+ }
+
+ virtual bool IsServerLocked ()
+ {
+ return ServerLockCount > 0;
+ }
+
+protected:
+ DWORD MessageThreadId;
+ LONG RefCount;
+ LONG ServerLockCount;
+};
+
+
+class BaseCom
+{
+public:
+ static DWORD CallDriver (DWORD ioctl, BSTR input, BSTR *output);
+ static DWORD CopyFile (BSTR sourceFile, BSTR destinationFile);
+ static DWORD DeleteFile (BSTR file);
+ static BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
+ static DWORD ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone);
+ static DWORD RegisterFilterDriver (BOOL registerDriver, int filterType);
+ static DWORD RegisterSystemFavoritesService (BOOL registerService);
+ static DWORD SetDriverServiceStartType (DWORD startType);
+ static DWORD WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value);
+};
+
+
+BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer);
+HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv);
+
+#endif // TC_HEADER_BASE_COM
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index 851d762..73b6445 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -1,2813 +1,2813 @@
-/*
- 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-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"
-#include "Platform/Finally.h"
-#include "Platform/ForEach.h"
-#include <devguid.h>
-#include <io.h>
-#include <shlobj.h>
-#include <atlbase.h>
-#include "BootEncryption.h"
-#include "Boot/Windows/BootCommon.h"
-#include "Common/Resource.h"
-#include "Crc.h"
-#include "Crypto.h"
-#include "Dlgcode.h"
-#include "Endian.h"
-#include "Language.h"
-#include "Random.h"
-#include "Registry.h"
-#include "Volumes.h"
-
-#ifdef VOLFORMAT
-#include "Format/FormatCom.h"
-#elif defined (TCMOUNT)
-#include "Mount/MainCom.h"
-#endif
-
-#include <Strsafe.h>
-
-namespace VeraCrypt
-{
-#if !defined (SETUP)
-
- class Elevator
- {
- public:
-
- static void AddReference ()
- {
- ++ReferenceCount;
- }
-
-
- static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
- {
- Elevate();
-
- CComBSTR inputBstr;
- if (input && inputBstr.AppendBytes ((const char *) input, inputSize) != S_OK)
- throw ParameterIncorrect (SRC_POS);
-
- CComBSTR outputBstr;
- if (output && outputBstr.AppendBytes ((const char *) output, outputSize) != S_OK)
- throw ParameterIncorrect (SRC_POS);
-
- DWORD result = ElevatedComInstance->CallDriver (ioctl, inputBstr, &outputBstr);
-
- if (output)
- memcpy (output, *(void **) &outputBstr, outputSize);
-
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
- }
-
- static void CopyFile (const wstring &sourceFile, const wstring &destinationFile)
- {
- Elevate();
- DWORD result;
- CComBSTR sourceFileBstr, destinationFileBstr;
- BSTR bstr = W2BSTR(sourceFile.c_str());
- if (bstr)
- {
- sourceFileBstr.Attach (bstr);
-
- bstr = W2BSTR(destinationFile.c_str());
- if (bstr)
- {
- destinationFileBstr.Attach (bstr);
- result = ElevatedComInstance->CopyFile (sourceFileBstr, destinationFileBstr);
- }
- else
- {
- result = ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- result = ERROR_OUTOFMEMORY;
- }
-
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
- }
-
- static void DeleteFile (const wstring &file)
- {
- Elevate();
- CComBSTR fileBstr;
- DWORD result;
- BSTR bstr = W2BSTR(file.c_str());
- if (bstr)
- {
- fileBstr.Attach (bstr);
- result = ElevatedComInstance->DeleteFile (fileBstr);
- }
- else
- {
- result = ERROR_OUTOFMEMORY;
- }
-
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
- }
-
- static void ReadWriteFile (BOOL write, BOOL device, const wstring &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone)
- {
- Elevate();
-
- DWORD result;
- CComBSTR bufferBstr, fileBstr;
- if (bufferBstr.AppendBytes ((const char *) buffer, size) != S_OK)
- throw ParameterIncorrect (SRC_POS);
- BSTR bstr = W2BSTR(filePath.c_str());
- if (bstr)
- {
- fileBstr.Attach (bstr);
- result = ElevatedComInstance->ReadWriteFile (write, device, fileBstr, &bufferBstr, offset, size, sizeDone);
- }
- else
- {
- result = ERROR_OUTOFMEMORY;
- }
-
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
-
- if (!write)
- memcpy (buffer, (BYTE *) bufferBstr.m_str, size);
- }
-
- static BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
- {
- Elevate();
-
- return ElevatedComInstance->IsPagingFileActive (checkNonWindowsPartitionsOnly);
- }
-
- static void WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value)
- {
- Elevate();
- DWORD result;
- CComBSTR keyPathBstr, valueNameBstr;
- BSTR bstr = W2BSTR(keyPath);
- if (bstr)
- {
- keyPathBstr.Attach (bstr);
-
- bstr = W2BSTR(valueName);
- if (bstr)
- {
- valueNameBstr.Attach (bstr);
-
- result = ElevatedComInstance->WriteLocalMachineRegistryDwordValue (keyPathBstr, valueNameBstr, value);
- }
- else
- {
- result = ERROR_OUTOFMEMORY;
- }
- }
- else
- {
- result = ERROR_OUTOFMEMORY;
- }
-
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
- }
-
- static void RegisterFilterDriver (bool registerDriver, BootEncryption::FilterType filterType)
- {
- Elevate();
-
- DWORD result = ElevatedComInstance->RegisterFilterDriver (registerDriver ? TRUE : FALSE, filterType);
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
- }
-
- static void RegisterSystemFavoritesService (BOOL registerService)
- {
- Elevate();
-
- DWORD result = ElevatedComInstance->RegisterSystemFavoritesService (registerService);
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
- }
-
- static void Release ()
- {
- if (--ReferenceCount == 0 && ElevatedComInstance)
- {
- ElevatedComInstance->Release();
- ElevatedComInstance = nullptr;
- CoUninitialize ();
- }
- }
-
- static void SetDriverServiceStartType (DWORD startType)
- {
- Elevate();
-
- DWORD result = ElevatedComInstance->SetDriverServiceStartType (startType);
- if (result != ERROR_SUCCESS)
- {
- SetLastError (result);
- throw SystemException(SRC_POS);
- }
- }
-
- protected:
- static void Elevate ()
- {
- if (IsAdmin())
- {
- SetLastError (ERROR_ACCESS_DENIED);
- throw SystemException(SRC_POS);
- }
-
- if (!ElevatedComInstance || ElevatedComInstanceThreadId != GetCurrentThreadId())
- {
- CoInitialize (NULL);
- ElevatedComInstance = GetElevatedInstance (GetActiveWindow() ? GetActiveWindow() : MainDlg);
- ElevatedComInstanceThreadId = GetCurrentThreadId();
- }
- }
-
-#if defined (TCMOUNT)
- static ITrueCryptMainCom *ElevatedComInstance;
-#elif defined (VOLFORMAT)
- static ITrueCryptFormatCom *ElevatedComInstance;
-#endif
- static DWORD ElevatedComInstanceThreadId;
- static int ReferenceCount;
- };
-
-#if defined (TCMOUNT)
- ITrueCryptMainCom *Elevator::ElevatedComInstance;
-#elif defined (VOLFORMAT)
- ITrueCryptFormatCom *Elevator::ElevatedComInstance;
-#endif
- DWORD Elevator::ElevatedComInstanceThreadId;
- int Elevator::ReferenceCount = 0;
-
-#else // SETUP
-
- class Elevator
- {
- public:
- static void AddReference () { }
- static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) { throw ParameterIncorrect (SRC_POS); }
- static void ReadWriteFile (BOOL write, BOOL device, const wstring &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) { throw ParameterIncorrect (SRC_POS); }
- static void RegisterFilterDriver (bool registerDriver, BootEncryption::FilterType filterType) { throw ParameterIncorrect (SRC_POS); }
- static void Release () { }
- static void SetDriverServiceStartType (DWORD startType) { throw ParameterIncorrect (SRC_POS); }
- };
-
-#endif // SETUP
-
-
- File::File (wstring path, bool readOnly, bool create) : Elevated (false), FileOpen (false), LastError(0)
- {
- Handle = CreateFile (path.c_str(),
- readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
-
- if (Handle != INVALID_HANDLE_VALUE)
- {
- FileOpen = true;
- }
- else
- {
- LastError = GetLastError();
- if (LastError == ERROR_ACCESS_DENIED && IsUacSupported())
- {
- Elevated = true;
- FileOpen = true;
- }
- }
-
- FilePointerPosition = 0;
- IsDevice = false;
- Path = path;
- }
-
- void File::Close ()
- {
- if (Handle != INVALID_HANDLE_VALUE)
- {
- CloseHandle (Handle);
- Handle = INVALID_HANDLE_VALUE;
- }
-
- FileOpen = false;
- }
-
- DWORD File::Read (byte *buffer, DWORD size)
- {
- DWORD bytesRead;
-
- if (!FileOpen)
- {
- SetLastError (LastError);
- throw SystemException (SRC_POS);
- }
-
- if (Elevated)
- {
- DWORD bytesRead;
-
- Elevator::ReadWriteFile (false, IsDevice, Path, buffer, FilePointerPosition, size, &bytesRead);
- FilePointerPosition += bytesRead;
- return bytesRead;
- }
-
- throw_sys_if (!ReadFile (Handle, buffer, size, &bytesRead, NULL));
- return bytesRead;
- }
-
- void File::SeekAt (int64 position)
- {
- if (!FileOpen)
- {
- SetLastError (LastError);
- throw SystemException (SRC_POS);
- }
-
- FilePointerPosition = position;
-
- if (!Elevated)
- {
- LARGE_INTEGER pos;
- pos.QuadPart = position;
- throw_sys_if (!SetFilePointerEx (Handle, pos, NULL, FILE_BEGIN));
- }
- }
-
- void File::Write (byte *buffer, DWORD size)
- {
- DWORD bytesWritten;
-
- if (!FileOpen)
- {
- SetLastError (LastError);
- throw SystemException (SRC_POS);
- }
-
- try
- {
- if (Elevated)
- {
- Elevator::ReadWriteFile (true, IsDevice, Path, buffer, FilePointerPosition, size, &bytesWritten);
- FilePointerPosition += bytesWritten;
- throw_sys_if (bytesWritten != size);
- }
- else
- {
- throw_sys_if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL) || bytesWritten != size);
- }
- }
- catch (SystemException &e)
- {
- if (!IsDevice || e.ErrorCode != ERROR_WRITE_PROTECT)
- throw;
-
- BootEncryption bootEnc (NULL);
-
- while (size >= TC_SECTOR_SIZE_BIOS)
- {
- bootEnc.WriteBootDriveSector (FilePointerPosition, buffer);
-
- FilePointerPosition += TC_SECTOR_SIZE_BIOS;
- buffer += TC_SECTOR_SIZE_BIOS;
- size -= TC_SECTOR_SIZE_BIOS;
- }
- }
- }
-
- void Show (HWND parent, const wstring &str)
- {
- MessageBox (parent, str.c_str(), NULL, 0);
- }
-
-
- Device::Device (wstring path, bool readOnly)
- {
- FileOpen = false;
- Elevated = false;
-
- Handle = CreateFile ((wstring (L"\\\\.\\") + path).c_str(),
- readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
-
- if (Handle != INVALID_HANDLE_VALUE)
- {
- FileOpen = true;
- }
- else
- {
- LastError = GetLastError ();
- if (LastError == ERROR_ACCESS_DENIED && IsUacSupported())
- {
- Elevated = true;
- FileOpen = true;
- }
- }
-
- FilePointerPosition = 0;
- IsDevice = true;
- Path = path;
- }
-
-
- BootEncryption::BootEncryption (HWND parent)
- : DriveConfigValid (false),
- ParentWindow (parent),
- RealSystemDriveSizeValid (false),
- RescueIsoImage (nullptr),
- RescueVolumeHeaderValid (false),
- SelectedEncryptionAlgorithmId (0),
- SelectedPrfAlgorithmId (0),
- VolumeHeaderValid (false)
- {
- HiddenOSCandidatePartition.IsGPT = FALSE;
- HiddenOSCandidatePartition.Number = (size_t) -1;
- DriveConfig.DriveNumber = -1;
- DriveConfig.ExtraBootPartitionPresent = false;
- DriveConfig.SystemLoaderPresent = false;
- DriveConfig.InitialUnallocatedSpace = 0;
- DriveConfig.TotalUnallocatedSpace = 0;
- Elevator::AddReference();
- }
-
-
- BootEncryption::~BootEncryption ()
- {
- if (RescueIsoImage)
- delete[] RescueIsoImage;
-
- Elevator::Release();
- }
-
-
- void BootEncryption::CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
- {
- try
- {
- DWORD bytesReturned;
- throw_sys_if (!DeviceIoControl (hDriver, ioctl, input, inputSize, output, outputSize, &bytesReturned, NULL));
- }
- catch (SystemException &)
- {
- if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
- Elevator::CallDriver (ioctl, input, inputSize, output, outputSize);
- else
- throw;
- }
- }
-
-
- // Finds the first partition physically located behind the active one and returns its properties
- Partition BootEncryption::GetPartitionForHiddenOS ()
- {
- Partition candidatePartition;
-
- memset (&candidatePartition, 0, sizeof(candidatePartition));
-
- // The user may have modified/added/deleted partitions since the time the partition table was last scanned
- InvalidateCachedSysDriveProperties();
-
- SystemDriveConfiguration config = GetSystemDriveConfiguration ();
- bool activePartitionFound = false;
- bool candidateForHiddenOSFound = false;
-
- if (config.SystemPartition.IsGPT)
- throw ParameterIncorrect (SRC_POS); // It is assumed that CheckRequirements() had been called
-
- // Find the first active partition on the system drive
- foreach (const Partition &partition, config.Partitions)
- {
- if (partition.Info.BootIndicator)
- {
- if (partition.Info.PartitionNumber != config.SystemPartition.Number)
- {
- // If there is an extra boot partition, the system partition must be located right behind it
- if (IsOSAtLeast (WIN_7) && config.ExtraBootPartitionPresent)
- {
- int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart;
- Partition bootPartition = partition;
- Partition partitionBehindBoot;
-
- foreach (const Partition &partition, config.Partitions)
- {
- if (partition.Info.StartingOffset.QuadPart > bootPartition.Info.StartingOffset.QuadPart
- && partition.Info.StartingOffset.QuadPart < minOffsetFound)
- {
- minOffsetFound = partition.Info.StartingOffset.QuadPart;
- partitionBehindBoot = partition;
- }
- }
-
- if (minOffsetFound != config.DrivePartition.Info.PartitionLength.QuadPart
- && partitionBehindBoot.Number == config.SystemPartition.Number)
- {
- activePartitionFound = true;
- break;
- }
- }
-
- throw ErrorException (wstring (GetString ("SYSTEM_PARTITION_NOT_ACTIVE"))
- + GetRemarksOnHiddenOS(), SRC_POS);
- }
-
- activePartitionFound = true;
- break;
- }
- }
-
- /* WARNING: Note that the partition number at the end of a device path (\Device\HarddiskY\PartitionX) must
- NOT be used to find the first partition physically located behind the active one. The reason is that the
- user may have deleted and created partitions during this session and e.g. the second partition could have
- a higer number than the third one. */
-
-
- // Find the first partition physically located behind the active partition
- if (activePartitionFound)
- {
- int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart;
-
- foreach (const Partition &partition, config.Partitions)
- {
- if (partition.Info.StartingOffset.QuadPart > config.SystemPartition.Info.StartingOffset.QuadPart
- && partition.Info.StartingOffset.QuadPart < minOffsetFound)
- {
- minOffsetFound = partition.Info.StartingOffset.QuadPart;
-
- candidatePartition = partition;
-
- candidateForHiddenOSFound = true;
- }
- }
-
- if (!candidateForHiddenOSFound)
- {
- throw ErrorException (wstring (GetString ("NO_PARTITION_FOLLOWS_BOOT_PARTITION"))
- + GetRemarksOnHiddenOS(), SRC_POS);
- }
-
- if (config.SystemPartition.Info.PartitionLength.QuadPart > TC_MAX_FAT_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
- {
- if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS)
- {
- throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS_NTFS"))
- + GetRemarksOnHiddenOS(), SRC_POS);
- }
- }
- else if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT)
- {
- throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS"))
- + GetRemarksOnHiddenOS(), SRC_POS);
- }
- }
- else
- {
- // No active partition on the system drive
- throw ErrorException ("SYSTEM_PARTITION_NOT_ACTIVE", SRC_POS);
- }
-
- HiddenOSCandidatePartition = candidatePartition;
- return candidatePartition;
- }
-
-
- DWORD BootEncryption::GetDriverServiceStartType ()
- {
- DWORD startType;
- throw_sys_if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", L"Start", &startType));
- return startType;
- }
-
-
- wstring BootEncryption::GetRemarksOnHiddenOS ()
- {
- return (wstring (L"\n\n")
- + GetString ("TWO_SYSTEMS_IN_ONE_PARTITION_REMARK")
- + L"\n\n"
- + GetString ("FOR_MORE_INFO_ON_PARTITIONS"));
- }
-
-
- void BootEncryption::SetDriverServiceStartType (DWORD startType)
- {
- if (!IsAdmin() && IsUacSupported())
- {
- Elevator::SetDriverServiceStartType (startType);
- return;
- }
-
- BOOL startOnBoot = (startType == SERVICE_BOOT_START);
-
- SC_HANDLE serviceManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
- throw_sys_if (!serviceManager);
-
- finally_do_arg (SC_HANDLE, serviceManager, { CloseServiceHandle (finally_arg); });
-
- SC_HANDLE service = OpenService (serviceManager, L"veracrypt", SERVICE_CHANGE_CONFIG);
- throw_sys_if (!service);
-
- finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); });
-
- // Windows versions preceding Vista can be installed on FAT filesystem which does not
- // support long filenames during boot. Convert the driver path to short form if required.
- wstring driverPath;
- if (startOnBoot && !IsOSAtLeast (WIN_VISTA))
- {
- wchar_t pathBuf[MAX_PATH];
- wchar_t filesystem[128];
-
- wstring path (GetWindowsDirectory());
- path += L"\\drivers\\veracrypt.sys";
-
- if (GetVolumePathName (path.c_str(), pathBuf, ARRAYSIZE (pathBuf))
- && GetVolumeInformation (pathBuf, NULL, 0, NULL, NULL, NULL, filesystem, ARRAYSIZE(filesystem))
- && wmemcmp (filesystem, L"FAT", 3) == 0)
- {
- throw_sys_if (GetShortPathName (path.c_str(), pathBuf, ARRAYSIZE (pathBuf)) == 0);
-
- // Convert absolute path to relative to the Windows directory
- driverPath = pathBuf;
- driverPath = driverPath.substr (driverPath.rfind (L"\\", driverPath.rfind (L"\\", driverPath.rfind (L"\\") - 1) - 1) + 1);
- }
- }
-
- throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
- startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL,
- driverPath.empty() ? NULL : driverPath.c_str(),
- startOnBoot ? L"Filter" : NULL,
- NULL, NULL, NULL, NULL, NULL));
-
- // ChangeServiceConfig() rejects SERVICE_BOOT_START with ERROR_INVALID_PARAMETER
- throw_sys_if (!WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", L"Start", startType));
- }
-
-
- void BootEncryption::ProbeRealSystemDriveSize ()
- {
- if (RealSystemDriveSizeValid)
- return;
-
- GetSystemDriveConfiguration();
-
- ProbeRealDriveSizeRequest request;
- StringCchCopyW (request.DeviceName, ARRAYSIZE (request.DeviceName), DriveConfig.DrivePartition.DevicePath.c_str());
-
- CallDriver (TC_IOCTL_PROBE_REAL_DRIVE_SIZE, &request, sizeof (request), &request, sizeof (request));
- DriveConfig.DrivePartition.Info.PartitionLength = request.RealDriveSize;
-
- RealSystemDriveSizeValid = true;
-
- if (request.TimeOut)
- throw TimeOut (SRC_POS);
- }
-
-
- void BootEncryption::InvalidateCachedSysDriveProperties ()
- {
- DriveConfigValid = false;
- RealSystemDriveSizeValid = false;
- }
-
-
- PartitionList BootEncryption::GetDrivePartitions (int driveNumber)
- {
- PartitionList partList;
-
- for (int partNumber = 0; partNumber < 64; ++partNumber)
- {
- wstringstream partPath;
- partPath << L"\\Device\\Harddisk" << driveNumber << L"\\Partition" << partNumber;
-
- DISK_PARTITION_INFO_STRUCT diskPartInfo = {0};
- StringCchCopyW (diskPartInfo.deviceName, ARRAYSIZE (diskPartInfo.deviceName), partPath.str().c_str());
-
- try
- {
- CallDriver (TC_IOCTL_GET_DRIVE_PARTITION_INFO, &diskPartInfo, sizeof (diskPartInfo), &diskPartInfo, sizeof (diskPartInfo));
- }
- catch (...)
- {
- continue;
- }
-
- if ( (diskPartInfo.IsGPT == TRUE || diskPartInfo.IsGPT == FALSE)
- && (diskPartInfo.IsDynamic == TRUE || diskPartInfo.IsDynamic == FALSE)
- && (diskPartInfo.partInfo.BootIndicator == TRUE || diskPartInfo.partInfo.BootIndicator == FALSE)
- && (diskPartInfo.partInfo.RecognizedPartition == TRUE || diskPartInfo.partInfo.RecognizedPartition == FALSE)
- && (diskPartInfo.partInfo.RewritePartition == TRUE || diskPartInfo.partInfo.RewritePartition == FALSE)
- && (diskPartInfo.partInfo.StartingOffset.QuadPart >= 0)
- && (diskPartInfo.partInfo.PartitionLength.QuadPart >= 0)
- )
- {
- Partition part;
- part.DevicePath = partPath.str();
- part.Number = partNumber;
- part.Info = diskPartInfo.partInfo;
- part.IsGPT = diskPartInfo.IsGPT;
-
- // Mount point
- int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) partPath.str().c_str());
-
- if (driveNumber >= 0)
- {
- part.MountPoint += (wchar_t) (driveNumber + L'A');
- part.MountPoint += L":";
- }
-
- // Volume ID
- wchar_t volumePath[TC_MAX_PATH];
- if (ResolveSymbolicLink ((wchar_t *) partPath.str().c_str(), volumePath, sizeof(volumePath)))
- {
- wchar_t volumeName[TC_MAX_PATH];
- HANDLE fh = FindFirstVolumeW (volumeName, array_capacity (volumeName));
- if (fh != INVALID_HANDLE_VALUE)
- {
- do
- {
- wstring volumeNameStr = volumeName;
- wchar_t devicePath[TC_MAX_PATH];
-
- if (QueryDosDeviceW (volumeNameStr.substr (4, volumeNameStr.size() - 1 - 4).c_str(), devicePath, array_capacity (devicePath)) != 0
- && wcscmp (volumePath, devicePath) == 0)
- {
- part.VolumeNameId = volumeName;
- break;
- }
-
- } while (FindNextVolumeW (fh, volumeName, array_capacity (volumeName)));
-
- FindVolumeClose (fh);
- }
- }
-
- partList.push_back (part);
- }
- }
-
- return partList;
- }
-
-
- DISK_GEOMETRY BootEncryption::GetDriveGeometry (int driveNumber)
- {
- wstringstream devName;
- devName << L"\\Device\\Harddisk" << driveNumber << L"\\Partition0";
-
- DISK_GEOMETRY geometry;
- throw_sys_if (!::GetDriveGeometry (devName.str().c_str(), &geometry));
- return geometry;
- }
-
-
- wstring BootEncryption::GetWindowsDirectory ()
- {
- wchar_t buf[MAX_PATH];
- throw_sys_if (GetSystemDirectory (buf, ARRAYSIZE (buf)) == 0);
-
- return wstring (buf);
- }
-
-
-
- uint16 BootEncryption::GetInstalledBootLoaderVersion ()
- {
- uint16 version;
- CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version));
- return version;
- }
-
- void BootEncryption::GetInstalledBootLoaderFingerprint (byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE])
- {
- BootLoaderFingerprintRequest request;
- CallDriver (VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT, NULL, 0, &request, sizeof (request));
- memcpy (fingerprint, request.Fingerprint, sizeof (request.Fingerprint));
- }
-
- // Note that this does not require admin rights (it just requires the driver to be running)
- bool BootEncryption::IsBootLoaderOnDrive (wchar_t *devicePath)
- {
- try
- {
- OPEN_TEST_STRUCT openTestStruct;
- memset (&openTestStruct, 0, sizeof (openTestStruct));
- DWORD dwResult;
-
- StringCchCopyW (&openTestStruct.wszFileName[0], ARRAYSIZE(openTestStruct.wszFileName),devicePath);
-
- openTestStruct.bDetectTCBootLoader = TRUE;
-
- return (DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST,
- &openTestStruct, sizeof (OPEN_TEST_STRUCT),
- &openTestStruct, sizeof (OPEN_TEST_STRUCT),
- &dwResult, NULL) && openTestStruct.TCBootLoaderDetected);
- }
- catch (...)
- {
- return false;
- }
- }
-
-
- BootEncryptionStatus BootEncryption::GetStatus ()
- {
- /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */
-
- BootEncryptionStatus status;
- CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status));
- return status;
- }
-
-
- void BootEncryption::GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties)
- {
- if (properties == NULL)
- throw ParameterIncorrect (SRC_POS);
-
- CallDriver (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES, NULL, 0, properties, sizeof (*properties));
- }
-
-
- bool BootEncryption::IsHiddenSystemRunning ()
- {
- int hiddenSystemStatus;
-
- CallDriver (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING, nullptr, 0, &hiddenSystemStatus, sizeof (hiddenSystemStatus));
- return hiddenSystemStatus != 0;
- }
-
-
- bool BootEncryption::SystemDriveContainsPartitionType (byte type)
- {
- Device device (GetSystemDriveConfiguration().DevicePath, true);
- device.CheckOpened (SRC_POS);
-
- byte mbrBuf[TC_SECTOR_SIZE_BIOS];
- device.SeekAt (0);
- device.Read (mbrBuf, sizeof (mbrBuf));
-
- MBR *mbr = reinterpret_cast <MBR *> (mbrBuf);
- if (mbr->Signature != 0xaa55)
- throw ParameterIncorrect (SRC_POS);
-
- for (size_t i = 0; i < array_capacity (mbr->Partitions); ++i)
- {
- if (mbr->Partitions[i].Type == type)
- return true;
- }
-
- return false;
- }
-
-
- bool BootEncryption::SystemDriveContainsExtendedPartition ()
- {
- return SystemDriveContainsPartitionType (PARTITION_EXTENDED) || SystemDriveContainsPartitionType (PARTITION_XINT13_EXTENDED);
- }
-
-
- bool BootEncryption::SystemDriveContainsNonStandardPartitions ()
- {
- for (int partitionType = 1; partitionType <= 0xff; ++partitionType)
- {
- switch (partitionType)
- {
- case PARTITION_FAT_12:
- case PARTITION_FAT_16:
- case PARTITION_EXTENDED:
- case PARTITION_HUGE:
- case PARTITION_IFS:
- case PARTITION_FAT32:
- case PARTITION_FAT32_XINT13:
- case PARTITION_XINT13:
- case PARTITION_XINT13_EXTENDED:
- continue;
- }
-
- if (SystemDriveContainsPartitionType ((byte) partitionType))
- return true;
- }
-
- return false;
- }
-
-
- bool BootEncryption::SystemDriveIsDynamic ()
- {
- GetSystemDriveConfigurationRequest request;
- StringCchCopyW (request.DevicePath, ARRAYSIZE (request.DevicePath), GetSystemDriveConfiguration().DeviceKernelPath.c_str());
-
- CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request));
- return request.DriveIsDynamic ? true : false;
- }
-
-
- SystemDriveConfiguration BootEncryption::GetSystemDriveConfiguration ()
- {
- if (DriveConfigValid)
- return DriveConfig;
-
- SystemDriveConfiguration config;
-
- wstring winDir = GetWindowsDirectory();
-
- // Scan all drives
- for (int driveNumber = 0; driveNumber < 32; ++driveNumber)
- {
- bool windowsFound = false;
- bool activePartitionFound = false;
- config.ExtraBootPartitionPresent = false;
- config.SystemLoaderPresent = false;
-
- PartitionList partitions = GetDrivePartitions (driveNumber);
- foreach (const Partition &part, partitions)
- {
- if (!part.MountPoint.empty()
- && (_waccess ((part.MountPoint + L"\\bootmgr").c_str(), 0) == 0 || _waccess ((part.MountPoint + L"\\ntldr").c_str(), 0) == 0))
- {
- config.SystemLoaderPresent = true;
- }
- else if (!part.VolumeNameId.empty()
- && (_waccess ((part.VolumeNameId + L"\\bootmgr").c_str(), 0) == 0 || _waccess ((part.VolumeNameId + L"\\ntldr").c_str(), 0) == 0))
- {
- config.SystemLoaderPresent = true;
- }
-
- if (!windowsFound && !part.MountPoint.empty() && ToUpperCase (winDir).find (ToUpperCase (part.MountPoint)) == 0)
- {
- config.SystemPartition = part;
- windowsFound = true;
- }
-
- if (!activePartitionFound && part.Info.BootIndicator)
- {
- activePartitionFound = true;
-
- if (part.Info.PartitionLength.QuadPart > 0 && part.Info.PartitionLength.QuadPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE)
- config.ExtraBootPartitionPresent = true;
- }
- }
-
- if (windowsFound)
- {
- config.DriveNumber = driveNumber;
-
- wstringstream ss;
- ss << L"PhysicalDrive" << driveNumber;
- config.DevicePath = ss.str();
-
- wstringstream kernelPath;
- kernelPath << L"\\Device\\Harddisk" << driveNumber << L"\\Partition0";
- config.DeviceKernelPath = kernelPath.str();
-
- config.DrivePartition = partitions.front();
- partitions.pop_front();
- config.Partitions = partitions;
-
- config.InitialUnallocatedSpace = 0x7fffFFFFffffFFFFull;
- config.TotalUnallocatedSpace = config.DrivePartition.Info.PartitionLength.QuadPart;
-
- foreach (const Partition &part, config.Partitions)
- {
- if (part.Info.StartingOffset.QuadPart < config.InitialUnallocatedSpace)
- config.InitialUnallocatedSpace = part.Info.StartingOffset.QuadPart;
-
- config.TotalUnallocatedSpace -= part.Info.PartitionLength.QuadPart;
- }
-
- DriveConfig = config;
- DriveConfigValid = true;
- return DriveConfig;
- }
- }
-
- throw ParameterIncorrect (SRC_POS);
- }
-
-
- bool BootEncryption::SystemPartitionCoversWholeDrive ()
- {
- SystemDriveConfiguration config = GetSystemDriveConfiguration();
-
- if (IsOSAtLeast (WIN_7)
- && config.Partitions.size() == 2
- && config.ExtraBootPartitionPresent
- && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 164 * BYTES_PER_MB)
- {
- return true;
- }
-
- return config.Partitions.size() == 1
- && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 64 * BYTES_PER_MB;
- }
-
-
- uint32 BootEncryption::GetChecksum (byte *data, size_t size)
- {
- uint32 sum = 0;
-
- while (size-- > 0)
- {
- sum += *data++;
- sum = _rotl (sum, 1);
- }
-
- return sum;
- }
-
-
- void BootEncryption::CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation)
- {
- if (bufferSize < TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE)
- throw ParameterIncorrect (SRC_POS);
-
- ZeroMemory (buffer, bufferSize);
-
- int ea = 0;
- int pkcs5_prf = 0;
- if (GetStatus().DriveMounted)
- {
- try
- {
- GetBootEncryptionAlgorithmNameRequest request;
- // since we added new field to GetBootEncryptionAlgorithmNameRequest since version 1.0f
- // we zero all the structure so that if we are talking to an older driver, the field
- // BootPrfAlgorithmName will be an empty string
- ZeroMemory(&request, sizeof(request));
- CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME, NULL, 0, &request, sizeof (request));
-
- if (_stricmp (request.BootEncryptionAlgorithmName, "AES") == 0)
- ea = AES;
- else if (_stricmp (request.BootEncryptionAlgorithmName, "Serpent") == 0)
- ea = SERPENT;
- else if (_stricmp (request.BootEncryptionAlgorithmName, "Twofish") == 0)
- ea = TWOFISH;
-
- if (_stricmp(request.BootPrfAlgorithmName, "SHA-256") == 0)
- pkcs5_prf = SHA256;
- else if (_stricmp(request.BootPrfAlgorithmName, "RIPEMD-160") == 0)
- pkcs5_prf = RIPEMD160;
- else if (strlen(request.BootPrfAlgorithmName) == 0) // case of version < 1.0f
- pkcs5_prf = RIPEMD160;
- }
- catch (...)
- {
- try
- {
- VOLUME_PROPERTIES_STRUCT properties;
- GetVolumeProperties (&properties);
- ea = properties.ea;
- pkcs5_prf = properties.pkcs5;
- }
- catch (...) { }
- }
- }
- else
- {
- if (SelectedEncryptionAlgorithmId == 0 || SelectedPrfAlgorithmId == 0)
- throw ParameterIncorrect (SRC_POS);
-
- ea = SelectedEncryptionAlgorithmId;
- pkcs5_prf = SelectedPrfAlgorithmId;
- }
-
- // Only RIPEMD160 and SHA-256 are supported for boot loader
- if (pkcs5_prf != RIPEMD160 && pkcs5_prf != SHA256)
- throw ParameterIncorrect (SRC_POS);
-
- int bootSectorId = 0;
- int bootLoaderId = 0;
-
- if (pkcs5_prf == SHA256)
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SHA2 : IDR_BOOT_SECTOR_SHA2;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SHA2 : IDR_BOOT_LOADER_SHA2;
- }
- else
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR : IDR_BOOT_SECTOR;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER : IDR_BOOT_LOADER;
- }
-
- switch (ea)
- {
- case AES:
- if (pkcs5_prf == SHA256)
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES_SHA2 : IDR_BOOT_SECTOR_AES_SHA2;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES_SHA2 : IDR_BOOT_LOADER_AES_SHA2;
- }
- else
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES : IDR_BOOT_SECTOR_AES;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES : IDR_BOOT_LOADER_AES;
- }
- break;
-
- case SERPENT:
- if (pkcs5_prf == SHA256)
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT_SHA2 : IDR_BOOT_SECTOR_SERPENT_SHA2;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT_SHA2 : IDR_BOOT_LOADER_SERPENT_SHA2;
- }
- else
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT : IDR_BOOT_SECTOR_SERPENT;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT : IDR_BOOT_LOADER_SERPENT;
- }
- break;
-
- case TWOFISH:
- if (pkcs5_prf == SHA256)
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH_SHA2 : IDR_BOOT_SECTOR_TWOFISH_SHA2;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH_SHA2 : IDR_BOOT_LOADER_TWOFISH_SHA2;
- }
- else
- {
- bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH : IDR_BOOT_SECTOR_TWOFISH;
- bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH : IDR_BOOT_LOADER_TWOFISH;
- }
- break;
- }
-
- // Boot sector
- DWORD size;
- byte *bootSecResourceImg = MapResource (L"BIN", bootSectorId, &size);
- if (!bootSecResourceImg || size != TC_SECTOR_SIZE_BIOS)
- throw ParameterIncorrect (SRC_POS);
-
- memcpy (buffer, bootSecResourceImg, size);
-
- *(uint16 *) (buffer + TC_BOOT_SECTOR_VERSION_OFFSET) = BE16 (VERSION_NUM);
-
- if (IsOSAtLeast (WIN_VISTA))
- buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER;
-
- if (rescueDisk && (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION))
- buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION;
-
- // Checksum of the backup header of the outer volume for the hidden system
- if (hiddenOSCreation)
- {
- Device device (GetSystemDriveConfiguration().DevicePath);
- device.CheckOpened (SRC_POS);
- byte headerSector[TC_SECTOR_SIZE_BIOS];
-
- device.SeekAt (HiddenOSCandidatePartition.Info.StartingOffset.QuadPart + HiddenOSCandidatePartition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_GROUP_SIZE + TC_VOLUME_HEADER_EFFECTIVE_SIZE);
- device.Read (headerSector, sizeof (headerSector));
-
- *(uint32 *) (buffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET) = GetCrc32 (headerSector, sizeof (headerSector));
- }
-
- // Decompressor
- byte *decompressor = MapResource (L"BIN", IDR_BOOT_LOADER_DECOMPRESSOR, &size);
- if (!decompressor || size > TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
- throw ParameterIncorrect (SRC_POS);
-
- memcpy (buffer + TC_SECTOR_SIZE_BIOS, decompressor, size);
-
- // Compressed boot loader
- byte *bootLoader = MapResource (L"BIN", bootLoaderId, &size);
- if (!bootLoader || size > TC_MAX_BOOT_LOADER_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
- throw ParameterIncorrect (SRC_POS);
-
- memcpy (buffer + TC_SECTOR_SIZE_BIOS + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS, bootLoader, size);
-
- // Boot loader and decompressor checksum
- *(uint16 *) (buffer + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET) = static_cast <uint16> (size);
- *(uint32 *) (buffer + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET) = GetChecksum (buffer + TC_SECTOR_SIZE_BIOS,
- TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS + size);
-
- // Backup of decompressor and boot loader
- if (size + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS <= TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
- {
- memcpy (buffer + TC_SECTOR_SIZE_BIOS + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS,
- buffer + TC_SECTOR_SIZE_BIOS, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS);
-
- buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE;
- }
- else if (!rescueDisk && bootLoaderId != IDR_BOOT_LOADER && bootLoaderId != IDR_BOOT_LOADER_SHA2)
- {
- throw ParameterIncorrect (SRC_POS);
- }
- }
-
-
- void BootEncryption::ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig, string *customUserMessage, uint16 *bootLoaderVersion)
- {
- if (config && bufLength < TC_BOOT_CFG_FLAG_AREA_SIZE)
- throw ParameterIncorrect (SRC_POS);
-
- GetSystemDriveConfigurationRequest request;
- StringCchCopyW (request.DevicePath, ARRAYSIZE (request.DevicePath), GetSystemDriveConfiguration().DeviceKernelPath.c_str());
-
- try
- {
- CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request));
- if (config)
- *config = request.Configuration;
-
- if (userConfig)
- *userConfig = request.UserConfiguration;
-
- if (customUserMessage)
- {
- request.CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0;
- *customUserMessage = request.CustomUserMessage;
- }
-
- if (bootLoaderVersion)
- *bootLoaderVersion = request.BootLoaderVersion;
- }
- catch (...)
- {
- if (config)
- *config = 0;
-
- if (userConfig)
- *userConfig = 0;
-
- if (customUserMessage)
- customUserMessage->clear();
-
- if (bootLoaderVersion)
- *bootLoaderVersion = 0;
- }
- }
-
-
- void BootEncryption::WriteBootSectorConfig (const byte newConfig[])
- {
- Device device (GetSystemDriveConfiguration().DevicePath);
- device.CheckOpened (SRC_POS);
- byte mbr[TC_SECTOR_SIZE_BIOS];
-
- device.SeekAt (0);
- device.Read (mbr, sizeof (mbr));
-
- memcpy (mbr + TC_BOOT_SECTOR_CONFIG_OFFSET, newConfig, TC_BOOT_CFG_FLAG_AREA_SIZE);
-
- device.SeekAt (0);
- device.Write (mbr, sizeof (mbr));
-
- byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS];
- device.SeekAt (0);
- device.Read (mbrVerificationBuf, sizeof (mbr));
-
- if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
- throw ErrorException ("ERROR_MBR_PROTECTED", SRC_POS);
- }
-
-
- void BootEncryption::WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim)
- {
- Device device (GetSystemDriveConfiguration().DevicePath);
- device.CheckOpened (SRC_POS);
- byte mbr[TC_SECTOR_SIZE_BIOS];
-
- device.SeekAt (0);
- device.Read (mbr, sizeof (mbr));
-
- if (!BufferContainsString (mbr, sizeof (mbr), TC_APP_NAME)
- || BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET)) != VERSION_NUM)
- {
- return;
- }
-
- mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = userConfig;
-
- memset (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, 0, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
-
- if (!customUserMessage.empty())
- {
- if (customUserMessage.size() > TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)
- throw ParameterIncorrect (SRC_POS);
-
- memcpy (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, customUserMessage.c_str(), customUserMessage.size());
- }
-
- if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
- {
- // PIM for pre-boot authentication can be encoded on two bytes since its maximum
- // value is 65535 (0xFFFF)
- memcpy (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
- }
- else
- memset (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, 0, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
-
- device.SeekAt (0);
- device.Write (mbr, sizeof (mbr));
-
- byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS];
- device.SeekAt (0);
- device.Read (mbrVerificationBuf, sizeof (mbr));
-
- if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
- throw ErrorException ("ERROR_MBR_PROTECTED", SRC_POS);
- }
-
-
- unsigned int BootEncryption::GetHiddenOSCreationPhase ()
- {
- byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];
-
- ReadBootSectorConfig (configFlags, sizeof(configFlags));
-
- return (configFlags[0] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE);
- }
-
-
- void BootEncryption::SetHiddenOSCreationPhase (unsigned int newPhase)
- {
-#if TC_BOOT_CFG_FLAG_AREA_SIZE != 1
-# error TC_BOOT_CFG_FLAG_AREA_SIZE != 1; revise GetHiddenOSCreationPhase() and SetHiddenOSCreationPhase()
-#endif
- byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];
-
- ReadBootSectorConfig (configFlags, sizeof(configFlags));
-
- configFlags[0] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
-
- configFlags[0] |= newPhase;
-
- WriteBootSectorConfig (configFlags);
- }
-
-
-#ifndef SETUP
-
- void BootEncryption::StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm)
- {
- if (!IsHiddenOSRunning())
- throw ParameterIncorrect (SRC_POS);
-
- WipeDecoySystemRequest request;
- ZeroMemory (&request, sizeof (request));
-
- request.WipeAlgorithm = wipeAlgorithm;
-
- if (Randinit() != ERR_SUCCESS)
- {
- if (CryptoAPILastError == ERROR_SUCCESS)
- throw RandInitFailed (SRC_POS, GetLastError ());
- else
- throw CryptoApiFailed (SRC_POS, CryptoAPILastError);
- }
-
- /* force the display of the random enriching dialog */
- SetRandomPoolEnrichedByUserStatus (FALSE);
-
- UserEnrichRandomPool (ParentWindow);
-
- if (!RandgetBytes (ParentWindow, request.WipeKey, sizeof (request.WipeKey), TRUE))
- throw ParameterIncorrect (SRC_POS);
-
- CallDriver (TC_IOCTL_START_DECOY_SYSTEM_WIPE, &request, sizeof (request), NULL, 0);
-
- burn (&request, sizeof (request));
- }
-
-
- void BootEncryption::AbortDecoyOSWipe ()
- {
- CallDriver (TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE);
- }
-
-
- DecoySystemWipeStatus BootEncryption::GetDecoyOSWipeStatus ()
- {
- DecoySystemWipeStatus status;
- CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS, NULL, 0, &status, sizeof (status));
- return status;
- }
-
-
- void BootEncryption::CheckDecoyOSWipeResult ()
- {
- CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT);
- }
-
-
- void BootEncryption::WipeHiddenOSCreationConfig ()
- {
- if (IsHiddenOSRunning())
- throw ParameterIncorrect (SRC_POS);
-
- if (Randinit() != ERR_SUCCESS)
- {
- if (CryptoAPILastError == ERROR_SUCCESS)
- throw RandInitFailed (SRC_POS, GetLastError ());
- else
- throw CryptoApiFailed (SRC_POS, CryptoAPILastError);
- }
-
- Device device (GetSystemDriveConfiguration().DevicePath);
- device.CheckOpened(SRC_POS);
- byte mbr[TC_SECTOR_SIZE_BIOS];
-
- device.SeekAt (0);
- device.Read (mbr, sizeof (mbr));
-
- finally_do_arg (BootEncryption *, this,
- {
- try
- {
- finally_arg->SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
- } catch (...) { }
- });
-
-#if PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE
-# error PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE
-#endif
-
- byte randData[PRAND_DISK_WIPE_PASSES];
- if (!RandgetBytes (ParentWindow, randData, sizeof (randData), FALSE))
- throw ParameterIncorrect (SRC_POS);
-
- for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
- {
- for (int i = 0; i < TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE; ++i)
- {
- mbr[TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + i] = randData[wipePass];
- }
-
- mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
- mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] |= randData[wipePass] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
-
- if (wipePass == PRAND_DISK_WIPE_PASSES - 1)
- memset (mbr + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, 0, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE);
-
- device.SeekAt (0);
- device.Write (mbr, sizeof (mbr));
- }
-
- for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES/4 + 1; wipePass++)
- {
- SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
- SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_CLONING);
- SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPING);
- SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPED);
- }
- SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
- }
-
-#endif // !SETUP
-
-
- void BootEncryption::InstallBootLoader (bool preserveUserConfig, bool hiddenOSCreation)
- {
- Device device (GetSystemDriveConfiguration().DevicePath);
- device.CheckOpened (SRC_POS);
-
- InstallBootLoader (device, preserveUserConfig, hiddenOSCreation);
- }
-
- void BootEncryption::InstallBootLoader (Device& device, bool preserveUserConfig, bool hiddenOSCreation, int pim)
- {
- byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
- CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, hiddenOSCreation);
-
- // Write MBR
- byte mbr[TC_SECTOR_SIZE_BIOS];
-
- device.SeekAt (0);
- device.Read (mbr, sizeof (mbr));
-
- if (preserveUserConfig && BufferContainsString (mbr, sizeof (mbr), TC_APP_NAME))
- {
- uint16 version = BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET));
- if (version != 0)
- {
- bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
- memcpy (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
-
- if (bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
- {
- if (pim >= 0)
- {
- memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
- }
- else
- memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
- }
- }
- }
-
- memcpy (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE);
-
- device.SeekAt (0);
- device.Write (mbr, sizeof (mbr));
-
- byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS];
- device.SeekAt (0);
- device.Read (mbrVerificationBuf, sizeof (mbr));
-
- if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
- throw ErrorException ("ERROR_MBR_PROTECTED", SRC_POS);
-
- // Write boot loader
- device.SeekAt (TC_SECTOR_SIZE_BIOS);
- device.Write (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, sizeof (bootLoaderBuf) - TC_SECTOR_SIZE_BIOS);
- }
-
-#ifndef SETUP
- bool BootEncryption::CheckBootloaderFingerprint (bool bSilent)
- {
- byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
- byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
- byte expectedFingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
- bool bRet = false;
-
- try
- {
- // read bootloader fingerprint
- GetInstalledBootLoaderFingerprint (fingerprint);
-
- // compute expected fingerprint
- CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, false);
- ::ComputeBootloaderFingerprint (bootLoaderBuf, sizeof (bootLoaderBuf), expectedFingerprint);
-
- // compare values
- if (0 == memcmp (fingerprint, expectedFingerprint, sizeof (expectedFingerprint)))
- {
- bRet = true;
- }
- }
- catch (SystemException &e)
- {
- if (!bSilent && (GetLastError () != ERROR_INVALID_IMAGE_HASH))
- e.Show (ParentWindow);
- }
- catch (Exception& e)
- {
- if (!bSilent)
- e.Show (ParentWindow);
- }
-
- return bRet;
- }
-#endif
-
- wstring BootEncryption::GetSystemLoaderBackupPath ()
- {
- WCHAR pathBuf[MAX_PATH];
-
- throw_sys_if (!SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, pathBuf)));
-
- wstring path = wstring (pathBuf) + L"\\" _T(TC_APP_NAME);
- CreateDirectory (path.c_str(), NULL);
-
- return path + L'\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME;
- }
-
-
- void BootEncryption::RenameDeprecatedSystemLoaderBackup ()
- {
- WCHAR pathBuf[MAX_PATH];
-
- if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA, NULL, 0, pathBuf)))
- {
- wstring path = wstring (pathBuf) + L"\\" _T(TC_APP_NAME) + L'\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY;
-
- if (FileExists (path.c_str()) && !FileExists (GetSystemLoaderBackupPath().c_str()))
- throw_sys_if (_wrename (path.c_str(), GetSystemLoaderBackupPath().c_str()) != 0);
- }
- }
-
-
-#ifndef SETUP
- void BootEncryption::CreateRescueIsoImage (bool initialSetup, const wstring &isoImagePath)
- {
- BootEncryptionStatus encStatus = GetStatus();
- if (encStatus.SetupInProgress)
- throw ParameterIncorrect (SRC_POS);
-
- Buffer imageBuf (RescueIsoImageSize);
-
- byte *image = imageBuf.Ptr();
- memset (image, 0, RescueIsoImageSize);
-
- // Primary volume descriptor
- const char* szPrimVolDesc = "\001CD001\001";
- const char* szPrimVolLabel = "VeraCrypt Rescue Disk ";
- memcpy (image + 0x8000, szPrimVolDesc, strlen(szPrimVolDesc) + 1);
- memcpy (image + 0x7fff + 41, szPrimVolLabel, strlen(szPrimVolLabel) + 1);
- *(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048;
- *(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048);
- image[0x7fff + 121] = 1;
- image[0x7fff + 124] = 1;
- image[0x7fff + 125] = 1;
- image[0x7fff + 128] = 1;
- image[0x7fff + 130] = 8;
- image[0x7fff + 131] = 8;
-
- image[0x7fff + 133] = 10;
- image[0x7fff + 140] = 10;
- image[0x7fff + 141] = 0x14;
- image[0x7fff + 157] = 0x22;
- image[0x7fff + 159] = 0x18;
-
- // Boot record volume descriptor
- const char* szBootRecDesc = "CD001\001EL TORITO SPECIFICATION";
- memcpy (image + 0x8801, szBootRecDesc, strlen(szBootRecDesc) + 1);
- image[0x8800 + 0x47] = 0x19;
-
- // Volume descriptor set terminator
- const char* szVolDescTerm = "\377CD001\001";
- memcpy (image + 0x9000, szVolDescTerm, strlen(szVolDescTerm) + 1);
-
- // Path table
- image[0xA000 + 0] = 1;
- image[0xA000 + 2] = 0x18;
- image[0xA000 + 6] = 1;
-
- // Root directory
- image[0xc000 + 0] = 0x22;
- image[0xc000 + 2] = 0x18;
- image[0xc000 + 9] = 0x18;
- image[0xc000 + 11] = 0x08;
- image[0xc000 + 16] = 0x08;
- image[0xc000 + 25] = 0x02;
- image[0xc000 + 28] = 0x01;
- image[0xc000 + 31] = 0x01;
- image[0xc000 + 32] = 0x01;
- image[0xc000 + 34] = 0x22;
- image[0xc000 + 36] = 0x18;
- image[0xc000 + 43] = 0x18;
- image[0xc000 + 45] = 0x08;
- image[0xc000 + 50] = 0x08;
- image[0xc000 + 59] = 0x02;
- image[0xc000 + 62] = 0x01;
- *(uint32 *) (image + 0xc000 + 65) = 0x010101;
-
- // Validation entry
- image[0xc800] = 1;
- int offset = 0xc800 + 0x1c;
- image[offset++] = 0xaa;
- image[offset++] = 0x55;
- image[offset++] = 0x55;
- image[offset] = 0xaa;
-
- // Initial entry
- offset = 0xc820;
- image[offset++] = 0x88;
- image[offset++] = 2;
- image[0xc820 + 6] = 1;
- image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR;
-
- // TrueCrypt Boot Loader
- CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, true);
-
- // Volume header
- if (initialSetup)
- {
- if (!RescueVolumeHeaderValid)
- throw ParameterIncorrect (SRC_POS);
-
- memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
- }
- else
- {
- Device bootDevice (GetSystemDriveConfiguration().DevicePath, true);
- bootDevice.CheckOpened (SRC_POS);
- bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
- bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
- }
-
- // Original system loader
- try
- {
- File sysBakFile (GetSystemLoaderBackupPath(), true);
- sysBakFile.CheckOpened (SRC_POS);
- sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE);
-
- image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER;
- }
- catch (Exception &e)
- {
- e.Show (ParentWindow);
- Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK", ParentWindow);
- }
-
- // Boot loader backup
- CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, false);
-
- RescueIsoImage = new byte[RescueIsoImageSize];
- if (!RescueIsoImage)
- throw bad_alloc();
- memcpy (RescueIsoImage, image, RescueIsoImageSize);
-
- if (!isoImagePath.empty())
- {
- File isoFile (isoImagePath, false, true);
- isoFile.Write (image, RescueIsoImageSize);
- }
- }
-#endif
-
-
- bool BootEncryption::IsCDRecorderPresent ()
- {
- ICDBurn* pICDBurn;
- BOOL bHasRecorder = FALSE;
-
- if (SUCCEEDED( CoCreateInstance (CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn)))
- {
- if (pICDBurn->HasRecordableDrive (&bHasRecorder) != S_OK)
- {
- bHasRecorder = FALSE;
- }
- pICDBurn->Release();
- }
- return bHasRecorder? true : false;
- }
-
-
- bool BootEncryption::VerifyRescueDisk ()
- {
- if (!RescueIsoImage)
- throw ParameterIncorrect (SRC_POS);
-
- for (WCHAR drive = L'Z'; drive >= L'C'; --drive)
- {
- try
- {
- WCHAR rootPath[4] = { drive, L':', L'\\', 0};
- UINT driveType = GetDriveType (rootPath);
- // check that it is a CD/DVD drive or a removable media in case a bootable
- // USB key was created from the rescue disk ISO file
- if ((DRIVE_CDROM == driveType) || (DRIVE_REMOVABLE == driveType))
- {
- rootPath[2] = 0; // remove trailing backslash
-
- Device driveDevice (rootPath, true);
- driveDevice.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 = driveDevice.Read (buffer.Ptr(), (DWORD) buffer.Size());
- if (bytesRead != buffer.Size())
- continue;
-
- if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0)
- return true;
- }
- }
- catch (...) { }
- }
-
- return false;
- }
-
- bool BootEncryption::VerifyRescueDiskIsoImage (const wchar_t* imageFile)
- {
- if (!RescueIsoImage)
- throw ParameterIncorrect (SRC_POS);
-
- try
- {
- File isoFile (imageFile, true);
- isoFile.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 = isoFile.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,
- 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, FALSE, 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);
-
- byte *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);
-
- device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
- device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader));
- }
-
-
- // For synchronous operations use AbortSetupWait()
- void BootEncryption::AbortSetup ()
- {
- CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
- }
-
-
- // For asynchronous operations use AbortSetup()
- void BootEncryption::AbortSetupWait ()
- {
- CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
-
- BootEncryptionStatus encStatus = GetStatus();
-
- while (encStatus.SetupInProgress)
- {
- Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL);
- encStatus = GetStatus();
- }
- }
-
-
- void BootEncryption::BackupSystemLoader ()
- {
- Device device (GetSystemDriveConfiguration().DevicePath, true);
- device.CheckOpened (SRC_POS);
- byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS];
-
- device.SeekAt (0);
- device.Read (bootLoaderBuf, sizeof (bootLoaderBuf));
-
- // Prevent TrueCrypt loader from being backed up
- for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i)
- {
- if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
- {
- if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED", ParentWindow) == IDNO)
- throw UserAbort (SRC_POS);
- return;
- }
- }
-
- File backupFile (GetSystemLoaderBackupPath(), false, true);
- backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
- }
-
-
- void BootEncryption::RestoreSystemLoader ()
- {
- byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS];
-
- File backupFile (GetSystemLoaderBackupPath(), true);
- backupFile.CheckOpened(SRC_POS);
- if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf))
- throw ParameterIncorrect (SRC_POS);
-
- Device device (GetSystemDriveConfiguration().DevicePath);
- device.CheckOpened (SRC_POS);
-
- // Preserve current partition table
- byte mbr[TC_SECTOR_SIZE_BIOS];
- device.SeekAt (0);
- device.Read (mbr, sizeof (mbr));
- memcpy (bootLoaderBuf + TC_MAX_MBR_BOOT_CODE_SIZE, mbr + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbr) - TC_MAX_MBR_BOOT_CODE_SIZE);
-
- device.SeekAt (0);
- device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
- }
-
-#endif // SETUP
-
- void BootEncryption::RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid)
- {
- string filter;
- string filterReg;
- HKEY regKey;
-
- switch (filterType)
- {
- case DriveFilter:
- case VolumeFilter:
- filter = "veracrypt";
- filterReg = "UpperFilters";
- regKey = OpenDeviceClassRegKey (deviceClassGuid);
- throw_sys_if (regKey == INVALID_HANDLE_VALUE);
-
- break;
-
- case DumpFilter:
- if (!IsOSAtLeast (WIN_VISTA))
- return;
-
- filter = "veracrypt.sys";
- filterReg = "DumpFilters";
- SetLastError (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\CrashControl", 0, KEY_READ | KEY_WRITE, &regKey));
- throw_sys_if (GetLastError() != ERROR_SUCCESS);
-
- break;
-
- default:
- throw ParameterIncorrect (SRC_POS);
- }
-
- finally_do_arg (HKEY, regKey, { RegCloseKey (finally_arg); });
-
- if (registerFilter && filterType != DumpFilter)
- {
- // Register class filter below all other filters in the stack
-
- size_t strSize = filter.size() + 1;
- byte regKeyBuf[65536];
- DWORD size = (DWORD) (sizeof (regKeyBuf) - strSize);
-
- // SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly
- StringCchCopyA ((char *) regKeyBuf, ARRAYSIZE(regKeyBuf), filter.c_str());
-
- if (RegQueryValueExA (regKey, filterReg.c_str(), NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS)
- size = 1;
-
- SetLastError (RegSetValueExA (regKey, filterReg.c_str(), 0, REG_MULTI_SZ, regKeyBuf, (DWORD) strSize + size));
- throw_sys_if (GetLastError() != ERROR_SUCCESS);
- }
- else
- {
- RegisterDriverInf (registerFilter, filter, filterReg, ParentWindow, regKey);
- }
- }
-
- void BootEncryption::RegisterFilterDriver (bool registerDriver, FilterType filterType)
- {
- if (!IsAdmin() && IsUacSupported())
- {
- Elevator::RegisterFilterDriver (registerDriver, filterType);
- return;
- }
-
- switch (filterType)
- {
- case DriveFilter:
- RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_DISKDRIVE);
- break;
-
- case VolumeFilter:
- RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_VOLUME);
- RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_FLOPPYDISK);
- break;
-
- case DumpFilter:
- RegisterFilter (registerDriver, filterType);
- break;
-
- default:
- throw ParameterIncorrect (SRC_POS);
- }
- }
-
- void BootEncryption::RegisterSystemFavoritesService (BOOL registerService, BOOL noFileHandling)
- {
- SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
- throw_sys_if (!scm);
- finally_do_arg (SC_HANDLE, scm, { CloseServiceHandle (finally_arg); });
-
- wstring servicePath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", false);
- wstring serviceLegacyPath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", true);
-
- if (registerService)
- {
- try
- {
- RegisterSystemFavoritesService (FALSE, noFileHandling);
- }
- catch (...) { }
-
- if (!noFileHandling)
- {
- wchar_t appPath[TC_MAX_PATH];
- throw_sys_if (!GetModuleFileName (NULL, appPath, ARRAYSIZE (appPath)));
-
- throw_sys_if (!CopyFile (appPath, servicePath.c_str(), FALSE));
- }
-
- SC_HANDLE service = CreateService (scm,
- TC_SYSTEM_FAVORITES_SERVICE_NAME,
- _T(TC_APP_NAME) L" System Favorites",
- SERVICE_ALL_ACCESS,
- SERVICE_WIN32_OWN_PROCESS,
- SERVICE_AUTO_START,
- SERVICE_ERROR_NORMAL,
- (wstring (L"\"") + servicePath + L"\" " TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION).c_str(),
- TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP,
- NULL,
- NULL,
- NULL,
- NULL);
-
- throw_sys_if (!service);
-
- SERVICE_DESCRIPTION description;
- description.lpDescription = L"Mounts VeraCrypt system favorite volumes.";
- ChangeServiceConfig2 (service, SERVICE_CONFIG_DESCRIPTION, &description);
-
- CloseServiceHandle (service);
-
- try
- {
- WriteLocalMachineRegistryString (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, L"Service", FALSE);
- WriteLocalMachineRegistryString (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Network\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, L"Service", FALSE);
-
- SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, true);
- }
- catch (...)
- {
- try
- {
- RegisterSystemFavoritesService (FALSE, noFileHandling);
- }
- catch (...) { }
-
- throw;
- }
- }
- else
- {
- SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, false);
-
- DeleteLocalMachineRegistryKey (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal", TC_SYSTEM_FAVORITES_SERVICE_NAME);
- DeleteLocalMachineRegistryKey (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Network", TC_SYSTEM_FAVORITES_SERVICE_NAME);
-
- SC_HANDLE service = OpenService (scm, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS);
- throw_sys_if (!service);
-
- throw_sys_if (!DeleteService (service));
- CloseServiceHandle (service);
-
- if (!noFileHandling)
- {
- DeleteFile (servicePath.c_str());
- if (serviceLegacyPath != servicePath)
- DeleteFile (serviceLegacyPath.c_str());
- }
- }
- }
-
- void BootEncryption::UpdateSystemFavoritesService ()
- {
- SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
- throw_sys_if (!scm);
-
- finally_do_arg (SC_HANDLE, scm, { CloseServiceHandle (finally_arg); });
-
- wstring servicePath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", false);
-
- // check if service exists
- SC_HANDLE service = OpenService (scm, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS);
- if (service)
- {
- finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); });
- // ensure that its parameters are correct
- throw_sys_if (!ChangeServiceConfig (service,
- SERVICE_WIN32_OWN_PROCESS,
- SERVICE_AUTO_START,
- SERVICE_ERROR_NORMAL,
- (wstring (L"\"") + servicePath + L"\" " TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION).c_str(),
- TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP,
- NULL,
- NULL,
- NULL,
- NULL,
- _T(TC_APP_NAME) L" System Favorites"));
-
- }
- else
- {
- RegisterSystemFavoritesService (TRUE, TRUE);
- }
- }
-
- void BootEncryption::SetDriverConfigurationFlag (uint32 flag, bool state)
- {
- DWORD configMap = ReadDriverConfigurationFlags();
-
- if (state)
- configMap |= flag;
- else
- configMap &= ~flag;
-#ifdef SETUP
- WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, configMap);
-#else
- WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, configMap);
-#endif
- }
-
-#ifndef SETUP
-
- void BootEncryption::RegisterSystemFavoritesService (BOOL registerService)
- {
- if (!IsAdmin() && IsUacSupported())
- {
- Elevator::RegisterSystemFavoritesService (registerService);
- return;
- }
-
- RegisterSystemFavoritesService (registerService, FALSE);
- }
-
- void BootEncryption::CheckRequirements ()
- {
- if (nCurrentOS == WIN_2000)
- throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS", SRC_POS);
-
- if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1)
- throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_VISTA_SP0", SRC_POS);
-
- if (IsNonInstallMode())
- throw ErrorException ("FEATURE_REQUIRES_INSTALLATION", SRC_POS);
-
- SystemDriveConfiguration config = GetSystemDriveConfiguration ();
-
- if (config.SystemPartition.IsGPT)
- throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED", SRC_POS);
-
- if (SystemDriveIsDynamic())
- throw ErrorException ("SYSENC_UNSUPPORTED_FOR_DYNAMIC_DISK", SRC_POS);
-
- if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE)
- throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER", SRC_POS);
-
- DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
-
- if (geometry.BytesPerSector != TC_SECTOR_SIZE_BIOS)
- throw ErrorException ("SYSENC_UNSUPPORTED_SECTOR_SIZE_BIOS", SRC_POS);
-
- bool activePartitionFound = false;
- if (!config.SystemPartition.IsGPT)
- {
- // Determine whether there is an Active partition on the system drive
- foreach (const Partition &partition, config.Partitions)
- {
- if (partition.Info.BootIndicator)
- {
- activePartitionFound = true;
- break;
- }
- }
- }
-
- if (!config.SystemLoaderPresent || !activePartitionFound)
- {
- static bool confirmed = false;
-
- if (!confirmed && AskWarnNoYes ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR", ParentWindow) == IDNO)
- throw UserAbort (SRC_POS);
-
- confirmed = true;
- }
- }
-
-
- void BootEncryption::CheckRequirementsHiddenOS ()
- {
- // It is assumed that CheckRequirements() had been called (so we don't check e.g. whether it's GPT).
-
- // The user may have modified/added/deleted partitions since the partition table was last scanned.
- InvalidateCachedSysDriveProperties ();
-
- GetPartitionForHiddenOS ();
- }
-
-
- void BootEncryption::InitialSecurityChecksForHiddenOS ()
- {
- wchar_t windowsDrive = (wchar_t) towupper (GetWindowsDirectory()[0]);
-
- // Paging files
- bool pagingFilesOk = !IsPagingFileActive (TRUE);
-
- wchar_t pagingFileRegData[65536];
- DWORD pagingFileRegDataSize = sizeof (pagingFileRegData);
-
- if (ReadLocalMachineRegistryMultiString (L"System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", L"PagingFiles", pagingFileRegData, &pagingFileRegDataSize)
- && pagingFileRegDataSize > 8)
- {
- for (size_t i = 1; i < pagingFileRegDataSize/2 - 2; ++i)
- {
- if (wmemcmp (pagingFileRegData + i, L":\\", 2) == 0 && towupper (pagingFileRegData[i - 1]) != windowsDrive)
- {
- pagingFilesOk = false;
- break;
- }
- }
- }
-
- if (!pagingFilesOk)
- {
- if (AskWarnYesNoString ((wchar_t *) (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION"))
- + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")
- + L"\n\n\n"
- + GetString ("RESTRICT_PAGING_FILES_TO_SYS_PARTITION")
- ).c_str(), ParentWindow) == IDYES)
- {
- RestrictPagingFilesToSystemPartition();
- RestartComputer();
- AbortProcessSilent();
- }
-
- throw ErrorException (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION"))
- + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"), SRC_POS);
- }
-
- // User profile
- wchar_t *configPath = GetConfigPath (L"dummy");
- if (configPath && towupper (configPath[0]) != windowsDrive)
- {
- throw ErrorException (wstring (GetString ("USER_PROFILE_NOT_ON_SYS_PARTITION"))
- + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"), SRC_POS);
- }
-
- // Temporary files
- if (towupper (GetTempPathString()[0]) != windowsDrive)
- {
- throw ErrorException (wstring (GetString ("TEMP_NOT_ON_SYS_PARTITION"))
- + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"), SRC_POS);
- }
- }
-
-
- // This operation may take a long time when an antivirus is installed and its real-time protection enabled.
- // Therefore, if calling it without the wizard displayed, it should be called with displayWaitDialog set to true.
- void BootEncryption::Deinstall (bool displayWaitDialog)
- {
- BootEncryptionStatus encStatus = GetStatus();
-
- if (encStatus.DriveEncrypted || encStatus.DriveMounted)
- throw ParameterIncorrect (SRC_POS);
-
- SystemDriveConfiguration config = GetSystemDriveConfiguration ();
-
- if (encStatus.VolumeHeaderPresent)
- {
- // Verify CRC of header salt
- Device device (config.DevicePath, true);
- device.CheckOpened (SRC_POS);
- byte header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
-
- device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
- device.Read (header, sizeof (header));
-
- if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE))
- throw ParameterIncorrect (SRC_POS);
- }
-
- try
- {
- RegisterFilterDriver (false, DriveFilter);
- RegisterFilterDriver (false, VolumeFilter);
- RegisterFilterDriver (false, DumpFilter);
- SetDriverServiceStartType (SERVICE_SYSTEM_START);
- }
- catch (...)
- {
- try
- {
- RegisterBootDriver (IsHiddenSystemRunning());
- }
- catch (...) { }
-
- throw;
- }
-
- SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); // In case RestoreSystemLoader() fails
-
- try
- {
- 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];
- 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 ((byte *) header, sizeof (header));
-
- PCRYPTO_INFO cryptoInfo = NULL;
-
- int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, old_pkcs5, old_pim, FALSE, &cryptoInfo, NULL);
- finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); });
-
- 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);
- }
- finally_do ({ RandStop (FALSE); });
-
- /* force the display of the random enriching dialog */
- SetRandomPoolEnrichedByUserStatus (FALSE);
-
- NormalCursor();
- UserEnrichRandomPool (hwndDlg);
- WaitCursor();
-
- /* The header will be re-encrypted wipePassCount times to prevent adversaries from using
- techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
- to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
- times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
- impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
- valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
- recommends. During each pass we will write a valid working header. Each pass will use the same master
- key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
- item that will be different for each pass will be the salt. This is sufficient to cause each "version"
- of the header to differ substantially and in a random manner from the versions written during the
- other passes. */
-
- bool headerUpdated = false;
- int result = ERR_SUCCESS;
-
- try
- {
- BOOL backupHeader = FALSE;
- while (TRUE)
- {
- for (int wipePass = 0; wipePass < wipePassCount; wipePass++)
- {
- PCRYPTO_INFO tmpCryptoInfo = NULL;
-
- status = CreateVolumeHeaderInMemory (hwndDlg, !encStatus.HiddenSystem,
- header,
- cryptoInfo->ea,
- cryptoInfo->mode,
- newPassword,
- cryptoInfo->pkcs5,
- pim,
- (char *) cryptoInfo->master_keydata,
- &tmpCryptoInfo,
- cryptoInfo->VolumeSize.Value,
- cryptoInfo->hiddenVolumeSize,
- cryptoInfo->EncryptedAreaStart.Value,
- cryptoInfo->EncryptedAreaLength.Value,
- cryptoInfo->RequiredProgramVersion,
- cryptoInfo->HeaderFlags | TC_HEADER_FLAG_ENCRYPTED_SYSTEM,
- cryptoInfo->SectorSize,
- wipePass < wipePassCount - 1);
-
- if (tmpCryptoInfo)
- crypto_close (tmpCryptoInfo);
-
- if (status != 0)
- {
- handleError (hwndDlg, status, SRC_POS);
- return status;
- }
-
- device.SeekAt (headerOffset);
- device.Write ((byte *) header, sizeof (header));
- headerUpdated = true;
- }
-
- if (!encStatus.HiddenSystem || backupHeader)
- break;
-
- backupHeader = TRUE;
- headerOffset = backupHeaderOffset;
- }
- }
- catch (Exception &e)
- {
- e.Show (hwndDlg);
- result = ERR_OS_ERROR;
- }
-
- if (headerUpdated)
- {
- bool storedPimUpdateNeeded = false;
- ReopenBootVolumeHeaderRequest reopenRequest;
- reopenRequest.VolumePassword = *newPassword;
- reopenRequest.pkcs5_prf = cryptoInfo->pkcs5;
- reopenRequest.pim = pim;
- finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
-
- if (old_pim != pim)
- {
- try
- {
- // check if PIM is stored in MBR
- byte userConfig;
- ReadBootSectorConfig (nullptr, 0, &userConfig);
- if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
- storedPimUpdateNeeded = true;
- }
- catch (...)
- {}
- }
-
- try
- {
- // force update of bootloader if fingerprint doesn't match or if the stored PIM changed
- if (storedPimUpdateNeeded || !CheckBootloaderFingerprint (true))
- InstallBootLoader (device, true, false, pim);
- }
- catch (...)
- {}
-
- CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
- }
-
- return result;
- }
-
-
- void BootEncryption::CheckEncryptionSetupResult ()
- {
- CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
- }
-
-
- void BootEncryption::Install (bool hiddenSystem)
- {
- BootEncryptionStatus encStatus = GetStatus();
- if (encStatus.DriveMounted)
- throw ParameterIncorrect (SRC_POS);
-
- try
- {
- InstallBootLoader (false, hiddenSystem);
-
- if (!hiddenSystem)
- InstallVolumeHeader ();
-
- RegisterBootDriver (hiddenSystem);
- }
- catch (Exception &)
- {
- try
- {
- RestoreSystemLoader ();
- }
- catch (Exception &e)
- {
- e.Show (ParentWindow);
- }
-
- throw;
- }
- }
-
-
- void BootEncryption::PrepareHiddenOSCreation (int ea, int mode, int pkcs5)
- {
- BootEncryptionStatus encStatus = GetStatus();
- if (encStatus.DriveMounted)
- throw ParameterIncorrect (SRC_POS);
-
- CheckRequirements();
- BackupSystemLoader();
-
- SelectedEncryptionAlgorithmId = ea;
- SelectedPrfAlgorithmId = pkcs5;
- }
-
-
- void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, int pim, const wstring &rescueIsoImagePath)
- {
- BootEncryptionStatus encStatus = GetStatus();
- if (encStatus.DriveMounted)
- throw ParameterIncorrect (SRC_POS);
-
- CheckRequirements ();
-
- SystemDriveConfiguration config = GetSystemDriveConfiguration();
-
- // Some chipset drivers may prevent access to the last sector of the drive
- if (!systemPartitionOnly)
- {
- DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
- if ((geometry.BytesPerSector > 0) && (geometry.BytesPerSector < TC_MAX_VOLUME_SECTOR_SIZE))
- {
- Buffer sector (geometry.BytesPerSector);
-
- Device device (config.DevicePath);
- device.CheckOpened (SRC_POS);
-
- try
- {
- device.SeekAt (config.DrivePartition.Info.PartitionLength.QuadPart - geometry.BytesPerSector);
- device.Read (sector.Ptr(), (DWORD) sector.Size());
- }
- catch (SystemException &e)
- {
- if (e.ErrorCode != ERROR_CRC)
- {
- e.Show (ParentWindow);
- Error ("WHOLE_DRIVE_ENCRYPTION_PREVENTED_BY_DRIVERS", ParentWindow);
- throw UserAbort (SRC_POS);
- }
- }
- }
- }
-
- BackupSystemLoader ();
-
- uint64 volumeSize;
- uint64 encryptedAreaStart;
-
- if (systemPartitionOnly)
- {
- volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart;
- encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart;
- }
- else
- {
- volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE;
- encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE;
- }
-
- SelectedEncryptionAlgorithmId = ea;
- SelectedPrfAlgorithmId = pkcs5;
- CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5, pim);
-
- if (!rescueIsoImagePath.empty())
- CreateRescueIsoImage (true, rescueIsoImagePath);
- }
-
- bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
- {
- if (!IsAdmin() && IsUacSupported())
- return Elevator::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false;
-
- return ::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false;
- }
-
- void BootEncryption::RestrictPagingFilesToSystemPartition ()
- {
- wchar_t pagingFiles[128] = {0};
- StringCchCopyW (pagingFiles, ARRAYSIZE(pagingFiles), L"X:\\pagefile.sys 0 0");
- pagingFiles[0] = GetWindowsDirectory()[0];
-
- throw_sys_if (!WriteLocalMachineRegistryMultiString (L"System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", L"PagingFiles", pagingFiles, (DWORD) (wcslen (pagingFiles) + 2) * sizeof (wchar_t)));
- }
-
- void BootEncryption::WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value)
- {
- if (!IsAdmin() && IsUacSupported())
- {
- Elevator::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value);
- return;
- }
-
- throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value));
- }
-
- void BootEncryption::StartDecryption (BOOL discardUnreadableEncryptedSectors)
- {
- BootEncryptionStatus encStatus = GetStatus();
-
- if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
- throw ParameterIncorrect (SRC_POS);
-
- BootEncryptionSetupRequest request;
- ZeroMemory (&request, sizeof (request));
-
- request.SetupMode = SetupDecryption;
- request.DiscardUnreadableEncryptedSectors = discardUnreadableEncryptedSectors;
-
- CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
- }
-
- void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors)
- {
- BootEncryptionStatus encStatus = GetStatus();
-
- if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
- throw ParameterIncorrect (SRC_POS);
-
- BootEncryptionSetupRequest request;
- ZeroMemory (&request, sizeof (request));
-
- request.SetupMode = SetupEncryption;
- request.WipeAlgorithm = wipeAlgorithm;
- request.ZeroUnreadableSectors = zeroUnreadableSectors;
-
- CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
- }
-
- void BootEncryption::CopyFileAdmin (const wstring &sourceFile, const wstring &destinationFile)
- {
- if (!IsAdmin())
- {
- if (!IsUacSupported())
- {
- SetLastError (ERROR_ACCESS_DENIED);
- throw SystemException(SRC_POS);
- }
- else
- Elevator::CopyFile (sourceFile, destinationFile);
- }
- else
- throw_sys_if (!::CopyFile (sourceFile.c_str(), destinationFile.c_str(), FALSE));
- }
-
- void BootEncryption::DeleteFileAdmin (const wstring &file)
- {
- if (!IsAdmin() && IsUacSupported())
- Elevator::DeleteFile (file);
- else
- throw_sys_if (!::DeleteFile (file.c_str()));
- }
-
-#endif // !SETUP
-
- uint32 BootEncryption::ReadDriverConfigurationFlags ()
- {
- DWORD configMap;
-
- if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, &configMap))
- configMap = 0;
-
- return configMap;
- }
-
- void BootEncryption::WriteBootDriveSector (uint64 offset, byte *data)
- {
- WriteBootDriveSectorRequest request;
- request.Offset.QuadPart = offset;
- memcpy (request.Data, data, sizeof (request.Data));
-
- CallDriver (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR, &request, sizeof (request), NULL, 0);
- }
-
- void BootEncryption::RegisterBootDriver (bool hiddenSystem)
- {
- SetDriverServiceStartType (SERVICE_BOOT_START);
-
- try
- {
- RegisterFilterDriver (false, DriveFilter);
- RegisterFilterDriver (false, VolumeFilter);
- RegisterFilterDriver (false, DumpFilter);
- }
- catch (...) { }
-
- try
- {
- RegisterFilterDriver (true, DriveFilter);
-
- if (hiddenSystem)
- RegisterFilterDriver (true, VolumeFilter);
-
- RegisterFilterDriver (true, DumpFilter);
- }
- catch (...)
- {
- try { RegisterFilterDriver (false, DriveFilter); } catch (...) { }
- try { RegisterFilterDriver (false, VolumeFilter); } catch (...) { }
- try { RegisterFilterDriver (false, DumpFilter); } catch (...) { }
- try { SetDriverServiceStartType (SERVICE_SYSTEM_START); } catch (...) { }
-
- throw;
- }
- }
-
- bool BootEncryption::RestartComputer (void)
- {
- return (::RestartComputer() != FALSE);
- }
-}
+/*
+ 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-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"
+#include "Platform/Finally.h"
+#include "Platform/ForEach.h"
+#include <devguid.h>
+#include <io.h>
+#include <shlobj.h>
+#include <atlbase.h>
+#include "BootEncryption.h"
+#include "Boot/Windows/BootCommon.h"
+#include "Common/Resource.h"
+#include "Crc.h"
+#include "Crypto.h"
+#include "Dlgcode.h"
+#include "Endian.h"
+#include "Language.h"
+#include "Random.h"
+#include "Registry.h"
+#include "Volumes.h"
+
+#ifdef VOLFORMAT
+#include "Format/FormatCom.h"
+#elif defined (TCMOUNT)
+#include "Mount/MainCom.h"
+#endif
+
+#include <Strsafe.h>
+
+namespace VeraCrypt
+{
+#if !defined (SETUP)
+
+ class Elevator
+ {
+ public:
+
+ static void AddReference ()
+ {
+ ++ReferenceCount;
+ }
+
+
+ static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
+ {
+ Elevate();
+
+ CComBSTR inputBstr;
+ if (input && inputBstr.AppendBytes ((const char *) input, inputSize) != S_OK)
+ throw ParameterIncorrect (SRC_POS);
+
+ CComBSTR outputBstr;
+ if (output && outputBstr.AppendBytes ((const char *) output, outputSize) != S_OK)
+ throw ParameterIncorrect (SRC_POS);
+
+ DWORD result = ElevatedComInstance->CallDriver (ioctl, inputBstr, &outputBstr);
+
+ if (output)
+ memcpy (output, *(void **) &outputBstr, outputSize);
+
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
+ static void CopyFile (const wstring &sourceFile, const wstring &destinationFile)
+ {
+ Elevate();
+ DWORD result;
+ CComBSTR sourceFileBstr, destinationFileBstr;
+ BSTR bstr = W2BSTR(sourceFile.c_str());
+ if (bstr)
+ {
+ sourceFileBstr.Attach (bstr);
+
+ bstr = W2BSTR(destinationFile.c_str());
+ if (bstr)
+ {
+ destinationFileBstr.Attach (bstr);
+ result = ElevatedComInstance->CopyFile (sourceFileBstr, destinationFileBstr);
+ }
+ else
+ {
+ result = ERROR_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ result = ERROR_OUTOFMEMORY;
+ }
+
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
+ static void DeleteFile (const wstring &file)
+ {
+ Elevate();
+ CComBSTR fileBstr;
+ DWORD result;
+ BSTR bstr = W2BSTR(file.c_str());
+ if (bstr)
+ {
+ fileBstr.Attach (bstr);
+ result = ElevatedComInstance->DeleteFile (fileBstr);
+ }
+ else
+ {
+ result = ERROR_OUTOFMEMORY;
+ }
+
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
+ static void ReadWriteFile (BOOL write, BOOL device, const wstring &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone)
+ {
+ Elevate();
+
+ DWORD result;
+ CComBSTR bufferBstr, fileBstr;
+ if (bufferBstr.AppendBytes ((const char *) buffer, size) != S_OK)
+ throw ParameterIncorrect (SRC_POS);
+ BSTR bstr = W2BSTR(filePath.c_str());
+ if (bstr)
+ {
+ fileBstr.Attach (bstr);
+ result = ElevatedComInstance->ReadWriteFile (write, device, fileBstr, &bufferBstr, offset, size, sizeDone);
+ }
+ else
+ {
+ result = ERROR_OUTOFMEMORY;
+ }
+
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+
+ if (!write)
+ memcpy (buffer, (BYTE *) bufferBstr.m_str, size);
+ }
+
+ static BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
+ {
+ Elevate();
+
+ return ElevatedComInstance->IsPagingFileActive (checkNonWindowsPartitionsOnly);
+ }
+
+ static void WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value)
+ {
+ Elevate();
+ DWORD result;
+ CComBSTR keyPathBstr, valueNameBstr;
+ BSTR bstr = W2BSTR(keyPath);
+ if (bstr)
+ {
+ keyPathBstr.Attach (bstr);
+
+ bstr = W2BSTR(valueName);
+ if (bstr)
+ {
+ valueNameBstr.Attach (bstr);
+
+ result = ElevatedComInstance->WriteLocalMachineRegistryDwordValue (keyPathBstr, valueNameBstr, value);
+ }
+ else
+ {
+ result = ERROR_OUTOFMEMORY;
+ }
+ }
+ else
+ {
+ result = ERROR_OUTOFMEMORY;
+ }
+
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
+ static void RegisterFilterDriver (bool registerDriver, BootEncryption::FilterType filterType)
+ {
+ Elevate();
+
+ DWORD result = ElevatedComInstance->RegisterFilterDriver (registerDriver ? TRUE : FALSE, filterType);
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
+ static void RegisterSystemFavoritesService (BOOL registerService)
+ {
+ Elevate();
+
+ DWORD result = ElevatedComInstance->RegisterSystemFavoritesService (registerService);
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
+ static void Release ()
+ {
+ if (--ReferenceCount == 0 && ElevatedComInstance)
+ {
+ ElevatedComInstance->Release();
+ ElevatedComInstance = nullptr;
+ CoUninitialize ();
+ }
+ }
+
+ static void SetDriverServiceStartType (DWORD startType)
+ {
+ Elevate();
+
+ DWORD result = ElevatedComInstance->SetDriverServiceStartType (startType);
+ if (result != ERROR_SUCCESS)
+ {
+ SetLastError (result);
+ throw SystemException(SRC_POS);
+ }
+ }
+
+ protected:
+ static void Elevate ()
+ {
+ if (IsAdmin())
+ {
+ SetLastError (ERROR_ACCESS_DENIED);
+ throw SystemException(SRC_POS);
+ }
+
+ if (!ElevatedComInstance || ElevatedComInstanceThreadId != GetCurrentThreadId())
+ {
+ CoInitialize (NULL);
+ ElevatedComInstance = GetElevatedInstance (GetActiveWindow() ? GetActiveWindow() : MainDlg);
+ ElevatedComInstanceThreadId = GetCurrentThreadId();
+ }
+ }
+
+#if defined (TCMOUNT)
+ static ITrueCryptMainCom *ElevatedComInstance;
+#elif defined (VOLFORMAT)
+ static ITrueCryptFormatCom *ElevatedComInstance;
+#endif
+ static DWORD ElevatedComInstanceThreadId;
+ static int ReferenceCount;
+ };
+
+#if defined (TCMOUNT)
+ ITrueCryptMainCom *Elevator::ElevatedComInstance;
+#elif defined (VOLFORMAT)
+ ITrueCryptFormatCom *Elevator::ElevatedComInstance;
+#endif
+ DWORD Elevator::ElevatedComInstanceThreadId;
+ int Elevator::ReferenceCount = 0;
+
+#else // SETUP
+
+ class Elevator
+ {
+ public:
+ static void AddReference () { }
+ static void CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize) { throw ParameterIncorrect (SRC_POS); }
+ static void ReadWriteFile (BOOL write, BOOL device, const wstring &filePath, byte *buffer, uint64 offset, uint32 size, DWORD *sizeDone) { throw ParameterIncorrect (SRC_POS); }
+ static void RegisterFilterDriver (bool registerDriver, BootEncryption::FilterType filterType) { throw ParameterIncorrect (SRC_POS); }
+ static void Release () { }
+ static void SetDriverServiceStartType (DWORD startType) { throw ParameterIncorrect (SRC_POS); }
+ };
+
+#endif // SETUP
+
+
+ File::File (wstring path, bool readOnly, bool create) : Elevated (false), FileOpen (false), LastError(0)
+ {
+ Handle = CreateFile (path.c_str(),
+ readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, create ? CREATE_ALWAYS : OPEN_EXISTING,
+ FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
+
+ if (Handle != INVALID_HANDLE_VALUE)
+ {
+ FileOpen = true;
+ }
+ else
+ {
+ LastError = GetLastError();
+ if (LastError == ERROR_ACCESS_DENIED && IsUacSupported())
+ {
+ Elevated = true;
+ FileOpen = true;
+ }
+ }
+
+ FilePointerPosition = 0;
+ IsDevice = false;
+ Path = path;
+ }
+
+ void File::Close ()
+ {
+ if (Handle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle (Handle);
+ Handle = INVALID_HANDLE_VALUE;
+ }
+
+ FileOpen = false;
+ }
+
+ DWORD File::Read (byte *buffer, DWORD size)
+ {
+ DWORD bytesRead;
+
+ if (!FileOpen)
+ {
+ SetLastError (LastError);
+ throw SystemException (SRC_POS);
+ }
+
+ if (Elevated)
+ {
+ DWORD bytesRead;
+
+ Elevator::ReadWriteFile (false, IsDevice, Path, buffer, FilePointerPosition, size, &bytesRead);
+ FilePointerPosition += bytesRead;
+ return bytesRead;
+ }
+
+ throw_sys_if (!ReadFile (Handle, buffer, size, &bytesRead, NULL));
+ return bytesRead;
+ }
+
+ void File::SeekAt (int64 position)
+ {
+ if (!FileOpen)
+ {
+ SetLastError (LastError);
+ throw SystemException (SRC_POS);
+ }
+
+ FilePointerPosition = position;
+
+ if (!Elevated)
+ {
+ LARGE_INTEGER pos;
+ pos.QuadPart = position;
+ throw_sys_if (!SetFilePointerEx (Handle, pos, NULL, FILE_BEGIN));
+ }
+ }
+
+ void File::Write (byte *buffer, DWORD size)
+ {
+ DWORD bytesWritten;
+
+ if (!FileOpen)
+ {
+ SetLastError (LastError);
+ throw SystemException (SRC_POS);
+ }
+
+ try
+ {
+ if (Elevated)
+ {
+ Elevator::ReadWriteFile (true, IsDevice, Path, buffer, FilePointerPosition, size, &bytesWritten);
+ FilePointerPosition += bytesWritten;
+ throw_sys_if (bytesWritten != size);
+ }
+ else
+ {
+ throw_sys_if (!WriteFile (Handle, buffer, size, &bytesWritten, NULL) || bytesWritten != size);
+ }
+ }
+ catch (SystemException &e)
+ {
+ if (!IsDevice || e.ErrorCode != ERROR_WRITE_PROTECT)
+ throw;
+
+ BootEncryption bootEnc (NULL);
+
+ while (size >= TC_SECTOR_SIZE_BIOS)
+ {
+ bootEnc.WriteBootDriveSector (FilePointerPosition, buffer);
+
+ FilePointerPosition += TC_SECTOR_SIZE_BIOS;
+ buffer += TC_SECTOR_SIZE_BIOS;
+ size -= TC_SECTOR_SIZE_BIOS;
+ }
+ }
+ }
+
+ void Show (HWND parent, const wstring &str)
+ {
+ MessageBox (parent, str.c_str(), NULL, 0);
+ }
+
+
+ Device::Device (wstring path, bool readOnly)
+ {
+ FileOpen = false;
+ Elevated = false;
+
+ Handle = CreateFile ((wstring (L"\\\\.\\") + path).c_str(),
+ readOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_WRITE_THROUGH, NULL);
+
+ if (Handle != INVALID_HANDLE_VALUE)
+ {
+ FileOpen = true;
+ }
+ else
+ {
+ LastError = GetLastError ();
+ if (LastError == ERROR_ACCESS_DENIED && IsUacSupported())
+ {
+ Elevated = true;
+ FileOpen = true;
+ }
+ }
+
+ FilePointerPosition = 0;
+ IsDevice = true;
+ Path = path;
+ }
+
+
+ BootEncryption::BootEncryption (HWND parent)
+ : DriveConfigValid (false),
+ ParentWindow (parent),
+ RealSystemDriveSizeValid (false),
+ RescueIsoImage (nullptr),
+ RescueVolumeHeaderValid (false),
+ SelectedEncryptionAlgorithmId (0),
+ SelectedPrfAlgorithmId (0),
+ VolumeHeaderValid (false)
+ {
+ HiddenOSCandidatePartition.IsGPT = FALSE;
+ HiddenOSCandidatePartition.Number = (size_t) -1;
+ DriveConfig.DriveNumber = -1;
+ DriveConfig.ExtraBootPartitionPresent = false;
+ DriveConfig.SystemLoaderPresent = false;
+ DriveConfig.InitialUnallocatedSpace = 0;
+ DriveConfig.TotalUnallocatedSpace = 0;
+ Elevator::AddReference();
+ }
+
+
+ BootEncryption::~BootEncryption ()
+ {
+ if (RescueIsoImage)
+ delete[] RescueIsoImage;
+
+ Elevator::Release();
+ }
+
+
+ void BootEncryption::CallDriver (DWORD ioctl, void *input, DWORD inputSize, void *output, DWORD outputSize)
+ {
+ try
+ {
+ DWORD bytesReturned;
+ throw_sys_if (!DeviceIoControl (hDriver, ioctl, input, inputSize, output, outputSize, &bytesReturned, NULL));
+ }
+ catch (SystemException &)
+ {
+ if (GetLastError() == ERROR_ACCESS_DENIED && IsUacSupported())
+ Elevator::CallDriver (ioctl, input, inputSize, output, outputSize);
+ else
+ throw;
+ }
+ }
+
+
+ // Finds the first partition physically located behind the active one and returns its properties
+ Partition BootEncryption::GetPartitionForHiddenOS ()
+ {
+ Partition candidatePartition;
+
+ memset (&candidatePartition, 0, sizeof(candidatePartition));
+
+ // The user may have modified/added/deleted partitions since the time the partition table was last scanned
+ InvalidateCachedSysDriveProperties();
+
+ SystemDriveConfiguration config = GetSystemDriveConfiguration ();
+ bool activePartitionFound = false;
+ bool candidateForHiddenOSFound = false;
+
+ if (config.SystemPartition.IsGPT)
+ throw ParameterIncorrect (SRC_POS); // It is assumed that CheckRequirements() had been called
+
+ // Find the first active partition on the system drive
+ foreach (const Partition &partition, config.Partitions)
+ {
+ if (partition.Info.BootIndicator)
+ {
+ if (partition.Info.PartitionNumber != config.SystemPartition.Number)
+ {
+ // If there is an extra boot partition, the system partition must be located right behind it
+ if (IsOSAtLeast (WIN_7) && config.ExtraBootPartitionPresent)
+ {
+ int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart;
+ Partition bootPartition = partition;
+ Partition partitionBehindBoot;
+
+ foreach (const Partition &partition, config.Partitions)
+ {
+ if (partition.Info.StartingOffset.QuadPart > bootPartition.Info.StartingOffset.QuadPart
+ && partition.Info.StartingOffset.QuadPart < minOffsetFound)
+ {
+ minOffsetFound = partition.Info.StartingOffset.QuadPart;
+ partitionBehindBoot = partition;
+ }
+ }
+
+ if (minOffsetFound != config.DrivePartition.Info.PartitionLength.QuadPart
+ && partitionBehindBoot.Number == config.SystemPartition.Number)
+ {
+ activePartitionFound = true;
+ break;
+ }
+ }
+
+ throw ErrorException (wstring (GetString ("SYSTEM_PARTITION_NOT_ACTIVE"))
+ + GetRemarksOnHiddenOS(), SRC_POS);
+ }
+
+ activePartitionFound = true;
+ break;
+ }
+ }
+
+ /* WARNING: Note that the partition number at the end of a device path (\Device\HarddiskY\PartitionX) must
+ NOT be used to find the first partition physically located behind the active one. The reason is that the
+ user may have deleted and created partitions during this session and e.g. the second partition could have
+ a higer number than the third one. */
+
+
+ // Find the first partition physically located behind the active partition
+ if (activePartitionFound)
+ {
+ int64 minOffsetFound = config.DrivePartition.Info.PartitionLength.QuadPart;
+
+ foreach (const Partition &partition, config.Partitions)
+ {
+ if (partition.Info.StartingOffset.QuadPart > config.SystemPartition.Info.StartingOffset.QuadPart
+ && partition.Info.StartingOffset.QuadPart < minOffsetFound)
+ {
+ minOffsetFound = partition.Info.StartingOffset.QuadPart;
+
+ candidatePartition = partition;
+
+ candidateForHiddenOSFound = true;
+ }
+ }
+
+ if (!candidateForHiddenOSFound)
+ {
+ throw ErrorException (wstring (GetString ("NO_PARTITION_FOLLOWS_BOOT_PARTITION"))
+ + GetRemarksOnHiddenOS(), SRC_POS);
+ }
+
+ if (config.SystemPartition.Info.PartitionLength.QuadPart > TC_MAX_FAT_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
+ {
+ if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS)
+ {
+ throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS_NTFS"))
+ + GetRemarksOnHiddenOS(), SRC_POS);
+ }
+ }
+ else if ((double) candidatePartition.Info.PartitionLength.QuadPart / config.SystemPartition.Info.PartitionLength.QuadPart < MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT)
+ {
+ throw ErrorException (wstring (GetString ("PARTITION_TOO_SMALL_FOR_HIDDEN_OS"))
+ + GetRemarksOnHiddenOS(), SRC_POS);
+ }
+ }
+ else
+ {
+ // No active partition on the system drive
+ throw ErrorException ("SYSTEM_PARTITION_NOT_ACTIVE", SRC_POS);
+ }
+
+ HiddenOSCandidatePartition = candidatePartition;
+ return candidatePartition;
+ }
+
+
+ DWORD BootEncryption::GetDriverServiceStartType ()
+ {
+ DWORD startType;
+ throw_sys_if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", L"Start", &startType));
+ return startType;
+ }
+
+
+ wstring BootEncryption::GetRemarksOnHiddenOS ()
+ {
+ return (wstring (L"\n\n")
+ + GetString ("TWO_SYSTEMS_IN_ONE_PARTITION_REMARK")
+ + L"\n\n"
+ + GetString ("FOR_MORE_INFO_ON_PARTITIONS"));
+ }
+
+
+ void BootEncryption::SetDriverServiceStartType (DWORD startType)
+ {
+ if (!IsAdmin() && IsUacSupported())
+ {
+ Elevator::SetDriverServiceStartType (startType);
+ return;
+ }
+
+ BOOL startOnBoot = (startType == SERVICE_BOOT_START);
+
+ SC_HANDLE serviceManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ throw_sys_if (!serviceManager);
+
+ finally_do_arg (SC_HANDLE, serviceManager, { CloseServiceHandle (finally_arg); });
+
+ SC_HANDLE service = OpenService (serviceManager, L"veracrypt", SERVICE_CHANGE_CONFIG);
+ throw_sys_if (!service);
+
+ finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); });
+
+ // Windows versions preceding Vista can be installed on FAT filesystem which does not
+ // support long filenames during boot. Convert the driver path to short form if required.
+ wstring driverPath;
+ if (startOnBoot && !IsOSAtLeast (WIN_VISTA))
+ {
+ wchar_t pathBuf[MAX_PATH];
+ wchar_t filesystem[128];
+
+ wstring path (GetWindowsDirectory());
+ path += L"\\drivers\\veracrypt.sys";
+
+ if (GetVolumePathName (path.c_str(), pathBuf, ARRAYSIZE (pathBuf))
+ && GetVolumeInformation (pathBuf, NULL, 0, NULL, NULL, NULL, filesystem, ARRAYSIZE(filesystem))
+ && wmemcmp (filesystem, L"FAT", 3) == 0)
+ {
+ throw_sys_if (GetShortPathName (path.c_str(), pathBuf, ARRAYSIZE (pathBuf)) == 0);
+
+ // Convert absolute path to relative to the Windows directory
+ driverPath = pathBuf;
+ driverPath = driverPath.substr (driverPath.rfind (L"\\", driverPath.rfind (L"\\", driverPath.rfind (L"\\") - 1) - 1) + 1);
+ }
+ }
+
+ throw_sys_if (!ChangeServiceConfig (service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
+ startOnBoot ? SERVICE_ERROR_SEVERE : SERVICE_ERROR_NORMAL,
+ driverPath.empty() ? NULL : driverPath.c_str(),
+ startOnBoot ? L"Filter" : NULL,
+ NULL, NULL, NULL, NULL, NULL));
+
+ // ChangeServiceConfig() rejects SERVICE_BOOT_START with ERROR_INVALID_PARAMETER
+ throw_sys_if (!WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", L"Start", startType));
+ }
+
+
+ void BootEncryption::ProbeRealSystemDriveSize ()
+ {
+ if (RealSystemDriveSizeValid)
+ return;
+
+ GetSystemDriveConfiguration();
+
+ ProbeRealDriveSizeRequest request;
+ StringCchCopyW (request.DeviceName, ARRAYSIZE (request.DeviceName), DriveConfig.DrivePartition.DevicePath.c_str());
+
+ CallDriver (TC_IOCTL_PROBE_REAL_DRIVE_SIZE, &request, sizeof (request), &request, sizeof (request));
+ DriveConfig.DrivePartition.Info.PartitionLength = request.RealDriveSize;
+
+ RealSystemDriveSizeValid = true;
+
+ if (request.TimeOut)
+ throw TimeOut (SRC_POS);
+ }
+
+
+ void BootEncryption::InvalidateCachedSysDriveProperties ()
+ {
+ DriveConfigValid = false;
+ RealSystemDriveSizeValid = false;
+ }
+
+
+ PartitionList BootEncryption::GetDrivePartitions (int driveNumber)
+ {
+ PartitionList partList;
+
+ for (int partNumber = 0; partNumber < 64; ++partNumber)
+ {
+ wstringstream partPath;
+ partPath << L"\\Device\\Harddisk" << driveNumber << L"\\Partition" << partNumber;
+
+ DISK_PARTITION_INFO_STRUCT diskPartInfo = {0};
+ StringCchCopyW (diskPartInfo.deviceName, ARRAYSIZE (diskPartInfo.deviceName), partPath.str().c_str());
+
+ try
+ {
+ CallDriver (TC_IOCTL_GET_DRIVE_PARTITION_INFO, &diskPartInfo, sizeof (diskPartInfo), &diskPartInfo, sizeof (diskPartInfo));
+ }
+ catch (...)
+ {
+ continue;
+ }
+
+ if ( (diskPartInfo.IsGPT == TRUE || diskPartInfo.IsGPT == FALSE)
+ && (diskPartInfo.IsDynamic == TRUE || diskPartInfo.IsDynamic == FALSE)
+ && (diskPartInfo.partInfo.BootIndicator == TRUE || diskPartInfo.partInfo.BootIndicator == FALSE)
+ && (diskPartInfo.partInfo.RecognizedPartition == TRUE || diskPartInfo.partInfo.RecognizedPartition == FALSE)
+ && (diskPartInfo.partInfo.RewritePartition == TRUE || diskPartInfo.partInfo.RewritePartition == FALSE)
+ && (diskPartInfo.partInfo.StartingOffset.QuadPart >= 0)
+ && (diskPartInfo.partInfo.PartitionLength.QuadPart >= 0)
+ )
+ {
+ Partition part;
+ part.DevicePath = partPath.str();
+ part.Number = partNumber;
+ part.Info = diskPartInfo.partInfo;
+ part.IsGPT = diskPartInfo.IsGPT;
+
+ // Mount point
+ int driveNumber = GetDiskDeviceDriveLetter ((wchar_t *) partPath.str().c_str());
+
+ if (driveNumber >= 0)
+ {
+ part.MountPoint += (wchar_t) (driveNumber + L'A');
+ part.MountPoint += L":";
+ }
+
+ // Volume ID
+ wchar_t volumePath[TC_MAX_PATH];
+ if (ResolveSymbolicLink ((wchar_t *) partPath.str().c_str(), volumePath, sizeof(volumePath)))
+ {
+ wchar_t volumeName[TC_MAX_PATH];
+ HANDLE fh = FindFirstVolumeW (volumeName, array_capacity (volumeName));
+ if (fh != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ wstring volumeNameStr = volumeName;
+ wchar_t devicePath[TC_MAX_PATH];
+
+ if (QueryDosDeviceW (volumeNameStr.substr (4, volumeNameStr.size() - 1 - 4).c_str(), devicePath, array_capacity (devicePath)) != 0
+ && wcscmp (volumePath, devicePath) == 0)
+ {
+ part.VolumeNameId = volumeName;
+ break;
+ }
+
+ } while (FindNextVolumeW (fh, volumeName, array_capacity (volumeName)));
+
+ FindVolumeClose (fh);
+ }
+ }
+
+ partList.push_back (part);
+ }
+ }
+
+ return partList;
+ }
+
+
+ DISK_GEOMETRY BootEncryption::GetDriveGeometry (int driveNumber)
+ {
+ wstringstream devName;
+ devName << L"\\Device\\Harddisk" << driveNumber << L"\\Partition0";
+
+ DISK_GEOMETRY geometry;
+ throw_sys_if (!::GetDriveGeometry (devName.str().c_str(), &geometry));
+ return geometry;
+ }
+
+
+ wstring BootEncryption::GetWindowsDirectory ()
+ {
+ wchar_t buf[MAX_PATH];
+ throw_sys_if (GetSystemDirectory (buf, ARRAYSIZE (buf)) == 0);
+
+ return wstring (buf);
+ }
+
+
+
+ uint16 BootEncryption::GetInstalledBootLoaderVersion ()
+ {
+ uint16 version;
+ CallDriver (TC_IOCTL_GET_BOOT_LOADER_VERSION, NULL, 0, &version, sizeof (version));
+ return version;
+ }
+
+ void BootEncryption::GetInstalledBootLoaderFingerprint (byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE])
+ {
+ BootLoaderFingerprintRequest request;
+ CallDriver (VC_IOCTL_GET_BOOT_LOADER_FINGERPRINT, NULL, 0, &request, sizeof (request));
+ memcpy (fingerprint, request.Fingerprint, sizeof (request.Fingerprint));
+ }
+
+ // Note that this does not require admin rights (it just requires the driver to be running)
+ bool BootEncryption::IsBootLoaderOnDrive (wchar_t *devicePath)
+ {
+ try
+ {
+ OPEN_TEST_STRUCT openTestStruct;
+ memset (&openTestStruct, 0, sizeof (openTestStruct));
+ DWORD dwResult;
+
+ StringCchCopyW (&openTestStruct.wszFileName[0], ARRAYSIZE(openTestStruct.wszFileName),devicePath);
+
+ openTestStruct.bDetectTCBootLoader = TRUE;
+
+ return (DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST,
+ &openTestStruct, sizeof (OPEN_TEST_STRUCT),
+ &openTestStruct, sizeof (OPEN_TEST_STRUCT),
+ &dwResult, NULL) && openTestStruct.TCBootLoaderDetected);
+ }
+ catch (...)
+ {
+ return false;
+ }
+ }
+
+
+ BootEncryptionStatus BootEncryption::GetStatus ()
+ {
+ /* IMPORTANT: Do NOT add any potentially time-consuming operations to this function. */
+
+ BootEncryptionStatus status;
+ CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS, NULL, 0, &status, sizeof (status));
+ return status;
+ }
+
+
+ void BootEncryption::GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties)
+ {
+ if (properties == NULL)
+ throw ParameterIncorrect (SRC_POS);
+
+ CallDriver (TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES, NULL, 0, properties, sizeof (*properties));
+ }
+
+
+ bool BootEncryption::IsHiddenSystemRunning ()
+ {
+ int hiddenSystemStatus;
+
+ CallDriver (TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING, nullptr, 0, &hiddenSystemStatus, sizeof (hiddenSystemStatus));
+ return hiddenSystemStatus != 0;
+ }
+
+
+ bool BootEncryption::SystemDriveContainsPartitionType (byte type)
+ {
+ Device device (GetSystemDriveConfiguration().DevicePath, true);
+ device.CheckOpened (SRC_POS);
+
+ byte mbrBuf[TC_SECTOR_SIZE_BIOS];
+ device.SeekAt (0);
+ device.Read (mbrBuf, sizeof (mbrBuf));
+
+ MBR *mbr = reinterpret_cast <MBR *> (mbrBuf);
+ if (mbr->Signature != 0xaa55)
+ throw ParameterIncorrect (SRC_POS);
+
+ for (size_t i = 0; i < array_capacity (mbr->Partitions); ++i)
+ {
+ if (mbr->Partitions[i].Type == type)
+ return true;
+ }
+
+ return false;
+ }
+
+
+ bool BootEncryption::SystemDriveContainsExtendedPartition ()
+ {
+ return SystemDriveContainsPartitionType (PARTITION_EXTENDED) || SystemDriveContainsPartitionType (PARTITION_XINT13_EXTENDED);
+ }
+
+
+ bool BootEncryption::SystemDriveContainsNonStandardPartitions ()
+ {
+ for (int partitionType = 1; partitionType <= 0xff; ++partitionType)
+ {
+ switch (partitionType)
+ {
+ case PARTITION_FAT_12:
+ case PARTITION_FAT_16:
+ case PARTITION_EXTENDED:
+ case PARTITION_HUGE:
+ case PARTITION_IFS:
+ case PARTITION_FAT32:
+ case PARTITION_FAT32_XINT13:
+ case PARTITION_XINT13:
+ case PARTITION_XINT13_EXTENDED:
+ continue;
+ }
+
+ if (SystemDriveContainsPartitionType ((byte) partitionType))
+ return true;
+ }
+
+ return false;
+ }
+
+
+ bool BootEncryption::SystemDriveIsDynamic ()
+ {
+ GetSystemDriveConfigurationRequest request;
+ StringCchCopyW (request.DevicePath, ARRAYSIZE (request.DevicePath), GetSystemDriveConfiguration().DeviceKernelPath.c_str());
+
+ CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request));
+ return request.DriveIsDynamic ? true : false;
+ }
+
+
+ SystemDriveConfiguration BootEncryption::GetSystemDriveConfiguration ()
+ {
+ if (DriveConfigValid)
+ return DriveConfig;
+
+ SystemDriveConfiguration config;
+
+ wstring winDir = GetWindowsDirectory();
+
+ // Scan all drives
+ for (int driveNumber = 0; driveNumber < 32; ++driveNumber)
+ {
+ bool windowsFound = false;
+ bool activePartitionFound = false;
+ config.ExtraBootPartitionPresent = false;
+ config.SystemLoaderPresent = false;
+
+ PartitionList partitions = GetDrivePartitions (driveNumber);
+ foreach (const Partition &part, partitions)
+ {
+ if (!part.MountPoint.empty()
+ && (_waccess ((part.MountPoint + L"\\bootmgr").c_str(), 0) == 0 || _waccess ((part.MountPoint + L"\\ntldr").c_str(), 0) == 0))
+ {
+ config.SystemLoaderPresent = true;
+ }
+ else if (!part.VolumeNameId.empty()
+ && (_waccess ((part.VolumeNameId + L"\\bootmgr").c_str(), 0) == 0 || _waccess ((part.VolumeNameId + L"\\ntldr").c_str(), 0) == 0))
+ {
+ config.SystemLoaderPresent = true;
+ }
+
+ if (!windowsFound && !part.MountPoint.empty() && ToUpperCase (winDir).find (ToUpperCase (part.MountPoint)) == 0)
+ {
+ config.SystemPartition = part;
+ windowsFound = true;
+ }
+
+ if (!activePartitionFound && part.Info.BootIndicator)
+ {
+ activePartitionFound = true;
+
+ if (part.Info.PartitionLength.QuadPart > 0 && part.Info.PartitionLength.QuadPart <= TC_MAX_EXTRA_BOOT_PARTITION_SIZE)
+ config.ExtraBootPartitionPresent = true;
+ }
+ }
+
+ if (windowsFound)
+ {
+ config.DriveNumber = driveNumber;
+
+ wstringstream ss;
+ ss << L"PhysicalDrive" << driveNumber;
+ config.DevicePath = ss.str();
+
+ wstringstream kernelPath;
+ kernelPath << L"\\Device\\Harddisk" << driveNumber << L"\\Partition0";
+ config.DeviceKernelPath = kernelPath.str();
+
+ config.DrivePartition = partitions.front();
+ partitions.pop_front();
+ config.Partitions = partitions;
+
+ config.InitialUnallocatedSpace = 0x7fffFFFFffffFFFFull;
+ config.TotalUnallocatedSpace = config.DrivePartition.Info.PartitionLength.QuadPart;
+
+ foreach (const Partition &part, config.Partitions)
+ {
+ if (part.Info.StartingOffset.QuadPart < config.InitialUnallocatedSpace)
+ config.InitialUnallocatedSpace = part.Info.StartingOffset.QuadPart;
+
+ config.TotalUnallocatedSpace -= part.Info.PartitionLength.QuadPart;
+ }
+
+ DriveConfig = config;
+ DriveConfigValid = true;
+ return DriveConfig;
+ }
+ }
+
+ throw ParameterIncorrect (SRC_POS);
+ }
+
+
+ bool BootEncryption::SystemPartitionCoversWholeDrive ()
+ {
+ SystemDriveConfiguration config = GetSystemDriveConfiguration();
+
+ if (IsOSAtLeast (WIN_7)
+ && config.Partitions.size() == 2
+ && config.ExtraBootPartitionPresent
+ && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 164 * BYTES_PER_MB)
+ {
+ return true;
+ }
+
+ return config.Partitions.size() == 1
+ && config.DrivePartition.Info.PartitionLength.QuadPart - config.SystemPartition.Info.PartitionLength.QuadPart < 64 * BYTES_PER_MB;
+ }
+
+
+ uint32 BootEncryption::GetChecksum (byte *data, size_t size)
+ {
+ uint32 sum = 0;
+
+ while (size-- > 0)
+ {
+ sum += *data++;
+ sum = _rotl (sum, 1);
+ }
+
+ return sum;
+ }
+
+
+ void BootEncryption::CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation)
+ {
+ if (bufferSize < TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE)
+ throw ParameterIncorrect (SRC_POS);
+
+ ZeroMemory (buffer, bufferSize);
+
+ int ea = 0;
+ int pkcs5_prf = 0;
+ if (GetStatus().DriveMounted)
+ {
+ try
+ {
+ GetBootEncryptionAlgorithmNameRequest request;
+ // since we added new field to GetBootEncryptionAlgorithmNameRequest since version 1.0f
+ // we zero all the structure so that if we are talking to an older driver, the field
+ // BootPrfAlgorithmName will be an empty string
+ ZeroMemory(&request, sizeof(request));
+ CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME, NULL, 0, &request, sizeof (request));
+
+ if (_stricmp (request.BootEncryptionAlgorithmName, "AES") == 0)
+ ea = AES;
+ else if (_stricmp (request.BootEncryptionAlgorithmName, "Serpent") == 0)
+ ea = SERPENT;
+ else if (_stricmp (request.BootEncryptionAlgorithmName, "Twofish") == 0)
+ ea = TWOFISH;
+
+ if (_stricmp(request.BootPrfAlgorithmName, "SHA-256") == 0)
+ pkcs5_prf = SHA256;
+ else if (_stricmp(request.BootPrfAlgorithmName, "RIPEMD-160") == 0)
+ pkcs5_prf = RIPEMD160;
+ else if (strlen(request.BootPrfAlgorithmName) == 0) // case of version < 1.0f
+ pkcs5_prf = RIPEMD160;
+ }
+ catch (...)
+ {
+ try
+ {
+ VOLUME_PROPERTIES_STRUCT properties;
+ GetVolumeProperties (&properties);
+ ea = properties.ea;
+ pkcs5_prf = properties.pkcs5;
+ }
+ catch (...) { }
+ }
+ }
+ else
+ {
+ if (SelectedEncryptionAlgorithmId == 0 || SelectedPrfAlgorithmId == 0)
+ throw ParameterIncorrect (SRC_POS);
+
+ ea = SelectedEncryptionAlgorithmId;
+ pkcs5_prf = SelectedPrfAlgorithmId;
+ }
+
+ // Only RIPEMD160 and SHA-256 are supported for boot loader
+ if (pkcs5_prf != RIPEMD160 && pkcs5_prf != SHA256)
+ throw ParameterIncorrect (SRC_POS);
+
+ int bootSectorId = 0;
+ int bootLoaderId = 0;
+
+ if (pkcs5_prf == SHA256)
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SHA2 : IDR_BOOT_SECTOR_SHA2;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SHA2 : IDR_BOOT_LOADER_SHA2;
+ }
+ else
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR : IDR_BOOT_SECTOR;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER : IDR_BOOT_LOADER;
+ }
+
+ switch (ea)
+ {
+ case AES:
+ if (pkcs5_prf == SHA256)
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES_SHA2 : IDR_BOOT_SECTOR_AES_SHA2;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES_SHA2 : IDR_BOOT_LOADER_AES_SHA2;
+ }
+ else
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_AES : IDR_BOOT_SECTOR_AES;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_AES : IDR_BOOT_LOADER_AES;
+ }
+ break;
+
+ case SERPENT:
+ if (pkcs5_prf == SHA256)
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT_SHA2 : IDR_BOOT_SECTOR_SERPENT_SHA2;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT_SHA2 : IDR_BOOT_LOADER_SERPENT_SHA2;
+ }
+ else
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_SERPENT : IDR_BOOT_SECTOR_SERPENT;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_SERPENT : IDR_BOOT_LOADER_SERPENT;
+ }
+ break;
+
+ case TWOFISH:
+ if (pkcs5_prf == SHA256)
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH_SHA2 : IDR_BOOT_SECTOR_TWOFISH_SHA2;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH_SHA2 : IDR_BOOT_LOADER_TWOFISH_SHA2;
+ }
+ else
+ {
+ bootSectorId = rescueDisk ? IDR_RESCUE_BOOT_SECTOR_TWOFISH : IDR_BOOT_SECTOR_TWOFISH;
+ bootLoaderId = rescueDisk ? IDR_RESCUE_LOADER_TWOFISH : IDR_BOOT_LOADER_TWOFISH;
+ }
+ break;
+ }
+
+ // Boot sector
+ DWORD size;
+ byte *bootSecResourceImg = MapResource (L"BIN", bootSectorId, &size);
+ if (!bootSecResourceImg || size != TC_SECTOR_SIZE_BIOS)
+ throw ParameterIncorrect (SRC_POS);
+
+ memcpy (buffer, bootSecResourceImg, size);
+
+ *(uint16 *) (buffer + TC_BOOT_SECTOR_VERSION_OFFSET) = BE16 (VERSION_NUM);
+
+ if (IsOSAtLeast (WIN_VISTA))
+ buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER;
+
+ if (rescueDisk && (ReadDriverConfigurationFlags() & TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION))
+ buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISABLE_HW_ENCRYPTION;
+
+ // Checksum of the backup header of the outer volume for the hidden system
+ if (hiddenOSCreation)
+ {
+ Device device (GetSystemDriveConfiguration().DevicePath);
+ device.CheckOpened (SRC_POS);
+ byte headerSector[TC_SECTOR_SIZE_BIOS];
+
+ device.SeekAt (HiddenOSCandidatePartition.Info.StartingOffset.QuadPart + HiddenOSCandidatePartition.Info.PartitionLength.QuadPart - TC_VOLUME_HEADER_GROUP_SIZE + TC_VOLUME_HEADER_EFFECTIVE_SIZE);
+ device.Read (headerSector, sizeof (headerSector));
+
+ *(uint32 *) (buffer + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET) = GetCrc32 (headerSector, sizeof (headerSector));
+ }
+
+ // Decompressor
+ byte *decompressor = MapResource (L"BIN", IDR_BOOT_LOADER_DECOMPRESSOR, &size);
+ if (!decompressor || size > TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
+ throw ParameterIncorrect (SRC_POS);
+
+ memcpy (buffer + TC_SECTOR_SIZE_BIOS, decompressor, size);
+
+ // Compressed boot loader
+ byte *bootLoader = MapResource (L"BIN", bootLoaderId, &size);
+ if (!bootLoader || size > TC_MAX_BOOT_LOADER_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
+ throw ParameterIncorrect (SRC_POS);
+
+ memcpy (buffer + TC_SECTOR_SIZE_BIOS + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS, bootLoader, size);
+
+ // Boot loader and decompressor checksum
+ *(uint16 *) (buffer + TC_BOOT_SECTOR_LOADER_LENGTH_OFFSET) = static_cast <uint16> (size);
+ *(uint32 *) (buffer + TC_BOOT_SECTOR_LOADER_CHECKSUM_OFFSET) = GetChecksum (buffer + TC_SECTOR_SIZE_BIOS,
+ TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS + size);
+
+ // Backup of decompressor and boot loader
+ if (size + TC_BOOT_LOADER_DECOMPRESSOR_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS <= TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS)
+ {
+ memcpy (buffer + TC_SECTOR_SIZE_BIOS + TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS,
+ buffer + TC_SECTOR_SIZE_BIOS, TC_BOOT_LOADER_BACKUP_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS);
+
+ buffer[TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_BACKUP_LOADER_AVAILABLE;
+ }
+ else if (!rescueDisk && bootLoaderId != IDR_BOOT_LOADER && bootLoaderId != IDR_BOOT_LOADER_SHA2)
+ {
+ throw ParameterIncorrect (SRC_POS);
+ }
+ }
+
+
+ void BootEncryption::ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig, string *customUserMessage, uint16 *bootLoaderVersion)
+ {
+ if (config && bufLength < TC_BOOT_CFG_FLAG_AREA_SIZE)
+ throw ParameterIncorrect (SRC_POS);
+
+ GetSystemDriveConfigurationRequest request;
+ StringCchCopyW (request.DevicePath, ARRAYSIZE (request.DevicePath), GetSystemDriveConfiguration().DeviceKernelPath.c_str());
+
+ try
+ {
+ CallDriver (TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG, &request, sizeof (request), &request, sizeof (request));
+ if (config)
+ *config = request.Configuration;
+
+ if (userConfig)
+ *userConfig = request.UserConfiguration;
+
+ if (customUserMessage)
+ {
+ request.CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH] = 0;
+ *customUserMessage = request.CustomUserMessage;
+ }
+
+ if (bootLoaderVersion)
+ *bootLoaderVersion = request.BootLoaderVersion;
+ }
+ catch (...)
+ {
+ if (config)
+ *config = 0;
+
+ if (userConfig)
+ *userConfig = 0;
+
+ if (customUserMessage)
+ customUserMessage->clear();
+
+ if (bootLoaderVersion)
+ *bootLoaderVersion = 0;
+ }
+ }
+
+
+ void BootEncryption::WriteBootSectorConfig (const byte newConfig[])
+ {
+ Device device (GetSystemDriveConfiguration().DevicePath);
+ device.CheckOpened (SRC_POS);
+ byte mbr[TC_SECTOR_SIZE_BIOS];
+
+ device.SeekAt (0);
+ device.Read (mbr, sizeof (mbr));
+
+ memcpy (mbr + TC_BOOT_SECTOR_CONFIG_OFFSET, newConfig, TC_BOOT_CFG_FLAG_AREA_SIZE);
+
+ device.SeekAt (0);
+ device.Write (mbr, sizeof (mbr));
+
+ byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS];
+ device.SeekAt (0);
+ device.Read (mbrVerificationBuf, sizeof (mbr));
+
+ if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
+ throw ErrorException ("ERROR_MBR_PROTECTED", SRC_POS);
+ }
+
+
+ void BootEncryption::WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim)
+ {
+ Device device (GetSystemDriveConfiguration().DevicePath);
+ device.CheckOpened (SRC_POS);
+ byte mbr[TC_SECTOR_SIZE_BIOS];
+
+ device.SeekAt (0);
+ device.Read (mbr, sizeof (mbr));
+
+ if (!BufferContainsString (mbr, sizeof (mbr), TC_APP_NAME)
+ || BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET)) != VERSION_NUM)
+ {
+ return;
+ }
+
+ mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = userConfig;
+
+ memset (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, 0, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
+
+ if (!customUserMessage.empty())
+ {
+ if (customUserMessage.size() > TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)
+ throw ParameterIncorrect (SRC_POS);
+
+ memcpy (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, customUserMessage.c_str(), customUserMessage.size());
+ }
+
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ {
+ // PIM for pre-boot authentication can be encoded on two bytes since its maximum
+ // value is 65535 (0xFFFF)
+ memcpy (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
+ else
+ memset (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, 0, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+
+ device.SeekAt (0);
+ device.Write (mbr, sizeof (mbr));
+
+ byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS];
+ device.SeekAt (0);
+ device.Read (mbrVerificationBuf, sizeof (mbr));
+
+ if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
+ throw ErrorException ("ERROR_MBR_PROTECTED", SRC_POS);
+ }
+
+
+ unsigned int BootEncryption::GetHiddenOSCreationPhase ()
+ {
+ byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];
+
+ ReadBootSectorConfig (configFlags, sizeof(configFlags));
+
+ return (configFlags[0] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE);
+ }
+
+
+ void BootEncryption::SetHiddenOSCreationPhase (unsigned int newPhase)
+ {
+#if TC_BOOT_CFG_FLAG_AREA_SIZE != 1
+# error TC_BOOT_CFG_FLAG_AREA_SIZE != 1; revise GetHiddenOSCreationPhase() and SetHiddenOSCreationPhase()
+#endif
+ byte configFlags [TC_BOOT_CFG_FLAG_AREA_SIZE];
+
+ ReadBootSectorConfig (configFlags, sizeof(configFlags));
+
+ configFlags[0] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
+
+ configFlags[0] |= newPhase;
+
+ WriteBootSectorConfig (configFlags);
+ }
+
+
+#ifndef SETUP
+
+ void BootEncryption::StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm)
+ {
+ if (!IsHiddenOSRunning())
+ throw ParameterIncorrect (SRC_POS);
+
+ WipeDecoySystemRequest request;
+ ZeroMemory (&request, sizeof (request));
+
+ request.WipeAlgorithm = wipeAlgorithm;
+
+ if (Randinit() != ERR_SUCCESS)
+ {
+ if (CryptoAPILastError == ERROR_SUCCESS)
+ throw RandInitFailed (SRC_POS, GetLastError ());
+ else
+ throw CryptoApiFailed (SRC_POS, CryptoAPILastError);
+ }
+
+ /* force the display of the random enriching dialog */
+ SetRandomPoolEnrichedByUserStatus (FALSE);
+
+ UserEnrichRandomPool (ParentWindow);
+
+ if (!RandgetBytes (ParentWindow, request.WipeKey, sizeof (request.WipeKey), TRUE))
+ throw ParameterIncorrect (SRC_POS);
+
+ CallDriver (TC_IOCTL_START_DECOY_SYSTEM_WIPE, &request, sizeof (request), NULL, 0);
+
+ burn (&request, sizeof (request));
+ }
+
+
+ void BootEncryption::AbortDecoyOSWipe ()
+ {
+ CallDriver (TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE);
+ }
+
+
+ DecoySystemWipeStatus BootEncryption::GetDecoyOSWipeStatus ()
+ {
+ DecoySystemWipeStatus status;
+ CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS, NULL, 0, &status, sizeof (status));
+ return status;
+ }
+
+
+ void BootEncryption::CheckDecoyOSWipeResult ()
+ {
+ CallDriver (TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT);
+ }
+
+
+ void BootEncryption::WipeHiddenOSCreationConfig ()
+ {
+ if (IsHiddenOSRunning())
+ throw ParameterIncorrect (SRC_POS);
+
+ if (Randinit() != ERR_SUCCESS)
+ {
+ if (CryptoAPILastError == ERROR_SUCCESS)
+ throw RandInitFailed (SRC_POS, GetLastError ());
+ else
+ throw CryptoApiFailed (SRC_POS, CryptoAPILastError);
+ }
+
+ Device device (GetSystemDriveConfiguration().DevicePath);
+ device.CheckOpened(SRC_POS);
+ byte mbr[TC_SECTOR_SIZE_BIOS];
+
+ device.SeekAt (0);
+ device.Read (mbr, sizeof (mbr));
+
+ finally_do_arg (BootEncryption *, this,
+ {
+ try
+ {
+ finally_arg->SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
+ } catch (...) { }
+ });
+
+#if PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE
+# error PRAND_DISK_WIPE_PASSES > RNG_POOL_SIZE
+#endif
+
+ byte randData[PRAND_DISK_WIPE_PASSES];
+ if (!RandgetBytes (ParentWindow, randData, sizeof (randData), FALSE))
+ throw ParameterIncorrect (SRC_POS);
+
+ for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
+ {
+ for (int i = 0; i < TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE; ++i)
+ {
+ mbr[TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + i] = randData[wipePass];
+ }
+
+ mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] &= (byte) ~TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
+ mbr[TC_BOOT_SECTOR_CONFIG_OFFSET] |= randData[wipePass] & TC_BOOT_CFG_MASK_HIDDEN_OS_CREATION_PHASE;
+
+ if (wipePass == PRAND_DISK_WIPE_PASSES - 1)
+ memset (mbr + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, 0, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE);
+
+ device.SeekAt (0);
+ device.Write (mbr, sizeof (mbr));
+ }
+
+ for (int wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES/4 + 1; wipePass++)
+ {
+ SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
+ SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_CLONING);
+ SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPING);
+ SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_WIPED);
+ }
+ SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE);
+ }
+
+#endif // !SETUP
+
+
+ void BootEncryption::InstallBootLoader (bool preserveUserConfig, bool hiddenOSCreation)
+ {
+ Device device (GetSystemDriveConfiguration().DevicePath);
+ device.CheckOpened (SRC_POS);
+
+ InstallBootLoader (device, preserveUserConfig, hiddenOSCreation);
+ }
+
+ void BootEncryption::InstallBootLoader (Device& device, bool preserveUserConfig, bool hiddenOSCreation, int pim)
+ {
+ byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
+ CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, hiddenOSCreation);
+
+ // Write MBR
+ byte mbr[TC_SECTOR_SIZE_BIOS];
+
+ device.SeekAt (0);
+ device.Read (mbr, sizeof (mbr));
+
+ if (preserveUserConfig && BufferContainsString (mbr, sizeof (mbr), TC_APP_NAME))
+ {
+ uint16 version = BE16 (*(uint16 *) (mbr + TC_BOOT_SECTOR_VERSION_OFFSET));
+ if (version != 0)
+ {
+ bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
+ memcpy (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
+
+ if (bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ {
+ if (pim >= 0)
+ {
+ memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
+ else
+ memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
+ }
+ }
+
+ memcpy (mbr, bootLoaderBuf, TC_MAX_MBR_BOOT_CODE_SIZE);
+
+ device.SeekAt (0);
+ device.Write (mbr, sizeof (mbr));
+
+ byte mbrVerificationBuf[TC_SECTOR_SIZE_BIOS];
+ device.SeekAt (0);
+ device.Read (mbrVerificationBuf, sizeof (mbr));
+
+ if (memcmp (mbr, mbrVerificationBuf, sizeof (mbr)) != 0)
+ throw ErrorException ("ERROR_MBR_PROTECTED", SRC_POS);
+
+ // Write boot loader
+ device.SeekAt (TC_SECTOR_SIZE_BIOS);
+ device.Write (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, sizeof (bootLoaderBuf) - TC_SECTOR_SIZE_BIOS);
+ }
+
+#ifndef SETUP
+ bool BootEncryption::CheckBootloaderFingerprint (bool bSilent)
+ {
+ byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
+ byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
+ byte expectedFingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE];
+ bool bRet = false;
+
+ try
+ {
+ // read bootloader fingerprint
+ GetInstalledBootLoaderFingerprint (fingerprint);
+
+ // compute expected fingerprint
+ CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, false);
+ ::ComputeBootloaderFingerprint (bootLoaderBuf, sizeof (bootLoaderBuf), expectedFingerprint);
+
+ // compare values
+ if (0 == memcmp (fingerprint, expectedFingerprint, sizeof (expectedFingerprint)))
+ {
+ bRet = true;
+ }
+ }
+ catch (SystemException &e)
+ {
+ if (!bSilent && (GetLastError () != ERROR_INVALID_IMAGE_HASH))
+ e.Show (ParentWindow);
+ }
+ catch (Exception& e)
+ {
+ if (!bSilent)
+ e.Show (ParentWindow);
+ }
+
+ return bRet;
+ }
+#endif
+
+ wstring BootEncryption::GetSystemLoaderBackupPath ()
+ {
+ WCHAR pathBuf[MAX_PATH];
+
+ throw_sys_if (!SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, pathBuf)));
+
+ wstring path = wstring (pathBuf) + L"\\" _T(TC_APP_NAME);
+ CreateDirectory (path.c_str(), NULL);
+
+ return path + L'\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME;
+ }
+
+
+ void BootEncryption::RenameDeprecatedSystemLoaderBackup ()
+ {
+ WCHAR pathBuf[MAX_PATH];
+
+ if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_APPDATA, NULL, 0, pathBuf)))
+ {
+ wstring path = wstring (pathBuf) + L"\\" _T(TC_APP_NAME) + L'\\' + TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY;
+
+ if (FileExists (path.c_str()) && !FileExists (GetSystemLoaderBackupPath().c_str()))
+ throw_sys_if (_wrename (path.c_str(), GetSystemLoaderBackupPath().c_str()) != 0);
+ }
+ }
+
+
+#ifndef SETUP
+ void BootEncryption::CreateRescueIsoImage (bool initialSetup, const wstring &isoImagePath)
+ {
+ BootEncryptionStatus encStatus = GetStatus();
+ if (encStatus.SetupInProgress)
+ throw ParameterIncorrect (SRC_POS);
+
+ Buffer imageBuf (RescueIsoImageSize);
+
+ byte *image = imageBuf.Ptr();
+ memset (image, 0, RescueIsoImageSize);
+
+ // Primary volume descriptor
+ const char* szPrimVolDesc = "\001CD001\001";
+ const char* szPrimVolLabel = "VeraCrypt Rescue Disk ";
+ memcpy (image + 0x8000, szPrimVolDesc, strlen(szPrimVolDesc) + 1);
+ memcpy (image + 0x7fff + 41, szPrimVolLabel, strlen(szPrimVolLabel) + 1);
+ *(uint32 *) (image + 0x7fff + 81) = RescueIsoImageSize / 2048;
+ *(uint32 *) (image + 0x7fff + 85) = BE32 (RescueIsoImageSize / 2048);
+ image[0x7fff + 121] = 1;
+ image[0x7fff + 124] = 1;
+ image[0x7fff + 125] = 1;
+ image[0x7fff + 128] = 1;
+ image[0x7fff + 130] = 8;
+ image[0x7fff + 131] = 8;
+
+ image[0x7fff + 133] = 10;
+ image[0x7fff + 140] = 10;
+ image[0x7fff + 141] = 0x14;
+ image[0x7fff + 157] = 0x22;
+ image[0x7fff + 159] = 0x18;
+
+ // Boot record volume descriptor
+ const char* szBootRecDesc = "CD001\001EL TORITO SPECIFICATION";
+ memcpy (image + 0x8801, szBootRecDesc, strlen(szBootRecDesc) + 1);
+ image[0x8800 + 0x47] = 0x19;
+
+ // Volume descriptor set terminator
+ const char* szVolDescTerm = "\377CD001\001";
+ memcpy (image + 0x9000, szVolDescTerm, strlen(szVolDescTerm) + 1);
+
+ // Path table
+ image[0xA000 + 0] = 1;
+ image[0xA000 + 2] = 0x18;
+ image[0xA000 + 6] = 1;
+
+ // Root directory
+ image[0xc000 + 0] = 0x22;
+ image[0xc000 + 2] = 0x18;
+ image[0xc000 + 9] = 0x18;
+ image[0xc000 + 11] = 0x08;
+ image[0xc000 + 16] = 0x08;
+ image[0xc000 + 25] = 0x02;
+ image[0xc000 + 28] = 0x01;
+ image[0xc000 + 31] = 0x01;
+ image[0xc000 + 32] = 0x01;
+ image[0xc000 + 34] = 0x22;
+ image[0xc000 + 36] = 0x18;
+ image[0xc000 + 43] = 0x18;
+ image[0xc000 + 45] = 0x08;
+ image[0xc000 + 50] = 0x08;
+ image[0xc000 + 59] = 0x02;
+ image[0xc000 + 62] = 0x01;
+ *(uint32 *) (image + 0xc000 + 65) = 0x010101;
+
+ // Validation entry
+ image[0xc800] = 1;
+ int offset = 0xc800 + 0x1c;
+ image[offset++] = 0xaa;
+ image[offset++] = 0x55;
+ image[offset++] = 0x55;
+ image[offset] = 0xaa;
+
+ // Initial entry
+ offset = 0xc820;
+ image[offset++] = 0x88;
+ image[offset++] = 2;
+ image[0xc820 + 6] = 1;
+ image[0xc820 + 8] = TC_CD_BOOT_LOADER_SECTOR;
+
+ // TrueCrypt Boot Loader
+ CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, true);
+
+ // Volume header
+ if (initialSetup)
+ {
+ if (!RescueVolumeHeaderValid)
+ throw ParameterIncorrect (SRC_POS);
+
+ memcpy (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, RescueVolumeHeader, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
+ }
+ else
+ {
+ Device bootDevice (GetSystemDriveConfiguration().DevicePath, true);
+ bootDevice.CheckOpened (SRC_POS);
+ bootDevice.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
+ bootDevice.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET, TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
+ }
+
+ // Original system loader
+ try
+ {
+ File sysBakFile (GetSystemLoaderBackupPath(), true);
+ sysBakFile.CheckOpened (SRC_POS);
+ sysBakFile.Read (image + TC_CD_BOOTSECTOR_OFFSET + TC_ORIG_BOOT_LOADER_BACKUP_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE);
+
+ image[TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_SECTOR_CONFIG_OFFSET] |= TC_BOOT_CFG_FLAG_RESCUE_DISK_ORIG_SYS_LOADER;
+ }
+ catch (Exception &e)
+ {
+ e.Show (ParentWindow);
+ Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK", ParentWindow);
+ }
+
+ // Boot loader backup
+ CreateBootLoaderInMemory (image + TC_CD_BOOTSECTOR_OFFSET + TC_BOOT_LOADER_BACKUP_RESCUE_DISK_SECTOR_OFFSET, TC_BOOT_LOADER_AREA_SIZE, false);
+
+ RescueIsoImage = new byte[RescueIsoImageSize];
+ if (!RescueIsoImage)
+ throw bad_alloc();
+ memcpy (RescueIsoImage, image, RescueIsoImageSize);
+
+ if (!isoImagePath.empty())
+ {
+ File isoFile (isoImagePath, false, true);
+ isoFile.Write (image, RescueIsoImageSize);
+ }
+ }
+#endif
+
+
+ bool BootEncryption::IsCDRecorderPresent ()
+ {
+ ICDBurn* pICDBurn;
+ BOOL bHasRecorder = FALSE;
+
+ if (SUCCEEDED( CoCreateInstance (CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn)))
+ {
+ if (pICDBurn->HasRecordableDrive (&bHasRecorder) != S_OK)
+ {
+ bHasRecorder = FALSE;
+ }
+ pICDBurn->Release();
+ }
+ return bHasRecorder? true : false;
+ }
+
+
+ bool BootEncryption::VerifyRescueDisk ()
+ {
+ if (!RescueIsoImage)
+ throw ParameterIncorrect (SRC_POS);
+
+ for (WCHAR drive = L'Z'; drive >= L'C'; --drive)
+ {
+ try
+ {
+ WCHAR rootPath[4] = { drive, L':', L'\\', 0};
+ UINT driveType = GetDriveType (rootPath);
+ // check that it is a CD/DVD drive or a removable media in case a bootable
+ // USB key was created from the rescue disk ISO file
+ if ((DRIVE_CDROM == driveType) || (DRIVE_REMOVABLE == driveType))
+ {
+ rootPath[2] = 0; // remove trailing backslash
+
+ Device driveDevice (rootPath, true);
+ driveDevice.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 = driveDevice.Read (buffer.Ptr(), (DWORD) buffer.Size());
+ if (bytesRead != buffer.Size())
+ continue;
+
+ if (memcmp (buffer.Ptr(), RescueIsoImage, buffer.Size()) == 0)
+ return true;
+ }
+ }
+ catch (...) { }
+ }
+
+ return false;
+ }
+
+ bool BootEncryption::VerifyRescueDiskIsoImage (const wchar_t* imageFile)
+ {
+ if (!RescueIsoImage)
+ throw ParameterIncorrect (SRC_POS);
+
+ try
+ {
+ File isoFile (imageFile, true);
+ isoFile.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 = isoFile.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,
+ 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, FALSE, 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);
+
+ byte *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);
+
+ device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
+ device.Write ((byte *) VolumeHeader, sizeof (VolumeHeader));
+ }
+
+
+ // For synchronous operations use AbortSetupWait()
+ void BootEncryption::AbortSetup ()
+ {
+ CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
+ }
+
+
+ // For asynchronous operations use AbortSetup()
+ void BootEncryption::AbortSetupWait ()
+ {
+ CallDriver (TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP);
+
+ BootEncryptionStatus encStatus = GetStatus();
+
+ while (encStatus.SetupInProgress)
+ {
+ Sleep (TC_ABORT_TRANSFORM_WAIT_INTERVAL);
+ encStatus = GetStatus();
+ }
+ }
+
+
+ void BootEncryption::BackupSystemLoader ()
+ {
+ Device device (GetSystemDriveConfiguration().DevicePath, true);
+ device.CheckOpened (SRC_POS);
+ byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS];
+
+ device.SeekAt (0);
+ device.Read (bootLoaderBuf, sizeof (bootLoaderBuf));
+
+ // Prevent TrueCrypt loader from being backed up
+ for (size_t i = 0; i < sizeof (bootLoaderBuf) - strlen (TC_APP_NAME); ++i)
+ {
+ if (memcmp (bootLoaderBuf + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0)
+ {
+ if (AskWarnNoYes ("TC_BOOT_LOADER_ALREADY_INSTALLED", ParentWindow) == IDNO)
+ throw UserAbort (SRC_POS);
+ return;
+ }
+ }
+
+ File backupFile (GetSystemLoaderBackupPath(), false, true);
+ backupFile.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
+ }
+
+
+ void BootEncryption::RestoreSystemLoader ()
+ {
+ byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SECTOR_COUNT * TC_SECTOR_SIZE_BIOS];
+
+ File backupFile (GetSystemLoaderBackupPath(), true);
+ backupFile.CheckOpened(SRC_POS);
+ if (backupFile.Read (bootLoaderBuf, sizeof (bootLoaderBuf)) != sizeof (bootLoaderBuf))
+ throw ParameterIncorrect (SRC_POS);
+
+ Device device (GetSystemDriveConfiguration().DevicePath);
+ device.CheckOpened (SRC_POS);
+
+ // Preserve current partition table
+ byte mbr[TC_SECTOR_SIZE_BIOS];
+ device.SeekAt (0);
+ device.Read (mbr, sizeof (mbr));
+ memcpy (bootLoaderBuf + TC_MAX_MBR_BOOT_CODE_SIZE, mbr + TC_MAX_MBR_BOOT_CODE_SIZE, sizeof (mbr) - TC_MAX_MBR_BOOT_CODE_SIZE);
+
+ device.SeekAt (0);
+ device.Write (bootLoaderBuf, sizeof (bootLoaderBuf));
+ }
+
+#endif // SETUP
+
+ void BootEncryption::RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid)
+ {
+ string filter;
+ string filterReg;
+ HKEY regKey;
+
+ switch (filterType)
+ {
+ case DriveFilter:
+ case VolumeFilter:
+ filter = "veracrypt";
+ filterReg = "UpperFilters";
+ regKey = OpenDeviceClassRegKey (deviceClassGuid);
+ throw_sys_if (regKey == INVALID_HANDLE_VALUE);
+
+ break;
+
+ case DumpFilter:
+ if (!IsOSAtLeast (WIN_VISTA))
+ return;
+
+ filter = "veracrypt.sys";
+ filterReg = "DumpFilters";
+ SetLastError (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\CrashControl", 0, KEY_READ | KEY_WRITE, &regKey));
+ throw_sys_if (GetLastError() != ERROR_SUCCESS);
+
+ break;
+
+ default:
+ throw ParameterIncorrect (SRC_POS);
+ }
+
+ finally_do_arg (HKEY, regKey, { RegCloseKey (finally_arg); });
+
+ if (registerFilter && filterType != DumpFilter)
+ {
+ // Register class filter below all other filters in the stack
+
+ size_t strSize = filter.size() + 1;
+ byte regKeyBuf[65536];
+ DWORD size = (DWORD) (sizeof (regKeyBuf) - strSize);
+
+ // SetupInstallFromInfSection() does not support prepending of values so we have to modify the registry directly
+ StringCchCopyA ((char *) regKeyBuf, ARRAYSIZE(regKeyBuf), filter.c_str());
+
+ if (RegQueryValueExA (regKey, filterReg.c_str(), NULL, NULL, regKeyBuf + strSize, &size) != ERROR_SUCCESS)
+ size = 1;
+
+ SetLastError (RegSetValueExA (regKey, filterReg.c_str(), 0, REG_MULTI_SZ, regKeyBuf, (DWORD) strSize + size));
+ throw_sys_if (GetLastError() != ERROR_SUCCESS);
+ }
+ else
+ {
+ RegisterDriverInf (registerFilter, filter, filterReg, ParentWindow, regKey);
+ }
+ }
+
+ void BootEncryption::RegisterFilterDriver (bool registerDriver, FilterType filterType)
+ {
+ if (!IsAdmin() && IsUacSupported())
+ {
+ Elevator::RegisterFilterDriver (registerDriver, filterType);
+ return;
+ }
+
+ switch (filterType)
+ {
+ case DriveFilter:
+ RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_DISKDRIVE);
+ break;
+
+ case VolumeFilter:
+ RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_VOLUME);
+ RegisterFilter (registerDriver, filterType, &GUID_DEVCLASS_FLOPPYDISK);
+ break;
+
+ case DumpFilter:
+ RegisterFilter (registerDriver, filterType);
+ break;
+
+ default:
+ throw ParameterIncorrect (SRC_POS);
+ }
+ }
+
+ void BootEncryption::RegisterSystemFavoritesService (BOOL registerService, BOOL noFileHandling)
+ {
+ SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ throw_sys_if (!scm);
+ finally_do_arg (SC_HANDLE, scm, { CloseServiceHandle (finally_arg); });
+
+ wstring servicePath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", false);
+ wstring serviceLegacyPath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", true);
+
+ if (registerService)
+ {
+ try
+ {
+ RegisterSystemFavoritesService (FALSE, noFileHandling);
+ }
+ catch (...) { }
+
+ if (!noFileHandling)
+ {
+ wchar_t appPath[TC_MAX_PATH];
+ throw_sys_if (!GetModuleFileName (NULL, appPath, ARRAYSIZE (appPath)));
+
+ throw_sys_if (!CopyFile (appPath, servicePath.c_str(), FALSE));
+ }
+
+ SC_HANDLE service = CreateService (scm,
+ TC_SYSTEM_FAVORITES_SERVICE_NAME,
+ _T(TC_APP_NAME) L" System Favorites",
+ SERVICE_ALL_ACCESS,
+ SERVICE_WIN32_OWN_PROCESS,
+ SERVICE_AUTO_START,
+ SERVICE_ERROR_NORMAL,
+ (wstring (L"\"") + servicePath + L"\" " TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION).c_str(),
+ TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ throw_sys_if (!service);
+
+ SERVICE_DESCRIPTION description;
+ description.lpDescription = L"Mounts VeraCrypt system favorite volumes.";
+ ChangeServiceConfig2 (service, SERVICE_CONFIG_DESCRIPTION, &description);
+
+ CloseServiceHandle (service);
+
+ try
+ {
+ WriteLocalMachineRegistryString (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, L"Service", FALSE);
+ WriteLocalMachineRegistryString (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Network\\" TC_SYSTEM_FAVORITES_SERVICE_NAME, NULL, L"Service", FALSE);
+
+ SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, true);
+ }
+ catch (...)
+ {
+ try
+ {
+ RegisterSystemFavoritesService (FALSE, noFileHandling);
+ }
+ catch (...) { }
+
+ throw;
+ }
+ }
+ else
+ {
+ SetDriverConfigurationFlag (TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES, false);
+
+ DeleteLocalMachineRegistryKey (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal", TC_SYSTEM_FAVORITES_SERVICE_NAME);
+ DeleteLocalMachineRegistryKey (L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Network", TC_SYSTEM_FAVORITES_SERVICE_NAME);
+
+ SC_HANDLE service = OpenService (scm, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS);
+ throw_sys_if (!service);
+
+ throw_sys_if (!DeleteService (service));
+ CloseServiceHandle (service);
+
+ if (!noFileHandling)
+ {
+ DeleteFile (servicePath.c_str());
+ if (serviceLegacyPath != servicePath)
+ DeleteFile (serviceLegacyPath.c_str());
+ }
+ }
+ }
+
+ void BootEncryption::UpdateSystemFavoritesService ()
+ {
+ SC_HANDLE scm = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ throw_sys_if (!scm);
+
+ finally_do_arg (SC_HANDLE, scm, { CloseServiceHandle (finally_arg); });
+
+ wstring servicePath = GetServiceConfigPath (_T(TC_APP_NAME) L".exe", false);
+
+ // check if service exists
+ SC_HANDLE service = OpenService (scm, TC_SYSTEM_FAVORITES_SERVICE_NAME, SERVICE_ALL_ACCESS);
+ if (service)
+ {
+ finally_do_arg (SC_HANDLE, service, { CloseServiceHandle (finally_arg); });
+ // ensure that its parameters are correct
+ throw_sys_if (!ChangeServiceConfig (service,
+ SERVICE_WIN32_OWN_PROCESS,
+ SERVICE_AUTO_START,
+ SERVICE_ERROR_NORMAL,
+ (wstring (L"\"") + servicePath + L"\" " TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION).c_str(),
+ TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _T(TC_APP_NAME) L" System Favorites"));
+
+ }
+ else
+ {
+ RegisterSystemFavoritesService (TRUE, TRUE);
+ }
+ }
+
+ void BootEncryption::SetDriverConfigurationFlag (uint32 flag, bool state)
+ {
+ DWORD configMap = ReadDriverConfigurationFlags();
+
+ if (state)
+ configMap |= flag;
+ else
+ configMap &= ~flag;
+#ifdef SETUP
+ WriteLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, configMap);
+#else
+ WriteLocalMachineRegistryDwordValue (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, configMap);
+#endif
+ }
+
+#ifndef SETUP
+
+ void BootEncryption::RegisterSystemFavoritesService (BOOL registerService)
+ {
+ if (!IsAdmin() && IsUacSupported())
+ {
+ Elevator::RegisterSystemFavoritesService (registerService);
+ return;
+ }
+
+ RegisterSystemFavoritesService (registerService, FALSE);
+ }
+
+ void BootEncryption::CheckRequirements ()
+ {
+ if (nCurrentOS == WIN_2000)
+ throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_CURRENT_OS", SRC_POS);
+
+ if (CurrentOSMajor == 6 && CurrentOSMinor == 0 && CurrentOSServicePack < 1)
+ throw ErrorException ("SYS_ENCRYPTION_UNSUPPORTED_ON_VISTA_SP0", SRC_POS);
+
+ if (IsNonInstallMode())
+ throw ErrorException ("FEATURE_REQUIRES_INSTALLATION", SRC_POS);
+
+ SystemDriveConfiguration config = GetSystemDriveConfiguration ();
+
+ if (config.SystemPartition.IsGPT)
+ throw ErrorException ("GPT_BOOT_DRIVE_UNSUPPORTED", SRC_POS);
+
+ if (SystemDriveIsDynamic())
+ throw ErrorException ("SYSENC_UNSUPPORTED_FOR_DYNAMIC_DISK", SRC_POS);
+
+ if (config.InitialUnallocatedSpace < TC_BOOT_LOADER_AREA_SIZE)
+ throw ErrorException ("NO_SPACE_FOR_BOOT_LOADER", SRC_POS);
+
+ DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
+
+ if (geometry.BytesPerSector != TC_SECTOR_SIZE_BIOS)
+ throw ErrorException ("SYSENC_UNSUPPORTED_SECTOR_SIZE_BIOS", SRC_POS);
+
+ bool activePartitionFound = false;
+ if (!config.SystemPartition.IsGPT)
+ {
+ // Determine whether there is an Active partition on the system drive
+ foreach (const Partition &partition, config.Partitions)
+ {
+ if (partition.Info.BootIndicator)
+ {
+ activePartitionFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!config.SystemLoaderPresent || !activePartitionFound)
+ {
+ static bool confirmed = false;
+
+ if (!confirmed && AskWarnNoYes ("WINDOWS_NOT_ON_BOOT_DRIVE_ERROR", ParentWindow) == IDNO)
+ throw UserAbort (SRC_POS);
+
+ confirmed = true;
+ }
+ }
+
+
+ void BootEncryption::CheckRequirementsHiddenOS ()
+ {
+ // It is assumed that CheckRequirements() had been called (so we don't check e.g. whether it's GPT).
+
+ // The user may have modified/added/deleted partitions since the partition table was last scanned.
+ InvalidateCachedSysDriveProperties ();
+
+ GetPartitionForHiddenOS ();
+ }
+
+
+ void BootEncryption::InitialSecurityChecksForHiddenOS ()
+ {
+ wchar_t windowsDrive = (wchar_t) towupper (GetWindowsDirectory()[0]);
+
+ // Paging files
+ bool pagingFilesOk = !IsPagingFileActive (TRUE);
+
+ wchar_t pagingFileRegData[65536];
+ DWORD pagingFileRegDataSize = sizeof (pagingFileRegData);
+
+ if (ReadLocalMachineRegistryMultiString (L"System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", L"PagingFiles", pagingFileRegData, &pagingFileRegDataSize)
+ && pagingFileRegDataSize > 8)
+ {
+ for (size_t i = 1; i < pagingFileRegDataSize/2 - 2; ++i)
+ {
+ if (wmemcmp (pagingFileRegData + i, L":\\", 2) == 0 && towupper (pagingFileRegData[i - 1]) != windowsDrive)
+ {
+ pagingFilesOk = false;
+ break;
+ }
+ }
+ }
+
+ if (!pagingFilesOk)
+ {
+ if (AskWarnYesNoString ((wchar_t *) (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION"))
+ + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION")
+ + L"\n\n\n"
+ + GetString ("RESTRICT_PAGING_FILES_TO_SYS_PARTITION")
+ ).c_str(), ParentWindow) == IDYES)
+ {
+ RestrictPagingFilesToSystemPartition();
+ RestartComputer();
+ AbortProcessSilent();
+ }
+
+ throw ErrorException (wstring (GetString ("PAGING_FILE_NOT_ON_SYS_PARTITION"))
+ + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"), SRC_POS);
+ }
+
+ // User profile
+ wchar_t *configPath = GetConfigPath (L"dummy");
+ if (configPath && towupper (configPath[0]) != windowsDrive)
+ {
+ throw ErrorException (wstring (GetString ("USER_PROFILE_NOT_ON_SYS_PARTITION"))
+ + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"), SRC_POS);
+ }
+
+ // Temporary files
+ if (towupper (GetTempPathString()[0]) != windowsDrive)
+ {
+ throw ErrorException (wstring (GetString ("TEMP_NOT_ON_SYS_PARTITION"))
+ + GetString ("LEAKS_OUTSIDE_SYSPART_UNIVERSAL_EXPLANATION"), SRC_POS);
+ }
+ }
+
+
+ // This operation may take a long time when an antivirus is installed and its real-time protection enabled.
+ // Therefore, if calling it without the wizard displayed, it should be called with displayWaitDialog set to true.
+ void BootEncryption::Deinstall (bool displayWaitDialog)
+ {
+ BootEncryptionStatus encStatus = GetStatus();
+
+ if (encStatus.DriveEncrypted || encStatus.DriveMounted)
+ throw ParameterIncorrect (SRC_POS);
+
+ SystemDriveConfiguration config = GetSystemDriveConfiguration ();
+
+ if (encStatus.VolumeHeaderPresent)
+ {
+ // Verify CRC of header salt
+ Device device (config.DevicePath, true);
+ device.CheckOpened (SRC_POS);
+ byte header[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
+
+ device.SeekAt (TC_BOOT_VOLUME_HEADER_SECTOR_OFFSET);
+ device.Read (header, sizeof (header));
+
+ if (encStatus.VolumeHeaderSaltCrc32 != GetCrc32 ((byte *) header, PKCS5_SALT_SIZE))
+ throw ParameterIncorrect (SRC_POS);
+ }
+
+ try
+ {
+ RegisterFilterDriver (false, DriveFilter);
+ RegisterFilterDriver (false, VolumeFilter);
+ RegisterFilterDriver (false, DumpFilter);
+ SetDriverServiceStartType (SERVICE_SYSTEM_START);
+ }
+ catch (...)
+ {
+ try
+ {
+ RegisterBootDriver (IsHiddenSystemRunning());
+ }
+ catch (...) { }
+
+ throw;
+ }
+
+ SetHiddenOSCreationPhase (TC_HIDDEN_OS_CREATION_PHASE_NONE); // In case RestoreSystemLoader() fails
+
+ try
+ {
+ 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];
+ 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 ((byte *) header, sizeof (header));
+
+ PCRYPTO_INFO cryptoInfo = NULL;
+
+ int status = ReadVolumeHeader (!encStatus.HiddenSystem, header, oldPassword, old_pkcs5, old_pim, FALSE, &cryptoInfo, NULL);
+ finally_do_arg (PCRYPTO_INFO, cryptoInfo, { if (finally_arg) crypto_close (finally_arg); });
+
+ 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);
+ }
+ finally_do ({ RandStop (FALSE); });
+
+ /* force the display of the random enriching dialog */
+ SetRandomPoolEnrichedByUserStatus (FALSE);
+
+ NormalCursor();
+ UserEnrichRandomPool (hwndDlg);
+ WaitCursor();
+
+ /* The header will be re-encrypted wipePassCount times to prevent adversaries from using
+ techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
+ to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
+ times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
+ impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
+ valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
+ recommends. During each pass we will write a valid working header. Each pass will use the same master
+ key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
+ item that will be different for each pass will be the salt. This is sufficient to cause each "version"
+ of the header to differ substantially and in a random manner from the versions written during the
+ other passes. */
+
+ bool headerUpdated = false;
+ int result = ERR_SUCCESS;
+
+ try
+ {
+ BOOL backupHeader = FALSE;
+ while (TRUE)
+ {
+ for (int wipePass = 0; wipePass < wipePassCount; wipePass++)
+ {
+ PCRYPTO_INFO tmpCryptoInfo = NULL;
+
+ status = CreateVolumeHeaderInMemory (hwndDlg, !encStatus.HiddenSystem,
+ header,
+ cryptoInfo->ea,
+ cryptoInfo->mode,
+ newPassword,
+ cryptoInfo->pkcs5,
+ pim,
+ (char *) cryptoInfo->master_keydata,
+ &tmpCryptoInfo,
+ cryptoInfo->VolumeSize.Value,
+ cryptoInfo->hiddenVolumeSize,
+ cryptoInfo->EncryptedAreaStart.Value,
+ cryptoInfo->EncryptedAreaLength.Value,
+ cryptoInfo->RequiredProgramVersion,
+ cryptoInfo->HeaderFlags | TC_HEADER_FLAG_ENCRYPTED_SYSTEM,
+ cryptoInfo->SectorSize,
+ wipePass < wipePassCount - 1);
+
+ if (tmpCryptoInfo)
+ crypto_close (tmpCryptoInfo);
+
+ if (status != 0)
+ {
+ handleError (hwndDlg, status, SRC_POS);
+ return status;
+ }
+
+ device.SeekAt (headerOffset);
+ device.Write ((byte *) header, sizeof (header));
+ headerUpdated = true;
+ }
+
+ if (!encStatus.HiddenSystem || backupHeader)
+ break;
+
+ backupHeader = TRUE;
+ headerOffset = backupHeaderOffset;
+ }
+ }
+ catch (Exception &e)
+ {
+ e.Show (hwndDlg);
+ result = ERR_OS_ERROR;
+ }
+
+ if (headerUpdated)
+ {
+ bool storedPimUpdateNeeded = false;
+ ReopenBootVolumeHeaderRequest reopenRequest;
+ reopenRequest.VolumePassword = *newPassword;
+ reopenRequest.pkcs5_prf = cryptoInfo->pkcs5;
+ reopenRequest.pim = pim;
+ finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
+
+ if (old_pim != pim)
+ {
+ try
+ {
+ // check if PIM is stored in MBR
+ byte userConfig;
+ ReadBootSectorConfig (nullptr, 0, &userConfig);
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ storedPimUpdateNeeded = true;
+ }
+ catch (...)
+ {}
+ }
+
+ try
+ {
+ // force update of bootloader if fingerprint doesn't match or if the stored PIM changed
+ if (storedPimUpdateNeeded || !CheckBootloaderFingerprint (true))
+ InstallBootLoader (device, true, false, pim);
+ }
+ catch (...)
+ {}
+
+ CallDriver (TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER, &reopenRequest, sizeof (reopenRequest));
+ }
+
+ return result;
+ }
+
+
+ void BootEncryption::CheckEncryptionSetupResult ()
+ {
+ CallDriver (TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT);
+ }
+
+
+ void BootEncryption::Install (bool hiddenSystem)
+ {
+ BootEncryptionStatus encStatus = GetStatus();
+ if (encStatus.DriveMounted)
+ throw ParameterIncorrect (SRC_POS);
+
+ try
+ {
+ InstallBootLoader (false, hiddenSystem);
+
+ if (!hiddenSystem)
+ InstallVolumeHeader ();
+
+ RegisterBootDriver (hiddenSystem);
+ }
+ catch (Exception &)
+ {
+ try
+ {
+ RestoreSystemLoader ();
+ }
+ catch (Exception &e)
+ {
+ e.Show (ParentWindow);
+ }
+
+ throw;
+ }
+ }
+
+
+ void BootEncryption::PrepareHiddenOSCreation (int ea, int mode, int pkcs5)
+ {
+ BootEncryptionStatus encStatus = GetStatus();
+ if (encStatus.DriveMounted)
+ throw ParameterIncorrect (SRC_POS);
+
+ CheckRequirements();
+ BackupSystemLoader();
+
+ SelectedEncryptionAlgorithmId = ea;
+ SelectedPrfAlgorithmId = pkcs5;
+ }
+
+
+ void BootEncryption::PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, int pim, const wstring &rescueIsoImagePath)
+ {
+ BootEncryptionStatus encStatus = GetStatus();
+ if (encStatus.DriveMounted)
+ throw ParameterIncorrect (SRC_POS);
+
+ CheckRequirements ();
+
+ SystemDriveConfiguration config = GetSystemDriveConfiguration();
+
+ // Some chipset drivers may prevent access to the last sector of the drive
+ if (!systemPartitionOnly)
+ {
+ DISK_GEOMETRY geometry = GetDriveGeometry (config.DriveNumber);
+ if ((geometry.BytesPerSector > 0) && (geometry.BytesPerSector < TC_MAX_VOLUME_SECTOR_SIZE))
+ {
+ Buffer sector (geometry.BytesPerSector);
+
+ Device device (config.DevicePath);
+ device.CheckOpened (SRC_POS);
+
+ try
+ {
+ device.SeekAt (config.DrivePartition.Info.PartitionLength.QuadPart - geometry.BytesPerSector);
+ device.Read (sector.Ptr(), (DWORD) sector.Size());
+ }
+ catch (SystemException &e)
+ {
+ if (e.ErrorCode != ERROR_CRC)
+ {
+ e.Show (ParentWindow);
+ Error ("WHOLE_DRIVE_ENCRYPTION_PREVENTED_BY_DRIVERS", ParentWindow);
+ throw UserAbort (SRC_POS);
+ }
+ }
+ }
+ }
+
+ BackupSystemLoader ();
+
+ uint64 volumeSize;
+ uint64 encryptedAreaStart;
+
+ if (systemPartitionOnly)
+ {
+ volumeSize = config.SystemPartition.Info.PartitionLength.QuadPart;
+ encryptedAreaStart = config.SystemPartition.Info.StartingOffset.QuadPart;
+ }
+ else
+ {
+ volumeSize = config.DrivePartition.Info.PartitionLength.QuadPart - TC_BOOT_LOADER_AREA_SIZE;
+ encryptedAreaStart = config.DrivePartition.Info.StartingOffset.QuadPart + TC_BOOT_LOADER_AREA_SIZE;
+ }
+
+ SelectedEncryptionAlgorithmId = ea;
+ SelectedPrfAlgorithmId = pkcs5;
+ CreateVolumeHeader (volumeSize, encryptedAreaStart, &password, ea, mode, pkcs5, pim);
+
+ if (!rescueIsoImagePath.empty())
+ CreateRescueIsoImage (true, rescueIsoImagePath);
+ }
+
+ bool BootEncryption::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
+ {
+ if (!IsAdmin() && IsUacSupported())
+ return Elevator::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false;
+
+ return ::IsPagingFileActive (checkNonWindowsPartitionsOnly) ? true : false;
+ }
+
+ void BootEncryption::RestrictPagingFilesToSystemPartition ()
+ {
+ wchar_t pagingFiles[128] = {0};
+ StringCchCopyW (pagingFiles, ARRAYSIZE(pagingFiles), L"X:\\pagefile.sys 0 0");
+ pagingFiles[0] = GetWindowsDirectory()[0];
+
+ throw_sys_if (!WriteLocalMachineRegistryMultiString (L"System\\CurrentControlSet\\Control\\Session Manager\\Memory Management", L"PagingFiles", pagingFiles, (DWORD) (wcslen (pagingFiles) + 2) * sizeof (wchar_t)));
+ }
+
+ void BootEncryption::WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value)
+ {
+ if (!IsAdmin() && IsUacSupported())
+ {
+ Elevator::WriteLocalMachineRegistryDwordValue (keyPath, valueName, value);
+ return;
+ }
+
+ throw_sys_if (!WriteLocalMachineRegistryDword (keyPath, valueName, value));
+ }
+
+ void BootEncryption::StartDecryption (BOOL discardUnreadableEncryptedSectors)
+ {
+ BootEncryptionStatus encStatus = GetStatus();
+
+ if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
+ throw ParameterIncorrect (SRC_POS);
+
+ BootEncryptionSetupRequest request;
+ ZeroMemory (&request, sizeof (request));
+
+ request.SetupMode = SetupDecryption;
+ request.DiscardUnreadableEncryptedSectors = discardUnreadableEncryptedSectors;
+
+ CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
+ }
+
+ void BootEncryption::StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors)
+ {
+ BootEncryptionStatus encStatus = GetStatus();
+
+ if (!encStatus.DeviceFilterActive || !encStatus.DriveMounted || encStatus.SetupInProgress)
+ throw ParameterIncorrect (SRC_POS);
+
+ BootEncryptionSetupRequest request;
+ ZeroMemory (&request, sizeof (request));
+
+ request.SetupMode = SetupEncryption;
+ request.WipeAlgorithm = wipeAlgorithm;
+ request.ZeroUnreadableSectors = zeroUnreadableSectors;
+
+ CallDriver (TC_IOCTL_BOOT_ENCRYPTION_SETUP, &request, sizeof (request), NULL, 0);
+ }
+
+ void BootEncryption::CopyFileAdmin (const wstring &sourceFile, const wstring &destinationFile)
+ {
+ if (!IsAdmin())
+ {
+ if (!IsUacSupported())
+ {
+ SetLastError (ERROR_ACCESS_DENIED);
+ throw SystemException(SRC_POS);
+ }
+ else
+ Elevator::CopyFile (sourceFile, destinationFile);
+ }
+ else
+ throw_sys_if (!::CopyFile (sourceFile.c_str(), destinationFile.c_str(), FALSE));
+ }
+
+ void BootEncryption::DeleteFileAdmin (const wstring &file)
+ {
+ if (!IsAdmin() && IsUacSupported())
+ Elevator::DeleteFile (file);
+ else
+ throw_sys_if (!::DeleteFile (file.c_str()));
+ }
+
+#endif // !SETUP
+
+ uint32 BootEncryption::ReadDriverConfigurationFlags ()
+ {
+ DWORD configMap;
+
+ if (!ReadLocalMachineRegistryDword (L"SYSTEM\\CurrentControlSet\\Services\\veracrypt", TC_DRIVER_CONFIG_REG_VALUE_NAME, &configMap))
+ configMap = 0;
+
+ return configMap;
+ }
+
+ void BootEncryption::WriteBootDriveSector (uint64 offset, byte *data)
+ {
+ WriteBootDriveSectorRequest request;
+ request.Offset.QuadPart = offset;
+ memcpy (request.Data, data, sizeof (request.Data));
+
+ CallDriver (TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR, &request, sizeof (request), NULL, 0);
+ }
+
+ void BootEncryption::RegisterBootDriver (bool hiddenSystem)
+ {
+ SetDriverServiceStartType (SERVICE_BOOT_START);
+
+ try
+ {
+ RegisterFilterDriver (false, DriveFilter);
+ RegisterFilterDriver (false, VolumeFilter);
+ RegisterFilterDriver (false, DumpFilter);
+ }
+ catch (...) { }
+
+ try
+ {
+ RegisterFilterDriver (true, DriveFilter);
+
+ if (hiddenSystem)
+ RegisterFilterDriver (true, VolumeFilter);
+
+ RegisterFilterDriver (true, DumpFilter);
+ }
+ catch (...)
+ {
+ try { RegisterFilterDriver (false, DriveFilter); } catch (...) { }
+ try { RegisterFilterDriver (false, VolumeFilter); } catch (...) { }
+ try { RegisterFilterDriver (false, DumpFilter); } catch (...) { }
+ try { SetDriverServiceStartType (SERVICE_SYSTEM_START); } catch (...) { }
+
+ throw;
+ }
+ }
+
+ bool BootEncryption::RestartComputer (void)
+ {
+ return (::RestartComputer() != FALSE);
+ }
+}
diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h
index a922d1f..a89b2ec 100644
--- a/src/Common/BootEncryption.h
+++ b/src/Common/BootEncryption.h
@@ -1,255 +1,255 @@
-/*
- 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-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.
-*/
-
-#ifndef TC_HEADER_Common_BootEncryption
-#define TC_HEADER_Common_BootEncryption
-
-#include "Tcdefs.h"
-#include "Dlgcode.h"
-#include "Exception.h"
-#include "Platform/PlatformBase.h"
-#include "Volumes.h"
-
-using namespace std;
-
-namespace VeraCrypt
-{
- class File
- {
- public:
- File () : Elevated (false), FileOpen (false), FilePointerPosition(0), Handle(INVALID_HANDLE_VALUE), IsDevice(false), LastError(0) { }
- File (wstring path,bool readOnly = false, bool create = false);
- virtual ~File () { Close(); }
-
- void CheckOpened (const char* srcPos) { if (!FileOpen) { SetLastError (LastError); throw SystemException (srcPos);} }
- void Close ();
- DWORD Read (byte *buffer, DWORD size);
- void Write (byte *buffer, DWORD size);
- void SeekAt (int64 position);
-
- protected:
- bool Elevated;
- bool FileOpen;
- uint64 FilePointerPosition;
- HANDLE Handle;
- bool IsDevice;
- wstring Path;
- DWORD LastError;
- };
-
-
- class Device : public File
- {
- public:
- Device (wstring path,bool readOnly = false);
- virtual ~Device () {}
- };
-
-
- class Buffer
- {
- public:
- Buffer (size_t size) : DataSize (size)
- {
- DataPtr = new byte[size];
- if (!DataPtr)
- throw bad_alloc();
- }
-
- ~Buffer () { delete[] DataPtr; }
- byte *Ptr () const { return DataPtr; }
- size_t Size () const { return DataSize; }
-
- protected:
- byte *DataPtr;
- size_t DataSize;
- };
-
-
- struct Partition
- {
- wstring DevicePath;
- PARTITION_INFORMATION Info;
- wstring MountPoint;
- size_t Number;
- BOOL IsGPT;
- wstring VolumeNameId;
- };
-
- typedef list <Partition> PartitionList;
-
-#pragma pack (push)
-#pragma pack(1)
-
- struct PartitionEntryMBR
- {
- byte BootIndicator;
-
- byte StartHead;
- byte StartCylSector;
- byte StartCylinder;
-
- byte Type;
-
- byte EndHead;
- byte EndSector;
- byte EndCylinder;
-
- uint32 StartLBA;
- uint32 SectorCountLBA;
- };
-
- struct MBR
- {
- byte Code[446];
- PartitionEntryMBR Partitions[4];
- uint16 Signature;
- };
-
-#pragma pack (pop)
-
- struct SystemDriveConfiguration
- {
- wstring DeviceKernelPath;
- wstring DevicePath;
- int DriveNumber;
- Partition DrivePartition;
- bool ExtraBootPartitionPresent;
- int64 InitialUnallocatedSpace;
- PartitionList Partitions;
- Partition SystemPartition;
- int64 TotalUnallocatedSpace;
- bool SystemLoaderPresent;
- };
-
- class BootEncryption
- {
- public:
- BootEncryption (HWND parent);
- ~BootEncryption ();
-
- enum FilterType
- {
- DriveFilter,
- VolumeFilter,
- DumpFilter
- };
-
- void SetParentWindow (HWND parent) { ParentWindow = parent; }
- void AbortDecoyOSWipe ();
- void AbortSetup ();
- void AbortSetupWait ();
- void CallDriver (DWORD ioctl, void *input = nullptr, DWORD inputSize = 0, void *output = nullptr, DWORD outputSize = 0);
- int ChangePassword (Password *oldPassword, int old_pkcs5, int old_pim, Password *newPassword, int pkcs5, int pim, int wipePassCount, HWND hwndDlg);
- void CheckDecoyOSWipeResult ();
- void CheckEncryptionSetupResult ();
- void CheckRequirements ();
- void CheckRequirementsHiddenOS ();
- void CopyFileAdmin (const wstring &sourceFile, const wstring &destinationFile);
- void CreateRescueIsoImage (bool initialSetup, const wstring &isoImagePath);
- void Deinstall (bool displayWaitDialog = false);
- void DeleteFileAdmin (const wstring &file);
- DecoySystemWipeStatus GetDecoyOSWipeStatus ();
- DWORD GetDriverServiceStartType ();
- unsigned int GetHiddenOSCreationPhase ();
- uint16 GetInstalledBootLoaderVersion ();
- void GetInstalledBootLoaderFingerprint (byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE]);
- Partition GetPartitionForHiddenOS ();
- bool IsBootLoaderOnDrive (wchar_t *devicePath);
- BootEncryptionStatus GetStatus ();
- void GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties);
- SystemDriveConfiguration GetSystemDriveConfiguration ();
- void Install (bool hiddenSystem);
- void InstallBootLoader (Device& device, bool preserveUserConfig = false, bool hiddenOSCreation = false, int pim = -1);
- void InstallBootLoader (bool preserveUserConfig = false, bool hiddenOSCreation = false);
- bool CheckBootloaderFingerprint (bool bSilent = false);
- void InvalidateCachedSysDriveProperties ();
- bool IsCDRecorderPresent ();
- bool IsHiddenSystemRunning ();
- bool IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
- void PrepareHiddenOSCreation (int ea, int mode, int pkcs5);
- void PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, int pim, const wstring &rescueIsoImagePath);
- void ProbeRealSystemDriveSize ();
- void ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig = nullptr, string *customUserMessage = nullptr, uint16 *bootLoaderVersion = nullptr);
- uint32 ReadDriverConfigurationFlags ();
- void RegisterBootDriver (bool hiddenSystem);
- void RegisterFilterDriver (bool registerDriver, FilterType filterType);
- void RegisterSystemFavoritesService (BOOL registerService);
- void RegisterSystemFavoritesService (BOOL registerService, BOOL noFileHandling);
- void UpdateSystemFavoritesService ();
- void RenameDeprecatedSystemLoaderBackup ();
- bool RestartComputer (void);
- void InitialSecurityChecksForHiddenOS ();
- void RestrictPagingFilesToSystemPartition ();
- void SetDriverConfigurationFlag (uint32 flag, bool state);
- void SetDriverServiceStartType (DWORD startType);
- void SetHiddenOSCreationPhase (unsigned int newPhase);
- void StartDecryption (BOOL discardUnreadableEncryptedSectors);
- void StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm);
- void StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors);
- bool SystemDriveContainsPartitionType (byte type);
- bool SystemDriveContainsExtendedPartition ();
- bool SystemDriveContainsNonStandardPartitions ();
- bool SystemPartitionCoversWholeDrive ();
- bool SystemDriveIsDynamic ();
- bool VerifyRescueDisk ();
- bool VerifyRescueDiskIsoImage (const wchar_t* imageFile);
- void WipeHiddenOSCreationConfig ();
- void WriteBootDriveSector (uint64 offset, byte *data);
- void WriteBootSectorConfig (const byte newConfig[]);
- void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim);
- void WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value);
-
- protected:
- static const uint32 RescueIsoImageSize = 1835008; // Size of ISO9660 image with bootable emulated 1.44MB floppy disk image
-
- void BackupSystemLoader ();
- void CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation = false);
- void CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5, int pim);
- wstring GetSystemLoaderBackupPath ();
- uint32 GetChecksum (byte *data, size_t size);
- DISK_GEOMETRY GetDriveGeometry (int driveNumber);
- PartitionList GetDrivePartitions (int driveNumber);
- wstring GetRemarksOnHiddenOS ();
- wstring GetWindowsDirectory ();
- void RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid = nullptr);
- void RestoreSystemLoader ();
- void InstallVolumeHeader ();
-
- HWND ParentWindow;
- SystemDriveConfiguration DriveConfig;
- int SelectedEncryptionAlgorithmId;
- int SelectedPrfAlgorithmId;
- Partition HiddenOSCandidatePartition;
- byte *RescueIsoImage;
- byte RescueVolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
- byte VolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
- bool DriveConfigValid;
- bool RealSystemDriveSizeValid;
- bool RescueVolumeHeaderValid;
- bool VolumeHeaderValid;
- };
-}
-
-#define TC_ABORT_TRANSFORM_WAIT_INTERVAL 10
-
-#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS 2.1
-#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT 1.05
-
-#define TC_SYS_BOOT_LOADER_BACKUP_NAME L"Original System Loader"
-#define TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY L"Original System Loader.bak" // Deprecated to prevent removal by some "cleaners"
-
-#define TC_SYSTEM_FAVORITES_SERVICE_NAME _T(TC_APP_NAME) L"SystemFavorites"
-#define TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP L"Event Log"
-#define TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION L"/systemFavoritesService"
-
-#endif // TC_HEADER_Common_BootEncryption
+/*
+ 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-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.
+*/
+
+#ifndef TC_HEADER_Common_BootEncryption
+#define TC_HEADER_Common_BootEncryption
+
+#include "Tcdefs.h"
+#include "Dlgcode.h"
+#include "Exception.h"
+#include "Platform/PlatformBase.h"
+#include "Volumes.h"
+
+using namespace std;
+
+namespace VeraCrypt
+{
+ class File
+ {
+ public:
+ File () : Elevated (false), FileOpen (false), FilePointerPosition(0), Handle(INVALID_HANDLE_VALUE), IsDevice(false), LastError(0) { }
+ File (wstring path,bool readOnly = false, bool create = false);
+ virtual ~File () { Close(); }
+
+ void CheckOpened (const char* srcPos) { if (!FileOpen) { SetLastError (LastError); throw SystemException (srcPos);} }
+ void Close ();
+ DWORD Read (byte *buffer, DWORD size);
+ void Write (byte *buffer, DWORD size);
+ void SeekAt (int64 position);
+
+ protected:
+ bool Elevated;
+ bool FileOpen;
+ uint64 FilePointerPosition;
+ HANDLE Handle;
+ bool IsDevice;
+ wstring Path;
+ DWORD LastError;
+ };
+
+
+ class Device : public File
+ {
+ public:
+ Device (wstring path,bool readOnly = false);
+ virtual ~Device () {}
+ };
+
+
+ class Buffer
+ {
+ public:
+ Buffer (size_t size) : DataSize (size)
+ {
+ DataPtr = new byte[size];
+ if (!DataPtr)
+ throw bad_alloc();
+ }
+
+ ~Buffer () { delete[] DataPtr; }
+ byte *Ptr () const { return DataPtr; }
+ size_t Size () const { return DataSize; }
+
+ protected:
+ byte *DataPtr;
+ size_t DataSize;
+ };
+
+
+ struct Partition
+ {
+ wstring DevicePath;
+ PARTITION_INFORMATION Info;
+ wstring MountPoint;
+ size_t Number;
+ BOOL IsGPT;
+ wstring VolumeNameId;
+ };
+
+ typedef list <Partition> PartitionList;
+
+#pragma pack (push)
+#pragma pack(1)
+
+ struct PartitionEntryMBR
+ {
+ byte BootIndicator;
+
+ byte StartHead;
+ byte StartCylSector;
+ byte StartCylinder;
+
+ byte Type;
+
+ byte EndHead;
+ byte EndSector;
+ byte EndCylinder;
+
+ uint32 StartLBA;
+ uint32 SectorCountLBA;
+ };
+
+ struct MBR
+ {
+ byte Code[446];
+ PartitionEntryMBR Partitions[4];
+ uint16 Signature;
+ };
+
+#pragma pack (pop)
+
+ struct SystemDriveConfiguration
+ {
+ wstring DeviceKernelPath;
+ wstring DevicePath;
+ int DriveNumber;
+ Partition DrivePartition;
+ bool ExtraBootPartitionPresent;
+ int64 InitialUnallocatedSpace;
+ PartitionList Partitions;
+ Partition SystemPartition;
+ int64 TotalUnallocatedSpace;
+ bool SystemLoaderPresent;
+ };
+
+ class BootEncryption
+ {
+ public:
+ BootEncryption (HWND parent);
+ ~BootEncryption ();
+
+ enum FilterType
+ {
+ DriveFilter,
+ VolumeFilter,
+ DumpFilter
+ };
+
+ void SetParentWindow (HWND parent) { ParentWindow = parent; }
+ void AbortDecoyOSWipe ();
+ void AbortSetup ();
+ void AbortSetupWait ();
+ void CallDriver (DWORD ioctl, void *input = nullptr, DWORD inputSize = 0, void *output = nullptr, DWORD outputSize = 0);
+ int ChangePassword (Password *oldPassword, int old_pkcs5, int old_pim, Password *newPassword, int pkcs5, int pim, int wipePassCount, HWND hwndDlg);
+ void CheckDecoyOSWipeResult ();
+ void CheckEncryptionSetupResult ();
+ void CheckRequirements ();
+ void CheckRequirementsHiddenOS ();
+ void CopyFileAdmin (const wstring &sourceFile, const wstring &destinationFile);
+ void CreateRescueIsoImage (bool initialSetup, const wstring &isoImagePath);
+ void Deinstall (bool displayWaitDialog = false);
+ void DeleteFileAdmin (const wstring &file);
+ DecoySystemWipeStatus GetDecoyOSWipeStatus ();
+ DWORD GetDriverServiceStartType ();
+ unsigned int GetHiddenOSCreationPhase ();
+ uint16 GetInstalledBootLoaderVersion ();
+ void GetInstalledBootLoaderFingerprint (byte fingerprint[WHIRLPOOL_DIGESTSIZE + SHA512_DIGESTSIZE]);
+ Partition GetPartitionForHiddenOS ();
+ bool IsBootLoaderOnDrive (wchar_t *devicePath);
+ BootEncryptionStatus GetStatus ();
+ void GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties);
+ SystemDriveConfiguration GetSystemDriveConfiguration ();
+ void Install (bool hiddenSystem);
+ void InstallBootLoader (Device& device, bool preserveUserConfig = false, bool hiddenOSCreation = false, int pim = -1);
+ void InstallBootLoader (bool preserveUserConfig = false, bool hiddenOSCreation = false);
+ bool CheckBootloaderFingerprint (bool bSilent = false);
+ void InvalidateCachedSysDriveProperties ();
+ bool IsCDRecorderPresent ();
+ bool IsHiddenSystemRunning ();
+ bool IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
+ void PrepareHiddenOSCreation (int ea, int mode, int pkcs5);
+ void PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, int pim, const wstring &rescueIsoImagePath);
+ void ProbeRealSystemDriveSize ();
+ void ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig = nullptr, string *customUserMessage = nullptr, uint16 *bootLoaderVersion = nullptr);
+ uint32 ReadDriverConfigurationFlags ();
+ void RegisterBootDriver (bool hiddenSystem);
+ void RegisterFilterDriver (bool registerDriver, FilterType filterType);
+ void RegisterSystemFavoritesService (BOOL registerService);
+ void RegisterSystemFavoritesService (BOOL registerService, BOOL noFileHandling);
+ void UpdateSystemFavoritesService ();
+ void RenameDeprecatedSystemLoaderBackup ();
+ bool RestartComputer (void);
+ void InitialSecurityChecksForHiddenOS ();
+ void RestrictPagingFilesToSystemPartition ();
+ void SetDriverConfigurationFlag (uint32 flag, bool state);
+ void SetDriverServiceStartType (DWORD startType);
+ void SetHiddenOSCreationPhase (unsigned int newPhase);
+ void StartDecryption (BOOL discardUnreadableEncryptedSectors);
+ void StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm);
+ void StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors);
+ bool SystemDriveContainsPartitionType (byte type);
+ bool SystemDriveContainsExtendedPartition ();
+ bool SystemDriveContainsNonStandardPartitions ();
+ bool SystemPartitionCoversWholeDrive ();
+ bool SystemDriveIsDynamic ();
+ bool VerifyRescueDisk ();
+ bool VerifyRescueDiskIsoImage (const wchar_t* imageFile);
+ void WipeHiddenOSCreationConfig ();
+ void WriteBootDriveSector (uint64 offset, byte *data);
+ void WriteBootSectorConfig (const byte newConfig[]);
+ void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim);
+ void WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value);
+
+ protected:
+ static const uint32 RescueIsoImageSize = 1835008; // Size of ISO9660 image with bootable emulated 1.44MB floppy disk image
+
+ void BackupSystemLoader ();
+ void CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation = false);
+ void CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5, int pim);
+ wstring GetSystemLoaderBackupPath ();
+ uint32 GetChecksum (byte *data, size_t size);
+ DISK_GEOMETRY GetDriveGeometry (int driveNumber);
+ PartitionList GetDrivePartitions (int driveNumber);
+ wstring GetRemarksOnHiddenOS ();
+ wstring GetWindowsDirectory ();
+ void RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid = nullptr);
+ void RestoreSystemLoader ();
+ void InstallVolumeHeader ();
+
+ HWND ParentWindow;
+ SystemDriveConfiguration DriveConfig;
+ int SelectedEncryptionAlgorithmId;
+ int SelectedPrfAlgorithmId;
+ Partition HiddenOSCandidatePartition;
+ byte *RescueIsoImage;
+ byte RescueVolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
+ byte VolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
+ bool DriveConfigValid;
+ bool RealSystemDriveSizeValid;
+ bool RescueVolumeHeaderValid;
+ bool VolumeHeaderValid;
+ };
+}
+
+#define TC_ABORT_TRANSFORM_WAIT_INTERVAL 10
+
+#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS 2.1
+#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT 1.05
+
+#define TC_SYS_BOOT_LOADER_BACKUP_NAME L"Original System Loader"
+#define TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY L"Original System Loader.bak" // Deprecated to prevent removal by some "cleaners"
+
+#define TC_SYSTEM_FAVORITES_SERVICE_NAME _T(TC_APP_NAME) L"SystemFavorites"
+#define TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP L"Event Log"
+#define TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION L"/systemFavoritesService"
+
+#endif // TC_HEADER_Common_BootEncryption
diff --git a/src/Common/Cache.c b/src/Common/Cache.c
index e32896f..ba6c6df 100644
--- a/src/Common/Cache.c
+++ b/src/Common/Cache.c
@@ -1,115 +1,115 @@
-/*
- 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-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"
-#include "Crypto.h"
-#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;
-
-int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, char *header, Password *password, int pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo)
-{
- int nReturnCode = ERR_PASSWORD_WRONG;
- int i, effectivePim;
-
- /* Attempt to recognize volume using mount password */
- if (password->Length > 0)
- {
- nReturnCode = ReadVolumeHeader (bBoot, header, password, pkcs5_prf, pim, truecryptMode, retInfo, NULL);
-
- /* Save mount passwords back into cache if asked to do so */
- if (bCache && (nReturnCode == 0 || nReturnCode == ERR_CIPHER_INIT_WEAK_KEY))
- {
- for (i = 0; i < CACHE_SIZE; i++)
- {
- if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0)
- break;
- }
-
- if (i == CACHE_SIZE)
- {
- /* Store the password */
- CachedPasswords[nPasswordIdx] = *password;
-
- /* Store also PIM if requested, otherwise set to default */
- if (bCachePim && (pim > 0))
- CachedPim[nPasswordIdx] = pim;
- else
- CachedPim[nPasswordIdx] = 0;
-
- /* Try another slot */
- nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE;
-
- cacheEmpty = 0;
- }
- else if (bCachePim)
- {
- CachedPim[i] = pim > 0? pim : 0;
- }
- }
- }
- else if (!cacheEmpty)
- {
- /* Attempt to recognize volume using cached passwords */
- for (i = 0; i < CACHE_SIZE; i++)
- {
- if (CachedPasswords[i].Length > 0)
- {
- if (truecryptMode)
- effectivePim = 0;
- else if (pim == -1)
- effectivePim = CachedPim[i];
- else
- effectivePim = pim;
- nReturnCode = ReadVolumeHeader (bBoot, header, &CachedPasswords[i], pkcs5_prf, effectivePim, truecryptMode, retInfo, NULL);
-
- if (nReturnCode != ERR_PASSWORD_WRONG)
- break;
- }
- }
- }
-
- return nReturnCode;
-}
-
-
-void AddPasswordToCache (Password *password, int pim)
-{
- int i;
- for (i = 0; i < CACHE_SIZE; i++)
- {
- if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0)
- return;
- }
-
- CachedPasswords[nPasswordIdx] = *password;
- CachedPim[nPasswordIdx] = pim > 0? pim : 0;
- nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE;
- cacheEmpty = 0;
-}
-
-
-void WipeCache ()
-{
- burn (CachedPasswords, sizeof (CachedPasswords));
- burn (CachedPim, sizeof (CachedPim));
- nPasswordIdx = 0;
- cacheEmpty = 1;
-}
+/*
+ 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-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"
+#include "Crypto.h"
+#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;
+
+int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, BOOL bCachePim, char *header, Password *password, int pkcs5_prf, int pim, BOOL truecryptMode, PCRYPTO_INFO *retInfo)
+{
+ int nReturnCode = ERR_PASSWORD_WRONG;
+ int i, effectivePim;
+
+ /* Attempt to recognize volume using mount password */
+ if (password->Length > 0)
+ {
+ nReturnCode = ReadVolumeHeader (bBoot, header, password, pkcs5_prf, pim, truecryptMode, retInfo, NULL)