diff options
author | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2016-05-10 22:34:27 +0200 |
---|---|---|
committer | Mounir IDRASSI <mounir.idrassi@idrix.fr> | 2016-05-10 22:34:27 +0200 |
commit | 268ef2d8e904db5068dbdc0fdc7ce3940d6452ea (patch) | |
tree | b1afa687c97fbf5e1ba2c92c5a10479ae5f832f5 /src/Boot/Windows | |
parent | 6d61f06a5348aebe7dbc0bf44d3e2729c20f7fd0 (diff) | |
parent | 5f47d8b6f11cdb3c4c2f43e04e5acfc6ffcb3035 (diff) | |
download | VeraCrypt-268ef2d8e904db5068dbdc0fdc7ce3940d6452ea.tar.gz VeraCrypt-268ef2d8e904db5068dbdc0fdc7ce3940d6452ea.zip |
Merge pull request #61 from davidfoerster/normalize-line-terminators
Normalize line terminators
Diffstat (limited to 'src/Boot/Windows')
27 files changed, 5110 insertions, 5110 deletions
diff --git a/src/Boot/Windows/Bios.h b/src/Boot/Windows/Bios.h index 314b1a62..e6f9ec89 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 d0b40f1a..64ad48ec 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>NUL:
nmake.exe /nologo RELEASE=1

md Release_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

md Release_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

md Rescue_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

md Rescue_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

md Rescue_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

md Rescue_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2"
- ReBuildCommandLine="del /q /s Release >NUL:
md Release 2>NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_SHA2 >NUL:
md Release_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

del /q /s Release_AES >NUL:
md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_AES_SHA2 >NUL:
md Release_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

del /q /s Release_Serpent >NUL:
md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Serpent_SHA2 >NUL:
md Release_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

del /q /s Release_Twofish >NUL:
md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

del /q /s Release_Twofish_SHA2 >NUL:
md Release_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

del /q /s Rescue >NUL:
md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

del /q /s Rescue_SHA2 >NUL:
md Rescue_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_AES >NUL:
md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

del /q /s Rescue_AES_SHA2 >NUL:
md Rescue_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Serpent >NUL:
md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

del /q /s Rescue_Serpent_SHA2 >NUL:
md Rescue_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Twofish >NUL:
md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

del /q /s Rescue_Twofish_SHA2 >NUL:
md Rescue_Twofish_SHA2 2>NUL:
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 >NUL:
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 >NUL:
"
- Output="Release\BootLoader.com"
- PreprocessorDefinitions="WIN32;NDEBUG"
- IncludeSearchPath=""$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(MSVC16_ROOT)\Include""
- ForcedIncludes=""
- AssemblySearchPath=""
- ForcedUsingAssemblies=""
- CompileAsManaged=""
- />
- </Configuration>
- <Configuration
- Name="Release Loader|Win32"
- OutputDirectory="$(ConfigurationName)"
- IntermediateDirectory="$(ConfigurationName)"
- ConfigurationType="0"
- >
- <Tool
- Name="VCNMakeTool"
- BuildCommandLine="md Release 2>NUL:
nmake.exe /nologo RELEASE=1

md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
- ReBuildCommandLine="del /q /s Release >NUL:
md Release 2>NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_AES >NUL:
md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_Serpent >NUL:
md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Twofish >NUL:
md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
- CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish >NUL:"
- Output="Release\BootLoader.com"
- PreprocessorDefinitions="WIN32;NDEBUG"
- IncludeSearchPath=""$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(MSVC16_ROOT)\Include""
- 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>NUL:
nmake.exe /nologo RELEASE=1

md Release_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

md Release_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

md Rescue_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

md Rescue_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

md Rescue_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

md Rescue_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1 SINGLE_PRF=SHA2" + ReBuildCommandLine="del /q /s Release >NUL:
md Release 2>NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_SHA2 >NUL:
md Release_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_PRF=SHA2

del /q /s Release_AES >NUL:
md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_AES_SHA2 >NUL:
md Release_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES SINGLE_PRF=SHA2

del /q /s Release_Serpent >NUL:
md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Serpent_SHA2 >NUL:
md Release_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT SINGLE_PRF=SHA2

del /q /s Release_Twofish >NUL:
md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH

del /q /s Release_Twofish_SHA2 >NUL:
md Release_Twofish_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH SINGLE_PRF=SHA2

del /q /s Rescue >NUL:
md Rescue 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1

del /q /s Rescue_SHA2 >NUL:
md Rescue_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_AES >NUL:
md Rescue_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1

del /q /s Rescue_AES_SHA2 >NUL:
md Rescue_AES_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Serpent >NUL:
md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

del /q /s Rescue_Serpent_SHA2 >NUL:
md Rescue_Serpent_SHA2 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1 SINGLE_PRF=SHA2

del /q /s Rescue_Twofish >NUL:
md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1

del /q /s Rescue_Twofish_SHA2 >NUL:
md Rescue_Twofish_SHA2 2>NUL:
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 >NUL:
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 >NUL:
" + Output="Release\BootLoader.com" + PreprocessorDefinitions="WIN32;NDEBUG" + IncludeSearchPath=""$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(MSVC16_ROOT)\Include"" + ForcedIncludes="" + AssemblySearchPath="" + ForcedUsingAssemblies="" + CompileAsManaged="" + /> + </Configuration> + <Configuration + Name="Release Loader|Win32" + OutputDirectory="$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="0" + > + <Tool + Name="VCNMakeTool" + BuildCommandLine="md Release 2>NUL:
nmake.exe /nologo RELEASE=1

md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH" + ReBuildCommandLine="del /q /s Release >NUL:
md Release 2>NUL:
nmake.exe /nologo RELEASE=1

del /q /s Release_AES >NUL:
md Release_AES 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES

del /q /s Release_Serpent >NUL:
md Release_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT

del /q /s Release_Twofish >NUL:
md Release_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH" + CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish >NUL:" + Output="Release\BootLoader.com" + PreprocessorDefinitions="WIN32;NDEBUG" + IncludeSearchPath=""$(SolutionDir)";"$(SolutionDir)\Common";"$(SolutionDir)\Crypto";"$(MSVC16_ROOT)\Include"" + 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 4d91981b..0d4f710d 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 63ebaf5e..3e41d610 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 0c5eee74..428d713c 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 31b66673..2fee84fc 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 6af75c05..52a054fe 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 e309fcb0..92ac1563 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 0f33ed5a..dd0863a0 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 138dcf62..e7ae4134 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 69c57dbc..1fc923ae 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 31917a64..15d6f711 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 §orCount)
-{
- 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 §or, 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, §or);
-
- return result;
-}
-
-
-static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 §or, 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 §or, 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 §or, uint16 sectorCount, bool silent)
-{
- return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent);
-}
-
-
-BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, 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 §or, 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 §orCount) +{ + 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 §or, 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, §or); + + return result; +} + + +static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 §or, 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 §or, 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 §or, uint16 sectorCount, bool silent) +{ + return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent); +} + + +BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, 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 §or, 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 d1c1ccff..ad9d1437 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 §orCount);
-BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false);
-BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false);
-BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, 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 §or, uint16 sectorCount, bool silent);
-BiosResult WriteSectors (byte *buffer, byte drive, const uint64 §or, 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 §orCount); +BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false); +BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 §or, uint16 sectorCount, bool silent = false); +BiosResult ReadSectors (byte *buffer, byte drive, const uint64 §or, 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 §or, uint16 sectorCount, bool silent); +BiosResult WriteSectors (byte *buffer, byte drive, const uint64 §or, 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 d130534f..63fd0f47 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, §or, 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 §or, 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, §or, 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 §or, 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 6cc375fa..d27ec9ea 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 §or, 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 §or, uint16 sectorCount); + +#endif // TC_HEADER_Boot_BootEncryptionIo diff --git a/src/Boot/Windows/BootMain.cpp b/src/Boot/Windows/BootMain.cpp index 275c5762..57697a4f 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 b6e75fa6..0f89179a 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 c1dd3833..5729142f 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 0ed0470d..d08e88ac 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 e0049d29..833ff616 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 dcf197a1..6c5d7847 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 475a501d..3bed8c67 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 0671c4d0..4a39fd14 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 (®s, &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, ®s, 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, ®s, 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, ¤tInt13Handler, 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 (®s, &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, ®s, 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, ®s, 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, ¤tInt13Handler, 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 af354802..3f3a486a 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 f9851051..8377520b 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 d9819cfa..0a45bba6 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 2fa532ce..a8e83bec 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 |