mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-27 13:33:29 +01:00
Add original TrueCrypt 7.1a sources
This commit is contained in:
commit
c606f0866c
28
src/Boot/Windows/Bios.h
Normal file
28
src/Boot/Windows/Bios.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
242
src/Boot/Windows/Boot.vcproj
Normal file
242
src/Boot/Windows/Boot.vcproj
Normal file
@ -0,0 +1,242 @@
|
||||
<?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_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

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

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

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

md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1"
|
||||
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

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

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_Serpent >NUL:
md Rescue_Serpent 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1

del /q /s Rescue_Twofish >NUL:
md Rescue_Twofish 2>NUL:
nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1"
|
||||
CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish Rescue Rescue_AES Rescue_Serpent Rescue_Twofish >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\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>
|
78
src/Boot/Windows/BootCommon.h
Normal file
78
src/Boot/Windows/BootCommon.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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 0x060a
|
||||
|
||||
#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
|
90
src/Boot/Windows/BootConfig.cpp
Normal file
90
src/Boot/Windows/BootConfig.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright (c) 2008-2012 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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 HiddenVolumeStartUnitNo;
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
42
src/Boot/Windows/BootConfig.h
Normal file
42
src/Boot/Windows/BootConfig.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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 HiddenVolumeStartUnitNo;
|
||||
extern uint64 HiddenVolumeStartSector;
|
||||
|
||||
|
||||
void ReadBootSectorUserConfiguration ();
|
||||
BiosResult UpdateBootSectorConfiguration (byte drive);
|
||||
|
||||
#endif // TC_HEADER_Boot_BootConfig
|
330
src/Boot/Windows/BootConsoleIo.cpp
Normal file
330
src/Boot/Windows/BootConsoleIo.cpp
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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 <= '~';
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
67
src/Boot/Windows/BootConsoleIo.h
Normal file
67
src/Boot/Windows/BootConsoleIo.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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);
|
||||
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
|
23
src/Boot/Windows/BootCrt.asm
Normal file
23
src/Boot/Windows/BootCrt.asm
Normal file
@ -0,0 +1,23 @@
|
||||
;
|
||||
; Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
;
|
||||
; Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
; the file License.txt included in TrueCrypt 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
|
177
src/Boot/Windows/BootDebug.cpp
Normal file
177
src/Boot/Windows/BootDebug.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
56
src/Boot/Windows/BootDebug.h
Normal file
56
src/Boot/Windows/BootDebug.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
188
src/Boot/Windows/BootDefs.h
Normal file
188
src/Boot/Windows/BootDefs.h
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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 42
|
||||
|
||||
#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 30
|
||||
# else
|
||||
# define TC__BOOT_MEMORY_REQUIRED 28
|
||||
# endif
|
||||
# elif defined (TC_WINDOWS_BOOT_SERPENT)
|
||||
# define TC__BOOT_MEMORY_REQUIRED 32
|
||||
# elif defined (TC_WINDOWS_BOOT_TWOFISH)
|
||||
# define TC__BOOT_MEMORY_REQUIRED 40
|
||||
# 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_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)
|
||||
|
||||
// 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_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_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
|
487
src/Boot/Windows/BootDiskIo.cpp
Normal file
487
src/Boot/Windows/BootDiskIo.cpp
Normal file
@ -0,0 +1,487 @@
|
||||
/*
|
||||
Copyright (c) 2008-2011 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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;
|
||||
}
|
116
src/Boot/Windows/BootDiskIo.h
Normal file
116
src/Boot/Windows/BootDiskIo.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Copyright (c) 2008-2011 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
128
src/Boot/Windows/BootEncryptedIo.cpp
Normal file
128
src/Boot/Windows/BootEncryptedIo.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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 += HiddenVolumeStartUnitNo;
|
||||
}
|
||||
|
||||
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;
|
||||
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 += HiddenVolumeStartUnitNo;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
18
src/Boot/Windows/BootEncryptedIo.h
Normal file
18
src/Boot/Windows/BootEncryptedIo.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
1151
src/Boot/Windows/BootMain.cpp
Normal file
1151
src/Boot/Windows/BootMain.cpp
Normal file
File diff suppressed because it is too large
Load Diff
30
src/Boot/Windows/BootMain.h
Normal file
30
src/Boot/Windows/BootMain.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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);
|
||||
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
|
82
src/Boot/Windows/BootMemory.cpp
Normal file
82
src/Boot/Windows/BootMemory.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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);
|
||||
}
|
24
src/Boot/Windows/BootMemory.h
Normal file
24
src/Boot/Windows/BootMemory.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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);
|
237
src/Boot/Windows/BootSector.asm
Normal file
237
src/Boot/Windows/BootSector.asm
Normal file
@ -0,0 +1,237 @@
|
||||
;
|
||||
; Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
;
|
||||
; Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
; the file License.txt included in TrueCrypt 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 ' TrueCrypt 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
|
||||
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, 6
|
||||
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! Use Rescue Disk: Repair Options > Restore', 0
|
||||
|
||||
ORG 7C00h + 510
|
||||
dw 0AA55h ; Boot sector signature
|
||||
|
||||
_TEXT ENDS
|
||||
END start
|
16
src/Boot/Windows/BootStrings.h
Normal file
16
src/Boot/Windows/BootStrings.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
436
src/Boot/Windows/Decompressor.c
Normal file
436
src/Boot/Windows/Decompressor.c
Normal file
@ -0,0 +1,436 @@
|
||||
/*
|
||||
puff.c
|
||||
Copyright (C) 2002-2004 Mark Adler, all rights reserved
|
||||
version 1.8, 9 Jan 2004
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Mark Adler madler@alumni.caltech.edu
|
||||
*/
|
||||
|
||||
/* Adapted for TrueCrypt */
|
||||
|
||||
|
||||
#define local static /* for local function definitions */
|
||||
#define NIL ((unsigned char *)0) /* for no output option */
|
||||
|
||||
/*
|
||||
* Maximums for allocations and loops. It is not useful to change these --
|
||||
* they are fixed by the deflate format.
|
||||
*/
|
||||
#define MAXBITS 15 /* maximum bits in a code */
|
||||
#define MAXLCODES 286 /* maximum number of literal/length codes */
|
||||
#define MAXDCODES 30 /* maximum number of distance codes */
|
||||
#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */
|
||||
#define FIXLCODES 288 /* number of fixed literal/length codes */
|
||||
|
||||
/* input and output state */
|
||||
struct state {
|
||||
/* output state */
|
||||
unsigned char *out; /* output buffer */
|
||||
unsigned int outlen; /* available space at out */
|
||||
unsigned int outcnt; /* bytes written to out so far */
|
||||
|
||||
/* input state */
|
||||
unsigned char *in; /* input buffer */
|
||||
unsigned int incnt; /* bytes read so far */
|
||||
int bitbuf; /* bit buffer */
|
||||
int bitcnt; /* number of bits in bit buffer */
|
||||
};
|
||||
|
||||
|
||||
local int bits(struct state *s, int need)
|
||||
{
|
||||
long val; /* bit accumulator (can use up to 20 bits) */
|
||||
|
||||
/* load at least need bits into val */
|
||||
val = s->bitbuf;
|
||||
while (s->bitcnt < need) {
|
||||
val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
|
||||
s->bitcnt += 8;
|
||||
}
|
||||
|
||||
/* drop need bits and update buffer, always zero to seven bits left */
|
||||
s->bitbuf = (int)(val >> need);
|
||||
s->bitcnt -= need;
|
||||
|
||||
/* return need bits, zeroing the bits above that */
|
||||
return (int)(val & ((1L << need) - 1));
|
||||
}
|
||||
|
||||
|
||||
local int stored(struct state *s)
|
||||
{
|
||||
unsigned len; /* length of stored block */
|
||||
|
||||
/* discard leftover bits from current byte (assumes s->bitcnt < 8) */
|
||||
s->bitbuf = 0;
|
||||
s->bitcnt = 0;
|
||||
|
||||
/* get length and check against its one's complement */
|
||||
len = s->in[s->incnt++];
|
||||
len |= s->in[s->incnt++] << 8;
|
||||
if (s->in[s->incnt++] != (~len & 0xff) ||
|
||||
s->in[s->incnt++] != ((~len >> 8) & 0xff))
|
||||
return -2; /* didn't match complement! */
|
||||
|
||||
/* copy len bytes from in to out */
|
||||
if (s->out != NIL) {
|
||||
if (s->outcnt + len > s->outlen)
|
||||
return 1; /* not enough output space */
|
||||
while (len--)
|
||||
s->out[s->outcnt++] = s->in[s->incnt++];
|
||||
}
|
||||
else { /* just scanning */
|
||||
s->outcnt += len;
|
||||
s->incnt += len;
|
||||
}
|
||||
|
||||
/* done with a valid stored block */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct huffman {
|
||||
short *count; /* number of symbols of each length */
|
||||
short *symbol; /* canonically ordered symbols */
|
||||
};
|
||||
|
||||
|
||||
#ifdef SLOW
|
||||
local int decode(struct state *s, struct huffman *h)
|
||||
{
|
||||
int len; /* current number of bits in code */
|
||||
int code; /* len bits being decoded */
|
||||
int first; /* first code of length len */
|
||||
int count; /* number of codes of length len */
|
||||
int index; /* index of first code of length len in symbol table */
|
||||
|
||||
code = first = index = 0;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
code |= bits(s, 1); /* get next bit */
|
||||
count = h->count[len];
|
||||
if (code < first + count) /* if length len, return symbol */
|
||||
return h->symbol[index + (code - first)];
|
||||
index += count; /* else update for next length */
|
||||
first += count;
|
||||
first <<= 1;
|
||||
code <<= 1;
|
||||
}
|
||||
return -9; /* ran out of codes */
|
||||
}
|
||||
|
||||
/*
|
||||
* A faster version of decode() for real applications of this code. It's not
|
||||
* as readable, but it makes puff() twice as fast. And it only makes the code
|
||||
* a few percent larger.
|
||||
*/
|
||||
#else /* !SLOW */
|
||||
local int decode(struct state *s, struct huffman *h)
|
||||
{
|
||||
int len; /* current number of bits in code */
|
||||
int code; /* len bits being decoded */
|
||||
int first; /* first code of length len */
|
||||
int count; /* number of codes of length len */
|
||||
int index; /* index of first code of length len in symbol table */
|
||||
int bitbuf; /* bits from stream */
|
||||
int left; /* bits left in next or left to process */
|
||||
short *next; /* next number of codes */
|
||||
|
||||
bitbuf = s->bitbuf;
|
||||
left = s->bitcnt;
|
||||
code = first = index = 0;
|
||||
len = 1;
|
||||
next = h->count + 1;
|
||||
while (1) {
|
||||
while (left--) {
|
||||
code |= bitbuf & 1;
|
||||
bitbuf >>= 1;
|
||||
count = *next++;
|
||||
if (code < first + count) { /* if length len, return symbol */
|
||||
s->bitbuf = bitbuf;
|
||||
s->bitcnt = (s->bitcnt - len) & 7;
|
||||
return h->symbol[index + (code - first)];
|
||||
}
|
||||
index += count; /* else update for next length */
|
||||
first += count;
|
||||
first <<= 1;
|
||||
code <<= 1;
|
||||
len++;
|
||||
}
|
||||
left = (MAXBITS+1) - len;
|
||||
if (left == 0) break;
|
||||
bitbuf = s->in[s->incnt++];
|
||||
if (left > 8) left = 8;
|
||||
}
|
||||
return -9; /* ran out of codes */
|
||||
}
|
||||
#endif /* SLOW */
|
||||
|
||||
|
||||
local int construct(struct huffman *h, short *length, int n)
|
||||
{
|
||||
int symbol; /* current symbol when stepping through length[] */
|
||||
int len; /* current length when stepping through h->count[] */
|
||||
int left; /* number of possible codes left of current length */
|
||||
short offs[MAXBITS+1]; /* offsets in symbol table for each length */
|
||||
|
||||
/* count number of codes of each length */
|
||||
for (len = 0; len <= MAXBITS; len++)
|
||||
h->count[len] = 0;
|
||||
for (symbol = 0; symbol < n; symbol++)
|
||||
(h->count[length[symbol]])++; /* assumes lengths are within bounds */
|
||||
if (h->count[0] == n) /* no codes! */
|
||||
return 0; /* complete, but decode() will fail */
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1; /* one possible code of zero length */
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1; /* one more bit, double codes left */
|
||||
left -= h->count[len]; /* deduct count from possible codes */
|
||||
if (left < 0) return left; /* over-subscribed--return negative */
|
||||
} /* left > 0 means incomplete */
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++)
|
||||
offs[len + 1] = offs[len] + h->count[len];
|
||||
|
||||
/*
|
||||
* put symbols in table sorted by length, by symbol order within each
|
||||
* length
|
||||
*/
|
||||
for (symbol = 0; symbol < n; symbol++)
|
||||
if (length[symbol] != 0)
|
||||
h->symbol[offs[length[symbol]]++] = symbol;
|
||||
|
||||
/* return zero for complete set, positive for incomplete set */
|
||||
return left;
|
||||
}
|
||||
|
||||
|
||||
local int codes(struct state *s,
|
||||
struct huffman *lencode,
|
||||
struct huffman *distcode)
|
||||
{
|
||||
int symbol; /* decoded symbol */
|
||||
int len; /* length for copy */
|
||||
unsigned dist; /* distance for copy */
|
||||
static const short lens[29] = { /* Size base for length codes 257..285 */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
|
||||
static const short lext[29] = { /* Extra bits for length codes 257..285 */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
|
||||
static const short dists[30] = { /* Offset base for distance codes 0..29 */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577};
|
||||
static const short dext[30] = { /* Extra bits for distance codes 0..29 */
|
||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||
12, 12, 13, 13};
|
||||
|
||||
/* decode literals and length/distance pairs */
|
||||
do {
|
||||
symbol = decode(s, lencode);
|
||||
if (symbol < 0) return symbol; /* invalid symbol */
|
||||
if (symbol < 256) { /* literal: symbol is the byte */
|
||||
/* write out the literal */
|
||||
if (s->out != NIL) {
|
||||
if (s->outcnt == s->outlen) return 1;
|
||||
s->out[s->outcnt] = symbol;
|
||||
}
|
||||
s->outcnt++;
|
||||
}
|
||||
else if (symbol > 256) { /* length */
|
||||
/* get and compute length */
|
||||
symbol -= 257;
|
||||
if (symbol >= 29) return -9; /* invalid fixed code */
|
||||
len = lens[symbol] + bits(s, lext[symbol]);
|
||||
|
||||
/* get and check distance */
|
||||
symbol = decode(s, distcode);
|
||||
if (symbol < 0) return symbol; /* invalid symbol */
|
||||
dist = dists[symbol] + bits(s, dext[symbol]);
|
||||
if (dist > s->outcnt)
|
||||
return -10; /* distance too far back */
|
||||
|
||||
/* copy length bytes from distance bytes back */
|
||||
if (s->out != NIL) {
|
||||
if (s->outcnt + len > s->outlen) return 1;
|
||||
while (len--) {
|
||||
s->out[s->outcnt] = s->out[s->outcnt - dist];
|
||||
s->outcnt++;
|
||||
}
|
||||
}
|
||||
else
|
||||
s->outcnt += len;
|
||||
}
|
||||
} while (symbol != 256); /* end of block symbol */
|
||||
|
||||
/* done with a valid fixed or dynamic block */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
local int fixed(struct state *s)
|
||||
{
|
||||
static int virgin = 1;
|
||||
static short lencnt[MAXBITS+1], lensym[FIXLCODES];
|
||||
static short distcnt[MAXBITS+1], distsym[MAXDCODES];
|
||||
static struct huffman lencode = {lencnt, lensym};
|
||||
static struct huffman distcode = {distcnt, distsym};
|
||||
|
||||
/* build fixed huffman tables if first call (may not be thread safe) */
|
||||
if (virgin) {
|
||||
int symbol;
|
||||
short lengths[FIXLCODES];
|
||||
|
||||
/* literal/length table */
|
||||
for (symbol = 0; symbol < 144; symbol++)
|
||||
lengths[symbol] = 8;
|
||||
for (; symbol < 256; symbol++)
|
||||
lengths[symbol] = 9;
|
||||
for (; symbol < 280; symbol++)
|
||||
lengths[symbol] = 7;
|
||||
for (; symbol < FIXLCODES; symbol++)
|
||||
lengths[symbol] = 8;
|
||||
construct(&lencode, lengths, FIXLCODES);
|
||||
|
||||
/* distance table */
|
||||
for (symbol = 0; symbol < MAXDCODES; symbol++)
|
||||
lengths[symbol] = 5;
|
||||
construct(&distcode, lengths, MAXDCODES);
|
||||
|
||||
/* do this just once */
|
||||
virgin = 0;
|
||||
}
|
||||
|
||||
/* decode data until end-of-block code */
|
||||
return codes(s, &lencode, &distcode);
|
||||
}
|
||||
|
||||
|
||||
local int dynamic(struct state *s)
|
||||
{
|
||||
int nlen, ndist, ncode; /* number of lengths in descriptor */
|
||||
int index; /* index of lengths[] */
|
||||
int err; /* construct() return value */
|
||||
short lengths[MAXCODES]; /* descriptor code lengths */
|
||||
short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
|
||||
short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
|
||||
struct huffman lencode = {lencnt, lensym}; /* length code */
|
||||
struct huffman distcode = {distcnt, distsym}; /* distance code */
|
||||
static const short order[19] = /* permutation of code length codes */
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
|
||||
|
||||
/* get number of lengths in each table, check lengths */
|
||||
nlen = bits(s, 5) + 257;
|
||||
ndist = bits(s, 5) + 1;
|
||||
ncode = bits(s, 4) + 4;
|
||||
if (nlen > MAXLCODES || ndist > MAXDCODES)
|
||||
return -3; /* bad counts */
|
||||
|
||||
/* read code length code lengths (really), missing lengths are zero */
|
||||
for (index = 0; index < ncode; index++)
|
||||
lengths[order[index]] = bits(s, 3);
|
||||
for (; index < 19; index++)
|
||||
lengths[order[index]] = 0;
|
||||
|
||||
/* build huffman table for code lengths codes (use lencode temporarily) */
|
||||
err = construct(&lencode, lengths, 19);
|
||||
if (err != 0) return -4; /* require complete code set here */
|
||||
|
||||
/* read length/literal and distance code length tables */
|
||||
index = 0;
|
||||
while (index < nlen + ndist) {
|
||||
int symbol; /* decoded value */
|
||||
int len; /* last length to repeat */
|
||||
|
||||
symbol = decode(s, &lencode);
|
||||
if (symbol < 16) /* length in 0..15 */
|
||||
lengths[index++] = symbol;
|
||||
else { /* repeat instruction */
|
||||
len = 0; /* assume repeating zeros */
|
||||
if (symbol == 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);
|
||||
}
|
||||
else if (symbol == 17) /* repeat zero 3..10 times */
|
||||
symbol = 3 + bits(s, 3);
|
||||
else /* == 18, repeat zero 11..138 times */
|
||||
symbol = 11 + bits(s, 7);
|
||||
if (index + symbol > nlen + ndist)
|
||||
return -6; /* too many lengths! */
|
||||
while (symbol--) /* repeat last or zero symbol times */
|
||||
lengths[index++] = len;
|
||||
}
|
||||
}
|
||||
|
||||
/* build huffman table for literal/length codes */
|
||||
err = construct(&lencode, lengths, nlen);
|
||||
if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
|
||||
return -7; /* only allow incomplete codes if just one code */
|
||||
|
||||
/* build huffman table for distance codes */
|
||||
err = construct(&distcode, lengths + nlen, ndist);
|
||||
if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1))
|
||||
return -8; /* only allow incomplete codes if just one code */
|
||||
|
||||
/* decode data until end-of-block code */
|
||||
return codes(s, &lencode, &distcode);
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
{
|
||||
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.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 */
|
||||
err = type == 0 ? stored(&s) :
|
||||
(type == 1 ? fixed(&s) :
|
||||
(type == 2 ? dynamic(&s) :
|
||||
-1)); /* type == 3, invalid */
|
||||
if (err != 0) break; /* return with error */
|
||||
} while (!last);
|
||||
|
||||
return err;
|
||||
}
|
641
src/Boot/Windows/IntFilter.cpp
Normal file
641
src/Boot/Windows/IntFilter.cpp
Normal file
@ -0,0 +1,641 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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;
|
||||
}
|
16
src/Boot/Windows/IntFilter.h
Normal file
16
src/Boot/Windows/IntFilter.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
184
src/Boot/Windows/Makefile
Normal file
184
src/Boot/Windows/Makefile
Normal file
@ -0,0 +1,184 @@
|
||||
#
|
||||
# Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
#
|
||||
# Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
# the file License.txt included in TrueCrypt 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
|
||||
|
||||
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
|
||||
|
||||
OBJS = $(OBJS) $(OUTDIR)\Rmd160.obj
|
||||
|
||||
!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
|
||||
|
||||
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 ..
|
226
src/Boot/Windows/Platform.cpp
Normal file
226
src/Boot/Windows/Platform.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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);
|
||||
}
|
112
src/Boot/Windows/Platform.h
Normal file
112
src/Boot/Windows/Platform.h
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt 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
|
317
src/Common/Apidrvr.h
Normal file
317
src/Common/Apidrvr.h
Normal file
@ -0,0 +1,317 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Boot/Windows/BootDefs.h"
|
||||
#include "Common.h"
|
||||
#include "Crypto.h"
|
||||
#include "Volumes.h"
|
||||
#include "Wipe.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* WARNING: Modifying the following values or their meanings can introduce incompatibility with previous versions. */
|
||||
|
||||
#define TC_IOCTL(CODE) (CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800 + (CODE), METHOD_BUFFERED, FILE_ANY_ACCESS))
|
||||
|
||||
#define TC_IOCTL_GET_DRIVER_VERSION TC_IOCTL (1)
|
||||
#define TC_IOCTL_GET_BOOT_LOADER_VERSION TC_IOCTL (2)
|
||||
#define TC_IOCTL_MOUNT_VOLUME TC_IOCTL (3)
|
||||
#define TC_IOCTL_DISMOUNT_VOLUME TC_IOCTL (4)
|
||||
#define TC_IOCTL_DISMOUNT_ALL_VOLUMES TC_IOCTL (5)
|
||||
#define TC_IOCTL_GET_MOUNTED_VOLUMES TC_IOCTL (6)
|
||||
#define TC_IOCTL_GET_VOLUME_PROPERTIES TC_IOCTL (7)
|
||||
#define TC_IOCTL_GET_DEVICE_REFCOUNT TC_IOCTL (8)
|
||||
#define TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED TC_IOCTL (9)
|
||||
#define TC_IOCTL_IS_ANY_VOLUME_MOUNTED TC_IOCTL (10)
|
||||
#define TC_IOCTL_GET_PASSWORD_CACHE_STATUS TC_IOCTL (11)
|
||||
#define TC_IOCTL_WIPE_PASSWORD_CACHE TC_IOCTL (12)
|
||||
#define TC_IOCTL_OPEN_TEST TC_IOCTL (13)
|
||||
#define TC_IOCTL_GET_DRIVE_PARTITION_INFO TC_IOCTL (14)
|
||||
#define TC_IOCTL_GET_DRIVE_GEOMETRY TC_IOCTL (15)
|
||||
#define TC_IOCTL_PROBE_REAL_DRIVE_SIZE TC_IOCTL (16)
|
||||
#define TC_IOCTL_GET_RESOLVED_SYMLINK TC_IOCTL (17)
|
||||
#define TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS TC_IOCTL (18)
|
||||
#define TC_IOCTL_BOOT_ENCRYPTION_SETUP TC_IOCTL (19)
|
||||
#define TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP TC_IOCTL (20)
|
||||
#define TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT TC_IOCTL (21)
|
||||
#define TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES TC_IOCTL (22)
|
||||
#define TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER TC_IOCTL (23)
|
||||
#define TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME TC_IOCTL (24)
|
||||
#define TC_IOCTL_GET_PORTABLE_MODE_STATUS TC_IOCTL (25)
|
||||
#define TC_IOCTL_SET_PORTABLE_MODE_STATUS TC_IOCTL (26)
|
||||
#define TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING TC_IOCTL (27)
|
||||
#define TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG TC_IOCTL (28)
|
||||
#define TC_IOCTL_DISK_IS_WRITABLE TC_IOCTL (29)
|
||||
#define TC_IOCTL_START_DECOY_SYSTEM_WIPE TC_IOCTL (30)
|
||||
#define TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE TC_IOCTL (31)
|
||||
#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS TC_IOCTL (32)
|
||||
#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT TC_IOCTL (33)
|
||||
#define TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR TC_IOCTL (34)
|
||||
#define TC_IOCTL_GET_WARNING_FLAGS TC_IOCTL (35)
|
||||
#define TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY TC_IOCTL (36)
|
||||
#define TC_IOCTL_REREAD_DRIVER_CONFIG TC_IOCTL (37)
|
||||
#define TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG TC_IOCTL (38)
|
||||
|
||||
// Legacy IOCTLs used before version 5.0
|
||||
#define TC_IOCTL_LEGACY_GET_DRIVER_VERSION 466968
|
||||
#define TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES 466948
|
||||
|
||||
|
||||
/* Start of driver interface structures, the size of these structures may
|
||||
change between versions; so make sure you first send DRIVER_VERSION to
|
||||
check that it's the correct device driver */
|
||||
|
||||
#pragma pack (push)
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nReturnCode; /* Return code back from driver */
|
||||
BOOL FilesystemDirty;
|
||||
BOOL VolumeMountedReadOnlyAfterAccessDenied;
|
||||
BOOL VolumeMountedReadOnlyAfterDeviceWriteProtected;
|
||||
|
||||
wchar_t wszVolume[TC_MAX_PATH]; /* Volume to be mounted */
|
||||
Password VolumePassword; /* User password */
|
||||
BOOL bCache; /* Cache passwords in driver */
|
||||
int nDosDriveNo; /* Drive number to mount */
|
||||
uint32 BytesPerSector;
|
||||
BOOL bMountReadOnly; /* Mount volume in read-only mode */
|
||||
BOOL bMountRemovable; /* Mount volume as removable media */
|
||||
BOOL bExclusiveAccess; /* Open host file/device in exclusive access mode */
|
||||
BOOL bMountManager; /* Announce volume to mount manager */
|
||||
BOOL bPreserveTimestamp; /* Preserve file container timestamp */
|
||||
BOOL bPartitionInInactiveSysEncScope; /* If TRUE, we are to attempt to mount a partition located on an encrypted system drive without pre-boot authentication. */
|
||||
int nPartitionInInactiveSysEncScopeDriveNo; /* If bPartitionInInactiveSysEncScope is TRUE, this contains the drive number of the system drive on which the partition is located. */
|
||||
BOOL SystemFavorite;
|
||||
// Hidden volume protection
|
||||
BOOL bProtectHiddenVolume; /* TRUE if the user wants the hidden volume within this volume to be protected against being overwritten (damaged) */
|
||||
Password ProtectedHidVolPassword; /* Password to the hidden volume to be protected against overwriting */
|
||||
BOOL UseBackupHeader;
|
||||
BOOL RecoveryMode;
|
||||
} MOUNT_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nDosDriveNo; /* Drive letter to unmount */
|
||||
BOOL ignoreOpenFiles;
|
||||
BOOL HiddenVolumeProtectionTriggered;
|
||||
int nReturnCode; /* Return code back from driver */
|
||||
} UNMOUNT_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned __int32 ulMountedDrives; /* Bitfield of all mounted drive letters */
|
||||
wchar_t wszVolume[26][TC_MAX_PATH]; /* Volume names of mounted volumes */
|
||||
unsigned __int64 diskLength[26];
|
||||
int ea[26];
|
||||
int volumeType[26]; /* Volume type (e.g. PROP_VOL_TYPE_OUTER, PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, etc.) */
|
||||
} MOUNT_LIST_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int driveNo;
|
||||
int uniqueId;
|
||||
wchar_t wszVolume[TC_MAX_PATH];
|
||||
unsigned __int64 diskLength;
|
||||
int ea;
|
||||
int mode;
|
||||
int pkcs5;
|
||||
int pkcs5Iterations;
|
||||
BOOL hiddenVolume;
|
||||
BOOL readOnly;
|
||||
BOOL removable;
|
||||
BOOL partitionInInactiveSysEncScope;
|
||||
#if 0
|
||||
unsigned __int64 volumeCreationTime; // Deprecated in v6.0
|
||||
unsigned __int64 headerCreationTime; // Deprecated in v6.0
|
||||
#endif
|
||||
uint32 volumeHeaderFlags;
|
||||
unsigned __int64 totalBytesRead;
|
||||
unsigned __int64 totalBytesWritten;
|
||||
int hiddenVolProtection; /* Hidden volume protection status (e.g. HIDVOL_PROT_STATUS_NONE, HIDVOL_PROT_STATUS_ACTIVE, etc.) */
|
||||
int volFormatVersion;
|
||||
} VOLUME_PROPERTIES_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR symLinkName[TC_MAX_PATH];
|
||||
WCHAR targetName[TC_MAX_PATH];
|
||||
} RESOLVE_SYMLINK_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR deviceName[TC_MAX_PATH];
|
||||
PARTITION_INFORMATION partInfo;
|
||||
BOOL IsGPT;
|
||||
BOOL IsDynamic;
|
||||
}
|
||||
DISK_PARTITION_INFO_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR deviceName[TC_MAX_PATH];
|
||||
DISK_GEOMETRY diskGeometry;
|
||||
}
|
||||
DISK_GEOMETRY_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR DeviceName[TC_MAX_PATH];
|
||||
LARGE_INTEGER RealDriveSize;
|
||||
BOOL TimeOut;
|
||||
} ProbeRealDriveSizeRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wchar_t wszFileName[TC_MAX_PATH]; // Volume to be "open tested"
|
||||
BOOL bDetectTCBootLoader; // Whether the driver is to determine if the first sector contains a portion of the TrueCrypt Boot Loader
|
||||
BOOL TCBootLoaderDetected;
|
||||
BOOL DetectFilesystem;
|
||||
BOOL FilesystemDetected;
|
||||
} OPEN_TEST_STRUCT;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SetupNone = 0,
|
||||
SetupEncryption,
|
||||
SetupDecryption
|
||||
} BootEncryptionSetupMode;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// New fields must be added at the end of the structure to maintain compatibility with previous versions
|
||||
BOOL DeviceFilterActive;
|
||||
|
||||
uint16 BootLoaderVersion;
|
||||
|
||||
BOOL DriveMounted;
|
||||
BOOL VolumeHeaderPresent;
|
||||
BOOL DriveEncrypted;
|
||||
|
||||
LARGE_INTEGER BootDriveLength;
|
||||
|
||||
int64 ConfiguredEncryptedAreaStart;
|
||||
int64 ConfiguredEncryptedAreaEnd;
|
||||
int64 EncryptedAreaStart;
|
||||
int64 EncryptedAreaEnd;
|
||||
|
||||
uint32 VolumeHeaderSaltCrc32;
|
||||
|
||||
BOOL SetupInProgress;
|
||||
BootEncryptionSetupMode SetupMode;
|
||||
BOOL TransformWaitingForIdle;
|
||||
|
||||
uint32 HibernationPreventionCount;
|
||||
|
||||
BOOL HiddenSystem;
|
||||
int64 HiddenSystemPartitionStart;
|
||||
|
||||
// Number of times the filter driver answered that an unencrypted volume
|
||||
// is read-only (or mounted an outer/normal TrueCrypt volume as read only)
|
||||
uint32 HiddenSysLeakProtectionCount;
|
||||
|
||||
} BootEncryptionStatus;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BootEncryptionSetupMode SetupMode;
|
||||
WipeAlgorithmId WipeAlgorithm;
|
||||
BOOL ZeroUnreadableSectors;
|
||||
BOOL DiscardUnreadableEncryptedSectors;
|
||||
} BootEncryptionSetupRequest;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Password VolumePassword;
|
||||
} ReopenBootVolumeHeaderRequest;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char BootEncryptionAlgorithmName[256];
|
||||
} GetBootEncryptionAlgorithmNameRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wchar_t DevicePath[TC_MAX_PATH];
|
||||
byte Configuration;
|
||||
BOOL DriveIsDynamic;
|
||||
uint16 BootLoaderVersion;
|
||||
byte UserConfiguration;
|
||||
char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
|
||||
} GetSystemDriveConfigurationRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WipeAlgorithmId WipeAlgorithm;
|
||||
byte WipeKey[MASTER_KEYDATA_SIZE];
|
||||
} WipeDecoySystemRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL WipeInProgress;
|
||||
WipeAlgorithmId WipeAlgorithm;
|
||||
int64 WipedAreaEnd;
|
||||
} DecoySystemWipeStatus;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LARGE_INTEGER Offset;
|
||||
byte Data[TC_SECTOR_SIZE_BIOS];
|
||||
} WriteBootDriveSectorRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL PagingFileCreationPrevented;
|
||||
BOOL SystemFavoriteVolumeDirty;
|
||||
} GetWarningFlagsRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct _DriveFilterExtension *BootDriveFilterExtension;
|
||||
BOOL HwEncryptionEnabled;
|
||||
} GetSystemDriveDumpConfigRequest;
|
||||
|
||||
#pragma pack (pop)
|
||||
|
||||
#ifdef TC_WINDOWS_DRIVER
|
||||
#define DRIVER_STR WIDE
|
||||
#else
|
||||
#define DRIVER_STR
|
||||
#endif
|
||||
|
||||
#define TC_UNIQUE_ID_PREFIX "TrueCryptVolume"
|
||||
#define TC_MOUNT_PREFIX L"\\Device\\TrueCryptVolume"
|
||||
|
||||
#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\TrueCryptVolume")
|
||||
#define NT_ROOT_PREFIX DRIVER_STR("\\Device\\TrueCrypt")
|
||||
#define DOS_MOUNT_PREFIX DRIVER_STR("\\DosDevices\\")
|
||||
#define DOS_ROOT_PREFIX DRIVER_STR("\\DosDevices\\TrueCrypt")
|
||||
#define WIN32_ROOT_PREFIX DRIVER_STR("\\\\.\\TrueCrypt")
|
||||
|
||||
#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("TrueCryptConfig")
|
||||
#define TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME DRIVER_STR("TrueCryptEncryptionFreeCpuCount")
|
||||
|
||||
// WARNING: Modifying the following values can introduce incompatibility with previous versions.
|
||||
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
|
||||
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
|
||||
#define TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS 0x4
|
||||
#define TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION 0x8
|
||||
|
||||
#endif /* _WIN32 */
|
231
src/Common/BaseCom.cpp
Normal file
231
src/Common/BaseCom.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <atlcomcli.h>
|
||||
#include <atlconv.h>
|
||||
#include <comutil.h>
|
||||
#include <windows.h>
|
||||
#include "BaseCom.h"
|
||||
#include "BootEncryption.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Registry.h"
|
||||
|
||||
using namespace TrueCrypt;
|
||||
|
||||
HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv)
|
||||
{
|
||||
WCHAR monikerName[1024];
|
||||
WCHAR clsid[1024];
|
||||
BIND_OPTS3 bo;
|
||||
|
||||
StringFromGUID2 (guid, clsid, sizeof (clsid) / 2);
|
||||
swprintf_s (monikerName, sizeof (monikerName) / 2, L"Elevation:Administrator!new:%s", clsid);
|
||||
|
||||
memset (&bo, 0, sizeof (bo));
|
||||
bo.cbStruct = sizeof (bo);
|
||||
bo.hwnd = hwnd;
|
||||
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
|
||||
|
||||
// Prevent the GUI from being half-rendered when the UAC prompt "freezes" it
|
||||
ProcessPaintMessages (hwnd, 5000);
|
||||
|
||||
return CoGetObject (monikerName, &bo, iid, ppv);
|
||||
}
|
||||
|
||||
|
||||
BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer)
|
||||
{
|
||||
BOOL r;
|
||||
|
||||
if (IsUacSupported ())
|
||||
r = CreateElevatedComObject (hWnd, clsid, iid, tcServer) == S_OK;
|
||||
else
|
||||
r = CoCreateInstance (clsid, NULL, CLSCTX_LOCAL_SERVER, iid, tcServer) == S_OK;
|
||||
|
||||
if (!r)
|
||||
Error ("UAC_INIT_ERROR");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::CallDriver (DWORD ioctl, BSTR input, BSTR *output)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.CallDriver (ioctl,
|
||||
(BYTE *) input, !(BYTE *) input ? 0 : ((DWORD *) ((BYTE *) input))[-1],
|
||||
(BYTE *) *output, !(BYTE *) *output ? 0 : ((DWORD *) ((BYTE *) *output))[-1]);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::CopyFile (BSTR sourceFile, BSTR destinationFile)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
if (!::CopyFile (CW2A (sourceFile), CW2A (destinationFile), FALSE))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::DeleteFile (BSTR file)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
if (!::DeleteFile (CW2A (file)))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
BOOL BaseCom::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
|
||||
{
|
||||
return ::IsPagingFileActive (checkNonWindowsPartitionsOnly);
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
try
|
||||
{
|
||||
auto_ptr <File> file (device ? new Device (string (CW2A (filePath)), !write) : new File (string (CW2A (filePath)), !write));
|
||||
file->SeekAt (offset);
|
||||
|
||||
if (write)
|
||||
{
|
||||
file->Write ((BYTE *) *bufferBstr, size);
|
||||
*sizeDone = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
*sizeDone = file->Read ((BYTE *) *bufferBstr, size);
|
||||
}
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::RegisterFilterDriver (BOOL registerDriver, int filterType)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.RegisterFilterDriver (registerDriver ? true : false, (BootEncryption::FilterType) filterType);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::RegisterSystemFavoritesService (BOOL registerService)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.RegisterSystemFavoritesService (registerService);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::SetDriverServiceStartType (DWORD startType)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.SetDriverServiceStartType (startType);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
if (!::WriteLocalMachineRegistryDword (CW2A (keyPath), CW2A (valueName), value))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
115
src/Common/BaseCom.h
Normal file
115
src/Common/BaseCom.h
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_BASE_COM
|
||||
#define TC_HEADER_BASE_COM
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
template <class TClass>
|
||||
class TrueCryptFactory : public IClassFactory
|
||||
{
|
||||
|
||||
public:
|
||||
TrueCryptFactory (DWORD messageThreadId) :
|
||||
RefCount (1), ServerLockCount (0), MessageThreadId (messageThreadId) { }
|
||||
|
||||
~TrueCryptFactory () { }
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef ()
|
||||
{
|
||||
return InterlockedIncrement (&RefCount) - 1;
|
||||
}
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE Release ()
|
||||
{
|
||||
ULONG r = InterlockedDecrement (&RefCount) + 1;
|
||||
|
||||
if (r == 0)
|
||||
delete this;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **ppvObject)
|
||||
{
|
||||
if (riid == IID_IUnknown || riid == IID_IClassFactory)
|
||||
*ppvObject = this;
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef ();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateInstance (IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
|
||||
{
|
||||
if (pUnkOuter != NULL)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
TClass *tc = new TClass (MessageThreadId);
|
||||
if (tc == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
HRESULT hr = tc->QueryInterface (riid, ppvObject);
|
||||
|
||||
if (hr)
|
||||
delete tc;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE LockServer (BOOL fLock)
|
||||
{
|
||||
if (fLock)
|
||||
{
|
||||
InterlockedIncrement (&ServerLockCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!InterlockedDecrement (&ServerLockCount))
|
||||
PostThreadMessage (MessageThreadId, WM_APP, 0, 0);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual bool IsServerLocked ()
|
||||
{
|
||||
return ServerLockCount > 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
DWORD MessageThreadId;
|
||||
LONG RefCount;
|
||||
LONG ServerLockCount;
|
||||
};
|
||||
|
||||
|
||||
class BaseCom
|
||||
{
|
||||
public:
|
||||
static DWORD CallDriver (DWORD ioctl, BSTR input, BSTR *output);
|
||||
static DWORD CopyFile (BSTR sourceFile, BSTR destinationFile);
|
||||
static DWORD DeleteFile (BSTR file);
|
||||
static BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
|
||||
static DWORD ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone);
|
||||
static DWORD RegisterFilterDriver (BOOL registerDriver, int filterType);
|
||||
static DWORD RegisterSystemFavoritesService (BOOL registerService);
|
||||
static DWORD SetDriverServiceStartType (DWORD startType);
|
||||
static DWORD WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value);
|
||||
};
|
||||
|
||||
|
||||
BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer);
|
||||
HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv);
|
||||
|
||||
#endif // TC_HEADER_BASE_COM
|
2457
src/Common/BootEncryption.cpp
Normal file
2457
src/Common/BootEncryption.cpp
Normal file
File diff suppressed because it is too large
Load Diff
241
src/Common/BootEncryption.h
Normal file
241
src/Common/BootEncryption.h
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_BootEncryption
|
||||
#define TC_HEADER_Common_BootEncryption
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Exception.h"
|
||||
#include "Platform/PlatformBase.h"
|
||||
#include "Volumes.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class File
|
||||
{
|
||||
public:
|
||||
File () : FileOpen (false) { }
|
||||
File (string path, bool readOnly = false, bool create = false);
|
||||
~File () { Close(); }
|
||||
|
||||
void Close ();
|
||||
DWORD Read (byte *buffer, DWORD size);
|
||||
void Write (byte *buffer, DWORD size);
|
||||
void SeekAt (int64 position);
|
||||
|
||||
protected:
|
||||
bool Elevated;
|
||||
bool FileOpen;
|
||||
uint64 FilePointerPosition;
|
||||
HANDLE Handle;
|
||||
bool IsDevice;
|
||||
string Path;
|
||||
};
|
||||
|
||||
|
||||
class Device : public File
|
||||
{
|
||||
public:
|
||||
Device (string path, bool readOnly = false);
|
||||
};
|
||||
|
||||
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
Buffer (size_t size) : DataSize (size)
|
||||
{
|
||||
DataPtr = new byte[size];
|
||||
if (!DataPtr)
|
||||
throw bad_alloc();
|
||||
}
|
||||
|
||||
~Buffer () { delete[] DataPtr; }
|
||||
byte *Ptr () const { return DataPtr; }
|
||||
size_t Size () const { return DataSize; }
|
||||
|
||||
protected:
|
||||
byte *DataPtr;
|
||||
size_t DataSize;
|
||||
};
|
||||
|
||||
|
||||
struct Partition
|
||||
{
|
||||
string DevicePath;
|
||||
PARTITION_INFORMATION Info;
|
||||
string MountPoint;
|
||||
size_t Number;
|
||||
BOOL IsGPT;
|
||||
wstring VolumeNameId;
|
||||
};
|
||||
|
||||
typedef list <Partition> PartitionList;
|
||||
|
||||
#pragma pack (push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct PartitionEntryMBR
|
||||
{
|
||||
byte BootIndicator;
|
||||
|
||||
byte StartHead;
|
||||
byte StartCylSector;
|
||||
byte StartCylinder;
|
||||
|
||||
byte Type;
|
||||
|
||||
byte EndHead;
|
||||
byte EndSector;
|
||||
byte EndCylinder;
|
||||
|
||||
uint32 StartLBA;
|
||||
uint32 SectorCountLBA;
|
||||
};
|
||||
|
||||
struct MBR
|
||||
{
|
||||
byte Code[446];
|
||||
PartitionEntryMBR Partitions[4];
|
||||
uint16 Signature;
|
||||
};
|
||||
|
||||
#pragma pack (pop)
|
||||
|
||||
struct SystemDriveConfiguration
|
||||
{
|
||||
string DeviceKernelPath;
|
||||
string DevicePath;
|
||||
int DriveNumber;
|
||||
Partition DrivePartition;
|
||||
bool ExtraBootPartitionPresent;
|
||||
int64 InitialUnallocatedSpace;
|
||||
PartitionList Partitions;
|
||||
Partition SystemPartition;
|
||||
int64 TotalUnallocatedSpace;
|
||||
bool SystemLoaderPresent;
|
||||
};
|
||||
|
||||
class BootEncryption
|
||||
{
|
||||
public:
|
||||
BootEncryption (HWND parent);
|
||||
~BootEncryption ();
|
||||
|
||||
enum FilterType
|
||||
{
|
||||
DriveFilter,
|
||||
VolumeFilter,
|
||||
DumpFilter
|
||||
};
|
||||
|
||||
void AbortDecoyOSWipe ();
|
||||
void AbortSetup ();
|
||||
void AbortSetupWait ();
|
||||
void CallDriver (DWORD ioctl, void *input = nullptr, DWORD inputSize = 0, void *output = nullptr, DWORD outputSize = 0);
|
||||
int ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5);
|
||||
void CheckDecoyOSWipeResult ();
|
||||
void CheckEncryptionSetupResult ();
|
||||
void CheckRequirements ();
|
||||
void CheckRequirementsHiddenOS ();
|
||||
void CopyFileAdmin (const string &sourceFile, const string &destinationFile);
|
||||
void CreateRescueIsoImage (bool initialSetup, const string &isoImagePath);
|
||||
void Deinstall (bool displayWaitDialog = false);
|
||||
void DeleteFileAdmin (const string &file);
|
||||
DecoySystemWipeStatus GetDecoyOSWipeStatus ();
|
||||
DWORD GetDriverServiceStartType ();
|
||||
unsigned int GetHiddenOSCreationPhase ();
|
||||
uint16 GetInstalledBootLoaderVersion ();
|
||||
Partition GetPartitionForHiddenOS ();
|
||||
bool IsBootLoaderOnDrive (char *devicePath);
|
||||
BootEncryptionStatus GetStatus ();
|
||||
string GetTempPath ();
|
||||
void GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties);
|
||||
SystemDriveConfiguration GetSystemDriveConfiguration ();
|
||||
void Install (bool hiddenSystem);
|
||||
void InstallBootLoader (bool preserveUserConfig = false, bool hiddenOSCreation = false);
|
||||
void InvalidateCachedSysDriveProperties ();
|
||||
bool IsCDDrivePresent ();
|
||||
bool IsHiddenSystemRunning ();
|
||||
bool IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
|
||||
void PrepareHiddenOSCreation (int ea, int mode, int pkcs5);
|
||||
void PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath);
|
||||
void ProbeRealSystemDriveSize ();
|
||||
void ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig = nullptr, string *customUserMessage = nullptr, uint16 *bootLoaderVersion = nullptr);
|
||||
uint32 ReadDriverConfigurationFlags ();
|
||||
void RegisterBootDriver (bool hiddenSystem);
|
||||
void RegisterFilterDriver (bool registerDriver, FilterType filterType);
|
||||
void RegisterSystemFavoritesService (BOOL registerService);
|
||||
void RenameDeprecatedSystemLoaderBackup ();
|
||||
bool RestartComputer (void);
|
||||
void InitialSecurityChecksForHiddenOS ();
|
||||
void RestrictPagingFilesToSystemPartition ();
|
||||
void SetDriverConfigurationFlag (uint32 flag, bool state);
|
||||
void SetDriverServiceStartType (DWORD startType);
|
||||
void SetHiddenOSCreationPhase (unsigned int newPhase);
|
||||
void StartDecryption (BOOL discardUnreadableEncryptedSectors);
|
||||
void StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm);
|
||||
void StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors);
|
||||
bool SystemDriveContainsPartitionType (byte type);
|
||||
bool SystemDriveContainsExtendedPartition ();
|
||||
bool SystemDriveContainsNonStandardPartitions ();
|
||||
bool SystemPartitionCoversWholeDrive ();
|
||||
bool SystemDriveIsDynamic ();
|
||||
bool VerifyRescueDisk ();
|
||||
void WipeHiddenOSCreationConfig ();
|
||||
void WriteBootDriveSector (uint64 offset, byte *data);
|
||||
void WriteBootSectorConfig (const byte newConfig[]);
|
||||
void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage);
|
||||
void WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value);
|
||||
|
||||
protected:
|
||||
static const uint32 RescueIsoImageSize = 1835008; // Size of ISO9660 image with bootable emulated 1.44MB floppy disk image
|
||||
|
||||
void BackupSystemLoader ();
|
||||
void CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation = false);
|
||||
void CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5);
|
||||
string GetSystemLoaderBackupPath ();
|
||||
uint32 GetChecksum (byte *data, size_t size);
|
||||
DISK_GEOMETRY GetDriveGeometry (int driveNumber);
|
||||
PartitionList GetDrivePartitions (int driveNumber);
|
||||
wstring GetRemarksOnHiddenOS ();
|
||||
string GetWindowsDirectory ();
|
||||
void RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid = nullptr);
|
||||
void RestoreSystemLoader ();
|
||||
void InstallVolumeHeader ();
|
||||
|
||||
HWND ParentWindow;
|
||||
SystemDriveConfiguration DriveConfig;
|
||||
int SelectedEncryptionAlgorithmId;
|
||||
Partition HiddenOSCandidatePartition;
|
||||
byte *RescueIsoImage;
|
||||
byte RescueVolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
|
||||
byte VolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
|
||||
bool DriveConfigValid;
|
||||
bool RealSystemDriveSizeValid;
|
||||
bool RescueVolumeHeaderValid;
|
||||
bool VolumeHeaderValid;
|
||||
};
|
||||
}
|
||||
|
||||
#define TC_ABORT_TRANSFORM_WAIT_INTERVAL 10
|
||||
|
||||
#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS 2.1
|
||||
#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT 1.05
|
||||
|
||||
#define TC_SYS_BOOT_LOADER_BACKUP_NAME "Original System Loader"
|
||||
#define TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY "Original System Loader.bak" // Deprecated to prevent removal by some "cleaners"
|
||||
|
||||
#define TC_SYSTEM_FAVORITES_SERVICE_NAME TC_APP_NAME "SystemFavorites"
|
||||
#define TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP "Event Log"
|
||||
#define TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION "/systemFavoritesService"
|
||||
|
||||
#endif // TC_HEADER_Common_BootEncryption
|
94
src/Common/Cache.c
Normal file
94
src/Common/Cache.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crypto.h"
|
||||
#include "Fat.h"
|
||||
#include "Volumes.h"
|
||||
#include "Apidrvr.h"
|
||||
#include "Common.h"
|
||||
#include "Cache.h"
|
||||
|
||||
Password CachedPasswords[CACHE_SIZE];
|
||||
int cacheEmpty = 1;
|
||||
static int nPasswordIdx = 0;
|
||||
|
||||
int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, PCRYPTO_INFO *retInfo)
|
||||
{
|
||||
int nReturnCode = ERR_PASSWORD_WRONG;
|
||||
int i;
|
||||
|
||||
/* Attempt to recognize volume using mount password */
|
||||
if (password->Length > 0)
|
||||
{
|
||||
nReturnCode = ReadVolumeHeader (bBoot, header, password, retInfo, NULL);
|
||||
|
||||
/* Save mount passwords back into cache if asked to do so */
|
||||
if (bCache && (nReturnCode == 0 || nReturnCode == ERR_CIPHER_INIT_WEAK_KEY))
|
||||
{
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == CACHE_SIZE)
|
||||
{
|
||||
/* Store the password */
|
||||
CachedPasswords[nPasswordIdx] = *password;
|
||||
|
||||
/* Try another slot */
|
||||
nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE;
|
||||
|
||||
cacheEmpty = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!cacheEmpty)
|
||||
{
|
||||
/* Attempt to recognize volume using cached passwords */
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
if (CachedPasswords[i].Length > 0)
|
||||
{
|
||||
nReturnCode = ReadVolumeHeader (bBoot, header, &CachedPasswords[i], retInfo, NULL);
|
||||
|
||||
if (nReturnCode != ERR_PASSWORD_WRONG)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nReturnCode;
|
||||
}
|
||||
|
||||
|
||||
void AddPasswordToCache (Password *password)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
CachedPasswords[nPasswordIdx] = *password;
|
||||
nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE;
|
||||
cacheEmpty = 0;
|
||||
}
|
||||
|
||||
|
||||
void WipeCache ()
|
||||
{
|
||||
burn (CachedPasswords, sizeof (CachedPasswords));
|
||||
nPasswordIdx = 0;
|
||||
cacheEmpty = 1;
|
||||
}
|
23
src/Common/Cache.h
Normal file
23
src/Common/Cache.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#ifndef CACHE_SIZE
|
||||
/* WARNING: Changing this value might not be safe (some items may be hard coded for 4)! Inspection necessary. */
|
||||
#define CACHE_SIZE 4
|
||||
#endif
|
||||
|
||||
extern int cacheEmpty;
|
||||
|
||||
void AddPasswordToCache (Password *password);
|
||||
int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, PCRYPTO_INFO *retInfo);
|
||||
void WipeCache (void);
|
240
src/Common/Cmdline.c
Normal file
240
src/Common/Cmdline.c
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <ctype.h>
|
||||
#include "Cmdline.h"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Crypto.h"
|
||||
#include "Apidrvr.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Language.h"
|
||||
|
||||
/* Except in response to the WM_INITDIALOG message, the dialog box procedure
|
||||
should return nonzero if it processes the message, and zero if it does
|
||||
not. - see DialogProc */
|
||||
BOOL CALLBACK CommandHelpDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (lParam); /* remove warning */
|
||||
if (wParam); /* remove warning */
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
char * tmp = err_malloc(8192);
|
||||
char tmp2[MAX_PATH * 2];
|
||||
argumentspec *as;
|
||||
int i;
|
||||
|
||||
LocalizeDialog (hwndDlg, "IDD_COMMANDHELP_DLG");
|
||||
|
||||
as = (argumentspec*) lParam;
|
||||
|
||||
*tmp = 0;
|
||||
|
||||
strcpy (tmp, "Command line options:\n\n");
|
||||
for (i = 0; i < as->arg_cnt; i ++)
|
||||
{
|
||||
if (!as->args[i].Internal)
|
||||
{
|
||||
sprintf(tmp2, "%s\t%s\n", as->args[i].short_name, as->args[i].long_name);
|
||||
strcat(tmp,tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
SetWindowText (GetDlgItem (hwndDlg, IDC_COMMANDHELP_TEXT), (char*) tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
return 1;
|
||||
case WM_CLOSE:
|
||||
EndDialog (hwndDlg, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Win32CommandLine (char *lpszCommandLine, char ***lpszArgs)
|
||||
{
|
||||
int argumentCount;
|
||||
int i;
|
||||
|
||||
LPWSTR *arguments = CommandLineToArgvW (GetCommandLineW(), &argumentCount);
|
||||
if (!arguments)
|
||||
{
|
||||
handleWin32Error (NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--argumentCount;
|
||||
if (argumentCount < 1)
|
||||
{
|
||||
LocalFree (arguments);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*lpszArgs = malloc (sizeof (char *) * argumentCount);
|
||||
if (!*lpszArgs)
|
||||
AbortProcess ("OUTOFMEMORY");
|
||||
|
||||
for (i = 0; i < argumentCount; ++i)
|
||||
{
|
||||
size_t argLen = wcslen (arguments[i + 1]);
|
||||
|
||||
char *arg = malloc (argLen + 1);
|
||||
if (!arg)
|
||||
AbortProcess ("OUTOFMEMORY");
|
||||
|
||||
if (argLen > 0)
|
||||
{
|
||||
int len = WideCharToMultiByte (CP_ACP, 0, arguments[i + 1], -1, arg, argLen + 1, NULL, NULL);
|
||||
if (len == 0)
|
||||
{
|
||||
handleWin32Error (NULL);
|
||||
AbortProcessSilent();
|
||||
}
|
||||
}
|
||||
else
|
||||
arg[0] = 0;
|
||||
|
||||
(*lpszArgs)[i] = arg;
|
||||
}
|
||||
|
||||
LocalFree (arguments);
|
||||
return argumentCount;
|
||||
}
|
||||
|
||||
int GetArgSepPosOffset (char *lpszArgument)
|
||||
{
|
||||
if (lpszArgument[0] == '/')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetArgumentID (argumentspec *as, char *lpszArgument, int *nArgPos)
|
||||
{
|
||||
char szTmp[MAX_PATH * 2];
|
||||
int i;
|
||||
|
||||
i = strlen (lpszArgument);
|
||||
szTmp[i] = 0;
|
||||
while (--i >= 0)
|
||||
{
|
||||
szTmp[i] = (char) tolower (lpszArgument[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < as->arg_cnt; i++)
|
||||
{
|
||||
size_t k;
|
||||
|
||||
k = strlen (as->args[i].long_name);
|
||||
if (memcmp (as->args[i].long_name, szTmp, k * sizeof (char)) == 0)
|
||||
{
|
||||
int x;
|
||||
for (x = i + 1; x < as->arg_cnt; x++)
|
||||
{
|
||||
size_t m;
|
||||
|
||||
m = strlen (as->args[x].long_name);
|
||||
if (memcmp (as->args[x].long_name, szTmp, m * sizeof (char)) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x == as->arg_cnt)
|
||||
{
|
||||
if (strlen (lpszArgument) != k)
|
||||
*nArgPos = k;
|
||||
else
|
||||
*nArgPos = 0;
|
||||
return as->args[i].Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < as->arg_cnt; i++)
|
||||
{
|
||||
size_t k;
|
||||
|
||||
if (as->args[i].short_name[0] == 0)
|
||||
continue;
|
||||
|
||||
k = strlen (as->args[i].short_name);
|
||||
if (memcmp (as->args[i].short_name, szTmp, k * sizeof (char)) == 0)
|
||||
{
|
||||
int x;
|
||||
for (x = i + 1; x < as->arg_cnt; x++)
|
||||
{
|
||||
size_t m;
|
||||
|
||||
if (as->args[x].short_name[0] == 0)
|
||||
continue;
|
||||
|
||||
m = strlen (as->args[x].short_name);
|
||||
if (memcmp (as->args[x].short_name, szTmp, m * sizeof (char)) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x == as->arg_cnt)
|
||||
{
|
||||
if (strlen (lpszArgument) != k)
|
||||
*nArgPos = k;
|
||||
else
|
||||
*nArgPos = 0;
|
||||
return as->args[i].Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GetArgumentValue (char **lpszCommandLineArgs, int nArgPos, int *nArgIdx,
|
||||
int nNoCommandLineArgs, char *lpszValue, int nValueSize)
|
||||
{
|
||||
*lpszValue = 0;
|
||||
|
||||
if (nArgPos)
|
||||
{
|
||||
/* Handles the case of no space between parameter code and
|
||||
value */
|
||||
strncpy (lpszValue, &lpszCommandLineArgs[*nArgIdx][nArgPos], nValueSize);
|
||||
lpszValue[nValueSize - 1] = 0;
|
||||
return HAS_ARGUMENT;
|
||||
}
|
||||
else if (*nArgIdx + 1 < nNoCommandLineArgs)
|
||||
{
|
||||
int x = GetArgSepPosOffset (lpszCommandLineArgs[*nArgIdx + 1]);
|
||||
if (x == 0)
|
||||
{
|
||||
/* Handles the case of space between parameter code
|
||||
and value */
|
||||
strncpy (lpszValue, &lpszCommandLineArgs[*nArgIdx + 1][x], nValueSize);
|
||||
lpszValue[nValueSize - 1] = 0;
|
||||
(*nArgIdx)++;
|
||||
return HAS_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
return HAS_NO_ARGUMENT;
|
||||
}
|
41
src/Common/Cmdline.h
Normal file
41
src/Common/Cmdline.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HAS_ARGUMENT 1
|
||||
#define HAS_NO_ARGUMENT !HAS_ARGUMENT
|
||||
|
||||
typedef struct argument_t
|
||||
{
|
||||
int Id;
|
||||
char long_name[32];
|
||||
char short_name[8];
|
||||
BOOL Internal;
|
||||
} argument;
|
||||
|
||||
typedef struct argumentspec_t
|
||||
{
|
||||
argument *args;
|
||||
int arg_cnt;
|
||||
} argumentspec;
|
||||
|
||||
BOOL CALLBACK CommandHelpDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam );
|
||||
int Win32CommandLine ( char *lpszCommandLine , char ***lpszArgs );
|
||||
int GetArgSepPosOffset ( char *lpszArgument );
|
||||
int GetArgumentID ( argumentspec *as , char *lpszArgument , int *nArgPos );
|
||||
int GetArgumentValue ( char **lpszCommandLineArgs , int nArgPos , int *nArgIdx , int nNoCommandLineArgs , char *lpszValue , int nValueSize );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
212
src/Common/Combo.c
Normal file
212
src/Common/Combo.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Combo.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Xml.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#define SIZEOF_MRU_LIST 20
|
||||
|
||||
void AddComboItem (HWND hComboBox, char *lpszFileName, BOOL saveHistory)
|
||||
{
|
||||
LPARAM nIndex;
|
||||
|
||||
if (!saveHistory)
|
||||
{
|
||||
SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
|
||||
SetWindowText (hComboBox, lpszFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
nIndex = SendMessage (hComboBox, CB_FINDSTRINGEXACT, (WPARAM) - 1, (LPARAM) & lpszFileName[0]);
|
||||
|
||||
if (nIndex == CB_ERR && *lpszFileName)
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) & lpszFileName[0]);
|
||||
if (nIndex != CB_ERR)
|
||||
SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) lTime);
|
||||
}
|
||||
|
||||
if (nIndex != CB_ERR && *lpszFileName)
|
||||
nIndex = SendMessage (hComboBox, CB_SETCURSEL, nIndex, 0);
|
||||
|
||||
if (*lpszFileName == 0)
|
||||
{
|
||||
SendMessage (hComboBox, CB_SETCURSEL, (WPARAM) - 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LPARAM MoveEditToCombo (HWND hComboBox, BOOL saveHistory)
|
||||
{
|
||||
char szTmp[TC_MAX_PATH] = {0};
|
||||
|
||||
if (!saveHistory)
|
||||
{
|
||||
GetWindowText (hComboBox, szTmp, sizeof (szTmp));
|
||||
SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
|
||||
SetWindowText (hComboBox, szTmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GetWindowText (hComboBox, szTmp, sizeof (szTmp));
|
||||
|
||||
if (strlen (szTmp) > 0)
|
||||
{
|
||||
LPARAM nIndex = SendMessage (hComboBox, CB_FINDSTRINGEXACT, (WPARAM) - 1,
|
||||
(LPARAM) & szTmp[0]);
|
||||
if (nIndex == CB_ERR)
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) & szTmp[0]);
|
||||
if (nIndex != CB_ERR)
|
||||
SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (DWORD) lTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (DWORD) lTime);
|
||||
}
|
||||
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
return SendMessage (hComboBox, CB_GETCURSEL, 0, 0);
|
||||
}
|
||||
|
||||
int GetOrderComboIdx (HWND hComboBox, int *nIdxList, int nElems)
|
||||
{
|
||||
int x = (int) SendMessage (hComboBox, CB_GETCOUNT, 0, 0);
|
||||
if (x != CB_ERR)
|
||||
{
|
||||
int i, nHighIdx = CB_ERR;
|
||||
time_t lHighTime = -1;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
time_t lTime = SendMessage (hComboBox, CB_GETITEMDATA, (WPARAM) i, 0);
|
||||
if (lTime > lHighTime)
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < nElems; n++)
|
||||
if (nIdxList[n] == i)
|
||||
break;
|
||||
if (n == nElems)
|
||||
{
|
||||
lHighTime = lTime;
|
||||
nHighIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nHighIdx;
|
||||
}
|
||||
|
||||
return CB_ERR;
|
||||
}
|
||||
|
||||
LPARAM UpdateComboOrder (HWND hComboBox)
|
||||
{
|
||||
LPARAM nIndex;
|
||||
|
||||
nIndex = SendMessage (hComboBox, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (nIndex != CB_ERR)
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
nIndex = SendMessage (hComboBox, CB_SETITEMDATA, (WPARAM) nIndex,
|
||||
(LPARAM) lTime);
|
||||
}
|
||||
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
void LoadCombo (HWND hComboBox)
|
||||
{
|
||||
DWORD size;
|
||||
char *history = LoadFile (GetConfigPath (TC_APPD_FILENAME_HISTORY), &size);
|
||||
char *xml = history;
|
||||
char volume[MAX_PATH];
|
||||
|
||||
if (xml == NULL) return;
|
||||
|
||||
while (xml = XmlFindElement (xml, "volume"))
|
||||
{
|
||||
XmlGetNodeText (xml, volume, sizeof (volume));
|
||||
AddComboItem (hComboBox, volume, TRUE);
|
||||
xml++;
|
||||
}
|
||||
|
||||
SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
|
||||
|
||||
free (history);
|
||||
}
|
||||
|
||||
void DumpCombo (HWND hComboBox, int bClear)
|
||||
{
|
||||
FILE *f;
|
||||
int i, nComboIdx[SIZEOF_MRU_LIST];
|
||||
|
||||
if (bClear)
|
||||
{
|
||||
DeleteFile (GetConfigPath (TC_APPD_FILENAME_HISTORY));
|
||||
return;
|
||||
}
|
||||
|
||||
f = fopen (GetConfigPath (TC_APPD_FILENAME_HISTORY), "w");
|
||||
if (f == NULL) return;
|
||||
|
||||
XmlWriteHeader (f);
|
||||
fputs ("\n\t<history>", f);
|
||||
|
||||
/* combo list part:- get mru items */
|
||||
for (i = 0; i < SIZEOF_MRU_LIST; i++)
|
||||
nComboIdx[i] = GetOrderComboIdx (hComboBox, &nComboIdx[0], i);
|
||||
|
||||
/* combo list part:- write out mru items */
|
||||
for (i = 0; i < SIZEOF_MRU_LIST; i++)
|
||||
{
|
||||
char szTmp[MAX_PATH] = { 0 };
|
||||
|
||||
if (SendMessage (hComboBox, CB_GETLBTEXTLEN, nComboIdx[i], 0) < sizeof (szTmp))
|
||||
SendMessage (hComboBox, CB_GETLBTEXT, nComboIdx[i], (LPARAM) & szTmp[0]);
|
||||
|
||||
if (szTmp[0] != 0)
|
||||
{
|
||||
char q[MAX_PATH * 2] = { 0 };
|
||||
XmlQuoteText (szTmp, q, sizeof (q));
|
||||
|
||||
fprintf (f, "\n\t\t<volume>%s</volume>", q);
|
||||
}
|
||||
}
|
||||
|
||||
fputs ("\n\t</history>", f);
|
||||
XmlWriteFooter (f);
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
void ClearCombo (HWND hComboBox)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SIZEOF_MRU_LIST; i++)
|
||||
{
|
||||
SendMessage (hComboBox, CB_DELETESTRING, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int IsComboEmpty (HWND hComboBox)
|
||||
{
|
||||
return SendMessage (hComboBox, CB_GETCOUNT, 0, 0) < 1;
|
||||
}
|
27
src/Common/Combo.h
Normal file
27
src/Common/Combo.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void AddComboItem (HWND hComboBox, char *lpszFileName, BOOL saveHistory);
|
||||
LPARAM MoveEditToCombo (HWND hComboBox, BOOL saveHistory);
|
||||
int GetOrderComboIdx ( HWND hComboBox , int *nIdxList , int nElems );
|
||||
LPARAM UpdateComboOrder ( HWND hComboBox );
|
||||
void LoadCombo ( HWND hComboBox );
|
||||
void DumpCombo ( HWND hComboBox , int bClear );
|
||||
void ClearCombo (HWND hComboBox);
|
||||
int IsComboEmpty (HWND hComboBox);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
81
src/Common/Common.h
Normal file
81
src/Common/Common.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include "Crypto.h"
|
||||
|
||||
#define MIN_MOUNTED_VOLUME_DRIVE_NUMBER ('A' - 'A')
|
||||
#define MAX_MOUNTED_VOLUME_DRIVE_NUMBER ('Z' - 'A')
|
||||
|
||||
#define MAX_HOST_DRIVE_NUMBER 64
|
||||
#define MAX_HOST_PARTITION_NUMBER 32
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// IMPORTANT: If you add a new item here, update IsOSVersionAtLeast().
|
||||
|
||||
WIN_UNKNOWN = 0,
|
||||
WIN_31,
|
||||
WIN_95,
|
||||
WIN_98,
|
||||
WIN_ME,
|
||||
WIN_NT3,
|
||||
WIN_NT4,
|
||||
WIN_2000,
|
||||
WIN_XP,
|
||||
WIN_XP64,
|
||||
WIN_SERVER_2003,
|
||||
WIN_VISTA,
|
||||
WIN_SERVER_2008,
|
||||
WIN_7,
|
||||
WIN_SERVER_2008_R2,
|
||||
} OSVersionEnum;
|
||||
|
||||
/* Volume types */
|
||||
enum
|
||||
{
|
||||
TC_VOLUME_TYPE_NORMAL = 0,
|
||||
TC_VOLUME_TYPE_HIDDEN,
|
||||
TC_VOLUME_TYPE_HIDDEN_LEGACY,
|
||||
TC_VOLUME_TYPE_COUNT
|
||||
};
|
||||
|
||||
/* Prop volume types */
|
||||
enum
|
||||
{
|
||||
PROP_VOL_TYPE_NORMAL = 0,
|
||||
PROP_VOL_TYPE_HIDDEN,
|
||||
PROP_VOL_TYPE_OUTER, /* Outer/normal (hidden volume protected) */
|
||||
PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, /* Outer/normal (hidden volume protected AND write already prevented) */
|
||||
PROP_VOL_TYPE_SYSTEM,
|
||||
PROP_NBR_VOLUME_TYPES
|
||||
};
|
||||
|
||||
/* Hidden volume protection status */
|
||||
enum
|
||||
{
|
||||
HIDVOL_PROT_STATUS_NONE = 0,
|
||||
HIDVOL_PROT_STATUS_ACTIVE,
|
||||
HIDVOL_PROT_STATUS_ACTION_TAKEN /* Active + action taken (write operation has already been denied) */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL ReadOnly;
|
||||
BOOL Removable;
|
||||
BOOL ProtectHiddenVolume;
|
||||
BOOL PreserveTimestamp;
|
||||
BOOL PartitionInInactiveSysEncScope; /* If TRUE, we are to attempt to mount a partition located on an encrypted system drive without pre-boot authentication. */
|
||||
Password ProtectedHidVolPassword; /* Password of hidden volume to protect against overwriting */
|
||||
BOOL UseBackupHeader;
|
||||
BOOL RecoveryMode;
|
||||
} MountOptions;
|
||||
|
||||
#endif
|
541
src/Common/Common.rc
Normal file
541
src/Common/Common.rc
Normal file
@ -0,0 +1,541 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUT_DLG DIALOGEX 31, 51, 292, 199
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About TrueCrypt"
|
||||
CLASS "SplashDlg"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
EDITTEXT IDC_ABOUT_CREDITS,7,111,277,45,ES_MULTILINE | WS_VSCROLL | NOT WS_TABSTOP
|
||||
DEFPUSHBUTTON "OK",IDOK,230,178,52,14
|
||||
LTEXT "",IDC_HOMEPAGE,18,87,117,9,SS_NOTIFY
|
||||
LTEXT "",IDT_ABOUT_RELEASE,18,71,235,8
|
||||
CONTROL 517,IDC_ABOUT_BKG,"Static",SS_BITMAP,0,0,12,11,WS_EX_STATICEDGE
|
||||
LTEXT "",IDT_ABOUT_VERSION,18,61,161,8
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,167,291,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,169,291,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,107,291,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_ABOUT_LOGO_AREA,"Static",SS_GRAYRECT | NOT WS_VISIBLE,0,0,293,50,WS_EX_TRANSPARENT | WS_EX_STATICEDGE
|
||||
CONTROL 518,IDC_TEXTUAL_LOGO_IMG,"Static",SS_BITMAP,12,26,157,16
|
||||
END
|
||||
|
||||
IDD_COMMANDHELP_DLG DIALOGEX 0, 0, 249, 213
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Command Line Help"
|
||||
CLASS "CustomDlg"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,93,191,59,14
|
||||
LTEXT "",IDC_COMMANDHELP_TEXT,20,11,208,174
|
||||
END
|
||||
|
||||
IDD_RAWDEVICES_DLG DIALOGEX 0, 0, 305, 209
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Select a Partition or Device"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x0
|
||||
BEGIN
|
||||
CONTROL "",IDC_DEVICELIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,291,178
|
||||
DEFPUSHBUTTON "OK",IDOK,192,190,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,248,190,50,14
|
||||
END
|
||||
|
||||
IDD_MOUNT_OPTIONS DIALOGEX 0, 0, 277, 172
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Mount Options"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "Mount volume as read-&only",IDC_MOUNT_READONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,11,194,10
|
||||
CONTROL "Mount volume as removable &medium",IDC_MOUNT_REMOVABLE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,25,195,10
|
||||
CONTROL "Mount partition &using system encryption without pre-boot authentication",IDC_MOUNT_SYSENC_PART_WITHOUT_PBA,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,53,259,11
|
||||
CONTROL "&Protect hidden volume against damage caused by writing to outer volume",IDC_PROTECT_HIDDEN_VOL,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,86,252,10
|
||||
EDITTEXT IDC_PASSWORD_PROT_HIDVOL,112,104,151,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
CONTROL "&Display password",IDC_SHOW_PASSWORD_MO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,123,90,10
|
||||
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE_HIDVOL_PROT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,136,90,10
|
||||
PUSHBUTTON "&Keyfiles...",IDC_KEYFILES_HIDVOL_PROT,203,125,60,14
|
||||
LTEXT "What is hidden volume protection?",IDC_LINK_HIDVOL_PROTECTION_INFO,16,151,247,10,SS_NOTIFY
|
||||
DEFPUSHBUTTON "OK",IDOK,211,7,60,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,211,24,60,14
|
||||
RTEXT "P&assword to hidden volume:\n(if empty, cache is used)",IDT_HIDDEN_PROT_PASSWD,15,103,91,17,0,WS_EX_RIGHT
|
||||
GROUPBOX "Hidden Volume Protection",IDT_HIDDEN_VOL_PROTECTION,6,72,265,95
|
||||
CONTROL "Use backup header embedded in &volume if available",IDC_USE_EMBEDDED_HEADER_BAK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,257,11
|
||||
END
|
||||
|
||||
IDD_KEYFILES DIALOGEX 0, 0, 345, 237
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Keyfiles"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_KEYLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,8,263,118
|
||||
PUSHBUTTON "Add &Files...",IDC_KEYADD,7,132,61,14
|
||||
PUSHBUTTON "Add &Path...",IDC_ADD_KEYFILE_PATH,73,132,61,14
|
||||
PUSHBUTTON "Add &Token Files...",IDC_TOKEN_FILES_ADD,139,132,65,14
|
||||
PUSHBUTTON "&Remove",IDC_KEYREMOVE,209,132,61,14
|
||||
PUSHBUTTON "Remove &All",IDC_KEYREMOVEALL,275,132,61,14
|
||||
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,219,83,11
|
||||
PUSHBUTTON "&Generate Random Keyfile...",IDC_GENERATE_KEYFILE,213,217,123,14
|
||||
DEFPUSHBUTTON "OK",IDOK,279,8,59,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,279,25,59,14
|
||||
LTEXT "",IDT_KEYFILES_NOTE,10,161,324,41,0,WS_EX_TRANSPARENT
|
||||
LTEXT "WARNING: If you lose a keyfile or if any bit of its first 1024 kilobytes changes, it will be impossible to mount volumes that use the keyfile!",IDT_KEYFILE_WARNING,279,44,58,85,0,WS_EX_TRANSPARENT
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,154,343,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,209,343,1,WS_EX_STATICEDGE
|
||||
LTEXT "More information on keyfiles",IDC_LINK_KEYFILES_INFO,96,220,108,10,SS_NOTIFY
|
||||
END
|
||||
|
||||
IDD_LANGUAGE DIALOGEX 0, 0, 209, 183
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Language"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LISTBOX IDC_LANGLIST,6,7,197,67,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_LANGPACK_CREDITS,6,108,197,28,ES_MULTILINE | ES_READONLY | WS_VSCROLL | NOT WS_TABSTOP
|
||||
CTEXT "Download language pack",IDC_GET_LANG_PACKS,2,146,205,10,SS_NOTIFY
|
||||
DEFPUSHBUTTON "OK",IDOK,97,165,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,153,165,50,14
|
||||
LTEXT "Translated by:",IDT_LANGPACK_AUTHORS,6,99,101,9,SS_NOTIFY,WS_EX_TRANSPARENT
|
||||
RTEXT "",IDC_LANGPACK_VERSION,79,86,118,11
|
||||
GROUPBOX "Active language pack",IDT_ACTIVE_LANG_PACK,0,77,209,65
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,158,208,1,WS_EX_STATICEDGE
|
||||
END
|
||||
|
||||
IDD_BENCHMARK_DLG DIALOGEX 0, 0, 330, 223
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Encryption Algorithm Benchmark"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
COMBOBOX IDC_BENCHMARK_BUFFER_SIZE,55,7,77,129,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_BENCHMARK_SORT_METHOD,207,7,116,74,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "",IDC_RESULTS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,37,249,160
|
||||
DEFPUSHBUTTON "Benchmark",IDC_PERFORM_BENCHMARK,265,37,58,14
|
||||
PUSHBUTTON "Close",IDCLOSE,265,55,58,14
|
||||
LTEXT "Hardware-accelerated AES:",IDC_HW_AES_LABEL_LINK,148,210,108,9,SS_NOTIFY,WS_EX_RIGHT
|
||||
CONTROL "",IDC_HW_AES,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,262,209,57,11,WS_EX_STATICEDGE
|
||||
LTEXT "Parallelization:",IDC_PARALLELIZATION_LABEL_LINK,4,210,67,9,SS_NOTIFY,WS_EX_RIGHT
|
||||
CONTROL "",IDC_PARALLELIZATION,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,77,209,57,11,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,29,328,1,WS_EX_STATICEDGE
|
||||
LTEXT "Buffer Size:",IDT_BUFFER_SIZE,0,9,53,8,0,WS_EX_RIGHT
|
||||
LTEXT "Sort Method:",IDT_SORT_METHOD,135,9,70,8,0,WS_EX_RIGHT
|
||||
LTEXT "Speed is affected by CPU load and storage device characteristics.\n\nThese tests take place in RAM.",IDT_BOX_BENCHMARK_INFO,266,81,57,116
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,205,328,1,WS_EX_STATICEDGE
|
||||
END
|
||||
|
||||
IDD_CIPHER_TEST_DLG DIALOGEX 0, 0, 326, 249
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Test Vectors"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
COMBOBOX IDC_CIPHER,109,10,104,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_KEY,8,36,309,14,ES_AUTOHSCROLL
|
||||
COMBOBOX IDC_KEY_SIZE,67,55,42,68,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_SECONDARY_KEY,8,93,309,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_TEST_DATA_UNIT_NUMBER,8,118,84,14,ES_AUTOHSCROLL
|
||||
CONTROL "XTS mode",IDC_XTS_MODE_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,12,95,10
|
||||
EDITTEXT IDC_PLAINTEXT,8,151,159,14,ES_AUTOHSCROLL
|
||||
COMBOBOX IDC_PLAINTEXT_SIZE,258,151,36,30,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_CIPHERTEXT,8,185,159,14,ES_AUTOHSCROLL
|
||||
DEFPUSHBUTTON "&Encrypt",IDC_ENCRYPT,8,229,52,14
|
||||
PUSHBUTTON "&Decrypt",IDC_DECRYPT,65,229,52,14
|
||||
PUSHBUTTON "&Auto-Test All",IDC_AUTO,129,229,67,14,BS_MULTILINE
|
||||
PUSHBUTTON "&Reset",IDC_RESET,208,229,52,14
|
||||
PUSHBUTTON "Close",IDCLOSE,266,229,52,14
|
||||
GROUPBOX "Key (hexadecimal)",IDT_TEST_KEY,1,26,323,49
|
||||
GROUPBOX "Plaintext (hexadecimal)",IDT_TEST_PLAINTEXT,1,140,323,33
|
||||
GROUPBOX "Ciphertext (hexadecimal)",IDT_TEST_CIPHERTEXT,1,174,323,33
|
||||
RTEXT "",IDC_TESTS_MESSAGE,50,213,178,10
|
||||
CONTROL "",IDC_REDTICK,"REDTICK",0x0,234,214,10,8
|
||||
RTEXT "Key size:",IDT_KEY,8,57,56,8
|
||||
RTEXT "Plaintext size:",IDT_PLAINTEXT,190,153,63,8
|
||||
LTEXT "bits",IDT_KEY_UNIT,114,57,45,8
|
||||
RTEXT "Cipher:",IDT_CIPHER,38,13,68,8
|
||||
LTEXT "bits",IDT_PLAINTEXT_SIZE_UNIT,298,153,22,8
|
||||
GROUPBOX "XTS mode",IDT_XTS_MODE,1,75,323,65
|
||||
LTEXT "Secondary key (hexadecimal)",IDT_SECONDARY_KEY,8,84,187,8
|
||||
LTEXT "Data unit number (64-bit hexadecimal, data unit size is 512 bytes)",IDT_TEST_DATA_UNIT_NUMBER,8,109,308,8
|
||||
RTEXT "Block number:",IDT_TEST_BLOCK_NUMBER,134,122,119,8
|
||||
COMBOBOX IDC_TEST_BLOCK_NUMBER,258,119,36,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
IDD_TEXT_INFO_DIALOG_BOX_DLG DIALOGEX 0, 0, 372, 220
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,305,200,58,14
|
||||
PUSHBUTTON "&Print",IDC_PRINT,156,200,58,14
|
||||
CONTROL "",IDC_INFO_BOX_TEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | ES_NUMBER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,5,6,361,188
|
||||
END
|
||||
|
||||
IDD_KEYFILE_GENERATOR DIALOGEX 0, 0, 308, 270
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Keyfile Generator"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Close",IDCLOSE,237,10,59,14
|
||||
COMBOBOX IDC_PRF_ID,79,49,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
|
||||
PUSHBUTTON "Generate and Save Keyfile...",IDC_GENERATE_AND_SAVE_KEYFILE,89,248,131,14
|
||||
LTEXT "IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases the cryptographic strength of the keyfile.",IDT_KEYFILE_GENERATOR_NOTE,11,5,213,33
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,40,307,1,WS_EX_STATICEDGE
|
||||
RTEXT "Mixing PRF:",IDT_PRF,6,51,67,10,SS_CENTERIMAGE
|
||||
GROUPBOX "Current Pool Content",IDT_POOL_CONTENTS,6,70,296,170
|
||||
CONTROL "",IDC_POOL_CONTENTS,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,16,83,282,148,WS_EX_TRANSPARENT
|
||||
CONTROL "Display pool content",IDC_DISPLAY_POOL_CONTENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,191,51,111,10
|
||||
END
|
||||
|
||||
IDD_MULTI_CHOICE_DLG DIALOGEX 0, 0, 167, 322
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
PUSHBUTTON "",IDC_CHOICE10,7,292,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE9,7,268,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE8,7,244,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE7,7,220,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE6,7,196,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE5,7,172,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE4,7,148,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE3,7,124,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE2,7,100,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE1,7,76,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
LTEXT "",IDC_MULTI_CHOICE_MSG,7,7,153,56,0,WS_EX_TRANSPARENT
|
||||
CONTROL "",IDC_MC_DLG_HR2,"Static",SS_ETCHEDHORZ,0,69,168,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_MC_DLG_HR1,"Static",SS_ETCHEDHORZ,0,1,168,1,WS_EX_STATICEDGE
|
||||
END
|
||||
|
||||
IDD_AUXILIARY_DLG DIALOGEX 0, 0, 426, 296
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_NOFAILCREATE | WS_POPUP
|
||||
EXSTYLE WS_EX_TRANSPARENT
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "",IDC_ASPECT_RATIO_CALIBRATION_BOX,3,2,282,282,WS_DISABLED
|
||||
END
|
||||
|
||||
IDD_TOKEN_PASSWORD DIALOGEX 0, 0, 281, 47
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Security token password/PIN required"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
EDITTEXT IDC_TOKEN_PASSWORD,8,20,199,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
DEFPUSHBUTTON "OK",IDOK,215,7,59,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,215,25,59,14
|
||||
LTEXT "",IDT_TOKEN_PASSWORD_INFO,9,8,196,8
|
||||
END
|
||||
|
||||
IDD_TOKEN_KEYFILES DIALOGEX 0, 0, 337, 185
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Security Token Keyfiles"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_TOKEN_FILE_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,256,152
|
||||
PUSHBUTTON "&Export...",IDC_EXPORT,7,164,55,14
|
||||
PUSHBUTTON "&Delete",IDC_DELETE,66,164,55,14
|
||||
PUSHBUTTON "&Import Keyfile to Token...",IDC_IMPORT_KEYFILE,126,164,137,14
|
||||
DEFPUSHBUTTON "OK",IDOK,271,7,59,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,271,25,59,14
|
||||
END
|
||||
|
||||
IDD_NEW_TOKEN_KEYFILE DIALOGEX 0, 0, 239, 82
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "New Security Token Keyfile Properties"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,128,61,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,183,61,50,14
|
||||
COMBOBOX IDC_SELECTED_TOKEN,77,13,140,43,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Security token:",IDT_SECURITY_TOKEN,11,15,62,8,0,WS_EX_RIGHT
|
||||
LTEXT "Keyfile name:",IDT_TOKEN_KEYFILE_NAME,12,34,61,8,0,WS_EX_RIGHT
|
||||
EDITTEXT IDC_TOKEN_KEYFILE_NAME,77,32,140,13,ES_AUTOHSCROLL
|
||||
GROUPBOX "",IDC_STATIC,5,2,228,51
|
||||
END
|
||||
|
||||
IDD_RANDOM_POOL_ENRICHMENT DIALOGEX 0, 0, 308, 270
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Random Pool Enrichment"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "&Continue",IDC_CONTINUE,119,248,71,14
|
||||
COMBOBOX IDC_PRF_ID,79,49,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
|
||||
LTEXT "IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases security. When done, click 'Continue'.",IDT_RANDOM_POOL_ENRICHMENT_NOTE,11,6,282,25
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,37,307,1,WS_EX_STATICEDGE
|
||||
RTEXT "Mixing PRF:",IDT_PRF,6,51,67,10,SS_CENTERIMAGE
|
||||
GROUPBOX "Current Pool Content",IDT_POOL_CONTENTS,6,70,296,170
|
||||
CONTROL "",IDC_POOL_CONTENTS,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,16,83,282,148,WS_EX_TRANSPARENT
|
||||
CONTROL "Display pool content",IDC_DISPLAY_POOL_CONTENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,191,51,111,10
|
||||
END
|
||||
|
||||
IDD_STATIC_MODELESS_WAIT_DLG DIALOGEX 0, 0, 292, 42
|
||||
STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
|
||||
EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
|
||||
CAPTION "TrueCrypt"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Please wait. This process may take a long time...",IDT_STATIC_MODELESS_WAIT_DLG_INFO,9,8,274,9
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_COMMANDHELP_DLG, DIALOG
|
||||
BEGIN
|
||||
BOTTOMMARGIN, 205
|
||||
END
|
||||
|
||||
IDD_RAWDEVICES_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 298
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 205
|
||||
END
|
||||
|
||||
IDD_MOUNT_OPTIONS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 166
|
||||
END
|
||||
|
||||
IDD_KEYFILES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 330
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 230
|
||||
END
|
||||
|
||||
IDD_LANGUAGE, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 6
|
||||
RIGHTMARGIN, 202
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 176
|
||||
END
|
||||
|
||||
IDD_BENCHMARK_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 323
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 216
|
||||
END
|
||||
|
||||
IDD_CIPHER_TEST_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 319
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 242
|
||||
END
|
||||
|
||||
IDD_TEXT_INFO_DIALOG_BOX_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 365
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 213
|
||||
END
|
||||
|
||||
IDD_KEYFILE_GENERATOR, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 299
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 266
|
||||
END
|
||||
|
||||
IDD_MULTI_CHOICE_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 160
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 316
|
||||
END
|
||||
|
||||
IDD_AUXILIARY_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 419
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 289
|
||||
END
|
||||
|
||||
IDD_TOKEN_PASSWORD, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 274
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 40
|
||||
END
|
||||
|
||||
IDD_TOKEN_KEYFILES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 330
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 178
|
||||
END
|
||||
|
||||
IDD_NEW_TOKEN_KEYFILE, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 232
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 75
|
||||
END
|
||||
|
||||
IDD_RANDOM_POOL_ENRICHMENT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 301
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 267
|
||||
END
|
||||
|
||||
IDD_STATIC_MODELESS_WAIT_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 285
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 35
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BIN
|
||||
//
|
||||
|
||||
IDR_BOOT_SECTOR BIN "..\\Boot\\Windows\\Release\\BootSector.bin"
|
||||
IDR_BOOT_SECTOR_AES BIN "..\\Boot\\Windows\\Release_AES\\BootSector.bin"
|
||||
IDR_BOOT_SECTOR_SERPENT BIN "..\\Boot\\Windows\\Release_Serpent\\BootSector.bin"
|
||||
IDR_BOOT_SECTOR_TWOFISH BIN "..\\Boot\\Windows\\Release_Twofish\\BootSector.bin"
|
||||
IDR_BOOT_LOADER_DECOMPRESSOR BIN "..\\Boot\\Windows\\Release\\Decompressor.com"
|
||||
IDR_BOOT_LOADER BIN "..\\Boot\\Windows\\Release\\BootLoader.com.gz"
|
||||
IDR_BOOT_LOADER_AES BIN "..\\Boot\\Windows\\Release_AES\\BootLoader.com.gz"
|
||||
IDR_BOOT_LOADER_SERPENT BIN "..\\Boot\\Windows\\Release_Serpent\\BootLoader.com.gz"
|
||||
IDR_BOOT_LOADER_TWOFISH BIN "..\\Boot\\Windows\\Release_Twofish\\BootLoader.com.gz"
|
||||
IDR_RESCUE_BOOT_SECTOR BIN "..\\Boot\\Windows\\Rescue\\BootSector.bin"
|
||||
IDR_RESCUE_BOOT_SECTOR_AES BIN "..\\Boot\\Windows\\Rescue_AES\\BootSector.bin"
|
||||
IDR_RESCUE_BOOT_SECTOR_SERPENT BIN "..\\Boot\\Windows\\Rescue_Serpent\\BootSector.bin"
|
||||
IDR_RESCUE_BOOT_SECTOR_TWOFISH BIN "..\\Boot\\Windows\\Rescue_Twofish\\BootSector.bin"
|
||||
IDR_RESCUE_LOADER BIN "..\\Boot\\Windows\\Rescue\\BootLoader.com.gz"
|
||||
IDR_RESCUE_LOADER_AES BIN "..\\Boot\\Windows\\Rescue_AES\\BootLoader.com.gz"
|
||||
IDR_RESCUE_LOADER_SERPENT BIN "..\\Boot\\Windows\\Rescue_Serpent\\BootLoader.com.gz"
|
||||
IDR_RESCUE_LOADER_TWOFISH BIN "..\\Boot\\Windows\\Rescue_Twofish\\BootLoader.com.gz"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// XML
|
||||
//
|
||||
|
||||
IDR_LANGUAGE XML "..\\Common\\Language.xml"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HEADER
|
||||
//
|
||||
|
||||
IDR_COMMON_RSRC_HEADER HEADER "..\\Common\\Resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXT
|
||||
//
|
||||
|
||||
IDR_LICENSE TEXT "..\\Resources\\Texts\\License.rtf"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_TRUECRYPT_ICON ICON "..\\Common\\TrueCrypt.ico"
|
||||
IDI_TRUECRYPT_VOL_ICON ICON "..\\Common\\TrueCrypt_volume.ico"
|
||||
IDI_TRUECRYPT_MOUNTED_ICON ICON "..\\Common\\TrueCrypt_mounted.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
IDB_TEXTUAL_LOGO_BKG BITMAP "..\\Common\\Textual_logo_background.bmp"
|
||||
IDB_TEXTUAL_LOGO_96DPI BITMAP "..\\Common\\Textual_logo_96dpi.bmp"
|
||||
IDB_TEXTUAL_LOGO_288DPI BITMAP "..\\Common\\Textual_logo_288dpi.bmp"
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
133
src/Common/Crc.c
Normal file
133
src/Common/Crc.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crc.h"
|
||||
#include "Common/Endian.h"
|
||||
|
||||
#ifndef TC_MINIMIZE_CODE_SIZE
|
||||
|
||||
/* CRC polynomial 0x04c11db7 */
|
||||
unsigned __int32 crc_32_tab[]=
|
||||
{
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
unsigned __int32 GetCrc32 (unsigned char *data, int length)
|
||||
{
|
||||
unsigned __int32 CRC = 0xffffffff;
|
||||
|
||||
while (length--)
|
||||
{
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *data++) & 0xFF ];
|
||||
}
|
||||
|
||||
return CRC ^ 0xffffffff;
|
||||
}
|
||||
|
||||
unsigned __int32 crc32int (unsigned __int32 *data)
|
||||
{
|
||||
unsigned char *d = (unsigned char *) data;
|
||||
unsigned __int32 CRC = 0xffffffff;
|
||||
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
|
||||
return (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d) & 0xFF ] ^ 0xffffffff;
|
||||
}
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define CRC_SELFTEST 0x6fcf9e13
|
||||
#else
|
||||
# define CRC_SELFTEST 0xca87914d
|
||||
#endif
|
||||
|
||||
BOOL crc32_selftests (void)
|
||||
{
|
||||
int i;
|
||||
unsigned __int32 crc = 0xffffffff;
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
for (i = 0; i < (int)sizeof(crc_32_tab); i++)
|
||||
crc = UPDC32 (((unsigned char *) crc_32_tab)[i], crc);
|
||||
|
||||
bSuccess = CRC_SELFTEST == (crc ^ 0xffffffff);
|
||||
|
||||
bSuccess &= GetCrc32 ((unsigned char *)crc_32_tab, sizeof crc_32_tab) == CRC_SELFTEST;
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
#else // TC_MINIMIZE_CODE_SIZE
|
||||
|
||||
unsigned __int32 GetCrc32 (unsigned char *data, int length)
|
||||
{
|
||||
unsigned __int32 r = 0xFFFFFFFFUL;
|
||||
int i, b;
|
||||
|
||||
for (i = 0; i < length; ++i)
|
||||
{
|
||||
r ^= data[i];
|
||||
for (b = 0; b < 8; ++b)
|
||||
{
|
||||
if ((unsigned __int8) r & 1)
|
||||
r = (r >> 1) ^ 0xEDB88320UL;
|
||||
else
|
||||
r >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return r ^ 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
BOOL crc32_selftests ()
|
||||
{
|
||||
unsigned __int8 testData[32];
|
||||
unsigned __int8 i;
|
||||
|
||||
for (i = 0; i < sizeof (testData); ++i)
|
||||
testData[i] = i;
|
||||
|
||||
return GetCrc32 (testData, sizeof (testData)) == 0x91267E8AUL;
|
||||
}
|
||||
|
||||
#endif // TC_MINIMIZE_CODE_SIZE
|
35
src/Common/Crc.h
Normal file
35
src/Common/Crc.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_CRC
|
||||
#define TC_HEADER_CRC
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define UPDC32(octet, crc)\
|
||||
(unsigned __int32)((crc_32_tab[(((unsigned __int32)(crc)) ^ ((unsigned char)(octet))) & 0xff] ^ (((unsigned __int32)(crc)) >> 8)))
|
||||
|
||||
unsigned __int32 GetCrc32 (unsigned char *data, int length);
|
||||
unsigned __int32 crc32int (unsigned __int32 *data);
|
||||
BOOL crc32_selftests (void);
|
||||
|
||||
extern unsigned __int32 crc_32_tab[];
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_CRC
|
1871
src/Common/Crypto.c
Normal file
1871
src/Common/Crypto.c
Normal file
File diff suppressed because it is too large
Load Diff
332
src/Common/Crypto.h
Normal file
332
src/Common/Crypto.h
Normal file
@ -0,0 +1,332 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
/* Update the following when adding a new cipher or EA:
|
||||
|
||||
Crypto.h:
|
||||
ID #define
|
||||
MAX_EXPANDED_KEY #define
|
||||
|
||||
Crypto.c:
|
||||
Ciphers[]
|
||||
EncryptionAlgorithms[]
|
||||
CipherInit()
|
||||
EncipherBlock()
|
||||
DecipherBlock()
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Encryption data unit size, which may differ from the sector size and must always be 512
|
||||
#define ENCRYPTION_DATA_UNIT_SIZE 512
|
||||
|
||||
// Size of the salt (in bytes)
|
||||
#define PKCS5_SALT_SIZE 64
|
||||
|
||||
// Size of the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode)
|
||||
#define MASTER_KEYDATA_SIZE 256
|
||||
|
||||
// Size of the deprecated volume header item containing either an IV seed (CBC mode) or tweak key (LRW mode)
|
||||
#define LEGACY_VOL_IV_SIZE 32
|
||||
|
||||
// The first PRF to try when mounting
|
||||
#define FIRST_PRF_ID 1
|
||||
|
||||
// Hash algorithms (pseudorandom functions).
|
||||
enum
|
||||
{
|
||||
RIPEMD160 = FIRST_PRF_ID,
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
SHA512,
|
||||
WHIRLPOOL,
|
||||
SHA1, // Deprecated/legacy
|
||||
#endif
|
||||
HASH_ENUM_END_ID
|
||||
};
|
||||
|
||||
// The last PRF to try when mounting and also the number of implemented PRFs
|
||||
#define LAST_PRF_ID (HASH_ENUM_END_ID - 1)
|
||||
|
||||
#define RIPEMD160_BLOCKSIZE 64
|
||||
#define RIPEMD160_DIGESTSIZE 20
|
||||
|
||||
#define SHA1_BLOCKSIZE 64
|
||||
#define SHA1_DIGESTSIZE 20
|
||||
|
||||
#define SHA512_BLOCKSIZE 128
|
||||
#define SHA512_DIGESTSIZE 64
|
||||
|
||||
#define WHIRLPOOL_BLOCKSIZE 64
|
||||
#define WHIRLPOOL_DIGESTSIZE 64
|
||||
|
||||
#define MAX_DIGESTSIZE WHIRLPOOL_DIGESTSIZE
|
||||
|
||||
#define DEFAULT_HASH_ALGORITHM FIRST_PRF_ID
|
||||
#define DEFAULT_HASH_ALGORITHM_BOOT RIPEMD160
|
||||
|
||||
// The mode of operation used for newly created volumes and first to try when mounting
|
||||
#define FIRST_MODE_OF_OPERATION_ID 1
|
||||
|
||||
// Modes of operation
|
||||
enum
|
||||
{
|
||||
/* If you add/remove a mode, update the following: GetMaxPkcs5OutSize(), EAInitMode() */
|
||||
|
||||
XTS = FIRST_MODE_OF_OPERATION_ID,
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
LRW, // Deprecated/legacy
|
||||
CBC, // Deprecated/legacy
|
||||
OUTER_CBC, // Deprecated/legacy
|
||||
INNER_CBC, // Deprecated/legacy
|
||||
#endif
|
||||
MODE_ENUM_END_ID
|
||||
};
|
||||
|
||||
|
||||
// The last mode of operation to try when mounting and also the number of implemented modes
|
||||
#define LAST_MODE_OF_OPERATION (MODE_ENUM_END_ID - 1)
|
||||
|
||||
// Ciphertext/plaintext block size for XTS mode (in bytes)
|
||||
#define BYTES_PER_XTS_BLOCK 16
|
||||
|
||||
// Number of ciphertext/plaintext blocks per XTS data unit
|
||||
#define BLOCKS_PER_XTS_DATA_UNIT (ENCRYPTION_DATA_UNIT_SIZE / BYTES_PER_XTS_BLOCK)
|
||||
|
||||
|
||||
// Cipher IDs
|
||||
enum
|
||||
{
|
||||
NONE = 0,
|
||||
AES,
|
||||
SERPENT,
|
||||
TWOFISH,
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
BLOWFISH, // Deprecated/legacy
|
||||
CAST, // Deprecated/legacy
|
||||
TRIPLEDES // Deprecated/legacy
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Id; // Cipher ID
|
||||
char *Name; // Name
|
||||
int BlockSize; // Block size (bytes)
|
||||
int KeySize; // Key size (bytes)
|
||||
int KeyScheduleSize; // Scheduled key size (bytes)
|
||||
} Cipher;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Ciphers[4]; // Null terminated array of ciphers used by encryption algorithm
|
||||
int Modes[LAST_MODE_OF_OPERATION + 1]; // Null terminated array of modes of operation
|
||||
int FormatEnabled;
|
||||
} EncryptionAlgorithm;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Id; // Hash ID
|
||||
char *Name; // Name
|
||||
BOOL Deprecated;
|
||||
BOOL SystemEncryption; // Available for system encryption
|
||||
} Hash;
|
||||
|
||||
// Maxium length of scheduled key
|
||||
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_AES)
|
||||
# define AES_KS (sizeof(aes_encrypt_ctx) + sizeof(aes_decrypt_ctx))
|
||||
#else
|
||||
# define AES_KS (sizeof(aes_context))
|
||||
#endif
|
||||
#define SERPENT_KS (140 * 4)
|
||||
|
||||
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
|
||||
|
||||
# ifdef TC_WINDOWS_BOOT_AES
|
||||
# define MAX_EXPANDED_KEY AES_KS
|
||||
# elif defined (TC_WINDOWS_BOOT_SERPENT)
|
||||
# define MAX_EXPANDED_KEY SERPENT_KS
|
||||
# elif defined (TC_WINDOWS_BOOT_TWOFISH)
|
||||
# define MAX_EXPANDED_KEY TWOFISH_KS
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
#define MAX_EXPANDED_KEY (AES_KS + SERPENT_KS + TWOFISH_KS)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define PRAND_DISK_WIPE_PASSES 3
|
||||
#else
|
||||
# define PRAND_DISK_WIPE_PASSES 256
|
||||
#endif
|
||||
|
||||
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_AES)
|
||||
# include "Aes.h"
|
||||
#else
|
||||
# include "AesSmall.h"
|
||||
#endif
|
||||
|
||||
#include "Aes_hw_cpu.h"
|
||||
#include "Blowfish.h"
|
||||
#include "Cast.h"
|
||||
#include "Des.h"
|
||||
#include "Serpent.h"
|
||||
#include "Twofish.h"
|
||||
|
||||
#include "Rmd160.h"
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
# include "Sha1.h"
|
||||
# include "Sha2.h"
|
||||
# include "Whirlpool.h"
|
||||
#endif
|
||||
|
||||
#include "GfMul.h"
|
||||
#include "Password.h"
|
||||
|
||||
typedef struct keyInfo_t
|
||||
{
|
||||
int noIterations; /* Number of times to iterate (PKCS-5) */
|
||||
int keyLength; /* Length of the key */
|
||||
__int8 userKey[MAX_PASSWORD]; /* Password (to which keyfiles may have been applied). WITHOUT +1 for the null terminator. */
|
||||
__int8 salt[PKCS5_SALT_SIZE]; /* PKCS-5 salt */
|
||||
__int8 master_keydata[MASTER_KEYDATA_SIZE]; /* Concatenated master primary and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
|
||||
} KEY_INFO, *PKEY_INFO;
|
||||
|
||||
typedef struct CRYPTO_INFO_t
|
||||
{
|
||||
int ea; /* Encryption algorithm ID */
|
||||
int mode; /* Mode of operation (e.g., XTS) */
|
||||
unsigned __int8 ks[MAX_EXPANDED_KEY]; /* Primary key schedule (if it is a cascade, it conatins multiple concatenated keys) */
|
||||
unsigned __int8 ks2[MAX_EXPANDED_KEY]; /* Secondary key schedule (if cascade, multiple concatenated) for XTS mode. */
|
||||
|
||||
BOOL hiddenVolume; // Indicates whether the volume is mounted/mountable as hidden volume
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
uint16 HeaderVersion;
|
||||
|
||||
GfCtx gf_ctx;
|
||||
|
||||
unsigned __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* This holds the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
|
||||
unsigned __int8 k2[MASTER_KEYDATA_SIZE]; /* For XTS, this contains the secondary key (if cascade, multiple concatenated). For LRW (deprecated/legacy), it contains the tweak key. For CBC (deprecated/legacy), it contains the IV seed. */
|
||||
unsigned __int8 salt[PKCS5_SALT_SIZE];
|
||||
int noIterations;
|
||||
int pkcs5;
|
||||
|
||||
uint64 volume_creation_time; // Legacy
|
||||
uint64 header_creation_time; // Legacy
|
||||
|
||||
BOOL bProtectHiddenVolume; // Indicates whether the volume contains a hidden volume to be protected against overwriting
|
||||
BOOL bHiddenVolProtectionAction; // TRUE if a write operation has been denied by the driver in order to prevent the hidden volume from being overwritten (set to FALSE upon volume mount).
|
||||
|
||||
uint64 volDataAreaOffset; // Absolute position, in bytes, of the first data sector of the volume.
|
||||
|
||||
uint64 hiddenVolumeSize; // Size of the hidden volume excluding the header (in bytes). Set to 0 for standard volumes.
|
||||
uint64 hiddenVolumeOffset; // Absolute position, in bytes, of the first hidden volume data sector within the host volume (provided that there is a hidden volume within). This must be set for all hidden volumes; in case of a normal volume, this variable is only used when protecting a hidden volume within it.
|
||||
uint64 hiddenVolumeProtectedSize;
|
||||
|
||||
BOOL bPartitionInInactiveSysEncScope; // If TRUE, the volume is a partition located on an encrypted system drive and mounted without pre-boot authentication.
|
||||
|
||||
UINT64_STRUCT FirstDataUnitNo; // First data unit number of the volume. This is 0 for file-hosted and non-system partition-hosted volumes. For partitions within key scope of system encryption this reflects real physical offset within the device (this is used e.g. when such a partition is mounted as a regular volume without pre-boot authentication).
|
||||
|
||||
uint16 RequiredProgramVersion;
|
||||
BOOL LegacyVolume;
|
||||
|
||||
uint32 SectorSize;
|
||||
|
||||
#endif // !TC_WINDOWS_BOOT
|
||||
|
||||
UINT64_STRUCT VolumeSize;
|
||||
|
||||
UINT64_STRUCT EncryptedAreaStart;
|
||||
UINT64_STRUCT EncryptedAreaLength;
|
||||
|
||||
uint32 HeaderFlags;
|
||||
|
||||
} CRYPTO_INFO, *PCRYPTO_INFO;
|
||||
|
||||
PCRYPTO_INFO crypto_open (void);
|
||||
void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen);
|
||||
void crypto_close (PCRYPTO_INFO cryptoInfo);
|
||||
|
||||
int CipherGetBlockSize (int cipher);
|
||||
int CipherGetKeySize (int cipher);
|
||||
int CipherGetKeyScheduleSize (int cipher);
|
||||
BOOL CipherSupportsIntraDataUnitParallelization (int cipher);
|
||||
char * CipherGetName (int cipher);
|
||||
|
||||
int CipherInit (int cipher, unsigned char *key, unsigned char *ks);
|
||||
int EAInit (int ea, unsigned char *key, unsigned char *ks);
|
||||
BOOL EAInitMode (PCRYPTO_INFO ci);
|
||||
void EncipherBlock(int cipher, void *data, void *ks);
|
||||
void DecipherBlock(int cipher, void *data, void *ks);
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount);
|
||||
void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount);
|
||||
#endif
|
||||
|
||||
int EAGetFirst ();
|
||||
int EAGetCount (void);
|
||||
int EAGetNext (int previousEA);
|
||||
char * EAGetName (char *buf, int ea);
|
||||
int EAGetByName (char *name);
|
||||
int EAGetKeySize (int ea);
|
||||
int EAGetFirstMode (int ea);
|
||||
int EAGetNextMode (int ea, int previousModeId);
|
||||
char * EAGetModeName (int ea, int mode, BOOL capitalLetters);
|
||||
int EAGetKeyScheduleSize (int ea);
|
||||
int EAGetLargestKey ();
|
||||
int EAGetLargestKeyForMode (int mode);
|
||||
|
||||
int EAGetCipherCount (int ea);
|
||||
int EAGetFirstCipher (int ea);
|
||||
int EAGetLastCipher (int ea);
|
||||
int EAGetNextCipher (int ea, int previousCipherId);
|
||||
int EAGetPreviousCipher (int ea, int previousCipherId);
|
||||
int EAIsFormatEnabled (int ea);
|
||||
BOOL EAIsModeSupported (int ea, int testedMode);
|
||||
|
||||
char *HashGetName (int hash_algo_id);
|
||||
BOOL HashIsDeprecated (int hashId);
|
||||
|
||||
int GetMaxPkcs5OutSize (void);
|
||||
|
||||
void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci);
|
||||
void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
|
||||
void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci);
|
||||
void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
|
||||
void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo);
|
||||
void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo);
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
void EncryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
void DecryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
void EncryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
void DecryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
uint64 DataUnit2LRWIndex (uint64 dataUnit, int blockSize, PCRYPTO_INFO ci);
|
||||
#endif // #ifndef TC_NO_COMPILER_INT64
|
||||
|
||||
BOOL IsAesHwCpuSupported ();
|
||||
void EnableHwEncryption (BOOL enable);
|
||||
BOOL IsHwEncryptionEnabled ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYPTO_H */
|
80
src/Common/Dictionary.c
Normal file
80
src/Common/Dictionary.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "../Common/Dictionary.h"
|
||||
#include <windows.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static map <string, void *> StringKeyMap;
|
||||
static map <int, void *> IntKeyMap;
|
||||
|
||||
static void *DataPool = NULL;
|
||||
static size_t DataPoolSize = 0;
|
||||
|
||||
|
||||
void AddDictionaryEntry (char *key, int intKey, void *value)
|
||||
{
|
||||
if (key)
|
||||
StringKeyMap[key] = value;
|
||||
|
||||
if (intKey != 0)
|
||||
IntKeyMap[intKey] = value;
|
||||
}
|
||||
|
||||
|
||||
void *GetDictionaryValue (const char *key)
|
||||
{
|
||||
map <string, void *>::const_iterator i = StringKeyMap.find (key);
|
||||
|
||||
if (i == StringKeyMap.end())
|
||||
return NULL;
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
void *GetDictionaryValueByInt (int intKey)
|
||||
{
|
||||
map <int, void *>::const_iterator i = IntKeyMap.find (intKey);
|
||||
|
||||
if (i == IntKeyMap.end())
|
||||
return NULL;
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
void *AddPoolData (void *data, size_t dataSize)
|
||||
{
|
||||
if (DataPoolSize + dataSize > DATA_POOL_CAPACITY) return NULL;
|
||||
|
||||
if (DataPool == NULL)
|
||||
{
|
||||
DataPool = malloc (DATA_POOL_CAPACITY);
|
||||
if (DataPool == NULL) return NULL;
|
||||
}
|
||||
|
||||
memcpy ((BYTE *)DataPool + DataPoolSize, data, dataSize);
|
||||
|
||||
// Ensure 32-bit alignment for next entries
|
||||
dataSize = (dataSize + 3) & (~(size_t)3);
|
||||
|
||||
DataPoolSize += dataSize;
|
||||
return (BYTE *)DataPool + DataPoolSize - dataSize;
|
||||
}
|
||||
|
||||
|
||||
void ClearDictionaryPool ()
|
||||
{
|
||||
DataPoolSize = 0;
|
||||
StringKeyMap.clear();
|
||||
IntKeyMap.clear();
|
||||
}
|
30
src/Common/Dictionary.h
Normal file
30
src/Common/Dictionary.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef DICTIONARY_H
|
||||
#define DICTIONARY_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DATA_POOL_CAPACITY 1000000
|
||||
|
||||
void AddDictionaryEntry (char *key, int intKey, void *value);
|
||||
void *GetDictionaryValue (const char *key);
|
||||
void *GetDictionaryValueByInt (int intKey);
|
||||
void *AddPoolData (void *data, size_t dataSize);
|
||||
void ClearDictionaryPool ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
9848
src/Common/Dlgcode.c
Normal file
9848
src/Common/Dlgcode.c
Normal file
File diff suppressed because it is too large
Load Diff
532
src/Common/Dlgcode.h
Normal file
532
src/Common/Dlgcode.h
Normal file
@ -0,0 +1,532 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_DLGCODE
|
||||
#define TC_HEADER_DLGCODE
|
||||
|
||||
#include "Common.h"
|
||||
#include "Apidrvr.h"
|
||||
#include "Keyfiles.h"
|
||||
#include "Wipe.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* IDs for dynamically generated GUI elements */
|
||||
enum dynamic_gui_element_ids
|
||||
{
|
||||
IDPM_CHECK_FILESYS = 500001,
|
||||
IDPM_REPAIR_FILESYS,
|
||||
IDPM_OPEN_VOLUME,
|
||||
IDPM_SELECT_FILE_AND_MOUNT,
|
||||
IDPM_SELECT_DEVICE_AND_MOUNT,
|
||||
IDPM_ADD_TO_FAVORITES,
|
||||
IDPM_ADD_TO_SYSTEM_FAVORITES,
|
||||
IDM_SHOW_HIDE,
|
||||
IDM_HOMEPAGE_SYSTRAY
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TC_TBXID_LEGAL_NOTICES,
|
||||
TC_TBXID_SYS_ENCRYPTION_PRETEST,
|
||||
TC_TBXID_SYS_ENC_RESCUE_DISK,
|
||||
TC_TBXID_DECOY_OS_INSTRUCTIONS,
|
||||
TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS
|
||||
};
|
||||
|
||||
#define TC_APPLICATION_ID L"TrueCryptFoundation.TrueCrypt"
|
||||
|
||||
#define TC_MUTEX_NAME_SYSENC "Global\\TrueCrypt System Encryption Wizard"
|
||||
#define TC_MUTEX_NAME_NONSYS_INPLACE_ENC "Global\\TrueCrypt In-Place Encryption Wizard"
|
||||
#define TC_MUTEX_NAME_APP_SETUP "Global\\TrueCrypt Setup"
|
||||
#define TC_MUTEX_NAME_DRIVER_SETUP "Global\\TrueCrypt Driver Setup"
|
||||
|
||||
#define IDC_ABOUT 0x7fff /* ID for AboutBox on system menu in wm_user range */
|
||||
|
||||
#define EXCL_ACCESS_MAX_AUTO_RETRIES 500
|
||||
#define EXCL_ACCESS_AUTO_RETRY_DELAY 10
|
||||
|
||||
#define UNMOUNT_MAX_AUTO_RETRIES 30
|
||||
#define UNMOUNT_AUTO_RETRY_DELAY 50
|
||||
|
||||
// After the user receives the "Incorrect password" error this number of times in a row, we should automatically
|
||||
// try using the embedded header backup (if any). This ensures that the "Incorrect password" message is reported faster
|
||||
// initially (most such errors are really caused by supplying an incorrect password, not by header corruption).
|
||||
#define TC_TRY_HEADER_BAK_AFTER_NBR_WRONG_PWD_TRIES 2
|
||||
|
||||
#define MAX_MULTI_CHOICES 10 /* Maximum number of options for mutliple-choice dialog */
|
||||
|
||||
#define TC_APPD_FILENAME_CONFIGURATION "Configuration.xml"
|
||||
#define TC_APPD_FILENAME_SYSTEM_ENCRYPTION "System Encryption.xml"
|
||||
#define TC_APPD_FILENAME_DEFAULT_KEYFILES "Default Keyfiles.xml"
|
||||
#define TC_APPD_FILENAME_HISTORY "History.xml"
|
||||
#define TC_APPD_FILENAME_FAVORITE_VOLUMES "Favorite Volumes.xml"
|
||||
#define TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES TC_APP_NAME " System Favorite Volumes.xml"
|
||||
#define TC_APPD_FILENAME_NONSYS_INPLACE_ENC "In-Place Encryption"
|
||||
#define TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE "In-Place Encryption Wipe Algo"
|
||||
#define TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL "Post-Install Task - Tutorial"
|
||||
#define TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES "Post-Install Task - Release Notes"
|
||||
|
||||
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||
#define USER_DEFAULT_SCREEN_DPI 96
|
||||
#endif
|
||||
|
||||
#if (USER_DEFAULT_SCREEN_DPI != 96)
|
||||
# error Revision of GUI and graphics necessary, since everything assumes default screen DPI as 96 (note that 96 is the default on Windows 2000, XP, and Vista).
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
TC_POST_INSTALL_CFG_REMOVE_ALL = 0,
|
||||
TC_POST_INSTALL_CFG_TUTORIAL,
|
||||
TC_POST_INSTALL_CFG_RELEASE_NOTES
|
||||
};
|
||||
|
||||
extern char *LastDialogId;
|
||||
extern char *ConfigBuffer;
|
||||
extern char szHelpFile[TC_MAX_PATH];
|
||||
extern char szHelpFile2[TC_MAX_PATH];
|
||||
extern char SecurityTokenLibraryPath[TC_MAX_PATH];
|
||||
extern HFONT hFixedDigitFont;
|
||||
extern HFONT hBoldFont;
|
||||
extern HFONT hTitleFont;
|
||||
extern HFONT hFixedFont;
|
||||
extern HFONT hUserFont;
|
||||
extern HFONT hUserUnderlineFont;
|
||||
extern HFONT hUserBoldFont;
|
||||
extern HFONT WindowTitleBarFont;
|
||||
extern int ScreenDPI;
|
||||
extern double DlgAspectRatio;
|
||||
extern HWND MainDlg;
|
||||
extern BOOL Silent;
|
||||
extern BOOL bHistory;
|
||||
extern BOOL bPreserveTimestamp;
|
||||
extern BOOL bStartOnLogon;
|
||||
extern BOOL bMountDevicesOnLogon;
|
||||
extern BOOL bMountFavoritesOnLogon;
|
||||
extern int HiddenSectorDetectionStatus;
|
||||
extern wchar_t *lpszTitle;
|
||||
extern OSVersionEnum nCurrentOS;
|
||||
extern int CurrentOSMajor;
|
||||
extern int CurrentOSMinor;
|
||||
extern int CurrentOSServicePack;
|
||||
extern BOOL RemoteSession;
|
||||
extern HANDLE hDriver;
|
||||
extern HINSTANCE hInst;
|
||||
extern int SystemEncryptionStatus;
|
||||
extern WipeAlgorithmId nWipeMode;
|
||||
extern BOOL bSysPartitionSelected;
|
||||
extern BOOL bSysDriveSelected;
|
||||
|
||||
extern BOOL bHyperLinkBeingTracked;
|
||||
extern BOOL bInPlaceEncNonSysPending;
|
||||
|
||||
extern BOOL KeyFilesEnable;
|
||||
extern KeyFile *FirstKeyFile;
|
||||
extern KeyFilesDlgParam defaultKeyFilesParam;
|
||||
extern BOOL UacElevated;
|
||||
extern BOOL IgnoreWmDeviceChange;
|
||||
extern BOOL DeviceChangeBroadcastDisabled;
|
||||
extern BOOL LastMountedVolumeDirty;
|
||||
extern BOOL MountVolumesAsSystemFavorite;
|
||||
extern BOOL FavoriteMountOnArrivalInProgress;
|
||||
extern BOOL MultipleMountOperationInProgress;
|
||||
|
||||
|
||||
enum tc_app_msg_ids
|
||||
{
|
||||
/* WARNING: Changing these values or their meanings may cause incompatibility with other versions
|
||||
(for example, if a new version of the TrueCrypt installer needed to shut down this version of
|
||||
TrueCrypt during upgrade, it could fail or do something unwanted because the signal value would
|
||||
be incorrect). When adding a new constant, verify that the value is unique within this block and
|
||||
that it is less than WM_APP+16383. */
|
||||
|
||||
// Common (inter-app)
|
||||
TC_APPMSG_CLOSE_BKG_TASK = WM_APP + 4, // Changing this value will prevent smooth upgrades from pre-5.x versions
|
||||
TC_APPMSG_SYSENC_CONFIG_UPDATE = WM_APP + 101,
|
||||
TC_APPMSG_TASKBAR_ICON = WM_APP + 102,
|
||||
TC_APPMSG_LOAD_TEXT_BOX_CONTENT = WM_APP + 103,
|
||||
// Mount
|
||||
TC_APPMSG_MOUNT_ENABLE_DISABLE_CONTROLS = WM_APP + 201,
|
||||
TC_APPMSG_MOUNT_SHOW_WINDOW = WM_APP + 202,
|
||||
TC_APPMSG_PREBOOT_PASSWORD_MODE = WM_APP + 203,
|
||||
// Format
|
||||
TC_APPMSG_VOL_TRANSFORM_THREAD_ENDED = WM_APP + 301,
|
||||
TC_APPMSG_FORMAT_FINISHED = WM_APP + 302,
|
||||
TC_APPMSG_FORMAT_USER_QUIT = WM_APP + 303,
|
||||
TC_APPMSG_PERFORM_POST_WMINIT_TASKS = WM_APP + 304,
|
||||
TC_APPMSG_PERFORM_POST_SYSENC_WMINIT_TASKS = WM_APP + 305,
|
||||
TC_APPMSG_NONSYS_INPLACE_ENC_FINISHED = WM_APP + 306,
|
||||
// Setup
|
||||
TC_APPMSG_INSTALL_SUCCESS = WM_APP + 401,
|
||||
TC_APPMSG_UNINSTALL_SUCCESS = WM_APP + 402,
|
||||
TC_APPMSG_EXTRACTION_SUCCESS = WM_APP + 403,
|
||||
TC_APPMSG_INSTALL_FAILURE = WM_APP + 404,
|
||||
TC_APPMSG_UNINSTALL_FAILURE = WM_APP + 405,
|
||||
TC_APPMSG_EXTRACTION_FAILURE = WM_APP + 406
|
||||
};
|
||||
|
||||
enum system_encryption_status
|
||||
{
|
||||
/* WARNING: As these values are written to config files, if they or their meanings
|
||||
are changed, incompatiblity with other versions may arise (upgrade, downgrade, etc.).
|
||||
When adding a new constant, verify that the value is unique within this block. */
|
||||
SYSENC_STATUS_NONE = 0,
|
||||
SYSENC_STATUS_PRETEST = 200, // This may also mean that the OS is to be (or has been) copied to a hidden volume (to create a hidden OS).
|
||||
SYSENC_STATUS_ENCRYPTING = 400,
|
||||
SYSENC_STATUS_DECRYPTING = 600
|
||||
};
|
||||
|
||||
enum vol_creation_wizard_modes
|
||||
{
|
||||
WIZARD_MODE_FILE_CONTAINER = 0,
|
||||
WIZARD_MODE_NONSYS_DEVICE,
|
||||
WIZARD_MODE_SYS_DEVICE
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL VolumeIsOpen;
|
||||
|
||||
CRYPTO_INFO *CryptoInfo;
|
||||
BOOL IsDevice;
|
||||
HANDLE HostFileHandle;
|
||||
uint64 HostSize;
|
||||
|
||||
BOOL TimestampsValid;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastWriteTime;
|
||||
FILETIME LastAccessTime;
|
||||
|
||||
} OpenVolumeContext;
|
||||
|
||||
|
||||
#define DEFAULT_VOL_CREATION_WIZARD_MODE WIZARD_MODE_FILE_CONTAINER
|
||||
|
||||
#define ICON_HAND MB_ICONHAND
|
||||
#define YES_NO MB_YESNO
|
||||
|
||||
#define ISO_BURNER_TOOL "isoburn.exe"
|
||||
#define PRINT_TOOL "notepad"
|
||||
|
||||
void cleanup ( void );
|
||||
void LowerCaseCopy ( char *lpszDest , const char *lpszSource );
|
||||
void UpperCaseCopy ( char *lpszDest , const char *lpszSource );
|
||||
void CreateFullVolumePath ( char *lpszDiskFile , const char *lpszFileName , BOOL *bDevice );
|
||||
int FakeDosNameForDevice ( const char *lpszDiskFile , char *lpszDosDevice , char *lpszCFDevice , BOOL bNameOnly );
|
||||
int RemoveFakeDosName ( char *lpszDiskFile , char *lpszDosDevice );
|
||||
void AbortProcess ( char *stringId );
|
||||
void AbortProcessSilent ( void );
|
||||
void *err_malloc ( size_t size );
|
||||
char *err_strdup ( char *lpszText );
|
||||
DWORD handleWin32Error ( HWND hwndDlg );
|
||||
BOOL IsDiskReadError (DWORD error);
|
||||
BOOL IsDiskWriteError (DWORD error);
|
||||
BOOL IsDiskError (DWORD error);
|
||||
BOOL translateWin32Error ( wchar_t *lpszMsgBuf , int nWSizeOfBuf );
|
||||
BOOL CALLBACK AboutDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam );
|
||||
static BOOL CALLBACK StaticModelessWaitDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void DisplayStaticModelessWaitDlg (HWND parent);
|
||||
void CloseStaticModelessWaitDlg (void);
|
||||
BOOL IsButtonChecked ( HWND hButton );
|
||||
void CheckButton ( HWND hButton );
|
||||
void LeftPadString (char *szTmp, int len, int targetLen, char filler);
|
||||
void ToSBCS ( LPWSTR lpszText );
|
||||
void ToUNICODE ( char *lpszText );
|
||||
void InitDialog ( HWND hwndDlg );
|
||||
void ProcessPaintMessages (HWND hwnd, int maxMessagesToProcess);
|
||||
HDC CreateMemBitmap ( HINSTANCE hInstance , HWND hwnd , char *resource );
|
||||
HBITMAP RenderBitmap ( char *resource , HWND hwndDest , int x , int y , int nWidth , int nHeight , BOOL bDirectRender , BOOL bKeepAspectRatio);
|
||||
LRESULT CALLBACK RedTick ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
BOOL RegisterRedTick ( HINSTANCE hInstance );
|
||||
BOOL UnregisterRedTick ( HINSTANCE hInstance );
|
||||
LRESULT CALLBACK SplashDlgProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
void WaitCursor ( void );
|
||||
void NormalCursor ( void );
|
||||
void ArrowWaitCursor ( void );
|
||||
void HandCursor ();
|
||||
void AddComboPair (HWND hComboBox, const char *lpszItem, int value);
|
||||
void AddComboPairW (HWND hComboBox, const wchar_t *lpszItem, int value);
|
||||
void SelectAlgo ( HWND hComboBox , int *nCipher );
|
||||
void PopulateWipeModeCombo (HWND hComboBox, BOOL bNA, BOOL bInPlaceEncryption);
|
||||
wchar_t *GetWipeModeName (WipeAlgorithmId modeId);
|
||||
wchar_t *GetPathType (const char *path, BOOL bUpperCase, BOOL *bIsPartition);
|
||||
LRESULT CALLBACK CustomDlgProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
BOOL TCCreateMutex (volatile HANDLE *hMutex, char *name);
|
||||
void TCCloseMutex (volatile HANDLE *hMutex);
|
||||
BOOL MutexExistsOnSystem (char *name);
|
||||
BOOL CreateSysEncMutex (void);
|
||||
BOOL InstanceHasSysEncMutex (void);
|
||||
void CloseSysEncMutex (void);
|
||||
BOOL CreateNonSysInplaceEncMutex (void);
|
||||
BOOL InstanceHasNonSysInplaceEncMutex (void);
|
||||
void CloseNonSysInplaceEncMutex (void);
|
||||
BOOL NonSysInplaceEncInProgressElsewhere (void);
|
||||
BOOL CreateDriverSetupMutex (void);
|
||||
void CloseDriverSetupMutex (void);
|
||||
BOOL CreateAppSetupMutex (void);
|
||||
BOOL InstanceHasAppSetupMutex (void);
|
||||
void CloseAppSetupMutex (void);
|
||||
BOOL IsTrueCryptInstallerRunning (void);
|
||||
uint32 ReadDriverConfigurationFlags ();
|
||||
uint32 ReadEncryptionThreadPoolFreeCpuCountLimit ();
|
||||
BOOL LoadSysEncSettings (HWND hwndDlg);
|
||||
int LoadNonSysInPlaceEncSettings (WipeAlgorithmId *wipeAlgorithm);
|
||||
void RemoveNonSysInPlaceEncNotifications (void);
|
||||
void SavePostInstallTasksSettings (int command);
|
||||
void DoPostInstallTasks (void);
|
||||
void InitOSVersionInfo ();
|
||||
void InitApp ( HINSTANCE hInstance, char *lpszCommandLine );
|
||||
void InitHelpFileName (void);
|
||||
BOOL OpenDevice (const char *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem);
|
||||
void NotifyDriverOfPortableMode (void);
|
||||
int GetAvailableFixedDisks ( HWND hComboBox , char *lpszRootPath );
|
||||
int GetAvailableRemovables ( HWND hComboBox , char *lpszRootPath );
|
||||
int IsSystemDevicePath (char *path, HWND hwndDlg, BOOL bReliableRequired);
|
||||
BOOL CALLBACK RawDevicesDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam );
|
||||
BOOL TextInfoDialogBox (int nID);
|
||||
BOOL CALLBACK TextInfoDialogBoxDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
char * GetLegalNotices ();
|
||||
BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void UserEnrichRandomPool (HWND hwndDlg);
|
||||
BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK MultiChoiceDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
int DriverAttach ( void );
|
||||
BOOL CALLBACK CipherTestDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
void ResetCipherTest ( HWND hwndDlg , int idTestCipher );
|
||||
void ResetCurrentDirectory ();
|
||||
BOOL BrowseFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter);
|
||||
BOOL BrowseDirectories (HWND hWnd, char *lpszTitle, char *dirName);
|
||||
void handleError ( HWND hwndDlg , int code );
|
||||
BOOL CheckFileStreamWriteErrors (FILE *file, const char *fileName);
|
||||
void LocalizeDialog ( HWND hwnd, char *stringId );
|
||||
void OpenVolumeExplorerWindow (int driveNo);
|
||||
static BOOL CALLBACK CloseVolumeExplorerWindowsEnum( HWND hwnd, LPARAM driveNo);
|
||||
BOOL CloseVolumeExplorerWindows (HWND hwnd, int driveNo);
|
||||
BOOL CheckCapsLock (HWND hwnd, BOOL quiet);
|
||||
BOOL CheckFileExtension (char *fileName);
|
||||
void IncreaseWrongPwdRetryCount (int count);
|
||||
void ResetWrongPwdRetryCount (void);
|
||||
BOOL WrongPwdRetryCountOverLimit (void);
|
||||
int GetFirstAvailableDrive ();
|
||||
int GetLastAvailableDrive ();
|
||||
BOOL IsDriveAvailable (int driveNo);
|
||||
BOOL IsDeviceMounted (char *deviceName);
|
||||
int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced);
|
||||
void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap);
|
||||
int MountVolume (HWND hwndDlg, int driveNo, char *volumePath, Password *password, BOOL cachePassword, BOOL sharedAccess, const MountOptions* const mountOptions, BOOL quiet, BOOL bReportWrongPassword);
|
||||
BOOL UnmountVolume (HWND hwndDlg , int nDosDriveNo, BOOL forceUnmount);
|
||||
BOOL IsPasswordCacheEmpty (void);
|
||||
BOOL IsMountedVolume (const char *volname);
|
||||
int GetMountedVolumeDriveNo (char *volname);
|
||||
BOOL IsAdmin (void);
|
||||
BOOL IsBuiltInAdmin ();
|
||||
BOOL IsUacSupported ();
|
||||
BOOL ResolveSymbolicLink (const wchar_t *symLinkName, PWSTR targetName);
|
||||
int GetDiskDeviceDriveLetter (PWSTR deviceName);
|
||||
int FileSystemAppearsEmpty (const char *devicePath);
|
||||
__int64 GetStatsFreeSpaceOnPartition (const char *devicePath, float *percent, __int64 *occupiedBytes, BOOL silent);
|
||||
__int64 GetDeviceSize (const char *devicePath);
|
||||
HANDLE DismountDrive (char *devName, char *devicePath);
|
||||
int64 FindString (const char *buf, const char *str, int64 bufLen, size_t strLen, int64 startOffset);
|
||||
BOOL FileExists (const char *filePathPtr);
|
||||
__int64 FindStringInFile (const char *filePath, const char *str, int strLen);
|
||||
BOOL TCCopyFile (char *sourceFileName, char *destinationFile);
|
||||
BOOL SaveBufferToFile (const char *inputBuffer, const char *destinationFile, DWORD inputLength, BOOL bAppend);
|
||||
BOOL TCFlushFile (FILE *f);
|
||||
BOOL PrintHardCopyTextUTF16 (wchar_t *text, char *title, int byteLen);
|
||||
void GetSpeedString (unsigned __int64 speed, wchar_t *str);
|
||||
BOOL IsNonInstallMode ();
|
||||
BOOL DriverUnload ();
|
||||
LRESULT SetCheckBox (HWND hwndDlg, int dlgItem, BOOL state);
|
||||
BOOL GetCheckBox (HWND hwndDlg, int dlgItem);
|
||||
void SetListScrollHPos (HWND hList, int topMostVisibleItem);
|
||||
void ManageStartupSeq (void);
|
||||
void ManageStartupSeqWiz (BOOL bRemove, const char *arg);
|
||||
void CleanLastVisitedMRU (void);
|
||||
void ClearHistory (HWND hwndDlgItem);
|
||||
LRESULT ListItemAdd (HWND list, int index, char *string);
|
||||
LRESULT ListItemAddW (HWND list, int index, wchar_t *string);
|
||||
LRESULT ListSubItemSet (HWND list, int index, int subIndex, char *string);
|
||||
LRESULT ListSubItemSetW (HWND list, int index, int subIndex, wchar_t *string);
|
||||
BOOL GetMountList (MOUNT_LIST_STRUCT *list);
|
||||
int GetDriverRefCount ();
|
||||
void GetSizeString (unsigned __int64 size, wchar_t *str);
|
||||
__int64 GetFileSize64 (const char *path);
|
||||
BOOL LoadInt16 (char *filePath, int *result, __int64 fileOffset);
|
||||
BOOL LoadInt32 (char *filePath, unsigned __int32 *result, __int64 fileOffset);
|
||||
char *LoadFile (const char *fileName, DWORD *size);
|
||||
char *LoadFileBlock (char *fileName, __int64 fileOffset, size_t count);
|
||||
char *GetModPath (char *path, int maxSize);
|
||||
char *GetConfigPath (char *fileName);
|
||||
char *GetProgramConfigPath (char *fileName);
|
||||
char GetSystemDriveLetter (void);
|
||||
void OpenPageHelp (HWND hwndDlg, int nPage);
|
||||
void TaskBarIconDisplayBalloonTooltip (HWND hwnd, wchar_t *headline, wchar_t *text, BOOL warning);
|
||||
void InfoBalloon (char *headingStringId, char *textStringId);
|
||||
void InfoBalloonDirect (wchar_t *headingString, wchar_t *textString);
|
||||
void WarningBalloon (char *headingStringId, char *textStringId);
|
||||
void WarningBalloonDirect (wchar_t *headingString, wchar_t *textString);
|
||||
int Info (char *stringId);
|
||||
int InfoTopMost (char *stringId);
|
||||
int InfoDirect (const wchar_t *msg);
|
||||
int Warning (char *stringId);
|
||||
int WarningTopMost (char *stringId);
|
||||
int WarningDirect (const wchar_t *warnMsg);
|
||||
int Error (char *stringId);
|
||||
int ErrorDirect (const wchar_t *errMsg);
|
||||
int ErrorTopMost (char *stringId);
|
||||
int AskYesNo (char *stringId);
|
||||
int AskYesNoString (const wchar_t *str);
|
||||
int AskYesNoTopmost (char *stringId);
|
||||
int AskNoYes (char *stringId);
|
||||
int AskOkCancel (char *stringId);
|
||||
int AskWarnYesNo (char *stringId);
|
||||
int AskWarnYesNoString (const wchar_t *string);
|
||||
int AskWarnYesNoTopmost (char *stringId);
|
||||
int AskWarnYesNoStringTopmost (const wchar_t *string);
|
||||
int AskWarnNoYes (char *stringId);
|
||||
int AskWarnNoYesString (const wchar_t *string);
|
||||
int AskWarnNoYesTopmost (char *stringId);
|
||||
int AskWarnOkCancel (char *stringId);
|
||||
int AskWarnCancelOk (char *stringId);
|
||||
int AskErrYesNo (char *stringId);
|
||||
int AskErrNoYes (char *stringId);
|
||||
int AskMultiChoice (void *strings[], BOOL bBold);
|
||||
BOOL ConfigWriteBegin ();
|
||||
BOOL ConfigWriteEnd ();
|
||||
BOOL ConfigWriteString (char *configKey, char *configValue);
|
||||
BOOL ConfigWriteInt (char *configKey, int configValue);
|
||||
int ConfigReadInt (char *configKey, int defaultValue);
|
||||
char *ConfigReadString (char *configKey, char *defaultValue, char *str, int maxLen);
|
||||
void RestoreDefaultKeyFilesParam (void);
|
||||
BOOL LoadDefaultKeyFilesParam (void);
|
||||
void Debug (char *format, ...);
|
||||
void DebugMsgBox (char *format, ...);
|
||||
BOOL IsOSAtLeast (OSVersionEnum reqMinOS);
|
||||
BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack);
|
||||
BOOL Is64BitOs ();
|
||||
BOOL IsServerOS ();
|
||||
BOOL IsHiddenOSRunning (void);
|
||||
BOOL EnableWow64FsRedirection (BOOL enable);
|
||||
BOOL RestartComputer (void);
|
||||
void Applink (char *dest, BOOL bSendOS, char *extraOutput);
|
||||
char *RelativePath2Absolute (char *szFileName);
|
||||
void HandleDriveNotReadyError ();
|
||||
BOOL CALLBACK CloseTCWindowsEnum( HWND hwnd, LPARAM lParam);
|
||||
BOOL CALLBACK FindTCWindowEnum (HWND hwnd, LPARAM lParam);
|
||||
BYTE *MapResource (char *resourceType, int resourceId, PDWORD size);
|
||||
void InconsistencyResolved (char *msg);
|
||||
void ReportUnexpectedState (char *techInfo);
|
||||
BOOL SelectMultipleFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory);
|
||||
BOOL SelectMultipleFilesNext (char *lpszFileName);
|
||||
void OpenOnlineHelp ();
|
||||
BOOL GetPartitionInfo (const char *deviceName, PPARTITION_INFORMATION rpartInfo);
|
||||
BOOL GetDeviceInfo (const char *deviceName, DISK_PARTITION_INFO_STRUCT *info);
|
||||
BOOL GetDriveGeometry (const char *deviceName, PDISK_GEOMETRY diskGeometry);
|
||||
BOOL IsVolumeDeviceHosted (const char *lpszDiskFile);
|
||||
int CompensateXDPI (int val);
|
||||
int CompensateYDPI (int val);
|
||||
int CompensateDPIFont (int val);
|
||||
int GetTextGfxWidth (HWND hwndDlgItem, const wchar_t *text, HFONT hFont);
|
||||
int GetTextGfxHeight (HWND hwndDlgItem, const wchar_t *text, HFONT hFont);
|
||||
BOOL ToHyperlink (HWND hwndDlg, UINT ctrlId);
|
||||
BOOL ToCustHyperlink (HWND hwndDlg, UINT ctrlId, HFONT hFont);
|
||||
void ToBootPwdField (HWND hwndDlg, UINT ctrlId);
|
||||
void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT hFont);
|
||||
BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize);
|
||||
BOOL DoDriverInstall (HWND hwndDlg);
|
||||
int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader);
|
||||
void CloseVolume (OpenVolumeContext *context);
|
||||
int ReEncryptVolumeHeader (char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, BOOL wipeMode);
|
||||
BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
|
||||
BOOL IsPagingFileWildcardActive ();
|
||||
BOOL DisablePagingFile ();
|
||||
BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL InitSecurityTokenLibrary ();
|
||||
BOOL FileHasReadOnlyAttribute (const char *path);
|
||||
BOOL IsFileOnReadOnlyFilesystem (const char *path);
|
||||
void CheckFilesystem (int driveNo, BOOL fixErrors);
|
||||
BOOL BufferContainsString (const byte *buffer, size_t bufferSize, const char *str);
|
||||
int AskNonSysInPlaceEncryptionResume ();
|
||||
BOOL RemoveDeviceWriteProtection (HWND hwndDlg, char *devicePath);
|
||||
void EnableElevatedCursorChange (HWND parent);
|
||||
BOOL DisableFileCompression (HANDLE file);
|
||||
BOOL VolumePathExists (char *volumePath);
|
||||
BOOL IsWindowsIsoBurnerAvailable ();
|
||||
BOOL LaunchWindowsIsoBurner (HWND hwnd, const char *isoPath);
|
||||
BOOL IsApplicationInstalled (const char *appName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct HostDevice
|
||||
{
|
||||
HostDevice ()
|
||||
:
|
||||
Bootable (false),
|
||||
ContainsSystem (false),
|
||||
DynamicVolume (false),
|
||||
Floppy (false),
|
||||
IsPartition (false),
|
||||
IsVirtualPartition (false),
|
||||
HasUnencryptedFilesystem (false),
|
||||
Removable (false),
|
||||
Size (0)
|
||||
{
|
||||
}
|
||||
|
||||
~HostDevice () { }
|
||||
|
||||
bool Bootable;
|
||||
bool ContainsSystem;
|
||||
bool DynamicVolume;
|
||||
bool Floppy;
|
||||
bool IsPartition;
|
||||
bool IsVirtualPartition;
|
||||
bool HasUnencryptedFilesystem;
|
||||
std::string MountPoint;
|
||||
std::wstring Name;
|
||||
std::string Path;
|
||||
bool Removable;
|
||||
uint64 Size;
|
||||
uint32 SystemNumber;
|
||||
|
||||
std::vector <HostDevice> Partitions;
|
||||
};
|
||||
|
||||
BOOL BrowseFilesInDir (HWND hwndDlg, char *stringId, char *initialDir, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter, const wchar_t *initialFileName = NULL, const wchar_t *defaultExtension = NULL);
|
||||
std::wstring SingleStringToWide (const std::string &singleString);
|
||||
std::wstring Utf8StringToWide (const std::string &utf8String);
|
||||
std::string WideToSingleString (const std::wstring &wideString);
|
||||
std::string WideToUtf8String (const std::wstring &wideString);
|
||||
std::string StringToUpperCase (const std::string &str);
|
||||
std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties = false, bool singleList = false, bool noFloppy = true, bool detectUnencryptedFilesystems = false);
|
||||
std::string ToUpperCase (const std::string &str);
|
||||
std::wstring GetWrongPasswordErrorMessage (HWND hwndDlg);
|
||||
std::string GetWindowsEdition ();
|
||||
std::string FitPathInGfxWidth (HWND hwnd, HFONT hFont, LONG width, const std::string &path);
|
||||
std::string GetServiceConfigPath (const char *fileName);
|
||||
std::string VolumeGuidPathToDevicePath (std::string volumeGuidPath);
|
||||
std::string HarddiskVolumePathToPartitionPath (const std::string &harddiskVolumePath);
|
||||
std::string FindLatestFileOrDirectory (const std::string &directory, const char *namePattern, bool findDirectory, bool findFile);
|
||||
std::string GetUserFriendlyVersionString (int version);
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // TC_HEADER_DLGCODE
|
507
src/Common/EncryptionThreadPool.c
Normal file
507
src/Common/EncryptionThreadPool.c
Normal file
@ -0,0 +1,507 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "EncryptionThreadPool.h"
|
||||
#include "Pkcs5.h"
|
||||
#ifdef DEVICE_DRIVER
|
||||
#include "Driver/Ntdriver.h"
|
||||
#endif
|
||||
|
||||
#define TC_ENC_THREAD_POOL_MAX_THREAD_COUNT 64
|
||||
#define TC_ENC_THREAD_POOL_QUEUE_SIZE (TC_ENC_THREAD_POOL_MAX_THREAD_COUNT * 2)
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
|
||||
#define TC_THREAD_HANDLE PKTHREAD
|
||||
#define TC_THREAD_PROC VOID
|
||||
|
||||
#define TC_SET_EVENT(EVENT) KeSetEvent (&EVENT, IO_DISK_INCREMENT, FALSE)
|
||||
#define TC_CLEAR_EVENT(EVENT) KeClearEvent (&EVENT)
|
||||
|
||||
#define TC_MUTEX FAST_MUTEX
|
||||
#define TC_ACQUIRE_MUTEX(MUTEX) ExAcquireFastMutex (MUTEX)
|
||||
#define TC_RELEASE_MUTEX(MUTEX) ExReleaseFastMutex (MUTEX)
|
||||
|
||||
#else // !DEVICE_DRIVER
|
||||
|
||||
#define TC_THREAD_HANDLE HANDLE
|
||||
#define TC_THREAD_PROC unsigned __stdcall
|
||||
|
||||
#define TC_SET_EVENT(EVENT) SetEvent (EVENT)
|
||||
#define TC_CLEAR_EVENT(EVENT) ResetEvent (EVENT)
|
||||
|
||||
#define TC_MUTEX HANDLE
|
||||
#define TC_ACQUIRE_MUTEX(MUTEX) WaitForSingleObject (*(MUTEX), INFINITE)
|
||||
#define TC_RELEASE_MUTEX(MUTEX) ReleaseMutex (*(MUTEX))
|
||||
|
||||
#endif // !DEVICE_DRIVER
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WorkItemFree,
|
||||
WorkItemReady,
|
||||
WorkItemBusy
|
||||
} WorkItemState;
|
||||
|
||||
|
||||
typedef struct EncryptionThreadPoolWorkItemStruct
|
||||
{
|
||||
WorkItemState State;
|
||||
EncryptionThreadPoolWorkType Type;
|
||||
|
||||
TC_EVENT ItemCompletedEvent;
|
||||
|
||||
struct EncryptionThreadPoolWorkItemStruct *FirstFragment;
|
||||
LONG OutstandingFragmentCount;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
PCRYPTO_INFO CryptoInfo;
|
||||
byte *Data;
|
||||
UINT64_STRUCT StartUnitNo;
|
||||
uint32 UnitCount;
|
||||
|
||||
} Encryption;
|
||||
|
||||
struct
|
||||
{
|
||||
TC_EVENT *CompletionEvent;
|
||||
LONG *CompletionFlag;
|
||||
char *DerivedKey;
|
||||
int IterationCount;
|
||||
TC_EVENT *NoOutstandingWorkItemEvent;
|
||||
LONG *OutstandingWorkItemCount;
|
||||
char *Password;
|
||||
int PasswordLength;
|
||||
int Pkcs5Prf;
|
||||
char *Salt;
|
||||
|
||||
} KeyDerivation;
|
||||
};
|
||||
|
||||
} EncryptionThreadPoolWorkItem;
|
||||
|
||||
|
||||
static volatile BOOL ThreadPoolRunning = FALSE;
|
||||
static volatile BOOL StopPending = FALSE;
|
||||
|
||||
static uint32 ThreadCount;
|
||||
static TC_THREAD_HANDLE ThreadHandles[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT];
|
||||
|
||||
static EncryptionThreadPoolWorkItem WorkItemQueue[TC_ENC_THREAD_POOL_QUEUE_SIZE];
|
||||
|
||||
static volatile int EnqueuePosition;
|
||||
static volatile int DequeuePosition;
|
||||
|
||||
static TC_MUTEX EnqueueMutex;
|
||||
static TC_MUTEX DequeueMutex;
|
||||
|
||||
static TC_EVENT WorkItemReadyEvent;
|
||||
static TC_EVENT WorkItemCompletedEvent;
|
||||
|
||||
|
||||
static WorkItemState GetWorkItemState (EncryptionThreadPoolWorkItem *workItem)
|
||||
{
|
||||
return InterlockedExchangeAdd ((LONG *) &workItem->State, 0);
|
||||
}
|
||||
|
||||
|
||||
static void SetWorkItemState (EncryptionThreadPoolWorkItem *workItem, WorkItemState newState)
|
||||
{
|
||||
InterlockedExchange ((LONG *) &workItem->State, (LONG) newState);
|
||||
}
|
||||
|
||||
|
||||
static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
|
||||
{
|
||||
EncryptionThreadPoolWorkItem *workItem;
|
||||
|
||||
while (!StopPending)
|
||||
{
|
||||
TC_ACQUIRE_MUTEX (&DequeueMutex);
|
||||
|
||||
workItem = &WorkItemQueue[DequeuePosition++];
|
||||
|
||||
if (DequeuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
|
||||
DequeuePosition = 0;
|
||||
|
||||
while (!StopPending && GetWorkItemState (workItem) != WorkItemReady)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemReadyEvent);
|
||||
}
|
||||
|
||||
SetWorkItemState (workItem, WorkItemBusy);
|
||||
|
||||
TC_RELEASE_MUTEX (&DequeueMutex);
|
||||
|
||||
if (StopPending)
|
||||
break;
|
||||
|
||||
switch (workItem->Type)
|
||||
{
|
||||
case DecryptDataUnitsWork:
|
||||
DecryptDataUnitsCurrentThread (workItem->Encryption.Data, &workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.CryptoInfo);
|
||||
break;
|
||||
|
||||
case EncryptDataUnitsWork:
|
||||
EncryptDataUnitsCurrentThread (workItem->Encryption.Data, &workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.CryptoInfo);
|
||||
break;
|
||||
|
||||
case DeriveKeyWork:
|
||||
switch (workItem->KeyDerivation.Pkcs5Prf)
|
||||
{
|
||||
case RIPEMD160:
|
||||
derive_key_ripemd160 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
derive_key_sha512 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
derive_key_whirlpool (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
case SHA1:
|
||||
derive_key_sha1 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
InterlockedExchange (workItem->KeyDerivation.CompletionFlag, TRUE);
|
||||
TC_SET_EVENT (*workItem->KeyDerivation.CompletionEvent);
|
||||
|
||||
if (InterlockedDecrement (workItem->KeyDerivation.OutstandingWorkItemCount) == 0)
|
||||
TC_SET_EVENT (*workItem->KeyDerivation.NoOutstandingWorkItemEvent);
|
||||
|
||||
SetWorkItemState (workItem, WorkItemFree);
|
||||
TC_SET_EVENT (WorkItemCompletedEvent);
|
||||
continue;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (workItem != workItem->FirstFragment)
|
||||
{
|
||||
SetWorkItemState (workItem, WorkItemFree);
|
||||
TC_SET_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
if (InterlockedDecrement (&workItem->FirstFragment->OutstandingFragmentCount) == 0)
|
||||
TC_SET_EVENT (workItem->FirstFragment->ItemCompletedEvent);
|
||||
}
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
PsTerminateSystemThread (STATUS_SUCCESS);
|
||||
#else
|
||||
_endthreadex (0);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
|
||||
{
|
||||
size_t cpuCount, i;
|
||||
|
||||
if (ThreadPoolRunning)
|
||||
return TRUE;
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
cpuCount = GetCpuCount();
|
||||
#else
|
||||
{
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetSystemInfo (&sysInfo);
|
||||
cpuCount = sysInfo.dwNumberOfProcessors;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cpuCount > encryptionFreeCpuCount)
|
||||
cpuCount -= encryptionFreeCpuCount;
|
||||
|
||||
if (cpuCount < 2)
|
||||
return TRUE;
|
||||
|
||||
if (cpuCount > TC_ENC_THREAD_POOL_MAX_THREAD_COUNT)
|
||||
cpuCount = TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
|
||||
|
||||
StopPending = FALSE;
|
||||
DequeuePosition = 0;
|
||||
EnqueuePosition = 0;
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
KeInitializeEvent (&WorkItemReadyEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent (&WorkItemCompletedEvent, SynchronizationEvent, FALSE);
|
||||
#else
|
||||
WorkItemReadyEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
if (!WorkItemReadyEvent)
|
||||
return FALSE;
|
||||
|
||||
WorkItemCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
if (!WorkItemCompletedEvent)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
ExInitializeFastMutex (&DequeueMutex);
|
||||
ExInitializeFastMutex (&EnqueueMutex);
|
||||
#else
|
||||
DequeueMutex = CreateMutex (NULL, FALSE, NULL);
|
||||
if (!DequeueMutex)
|
||||
return FALSE;
|
||||
|
||||
EnqueueMutex = CreateMutex (NULL, FALSE, NULL);
|
||||
if (!EnqueueMutex)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
memset (WorkItemQueue, 0, sizeof (WorkItemQueue));
|
||||
|
||||
for (i = 0; i < sizeof (WorkItemQueue) / sizeof (WorkItemQueue[0]); ++i)
|
||||
{
|
||||
WorkItemQueue[i].State = WorkItemFree;
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
KeInitializeEvent (&WorkItemQueue[i].ItemCompletedEvent, SynchronizationEvent, FALSE);
|
||||
#else
|
||||
WorkItemQueue[i].ItemCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
if (!WorkItemQueue[i].ItemCompletedEvent)
|
||||
{
|
||||
EncryptionThreadPoolStop();
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount)
|
||||
{
|
||||
#ifdef DEVICE_DRIVER
|
||||
if (!NT_SUCCESS (TCStartThread (EncryptionThreadProc, NULL, &ThreadHandles[ThreadCount])))
|
||||
#else
|
||||
if (!(ThreadHandles[ThreadCount] = (HANDLE) _beginthreadex (NULL, 0, EncryptionThreadProc, NULL, 0, NULL)))
|
||||
#endif
|
||||
{
|
||||
EncryptionThreadPoolStop();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPoolRunning = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void EncryptionThreadPoolStop ()
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!ThreadPoolRunning)
|
||||
return;
|
||||
|
||||
StopPending = TRUE;
|
||||
TC_SET_EVENT (WorkItemReadyEvent);
|
||||
|
||||
for (i = 0; i < ThreadCount; ++i)
|
||||
{
|
||||
#ifdef DEVICE_DRIVER
|
||||
TCStopThread (ThreadHandles[i], &WorkItemReadyEvent);
|
||||
#else
|
||||
TC_WAIT_EVENT (ThreadHandles[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
ThreadCount = 0;
|
||||
|
||||
#ifndef DEVICE_DRIVER
|
||||
CloseHandle (DequeueMutex);
|
||||
CloseHandle (EnqueueMutex);
|
||||
|
||||
CloseHandle (WorkItemReadyEvent);
|
||||
CloseHandle (WorkItemCompletedEvent);
|
||||
|
||||
for (i = 0; i < sizeof (WorkItemQueue) / sizeof (WorkItemQueue[0]); ++i)
|
||||
{
|
||||
if (WorkItemQueue[i].ItemCompletedEvent)
|
||||
CloseHandle (WorkItemQueue[i].ItemCompletedEvent);
|
||||
}
|
||||
#endif
|
||||
|
||||
ThreadPoolRunning = FALSE;
|
||||
}
|
||||
|
||||
|
||||
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey)
|
||||
{
|
||||
EncryptionThreadPoolWorkItem *workItem;
|
||||
|
||||
if (!ThreadPoolRunning)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
TC_ACQUIRE_MUTEX (&EnqueueMutex);
|
||||
|
||||
workItem = &WorkItemQueue[EnqueuePosition++];
|
||||
if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
|
||||
EnqueuePosition = 0;
|
||||
|
||||
while (GetWorkItemState (workItem) != WorkItemFree)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
workItem->Type = DeriveKeyWork;
|
||||
workItem->KeyDerivation.CompletionEvent = completionEvent;
|
||||
workItem->KeyDerivation.CompletionFlag = completionFlag;
|
||||
workItem->KeyDerivation.DerivedKey = derivedKey;
|
||||
workItem->KeyDerivation.IterationCount = iterationCount;
|
||||
workItem->KeyDerivation.NoOutstandingWorkItemEvent = noOutstandingWorkItemEvent;
|
||||
workItem->KeyDerivation.OutstandingWorkItemCount = outstandingWorkItemCount;
|
||||
workItem->KeyDerivation.Password = password;
|
||||
workItem->KeyDerivation.PasswordLength = passwordLength;
|
||||
workItem->KeyDerivation.Pkcs5Prf = pkcs5Prf;
|
||||
workItem->KeyDerivation.Salt = salt;
|
||||
|
||||
InterlockedIncrement (outstandingWorkItemCount);
|
||||
TC_CLEAR_EVENT (*noOutstandingWorkItemEvent);
|
||||
|
||||
SetWorkItemState (workItem, WorkItemReady);
|
||||
TC_SET_EVENT (WorkItemReadyEvent);
|
||||
TC_RELEASE_MUTEX (&EnqueueMutex);
|
||||
}
|
||||
|
||||
|
||||
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo)
|
||||
{
|
||||
uint32 fragmentCount;
|
||||
uint32 unitsPerFragment;
|
||||
uint32 remainder;
|
||||
|
||||
byte *fragmentData;
|
||||
uint64 fragmentStartUnitNo;
|
||||
|
||||
EncryptionThreadPoolWorkItem *workItem;
|
||||
EncryptionThreadPoolWorkItem *firstFragmentWorkItem;
|
||||
|
||||
if (unitCount == 0)
|
||||
return;
|
||||
|
||||
if (!ThreadPoolRunning || unitCount == 1)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DecryptDataUnitsWork:
|
||||
DecryptDataUnitsCurrentThread (data, startUnitNo, unitCount, cryptoInfo);
|
||||
break;
|
||||
|
||||
case EncryptDataUnitsWork:
|
||||
EncryptDataUnitsCurrentThread (data, startUnitNo, unitCount, cryptoInfo);
|
||||
break;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (unitCount <= ThreadCount)
|
||||
{
|
||||
fragmentCount = unitCount;
|
||||
unitsPerFragment = 1;
|
||||
remainder = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Note that it is not efficient to divide the data into fragments smaller than a few hundred bytes.
|
||||
The reason is that the overhead associated with thread handling would in most cases make a multi-threaded
|
||||
process actually slower than a single-threaded process. */
|
||||
|
||||
fragmentCount = ThreadCount;
|
||||
unitsPerFragment = unitCount / ThreadCount;
|
||||
remainder = unitCount % ThreadCount;
|
||||
|
||||
if (remainder > 0)
|
||||
++unitsPerFragment;
|
||||
}
|
||||
|
||||
fragmentData = data;
|
||||
fragmentStartUnitNo = startUnitNo->Value;
|
||||
|
||||
TC_ACQUIRE_MUTEX (&EnqueueMutex);
|
||||
firstFragmentWorkItem = &WorkItemQueue[EnqueuePosition];
|
||||
|
||||
while (GetWorkItemState (firstFragmentWorkItem) != WorkItemFree)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
firstFragmentWorkItem->OutstandingFragmentCount = fragmentCount;
|
||||
|
||||
while (fragmentCount-- > 0)
|
||||
{
|
||||
workItem = &WorkItemQueue[EnqueuePosition++];
|
||||
if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
|
||||
EnqueuePosition = 0;
|
||||
|
||||
while (GetWorkItemState (workItem) != WorkItemFree)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
workItem->Type = type;
|
||||
workItem->FirstFragment = firstFragmentWorkItem;
|
||||
|
||||
workItem->Encryption.CryptoInfo = cryptoInfo;
|
||||
workItem->Encryption.Data = fragmentData;
|
||||
workItem->Encryption.UnitCount = unitsPerFragment;
|
||||
workItem->Encryption.StartUnitNo.Value = fragmentStartUnitNo;
|
||||
|
||||
fragmentData += unitsPerFragment * ENCRYPTION_DATA_UNIT_SIZE;
|
||||
fragmentStartUnitNo += unitsPerFragment;
|
||||
|
||||
if (remainder > 0 && --remainder == 0)
|
||||
--unitsPerFragment;
|
||||
|
||||
SetWorkItemState (workItem, WorkItemReady);
|
||||
TC_SET_EVENT (WorkItemReadyEvent);
|
||||
}
|
||||
|
||||
TC_RELEASE_MUTEX (&EnqueueMutex);
|
||||
|
||||
TC_WAIT_EVENT (firstFragmentWorkItem->ItemCompletedEvent);
|
||||
SetWorkItemState (firstFragmentWorkItem, WorkItemFree);
|
||||
TC_SET_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
|
||||
size_t GetEncryptionThreadCount ()
|
||||
{
|
||||
return ThreadPoolRunning ? ThreadCount : 0;
|
||||
}
|
||||
|
||||
|
||||
size_t GetMaxEncryptionThreadCount ()
|
||||
{
|
||||
return TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
|
||||
}
|
||||
|
||||
|
||||
BOOL IsEncryptionThreadPoolRunning ()
|
||||
{
|
||||
return ThreadPoolRunning;
|
||||
}
|
38
src/Common/EncryptionThreadPool.h
Normal file
38
src/Common/EncryptionThreadPool.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_ENCRYPTION_THREAD_POOL
|
||||
#define TC_HEADER_ENCRYPTION_THREAD_POOL
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EncryptDataUnitsWork,
|
||||
DecryptDataUnitsWork,
|
||||
DeriveKeyWork
|
||||
} EncryptionThreadPoolWorkType;
|
||||
|
||||
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey);
|
||||
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo);
|
||||
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount);
|
||||
void EncryptionThreadPoolStop ();
|
||||
size_t GetEncryptionThreadCount ();
|
||||
size_t GetMaxEncryptionThreadCount ();
|
||||
BOOL IsEncryptionThreadPoolRunning ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_ENCRYPTION_THREAD_POOL
|
57
src/Common/Endian.c
Normal file
57
src/Common/Endian.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Common/Endian.h"
|
||||
|
||||
|
||||
unsigned __int16 MirrorBytes16 (unsigned __int16 x)
|
||||
{
|
||||
return (x << 8) | (x >> 8);
|
||||
}
|
||||
|
||||
|
||||
unsigned __int32 MirrorBytes32 (unsigned __int32 x)
|
||||
{
|
||||
unsigned __int32 n = (unsigned __int8) x;
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 8);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 16);
|
||||
return (n << 8) | (unsigned __int8) (x >> 24);
|
||||
}
|
||||
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
uint64 MirrorBytes64 (uint64 x)
|
||||
{
|
||||
uint64 n = (unsigned __int8) x;
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 8);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 16);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 24);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 32);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 40);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 48);
|
||||
return (n << 8) | (unsigned __int8) (x >> 56);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
LongReverse (unsigned __int32 *buffer, unsigned byteCount)
|
||||
{
|
||||
unsigned __int32 value;
|
||||
|
||||
byteCount /= sizeof (unsigned __int32);
|
||||
while (byteCount--)
|
||||
{
|
||||
value = *buffer;
|
||||
value = ((value & 0xFF00FF00L) >> 8) | \
|
||||
((value & 0x00FF00FFL) << 8);
|
||||
*buffer++ = (value << 16) | (value >> 16);
|
||||
}
|
||||
}
|
147
src/Common/Endian.h
Normal file
147
src/Common/Endian.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_ENDIAN_H
|
||||
#define TC_ENDIAN_H
|
||||
|
||||
#include "Common/Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# endif
|
||||
# ifndef BYTE_ORDER
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
# endif
|
||||
|
||||
#elif !defined(BYTE_ORDER)
|
||||
|
||||
# ifdef TC_MACOSX
|
||||
# include <machine/endian.h>
|
||||
# elif defined (TC_BSD)
|
||||
# include <sys/endian.h>
|
||||
# elif defined (TC_SOLARIS)
|
||||
# include <sys/types.h>
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# define BIG_ENDIAN 4321
|
||||
# ifdef _BIG_ENDIAN
|
||||
# define BYTE_ORDER BIG_ENDIAN
|
||||
# else
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
# endif
|
||||
# else
|
||||
# include <endian.h>
|
||||
# endif
|
||||
|
||||
# ifndef BYTE_ORDER
|
||||
# ifndef __BYTE_ORDER
|
||||
# error Byte order cannot be determined (BYTE_ORDER undefined)
|
||||
# endif
|
||||
|
||||
# define BYTE_ORDER __BYTE_ORDER
|
||||
# endif
|
||||
|
||||
# ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||
# endif
|
||||
|
||||
# ifndef BIG_ENDIAN
|
||||
# define BIG_ENDIAN __BIG_ENDIAN
|
||||
# endif
|
||||
|
||||
#endif // !BYTE_ORDER
|
||||
|
||||
/* Macros to read and write 16, 32, and 64-bit quantities in a portable manner.
|
||||
These functions are implemented as macros rather than true functions as
|
||||
the need to adjust the memory pointers makes them somewhat painful to call
|
||||
in user code */
|
||||
|
||||
#define mputInt64(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 56 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 48 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 40 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 32 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 24 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 16 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
|
||||
|
||||
#define mputLong(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 24 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 16 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
|
||||
|
||||
#define mputWord(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
|
||||
|
||||
#define mputByte(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) data
|
||||
|
||||
#define mputBytes(memPtr,data,len) \
|
||||
memcpy (memPtr,data,len); \
|
||||
memPtr += len;
|
||||
|
||||
#define mgetInt64(memPtr) \
|
||||
( memPtr += 8, ( ( unsigned __int64 ) memPtr[ -8 ] << 56 ) | ( ( unsigned __int64 ) memPtr[ -7 ] << 48 ) | \
|
||||
( ( unsigned __int64 ) memPtr[ -6 ] << 40 ) | ( ( unsigned __int64 ) memPtr[ -5 ] << 32 ) | \
|
||||
( ( unsigned __int64 ) memPtr[ -4 ] << 24 ) | ( ( unsigned __int64 ) memPtr[ -3 ] << 16 ) | \
|
||||
( ( unsigned __int64 ) memPtr[ -2 ] << 8 ) | ( unsigned __int64 ) memPtr[ -1 ] )
|
||||
|
||||
#define mgetLong(memPtr) \
|
||||
( memPtr += 4, ( ( unsigned __int32 ) memPtr[ -4 ] << 24 ) | ( ( unsigned __int32 ) memPtr[ -3 ] << 16 ) | \
|
||||
( ( unsigned __int32 ) memPtr[ -2 ] << 8 ) | ( unsigned __int32 ) memPtr[ -1 ] )
|
||||
|
||||
#define mgetWord(memPtr) \
|
||||
( memPtr += 2, ( unsigned short ) memPtr[ -2 ] << 8 ) | ( ( unsigned short ) memPtr[ -1 ] )
|
||||
|
||||
#define mgetByte(memPtr) \
|
||||
( ( unsigned char ) *memPtr++ )
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define LE16(x) MirrorBytes16(x)
|
||||
# define LE32(x) MirrorBytes32(x)
|
||||
# define LE64(x) MirrorBytes64(x)
|
||||
#else
|
||||
# define LE16(x) (x)
|
||||
# define LE32(x) (x)
|
||||
# define LE64(x) (x)
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define BE16(x) MirrorBytes16(x)
|
||||
# define BE32(x) MirrorBytes32(x)
|
||||
# define BE64(x) MirrorBytes64(x)
|
||||
#else
|
||||
# define BE16(x) (x)
|
||||
# define BE32(x) (x)
|
||||
# define BE64(x) (x)
|
||||
#endif
|
||||
|
||||
unsigned __int16 MirrorBytes16 (unsigned __int16 x);
|
||||
unsigned __int32 MirrorBytes32 (unsigned __int32 x);
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
uint64 MirrorBytes64 (uint64 x);
|
||||
#endif
|
||||
void LongReverse ( unsigned __int32 *buffer , unsigned byteCount );
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TC_ENDIAN_H */
|
81
src/Common/Exception.h
Normal file
81
src/Common/Exception.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_Exception
|
||||
#define TC_HEADER_Common_Exception
|
||||
|
||||
#include "Platform/PlatformBase.h"
|
||||
#include "Dlgcode.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
struct Exception
|
||||
{
|
||||
virtual void Show (HWND parent) const = 0;
|
||||
};
|
||||
|
||||
struct SystemException : public Exception
|
||||
{
|
||||
SystemException () : ErrorCode (GetLastError()) { }
|
||||
|
||||
void Show (HWND parent) const
|
||||
{
|
||||
SetLastError (ErrorCode);
|
||||
handleWin32Error (parent);
|
||||
}
|
||||
|
||||
DWORD ErrorCode;
|
||||
};
|
||||
|
||||
struct ErrorException : public Exception
|
||||
{
|
||||
ErrorException (char *langId) : ErrLangId (langId) { }
|
||||
ErrorException (const wstring &errMsg) : ErrMsg (errMsg) { }
|
||||
|
||||
void Show (HWND parent) const
|
||||
{
|
||||
if (ErrMsg.empty())
|
||||
::Error (ErrLangId);
|
||||
else
|
||||
::ErrorDirect (ErrMsg.c_str());
|
||||
}
|
||||
|
||||
char *ErrLangId;
|
||||
wstring ErrMsg;
|
||||
};
|
||||
|
||||
struct ParameterIncorrect : public Exception
|
||||
{
|
||||
ParameterIncorrect (const char *srcPos) : SrcPos (srcPos) { }
|
||||
|
||||
void Show (HWND parent) const
|
||||
{
|
||||
string msgBody = "Parameter incorrect.\n\n\n(If you report a bug in connection with this, please include the following technical information in the bug report:\n" + string (SrcPos) + ")";
|
||||
MessageBox (parent, msgBody.c_str(), "TrueCrypt", MB_ICONERROR | MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
const char *SrcPos;
|
||||
};
|
||||
|
||||
struct TimeOut : public Exception
|
||||
{
|
||||
TimeOut (const char *srcPos) { }
|
||||
void Show (HWND parent) const { ErrorDirect (L"Timeout"); }
|
||||
};
|
||||
|
||||
struct UserAbort : public Exception
|
||||
{
|
||||
UserAbort (const char *srcPos) { }
|
||||
void Show (HWND parent) const { }
|
||||
};
|
||||
}
|
||||
|
||||
#define throw_sys_if(condition) do { if (condition) throw SystemException(); } while (false)
|
||||
|
||||
|
||||
#endif // TC_HEADER_Common_Exception
|
445
src/Common/Fat.c
Normal file
445
src/Common/Fat.c
Normal file
@ -0,0 +1,445 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include "Crypto.h"
|
||||
#include "Common/Endian.h"
|
||||
#include "Format.h"
|
||||
#include "Fat.h"
|
||||
#include "Progress.h"
|
||||
#include "Random.h"
|
||||
#include "Volumes.h"
|
||||
|
||||
void
|
||||
GetFatParams (fatparams * ft)
|
||||
{
|
||||
uint64 volumeSize = (uint64) ft->num_sectors * ft->sector_size;
|
||||
unsigned int fatsecs;
|
||||
|
||||
if(ft->cluster_size == 0) // 'Default' cluster size
|
||||
{
|
||||
uint32 clusterSize;
|
||||
|
||||
// Determine optimal cluster size to minimize FAT size (mounting delay), maximize number of files, keep 4 KB alignment, etc.
|
||||
if (volumeSize >= 2 * BYTES_PER_TB)
|
||||
clusterSize = 256 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 512 * BYTES_PER_GB)
|
||||
clusterSize = 128 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 128 * BYTES_PER_GB)
|
||||
clusterSize = 64 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 64 * BYTES_PER_GB)
|
||||
clusterSize = 32 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 32 * BYTES_PER_GB)
|
||||
clusterSize = 16 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 16 * BYTES_PER_GB)
|
||||
clusterSize = 8 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 512 * BYTES_PER_MB)
|
||||
clusterSize = 4 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 256 * BYTES_PER_MB)
|
||||
clusterSize = 2 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 1 * BYTES_PER_MB)
|
||||
clusterSize = 1 * BYTES_PER_KB;
|
||||
else
|
||||
clusterSize = 512;
|
||||
|
||||
ft->cluster_size = clusterSize / ft->sector_size;
|
||||
|
||||
if (ft->cluster_size == 0)
|
||||
ft->cluster_size = 1;
|
||||
|
||||
if (ft->cluster_size * ft->sector_size > TC_MAX_FAT_CLUSTER_SIZE)
|
||||
ft->cluster_size = TC_MAX_FAT_CLUSTER_SIZE / ft->sector_size;
|
||||
|
||||
if (ft->cluster_size > 128)
|
||||
ft->cluster_size = 128;
|
||||
}
|
||||
|
||||
if (volumeSize <= TC_MAX_FAT_CLUSTER_SIZE * 4)
|
||||
ft->cluster_size = 1;
|
||||
|
||||
// Geometry always set to SECTORS/1/1
|
||||
ft->secs_track = 1;
|
||||
ft->heads = 1;
|
||||
|
||||
ft->dir_entries = 512;
|
||||
ft->fats = 2;
|
||||
ft->media = 0xf8;
|
||||
ft->hidden = 0;
|
||||
|
||||
ft->size_root_dir = ft->dir_entries * 32;
|
||||
|
||||
// FAT12
|
||||
ft->size_fat = 12;
|
||||
ft->reserved = 2;
|
||||
fatsecs = ft->num_sectors - (ft->size_root_dir + ft->sector_size - 1) / ft->sector_size - ft->reserved;
|
||||
ft->cluster_count = (int) (((__int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size));
|
||||
ft->fat_length = (((ft->cluster_count * 3 + 1) >> 1) + ft->sector_size - 1) / ft->sector_size;
|
||||
|
||||
if (ft->cluster_count >= 4085) // FAT16
|
||||
{
|
||||
ft->size_fat = 16;
|
||||
ft->reserved = 2;
|
||||
fatsecs = ft->num_sectors - (ft->size_root_dir + ft->sector_size - 1) / ft->sector_size - ft->reserved;
|
||||
ft->cluster_count = (int) (((__int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size));
|
||||
ft->fat_length = (ft->cluster_count * 2 + ft->sector_size - 1) / ft->sector_size;
|
||||
}
|
||||
|
||||
if(ft->cluster_count >= 65525) // FAT32
|
||||
{
|
||||
ft->size_fat = 32;
|
||||
ft->reserved = 32 - 1;
|
||||
|
||||
do
|
||||
{
|
||||
ft->reserved++;
|
||||
|
||||
fatsecs = ft->num_sectors - ft->reserved;
|
||||
ft->size_root_dir = ft->cluster_size * ft->sector_size;
|
||||
ft->cluster_count = (int) (((__int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size));
|
||||
ft->fat_length = (ft->cluster_count * 4 + ft->sector_size - 1) / ft->sector_size;
|
||||
|
||||
// Align data area on TC_MAX_VOLUME_SECTOR_SIZE
|
||||
|
||||
} while (ft->sector_size == TC_SECTOR_SIZE_LEGACY
|
||||
&& (ft->reserved * ft->sector_size + ft->fat_length * ft->fats * ft->sector_size) % TC_MAX_VOLUME_SECTOR_SIZE != 0);
|
||||
}
|
||||
|
||||
ft->cluster_count -= ft->fat_length * ft->fats / ft->cluster_size;
|
||||
|
||||
if (ft->num_sectors >= 65536 || ft->size_fat == 32)
|
||||
{
|
||||
ft->sectors = 0;
|
||||
ft->total_sect = ft->num_sectors;
|
||||
}
|
||||
else
|
||||
{
|
||||
ft->sectors = (uint16) ft->num_sectors;
|
||||
ft->total_sect = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PutBoot (fatparams * ft, unsigned char *boot)
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
boot[cnt++] = 0xeb; /* boot jump */
|
||||
boot[cnt++] = 0x3c;
|
||||
boot[cnt++] = 0x90;
|
||||
memcpy (boot + cnt, "MSDOS5.0", 8); /* system id */
|
||||
cnt += 8;
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->sector_size); /* bytes per sector */
|
||||
cnt += 2;
|
||||
boot[cnt++] = (__int8) ft->cluster_size; /* sectors per cluster */
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->reserved); /* reserved sectors */
|
||||
cnt += 2;
|
||||
boot[cnt++] = (__int8) ft->fats; /* 2 fats */
|
||||
|
||||
if(ft->size_fat == 32)
|
||||
{
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->dir_entries); /* 512 root entries */
|
||||
cnt += 2;
|
||||
}
|
||||
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->sectors); /* # sectors */
|
||||
cnt += 2;
|
||||
boot[cnt++] = (__int8) ft->media; /* media byte */
|
||||
|
||||
if(ft->size_fat == 32)
|
||||
{
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(__int16 *)(boot + cnt) = LE16((uint16) ft->fat_length); /* fat size */
|
||||
cnt += 2;
|
||||
}
|
||||
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->secs_track); /* # sectors per track */
|
||||
cnt += 2;
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->heads); /* # heads */
|
||||
cnt += 2;
|
||||
*(__int32 *)(boot + cnt) = LE32(ft->hidden); /* # hidden sectors */
|
||||
cnt += 4;
|
||||
*(__int32 *)(boot + cnt) = LE32(ft->total_sect); /* # huge sectors */
|
||||
cnt += 4;
|
||||
|
||||
if(ft->size_fat == 32)
|
||||
{
|
||||
*(__int32 *)(boot + cnt) = LE32(ft->fat_length); cnt += 4; /* fat size 32 */
|
||||
boot[cnt++] = 0x00; /* ExtFlags */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00; /* FSVer */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x02; /* RootClus */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x01; /* FSInfo */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x06; /* BkBootSec */
|
||||
boot[cnt++] = 0x00;
|
||||
memset(boot+cnt, 0, 12); cnt+=12; /* Reserved */
|
||||
}
|
||||
|
||||
boot[cnt++] = 0x00; /* drive number */ // FIXED 80 > 00
|
||||
boot[cnt++] = 0x00; /* reserved */
|
||||
boot[cnt++] = 0x29; /* boot sig */
|
||||
|
||||
memcpy (boot + cnt, ft->volume_id, 4); /* vol id */
|
||||
cnt += 4;
|
||||
|
||||
memcpy (boot + cnt, ft->volume_name, 11); /* vol title */
|
||||
cnt += 11;
|
||||
|
||||
switch(ft->size_fat) /* filesystem type */
|
||||
{
|
||||
case 12: memcpy (boot + cnt, "FAT12 ", 8); break;
|
||||
case 16: memcpy (boot + cnt, "FAT16 ", 8); break;
|
||||
case 32: memcpy (boot + cnt, "FAT32 ", 8); break;
|
||||
}
|
||||
cnt += 8;
|
||||
|
||||
memset (boot + cnt, 0, ft->size_fat==32 ? 420:448); /* boot code */
|
||||
cnt += ft->size_fat==32 ? 420:448;
|
||||
boot[cnt++] = 0x55;
|
||||
boot[cnt++] = 0xaa; /* boot sig */
|
||||
}
|
||||
|
||||
|
||||
/* FAT32 FSInfo */
|
||||
static void PutFSInfo (unsigned char *sector, fatparams *ft)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
sector[3]=0x41; /* LeadSig */
|
||||
sector[2]=0x61;
|
||||
sector[1]=0x52;
|
||||
sector[0]=0x52;
|
||||
sector[484+3]=0x61; /* StrucSig */
|
||||
sector[484+2]=0x41;
|
||||
sector[484+1]=0x72;
|
||||
sector[484+0]=0x72;
|
||||
|
||||
// Free cluster count
|
||||
*(uint32 *)(sector + 488) = LE32 (ft->cluster_count - ft->size_root_dir / ft->sector_size / ft->cluster_size);
|
||||
|
||||
// Next free cluster
|
||||
*(uint32 *)(sector + 492) = LE32 (2);
|
||||
|
||||
sector[508+3]=0xaa; /* TrailSig */
|
||||
sector[508+2]=0x55;
|
||||
sector[508+1]=0x00;
|
||||
sector[508+0]=0x00;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FormatFat (unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat)
|
||||
{
|
||||
int write_buf_cnt = 0;
|
||||
char sector[TC_MAX_VOLUME_SECTOR_SIZE], *write_buf;
|
||||
unsigned __int64 nSecNo = startSector;
|
||||
int x, n;
|
||||
int retVal;
|
||||
char temporaryKey[MASTER_KEYDATA_SIZE];
|
||||
|
||||
LARGE_INTEGER startOffset;
|
||||
LARGE_INTEGER newOffset;
|
||||
|
||||
// Seek to start sector
|
||||
startOffset.QuadPart = startSector * ft->sector_size;
|
||||
if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
|
||||
|| newOffset.QuadPart != startOffset.QuadPart)
|
||||
{
|
||||
return ERR_VOL_SEEKING;
|
||||
}
|
||||
|
||||
/* Write the data area */
|
||||
|
||||
write_buf = (char *)TCalloc (FormatWriteBufferSize);
|
||||
if (!write_buf)
|
||||
return ERR_OUTOFMEMORY;
|
||||
|
||||
memset (sector, 0, ft->sector_size);
|
||||
|
||||
RandgetBytes (ft->volume_id, sizeof (ft->volume_id), FALSE);
|
||||
|
||||
PutBoot (ft, (unsigned char *) sector);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
/* fat32 boot area */
|
||||
if (ft->size_fat == 32)
|
||||
{
|
||||
/* fsinfo */
|
||||
PutFSInfo((unsigned char *) sector, ft);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
/* reserved */
|
||||
while (nSecNo - startSector < 6)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
sector[508+3]=0xaa; /* TrailSig */
|
||||
sector[508+2]=0x55;
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* bootsector backup */
|
||||
memset (sector, 0, ft->sector_size);
|
||||
PutBoot (ft, (unsigned char *) sector);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
PutFSInfo((unsigned char *) sector, ft);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* reserved */
|
||||
while (nSecNo - startSector < (unsigned int)ft->reserved)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* write fat */
|
||||
for (x = 1; x <= ft->fats; x++)
|
||||
{
|
||||
for (n = 0; n < ft->fat_length; n++)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
unsigned char fat_sig[12];
|
||||
if (ft->size_fat == 32)
|
||||
{
|
||||
fat_sig[0] = (unsigned char) ft->media;
|
||||
fat_sig[1] = fat_sig[2] = 0xff;
|
||||
fat_sig[3] = 0x0f;
|
||||
fat_sig[4] = fat_sig[5] = fat_sig[6] = 0xff;
|
||||
fat_sig[7] = 0x0f;
|
||||
fat_sig[8] = fat_sig[9] = fat_sig[10] = 0xff;
|
||||
fat_sig[11] = 0x0f;
|
||||
memcpy (sector, fat_sig, 12);
|
||||
}
|
||||
else if (ft->size_fat == 16)
|
||||
{
|
||||
fat_sig[0] = (unsigned char) ft->media;
|
||||
fat_sig[1] = 0xff;
|
||||
fat_sig[2] = 0xff;
|
||||
fat_sig[3] = 0xff;
|
||||
memcpy (sector, fat_sig, 4);
|
||||
}
|
||||
else if (ft->size_fat == 12)
|
||||
{
|
||||
fat_sig[0] = (unsigned char) ft->media;
|
||||
fat_sig[1] = 0xff;
|
||||
fat_sig[2] = 0xff;
|
||||
fat_sig[3] = 0x00;
|
||||
memcpy (sector, fat_sig, 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* write rootdir */
|
||||
for (x = 0; x < ft->size_root_dir / ft->sector_size; x++)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
}
|
||||
|
||||
/* Fill the rest of the data area with random data */
|
||||
|
||||
if(!quickFormat)
|
||||
{
|
||||
if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
|
||||
goto fail;
|
||||
|
||||
/* Generate a random temporary key set to be used for "dummy" encryption that will fill
|
||||
the free disk space (data area) with random data. This is necessary for plausible
|
||||
deniability of hidden volumes (and also reduces the amount of predictable plaintext
|
||||
within the volume). */
|
||||
|
||||
// Temporary master key
|
||||
if (!RandgetBytes (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE))
|
||||
goto fail;
|
||||
|
||||
// Temporary secondary key (XTS mode)
|
||||
if (!RandgetBytes (cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE))
|
||||
goto fail;
|
||||
|
||||
retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
|
||||
if (retVal != ERR_SUCCESS)
|
||||
{
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return retVal;
|
||||
}
|
||||
if (!EAInitMode (cryptoInfo))
|
||||
{
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return ERR_MODE_INIT_FAILED;
|
||||
}
|
||||
|
||||
x = ft->num_sectors - ft->reserved - ft->size_root_dir / ft->sector_size - ft->fat_length * 2;
|
||||
while (x--)
|
||||
{
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
UpdateProgressBar (nSecNo * ft->sector_size);
|
||||
}
|
||||
else
|
||||
UpdateProgressBar ((uint64) ft->num_sectors * ft->sector_size);
|
||||
|
||||
if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
|
||||
goto fail;
|
||||
|
||||
TCfree (write_buf);
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
||||
TCfree (write_buf);
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return ERR_OS_ERROR;
|
||||
}
|
67
src/Common/Fat.h
Normal file
67
src/Common/Fat.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
typedef struct fatparams_t
|
||||
{
|
||||
char volume_name[11];
|
||||
byte volume_id[4];
|
||||
unsigned int num_sectors; /* total number of sectors */
|
||||
int cluster_count; /* number of clusters */
|
||||
int size_root_dir; /* size of the root directory in bytes */
|
||||
int size_fat; /* size of FAT */
|
||||
int fats;
|
||||
int media;
|
||||
int cluster_size;
|
||||
int fat_length;
|
||||
uint16 dir_entries;
|
||||
uint16 sector_size;
|
||||
int hidden;
|
||||
__int16 reserved;
|
||||
uint16 sectors;
|
||||
unsigned int total_sect;
|
||||
|
||||
uint16 heads;
|
||||
uint16 secs_track;
|
||||
|
||||
} fatparams;
|
||||
|
||||
|
||||
struct msdos_boot_sector
|
||||
{
|
||||
unsigned char boot_jump[3]; /* Boot strap short or near jump */
|
||||
char system_id[8]; /* Name - can be used to special case
|
||||
partition manager volumes */
|
||||
unsigned char sector_size[2]; /* bytes per logical sector */
|
||||
unsigned char cluster_size; /* sectors/cluster */
|
||||
unsigned short reserved;/* reserved sectors */
|
||||
unsigned char fats; /* number of FATs */
|
||||
unsigned char dir_entries[2]; /* root directory entries */
|
||||
unsigned char sectors[2]; /* number of sectors */
|
||||
unsigned char media; /* media code */
|
||||
unsigned short fat_length; /* sectors/FAT */
|
||||
unsigned short secs_track; /* sectors per track */
|
||||
unsigned short heads; /* number of heads */
|
||||
unsigned __int32 hidden; /* hidden sectors */
|
||||
unsigned __int32 total_sect; /* number of sectors (if sectors == 0) */
|
||||
unsigned char drive_number; /* BIOS drive number */
|
||||
unsigned char RESERVED; /* Unused */
|
||||
unsigned char ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */
|
||||
unsigned char volume_id[4]; /* Volume ID number */
|
||||
char volume_label[11]; /* Volume label */
|
||||
char fs_type[8]; /* Typically FAT12, FAT16, or FAT32 */
|
||||
unsigned char boot_code[448]; /* Boot code (or message) */
|
||||
unsigned short boot_sign; /* 0xAA55 */
|
||||
};
|
||||
|
||||
|
||||
void GetFatParams ( fatparams *ft );
|
||||
void PutBoot ( fatparams *ft , unsigned char *boot );
|
||||
int FormatFat (unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat);
|
1010
src/Common/Format.c
Normal file
1010
src/Common/Format.c
Normal file
File diff suppressed because it is too large
Load Diff
68
src/Common/Format.h
Normal file
68
src/Common/Format.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_Format
|
||||
#define TC_HEADER_Format
|
||||
|
||||
#include "Password.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// FMIFS
|
||||
typedef BOOLEAN (__stdcall *PFMIFSCALLBACK)( int command, DWORD subCommand, PVOID parameter );
|
||||
typedef VOID (__stdcall *PFORMATEX)( PWCHAR DriveRoot, DWORD MediaFlag, PWCHAR Format, PWCHAR Label, BOOL QuickFormat, DWORD ClusterSize, PFMIFSCALLBACK Callback );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL bDevice;
|
||||
BOOL hiddenVol;
|
||||
char *volumePath;
|
||||
unsigned __int64 size;
|
||||
unsigned __int64 hiddenVolHostSize;
|
||||
int ea;
|
||||
int pkcs5;
|
||||
uint32 headerFlags;
|
||||
int fileSystem;
|
||||
int clusterSize;
|
||||
BOOL sparseFileSwitch;
|
||||
BOOL quickFormat;
|
||||
int sectorSize;
|
||||
int *realClusterSize;
|
||||
Password *password;
|
||||
HWND hwndDlg;
|
||||
}
|
||||
FORMAT_VOL_PARAMETERS;
|
||||
|
||||
#define FMIFS_DONE 0xB
|
||||
#define FMIFS_HARDDISK 0xC
|
||||
|
||||
extern int FormatWriteBufferSize;
|
||||
|
||||
int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams);
|
||||
BOOL FormatNtfs (int driveNo, int clusterSize);
|
||||
uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize);
|
||||
int FormatNoFs (unsigned __int64 startSector, __int64 num_sectors, void *dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat);
|
||||
BOOL WriteSector ( void *dev , char *sector , char *write_buf , int *write_buf_cnt , __int64 *nSecNo , PCRYPTO_INFO cryptoInfo );
|
||||
BOOL FlushFormatWriteBuffer (void *dev, char *write_buf, int *write_buf_cnt, __int64 *nSecNo, PCRYPTO_INFO cryptoInfo);
|
||||
static BOOL StartFormatWriteThread ();
|
||||
static void StopFormatWriteThread ();
|
||||
|
||||
#define FILESYS_NONE 0
|
||||
#define FILESYS_FAT 1
|
||||
#define FILESYS_NTFS 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_Format
|
894
src/Common/GfMul.c
Normal file
894
src/Common/GfMul.c
Normal file
@ -0,0 +1,894 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software is allowed (with or without
|
||||
changes) provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 31/01/2004
|
||||
|
||||
My thanks to John Viega and David McGrew for their support in developing
|
||||
this code and to David for testing it on a big-endain system.
|
||||
*/
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Portions Copyright (c) 2005 TrueCrypt Developers Association
|
||||
|
||||
Changes:
|
||||
|
||||
- Added multiplication in the finite field GF(2^128) optimized for
|
||||
cases involving a 64-bit operand.
|
||||
|
||||
- Added multiplication in the finite field GF(2^64).
|
||||
|
||||
- Added MSB-first mode.
|
||||
|
||||
- Added basic test algorithms.
|
||||
|
||||
- Removed GCM.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include "GfMul.h"
|
||||
#include "Tcdefs.h"
|
||||
#include "Common/Endian.h"
|
||||
|
||||
/* BUFFER_ALIGN32 or BUFFER_ALIGN64 must be defined at this point to */
|
||||
/* enable faster operation by taking advantage of memory aligned values */
|
||||
/* NOTE: the BUFFER_ALIGN64 option has not been tested extensively */
|
||||
|
||||
#define BUFFER_ALIGN32
|
||||
#define UNROLL_LOOPS /* define to unroll some loops */
|
||||
#define IN_LINES /* define to use inline functions */
|
||||
/* in place of macros */
|
||||
|
||||
#define mode(x) GM_##x
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef unsigned __int32 mode(32t);
|
||||
typedef uint64 mode(64t);
|
||||
|
||||
#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma intrinsic(memcpy)
|
||||
#define in_line __inline
|
||||
#else
|
||||
#define in_line
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
#define rotl32 _lrotl
|
||||
#define rotr32 _lrotr
|
||||
#else
|
||||
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
#endif
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
|
||||
#define SWAP_BYTES
|
||||
#else
|
||||
#undef SWAP_BYTES
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
|
||||
#if defined ( IN_LINES )
|
||||
|
||||
in_line void bsw_32(void * p, unsigned int n)
|
||||
{ unsigned int i = n;
|
||||
while(i--)
|
||||
((mode(32t)*)p)[i] = bswap_32(((mode(32t)*)p)[i]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((mode(32t)*)p)[_i] = bswap_32(((mode(32t)*)p)[_i]); }
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
|
||||
/* These values are used to detect long word alignment in order */
|
||||
/* to speed up some GCM buffer operations. This facility may */
|
||||
/* not work on some machines */
|
||||
|
||||
#define lp08(x) ((unsigned char*)(x))
|
||||
#define lp32(x) ((mode(32t)*)(x))
|
||||
#define lp64(x) ((mode(64t)*)(x))
|
||||
|
||||
#define A32_MASK 3
|
||||
#define A64_MASK 7
|
||||
#define aligned32(x) (!(((mode(32t))(x)) & A32_MASK))
|
||||
#define aligned64(x) (!(((mode(32t))(x)) & A64_MASK))
|
||||
|
||||
#if defined( BUFFER_ALIGN32 )
|
||||
|
||||
#define ADR_MASK A32_MASK
|
||||
#define aligned aligned32
|
||||
#define lp lp32
|
||||
#define lp_inc 4
|
||||
|
||||
#if defined( IN_LINES )
|
||||
|
||||
in_line void move_block_aligned( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1],
|
||||
lp32(p)[2] = lp32(q)[2], lp32(p)[3] = lp32(q)[3];
|
||||
}
|
||||
|
||||
in_line void move_block_aligned64( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1];
|
||||
}
|
||||
|
||||
in_line void xor_block_aligned( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1],
|
||||
lp32(p)[2] ^= lp32(q)[2], lp32(p)[3] ^= lp32(q)[3];
|
||||
}
|
||||
|
||||
in_line void xor_block_aligned64( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define move_block_aligned(p,q) \
|
||||
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1], \
|
||||
lp32(p)[2] = lp32(q)[2], lp32(p)[3] = lp32(q)[3]
|
||||
|
||||
#define xor_block_aligned(p,q) \
|
||||
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1], \
|
||||
lp32(p)[2] ^= lp32(q)[2], lp32(p)[3] ^= lp32(q)[3]
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined( BUFFER_ALIGN64 )
|
||||
|
||||
#define ADR_MASK A64_MASK
|
||||
#define aligned aligned64
|
||||
#define lp lp64
|
||||
#define lp_inc 8
|
||||
|
||||
#define move_block_aligned(p,q) \
|
||||
lp64(p)[0] = lp64(q)[0], lp64(p)[1] = lp64(q)[1]
|
||||
|
||||
#define xor_block_aligned(p,q) \
|
||||
lp64(p)[0] ^= lp64(q)[0], lp64(p)[1] ^= lp64(q)[1]
|
||||
|
||||
#else
|
||||
#define aligned(x) 0
|
||||
#endif
|
||||
|
||||
#define move_block(p,q) memcpy((p), (q), BLOCK_LEN)
|
||||
|
||||
#define xor_block(p,q) \
|
||||
lp08(p)[ 0] ^= lp08(q)[ 0], lp08(p)[ 1] ^= lp08(q)[ 1], \
|
||||
lp08(p)[ 2] ^= lp08(q)[ 2], lp08(p)[ 3] ^= lp08(q)[ 3], \
|
||||
lp08(p)[ 4] ^= lp08(q)[ 4], lp08(p)[ 5] ^= lp08(q)[ 5], \
|
||||
lp08(p)[ 6] ^= lp08(q)[ 6], lp08(p)[ 7] ^= lp08(q)[ 7], \
|
||||
lp08(p)[ 8] ^= lp08(q)[ 8], lp08(p)[ 9] ^= lp08(q)[ 9], \
|
||||
lp08(p)[10] ^= lp08(q)[10], lp08(p)[11] ^= lp08(q)[11], \
|
||||
lp08(p)[12] ^= lp08(q)[12], lp08(p)[13] ^= lp08(q)[13], \
|
||||
lp08(p)[14] ^= lp08(q)[14], lp08(p)[15] ^= lp08(q)[15]
|
||||
|
||||
|
||||
#define gf_dat(q) {\
|
||||
q(0x00), q(0x01), q(0x02), q(0x03), q(0x04), q(0x05), q(0x06), q(0x07),\
|
||||
q(0x08), q(0x09), q(0x0a), q(0x0b), q(0x0c), q(0x0d), q(0x0e), q(0x0f),\
|
||||
q(0x10), q(0x11), q(0x12), q(0x13), q(0x14), q(0x15), q(0x16), q(0x17),\
|
||||
q(0x18), q(0x19), q(0x1a), q(0x1b), q(0x1c), q(0x1d), q(0x1e), q(0x1f),\
|
||||
q(0x20), q(0x21), q(0x22), q(0x23), q(0x24), q(0x25), q(0x26), q(0x27),\
|
||||
q(0x28), q(0x29), q(0x2a), q(0x2b), q(0x2c), q(0x2d), q(0x2e), q(0x2f),\
|
||||
q(0x30), q(0x31), q(0x32), q(0x33), q(0x34), q(0x35), q(0x36), q(0x37),\
|
||||
q(0x38), q(0x39), q(0x3a), q(0x3b), q(0x3c), q(0x3d), q(0x3e), q(0x3f),\
|
||||
q(0x40), q(0x41), q(0x42), q(0x43), q(0x44), q(0x45), q(0x46), q(0x47),\
|
||||
q(0x48), q(0x49), q(0x4a), q(0x4b), q(0x4c), q(0x4d), q(0x4e), q(0x4f),\
|
||||
q(0x50), q(0x51), q(0x52), q(0x53), q(0x54), q(0x55), q(0x56), q(0x57),\
|
||||
q(0x58), q(0x59), q(0x5a), q(0x5b), q(0x5c), q(0x5d), q(0x5e), q(0x5f),\
|
||||
q(0x60), q(0x61), q(0x62), q(0x63), q(0x64), q(0x65), q(0x66), q(0x67),\
|
||||
q(0x68), q(0x69), q(0x6a), q(0x6b), q(0x6c), q(0x6d), q(0x6e), q(0x6f),\
|
||||
q(0x70), q(0x71), q(0x72), q(0x73), q(0x74), q(0x75), q(0x76), q(0x77),\
|
||||
q(0x78), q(0x79), q(0x7a), q(0x7b), q(0x7c), q(0x7d), q(0x7e), q(0x7f),\
|
||||
q(0x80), q(0x81), q(0x82), q(0x83), q(0x84), q(0x85), q(0x86), q(0x87),\
|
||||
q(0x88), q(0x89), q(0x8a), q(0x8b), q(0x8c), q(0x8d), q(0x8e), q(0x8f),\
|
||||
q(0x90), q(0x91), q(0x92), q(0x93), q(0x94), q(0x95), q(0x96), q(0x97),\
|
||||
q(0x98), q(0x99), q(0x9a), q(0x9b), q(0x9c), q(0x9d), q(0x9e), q(0x9f),\
|
||||
q(0xa0), q(0xa1), q(0xa2), q(0xa3), q(0xa4), q(0xa5), q(0xa6), q(0xa7),\
|
||||
q(0xa8), q(0xa9), q(0xaa), q(0xab), q(0xac), q(0xad), q(0xae), q(0xaf),\
|
||||
q(0xb0), q(0xb1), q(0xb2), q(0xb3), q(0xb4), q(0xb5), q(0xb6), q(0xb7),\
|
||||
q(0xb8), q(0xb9), q(0xba), q(0xbb), q(0xbc), q(0xbd), q(0xbe), q(0xbf),\
|
||||
q(0xc0), q(0xc1), q(0xc2), q(0xc3), q(0xc4), q(0xc5), q(0xc6), q(0xc7),\
|
||||
q(0xc8), q(0xc9), q(0xca), q(0xcb), q(0xcc), q(0xcd), q(0xce), q(0xcf),\
|
||||
q(0xd0), q(0xd1), q(0xd2), q(0xd3), q(0xd4), q(0xd5), q(0xd6), q(0xd7),\
|
||||
q(0xd8), q(0xd9), q(0xda), q(0xdb), q(0xdc), q(0xdd), q(0xde), q(0xdf),\
|
||||
q(0xe0), q(0xe1), q(0xe2), q(0xe3), q(0xe4), q(0xe5), q(0xe6), q(0xe7),\
|
||||
q(0xe8), q(0xe9), q(0xea), q(0xeb), q(0xec), q(0xed), q(0xee), q(0xef),\
|
||||
q(0xf0), q(0xf1), q(0xf2), q(0xf3), q(0xf4), q(0xf5), q(0xf6), q(0xf7),\
|
||||
q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) }
|
||||
|
||||
/* given the value i in 0..255 as the byte overflow when a a field */
|
||||
/* element in GHASH is multipled by x^8, this function will return */
|
||||
/* the values that are generated in the lo 16-bit word of the field */
|
||||
/* value by applying the modular polynomial. The values lo_byte and */
|
||||
/* hi_byte are returned via the macro xp_fun(lo_byte, hi_byte) so */
|
||||
/* that the values can be assembled into memory as required by a */
|
||||
/* suitable definition of this macro operating on the table above */
|
||||
|
||||
#define xp(i) xp_fun( \
|
||||
(i & 0x80 ? 0xe1 : 0) ^ (i & 0x40 ? 0x70 : 0) ^ \
|
||||
(i & 0x20 ? 0x38 : 0) ^ (i & 0x10 ? 0x1c : 0) ^ \
|
||||
(i & 0x08 ? 0x0e : 0) ^ (i & 0x04 ? 0x07 : 0) ^ \
|
||||
(i & 0x02 ? 0x03 : 0) ^ (i & 0x01 ? 0x01 : 0), \
|
||||
(i & 0x80 ? 0x00 : 0) ^ (i & 0x40 ? 0x80 : 0) ^ \
|
||||
(i & 0x20 ? 0x40 : 0) ^ (i & 0x10 ? 0x20 : 0) ^ \
|
||||
(i & 0x08 ? 0x10 : 0) ^ (i & 0x04 ? 0x08 : 0) ^ \
|
||||
(i & 0x02 ? 0x84 : 0) ^ (i & 0x01 ? 0xc2 : 0) )
|
||||
|
||||
#define xp64(i) xp_fun( \
|
||||
(i & 0x80 ? 0xd8 : 0) ^ (i & 0x40 ? 0x6c : 0) ^ \
|
||||
(i & 0x20 ? 0x36 : 0) ^ (i & 0x10 ? 0x1b : 0) ^ \
|
||||
(i & 0x08 ? 0x0d : 0) ^ (i & 0x04 ? 0x06 : 0) ^ \
|
||||
(i & 0x02 ? 0x03 : 0) ^ (i & 0x01 ? 0x01 : 0), \
|
||||
(i & 0x80 ? 0x00 : 0) ^ (i & 0x40 ? 0x00 : 0) ^ \
|
||||
(i & 0x20 ? 0x00 : 0) ^ (i & 0x10 ? 0x00 : 0) ^ \
|
||||
(i & 0x08 ? 0x80 : 0) ^ (i & 0x04 ? 0xc0 : 0) ^ \
|
||||
(i & 0x02 ? 0x60 : 0) ^ (i & 0x01 ? 0xb0 : 0) )
|
||||
|
||||
static mode(32t) gf_poly[2] = { 0, 0xe1000000 };
|
||||
static mode(32t) gf_poly64[2] = { 0, 0xd8000000 };
|
||||
|
||||
/* Multiply of a GF128 field element by x. The field element */
|
||||
/* is held in an array of bytes in which field bits 8n..8n + 7 */
|
||||
/* are held in byte[n], with lower indexed bits placed in the */
|
||||
/* more numerically significant bit positions in bytes. */
|
||||
|
||||
/* This function multiples a field element x, in the polynomial */
|
||||
/* field representation. It uses 32-bit word operations to gain */
|
||||
/* speed but compensates for machine endianess and hence works */
|
||||
/* correctly on both styles of machine */
|
||||
|
||||
in_line void mul_x(mode(32t) x[4])
|
||||
{ mode(32t) t;
|
||||
|
||||
bsw_32(x, 4);
|
||||
|
||||
/* at this point the filed element bits 0..127 are set out */
|
||||
/* as follows in 32-bit words (where the most significant */
|
||||
/* (ms) numeric bits are to the left) */
|
||||
/* */
|
||||
/* x[0] x[1] x[2] x[3] */
|
||||
/* ms ls ms ls ms ls ms ls */
|
||||
/* field: 0 ... 31 32 .. 63 64 .. 95 96 .. 127 */
|
||||
|
||||
t = gf_poly[x[3] & 1]; /* bit 127 of the element */
|
||||
x[3] = (x[3] >> 1) | (x[2] << 31); /* shift bits up by one */
|
||||
x[2] = (x[2] >> 1) | (x[1] << 31); /* position */
|
||||
x[1] = (x[1] >> 1) | (x[0] << 31); /* if bit 7 is 1 xor in */
|
||||
x[0] = (x[0] >> 1) ^ t; /* the field polynomial */
|
||||
bsw_32(x, 4);
|
||||
}
|
||||
|
||||
in_line void mul_x64(mode(32t) x[2])
|
||||
{ mode(32t) t;
|
||||
|
||||
bsw_32(x, 2);
|
||||
|
||||
/* at this point the filed element bits 0..127 are set out */
|
||||
/* as follows in 32-bit words (where the most significant */
|
||||
/* (ms) numeric bits are to the left) */
|
||||
/* */
|
||||
/* x[0] x[1] x[2] x[3] */
|
||||
/* ms ls ms ls ms ls ms ls */
|
||||
/* field: 0 ... 31 32 .. 63 64 .. 95 96 .. 127 */
|
||||
|
||||
t = gf_poly64[x[1] & 1]; /* bit 127 of the element */
|
||||
/* shift bits up by one */
|
||||
/* position */
|
||||
x[1] = (x[1] >> 1) | (x[0] << 31); /* if bit 7 is 1 xor in */
|
||||
x[0] = (x[0] >> 1) ^ t; /* the field polynomial */
|
||||
bsw_32(x, 2);
|
||||
}
|
||||
|
||||
/* Multiply of a GF128 field element by x^8 using 32-bit words */
|
||||
/* for speed - machine endianess matters here */
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
|
||||
|
||||
#define xp_fun(x,y) ((mode(32t))(x)) | (((mode(32t))(y)) << 8)
|
||||
static const unsigned __int16 gft_le[256] = gf_dat(xp);
|
||||
static const unsigned __int16 gft_le64[256] = gf_dat(xp64);
|
||||
|
||||
in_line void mul_lex8(mode(32t) x[4]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[3] >> 24); /* in little endian format */
|
||||
x[3] = (x[3] << 8) | (x[2] >> 24);
|
||||
x[2] = (x[2] << 8) | (x[1] >> 24);
|
||||
x[1] = (x[1] << 8) | (x[0] >> 24);
|
||||
x[0] = (x[0] << 8) ^ gft_le[t];
|
||||
}
|
||||
|
||||
in_line void mul_lex8_64(mode(32t) x[2]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[1] >> 24); /* in little endian format */
|
||||
x[1] = (x[1] << 8) | (x[0] >> 24);
|
||||
x[0] = (x[0] << 8) ^ gft_le64[t];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 1 || (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
|
||||
|
||||
#undef xp_fun
|
||||
#define xp_fun(x,y) ((mode(32t))(y)) | (((mode(32t))(x)) << 8)
|
||||
static const unsigned __int16 gft_be[256] = gf_dat(xp);
|
||||
static const unsigned __int16 gft_be64[256] = gf_dat(xp64);
|
||||
|
||||
in_line void mul_bex8(mode(32t) x[4]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[3] & 0xff); /* in big endian format */
|
||||
x[3] = (x[3] >> 8) | (x[2] << 24);
|
||||
x[2] = (x[2] >> 8) | (x[1] << 24);
|
||||
x[1] = (x[1] >> 8) | (x[0] << 24);
|
||||
x[0] = (x[0] >> 8) ^ (((mode(32t))gft_be[t]) << 16);
|
||||
}
|
||||
|
||||
in_line void mul_bex8_64(mode(32t) x[2]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[1] & 0xff); /* in big endian format */
|
||||
x[1] = (x[1] >> 8) | (x[0] << 24);
|
||||
x[0] = (x[0] >> 8) ^ (((mode(32t))gft_be64[t]) << 16);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* hence choose the correct version for the machine endianess */
|
||||
|
||||
#if PLATFORM_BYTE_ORDER == BRG_BIG_ENDIAN
|
||||
#define mul_x8 mul_bex8
|
||||
#define mul_x8_64 mul_bex8_64
|
||||
#else
|
||||
#define mul_x8 mul_lex8
|
||||
#define mul_x8_64 mul_lex8_64
|
||||
#endif
|
||||
|
||||
/* different versions of the general gf_mul function are provided */
|
||||
/* here. Sadly none are very fast :-( */
|
||||
|
||||
void GfMul128 (void *a, const void* b)
|
||||
{ mode(32t) r[CBLK_LEN >> 2], p[8][CBLK_LEN >> 2];
|
||||
int i;
|
||||
|
||||
move_block_aligned(p[0], b);
|
||||
bsw_32(p[0], 4);
|
||||
for(i = 0; i < 7; ++i)
|
||||
{
|
||||
p[i + 1][3] = (p[i][3] >> 1) | (p[i][2] << 31);
|
||||
p[i + 1][2] = (p[i][2] >> 1) | (p[i][1] << 31);
|
||||
p[i + 1][1] = (p[i][1] >> 1) | (p[i][0] << 31);
|
||||
p[i + 1][0] = (p[i][0] >> 1) ^ gf_poly[p[i][3] & 1];
|
||||
}
|
||||
|
||||
memset(r, 0, CBLK_LEN);
|
||||
for(i = 0; i < 16; ++i)
|
||||
{
|
||||
if(i) mul_bex8(r); /* order is always big endian here */
|
||||
|
||||
if(((unsigned char*)a)[15 - i] & 0x80)
|
||||
xor_block_aligned(r, p[0]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x40)
|
||||
xor_block_aligned(r, p[1]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x20)
|
||||
xor_block_aligned(r, p[2]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x10)
|
||||
xor_block_aligned(r, p[3]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x08)
|
||||
xor_block_aligned(r, p[4]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x04)
|
||||
xor_block_aligned(r, p[5]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x02)
|
||||
xor_block_aligned(r, p[6]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x01)
|
||||
xor_block_aligned(r, p[7]);
|
||||
}
|
||||
bsw_32(r, 4);
|
||||
move_block_aligned(a, r);
|
||||
}
|
||||
|
||||
#if defined( UNROLL_LOOPS )
|
||||
|
||||
#define xor_8k(i) \
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i][a[i] & 15]); \
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i + 1][a[i] >> 4])
|
||||
|
||||
|
||||
void GfMul128Tab (unsigned char a[CBLK_LEN], GfCtx8k *ctx)
|
||||
{ unsigned __int32 r[CBLK_LEN >> 2];
|
||||
|
||||
move_block_aligned(r, ctx->gf_t8k[0][a[0] & 15]);
|
||||
xor_block_aligned(r, ctx->gf_t8k[1][a[0] >> 4]);
|
||||
xor_8k( 1); xor_8k( 2); xor_8k( 3);
|
||||
xor_8k( 4); xor_8k( 5); xor_8k( 6); xor_8k( 7);
|
||||
xor_8k( 8); xor_8k( 9); xor_8k(10); xor_8k(11);
|
||||
xor_8k(12); xor_8k(13); xor_8k(14); xor_8k(15);
|
||||
move_block_aligned(a, r);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void GfMul128Tab (unsigned char a[CBLK_LEN], GfCtx8k *ctx)
|
||||
{ unsigned __int32 r[CBLK_LEN >> 2], *p;
|
||||
int i;
|
||||
|
||||
p = ctx->gf_t8k[0][a[0] & 15];
|
||||
memcpy(r, p, CBLK_LEN);
|
||||
p = ctx->gf_t8k[1][a[0] >> 4];
|
||||
xor_block_aligned(r, p);
|
||||
for(i = 1; i < CBLK_LEN; ++i)
|
||||
{
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i][a[i] & 15]);
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i + 1][a[i] >> 4]);
|
||||
}
|
||||
memcpy(a, r, CBLK_LEN);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void compile_8k_table(unsigned __int8 *a, GfCtx8k *ctx)
|
||||
{ int i, j, k;
|
||||
|
||||
memset(ctx->gf_t8k, 0, 32 * 16 * 16);
|
||||
for(i = 0; i < 2 * CBLK_LEN; ++i)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[1][8], a, CBLK_LEN);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[1][j], ctx->gf_t8k[1][j + j], CBLK_LEN);
|
||||
mul_x(ctx->gf_t8k[1][j]);
|
||||
}
|
||||
memcpy(ctx->gf_t8k[0][8], ctx->gf_t8k[1][1], CBLK_LEN);
|
||||
mul_x(ctx->gf_t8k[0][8]);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[0][j], ctx->gf_t8k[0][j + j], CBLK_LEN);
|
||||
mul_x(ctx->gf_t8k[0][j]);
|
||||
}
|
||||
}
|
||||
else if(i > 1)
|
||||
for(j = 8; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[i][j], ctx->gf_t8k[i - 2][j], CBLK_LEN);
|
||||
mul_x8(ctx->gf_t8k[i][j]);
|
||||
}
|
||||
|
||||
for(j = 2; j < 16; j += j)
|
||||
{
|
||||
mode(32t) *pj = ctx->gf_t8k[i][j];
|
||||
mode(32t) *pk = ctx->gf_t8k[i][1];
|
||||
mode(32t) *pl = ctx->gf_t8k[i][j + 1];
|
||||
|
||||
for(k = 1; k < j; ++k)
|
||||
{
|
||||
*pl++ = pj[0] ^ *pk++;
|
||||
*pl++ = pj[1] ^ *pk++;
|
||||
*pl++ = pj[2] ^ *pk++;
|
||||
*pl++ = pj[3] ^ *pk++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void compile_4k_table64(unsigned __int8 *a, GfCtx4k64 *ctx)
|
||||
{ int i, j, k;
|
||||
|
||||
memset(ctx->gf_t4k, 0, sizeof(ctx->gf_t4k));
|
||||
for(i = 0; i < 2 * CBLK_LEN8; ++i)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[1][8], a, CBLK_LEN8);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[1][j], ctx->gf_t4k[1][j + j], CBLK_LEN8);
|
||||
mul_x64(ctx->gf_t4k[1][j]);
|
||||
}
|
||||
memcpy(ctx->gf_t4k[0][8], ctx->gf_t4k[1][1], CBLK_LEN8);
|
||||
mul_x64(ctx->gf_t4k[0][8]);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[0][j], ctx->gf_t4k[0][j + j], CBLK_LEN8);
|
||||
mul_x64(ctx->gf_t4k[0][j]);
|
||||
}
|
||||
}
|
||||
else if(i > 1)
|
||||
for(j = 8; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[i][j], ctx->gf_t4k[i - 2][j], CBLK_LEN8);
|
||||
mul_x8_64(ctx->gf_t4k[i][j]);
|
||||
}
|
||||
|
||||
for(j = 2; j < 16; j += j)
|
||||
{
|
||||
mode(32t) *pj = ctx->gf_t4k[i][j];
|
||||
mode(32t) *pk = ctx->gf_t4k[i][1];
|
||||
mode(32t) *pl = ctx->gf_t4k[i][j + 1];
|
||||
|
||||
for(k = 1; k < j; ++k)
|
||||
{
|
||||
*pl++ = pj[0] ^ *pk++;
|
||||
*pl++ = pj[1] ^ *pk++;
|
||||
*pl++ = pj[2] ^ *pk++;
|
||||
*pl++ = pj[3] ^ *pk++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int IsBitSet128 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
return a[(127 - bit) / 8] & (0x80 >> ((127 - bit) % 8));
|
||||
}
|
||||
|
||||
static int IsBitSet64 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
return a[(63 - bit) / 8] & (0x80 >> ((63 - bit) % 8));
|
||||
}
|
||||
|
||||
static void SetBit128 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
a[(127 - bit) / 8] |= 0x80 >> ((127 - bit) % 8);
|
||||
}
|
||||
|
||||
static void SetBit64 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
a[(63 - bit) / 8] |= 0x80 >> ((63 - bit) % 8);
|
||||
}
|
||||
|
||||
void MirrorBits128 (unsigned __int8 *a)
|
||||
{
|
||||
unsigned __int8 t[128 / 8];
|
||||
int i;
|
||||
memset (t,0,16);
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
if (IsBitSet128(i, a))
|
||||
SetBit128 (127 - i, t);
|
||||
}
|
||||
memcpy (a, t, sizeof (t));
|
||||
burn (t,sizeof (t));
|
||||
}
|
||||
|
||||
void MirrorBits64 (unsigned __int8 *a)
|
||||
{
|
||||
unsigned __int8 t[64 / 8];
|
||||
int i;
|
||||
memset (t,0,8);
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
if (IsBitSet64(i, a))
|
||||
SetBit64 (63 - i, t);
|
||||
}
|
||||
memcpy (a, t, sizeof (t));
|
||||
burn (t,sizeof (t));
|
||||
}
|
||||
|
||||
/* Allocate and initialize speed optimization table
|
||||
for multiplication by 64-bit operand in MSB-first mode */
|
||||
int Gf128Tab64Init (unsigned __int8 *a, GfCtx *ctx)
|
||||
{
|
||||
GfCtx8k *ctx8k;
|
||||
unsigned __int8 am[16];
|
||||
int i, j;
|
||||
|
||||
ctx8k = (GfCtx8k *) TCalloc (sizeof (GfCtx8k));
|
||||
if (!ctx8k)
|
||||
return FALSE;
|
||||
|
||||
memcpy (am, a, 16);
|
||||
MirrorBits128 (am);
|
||||
compile_8k_table (am, ctx8k);
|
||||
|
||||
/* Convert 8k LSB-first table to 4k MSB-first */
|
||||
for (i = 16; i < 32; i++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
int jm = 0;
|
||||
jm |= (j & 0x1) << 3;
|
||||
jm |= (j & 0x2) << 1;
|
||||
jm |= (j & 0x4) >> 1;
|
||||
jm |= (j & 0x8) >> 3;
|
||||
|
||||
memcpy (&ctx->gf_t128[i-16][jm], (unsigned char *)&ctx8k->gf_t8k[31-i][j], 16);
|
||||
MirrorBits128 ((unsigned char *)&ctx->gf_t128[i-16][jm]);
|
||||
}
|
||||
}
|
||||
|
||||
burn (ctx8k ,sizeof (*ctx8k));
|
||||
burn (am, sizeof (am));
|
||||
TCfree (ctx8k);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int Gf64TabInit (unsigned __int8 *a, GfCtx *ctx)
|
||||
{
|
||||
/* Deprecated/legacy */
|
||||
|
||||
GfCtx4k64 *ctx4k;
|
||||
unsigned __int8 am[8];
|
||||
int i, j;
|
||||
|
||||
ctx4k = (GfCtx4k64 *) TCalloc (sizeof (GfCtx4k64));
|
||||
if (!ctx4k)
|
||||
return FALSE;
|
||||
|
||||
memcpy (am, a, 8);
|
||||
MirrorBits64 (am);
|
||||
compile_4k_table64 (am, ctx4k);
|
||||
|
||||
/* Convert LSB-first table to MSB-first */
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
int jm = 0;
|
||||
jm |= (j & 0x1) << 3;
|
||||
jm |= (j & 0x2) << 1;
|
||||
jm |= (j & 0x4) >> 1;
|
||||
jm |= (j & 0x8) >> 3;
|
||||
|
||||
memcpy (&ctx->gf_t64[i][jm], (unsigned char *)&ctx4k->gf_t4k[15-i][j], 8);
|
||||
MirrorBits64 ((unsigned char *)&ctx->gf_t64[i][jm]);
|
||||
}
|
||||
}
|
||||
|
||||
burn (ctx4k,sizeof (*ctx4k));
|
||||
burn (am, sizeof (am));
|
||||
TCfree (ctx4k);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define xor_8kt64(i) \
|
||||
xor_block_aligned(r, ctx->gf_t128[i + i][a[i] & 15]); \
|
||||
xor_block_aligned(r, ctx->gf_t128[i + i + 1][a[i] >> 4])
|
||||
|
||||
/* Multiply a 128-bit number by a 64-bit number in the finite field GF(2^128) */
|
||||
void Gf128MulBy64Tab (unsigned __int8 a[8], unsigned __int8 p[16], GfCtx *ctx)
|
||||
{
|
||||
unsigned __int32 r[CBLK_LEN >> 2];
|
||||
|
||||
move_block_aligned(r, ctx->gf_t128[7*2][a[7] & 15]);
|
||||
xor_block_aligned(r, ctx->gf_t128[7*2+1][a[7] >> 4]);
|
||||
|
||||
if (*(unsigned __int16 *)a)
|
||||
{
|
||||
xor_8kt64(0);
|
||||
xor_8kt64(1);
|
||||
}
|
||||
if (a[2])
|
||||
{
|
||||
xor_8kt64(2);
|
||||
}
|
||||
xor_8kt64(3);
|
||||
xor_8kt64(4);
|
||||
xor_8kt64(5);
|
||||
xor_8kt64(6);
|
||||
|
||||
move_block_aligned(p, r);
|
||||
}
|
||||
|
||||
#define xor_8k64(i) \
|
||||
xor_block_aligned64(r, ctx->gf_t64[i + i][a[i] & 15]); \
|
||||
xor_block_aligned64(r, ctx->gf_t64[i + i + 1][a[i] >> 4])
|
||||
|
||||
/* Multiply two 64-bit numbers in the finite field GF(2^64) */
|
||||
void Gf64MulTab (unsigned char a[8], unsigned char p[8], GfCtx *ctx)
|
||||
{
|
||||
/* Deprecated/legacy */
|
||||
|
||||
unsigned __int32 r[CBLK_LEN8 >> 2];
|
||||
|
||||
move_block_aligned64(r, ctx->gf_t64[7*2][a[7] & 15]);
|
||||
xor_block_aligned64(r, ctx->gf_t64[7*2+1][a[7] >> 4]);
|
||||
|
||||
if (*(unsigned __int16 *)a)
|
||||
{
|
||||
xor_8k64(0);
|
||||
xor_8k64(1);
|
||||
}
|
||||
if (a[2])
|
||||
{
|
||||
xor_8k64(2);
|
||||
}
|
||||
xor_8k64(3);
|
||||
xor_8k64(4);
|
||||
xor_8k64(5);
|
||||
xor_8k64(6);
|
||||
|
||||
move_block_aligned64(p, r);
|
||||
}
|
||||
|
||||
|
||||
/* Basic algorithms for testing of optimized algorithms */
|
||||
|
||||
static void xor128 (uint64 *a, uint64 *b)
|
||||
{
|
||||
*a++ ^= *b++;
|
||||
*a ^= *b;
|
||||
}
|
||||
|
||||
static void shl128 (unsigned __int8 *a)
|
||||
{
|
||||
int i, x = 0, xx;
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
xx = (a[i] & 0x80) >> 7;
|
||||
a[i] = (char) ((a[i] << 1) | x);
|
||||
x = xx;
|
||||
}
|
||||
}
|
||||
|
||||
static void GfMul128Basic (unsigned __int8 *a, unsigned __int8 *b, unsigned __int8 *p)
|
||||
{
|
||||
int i;
|
||||
unsigned __int8 la[16];
|
||||
memcpy (la, a, 16);
|
||||
memset (p, 0, 16);
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
if (IsBitSet128 (i, b))
|
||||
xor128 ((uint64 *)p, (uint64 *)la);
|
||||
|
||||
if (la[0] & 0x80)
|
||||
{
|
||||
shl128 (la);
|
||||
la[15] ^= 0x87;
|
||||
}
|
||||
else
|
||||
{
|
||||
shl128 (la);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void xor64 (uint64 *a, uint64 *b)
|
||||
{
|
||||
*a ^= *b;
|
||||
}
|
||||
|
||||
static void shl64 (unsigned __int8 *a)
|
||||
{
|
||||
int i, x = 0, xx;
|
||||
for (i = 7; i >= 0; i--)
|
||||
{
|
||||
xx = (a[i] & 0x80) >> 7;
|
||||
a[i] = (char) ((a[i] << 1) | x);
|
||||
x = xx;
|
||||
}
|
||||
}
|
||||
|
||||
static void GfMul64Basic (unsigned __int8 *a, unsigned __int8 *b, unsigned __int8* p)
|
||||
{
|
||||
/* Deprecated/legacy */
|
||||
|
||||
int i;
|
||||
unsigned __int8 la[8];
|
||||
memcpy (la, a, 8);
|
||||
memset (p, 0, 8);
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
if (IsBitSet64 (i, b))
|
||||
xor64 ((uint64 *)p, (uint64 *)la);
|
||||
|
||||
if (la[0] & 0x80)
|
||||
{
|
||||
shl64 (la);
|
||||
la[7] ^= 0x1b;
|
||||
}
|
||||
else
|
||||
{
|
||||
shl64 (la);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL GfMulSelfTest ()
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
unsigned __int8 a[16];
|
||||
unsigned __int8 b[16];
|
||||
unsigned __int8 p1[16];
|
||||
unsigned __int8 p2[16];
|
||||
GfCtx *gfCtx = (GfCtx *) TCalloc (sizeof (GfCtx));
|
||||
int i, j;
|
||||
|
||||
if (!gfCtx)
|
||||
return FALSE;
|
||||
|
||||
/* GF(2^64) - deprecated/legacy */
|
||||
for (i = 0; i < 0x100; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
a[j] = (unsigned __int8) i;
|
||||
b[j] = a[j] ^ 0xff;
|
||||
}
|
||||
|
||||
GfMul64Basic (a, b, p1);
|
||||
|
||||
Gf64TabInit (a, gfCtx);
|
||||
Gf64MulTab (b, p2, gfCtx);
|
||||
|
||||
if (memcmp (p1, p2, 8) != 0)
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
/* GF(2^128) */
|
||||
for (i = 0; i < 0x100; i++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
a[j] = (unsigned __int8) i;
|
||||
b[j] = j < 8 ? 0 : a[j] ^ 0xff;
|
||||
}
|
||||
|
||||
GfMul128Basic (a, b, p1);
|
||||
|
||||
Gf128Tab64Init (a, gfCtx);
|
||||
Gf128MulBy64Tab (b + 8, p2, gfCtx);
|
||||
|
||||
if (memcmp (p1, p2, 16) != 0)
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
TCfree (gfCtx);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
76
src/Common/GfMul.h
Normal file
76
src/Common/GfMul.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software is allowed (with or without
|
||||
changes) provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 31/01/2004
|
||||
*/
|
||||
|
||||
/* Adapted for TrueCrypt */
|
||||
|
||||
#ifndef _GCM_H
|
||||
#define _GCM_H
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define CBLK_LEN 16 /* encryption block length */
|
||||
#define CBLK_LEN8 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned __int32 gf_t8k[CBLK_LEN * 2][16][CBLK_LEN / 4];
|
||||
} GfCtx8k;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned __int32 gf_t4k[CBLK_LEN8 * 2][16][CBLK_LEN / 4];
|
||||
} GfCtx4k64;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* union not used to support faster mounting */
|
||||
unsigned __int32 gf_t128[CBLK_LEN * 2 / 2][16][CBLK_LEN / 4];
|
||||
unsigned __int32 gf_t64[CBLK_LEN8 * 2][16][CBLK_LEN8 / 4];
|
||||
} GfCtx;
|
||||
|
||||
typedef int ret_type;
|
||||
|
||||
void GfMul128 (void *a, const void* b);
|
||||
void GfMul128Tab(unsigned char a[16], GfCtx8k *ctx);
|
||||
int Gf128Tab64Init (unsigned __int8 *a, GfCtx *ctx);
|
||||
void Gf128MulBy64Tab (unsigned __int8 a[8], unsigned __int8 p[16], GfCtx *ctx);
|
||||
int Gf64TabInit (unsigned __int8 *a, GfCtx *ctx);
|
||||
void Gf64MulTab (unsigned char a[8], unsigned char p[8], GfCtx *ctx);
|
||||
void MirrorBits128 (unsigned __int8 *a);
|
||||
void MirrorBits64 (unsigned __int8 *a);
|
||||
BOOL GfMulSelfTest ();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
1308
src/Common/Inflate.c
Normal file
1308
src/Common/Inflate.c
Normal file
File diff suppressed because it is too large
Load Diff
51
src/Common/Inflate.h
Normal file
51
src/Common/Inflate.h
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define WSIZE 0x8000 // Window size
|
||||
#define ZCONST const
|
||||
#define OF(p) p
|
||||
|
||||
typedef unsigned long ulg;
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef void zvoid;
|
||||
|
||||
typedef struct huft
|
||||
{
|
||||
uch b, e;
|
||||
union
|
||||
{
|
||||
ush n;
|
||||
struct huft *t;
|
||||
}v;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uch *inptr, *outbufptr;
|
||||
int incnt;
|
||||
int outCounter;
|
||||
|
||||
struct huft *fixed_tl;
|
||||
struct huft *fixed_td;
|
||||
int fixed_bl, fixed_bd;
|
||||
|
||||
unsigned bk, wp;
|
||||
ulg bb;
|
||||
} G_struct;
|
||||
|
||||
#define __GPRO void
|
||||
#define __GPRO__
|
||||
#define __G
|
||||
#define __G__
|
||||
#define __GDEF
|
||||
|
||||
|
||||
#define FLUSH(cnt) { memcpy (G.outbufptr, redirSlide, cnt); G.outbufptr += cnt; G.outCounter += cnt; }
|
||||
#define NEXTBYTE (((G.incnt--) >= 0) ? (*G.inptr++) : EOF)
|
||||
|
||||
|
||||
int huft_free(struct huft *t);
|
||||
int huft_build(__GDEF ZCONST unsigned *b, unsigned n, unsigned s, ZCONST ush *d, ZCONST ush *e, struct huft **t, int *m);
|
||||
|
||||
int DecompressDeflatedData (char *out, char *in, int inLength);
|
685
src/Common/Keyfiles.c
Normal file
685
src/Common/Keyfiles.c
Normal file
@ -0,0 +1,685 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Keyfiles.h"
|
||||
#include "Crc.h"
|
||||
|
||||
#include <io.h>
|
||||
#include "Dlgcode.h"
|
||||
#include "Language.h"
|
||||
#include "SecurityToken.h"
|
||||
#include "Common/resource.h"
|
||||
#include "Platform/Finally.h"
|
||||
#include "Platform/ForEach.h"
|
||||
|
||||
using namespace TrueCrypt;
|
||||
|
||||
#define stat _stat
|
||||
#define S_IFDIR _S_IFDIR
|
||||
#define snprintf _snprintf
|
||||
|
||||
|
||||
BOOL HiddenFilesPresentInKeyfilePath = FALSE;
|
||||
|
||||
|
||||
KeyFile *KeyFileAdd (KeyFile *firstKeyFile, KeyFile *keyFile)
|
||||
{
|
||||
KeyFile *kf = firstKeyFile;
|
||||
|
||||
if (firstKeyFile != NULL)
|
||||
{
|
||||
while (kf->Next)
|
||||
kf = kf->Next;
|
||||
|
||||
kf->Next = keyFile;
|
||||
}
|
||||
else
|
||||
firstKeyFile = keyFile;
|
||||
|
||||
keyFile->Next = NULL;
|
||||
|
||||
return firstKeyFile;
|
||||
}
|
||||
|
||||
|
||||
// Returns first keyfile, NULL if last keyfile was removed
|
||||
static KeyFile *KeyFileRemove (KeyFile *firstKeyFile, KeyFile *keyFile)
|
||||
{
|
||||
KeyFile *prevkf = NULL, *kf = firstKeyFile;
|
||||
|
||||
if (firstKeyFile == NULL) return NULL;
|
||||
do
|
||||
{
|
||||
if (kf == keyFile)
|
||||
{
|
||||
if (prevkf == NULL)
|
||||
firstKeyFile = kf->Next;
|
||||
else
|
||||
prevkf->Next = kf->Next;
|
||||
|
||||
burn (keyFile, sizeof(*keyFile)); // wipe
|
||||
free (keyFile);
|
||||
break;
|
||||
}
|
||||
prevkf = kf;
|
||||
}
|
||||
while (kf = kf->Next);
|
||||
|
||||
return firstKeyFile;
|
||||
}
|
||||
|
||||
|
||||
void KeyFileRemoveAll (KeyFile **firstKeyFile)
|
||||
{
|
||||
KeyFile *kf = *firstKeyFile;
|
||||
while (kf != NULL)
|
||||
{
|
||||
KeyFile *d = kf;
|
||||
kf = kf->Next;
|
||||
burn (d, sizeof(*d)); // wipe
|
||||
free (d);
|
||||
}
|
||||
|
||||
*firstKeyFile = NULL;
|
||||
}
|
||||
|
||||
|
||||
KeyFile *KeyFileClone (KeyFile *keyFile)
|
||||
{
|
||||
KeyFile *clone;
|
||||
|
||||
if (keyFile == NULL) return NULL;
|
||||
|
||||
clone = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
strcpy (clone->FileName, keyFile->FileName);
|
||||
clone->Next = NULL;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
KeyFile *KeyFileCloneAll (KeyFile *firstKeyFile)
|
||||
{
|
||||
KeyFile *cloneFirstKeyFile = KeyFileClone (firstKeyFile);
|
||||
KeyFile *kf;
|
||||
|
||||
if (firstKeyFile == NULL) return NULL;
|
||||
kf = firstKeyFile->Next;
|
||||
while (kf != NULL)
|
||||
{
|
||||
KeyFileAdd (cloneFirstKeyFile, KeyFileClone (kf));
|
||||
kf = kf->Next;
|
||||
}
|
||||
|
||||
return cloneFirstKeyFile;
|
||||
}
|
||||
|
||||
|
||||
static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
|
||||
{
|
||||
FILE *f;
|
||||
unsigned __int8 buffer[64 * 1024];
|
||||
unsigned __int32 crc = 0xffffffff;
|
||||
int writePos = 0;
|
||||
size_t bytesRead, totalRead = 0;
|
||||
int status = TRUE;
|
||||
|
||||
HANDLE src;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
|
||||
BOOL bTimeStampValid = FALSE;
|
||||
|
||||
/* Remember the last access time of the keyfile. It will be preserved in order to prevent
|
||||
an adversary from determining which file may have been used as keyfile. */
|
||||
src = CreateFile (keyFile->FileName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (src != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetFileTime ((HANDLE) src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
|
||||
bTimeStampValid = TRUE;
|
||||
}
|
||||
|
||||
finally_do_arg (HANDLE, src,
|
||||
{
|
||||
if (finally_arg != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (finally_arg);
|
||||
});
|
||||
|
||||
f = fopen (keyFile->FileName, "rb");
|
||||
if (f == NULL) return FALSE;
|
||||
|
||||
while ((bytesRead = fread (buffer, 1, sizeof (buffer), f)) > 0)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (ferror (f))
|
||||
{
|
||||
status = FALSE;
|
||||
goto close;
|
||||
}
|
||||
|
||||
for (i = 0; i < bytesRead; i++)
|
||||
{
|
||||
crc = UPDC32 (buffer[i], crc);
|
||||
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 24);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 16);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
|
||||
keyPool[writePos++] += (unsigned __int8) crc;
|
||||
|
||||
if (writePos >= KEYFILE_POOL_SIZE)
|
||||
writePos = 0;
|
||||
|
||||
if (++totalRead >= KEYFILE_MAX_READ_LEN)
|
||||
goto close;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror (f))
|
||||
{
|
||||
status = FALSE;
|
||||
}
|
||||
else if (totalRead == 0)
|
||||
{
|
||||
status = FALSE;
|
||||
SetLastError (ERROR_HANDLE_EOF);
|
||||
}
|
||||
|
||||
close:
|
||||
DWORD err = GetLastError();
|
||||
fclose (f);
|
||||
|
||||
if (bTimeStampValid && !IsFileOnReadOnlyFilesystem (keyFile->FileName))
|
||||
{
|
||||
// Restore the keyfile timestamp
|
||||
SetFileTime (src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);
|
||||
}
|
||||
|
||||
SetLastError (err);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
BOOL KeyFilesApply (Password *password, KeyFile *firstKeyFile)
|
||||
{
|
||||
BOOL status = TRUE;
|
||||
KeyFile kfSubStruct;
|
||||
KeyFile *kf;
|
||||
KeyFile *kfSub = &kfSubStruct;
|
||||
static unsigned __int8 keyPool [KEYFILE_POOL_SIZE];
|
||||
size_t i;
|
||||
struct stat statStruct;
|
||||
char searchPath [TC_MAX_PATH*2];
|
||||
struct _finddata_t fBuf;
|
||||
intptr_t searchHandle;
|
||||
|
||||
HiddenFilesPresentInKeyfilePath = FALSE;
|
||||
|
||||
if (firstKeyFile == NULL) return TRUE;
|
||||
|
||||
VirtualLock (keyPool, sizeof (keyPool));
|
||||
memset (keyPool, 0, sizeof (keyPool));
|
||||
|
||||
for (kf = firstKeyFile; kf != NULL; kf = kf->Next)
|
||||
{
|
||||
// Determine whether it's a security token path
|
||||
try
|
||||
{
|
||||
if (SecurityToken::IsKeyfilePathValid (SingleStringToWide (kf->FileName)))
|
||||
{
|
||||
// Apply security token keyfile
|
||||
vector <byte> keyfileData;
|
||||
SecurityToken::GetKeyfileData (SecurityTokenKeyfile (SingleStringToWide (kf->FileName)), keyfileData);
|
||||
|
||||
if (keyfileData.empty())
|
||||
{
|
||||
SetLastError (ERROR_HANDLE_EOF);
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned __int32 crc = 0xffffffff;
|
||||
int writePos = 0;
|
||||
size_t totalRead = 0;
|
||||
|
||||
for (size_t i = 0; i < keyfileData.size(); i++)
|
||||
{
|
||||
crc = UPDC32 (keyfileData[i], crc);
|
||||
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 24);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 16);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
|
||||
keyPool[writePos++] += (unsigned __int8) crc;
|
||||
|
||||
if (writePos >= KEYFILE_POOL_SIZE)
|
||||
writePos = 0;
|
||||
|
||||
if (++totalRead >= KEYFILE_MAX_READ_LEN)
|
||||
break;
|
||||
}
|
||||
|
||||
burn (&keyfileData.front(), keyfileData.size());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Determine whether it's a path or a file
|
||||
if (stat (kf->FileName, &statStruct) != 0)
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (statStruct.st_mode & S_IFDIR) // If it's a directory
|
||||
{
|
||||
/* Find and process all keyfiles in the directory */
|
||||
int keyfileCount = 0;
|
||||
|
||||
snprintf (searchPath, sizeof (searchPath), "%s\\*.*", kf->FileName);
|
||||
if ((searchHandle = _findfirst (searchPath, &fBuf)) == -1)
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE_PATH");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA fileAttributes;
|
||||
|
||||
snprintf (kfSub->FileName, sizeof(kfSub->FileName), "%s%c%s", kf->FileName,
|
||||
'\\',
|
||||
fBuf.name
|
||||
);
|
||||
|
||||
// Determine whether it's a path or a file
|
||||
if (stat (kfSub->FileName, &statStruct) != 0)
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
else if (statStruct.st_mode & S_IFDIR) // If it's a directory
|
||||
{
|
||||
// Prevent recursive folder scanning
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip hidden files
|
||||
if (GetFileAttributesEx (kfSub->FileName, GetFileExInfoStandard, &fileAttributes)
|
||||
&& (fileAttributes.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)
|
||||
{
|
||||
HiddenFilesPresentInKeyfilePath = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
++keyfileCount;
|
||||
|
||||
// Apply keyfile to the pool
|
||||
if (!KeyFileProcess (keyPool, kfSub))
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
}
|
||||
|
||||
} while (_findnext (searchHandle, &fBuf) != -1);
|
||||
_findclose (searchHandle);
|
||||
|
||||
burn (&kfSubStruct, sizeof (kfSubStruct));
|
||||
|
||||
if (keyfileCount == 0)
|
||||
{
|
||||
ErrorDirect ((wstring (GetString ("ERR_KEYFILE_PATH_EMPTY")) + L"\n\n" + SingleStringToWide (kf->FileName)).c_str());
|
||||
status = FALSE;
|
||||
}
|
||||
}
|
||||
// Apply keyfile to the pool
|
||||
else if (!KeyFileProcess (keyPool, kf))
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mix the keyfile pool contents into the password */
|
||||
|
||||
for (i = 0; i < sizeof (keyPool); i++)
|
||||
{
|
||||
if (i < password->Length)
|
||||
password->Text[i] += keyPool[i];
|
||||
else
|
||||
password->Text[i] = keyPool[i];
|
||||
}
|
||||
|
||||
if (password->Length < (int)sizeof (keyPool))
|
||||
password->Length = sizeof (keyPool);
|
||||
|
||||
burn (keyPool, sizeof (keyPool));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static void LoadKeyList (HWND hwndDlg, KeyFile *firstKeyFile)
|
||||
{
|
||||
KeyFile *kf;
|
||||
LVITEM LvItem;
|
||||
int line = 0;
|
||||
HWND hList = GetDlgItem (hwndDlg, IDC_KEYLIST);
|
||||
|
||||
ListView_DeleteAllItems (hList);
|
||||
EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVE), FALSE);
|
||||
EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVEALL), firstKeyFile != NULL);
|
||||
SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, firstKeyFile != NULL);
|
||||
|
||||
for (kf = firstKeyFile; kf != NULL; kf = kf->Next)
|
||||
{
|
||||
memset (&LvItem,0,sizeof(LvItem));
|
||||
LvItem.mask = LVIF_TEXT|LVIF_PARAM;
|
||||
LvItem.iItem = line++;
|
||||
LvItem.iSubItem = 0;
|
||||
LvItem.pszText = kf->FileName;
|
||||
LvItem.lParam = (LPARAM) kf;
|
||||
SendMessage (hList, LVM_INSERTITEM, 0, (LPARAM)&LvItem);
|
||||
}
|
||||
}
|
||||
|
||||
#if KEYFILE_POOL_SIZE % 4 != 0
|
||||
#error KEYFILE_POOL_SIZE must be a multiple of 4
|
||||
#endif
|
||||
|
||||
BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static KeyFilesDlgParam *param;
|
||||
static KeyFilesDlgParam origParam;
|
||||
|
||||
WORD lw = LOWORD (wParam);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
LVCOLUMNW LvCol;
|
||||
HWND hList = GetDlgItem (hwndDlg, IDC_KEYLIST);
|
||||
|
||||
param = (KeyFilesDlgParam *) lParam;
|
||||
origParam = *(KeyFilesDlgParam *) lParam;
|
||||
|
||||
param->FirstKeyFile = KeyFileCloneAll (param->FirstKeyFile);
|
||||
|
||||
LocalizeDialog (hwndDlg, "IDD_KEYFILES");
|
||||
DragAcceptFiles (hwndDlg, TRUE);
|
||||
|
||||
SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
|
||||
LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP
|
||||
);
|
||||
|
||||
memset (&LvCol,0,sizeof(LvCol));
|
||||
LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
|
||||
LvCol.pszText = GetString ("KEYFILE");
|
||||
LvCol.cx = CompensateXDPI (374);
|
||||
LvCol.fmt = LVCFMT_LEFT;
|
||||
SendMessageW (hList, LVM_INSERTCOLUMNW, 0, (LPARAM)&LvCol);
|
||||
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, param->EnableKeyFiles);
|
||||
|
||||
SetWindowTextW(GetDlgItem(hwndDlg, IDT_KEYFILES_NOTE), GetString ("KEYFILES_NOTE"));
|
||||
|
||||
ToHyperlink (hwndDlg, IDC_LINK_KEYFILES_INFO);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case WM_COMMAND:
|
||||
|
||||
if (lw == IDC_KEYADD)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, bHistory))
|
||||
{
|
||||
do
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
|
||||
kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
} while (SelectMultipleFilesNext (kf->FileName));
|
||||
}
|
||||
|
||||
free (kf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_ADD_KEYFILE_PATH)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
|
||||
if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
free (kf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_TOKEN_FILES_ADD)
|
||||
{
|
||||
list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
|
||||
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
|
||||
{
|
||||
foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
strcpy_s (kf->FileName, sizeof (kf->FileName), WideToSingleString (keyPath).c_str());
|
||||
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_KEYREMOVE)
|
||||
{
|
||||
HWND list = GetDlgItem (hwndDlg, IDC_KEYLIST);
|
||||
LVITEM LvItem;
|
||||
memset (&LvItem, 0, sizeof(LvItem));
|
||||
LvItem.mask = LVIF_PARAM;
|
||||
LvItem.iItem = -1;
|
||||
|
||||
while (-1 != (LvItem.iItem = ListView_GetNextItem (list, LvItem.iItem, LVIS_SELECTED)))
|
||||
{
|
||||
ListView_GetItem (list, &LvItem);
|
||||
param->FirstKeyFile = KeyFileRemove (param->FirstKeyFile, (KeyFile *) LvItem.lParam);
|
||||
}
|
||||
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_KEYREMOVEALL)
|
||||
{
|
||||
KeyFileRemoveAll (¶m->FirstKeyFile);
|
||||
LoadKeyList (hwndDlg, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_GENERATE_KEYFILE)
|
||||
{
|
||||
DialogBoxParamW (hInst,
|
||||
MAKEINTRESOURCEW (IDD_KEYFILE_GENERATOR), hwndDlg,
|
||||
(DLGPROC) KeyfileGeneratorDlgProc, (LPARAM) 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_LINK_KEYFILES_INFO)
|
||||
{
|
||||
Applink ("keyfiles", TRUE, "");
|
||||
}
|
||||
|
||||
if (lw == IDOK)
|
||||
{
|
||||
param->EnableKeyFiles = IsButtonChecked (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE));
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDCANCEL)
|
||||
{
|
||||
KeyFileRemoveAll (¶m->FirstKeyFile);
|
||||
*param = origParam;
|
||||
|
||||
EndDialog (hwndDlg, IDCLOSE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_DROPFILES:
|
||||
{
|
||||
HDROP hdrop = (HDROP) wParam;
|
||||
|
||||
int i = 0, count = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
|
||||
|
||||
while (count-- > 0)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
DragQueryFile (hdrop, i++, kf->FileName, sizeof (kf->FileName));
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
}
|
||||
|
||||
DragFinish (hdrop);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case WM_NOTIFY:
|
||||
if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
|
||||
{
|
||||
EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVE),
|
||||
ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_KEYLIST), -1, LVIS_SELECTED) != -1);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
KeyFileRemoveAll (¶m->FirstKeyFile);
|
||||
*param = origParam;
|
||||
|
||||
EndDialog (hwndDlg, IDCLOSE);
|
||||
return 1;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define IDM_KEYFILES_POPUP_ADD_FILES 9001
|
||||
#define IDM_KEYFILES_POPUP_ADD_DIR 9002
|
||||
#define IDM_KEYFILES_POPUP_ADD_TOKEN_FILES 9003
|
||||
|
||||
BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *param)
|
||||
{
|
||||
HMENU popup = CreatePopupMenu ();
|
||||
int sel;
|
||||
BOOL status = FALSE;
|
||||
|
||||
AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_FILES, GetString ("IDC_KEYADD"));
|
||||
AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_DIR, GetString ("IDC_ADD_KEYFILE_PATH"));
|
||||
AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_TOKEN_FILES, GetString ("IDC_TOKEN_FILES_ADD"));
|
||||
|
||||
sel = TrackPopupMenu (popup, TPM_RETURNCMD | TPM_LEFTBUTTON, popupPosition.x, popupPosition.y, 0, hwndDlg, NULL);
|
||||
|
||||
switch (sel)
|
||||
{
|
||||
case IDM_KEYFILES_POPUP_ADD_FILES:
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, bHistory))
|
||||
{
|
||||
do
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
} while (SelectMultipleFilesNext (kf->FileName));
|
||||
|
||||
param->EnableKeyFiles = TRUE;
|
||||
status = TRUE;
|
||||
}
|
||||
|
||||
free (kf);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_KEYFILES_POPUP_ADD_DIR:
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
|
||||
if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
param->EnableKeyFiles = TRUE;
|
||||
status = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (kf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_KEYFILES_POPUP_ADD_TOKEN_FILES:
|
||||
{
|
||||
list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
|
||||
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
|
||||
{
|
||||
foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
strcpy_s (kf->FileName, sizeof (kf->FileName), WideToSingleString (keyPath).c_str());
|
||||
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
param->EnableKeyFiles = TRUE;
|
||||
status = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DestroyMenu (popup);
|
||||
return status;
|
||||
}
|
48
src/Common/Keyfiles.h
Normal file
48
src/Common/Keyfiles.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (c) 2005 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef KEYFILES_H
|
||||
#define KEYFILES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#define KEYFILE_POOL_SIZE 64
|
||||
#define KEYFILE_MAX_READ_LEN (1024*1024)
|
||||
|
||||
typedef struct KeyFileStruct
|
||||
{
|
||||
char FileName[MAX_PATH];
|
||||
struct KeyFileStruct *Next;
|
||||
} KeyFile;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL EnableKeyFiles;
|
||||
KeyFile *FirstKeyFile;
|
||||
} KeyFilesDlgParam;
|
||||
|
||||
KeyFile *KeyFileAdd (KeyFile *firstKeyFile, KeyFile *keyFile);
|
||||
void KeyFileRemoveAll (KeyFile **firstKeyFile);
|
||||
KeyFile *KeyFileClone (KeyFile *keyFile);
|
||||
KeyFile *KeyFileCloneAll (KeyFile *firstKeyFile);
|
||||
BOOL KeyFilesApply (Password *password, KeyFile *firstKeyFile);
|
||||
|
||||
BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *dialogParam);
|
||||
|
||||
extern BOOL HiddenFilesPresentInKeyfilePath;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef KEYFILES_H */
|
515
src/Common/Language.c
Normal file
515
src/Common/Language.c
Normal file
@ -0,0 +1,515 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Language.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Tcdefs.h"
|
||||
#include "Xml.h"
|
||||
|
||||
#include "../Common/Resource.h"
|
||||
|
||||
#ifdef TCMOUNT
|
||||
#include "../Mount/Resource.h"
|
||||
#endif
|
||||
|
||||
#ifdef VOLFORMAT
|
||||
#include "../Format/Resource.h"
|
||||
#endif
|
||||
|
||||
#ifdef SETUP
|
||||
#include "../Setup/Resource.h"
|
||||
#endif
|
||||
|
||||
BOOL LocalizationActive;
|
||||
int LocalizationSerialNo;
|
||||
|
||||
wchar_t UnknownString[1024];
|
||||
static char *LanguageFileBuffer;
|
||||
static HANDLE LanguageFileFindHandle = INVALID_HANDLE_VALUE;
|
||||
static char PreferredLangId[6];
|
||||
static char *LanguageResource;
|
||||
static char *HeaderResource[2];
|
||||
static char ActiveLangPackVersion[6];
|
||||
|
||||
static char *MapFirstLanguageFile ()
|
||||
{
|
||||
if (LanguageFileFindHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FindClose (LanguageFileFindHandle);
|
||||
LanguageFileFindHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (LanguageResource == NULL)
|
||||
{
|
||||
DWORD size;
|
||||
LanguageResource = MapResource ("Xml", IDR_LANGUAGE, &size);
|
||||
LanguageResource[size - 1] = 0;
|
||||
}
|
||||
|
||||
return LanguageResource;
|
||||
}
|
||||
|
||||
|
||||
static char *MapNextLanguageFile ()
|
||||
{
|
||||
wchar_t f[TC_MAX_PATH*2], *t;
|
||||
WIN32_FIND_DATAW find;
|
||||
HANDLE file;
|
||||
DWORD read;
|
||||
|
||||
if (LanguageFileFindHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
GetModuleFileNameW (NULL, f, sizeof (f) / sizeof (f[0]));
|
||||
t = wcsrchr (f, L'\\');
|
||||
if (t == NULL) return NULL;
|
||||
|
||||
wcscpy (t, L"\\Language*.xml");
|
||||
|
||||
LanguageFileFindHandle = FindFirstFileW (f, &find);
|
||||
}
|
||||
else if (!FindNextFileW (LanguageFileFindHandle, &find))
|
||||
{
|
||||
FindClose (LanguageFileFindHandle);
|
||||
LanguageFileFindHandle = INVALID_HANDLE_VALUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (find.nFileSizeHigh != 0) return NULL;
|
||||
|
||||
if (LanguageFileBuffer != NULL) free (LanguageFileBuffer);
|
||||
LanguageFileBuffer = malloc(find.nFileSizeLow);
|
||||
if (LanguageFileBuffer == NULL) return NULL;
|
||||
|
||||
GetModuleFileNameW (NULL, f, sizeof (f) / sizeof(f[0]));
|
||||
t = wcsrchr (f, L'\\');
|
||||
wcscpy (t + 1, find.cFileName);
|
||||
|
||||
file = CreateFileW (f, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) return NULL;
|
||||
|
||||
ReadFile (file, LanguageFileBuffer, find.nFileSizeLow, &read, NULL);
|
||||
CloseHandle (file);
|
||||
if (read != find.nFileSizeLow) return NULL;
|
||||
|
||||
return LanguageFileBuffer;
|
||||
}
|
||||
|
||||
|
||||
BOOL LoadLanguageFile ()
|
||||
{
|
||||
DWORD size;
|
||||
BYTE *res;
|
||||
char *xml, *header;
|
||||
char langId[6] = "en", attr[32768], key[128];
|
||||
BOOL defaultLangParsed = FALSE, langFound = FALSE;
|
||||
WCHAR wattr[32768];
|
||||
int i, intKey, len;
|
||||
|
||||
char *xmlElements[] = {"control", "string", 0};
|
||||
|
||||
#ifdef TCMOUNT
|
||||
int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_MOUNT_RSRC_HEADER, 0 };
|
||||
#endif
|
||||
|
||||
#ifdef VOLFORMAT
|
||||
int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_FORMAT_RSRC_HEADER, 0 };
|
||||
#endif
|
||||
|
||||
#ifdef SETUP
|
||||
int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_SETUP_RSRC_HEADER, 0 };
|
||||
#endif
|
||||
|
||||
LocalizationActive = FALSE;
|
||||
ActiveLangPackVersion[0] = 0;
|
||||
ClearDictionaryPool ();
|
||||
|
||||
if (PreferredLangId[0] != 0)
|
||||
strcpy (langId, PreferredLangId);
|
||||
|
||||
// Parse all available language files until preferred language is found
|
||||
for (res = MapFirstLanguageFile (); res != NULL; res = MapNextLanguageFile ())
|
||||
{
|
||||
xml = (char *) res;
|
||||
xml = XmlFindElement (xml, "localization");
|
||||
if (!xml)
|
||||
continue;
|
||||
|
||||
// Required TrueCrypt version
|
||||
XmlGetAttributeText (xml, "prog-version", attr, sizeof (attr));
|
||||
|
||||
// Check version of external language file
|
||||
if (defaultLangParsed && strcmp (attr, VERSION_STRING) && strcmp (attr, "DEBUG"))
|
||||
{
|
||||
wchar_t m[2048];
|
||||
swprintf (m, L"The installed language pack is incompatible with this version of TrueCrypt (the language pack is for TrueCrypt %hs). A newer version may be available at www.truecrypt.org.\n\nTo prevent this message from being displayed, do any of the following:\n\n- Select 'Settings' > 'Language'; then select 'English' and click 'OK'.\n\n- Remove or replace the language pack with a compatible version (the language pack may reside e.g. in 'C:\\Program Files\\TrueCrypt' or '%%LOCALAPPDATA%%\\VirtualStore\\Program Files\\TrueCrypt', etc.)", attr);
|
||||
MessageBoxW (NULL, m, L"TrueCrypt", MB_ICONERROR);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Search language id in language file
|
||||
if (defaultLangParsed)
|
||||
{
|
||||
while (xml = XmlFindElement (xml, "language"))
|
||||
{
|
||||
XmlGetAttributeText (xml, "langid", attr, sizeof (attr));
|
||||
if (strcmp (attr, langId) == 0)
|
||||
{
|
||||
XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion));
|
||||
langFound = TRUE;
|
||||
break;
|
||||
}
|
||||
xml++;
|
||||
}
|
||||
|
||||
if (!langFound) continue;
|
||||
}
|
||||
|
||||
// Create font dictionary
|
||||
xml = (char *) res;
|
||||
while (xml = XmlFindElement (xml, "font"))
|
||||
{
|
||||
XmlGetAttributeText (xml, "lang", attr, sizeof (attr));
|
||||
if (!defaultLangParsed
|
||||
|| strcmp (attr, langId) == 0)
|
||||
{
|
||||
Font font;
|
||||
memset (&font, 0, sizeof (font));
|
||||
|
||||
XmlGetAttributeText (xml, "face", attr, sizeof (attr));
|
||||
|
||||
len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
|
||||
font.FaceName = AddPoolData ((void *) wattr, len * 2);
|
||||
|
||||
XmlGetAttributeText (xml, "size", attr, sizeof (attr));
|
||||
sscanf (attr, "%d", &font.Size);
|
||||
|
||||
strcpy (attr, "font_");
|
||||
XmlGetAttributeText (xml, "class", attr + 5, sizeof (attr) - 5);
|
||||
AddDictionaryEntry (
|
||||
AddPoolData ((void *) attr, strlen (attr) + 1), 0,
|
||||
AddPoolData ((void *) &font, sizeof(font)));
|
||||
}
|
||||
|
||||
xml++;
|
||||
}
|
||||
|
||||
// Create string and control dictionaries
|
||||
for (i = 0; xmlElements[i] != 0; i++)
|
||||
{
|
||||
xml = (char *) res;
|
||||
while (xml = XmlFindElement (xml, xmlElements[i]))
|
||||
{
|
||||
void *key;
|
||||
void *text;
|
||||
|
||||
XmlGetAttributeText (xml, "lang", attr, sizeof (attr));
|
||||
if (!defaultLangParsed
|
||||
|| strcmp (attr, langId) == 0)
|
||||
{
|
||||
if (XmlGetAttributeText (xml, "key", attr, sizeof (attr)))
|
||||
{
|
||||
key = AddPoolData (attr, strlen (attr) + 1);
|
||||
if (key == NULL) return FALSE;
|
||||
|
||||
XmlGetNodeText (xml, attr, sizeof (attr));
|
||||
|
||||
// Parse \ escape sequences
|
||||
{
|
||||
char *in = attr, *out = attr;
|
||||
while (*in)
|
||||
{
|
||||
if (*in == '\\')
|
||||
{
|
||||
in++;
|
||||
switch (*in++)
|
||||
{
|
||||
case '\\': *out++ = '\\'; break;
|
||||
case 't': *out++ = '\t'; break;
|
||||
case 'n': *out++ = 13; *out++ = 10; break;
|
||||
default:
|
||||
MessageBox (0, key, "TrueCrypt: Unknown '\\' escape sequence in string", MB_ICONERROR);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
*out++ = *in++;
|
||||
}
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
// UTF8 => wide char
|
||||
len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
|
||||
if (len == 0 || len == ERROR_NO_UNICODE_TRANSLATION)
|
||||
{
|
||||
MessageBox (0, key, "TrueCrypt: Error while decoding UTF-8 string", MB_ICONERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Add to dictionary
|
||||
text = AddPoolData ((void *) wattr, len * 2);
|
||||
if (text == NULL) return FALSE;
|
||||
|
||||
AddDictionaryEntry ((char *) key, 0, text);
|
||||
}
|
||||
}
|
||||
|
||||
xml++;
|
||||
}
|
||||
}
|
||||
|
||||
if (langFound)
|
||||
break;
|
||||
|
||||
if (!defaultLangParsed)
|
||||
{
|
||||
defaultLangParsed = TRUE;
|
||||
if (langId[0] == 0 || strcmp (langId, "en") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LocalizationActive = langFound && strcmp (langId, "en") != 0;
|
||||
LocalizationSerialNo++;
|
||||
|
||||
// Create control ID dictionary
|
||||
|
||||
// Default controls
|
||||
AddDictionaryEntry (NULL, 1, GetString ("IDOK"));
|
||||
AddDictionaryEntry (NULL, 2, GetString ("IDCANCEL"));
|
||||
AddDictionaryEntry (NULL, 8, GetString ("IDCLOSE"));
|
||||
AddDictionaryEntry (NULL, 9, GetString ("IDHELP"));
|
||||
|
||||
for (i = 0; headers[i] != 0; i++)
|
||||
{
|
||||
if (HeaderResource[i] == NULL)
|
||||
{
|
||||
HeaderResource[i] = MapResource ("Header", headers[i], &size);
|
||||
*(HeaderResource[i] + size - 1) = 0;
|
||||
}
|
||||
|
||||
header = HeaderResource[i];
|
||||
if (header == NULL) return FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
if (sscanf (header, "#define %s %d", key, &intKey) == 2)
|
||||
{
|
||||
WCHAR *str = GetString (key);
|
||||
|
||||
if (str != UnknownString)
|
||||
AddDictionaryEntry (NULL, intKey, str);
|
||||
}
|
||||
|
||||
} while ((header = strchr (header, '\n') + 1) != (char *) 1);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// lParam = 1: auto mode
|
||||
BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WORD lw = LOWORD (wParam);
|
||||
WORD hw = HIWORD (wParam);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
char *xml;
|
||||
char attr[2048], lastLangId[10];
|
||||
WCHAR wattr[2048];
|
||||
int len;
|
||||
int langCount = 0;
|
||||
BOOL defaultLangFound = FALSE;
|
||||
|
||||
LocalizeDialog (hwndDlg, "IDD_LANGUAGE");
|
||||
ToHyperlink (hwndDlg, IDC_GET_LANG_PACKS);
|
||||
|
||||
for (xml = MapFirstLanguageFile (); xml != NULL; xml = MapNextLanguageFile ())
|
||||
{
|
||||
while (xml = XmlFindElement (xml, "language"))
|
||||
{
|
||||
XmlGetAttributeText (xml, "name", attr, sizeof (attr));
|
||||
len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
|
||||
|
||||
if (len != 0 && len != ERROR_NO_UNICODE_TRANSLATION
|
||||
&& (!defaultLangFound || wcscmp (wattr, L"English") != 0))
|
||||
{
|
||||
int i = SendDlgItemMessageW (hwndDlg, IDC_LANGLIST, LB_ADDSTRING, 0, (LPARAM)wattr);
|
||||
if (i >= 0)
|
||||
{
|
||||
int id;
|
||||
|
||||
// Encode language id in LPARAM
|
||||
XmlGetAttributeText (xml, "langid", attr, sizeof (attr));
|
||||
switch (strlen (attr))
|
||||
{
|
||||
case 2: id = attr[0] | attr[1] << 8; break;
|
||||
case 5: id = attr[0] | attr[1] << 8 | attr[3] << 16 | attr[4] << 24; break;
|
||||
default: continue;
|
||||
}
|
||||
|
||||
if (!defaultLangFound)
|
||||
defaultLangFound = TRUE;
|
||||
|
||||
SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETITEMDATA, i, (LPARAM) id);
|
||||
|
||||
if (strcmp (attr, PreferredLangId) == 0)
|
||||
{
|
||||
char credits [10000];
|
||||
WCHAR wcredits [10000];
|
||||
WCHAR wversion [20];
|
||||
wchar_t szVers [200];
|
||||
int nLen;
|
||||
|
||||
SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETCURSEL, i, 0);
|
||||
|
||||
// Language pack version
|
||||
if (!ActiveLangPackVersion[0] || memcmp (ActiveLangPackVersion, "0.0.0", 5) == 0)
|
||||
{
|
||||
swprintf (szVers, GetString("LANG_PACK_VERSION"), L"--");
|
||||
}
|
||||
else
|
||||
{
|
||||
nLen = MultiByteToWideChar (CP_UTF8, 0, ActiveLangPackVersion, -1, wversion, sizeof (wversion) / sizeof(wversion[0]));
|
||||
if (nLen != 0 && nLen != ERROR_NO_UNICODE_TRANSLATION)
|
||||
swprintf (szVers, GetString("LANG_PACK_VERSION"), wversion);
|
||||
}
|
||||
SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_VERSION), szVers);
|
||||
|
||||
// Translator credits
|
||||
XmlGetAttributeText (xml, "translators", credits, sizeof (credits));
|
||||
nLen = MultiByteToWideChar (CP_UTF8, 0, credits, -1, wcredits, sizeof (wcredits) / sizeof(wcredits[0]));
|
||||
if (nLen != 0 && nLen != ERROR_NO_UNICODE_TRANSLATION)
|
||||
{
|
||||
SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_CREDITS), wcredits);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy (lastLangId, attr);
|
||||
langCount++;
|
||||
}
|
||||
}
|
||||
|
||||
xml++;
|
||||
}
|
||||
}
|
||||
|
||||
if (lParam == 1)
|
||||
{
|
||||
// Auto mode
|
||||
if (langCount < 2)
|
||||
EndDialog (hwndDlg, IDCANCEL);
|
||||
|
||||
if (langCount == 2)
|
||||
strcpy (PreferredLangId, lastLangId);
|
||||
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
|
||||
if (lw == IDOK || hw == LBN_DBLCLK)
|
||||
{
|
||||
int i = SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCURSEL, 0, 0);
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
int id = SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETITEMDATA, i, 0);
|
||||
|
||||
if (id != LB_ERR)
|
||||
{
|
||||
char l[6];
|
||||
|
||||
// Decode language id from LPARAM
|
||||
l[0] = (char) id;
|
||||
l[1] = (char) (id >> 8);
|
||||
l[2] = 0;
|
||||
|
||||
if ((id & 0xffff0000) != 0)
|
||||
{
|
||||
l[2] = '-';
|
||||
l[3] = (char) (id >> 16);
|
||||
l[4] = id >> 24;
|
||||
l[5] = 0;
|
||||
}
|
||||
|
||||
if (SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCOUNT, 0, 0) > 1)
|
||||
strcpy (PreferredLangId, l);
|
||||
}
|
||||
}
|
||||
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDCANCEL)
|
||||
{
|
||||
EndDialog (hwndDlg, lw);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_GET_LANG_PACKS)
|
||||
{
|
||||
char tmpstr [256];
|
||||
|
||||
if (strlen (ActiveLangPackVersion) > 0 && strlen (GetPreferredLangId()) > 0)
|
||||
sprintf (tmpstr, "&langpackversion=%s&lang=%s", ActiveLangPackVersion, GetPreferredLangId());
|
||||
else
|
||||
tmpstr[0] = 0;
|
||||
|
||||
Applink ("localizations", TRUE, tmpstr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *GetPreferredLangId ()
|
||||
{
|
||||
return PreferredLangId;
|
||||
}
|
||||
|
||||
|
||||
void SetPreferredLangId (char *langId)
|
||||
{
|
||||
strncpy (PreferredLangId, langId, 5);
|
||||
}
|
||||
|
||||
|
||||
char *GetActiveLangPackVersion ()
|
||||
{
|
||||
return ActiveLangPackVersion;
|
||||
}
|
||||
|
||||
|
||||
wchar_t *GetString (const char *stringId)
|
||||
{
|
||||
WCHAR *str = (WCHAR *) GetDictionaryValue (stringId);
|
||||
if (str != NULL) return str;
|
||||
|
||||
wsprintfW (UnknownString, UNKNOWN_STRING_ID L"%hs" UNKNOWN_STRING_ID, stringId);
|
||||
return UnknownString;
|
||||
}
|
||||
|
||||
|
||||
Font *GetFont (char *fontType)
|
||||
{
|
||||
return (Font *) GetDictionaryValue (fontType);
|
||||
|
||||
}
|
37
src/Common/Language.h
Normal file
37
src/Common/Language.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UNKNOWN_STRING_ID L"[?]"
|
||||
|
||||
extern BOOL LocalizationActive;
|
||||
extern int LocalizationSerialNo;
|
||||
extern wchar_t UnknownString[1024];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wchar_t *FaceName;
|
||||
int Size;
|
||||
} Font;
|
||||
|
||||
BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
wchar_t *GetString (const char *stringId);
|
||||
Font *GetFont (char *fontType);
|
||||
BOOL LoadLanguageFile ();
|
||||
char *GetPreferredLangId ();
|
||||
void SetPreferredLangId (char *langId);
|
||||
char *GetActiveLangPackVersion ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
1341
src/Common/Language.xml
Normal file
1341
src/Common/Language.xml
Normal file
File diff suppressed because it is too large
Load Diff
1
src/Common/Makefile
Normal file
1
src/Common/Makefile
Normal file
@ -0,0 +1 @@
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
422
src/Common/Password.c
Normal file
422
src/Common/Password.c
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include "Crypto.h"
|
||||
#include "Volumes.h"
|
||||
#include "Password.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Language.h"
|
||||
#include "Pkcs5.h"
|
||||
#include "Endian.h"
|
||||
#include "Random.h"
|
||||
|
||||
#include <io.h>
|
||||
|
||||
void VerifyPasswordAndUpdate (HWND hwndDlg, HWND hButton, HWND hPassword,
|
||||
HWND hVerify, unsigned char *szPassword,
|
||||
char *szVerify,
|
||||
BOOL keyFilesEnabled)
|
||||
{
|
||||
char szTmp1[MAX_PASSWORD + 1];
|
||||
char szTmp2[MAX_PASSWORD + 1];
|
||||
int k = GetWindowTextLength (hPassword);
|
||||
BOOL bEnable = FALSE;
|
||||
|
||||
if (hwndDlg); /* Remove warning */
|
||||
|
||||
GetWindowText (hPassword, szTmp1, sizeof (szTmp1));
|
||||
GetWindowText (hVerify, szTmp2, sizeof (szTmp2));
|
||||
|
||||
if (strcmp (szTmp1, szTmp2) != 0)
|
||||
bEnable = FALSE;
|
||||
else
|
||||
{
|
||||
if (k >= MIN_PASSWORD || keyFilesEnabled)
|
||||
bEnable = TRUE;
|
||||
else
|
||||
bEnable = FALSE;
|
||||
}
|
||||
|
||||
if (szPassword != NULL)
|
||||
memcpy (szPassword, szTmp1, sizeof (szTmp1));
|
||||
|
||||
if (szVerify != NULL)
|
||||
memcpy (szVerify, szTmp2, sizeof (szTmp2));
|
||||
|
||||
burn (szTmp1, sizeof (szTmp1));
|
||||
burn (szTmp2, sizeof (szTmp2));
|
||||
|
||||
EnableWindow (hButton, bEnable);
|
||||
}
|
||||
|
||||
|
||||
BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
if (hPassword == NULL)
|
||||
{
|
||||
unsigned char *pw;
|
||||
len = ptrPw->Length;
|
||||
pw = (unsigned char *) ptrPw->Text;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (pw[i] >= 0x7f || pw[i] < 0x20) // A non-ASCII or non-printable character?
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t s[MAX_PASSWORD + 1];
|
||||
len = GetWindowTextLength (hPassword);
|
||||
|
||||
if (len > MAX_PASSWORD)
|
||||
return FALSE;
|
||||
|
||||
GetWindowTextW (hPassword, s, sizeof (s) / sizeof (wchar_t));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (s[i] >= 0x7f || s[i] < 0x20) // A non-ASCII or non-printable character?
|
||||
break;
|
||||
}
|
||||
|
||||
burn (s, sizeof(s));
|
||||
|
||||
if (i < len)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CheckPasswordLength (HWND hwndDlg, HWND hwndItem)
|
||||
{
|
||||
if (GetWindowTextLength (hwndItem) < PASSWORD_LEN_WARNING)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
if (MessageBoxW (hwndDlg, GetString ("PASSWORD_LENGTH_WARNING"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2) != IDYES)
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int ChangePwd (char *lpszVolume, Password *oldPassword, Password *newPassword, int pkcs5, HWND hwndDlg)
|
||||
{
|
||||
int nDosLinkCreated = 1, nStatus = ERR_OS_ERROR;
|
||||
char szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH];
|
||||
char szDosDevice[TC_MAX_PATH];
|
||||
char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
|
||||
PCRYPTO_INFO cryptoInfo = NULL, ci = NULL;
|
||||
void *dev = INVALID_HANDLE_VALUE;
|
||||
DWORD dwError;
|
||||
DWORD bytesRead;
|
||||
BOOL bDevice;
|
||||
unsigned __int64 hostSize = 0;
|
||||
int volumeType;
|
||||
int wipePass;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
BOOL bTimeStampValid = FALSE;
|
||||
LARGE_INTEGER headerOffset;
|
||||
BOOL backupHeader;
|
||||
DISK_GEOMETRY driveInfo;
|
||||
|
||||
if (oldPassword->Length == 0 || newPassword->Length == 0) return -1;
|
||||
|
||||
WaitCursor ();
|
||||
|
||||
CreateFullVolumePath (szDiskFile, lpszVolume, &bDevice);
|
||||
|
||||
if (bDevice == FALSE)
|
||||
{
|
||||
strcpy (szCFDevice, szDiskFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, szCFDevice, FALSE);
|
||||
|
||||
if (nDosLinkCreated != 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev = CreateFile (szCFDevice, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (dev == INVALID_HANDLE_VALUE)
|
||||
goto error;
|
||||
|
||||
if (bDevice)
|
||||
{
|
||||
/* This is necessary to determine the hidden volume header offset */
|
||||
|
||||
if (dev == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
PARTITION_INFORMATION diskInfo;
|
||||
DWORD dwResult;
|
||||
BOOL bResult;
|
||||
|
||||
bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
|
||||
&driveInfo, sizeof (driveInfo), &dwResult, NULL);
|
||||
|
||||
if (!bResult)
|
||||
goto error;
|
||||
|
||||
bResult = GetPartitionInfo (lpszVolume, &diskInfo);
|
||||
|
||||
if (bResult)
|
||||
{
|
||||
hostSize = diskInfo.PartitionLength.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
hostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector *
|
||||
driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder;
|
||||
}
|
||||
|
||||
if (hostSize == 0)
|
||||
{
|
||||
nStatus = ERR_VOL_SIZE_WRONG;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx (dev, &fileSize))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
hostSize = fileSize.QuadPart;
|
||||
}
|
||||
|
||||
if (Randinit ())
|
||||
goto error;
|
||||
|
||||
if (!bDevice && bPreserveTimestamp)
|
||||
{
|
||||
if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
|
||||
bTimeStampValid = FALSE;
|
||||
else
|
||||
bTimeStampValid = TRUE;
|
||||
}
|
||||
|
||||
for (volumeType = TC_VOLUME_TYPE_NORMAL; volumeType < TC_VOLUME_TYPE_COUNT; volumeType++)
|
||||
{
|
||||
// Seek the volume header
|
||||
switch (volumeType)
|
||||
{
|
||||
case TC_VOLUME_TYPE_NORMAL:
|
||||
headerOffset.QuadPart = TC_VOLUME_HEADER_OFFSET;
|
||||
break;
|
||||
|
||||
case TC_VOLUME_TYPE_HIDDEN:
|
||||
if (TC_HIDDEN_VOLUME_HEADER_OFFSET + TC_VOLUME_HEADER_SIZE > hostSize)
|
||||
continue;
|
||||
|
||||
headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||
break;
|
||||
|
||||
case TC_VOLUME_TYPE_HIDDEN_LEGACY:
|
||||
if (bDevice && driveInfo.BytesPerSector != TC_SECTOR_SIZE_LEGACY)
|
||||
continue;
|
||||
|
||||
headerOffset.QuadPart = hostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Read in volume header */
|
||||
if (!ReadEffectiveVolumeHeader (bDevice, dev, buffer, &bytesRead))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bytesRead != sizeof (buffer))
|
||||
{
|
||||
// Windows may report EOF when reading sectors from the last cluster of a device formatted as NTFS
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
}
|
||||
|
||||
/* Try to decrypt the header */
|
||||
|
||||
nStatus = ReadVolumeHeader (FALSE, buffer, oldPassword, &cryptoInfo, NULL);
|
||||
if (nStatus == ERR_CIPHER_INIT_WEAK_KEY)
|
||||
nStatus = 0; // We can ignore this error here
|
||||
|
||||
if (nStatus == ERR_PASSWORD_WRONG)
|
||||
{
|
||||
continue; // Try next volume type
|
||||
}
|
||||
else if (nStatus != 0)
|
||||
{
|
||||
cryptoInfo = NULL;
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (nStatus != 0)
|
||||
{
|
||||
cryptoInfo = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM)
|
||||
{
|
||||
nStatus = ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Change the PKCS-5 PRF if requested by user
|
||||
if (pkcs5 != 0)
|
||||
cryptoInfo->pkcs5 = pkcs5;
|
||||
|
||||
RandSetHashFunction (cryptoInfo->pkcs5);
|
||||
|
||||
NormalCursor();
|
||||
UserEnrichRandomPool (hwndDlg);
|
||||
EnableElevatedCursorChange (hwndDlg);
|
||||
WaitCursor();
|
||||
|
||||
/* Re-encrypt the volume header */
|
||||
backupHeader = FALSE;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using
|
||||
techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
|
||||
to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
|
||||
times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
|
||||
impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
|
||||
valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
|
||||
recommends. During each pass we will write a valid working header. Each pass will use the same master
|
||||
key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
|
||||
item that will be different for each pass will be the salt. This is sufficient to cause each "version"
|
||||
of the header to differ substantially and in a random manner from the versions written during the
|
||||
other passes. */
|
||||
|
||||
for (wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
|
||||
{
|
||||
// Prepare new volume header
|
||||
nStatus = CreateVolumeHeaderInMemory (FALSE,
|
||||
buffer,
|
||||
cryptoInfo->ea,
|
||||
cryptoInfo->mode,
|
||||
newPassword,
|
||||
cryptoInfo->pkcs5,
|
||||
cryptoInfo->master_keydata,
|
||||
&ci,
|
||||
cryptoInfo->VolumeSize.Value,
|
||||
(volumeType == TC_VOLUME_TYPE_HIDDEN || volumeType == TC_VOLUME_TYPE_HIDDEN_LEGACY) ? cryptoInfo->hiddenVolumeSize : 0,
|
||||
cryptoInfo->EncryptedAreaStart.Value,
|
||||
cryptoInfo->EncryptedAreaLength.Value,
|
||||
cryptoInfo->RequiredProgramVersion,
|
||||
cryptoInfo->HeaderFlags,
|
||||
cryptoInfo->SectorSize,
|
||||
wipePass < PRAND_DISK_WIPE_PASSES - 1);
|
||||
|
||||
if (ci != NULL)
|
||||
crypto_close (ci);
|
||||
|
||||
if (nStatus != 0)
|
||||
goto error;
|
||||
|
||||
if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!WriteEffectiveVolumeHeader (bDevice, dev, buffer))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bDevice
|
||||
&& !cryptoInfo->LegacyVolume
|
||||
&& !cryptoInfo->hiddenVolume
|
||||
&& cryptoInfo->HeaderVersion == 4
|
||||
&& (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) != 0
|
||||
&& (cryptoInfo->HeaderFlags & ~TC_HEADER_FLAG_NONSYS_INPLACE_ENC) == 0)
|
||||
{
|
||||
nStatus = WriteRandomDataToReservedHeaderAreas (dev, cryptoInfo, cryptoInfo->VolumeSize.Value, !backupHeader, backupHeader);
|
||||
if (nStatus != ERR_SUCCESS)
|
||||
goto error;
|
||||
}
|
||||
|
||||
FlushFileBuffers (dev);
|
||||
}
|
||||
|
||||
if (backupHeader || cryptoInfo->LegacyVolume)
|
||||
break;
|
||||
|
||||
backupHeader = TRUE;
|
||||
headerOffset.QuadPart += hostSize - TC_VOLUME_HEADER_GROUP_SIZE;
|
||||
}
|
||||
|
||||
/* Password successfully changed */
|
||||
nStatus = 0;
|
||||
|
||||
error:
|
||||
dwError = GetLastError ();
|
||||
|
||||
burn (buffer, sizeof (buffer));
|
||||
|
||||
if (cryptoInfo != NULL)
|
||||
crypto_close (cryptoInfo);
|
||||
|
||||
if (bTimeStampValid)
|
||||
SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);
|
||||
|
||||
if (dev != INVALID_HANDLE_VALUE)
|
||||
CloseHandle ((HANDLE) dev);
|
||||
|
||||
if (nDosLinkCreated == 0)
|
||||
RemoveFakeDosName (szDiskFile, szDosDevice);
|
||||
|
||||
RandStop (FALSE);
|
||||
NormalCursor ();
|
||||
|
||||
SetLastError (dwError);
|
||||
|
||||
if (nStatus == ERR_OS_ERROR && dwError == ERROR_ACCESS_DENIED
|
||||
&& bDevice
|
||||
&& !UacElevated
|
||||
&& IsUacSupported ())
|
||||
return nStatus;
|
||||
|
||||
if (nStatus != 0)
|
||||
handleError (hwndDlg, nStatus);
|
||||
|
||||
return nStatus;
|
||||
}
|
||||
|
46
src/Common/Password.h
Normal file
46
src/Common/Password.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef PASSWORD_H
|
||||
#define PASSWORD_H
|
||||
|
||||
// User text input limits
|
||||
#define MIN_PASSWORD 1 // Minimum possible password length
|
||||
#define MAX_PASSWORD 64 // Maximum possible password length
|
||||
|
||||
#define PASSWORD_LEN_WARNING 20 // Display a warning when a password is shorter than this
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Modifying this structure can introduce incompatibility with previous versions
|
||||
unsigned __int32 Length;
|
||||
unsigned char Text[MAX_PASSWORD + 1];
|
||||
char Pad[3]; // keep 64-bit alignment
|
||||
} Password;
|
||||
|
||||
#if defined(_WIN32) && !defined(TC_WINDOWS_DRIVER)
|
||||
|
||||
void VerifyPasswordAndUpdate ( HWND hwndDlg , HWND hButton , HWND hPassword , HWND hVerify , unsigned char *szPassword , char *szVerify, BOOL keyFilesEnabled );
|
||||
BOOL CheckPasswordLength (HWND hwndDlg, HWND hwndItem);
|
||||
BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw);
|
||||
int ChangePwd (char *lpszVolume, Password *oldPassword, Password *newPassword, int pkcs5, HWND hwndDlg);
|
||||
|
||||
#endif // defined(_WIN32) && !defined(TC_WINDOWS_DRIVER)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PASSWORD_H
|
642
src/Common/Pkcs5.c
Normal file
642
src/Common/Pkcs5.c
Normal file
@ -0,0 +1,642 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include "Rmd160.h"
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
#include "Sha1.h"
|
||||
#include "Sha2.h"
|
||||
#include "Whirlpool.h"
|
||||
#endif
|
||||
#include "Pkcs5.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
void hmac_truncate
|
||||
(
|
||||
char *d1, /* data to be truncated */
|
||||
char *d2, /* truncated data */
|
||||
int len /* length in bytes to keep */
|
||||
)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
d2[i] = d1[i];
|
||||
}
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
|
||||
void hmac_sha512
|
||||
(
|
||||
char *k, /* secret key */
|
||||
int lk, /* length of the key in bytes */
|
||||
char *d, /* data */
|
||||
int ld, /* length of data in bytes */
|
||||
char *out, /* output buffer, at least "t" bytes */
|
||||
int t
|
||||
)
|
||||
{
|
||||
sha512_ctx ictx, octx;
|
||||
char isha[SHA512_DIGESTSIZE], osha[SHA512_DIGESTSIZE];
|
||||
char key[SHA512_DIGESTSIZE];
|
||||
char buf[SHA512_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = sha512(key), as per HMAC specifications. */
|
||||
if (lk > SHA512_BLOCKSIZE)
|
||||
{
|
||||
sha512_ctx tctx;
|
||||
|
||||
sha512_begin (&tctx);
|
||||
sha512_hash ((unsigned char *) k, lk, &tctx);
|
||||
sha512_end ((unsigned char *) key, &tctx);
|
||||
|
||||
k = key;
|
||||
lk = SHA512_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/**** Inner Digest ****/
|
||||
|
||||
sha512_begin (&ictx);
|
||||
|
||||
/* Pad the key for inner digest */
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x36);
|
||||
for (i = lk; i < SHA512_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x36;
|
||||
|
||||
sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &ictx);
|
||||
sha512_hash ((unsigned char *) d, ld, &ictx);
|
||||
|
||||
sha512_end ((unsigned char *) isha, &ictx);
|
||||
|
||||
/**** Outer Digest ****/
|
||||
|
||||
sha512_begin (&octx);
|
||||
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x5C);
|
||||
for (i = lk; i < SHA512_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x5C;
|
||||
|
||||
sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &octx);
|
||||
sha512_hash ((unsigned char *) isha, SHA512_DIGESTSIZE, &octx);
|
||||
|
||||
sha512_end ((unsigned char *) osha, &octx);
|
||||
|
||||
/* truncate and print the results */
|
||||
t = t > SHA512_DIGESTSIZE ? SHA512_DIGESTSIZE : t;
|
||||
hmac_truncate (osha, out, t);
|
||||
|
||||
/* Prevent leaks */
|
||||
burn (&ictx, sizeof(ictx));
|
||||
burn (&octx, sizeof(octx));
|
||||
burn (isha, sizeof(isha));
|
||||
burn (osha, sizeof(osha));
|
||||
burn (buf, sizeof(buf));
|
||||
burn (key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[SHA512_DIGESTSIZE], k[SHA512_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_sha512 (pwd, pwd_len, init, salt_len + 4, j, SHA512_DIGESTSIZE);
|
||||
memcpy (u, j, SHA512_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_sha512 (pwd, pwd_len, j, SHA512_DIGESTSIZE, k, SHA512_DIGESTSIZE);
|
||||
for (i = 0; i < SHA512_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
|
||||
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[SHA512_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % SHA512_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / SHA512_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / SHA512_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * SHA512_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, SHA512_DIGESTSIZE);
|
||||
dk += SHA512_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
|
||||
/* Deprecated/legacy */
|
||||
void hmac_sha1
|
||||
(
|
||||
char *k, /* secret key */
|
||||
int lk, /* length of the key in bytes */
|
||||
char *d, /* data */
|
||||
int ld, /* length of data in bytes */
|
||||
char *out, /* output buffer, at least "t" bytes */
|
||||
int t
|
||||
)
|
||||
{
|
||||
sha1_ctx ictx, octx;
|
||||
char isha[SHA1_DIGESTSIZE], osha[SHA1_DIGESTSIZE];
|
||||
char key[SHA1_DIGESTSIZE];
|
||||
char buf[SHA1_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = sha1(key), as per HMAC specifications. */
|
||||
if (lk > SHA1_BLOCKSIZE)
|
||||
{
|
||||
sha1_ctx tctx;
|
||||
|
||||
sha1_begin (&tctx);
|
||||
sha1_hash ((unsigned char *) k, lk, &tctx);
|
||||
sha1_end ((unsigned char *) key, &tctx);
|
||||
|
||||
k = key;
|
||||
lk = SHA1_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/**** Inner Digest ****/
|
||||
|
||||
sha1_begin (&ictx);
|
||||
|
||||
/* Pad the key for inner digest */
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x36);
|
||||
for (i = lk; i < SHA1_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x36;
|
||||
|
||||
sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &ictx);
|
||||
sha1_hash ((unsigned char *) d, ld, &ictx);
|
||||
|
||||
sha1_end ((unsigned char *) isha, &ictx);
|
||||
|
||||
/**** Outer Digest ****/
|
||||
|
||||
sha1_begin (&octx);
|
||||
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x5C);
|
||||
for (i = lk; i < SHA1_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x5C;
|
||||
|
||||
sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &octx);
|
||||
sha1_hash ((unsigned char *) isha, SHA1_DIGESTSIZE, &octx);
|
||||
|
||||
sha1_end ((unsigned char *) osha, &octx);
|
||||
|
||||
/* truncate and print the results */
|
||||
t = t > SHA1_DIGESTSIZE ? SHA1_DIGESTSIZE : t;
|
||||
hmac_truncate (osha, out, t);
|
||||
|
||||
/* Prevent leaks */
|
||||
burn (&ictx, sizeof(ictx));
|
||||
burn (&octx, sizeof(octx));
|
||||
burn (isha, sizeof(isha));
|
||||
burn (osha, sizeof(osha));
|
||||
burn (buf, sizeof(buf));
|
||||
burn (key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
/* Deprecated/legacy */
|
||||
void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[SHA1_DIGESTSIZE], k[SHA1_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_sha1 (pwd, pwd_len, init, salt_len + 4, j, SHA1_DIGESTSIZE);
|
||||
memcpy (u, j, SHA1_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_sha1 (pwd, pwd_len, j, SHA1_DIGESTSIZE, k, SHA1_DIGESTSIZE);
|
||||
for (i = 0; i < SHA1_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
|
||||
/* Deprecated/legacy */
|
||||
void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[SHA1_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % SHA1_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / SHA1_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / SHA1_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * SHA1_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, SHA1_DIGESTSIZE);
|
||||
dk += SHA1_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
#endif // TC_WINDOWS_BOOT
|
||||
|
||||
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest)
|
||||
{
|
||||
RMD160_CTX context;
|
||||
unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
|
||||
unsigned char k_opad[65]; /* outer padding - key XORd with opad */
|
||||
unsigned char tk[RIPEMD160_DIGESTSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = ripemd160(key), as per HMAC specifications. */
|
||||
if (keylen > RIPEMD160_BLOCKSIZE)
|
||||
{
|
||||
RMD160_CTX tctx;
|
||||
|
||||
RMD160Init(&tctx);
|
||||
RMD160Update(&tctx, (const unsigned char *) key, keylen);
|
||||
RMD160Final(tk, &tctx);
|
||||
|
||||
key = (char *) tk;
|
||||
keylen = RIPEMD160_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
RMD160(K XOR opad, RMD160(K XOR ipad, text))
|
||||
|
||||
where K is an n byte key
|
||||
ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times
|
||||
opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times
|
||||
and text is the data being protected */
|
||||
|
||||
|
||||
/* start out by storing key in pads */
|
||||
memset(k_ipad, 0x36, sizeof(k_ipad));
|
||||
memset(k_opad, 0x5c, sizeof(k_opad));
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i=0; i<keylen; i++)
|
||||
{
|
||||
k_ipad[i] ^= key[i];
|
||||
k_opad[i] ^= key[i];
|
||||
}
|
||||
|
||||
/* perform inner RIPEMD-160 */
|
||||
|
||||
RMD160Init(&context); /* init context for 1st pass */
|
||||
RMD160Update(&context, k_ipad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
|
||||
RMD160Update(&context, (const unsigned char *) input, len); /* then text of datagram */
|
||||
RMD160Final((unsigned char *) digest, &context); /* finish up 1st pass */
|
||||
|
||||
/* perform outer RIPEMD-160 */
|
||||
RMD160Init(&context); /* init context for 2nd pass */
|
||||
RMD160Update(&context, k_opad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
|
||||
/* results of 1st hash */
|
||||
RMD160Update(&context, (const unsigned char *) digest, RIPEMD160_DIGESTSIZE);
|
||||
RMD160Final((unsigned char *) digest, &context); /* finish up 2nd pass */
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (k_ipad, sizeof(k_ipad));
|
||||
burn (k_opad, sizeof(k_opad));
|
||||
burn (tk, sizeof(tk));
|
||||
burn (&context, sizeof(context));
|
||||
}
|
||||
|
||||
void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[RIPEMD160_DIGESTSIZE], k[RIPEMD160_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_ripemd160 (pwd, pwd_len, init, salt_len + 4, j);
|
||||
memcpy (u, j, RIPEMD160_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_ripemd160 (pwd, pwd_len, j, RIPEMD160_DIGESTSIZE, k);
|
||||
for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[RIPEMD160_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % RIPEMD160_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / RIPEMD160_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / RIPEMD160_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, RIPEMD160_DIGESTSIZE);
|
||||
dk += RIPEMD160_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
|
||||
void hmac_whirlpool
|
||||
(
|
||||
char *k, /* secret key */
|
||||
int lk, /* length of the key in bytes */
|
||||
char *d, /* data */
|
||||
int ld, /* length of data in bytes */
|
||||
char *out, /* output buffer, at least "t" bytes */
|
||||
int t
|
||||
)
|
||||
{
|
||||
WHIRLPOOL_CTX ictx, octx;
|
||||
char iwhi[WHIRLPOOL_DIGESTSIZE], owhi[WHIRLPOOL_DIGESTSIZE];
|
||||
char key[WHIRLPOOL_DIGESTSIZE];
|
||||
char buf[WHIRLPOOL_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = whirlpool(key), as per HMAC specifications. */
|
||||
if (lk > WHIRLPOOL_BLOCKSIZE)
|
||||
{
|
||||
WHIRLPOOL_CTX tctx;
|
||||
|
||||
WHIRLPOOL_init (&tctx);
|
||||
WHIRLPOOL_add ((unsigned char *) k, lk * 8, &tctx);
|
||||
WHIRLPOOL_finalize (&tctx, (unsigned char *) key);
|
||||
|
||||
k = key;
|
||||
lk = WHIRLPOOL_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/**** Inner Digest ****/
|
||||
|
||||
WHIRLPOOL_init (&ictx);
|
||||
|
||||
/* Pad the key for inner digest */
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x36);
|
||||
for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x36;
|
||||
|
||||
WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &ictx);
|
||||
WHIRLPOOL_add ((unsigned char *) d, ld * 8, &ictx);
|
||||
|
||||
WHIRLPOOL_finalize (&ictx, (unsigned char *) iwhi);
|
||||
|
||||
/**** Outer Digest ****/
|
||||
|
||||
WHIRLPOOL_init (&octx);
|
||||
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x5C);
|
||||
for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x5C;
|
||||
|
||||
WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &octx);
|
||||
WHIRLPOOL_add ((unsigned char *) iwhi, WHIRLPOOL_DIGESTSIZE * 8, &octx);
|
||||
|
||||
WHIRLPOOL_finalize (&octx, (unsigned char *) owhi);
|
||||
|
||||
/* truncate and print the results */
|
||||
t = t > WHIRLPOOL_DIGESTSIZE ? WHIRLPOOL_DIGESTSIZE : t;
|
||||
hmac_truncate (owhi, out, t);
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (&ictx, sizeof(ictx));
|
||||
burn (&octx, sizeof(octx));
|
||||
burn (owhi, sizeof(owhi));
|
||||
burn (iwhi, sizeof(iwhi));
|
||||
burn (buf, sizeof(buf));
|
||||
burn (key, sizeof(key));
|
||||
}
|
||||
|
||||
void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[WHIRLPOOL_DIGESTSIZE], k[WHIRLPOOL_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_whirlpool (pwd, pwd_len, init, salt_len + 4, j, WHIRLPOOL_DIGESTSIZE);
|
||||
memcpy (u, j, WHIRLPOOL_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_whirlpool (pwd, pwd_len, j, WHIRLPOOL_DIGESTSIZE, k, WHIRLPOOL_DIGESTSIZE);
|
||||
for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[WHIRLPOOL_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % WHIRLPOOL_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / WHIRLPOOL_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / WHIRLPOOL_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, WHIRLPOOL_DIGESTSIZE);
|
||||
dk += WHIRLPOOL_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
|
||||
char *get_pkcs5_prf_name (int pkcs5_prf_id)
|
||||
{
|
||||
switch (pkcs5_prf_id)
|
||||
{
|
||||
case SHA512:
|
||||
return "HMAC-SHA-512";
|
||||
|
||||
case SHA1: // Deprecated/legacy
|
||||
return "HMAC-SHA-1";
|
||||
|
||||
case RIPEMD160:
|
||||
return "HMAC-RIPEMD-160";
|
||||
|
||||
case WHIRLPOOL:
|
||||
return "HMAC-Whirlpool";
|
||||
|
||||
default:
|
||||
return "(Unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
#endif //!TC_WINDOWS_BOOT
|
||||
|
||||
|
||||
int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot)
|
||||
{
|
||||
switch (pkcs5_prf_id)
|
||||
{
|
||||
case RIPEMD160:
|
||||
return (bBoot ? 1000 : 2000);
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
|
||||
case SHA512:
|
||||
return 1000;
|
||||
|
||||
case SHA1: // Deprecated/legacy
|
||||
return 2000;
|
||||
|
||||
case WHIRLPOOL:
|
||||
return 1000;
|
||||
#endif
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
|
||||
}
|
||||
return 0;
|
||||
}
|
41
src/Common/Pkcs5.h
Normal file
41
src/Common/Pkcs5.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_PKCS5
|
||||
#define TC_HEADER_PKCS5
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void hmac_sha512 (char *k, int lk, char *d, int ld, char *out, int t);
|
||||
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
void hmac_sha1 (char *k, int lk, char *d, int ld, char *out, int t);
|
||||
void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest);
|
||||
void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
void hmac_whirlpool (char *k, int lk, char *d, int ld, char *out, int t);
|
||||
void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot);
|
||||
char *get_pkcs5_prf_name (int pkcs5_prf_id);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_PKCS5
|
130
src/Common/Progress.c
Normal file
130
src/Common/Progress.c
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Language.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Progress.h"
|
||||
#include "../Format/Tcformat.h"
|
||||
#include "../Format/FormatCom.h"
|
||||
#include "../Format/resource.h"
|
||||
|
||||
static ULONG prevTime, startTime;
|
||||
static __int64 TotalSize;
|
||||
static __int64 resumedPointBytesDone;
|
||||
static BOOL bProgressBarReverse = FALSE;
|
||||
static BOOL bRWThroughput = FALSE;
|
||||
static BOOL bShowStatus = FALSE;
|
||||
static BOOL bPercentMode = FALSE;
|
||||
|
||||
static wchar_t *seconds, *minutes, *hours, *days;
|
||||
|
||||
|
||||
// If bIOThroughput is TRUE, the speed reflects the amount of data read AND written per second (rather than
|
||||
// the speed of the "transform cursor").
|
||||
void InitProgressBar (__int64 totalBytes, __int64 bytesDone, BOOL bReverse, BOOL bIOThroughput, BOOL bDisplayStatus, BOOL bShowPercent)
|
||||
{
|
||||
HWND hProgressBar = GetDlgItem (hCurPage, nPbar);
|
||||
SendMessage (hProgressBar, PBM_SETRANGE32, 0, 10000);
|
||||
SendMessage (hProgressBar, PBM_SETSTEP, 1, 0);
|
||||
|
||||
bProgressBarReverse = bReverse;
|
||||
bRWThroughput = bIOThroughput;
|
||||
bShowStatus = bDisplayStatus;
|
||||
bPercentMode = bShowPercent;
|
||||
|
||||
seconds = GetString ("SECONDS");
|
||||
minutes = GetString ("MINUTES");
|
||||
hours = GetString ("HOURS");
|
||||
days = GetString ("DAYS");
|
||||
|
||||
prevTime = startTime = GetTickCount ();
|
||||
TotalSize = totalBytes;
|
||||
resumedPointBytesDone = bytesDone;
|
||||
}
|
||||
|
||||
|
||||
BOOL UpdateProgressBar (__int64 byteOffset)
|
||||
{
|
||||
return UpdateProgressBarProc (byteOffset);
|
||||
}
|
||||
|
||||
|
||||
BOOL UpdateProgressBarProc (__int64 byteOffset)
|
||||
{
|
||||
wchar_t text[100];
|
||||
wchar_t speed[100];
|
||||
HWND hProgressBar = GetDlgItem (hCurPage, nPbar);
|
||||
int time = GetTickCount ();
|
||||
int elapsed = (time - startTime) / 1000;
|
||||
|
||||
uint64 bytesDone = (bProgressBarReverse ? (TotalSize - byteOffset) : byteOffset);
|
||||
uint64 bytesPerSec = (bProgressBarReverse ? (resumedPointBytesDone - byteOffset) : (bytesDone - resumedPointBytesDone)) / (elapsed + 1);
|
||||
|
||||
if (bPercentMode)
|
||||
{
|
||||
double perc = (double) (100.0 * (bProgressBarReverse ? ((double) (TotalSize - byteOffset)) : ((double) byteOffset)) / (TotalSize == 0 ? 0.0001 : ((double) TotalSize)));
|
||||
|
||||
if (perc > 99.999999999)
|
||||
wcscpy (text, GetString ("PROCESSED_PORTION_100_PERCENT"));
|
||||
else
|
||||
_snwprintf (text, sizeof text/2, GetString ("PROCESSED_PORTION_X_PERCENT"), perc);
|
||||
|
||||
wcscat (speed, L" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
GetSizeString (bytesDone, text);
|
||||
if (bytesDone < (unsigned __int64) BYTES_PER_MB * 1000000)
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_MB, GetString ("MB"));
|
||||
else if (bytesDone < (unsigned __int64) BYTES_PER_GB * 1000000)
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_GB, GetString ("GB"));
|
||||
else if (bytesDone < (unsigned __int64) BYTES_PER_TB * 1000000)
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_TB, GetString ("TB"));
|
||||
else
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_PB, GetString ("PB"));
|
||||
}
|
||||
|
||||
SetWindowTextW (GetDlgItem (hCurPage, IDC_BYTESWRITTEN), text);
|
||||
|
||||
if (!bShowStatus)
|
||||
{
|
||||
GetSpeedString (bRWThroughput ? bytesPerSec*2 : bytesPerSec, speed);
|
||||
wcscat (speed, L" ");
|
||||
SetWindowTextW (GetDlgItem (hCurPage, IDC_WRITESPEED), speed);
|
||||
}
|
||||
|
||||
if (byteOffset < TotalSize)
|
||||
{
|
||||
int64 sec = (int64) ((bProgressBarReverse ? byteOffset : (TotalSize - byteOffset)) / (bytesPerSec == 0 ? 0.001 : bytesPerSec));
|
||||
|
||||
if (bytesPerSec == 0 || sec > 60 * 60 * 24 * 999)
|
||||
swprintf (text, L"%s ", GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"));
|
||||
else if (sec >= 60 * 60 * 24 * 2)
|
||||
swprintf (text, L"%I64d %s ", sec / (60 * 24 * 60), days);
|
||||
else if (sec >= 120 * 60)
|
||||
swprintf (text, L"%I64d %s ", sec / (60 * 60), hours);
|
||||
else if (sec >= 120)
|
||||
swprintf (text, L"%I64d %s ", sec / 60, minutes);
|
||||
else
|
||||
swprintf (text, L"%I64d %s ", sec, seconds);
|
||||
|
||||
SetWindowTextW (GetDlgItem (hCurPage, IDC_TIMEREMAIN), text);
|
||||
}
|
||||
|
||||
prevTime = time;
|
||||
|
||||
SendMessage (hProgressBar, PBM_SETPOS,
|
||||
(int) (10000.0 * (bProgressBarReverse ? (TotalSize - byteOffset) : byteOffset) / (TotalSize == 0 ? 1 : TotalSize)),
|
||||
0);
|
||||
|
||||
return bVolTransformThreadCancel;
|
||||
}
|
22
src/Common/Progress.h
Normal file
22
src/Common/Progress.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void InitProgressBar (__int64 totalBytes, __int64 bytesDone, BOOL bReverse, BOOL bIOThroughput, BOOL bDisplayStatus, BOOL bShowPercent);
|
||||
BOOL UpdateProgressBar (__int64 byteOffset);
|
||||
BOOL UpdateProgressBarProc (__int64 byteOffset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
772
src/Common/Random.c
Normal file
772
src/Common/Random.c
Normal file
@ -0,0 +1,772 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crc.h"
|
||||
#include "Random.h"
|
||||
|
||||
static unsigned __int8 buffer[RNG_POOL_SIZE];
|
||||
static unsigned char *pRandPool = NULL;
|
||||
static BOOL bRandDidInit = FALSE;
|
||||
static int nRandIndex = 0, randPoolReadIndex = 0;
|
||||
static int HashFunction = DEFAULT_HASH_ALGORITHM;
|
||||
static BOOL bDidSlowPoll = FALSE;
|
||||
BOOL volatile bFastPollEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */
|
||||
BOOL volatile bRandmixEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */
|
||||
static BOOL RandomPoolEnrichedByUser = FALSE;
|
||||
static HANDLE PeriodicFastPollThreadHandle = NULL;
|
||||
|
||||
/* Macro to add a single byte to the pool */
|
||||
#define RandaddByte(x) {\
|
||||
if (nRandIndex == RNG_POOL_SIZE) nRandIndex = 0;\
|
||||
pRandPool[nRandIndex] = (unsigned char) ((unsigned char)x + pRandPool[nRandIndex]); \
|
||||
if (nRandIndex % RANDMIX_BYTE_INTERVAL == 0) Randmix();\
|
||||
nRandIndex++; \
|
||||
}
|
||||
|
||||
/* Macro to add four bytes to the pool */
|
||||
#define RandaddInt32(x) RandAddInt((unsigned __int32)x);
|
||||
|
||||
void RandAddInt (unsigned __int32 x)
|
||||
{
|
||||
RandaddByte(x);
|
||||
RandaddByte((x >> 8));
|
||||
RandaddByte((x >> 16));
|
||||
RandaddByte((x >> 24));
|
||||
}
|
||||
|
||||
#include <tlhelp32.h>
|
||||
#include "Dlgcode.h"
|
||||
|
||||
HHOOK hMouse = NULL; /* Mouse hook for the random number generator */
|
||||
HHOOK hKeyboard = NULL; /* Keyboard hook for the random number generator */
|
||||
|
||||
/* Variables for thread control, the thread is used to gather up info about
|
||||
the system in in the background */
|
||||
CRITICAL_SECTION critRandProt; /* The critical section */
|
||||
BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among thread's so its made volatile */
|
||||
|
||||
/* Network library handle for the SlowPoll function */
|
||||
HANDLE hNetAPI32 = NULL;
|
||||
|
||||
// CryptoAPI
|
||||
BOOL CryptoAPIAvailable = FALSE;
|
||||
HCRYPTPROV hCryptProv;
|
||||
|
||||
|
||||
/* Init the random number generator, setup the hooks, and start the thread */
|
||||
int Randinit ()
|
||||
{
|
||||
if (GetMaxPkcs5OutSize() > RNG_POOL_SIZE)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
if(bRandDidInit)
|
||||
return 0;
|
||||
|
||||
InitializeCriticalSection (&critRandProt);
|
||||
|
||||
bRandDidInit = TRUE;
|
||||
|
||||
if (pRandPool == NULL)
|
||||
{
|
||||
pRandPool = (unsigned char *) TCalloc (RANDOMPOOL_ALLOCSIZE);
|
||||
if (pRandPool == NULL)
|
||||
goto error;
|
||||
|
||||
bDidSlowPoll = FALSE;
|
||||
RandomPoolEnrichedByUser = FALSE;
|
||||
|
||||
memset (pRandPool, 0, RANDOMPOOL_ALLOCSIZE);
|
||||
VirtualLock (pRandPool, RANDOMPOOL_ALLOCSIZE);
|
||||
}
|
||||
|
||||
hKeyboard = SetWindowsHookEx (WH_KEYBOARD, (HOOKPROC)&KeyboardProc, NULL, GetCurrentThreadId ());
|
||||
if (hKeyboard == 0) handleWin32Error (0);
|
||||
|
||||
hMouse = SetWindowsHookEx (WH_MOUSE, (HOOKPROC)&MouseProc, NULL, GetCurrentThreadId ());
|
||||
if (hMouse == 0)
|
||||
{
|
||||
handleWin32Error (0);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)
|
||||
&& !CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
|
||||
CryptoAPIAvailable = FALSE;
|
||||
else
|
||||
CryptoAPIAvailable = TRUE;
|
||||
|
||||
if (!(PeriodicFastPollThreadHandle = (HANDLE) _beginthreadex (NULL, 0, PeriodicFastPollThreadProc, NULL, 0, NULL)))
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
RandStop (TRUE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Close everything down, including the thread which is closed down by
|
||||
setting a flag which eventually causes the thread function to exit */
|
||||
void RandStop (BOOL freePool)
|
||||
{
|
||||
if (!bRandDidInit && freePool && pRandPool)
|
||||
goto freePool;
|
||||
|
||||
if (bRandDidInit == FALSE)
|
||||
return;
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
|
||||
if (hMouse != 0)
|
||||
UnhookWindowsHookEx (hMouse);
|
||||
if (hKeyboard != 0)
|
||||
UnhookWindowsHookEx (hKeyboard);
|
||||
|
||||
bThreadTerminate = TRUE;
|
||||
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
if (PeriodicFastPollThreadHandle)
|
||||
WaitForSingleObject (PeriodicFastPollThreadHandle, INFINITE);
|
||||
|
||||
if (hNetAPI32 != 0)
|
||||
{
|
||||
FreeLibrary (hNetAPI32);
|
||||
hNetAPI32 = NULL;
|
||||
}
|
||||
|
||||
if (CryptoAPIAvailable)
|
||||
{
|
||||
CryptReleaseContext (hCryptProv, 0);
|
||||
CryptoAPIAvailable = FALSE;
|
||||
}
|
||||
|
||||
hMouse = NULL;
|
||||
hKeyboard = NULL;
|
||||
bThreadTerminate = FALSE;
|
||||
DeleteCriticalSection (&critRandProt);
|
||||
|
||||
bRandDidInit = FALSE;
|
||||
|
||||
freePool:
|
||||
if (freePool)
|
||||
{
|
||||
bDidSlowPoll = FALSE;
|
||||
RandomPoolEnrichedByUser = FALSE;
|
||||
|
||||
if (pRandPool != NULL)
|
||||
{
|
||||
burn (pRandPool, RANDOMPOOL_ALLOCSIZE);
|
||||
TCfree (pRandPool);
|
||||
pRandPool = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL IsRandomNumberGeneratorStarted ()
|
||||
{
|
||||
return bRandDidInit;
|
||||
}
|
||||
|
||||
void RandSetHashFunction (int hash_algo_id)
|
||||
{
|
||||
if (HashIsDeprecated (hash_algo_id))
|
||||
hash_algo_id = DEFAULT_HASH_ALGORITHM;
|
||||
|
||||
HashFunction = hash_algo_id;
|
||||
}
|
||||
|
||||
int RandGetHashFunction (void)
|
||||
{
|
||||
return HashFunction;
|
||||
}
|
||||
|
||||
void SetRandomPoolEnrichedByUserStatus (BOOL enriched)
|
||||
{
|
||||
RandomPoolEnrichedByUser = enriched;
|
||||
}
|
||||
|
||||
BOOL IsRandomPoolEnrichedByUser ()
|
||||
{
|
||||
return RandomPoolEnrichedByUser;
|
||||
}
|
||||
|
||||
/* The random pool mixing function */
|
||||
BOOL Randmix ()
|
||||
{
|
||||
if (bRandmixEnabled)
|
||||
{
|
||||
unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
|
||||
WHIRLPOOL_CTX wctx;
|
||||
RMD160_CTX rctx;
|
||||
sha512_ctx sctx;
|
||||
int poolIndex, digestIndex, digestSize;
|
||||
|
||||
switch (HashFunction)
|
||||
{
|
||||
case RIPEMD160:
|
||||
digestSize = RIPEMD160_DIGESTSIZE;
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
digestSize = SHA512_DIGESTSIZE;
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
digestSize = WHIRLPOOL_DIGESTSIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (RNG_POOL_SIZE % digestSize)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
for (poolIndex = 0; poolIndex < RNG_POOL_SIZE; poolIndex += digestSize)
|
||||
{
|
||||
/* Compute the message digest of the entire pool using the selected hash function. */
|
||||
switch (HashFunction)
|
||||
{
|
||||
case RIPEMD160:
|
||||
RMD160Init(&rctx);
|
||||
RMD160Update(&rctx, pRandPool, RNG_POOL_SIZE);
|
||||
RMD160Final(hashOutputBuffer, &rctx);
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
sha512_begin (&sctx);
|
||||
sha512_hash (pRandPool, RNG_POOL_SIZE, &sctx);
|
||||
sha512_end (hashOutputBuffer, &sctx);
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
WHIRLPOOL_init (&wctx);
|
||||
WHIRLPOOL_add (pRandPool, RNG_POOL_SIZE * 8, &wctx);
|
||||
WHIRLPOOL_finalize (&wctx, hashOutputBuffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown/wrong ID
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
/* XOR the resultant message digest to the pool at the poolIndex position. */
|
||||
for (digestIndex = 0; digestIndex < digestSize; digestIndex++)
|
||||
{
|
||||
pRandPool [poolIndex + digestIndex] ^= hashOutputBuffer [digestIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent leaks */
|
||||
burn (hashOutputBuffer, MAX_DIGESTSIZE);
|
||||
switch (HashFunction)
|
||||
{
|
||||
case RIPEMD160:
|
||||
burn (&rctx, sizeof(rctx));
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
burn (&sctx, sizeof(sctx));
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
burn (&wctx, sizeof(wctx));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown/wrong ID
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add a buffer to the pool */
|
||||
void RandaddBuf (void *buf, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
RandaddByte (((unsigned char *) buf)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL RandpeekBytes (unsigned char *buf, int len)
|
||||
{
|
||||
if (!bRandDidInit)
|
||||
return FALSE;
|
||||
|
||||
if (len > RNG_POOL_SIZE)
|
||||
{
|
||||
Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
|
||||
len = RNG_POOL_SIZE;
|
||||
}
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
memcpy (buf, pRandPool, len);
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Get len random bytes from the pool (max. RNG_POOL_SIZE bytes per a single call) */
|
||||
BOOL RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll)
|
||||
{
|
||||
int i;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (!bRandDidInit || HashFunction == 0)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
|
||||
if (bDidSlowPoll == FALSE || forceSlowPoll)
|
||||
{
|
||||
if (!SlowPoll ())
|
||||
ret = FALSE;
|
||||
else
|
||||
bDidSlowPoll = TRUE;
|
||||
}
|
||||
|
||||
if (!FastPoll ())
|
||||
ret = FALSE;
|
||||
|
||||
/* There's never more than RNG_POOL_SIZE worth of randomess */
|
||||
if (len > RNG_POOL_SIZE)
|
||||
{
|
||||
Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
|
||||
len = RNG_POOL_SIZE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Requested number of bytes is copied from pool to output buffer,
|
||||
// pool is rehashed, and output buffer is XORed with new data from pool
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
buf[i] = pRandPool[randPoolReadIndex++];
|
||||
if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
|
||||
}
|
||||
|
||||
/* Invert the pool */
|
||||
for (i = 0; i < RNG_POOL_SIZE / 4; i++)
|
||||
{
|
||||
((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
|
||||
}
|
||||
|
||||
// Mix the pool
|
||||
if (!FastPoll ())
|
||||
ret = FALSE;
|
||||
|
||||
// XOR the current pool content into the output buffer to prevent pool state leaks
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
buf[i] ^= pRandPool[randPoolReadIndex++];
|
||||
if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
if (!ret)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Capture the mouse, and as long as the event is not the same as the last
|
||||
two events, add the crc of the event, and the crc of the time difference
|
||||
between this event and the last + the current time to the pool.
|
||||
The role of CRC-32 is merely to perform diffusion. Note that the output
|
||||
of CRC-32 is subsequently processed using a cryptographically secure hash
|
||||
algorithm. */
|
||||
LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static DWORD dwLastTimer;
|
||||
static unsigned __int32 lastCrc, lastCrc2;
|
||||
MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam;
|
||||
|
||||
if (nCode < 0)
|
||||
return CallNextHookEx (hMouse, nCode, wParam, lParam);
|
||||
else
|
||||
{
|
||||
DWORD dwTimer = GetTickCount ();
|
||||
DWORD j = dwLastTimer - dwTimer;
|
||||
unsigned __int32 crc = 0L;
|
||||
int i;
|
||||
|
||||
dwLastTimer = dwTimer;
|
||||
|
||||
for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++)
|
||||
{
|
||||
crc = UPDC32 (((unsigned char *) lpMouse)[i], crc);
|
||||
}
|
||||
|
||||
if (crc != lastCrc && crc != lastCrc2)
|
||||
{
|
||||
unsigned __int32 timeCrc = 0L;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
|
||||
}
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
RandaddInt32 ((unsigned __int32) (crc + timeCrc));
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
}
|
||||
lastCrc2 = lastCrc;
|
||||
lastCrc = crc;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Capture the keyboard, as long as the event is not the same as the last two
|
||||
events, add the crc of the event to the pool along with the crc of the time
|
||||
difference between this event and the last. The role of CRC-32 is merely to
|
||||
perform diffusion. Note that the output of CRC-32 is subsequently processed
|
||||
using a cryptographically secure hash algorithm. */
|
||||
LRESULT CALLBACK KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static int lLastKey, lLastKey2;
|
||||
static DWORD dwLastTimer;
|
||||
int nKey = (lParam & 0x00ff0000) >> 16;
|
||||
int nCapture = 0;
|
||||
|
||||
if (nCode < 0)
|
||||
return CallNextHookEx (hMouse, nCode, wParam, lParam);
|
||||
|
||||
if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) &&
|
||||
(lParam & 0x80000000))
|
||||
{
|
||||
if (nKey != lLastKey)
|
||||
nCapture = 1; /* Capture this key */
|
||||
else if (nKey != lLastKey2)
|
||||
nCapture = 1; /* Allow for one repeat */
|
||||
}
|
||||
if (nCapture)
|
||||
{
|
||||
DWORD dwTimer = GetTickCount ();
|
||||
DWORD j = dwLastTimer - dwTimer;
|
||||
unsigned __int32 timeCrc = 0L;
|
||||
int i;
|
||||
|
||||
dwLastTimer = dwTimer;
|
||||
lLastKey2 = lLastKey;
|
||||
lLastKey = nKey;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
|
||||
}
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
RandaddInt32 ((unsigned __int32) (crc32int(&lParam) + timeCrc));
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
}
|
||||
|
||||
return CallNextHookEx (hMouse, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
/* This is the thread function which will poll the system for randomness */
|
||||
static unsigned __stdcall PeriodicFastPollThreadProc (void *dummy)
|
||||
{
|
||||
if (dummy); /* Remove unused parameter warning */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
EnterCriticalSection (&critRandProt);
|
||||
|
||||
if (bThreadTerminate)
|
||||
{
|
||||
bThreadTerminate = FALSE;
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
_endthreadex (0);
|
||||
}
|
||||
else if (bFastPollEnabled)
|
||||
{
|
||||
FastPoll ();
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
Sleep (FASTPOLL_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Type definitions for function pointers to call NetAPI32 functions */
|
||||
|
||||
typedef
|
||||
DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
|
||||
DWORD dwLevel, DWORD dwOptions,
|
||||
LPBYTE * lpBuffer);
|
||||
typedef
|
||||
DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
|
||||
typedef
|
||||
DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
|
||||
|
||||
NETSTATISTICSGET pNetStatisticsGet = NULL;
|
||||
NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
|
||||
NETAPIBUFFERFREE pNetApiBufferFree = NULL;
|
||||
|
||||
|
||||
/* This is the slowpoll function which gathers up network/hard drive
|
||||
performance data for the random pool */
|
||||
BOOL SlowPoll (void)
|
||||
{
|
||||
static int isWorkstation = -1;
|
||||
static int cbPerfData = 0x10000;
|
||||
HANDLE hDevice;
|
||||
LPBYTE lpBuffer;
|
||||
DWORD dwSize, status;
|
||||
LPWSTR lpszLanW, lpszLanS;
|
||||
int nDrive;
|
||||
|
||||
/* Find out whether this is an NT server or workstation if necessary */
|
||||
if (isWorkstation == -1)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
|
||||
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
|
||||
0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
unsigned char szValue[32];
|
||||
dwSize = sizeof (szValue);
|
||||
|
||||
isWorkstation = TRUE;
|
||||
status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
|
||||
szValue, &dwSize);
|
||||
|
||||
if (status == ERROR_SUCCESS && _stricmp ((char *) szValue, "WinNT"))
|
||||
/* Note: There are (at least) three cases for
|
||||
ProductType: WinNT = NT Workstation,
|
||||
ServerNT = NT Server, LanmanNT = NT Server
|
||||
acting as a Domain Controller */
|
||||
isWorkstation = FALSE;
|
||||
|
||||
RegCloseKey (hKey);
|
||||
}
|
||||
}
|
||||
/* Initialize the NetAPI32 function pointers if necessary */
|
||||
if (hNetAPI32 == NULL)
|
||||
{
|
||||
/* Obtain a handle to the module containing the Lan Manager
|
||||
functions */
|
||||
hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
|
||||
if (hNetAPI32 != NULL)
|
||||
{
|
||||
/* Now get pointers to the functions */
|
||||
pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
|
||||
"NetStatisticsGet");
|
||||
pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
|
||||
"NetApiBufferSize");
|
||||
pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
|
||||
"NetApiBufferFree");
|
||||
|
||||
/* Make sure we got valid pointers for every NetAPI32
|
||||
function */
|
||||
if (pNetStatisticsGet == NULL ||
|
||||
pNetApiBufferSize == NULL ||
|
||||
pNetApiBufferFree == NULL)
|
||||
{
|
||||
/* Free the library reference and reset the
|
||||
static handle */
|
||||
FreeLibrary (hNetAPI32);
|
||||
hNetAPI32 = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get network statistics. Note: Both NT Workstation and NT Server
|
||||
by default will be running both the workstation and server
|
||||
services. The heuristic below is probably useful though on the
|
||||
assumption that the majority of the network traffic will be via
|
||||
the appropriate service */
|
||||
lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
|
||||
lpszLanS = (LPWSTR) WIDE ("LanmanServer");
|
||||
if (hNetAPI32 &&
|
||||
pNetStatisticsGet (NULL,
|
||||
isWorkstation ? lpszLanW : lpszLanS,
|
||||
0, 0, &lpBuffer) == 0)
|
||||
{
|
||||
pNetApiBufferSize (lpBuffer, &dwSize);
|
||||
RandaddBuf ((unsigned char *) lpBuffer, dwSize);
|
||||
pNetApiBufferFree (lpBuffer);
|
||||
}
|
||||
|
||||
/* Get disk I/O statistics for all the hard drives */
|
||||
for (nDrive = 0;; nDrive++)
|
||||
{
|
||||
DISK_PERFORMANCE diskPerformance;
|
||||
char szDevice[24];
|
||||
|
||||
/* Check whether we can access this device */
|
||||
sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
|
||||
hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hDevice == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
|
||||
/* Note: This only works if you have turned on the disk
|
||||
performance counters with 'diskperf -y'. These counters
|
||||
are off by default */
|
||||
if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
|
||||
&diskPerformance, sizeof (DISK_PERFORMANCE),
|
||||
&dwSize, NULL))
|
||||
{
|
||||
RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
|
||||
}
|
||||
CloseHandle (hDevice);
|
||||
}
|
||||
|
||||
// CryptoAPI
|
||||
if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
||||
RandaddBuf (buffer, sizeof (buffer));
|
||||
|
||||
burn(buffer, sizeof (buffer));
|
||||
Randmix();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* This is the fastpoll function which gathers up info by calling various api's */
|
||||
BOOL FastPoll (void)
|
||||
{
|
||||
int nOriginalRandIndex = nRandIndex;
|
||||
static BOOL addedFixedItems = FALSE;
|
||||
FILETIME creationTime, exitTime, kernelTime, userTime;
|
||||
DWORD minimumWorkingSetSize, maximumWorkingSetSize;
|
||||
LARGE_INTEGER performanceCount;
|
||||
MEMORYSTATUS memoryStatus;
|
||||
HANDLE handle;
|
||||
POINT point;
|
||||
|
||||
/* Get various basic pieces of system information */
|
||||
RandaddInt32 (GetActiveWindow ()); /* Handle of active window */
|
||||
RandaddInt32 (GetCapture ()); /* Handle of window with mouse
|
||||
capture */
|
||||
RandaddInt32 (GetClipboardOwner ()); /* Handle of clipboard owner */
|
||||
RandaddInt32 (GetClipboardViewer ()); /* Handle of start of
|
||||
clpbd.viewer list */
|
||||
RandaddInt32 (GetCurrentProcess ()); /* Pseudohandle of current
|
||||
process */
|
||||
RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */
|
||||
RandaddInt32 (GetCurrentThread ()); /* Pseudohandle of current
|
||||
thread */
|
||||
RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */
|
||||
RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows
|
||||
started */
|
||||
RandaddInt32 (GetDesktopWindow ()); /* Handle of desktop window */
|
||||
RandaddInt32 (GetFocus ()); /* Handle of window with kb.focus */
|
||||
RandaddInt32 (GetInputState ()); /* Whether sys.queue has any events */
|
||||
RandaddInt32 (GetMessagePos ()); /* Cursor pos.for last message */
|
||||
RandaddInt32 (GetMessageTime ()); /* 1 ms time for last message */
|
||||
RandaddInt32 (GetOpenClipboardWindow ()); /* Handle of window with
|
||||
clpbd.open */
|
||||
RandaddInt32 (GetProcessHeap ()); /* Handle of process heap */
|
||||
RandaddInt32 (GetProcessWindowStation ()); /* Handle of procs
|
||||
window station */
|
||||
RandaddInt32 (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in
|
||||
input queue */
|
||||
|
||||
/* Get multiword system information */
|
||||
GetCaretPos (&point); /* Current caret position */
|
||||
RandaddBuf ((unsigned char *) &point, sizeof (POINT));
|
||||
GetCursorPos (&point); /* Current mouse cursor position */
|
||||
RandaddBuf ((unsigned char *) &point, sizeof (POINT));
|
||||
|
||||
/* Get percent of memory in use, bytes of physical memory, bytes of
|
||||
free physical memory, bytes in paging file, free bytes in paging
|
||||
file, user bytes of address space, and free user bytes */
|
||||
memoryStatus.dwLength = sizeof (MEMORYSTATUS);
|
||||
GlobalMemoryStatus (&memoryStatus);
|
||||
RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));
|
||||
|
||||
/* Get thread and process creation time, exit time, time in kernel
|
||||
mode, and time in user mode in 100ns intervals */
|
||||
handle = GetCurrentThread ();
|
||||
GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
|
||||
RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
|
||||
handle = GetCurrentProcess ();
|
||||
GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
|
||||
RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
|
||||
|
||||
/* Get the minimum and maximum working set size for the current
|
||||
process */
|
||||
GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
|
||||
&maximumWorkingSetSize);
|
||||
RandaddInt32 (minimumWorkingSetSize);
|
||||
RandaddInt32 (maximumWorkingSetSize);
|
||||
|
||||
/* The following are fixed for the lifetime of the process so we only
|
||||
add them once */
|
||||
if (addedFixedItems == 0)
|
||||
{
|
||||
STARTUPINFO startupInfo;
|
||||
|
||||
/* Get name of desktop, console window title, new window
|
||||
position and size, window flags, and handles for stdin,
|
||||
stdout, and stderr */
|
||||
startupInfo.cb = sizeof (STARTUPINFO);
|
||||
GetStartupInfo (&startupInfo);
|
||||
RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
|
||||
addedFixedItems = TRUE;
|
||||
}
|
||||
/* The docs say QPC can fail if appropriate hardware is not
|
||||
available. It works on 486 & Pentium boxes, but hasn't been tested
|
||||
for 386 or RISC boxes */
|
||||
if (QueryPerformanceCounter (&performanceCount))
|
||||
RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
|
||||
else
|
||||
{
|
||||
/* Millisecond accuracy at best... */
|
||||
DWORD dwTicks = GetTickCount ();
|
||||
RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
|
||||
}
|
||||
|
||||
// CryptoAPI
|
||||
if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
||||
RandaddBuf (buffer, sizeof (buffer));
|
||||
|
||||
/* Apply the pool mixing function */
|
||||
Randmix();
|
||||
|
||||
/* Restore the original pool cursor position. If this wasn't done, mouse coordinates
|
||||
could be written to a limited area of the pool, especially when moving the mouse
|
||||
uninterruptedly. The severity of the problem would depend on the length of data
|
||||
written by FastPoll (if it was equal to the size of the pool, mouse coordinates
|
||||
would be written only to a particular 4-byte area, whenever moving the mouse
|
||||
uninterruptedly). */
|
||||
nRandIndex = nOriginalRandIndex;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
62
src/Common/Random.h
Normal file
62
src/Common/Random.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
|
||||
#include "Crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* RNG defines & pool pointers */
|
||||
#define RNG_POOL_SIZE 320 // Must be divisible by the size of the output of each of the implemented hash functions. (in bytes)
|
||||
|
||||
#if RNG_POOL_SIZE % SHA512_DIGESTSIZE || RNG_POOL_SIZE % WHIRLPOOL_DIGESTSIZE || RNG_POOL_SIZE % RIPEMD160_DIGESTSIZE
|
||||
#error RNG_POOL_SIZE must be divisible by the size of the output of each of the implemented hash functions.
|
||||
#endif
|
||||
|
||||
#define RANDOMPOOL_ALLOCSIZE RNG_POOL_SIZE
|
||||
|
||||
// After every RANDMIX_BYTE_INTERVAL-th byte written to the pool, the pool mixing function is applied to the entire pool
|
||||
#define RANDMIX_BYTE_INTERVAL 16
|
||||
|
||||
// FastPoll interval (in milliseconds)
|
||||
#define FASTPOLL_INTERVAL 500
|
||||
|
||||
void RandAddInt ( unsigned __int32 x );
|
||||
int Randinit ( void );
|
||||
void RandStop (BOOL freePool);
|
||||
BOOL IsRandomNumberGeneratorStarted ();
|
||||
void RandSetHashFunction ( int hash_algo_id );
|
||||
int RandGetHashFunction (void);
|
||||
void SetRandomPoolEnrichedByUserStatus (BOOL enriched);
|
||||
BOOL IsRandomPoolEnrichedByUser ();
|
||||
BOOL Randmix ( void );
|
||||
void RandaddBuf ( void *buf , int len );
|
||||
BOOL FastPoll ( void );
|
||||
BOOL SlowPoll ( void );
|
||||
BOOL RandpeekBytes ( unsigned char *buf , int len );
|
||||
BOOL RandgetBytes ( unsigned char *buf , int len, BOOL forceSlowPoll );
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
extern BOOL volatile bFastPollEnabled;
|
||||
extern BOOL volatile bRandmixEnabled;
|
||||
|
||||
LRESULT CALLBACK MouseProc ( int nCode , WPARAM wParam , LPARAM lParam );
|
||||
LRESULT CALLBACK KeyboardProc ( int nCode , WPARAM wParam , LPARAM lParam );
|
||||
static unsigned __stdcall PeriodicFastPollThreadProc (void *dummy);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
286
src/Common/Registry.c
Normal file
286
src/Common/Registry.c
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
Copyright (c) 2004-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Registry.h"
|
||||
|
||||
BOOL ReadLocalMachineRegistryDword (char *subKey, char *name, DWORD *value)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD size = sizeof (*value);
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) value, &size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_DWORD;
|
||||
}
|
||||
|
||||
BOOL ReadLocalMachineRegistryMultiString (char *subKey, char *name, char *value, DWORD *size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) value, size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_MULTI_SZ;
|
||||
}
|
||||
|
||||
BOOL ReadLocalMachineRegistryString (const char *subKey, char *name, char *str, DWORD *size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) str, size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_SZ;
|
||||
}
|
||||
|
||||
BOOL ReadLocalMachineRegistryStringNonReflected (const char *subKey, char *name, char *str, DWORD *size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ | KEY_WOW64_64KEY, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) str, size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_SZ;
|
||||
}
|
||||
|
||||
int ReadRegistryInt (char *subKey, char *name, int defaultValue)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD value, size = sizeof (DWORD);
|
||||
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return defaultValue;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) &value, &size) != ERROR_SUCCESS)
|
||||
value = defaultValue;
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return value;
|
||||
}
|
||||
|
||||
char *ReadRegistryString (char *subKey, char *name, char *defaultValue, char *str, int maxLen)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
char value[MAX_PATH*4];
|
||||
DWORD size = sizeof (value);
|
||||
|
||||
strncpy (str, defaultValue, maxLen-1);
|
||||
|
||||
ZeroMemory (value, sizeof value);
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, KEY_READ, &hkey) == ERROR_SUCCESS)
|
||||
if (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) &value, &size) == ERROR_SUCCESS)
|
||||
strncpy (str, value, maxLen-1);
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return str;
|
||||
}
|
||||
|
||||
DWORD ReadRegistryBytes (char *path, char *name, char *value, int maxLen)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD size = maxLen;
|
||||
BOOL success = FALSE;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, path, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
success = (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) value, &size) == ERROR_SUCCESS);
|
||||
RegCloseKey (hkey);
|
||||
|
||||
return success ? size : 0;
|
||||
}
|
||||
|
||||
void WriteRegistryInt (char *subKey, char *name, int value)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
|
||||
if (RegCreateKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
RegSetValueEx (hkey, name, 0, REG_DWORD, (BYTE *) &value, sizeof value);
|
||||
RegCloseKey (hkey);
|
||||
}
|
||||
|
||||
BOOL WriteLocalMachineRegistryDword (char *subKey, char *name, DWORD value)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
LONG status;
|
||||
|
||||
if ((status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegSetValueEx (hkey, name, 0, REG_DWORD, (BYTE *) &value, sizeof value)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WriteLocalMachineRegistryMultiString (char *subKey, char *name, char *multiString, DWORD size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
LONG status;
|
||||
|
||||
if ((status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegSetValueEx (hkey, name, 0, REG_MULTI_SZ, (BYTE *) multiString, size)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WriteLocalMachineRegistryString (char *subKey, char *name, char *str, BOOL expandable)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
LONG status;
|
||||
|
||||
if ((status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegSetValueEx (hkey, name, 0, expandable ? REG_EXPAND_SZ : REG_SZ, (BYTE *) str, strlen (str) + 1)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void WriteRegistryString (char *subKey, char *name, char *str)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
|
||||
if (RegCreateKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
RegSetValueEx (hkey, name, 0, REG_SZ, (BYTE *) str, strlen (str) + 1);
|
||||
RegCloseKey (hkey);
|
||||
}
|
||||
|
||||
BOOL WriteRegistryBytes (char *path, char *name, char *str, DWORD size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
BOOL res;
|
||||
|
||||
if (RegCreateKeyEx (HKEY_CURRENT_USER, path,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
res = RegSetValueEx (hkey, name, 0, REG_BINARY, (BYTE *) str, size);
|
||||
RegCloseKey (hkey);
|
||||
return res == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL DeleteLocalMachineRegistryKey (char *parentKey, char *subKeyToDelete)
|
||||
{
|
||||
LONG status;
|
||||
HKEY hkey = 0;
|
||||
|
||||
if ((status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, parentKey, 0, KEY_WRITE, &hkey)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegDeleteKey (hkey, subKeyToDelete)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void DeleteRegistryValue (char *subKey, char *name)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey, 0, KEY_WRITE, &hkey) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
RegDeleteValue (hkey, name);
|
||||
RegCloseKey (hkey);
|
||||
}
|
||||
|
||||
|
||||
void GetStartupRegKeyName (char *regk)
|
||||
{
|
||||
// The string is split in order to prevent some antivirus packages from falsely reporting
|
||||
// TrueCrypt.exe to contain a possible Trojan horse because of this string (heuristic scan).
|
||||
sprintf (regk, "%s%s", "Software\\Microsoft\\Windows\\Curren", "tVersion\\Run");
|
||||
}
|
32
src/Common/Registry.h
Normal file
32
src/Common/Registry.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (c) 2004-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
BOOL ReadLocalMachineRegistryDword (char *subKey, char *name, DWORD *value);
|
||||
BOOL ReadLocalMachineRegistryMultiString (char *subKey, char *name, char *value, DWORD *size);
|
||||
BOOL ReadLocalMachineRegistryString (const char *subKey, char *name, char *value, DWORD *size);
|
||||
BOOL ReadLocalMachineRegistryStringNonReflected (const char *subKey, char *name, char *str, DWORD *size);
|
||||
int ReadRegistryInt (char *subKey, char *name, int defaultValue);
|
||||
char *ReadRegistryString (char *subKey, char *name, char *defaultValue, char *str, int maxLen);
|
||||
DWORD ReadRegistryBytes (char *path, char *name, char *value, int maxLen);
|
||||
void WriteRegistryInt (char *subKey, char *name, int value);
|
||||
BOOL WriteLocalMachineRegistryDword (char *subKey, char *name, DWORD value);
|
||||
BOOL WriteLocalMachineRegistryMultiString (char *subKey, char *name, char *multiString, DWORD size);
|
||||
BOOL WriteLocalMachineRegistryString (char *subKey, char *name, char *str, BOOL expandable);
|
||||
void WriteRegistryString (char *subKey, char *name, char *str);
|
||||
BOOL WriteRegistryBytes (char *path, char *name, char *str, DWORD size);
|
||||
BOOL DeleteLocalMachineRegistryKey (char *parentKey, char *subKeyToDelete);
|
||||
void DeleteRegistryValue (char *subKey, char *name);
|
||||
void GetStartupRegKeyName (char *regk);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
174
src/Common/Resource.h
Normal file
174
src/Common/Resource.h
Normal file
@ -0,0 +1,174 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by Common.rc
|
||||
//
|
||||
#define IDI_TRUECRYPT_ICON 501
|
||||
#define IDI_TRUECRYPT_VOL_ICON 502
|
||||
#define IDD_BENCHMARK_DLG 503
|
||||
#define IDD_MOUNT_OPTIONS 504
|
||||
#define IDD_KEYFILES 505
|
||||
#define IDR_LANGUAGE 506
|
||||
#define IDI_TRUECRYPT 507
|
||||
#define IDD_ABOUT_DLG 508
|
||||
#define IDD_COMMANDHELP_DLG 509
|
||||
#define IDD_RAWDEVICES_DLG 510
|
||||
#define IDC_HOMEPAGE 511
|
||||
#define IDR_COMMON_RSRC_HEADER 512
|
||||
#define IDD_LANGUAGE 513
|
||||
#define IDD_CIPHER_TEST_DLG 514
|
||||
#define IDR_LICENSE 515
|
||||
#define IDD_AUXILIARY_DLG 516
|
||||
#define IDB_TEXTUAL_LOGO_BKG 517
|
||||
#define IDB_TEXTUAL_LOGO_96DPI 518
|
||||
#define IDB_TEXTUAL_LOGO_288DPI 519
|
||||
#define IDR_BOOT_SECTOR 520
|
||||
#define IDR_BOOT_SECTOR_AES 521
|
||||
#define IDR_BOOT_SECTOR_SERPENT 522
|
||||
#define IDR_BOOT_SECTOR_TWOFISH 523
|
||||
#define IDR_BOOT_LOADER_DECOMPRESSOR 524
|
||||
#define IDR_BOOT_LOADER 525
|
||||
#define IDR_BOOT_LOADER_AES 526
|
||||
#define IDR_BOOT_LOADER_SERPENT 527
|
||||
#define IDR_BOOT_LOADER_TWOFISH 528
|
||||
#define IDR_RESCUE_BOOT_SECTOR 529
|
||||
#define IDR_RESCUE_BOOT_SECTOR_AES 530
|
||||
#define IDR_RESCUE_BOOT_SECTOR_SERPENT 531
|
||||
#define IDR_RESCUE_BOOT_SECTOR_TWOFISH 532
|
||||
#define IDR_RESCUE_LOADER 533
|
||||
#define IDR_RESCUE_LOADER_AES 534
|
||||
#define IDR_RESCUE_LOADER_SERPENT 535
|
||||
#define IDR_RESCUE_LOADER_TWOFISH 536
|
||||
#define IDD_TOKEN_PASSWORD 537
|
||||
#define IDD_TOKEN_KEYFILES 538
|
||||
#define IDD_NEW_TOKEN_KEYFILE 539
|
||||
#define IDD_RANDOM_POOL_ENRICHMENT 540
|
||||
#define IDI_TRUECRYPT_MOUNTED_ICON 541
|
||||
#define IDC_HW_AES_LABEL_LINK 5000
|
||||
#define IDC_HW_AES 5001
|
||||
#define IDC_PARALLELIZATION_LABEL_LINK 5002
|
||||
#define IDC_PARALLELIZATION 5003
|
||||
#define IDT_TOKEN_PASSWORD 5004
|
||||
#define IDC_PRINT 5005
|
||||
#define IDC_KEY 5006
|
||||
#define IDC_PLAINTEXT 5007
|
||||
#define IDC_CIPHERTEXT 5008
|
||||
#define IDC_INFO_BOX_TEXT 5009
|
||||
#define IDC_SECONDARY_KEY 5010
|
||||
#define IDD_TEXT_INFO_DIALOG_BOX_DLG 5011
|
||||
#define IDC_TEST_DATA_UNIT_NUMBER 5012
|
||||
#define IDD_KEYFILE_GENERATOR 5013
|
||||
#define IDC_CIPHER 5014
|
||||
#define IDD_MULTI_CHOICE_DLG 5015
|
||||
#define IDC_TEST_BLOCK_NUMBER 5016
|
||||
#define IDD_STATIC_MODELESS_WAIT_DLG 5017
|
||||
#define IDC_POOL_CONTENTS 5018
|
||||
#define IDC_PRF_ID 5019
|
||||
#define IDC_KEY_SIZE 5020
|
||||
#define IDC_PLAINTEXT_SIZE 5021
|
||||
#define IDC_REDTICK 5022
|
||||
#define IDC_TESTS_MESSAGE 5023
|
||||
#define IDC_RESET 5024
|
||||
#define IDC_AUTO 5025
|
||||
#define IDC_DECRYPT 5026
|
||||
#define IDT_TEST_KEY 5027
|
||||
#define IDT_TEST_PLAINTEXT 5028
|
||||
#define IDT_PRF 5029
|
||||
#define IDT_XTS_MODE 5030
|
||||
#define IDT_TEST_CIPHERTEXT 5031
|
||||
#define IDT_KEY 5032
|
||||
#define IDT_PLAINTEXT 5033
|
||||
#define IDC_ENCRYPT 5034
|
||||
#define IDT_KEY_UNIT 5035
|
||||
#define IDT_CIPHER 5036
|
||||
#define IDT_PLAINTEXT_SIZE_UNIT 5037
|
||||
#define IDC_DEVICELIST 5038
|
||||
#define IDT_TEST_BLOCK_NUMBER 5039
|
||||
#define IDT_SECONDARY_KEY 5040
|
||||
#define IDC_PERFORM_BENCHMARK 5041
|
||||
#define IDT_TEST_DATA_UNIT_NUMBER 5042
|
||||
#define IDC_KEYFILES_HIDVOL_PROT 5043
|
||||
#define IDC_KEYLIST 5044
|
||||
#define IDC_ABOUT_BKG 5045
|
||||
#define IDT_ABOUT_VERSION 5046
|
||||
#define IDT_BOX_BENCHMARK_INFO 5047
|
||||
#define IDC_ABOUT_CREDITS 5048
|
||||
#define IDT_SORT_METHOD 5049
|
||||
#define IDC_MOUNT_READONLY 5050
|
||||
#define IDC_MOUNT_REMOVABLE 5051
|
||||
#define IDC_PROTECT_HIDDEN_VOL 5052
|
||||
#define IDC_COMMANDHELP_TEXT 5053
|
||||
#define IDC_USE_EMBEDDED_HEADER_BAK 5054
|
||||
#define IDC_MOUNT_SYSENC_PART_WITHOUT_PBA 5055
|
||||
#define IDT_HIDDEN_PROT_PASSWD 5056
|
||||
#define IDC_RESULTS 5057
|
||||
#define IDC_KEYADD 5058
|
||||
#define IDC_KEYREMOVE 5059
|
||||
#define IDC_KEYREMOVEALL 5060
|
||||
#define IDC_KEYFILES_ENABLE 5061
|
||||
#define IDT_HIDDEN_VOL_PROTECTION 5062
|
||||
#define IDC_ADD_KEYFILE_PATH 5063
|
||||
#define IDC_BENCHMARK_BUFFER_SIZE 5064
|
||||
#define IDC_SHOW_PASSWORD_MO 5065
|
||||
#define IDC_GENERATE_KEYFILE 5066
|
||||
#define IDC_BENCHMARK_SORT_METHOD 5067
|
||||
#define IDC_PASSWORD_PROT_HIDVOL 5068
|
||||
#define IDT_BUFFER_SIZE 5069
|
||||
#define IDC_LANGLIST 5070
|
||||
#define IDC_KEYFILES_ENABLE_HIDVOL_PROT 5071
|
||||
#define IDT_KEYFILES_NOTE 5072
|
||||
#define IDT_KEYFILE_WARNING 5073
|
||||
#define IDT_KEYFILE_GENERATOR_NOTE 5074
|
||||
#define IDC_GENERATE_AND_SAVE_KEYFILE 5075
|
||||
#define IDT_POOL_CONTENTS 5076
|
||||
#define IDC_GET_LANG_PACKS 5077
|
||||
#define IDT_LANGPACK_AUTHORS 5078
|
||||
#define IDC_LANGPACK_CREDITS 5079
|
||||
#define IDC_LANGPACK_VERSION 5080
|
||||
#define IDT_ACTIVE_LANG_PACK 5081
|
||||
#define IDC_DISPLAY_POOL_CONTENTS 5082
|
||||
#define IDC_XTS_MODE_ENABLED 5083
|
||||
#define IDC_MULTI_CHOICE_MSG 5084
|
||||
#define IDC_CHOICE1 5085
|
||||
#define IDC_CHOICE5 5086
|
||||
#define IDC_CHOICE2 5087
|
||||
#define IDC_CHOICE3 5088
|
||||
#define IDC_CHOICE4 5089
|
||||
#define IDC_CHOICE6 5090
|
||||
#define IDC_CHOICE7 5091
|
||||
#define IDC_CHOICE8 5092
|
||||
#define IDC_CHOICE9 5093
|
||||
#define IDC_CHOICE10 5094
|
||||
#define IDC_MC_DLG_HR1 5095
|
||||
#define IDC_MC_DLG_HR2 5096
|
||||
#define IDC_LINK_HIDVOL_PROTECTION_INFO 5097
|
||||
#define IDC_LINK_KEYFILES_INFO 5098
|
||||
#define IDC_TEXTUAL_LOGO_IMG 5099
|
||||
#define IDC_ASPECT_RATIO_CALIBRATION_BOX 5100
|
||||
#define IDC_ABOUT_LOGO_AREA 5101
|
||||
#define IDC_TOKEN_PASSWORD 5102
|
||||
#define IDC_TOKEN_FILE_LIST 5103
|
||||
#define IDC_TOKEN_FILES_ADD 5104
|
||||
#define IDC_EXPORT 5105
|
||||
#define IDC_DELETE 5106
|
||||
#define IDC_IMPORT_KEYFILE 5107
|
||||
#define IDC_SELECTED_TOKEN 5108
|
||||
#define IDT_SECURITY_TOKEN 5109
|
||||
#define IDT_TOKEN_KEYFILE_NAME 5110
|
||||
#define IDC_TOKEN_KEYFILE_NAME 5111
|
||||
#define IDT_TOKEN_PASSWORD_INFO 5112
|
||||
#define IDT_RANDOM_POOL_ENRICHMENT_NOTE 5113
|
||||
#define IDC_CONTINUE 5114
|
||||
#define IDT_ABOUT_RELEASE 5115
|
||||
#define IDT_STATIC_MODELESS_WAIT_DLG_INFO 5116
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 542
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 5117
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
761
src/Common/SecurityToken.cpp
Normal file
761
src/Common/SecurityToken.cpp
Normal file
@ -0,0 +1,761 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Platform/Finally.h"
|
||||
#include "Platform/ForEach.h"
|
||||
|
||||
#if !defined (TC_WINDOWS) || defined (TC_PROTOTYPE)
|
||||
# include "Platform/SerializerFactory.h"
|
||||
# include "Platform/StringConverter.h"
|
||||
# include "Platform/SystemException.h"
|
||||
#else
|
||||
# include "Dictionary.h"
|
||||
# include "Language.h"
|
||||
#endif
|
||||
|
||||
#ifdef TC_UNIX
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "SecurityToken.h"
|
||||
|
||||
#ifndef burn
|
||||
# define burn Memory::Erase
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path)
|
||||
{
|
||||
wstring pathStr = path;
|
||||
unsigned long slotId;
|
||||
|
||||
if (swscanf (pathStr.c_str(), TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1)
|
||||
throw InvalidSecurityTokenKeyfilePath();
|
||||
|
||||
SlotId = slotId;
|
||||
|
||||
size_t keyIdPos = pathStr.find (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/");
|
||||
if (keyIdPos == string::npos)
|
||||
throw InvalidSecurityTokenKeyfilePath();
|
||||
|
||||
Id = pathStr.substr (keyIdPos + wstring (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size());
|
||||
|
||||
vector <SecurityTokenKeyfile> keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id);
|
||||
|
||||
if (keyfiles.empty())
|
||||
throw SecurityTokenKeyfileNotFound();
|
||||
|
||||
*this = keyfiles.front();
|
||||
}
|
||||
|
||||
SecurityTokenKeyfile::operator SecurityTokenKeyfilePath () const
|
||||
{
|
||||
wstringstream path;
|
||||
path << TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/" << SlotId << L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/" << Id;
|
||||
return path.str();
|
||||
}
|
||||
|
||||
void SecurityToken::CheckLibraryStatus ()
|
||||
{
|
||||
if (!Initialized)
|
||||
throw SecurityTokenLibraryNotInitialized();
|
||||
}
|
||||
|
||||
void SecurityToken::CloseLibrary ()
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
CloseAllSessions();
|
||||
Pkcs11Functions->C_Finalize (NULL_PTR);
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
FreeLibrary (Pkcs11LibraryHandle);
|
||||
#else
|
||||
dlclose (Pkcs11LibraryHandle);
|
||||
#endif
|
||||
Initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::CloseAllSessions () throw ()
|
||||
{
|
||||
if (!Initialized)
|
||||
return;
|
||||
|
||||
typedef pair <CK_SLOT_ID, Pkcs11Session> SessionMapPair;
|
||||
|
||||
foreach (SessionMapPair p, Sessions)
|
||||
{
|
||||
try
|
||||
{
|
||||
CloseSession (p.first);
|
||||
}
|
||||
catch (...) { }
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::CloseSession (CK_SLOT_ID slotId)
|
||||
{
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
Pkcs11Functions->C_CloseSession (Sessions[slotId].Handle);
|
||||
Sessions.erase (Sessions.find (slotId));
|
||||
}
|
||||
|
||||
void SecurityToken::CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name)
|
||||
{
|
||||
if (name.empty())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
LoginUserIfRequired (slotId);
|
||||
|
||||
foreach (const SecurityTokenKeyfile &keyfile, GetAvailableKeyfiles (&slotId))
|
||||
{
|
||||
if (keyfile.IdUtf8 == name)
|
||||
throw SecurityTokenKeyfileAlreadyExists();
|
||||
}
|
||||
|
||||
CK_OBJECT_CLASS dataClass = CKO_DATA;
|
||||
CK_BBOOL trueVal = CK_TRUE;
|
||||
|
||||
CK_ATTRIBUTE keyfileTemplate[] =
|
||||
{
|
||||
{ CKA_CLASS, &dataClass, sizeof (dataClass) },
|
||||
{ CKA_TOKEN, &trueVal, sizeof (trueVal) },
|
||||
{ CKA_PRIVATE, &trueVal, sizeof (trueVal) },
|
||||
{ CKA_LABEL, (CK_UTF8CHAR *) name.c_str(), name.size() },
|
||||
{ CKA_VALUE, &keyfileData.front(), keyfileData.size() }
|
||||
};
|
||||
|
||||
CK_OBJECT_HANDLE keyfileHandle;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_CreateObject (Sessions[slotId].Handle, keyfileTemplate, array_capacity (keyfileTemplate), &keyfileHandle);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case CKR_DATA_LEN_RANGE:
|
||||
status = CKR_DEVICE_MEMORY;
|
||||
break;
|
||||
|
||||
case CKR_SESSION_READ_ONLY:
|
||||
status = CKR_TOKEN_WRITE_PROTECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
// Some tokens report success even if the new object was truncated to fit in the available memory
|
||||
vector <byte> objectData;
|
||||
|
||||
GetObjectAttribute (slotId, keyfileHandle, CKA_VALUE, objectData);
|
||||
finally_do_arg (vector <byte> *, &objectData, { if (!finally_arg->empty()) burn (&finally_arg->front(), finally_arg->size()); });
|
||||
|
||||
if (objectData.size() != keyfileData.size())
|
||||
{
|
||||
Pkcs11Functions->C_DestroyObject (Sessions[slotId].Handle, keyfileHandle);
|
||||
throw Pkcs11Exception (CKR_DEVICE_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::DeleteKeyfile (const SecurityTokenKeyfile &keyfile)
|
||||
{
|
||||
LoginUserIfRequired (keyfile.SlotId);
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_DestroyObject (Sessions[keyfile.SlotId].Handle, keyfile.Handle);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
}
|
||||
|
||||
vector <SecurityTokenKeyfile> SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter)
|
||||
{
|
||||
bool unrecognizedTokenPresent = false;
|
||||
vector <SecurityTokenKeyfile> keyfiles;
|
||||
|
||||
foreach (const CK_SLOT_ID &slotId, GetTokenSlots())
|
||||
{
|
||||
SecurityTokenInfo token;
|
||||
|
||||
if (slotIdFilter && *slotIdFilter != slotId)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
LoginUserIfRequired (slotId);
|
||||
token = GetTokenInfo (slotId);
|
||||
}
|
||||
catch (UserAbort &)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
catch (Pkcs11Exception &e)
|
||||
{
|
||||
if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED)
|
||||
{
|
||||
unrecognizedTokenPresent = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
foreach (const CK_OBJECT_HANDLE &dataHandle, GetObjects (slotId, CKO_DATA))
|
||||
{
|
||||
SecurityTokenKeyfile keyfile;
|
||||
keyfile.Handle = dataHandle;
|
||||
keyfile.SlotId = slotId;
|
||||
keyfile.Token = token;
|
||||
|
||||
vector <byte> privateAttrib;
|
||||
GetObjectAttribute (slotId, dataHandle, CKA_PRIVATE, privateAttrib);
|
||||
|
||||
if (privateAttrib.size() == sizeof (CK_BBOOL) && *(CK_BBOOL *) &privateAttrib.front() != CK_TRUE)
|
||||
continue;
|
||||
|
||||
vector <byte> label;
|
||||
GetObjectAttribute (slotId, dataHandle, CKA_LABEL, label);
|
||||
label.push_back (0);
|
||||
|
||||
keyfile.IdUtf8 = (char *) &label.front();
|
||||
|
||||
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
|
||||
keyfile.Id = Utf8StringToWide ((const char *) &label.front());
|
||||
#else
|
||||
keyfile.Id = StringConverter::ToWide ((const char *) &label.front());
|
||||
#endif
|
||||
if (keyfile.Id.empty() || (!keyfileIdFilter.empty() && keyfileIdFilter != keyfile.Id))
|
||||
continue;
|
||||
|
||||
keyfiles.push_back (keyfile);
|
||||
|
||||
if (!keyfileIdFilter.empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyfiles.empty() && unrecognizedTokenPresent)
|
||||
throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED);
|
||||
|
||||
return keyfiles;
|
||||
}
|
||||
|
||||
list <SecurityTokenInfo> SecurityToken::GetAvailableTokens ()
|
||||
{
|
||||
bool unrecognizedTokenPresent = false;
|
||||
list <SecurityTokenInfo> tokens;
|
||||
|
||||
foreach (const CK_SLOT_ID &slotId, GetTokenSlots())
|
||||
{
|
||||
try
|
||||
{
|
||||
tokens.push_back (GetTokenInfo (slotId));
|
||||
}
|
||||
catch (Pkcs11Exception &e)
|
||||
{
|
||||
if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED)
|
||||
{
|
||||
unrecognizedTokenPresent = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens.empty() && unrecognizedTokenPresent)
|
||||
throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED);
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
SecurityTokenInfo SecurityToken::GetTokenInfo (CK_SLOT_ID slotId)
|
||||
{
|
||||
CK_TOKEN_INFO info;
|
||||
CK_RV status = Pkcs11Functions->C_GetTokenInfo (slotId, &info);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
SecurityTokenInfo token;
|
||||
token.SlotId = slotId;
|
||||
token.Flags = info.flags;
|
||||
|
||||
char label[sizeof (info.label) + 1];
|
||||
memset (label, 0, sizeof (label));
|
||||
memcpy (label, info.label, sizeof (info.label));
|
||||
|
||||
token.LabelUtf8 = label;
|
||||
|
||||
size_t lastSpace = token.LabelUtf8.find_last_not_of (' ');
|
||||
if (lastSpace == string::npos)
|
||||
token.LabelUtf8.clear();
|
||||
else
|
||||
token.LabelUtf8 = token.LabelUtf8.substr (0, lastSpace + 1);
|
||||
|
||||
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
|
||||
token.Label = Utf8StringToWide (token.LabelUtf8);
|
||||
#else
|
||||
token.Label = StringConverter::ToWide (token.LabelUtf8);
|
||||
#endif
|
||||
return token;
|
||||
}
|
||||
|
||||
void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData)
|
||||
{
|
||||
LoginUserIfRequired (keyfile.SlotId);
|
||||
GetObjectAttribute (keyfile.SlotId, keyfile.Handle, CKA_VALUE, keyfileData);
|
||||
}
|
||||
|
||||
vector <CK_OBJECT_HANDLE> SecurityToken::GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass)
|
||||
{
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
CK_ATTRIBUTE findTemplate;
|
||||
findTemplate.type = CKA_CLASS;
|
||||
findTemplate.pValue = &objectClass;
|
||||
findTemplate.ulValueLen = sizeof (objectClass);
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_FindObjectsInit (Sessions[slotId].Handle, &findTemplate, 1);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
finally_do_arg (CK_SLOT_ID, slotId, { Pkcs11Functions->C_FindObjectsFinal (Sessions[finally_arg].Handle); });
|
||||
|
||||
CK_ULONG objectCount;
|
||||
vector <CK_OBJECT_HANDLE> objects;
|
||||
|
||||
while (true)
|
||||
{
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_RV status = Pkcs11Functions->C_FindObjects (Sessions[slotId].Handle, &object, 1, &objectCount);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
if (objectCount != 1)
|
||||
break;
|
||||
|
||||
objects.push_back (object);
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
void SecurityToken::GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue)
|
||||
{
|
||||
attributeValue.clear();
|
||||
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
CK_ATTRIBUTE attribute;
|
||||
attribute.type = attributeType;
|
||||
attribute.pValue = NULL_PTR;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
if (attribute.ulValueLen == 0)
|
||||
return;
|
||||
|
||||
attributeValue = vector <byte> (attribute.ulValueLen);
|
||||
attribute.pValue = &attributeValue.front();
|
||||
|
||||
status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
}
|
||||
|
||||
list <CK_SLOT_ID> SecurityToken::GetTokenSlots ()
|
||||
{
|
||||
CheckLibraryStatus();
|
||||
|
||||
list <CK_SLOT_ID> slots;
|
||||
CK_ULONG slotCount;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_GetSlotList (TRUE, NULL_PTR, &slotCount);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
if (slotCount > 0)
|
||||
{
|
||||
vector <CK_SLOT_ID> slotArray (slotCount);
|
||||
status = Pkcs11Functions->C_GetSlotList (TRUE, &slotArray.front(), &slotCount);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
for (size_t i = 0; i < slotCount; i++)
|
||||
{
|
||||
CK_SLOT_INFO slotInfo;
|
||||
status = Pkcs11Functions->C_GetSlotInfo (slotArray[i], &slotInfo);
|
||||
|
||||
if (status != CKR_OK || !(slotInfo.flags & CKF_TOKEN_PRESENT))
|
||||
continue;
|
||||
|
||||
slots.push_back (slotArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
bool SecurityToken::IsKeyfilePathValid (const wstring &securityTokenKeyfilePath)
|
||||
{
|
||||
return securityTokenKeyfilePath.find (TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0;
|
||||
}
|
||||
|
||||
void SecurityToken::Login (CK_SLOT_ID slotId, const string &pin)
|
||||
{
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
OpenSession (slotId);
|
||||
else if (Sessions[slotId].UserLoggedIn)
|
||||
return;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, (CK_CHAR_PTR) pin.c_str(), pin.size());
|
||||
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
Sessions[slotId].UserLoggedIn = true;
|
||||
}
|
||||
|
||||
void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId)
|
||||
{
|
||||
CheckLibraryStatus();
|
||||
CK_RV status;
|
||||
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
{
|
||||
OpenSession (slotId);
|
||||
}
|
||||
else
|
||||
{
|
||||
CK_SESSION_INFO sessionInfo;
|
||||
status = Pkcs11Functions->C_GetSessionInfo (Sessions[slotId].Handle, &sessionInfo);
|
||||
|
||||
if (status == CKR_OK)
|
||||
{
|
||||
Sessions[slotId].UserLoggedIn = (sessionInfo.state == CKS_RO_USER_FUNCTIONS || sessionInfo.state == CKS_RW_USER_FUNCTIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
CloseSession (slotId);
|
||||
}
|
||||
catch (...) { }
|
||||
OpenSession (slotId);
|
||||
}
|
||||
}
|
||||
|
||||
SecurityTokenInfo tokenInfo = GetTokenInfo (slotId);
|
||||
|
||||
while (!Sessions[slotId].UserLoggedIn && (tokenInfo.Flags & CKF_LOGIN_REQUIRED))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||
{
|
||||
status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, NULL_PTR, 0);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
}
|
||||
else
|
||||
{
|
||||
string pin = tokenInfo.LabelUtf8;
|
||||
if (tokenInfo.Label.empty())
|
||||
{
|
||||
stringstream s;
|
||||
s << "#" << slotId;
|
||||
pin = s.str();
|
||||
}
|
||||
|
||||
finally_do_arg (string*, &pin, { burn ((void *) finally_arg->c_str(), finally_arg->size()); });
|
||||
|
||||
(*PinCallback) (pin);
|
||||
Login (slotId, pin);
|
||||
}
|
||||
|
||||
Sessions[slotId].UserLoggedIn = true;
|
||||
}
|
||||
catch (Pkcs11Exception &e)
|
||||
{
|
||||
CK_RV error = e.GetErrorCode();
|
||||
|
||||
if (error == CKR_USER_ALREADY_LOGGED_IN)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (error == CKR_PIN_INCORRECT && !(tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH))
|
||||
{
|
||||
(*WarningCallback) (Pkcs11Exception (CKR_PIN_INCORRECT));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::InitLibrary (const string &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback)
|
||||
{
|
||||
if (Initialized)
|
||||
CloseLibrary();
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
Pkcs11LibraryHandle = LoadLibraryA (pkcs11LibraryPath.c_str());
|
||||
#else
|
||||
Pkcs11LibraryHandle = dlopen (pkcs11LibraryPath.c_str(), RTLD_NOW | RTLD_LOCAL);
|
||||
#endif
|
||||
throw_sys_if (!Pkcs11LibraryHandle);
|
||||
|
||||
typedef CK_RV (*C_GetFunctionList_t) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
|
||||
#ifdef TC_WINDOWS
|
||||
C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) GetProcAddress (Pkcs11LibraryHandle, "C_GetFunctionList");
|
||||
#else
|
||||
C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) dlsym (Pkcs11LibraryHandle, "C_GetFunctionList");
|
||||
#endif
|
||||
|
||||
if (!C_GetFunctionList)
|
||||
throw SecurityTokenLibraryNotInitialized();
|
||||
|
||||
CK_RV status = C_GetFunctionList (&Pkcs11Functions);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
status = Pkcs11Functions->C_Initialize (NULL_PTR);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
PinCallback = pinCallback;
|
||||
WarningCallback = warningCallback;
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
void SecurityToken::OpenSession (CK_SLOT_ID slotId)
|
||||
{
|
||||
if (Sessions.find (slotId) != Sessions.end())
|
||||
return;
|
||||
|
||||
CK_SESSION_HANDLE session;
|
||||
|
||||
CK_FLAGS flags = CKF_SERIAL_SESSION;
|
||||
|
||||
if (!(GetTokenInfo (slotId).Flags & CKF_WRITE_PROTECTED))
|
||||
flags |= CKF_RW_SESSION;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_OpenSession (slotId, flags, NULL_PTR, NULL_PTR, &session);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
Sessions[slotId].Handle = session;
|
||||
}
|
||||
|
||||
Pkcs11Exception::operator string () const
|
||||
{
|
||||
if (ErrorCode == CKR_OK)
|
||||
return string();
|
||||
|
||||
static const struct
|
||||
{
|
||||
CK_RV ErrorCode;
|
||||
const char *ErrorString;
|
||||
} ErrorStrings[] =
|
||||
{
|
||||
# define TC_TOKEN_ERR(CODE) { CODE, #CODE },
|
||||
|
||||
TC_TOKEN_ERR (CKR_CANCEL)
|
||||
TC_TOKEN_ERR (CKR_HOST_MEMORY)
|
||||
TC_TOKEN_ERR (CKR_SLOT_ID_INVALID)
|
||||
TC_TOKEN_ERR (CKR_GENERAL_ERROR)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_FAILED)
|
||||
TC_TOKEN_ERR (CKR_ARGUMENTS_BAD)
|
||||
TC_TOKEN_ERR (CKR_NO_EVENT)
|
||||
TC_TOKEN_ERR (CKR_NEED_TO_CREATE_THREADS)
|
||||
TC_TOKEN_ERR (CKR_CANT_LOCK)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_READ_ONLY)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_SENSITIVE)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_TYPE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_VALUE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_DATA_INVALID)
|
||||
TC_TOKEN_ERR (CKR_DATA_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_DEVICE_ERROR)
|
||||
TC_TOKEN_ERR (CKR_DEVICE_MEMORY)
|
||||
TC_TOKEN_ERR (CKR_DEVICE_REMOVED)
|
||||
TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_INVALID)
|
||||
TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_CANCELED)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_NOT_PARALLEL)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_NOT_SUPPORTED)
|
||||
TC_TOKEN_ERR (CKR_KEY_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_KEY_SIZE_RANGE)
|
||||
TC_TOKEN_ERR (CKR_KEY_TYPE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_KEY_NOT_NEEDED)
|
||||
TC_TOKEN_ERR (CKR_KEY_CHANGED)
|
||||
TC_TOKEN_ERR (CKR_KEY_NEEDED)
|
||||
TC_TOKEN_ERR (CKR_KEY_INDIGESTIBLE)
|
||||
TC_TOKEN_ERR (CKR_KEY_FUNCTION_NOT_PERMITTED)
|
||||
TC_TOKEN_ERR (CKR_KEY_NOT_WRAPPABLE)
|
||||
TC_TOKEN_ERR (CKR_KEY_UNEXTRACTABLE)
|
||||
TC_TOKEN_ERR (CKR_MECHANISM_INVALID)
|
||||
TC_TOKEN_ERR (CKR_MECHANISM_PARAM_INVALID)
|
||||
TC_TOKEN_ERR (CKR_OBJECT_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_OPERATION_ACTIVE)
|
||||
TC_TOKEN_ERR (CKR_OPERATION_NOT_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_PIN_INCORRECT)
|
||||
TC_TOKEN_ERR (CKR_PIN_INVALID)
|
||||
TC_TOKEN_ERR (CKR_PIN_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_PIN_EXPIRED)
|
||||
TC_TOKEN_ERR (CKR_PIN_LOCKED)
|
||||
TC_TOKEN_ERR (CKR_SESSION_CLOSED)
|
||||
TC_TOKEN_ERR (CKR_SESSION_COUNT)
|
||||
TC_TOKEN_ERR (CKR_SESSION_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_SESSION_PARALLEL_NOT_SUPPORTED)
|
||||
TC_TOKEN_ERR (CKR_SESSION_READ_ONLY)
|
||||
TC_TOKEN_ERR (CKR_SESSION_EXISTS)
|
||||
TC_TOKEN_ERR (CKR_SESSION_READ_ONLY_EXISTS)
|
||||
TC_TOKEN_ERR (CKR_SESSION_READ_WRITE_SO_EXISTS)
|
||||
TC_TOKEN_ERR (CKR_SIGNATURE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_SIGNATURE_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_TEMPLATE_INCOMPLETE)
|
||||
TC_TOKEN_ERR (CKR_TEMPLATE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_TOKEN_NOT_PRESENT)
|
||||
TC_TOKEN_ERR (CKR_TOKEN_NOT_RECOGNIZED)
|
||||
TC_TOKEN_ERR (CKR_TOKEN_WRITE_PROTECTED)
|
||||
TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_SIZE_RANGE)
|
||||
TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_USER_ALREADY_LOGGED_IN)
|
||||
TC_TOKEN_ERR (CKR_USER_NOT_LOGGED_IN)
|
||||
TC_TOKEN_ERR (CKR_USER_PIN_NOT_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_USER_TYPE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
|
||||
TC_TOKEN_ERR (CKR_USER_TOO_MANY_TYPES)
|
||||
TC_TOKEN_ERR (CKR_WRAPPED_KEY_INVALID)
|
||||
TC_TOKEN_ERR (CKR_WRAPPED_KEY_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_WRAPPING_KEY_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_WRAPPING_KEY_SIZE_RANGE)
|
||||
TC_TOKEN_ERR (CKR_WRAPPING_KEY_TYPE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_RANDOM_SEED_NOT_SUPPORTED)
|
||||
TC_TOKEN_ERR (CKR_RANDOM_NO_RNG)
|
||||
TC_TOKEN_ERR (CKR_DOMAIN_PARAMS_INVALID)
|
||||
TC_TOKEN_ERR (CKR_BUFFER_TOO_SMALL)
|
||||
TC_TOKEN_ERR (CKR_SAVED_STATE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_INFORMATION_SENSITIVE)
|
||||
TC_TOKEN_ERR (CKR_STATE_UNSAVEABLE)
|
||||
TC_TOKEN_ERR (CKR_CRYPTOKI_NOT_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_CRYPTOKI_ALREADY_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_MUTEX_BAD)
|
||||
TC_TOKEN_ERR (CKR_MUTEX_NOT_LOCKED)
|
||||
TC_TOKEN_ERR (CKR_NEW_PIN_MODE)
|
||||
TC_TOKEN_ERR (CKR_NEXT_OTP)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_REJECTED)
|
||||
|
||||
#undef TC_TOKEN_ERR
|
||||
};
|
||||
|
||||
|
||||
for (size_t i = 0; i < array_capacity (ErrorStrings); ++i)
|
||||
{
|
||||
if (ErrorStrings[i].ErrorCode == ErrorCode)
|
||||
return ErrorStrings[i].ErrorString;
|
||||
}
|
||||
|
||||
stringstream s;
|
||||
s << "0x" << hex << ErrorCode;
|
||||
return s.str();
|
||||
|
||||
}
|
||||
|
||||
#ifdef TC_HEADER_Common_Exception
|
||||
void Pkcs11Exception::Show (HWND parent) const
|
||||
{
|
||||
string errorString = string (*this);
|
||||
|
||||
if (!errorString.empty())
|
||||
{
|
||||
wstringstream subjectErrorCode;
|
||||
if (SubjectErrorCodeValid)
|
||||
subjectErrorCode << L": " << SubjectErrorCode;
|
||||
|
||||
if (!GetDictionaryValue (errorString.c_str()))
|
||||
{
|
||||
if (errorString.find ("CKR_") == 0)
|
||||
{
|
||||
errorString = errorString.substr (4);
|
||||
for (size_t i = 0; i < errorString.size(); ++i)
|
||||
{
|
||||
if (errorString[i] == '_')
|
||||
errorString[i] = ' ';
|
||||
}
|
||||
}
|
||||
wchar_t err[8192];
|
||||
wsprintfW (err, L"%s:\n\n%hs%s", GetString ("SECURITY_TOKEN_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str());
|
||||
ErrorDirect (err);
|
||||
}
|
||||
else
|
||||
{
|
||||
wstring err = GetString (errorString.c_str());
|
||||
|
||||
if (SubjectErrorCodeValid)
|
||||
err += L"\n\nError code" + subjectErrorCode.str();
|
||||
|
||||
ErrorDirect (err.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // TC_HEADER_Common_Exception
|
||||
|
||||
auto_ptr <GetPinFunctor> SecurityToken::PinCallback;
|
||||
auto_ptr <SendExceptionFunctor> SecurityToken::WarningCallback;
|
||||
|
||||
bool SecurityToken::Initialized;
|
||||
CK_FUNCTION_LIST_PTR SecurityToken::Pkcs11Functions;
|
||||
map <CK_SLOT_ID, Pkcs11Session> SecurityToken::Sessions;
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
HMODULE SecurityToken::Pkcs11LibraryHandle;
|
||||
#else
|
||||
void *SecurityToken::Pkcs11LibraryHandle;
|
||||
#endif
|
||||
|
||||
#ifdef TC_HEADER_Platform_Exception
|
||||
|
||||
void Pkcs11Exception::Deserialize (shared_ptr <Stream> stream)
|
||||
{
|
||||
Exception::Deserialize (stream);
|
||||
Serializer sr (stream);
|
||||
uint64 code;
|
||||
sr.Deserialize ("ErrorCode", code);
|
||||
sr.Deserialize ("SubjectErrorCodeValid", SubjectErrorCodeValid);
|
||||
sr.Deserialize ("SubjectErrorCode", SubjectErrorCode);
|
||||
ErrorCode = (CK_RV) code;
|
||||
}
|
||||
|
||||
void Pkcs11Exception::Serialize (shared_ptr <Stream> stream) const
|
||||
{
|
||||
Exception::Serialize (stream);
|
||||
Serializer sr (stream);
|
||||
sr.Serialize ("ErrorCode", (uint64) ErrorCode);
|
||||
sr.Serialize ("SubjectErrorCodeValid", SubjectErrorCodeValid);
|
||||
sr.Serialize ("SubjectErrorCode", SubjectErrorCode);
|
||||
}
|
||||
|
||||
# define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
# undef TC_EXCEPTION_NODECL
|
||||
# define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SecurityTokenException);
|
||||
|
||||
#endif
|
||||
}
|
216
src/Common/SecurityToken.h
Normal file
216
src/Common/SecurityToken.h
Normal file
@ -0,0 +1,216 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_SecurityToken
|
||||
#define TC_HEADER_Common_SecurityToken
|
||||
|
||||
#include "Platform/PlatformBase.h"
|
||||
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
|
||||
# include "Exception.h"
|
||||
#else
|
||||
# include "Platform/Exception.h"
|
||||
#endif
|
||||
|
||||
#ifndef NULL_PTR
|
||||
# define NULL_PTR 0
|
||||
#endif
|
||||
#define CK_PTR *
|
||||
#define CK_CALLBACK_FUNCTION(RET_TYPE, NAME) RET_TYPE (* NAME)
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# define CK_DEFINE_FUNCTION(RET_TYPE, NAME) RET_TYPE __declspec(dllexport) NAME
|
||||
# define CK_DECLARE_FUNCTION(RET_TYPE, NAME) RET_TYPE __declspec(dllimport) NAME
|
||||
# define CK_DECLARE_FUNCTION_POINTER(RET_TYPE, NAME) RET_TYPE __declspec(dllimport) (* NAME)
|
||||
|
||||
# pragma pack(push, cryptoki, 1)
|
||||
# include <pkcs11.h>
|
||||
# pragma pack(pop, cryptoki)
|
||||
|
||||
#else // !TC_WINDOWS
|
||||
|
||||
# define CK_DEFINE_FUNCTION(RET_TYPE, NAME) RET_TYPE NAME
|
||||
# define CK_DECLARE_FUNCTION(RET_TYPE, NAME) RET_TYPE NAME
|
||||
# define CK_DECLARE_FUNCTION_POINTER(RET_TYPE, NAME) RET_TYPE (* NAME)
|
||||
|
||||
# include <pkcs11.h>
|
||||
|
||||
#endif // !TC_WINDOWS
|
||||
|
||||
|
||||
#define TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX L"token://"
|
||||
#define TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"slot"
|
||||
#define TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"file"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
struct SecurityTokenInfo
|
||||
{
|
||||
CK_SLOT_ID SlotId;
|
||||
CK_FLAGS Flags;
|
||||
wstring Label;
|
||||
string LabelUtf8;
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfilePath
|
||||
{
|
||||
SecurityTokenKeyfilePath () { }
|
||||
SecurityTokenKeyfilePath (const wstring &path) : Path (path) { }
|
||||
operator wstring () const { return Path; }
|
||||
wstring Path;
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfile
|
||||
{
|
||||
SecurityTokenKeyfile () { }
|
||||
SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path);
|
||||
|
||||
operator SecurityTokenKeyfilePath () const;
|
||||
|
||||
CK_OBJECT_HANDLE Handle;
|
||||
wstring Id;
|
||||
string IdUtf8;
|
||||
CK_SLOT_ID SlotId;
|
||||
SecurityTokenInfo Token;
|
||||
};
|
||||
|
||||
struct Pkcs11Exception : public Exception
|
||||
{
|
||||
Pkcs11Exception (CK_RV errorCode = (CK_RV) -1)
|
||||
: ErrorCode (errorCode),
|
||||
SubjectErrorCodeValid (false)
|
||||
{
|
||||
}
|
||||
|
||||
Pkcs11Exception (CK_RV errorCode, uint64 subjectErrorCode)
|
||||
: ErrorCode (errorCode),
|
||||
SubjectErrorCodeValid (true),
|
||||
SubjectErrorCode (subjectErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TC_HEADER_Platform_Exception
|
||||
virtual ~Pkcs11Exception () throw () { }
|
||||
TC_SERIALIZABLE_EXCEPTION (Pkcs11Exception);
|
||||
#else
|
||||
void Show (HWND parent) const;
|
||||
#endif
|
||||
operator string () const;
|
||||
CK_RV GetErrorCode () const { return ErrorCode; }
|
||||
|
||||
protected:
|
||||
CK_RV ErrorCode;
|
||||
bool SubjectErrorCodeValid;
|
||||
uint64 SubjectErrorCode;
|
||||
};
|
||||
|
||||
|
||||
#ifdef TC_HEADER_Platform_Exception
|
||||
|
||||
#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,Exception)
|
||||
|
||||
#undef TC_EXCEPTION_SET
|
||||
#define TC_EXCEPTION_SET \
|
||||
TC_EXCEPTION_NODECL (Pkcs11Exception); \
|
||||
TC_EXCEPTION (InvalidSecurityTokenKeyfilePath); \
|
||||
TC_EXCEPTION (SecurityTokenLibraryNotInitialized); \
|
||||
TC_EXCEPTION (SecurityTokenKeyfileAlreadyExists); \
|
||||
TC_EXCEPTION (SecurityTokenKeyfileNotFound);
|
||||
|
||||
TC_EXCEPTION_SET;
|
||||
|
||||
#undef TC_EXCEPTION
|
||||
|
||||
#else // !TC_HEADER_Platform_Exception
|
||||
|
||||
struct SecurityTokenLibraryNotInitialized : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error (SecurityTokenLibraryPath[0] == 0 ? "NO_PKCS11_MODULE_SPECIFIED" : "PKCS11_MODULE_INIT_FAILED"); }
|
||||
};
|
||||
|
||||
struct InvalidSecurityTokenKeyfilePath : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error ("INVALID_TOKEN_KEYFILE_PATH"); }
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfileAlreadyExists : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error ("TOKEN_KEYFILE_ALREADY_EXISTS"); }
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfileNotFound : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error ("TOKEN_KEYFILE_NOT_FOUND"); }
|
||||
};
|
||||
|
||||
#endif // !TC_HEADER_Platform_Exception
|
||||
|
||||
|
||||
struct Pkcs11Session
|
||||
{
|
||||
Pkcs11Session () : UserLoggedIn (false) { }
|
||||
|
||||
CK_SESSION_HANDLE Handle;
|
||||
bool UserLoggedIn;
|
||||
};
|
||||
|
||||
struct GetPinFunctor
|
||||
{
|
||||
virtual ~GetPinFunctor () { }
|
||||
virtual void operator() (string &str) = 0;
|
||||
};
|
||||
|
||||
struct SendExceptionFunctor
|
||||
{
|
||||
virtual ~SendExceptionFunctor () { }
|
||||
virtual void operator() (const Exception &e) = 0;
|
||||
};
|
||||
|
||||
class SecurityToken
|
||||
{
|
||||
public:
|
||||
static void CloseAllSessions () throw ();
|
||||
static void CloseLibrary ();
|
||||
static void CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name);
|
||||
static void DeleteKeyfile (const SecurityTokenKeyfile &keyfile);
|
||||
static vector <SecurityTokenKeyfile> GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
|
||||
static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData);
|
||||
static list <SecurityTokenInfo> GetAvailableTokens ();
|
||||
static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId);
|
||||
static void InitLibrary (const string &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback);
|
||||
static bool IsInitialized () { return Initialized; }
|
||||
static bool IsKeyfilePathValid (const wstring &securityTokenKeyfilePath);
|
||||
|
||||
static const size_t MaxPasswordLength = 128;
|
||||
|
||||
protected:
|
||||
static void CloseSession (CK_SLOT_ID slotId);
|
||||
static vector <CK_OBJECT_HANDLE> GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass);
|
||||
static void GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue);
|
||||
static list <CK_SLOT_ID> GetTokenSlots ();
|
||||
static void Login (CK_SLOT_ID slotId, const string &pin);
|
||||
static void LoginUserIfRequired (CK_SLOT_ID slotId);
|
||||
static void OpenSession (CK_SLOT_ID slotId);
|
||||
static void CheckLibraryStatus ();
|
||||
|
||||
static bool Initialized;
|
||||
static auto_ptr <GetPinFunctor> PinCallback;
|
||||
static CK_FUNCTION_LIST_PTR Pkcs11Functions;
|
||||
#ifdef TC_WINDOWS
|
||||
static HMODULE Pkcs11LibraryHandle;
|
||||
#else
|
||||
static void *Pkcs11LibraryHandle;
|
||||
#endif
|
||||
static map <CK_SLOT_ID, Pkcs11Session> Sessions;
|
||||
static auto_ptr <SendExceptionFunctor> WarningCallback;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Common_SecurityToken
|
17
src/Common/Sources
Normal file
17
src/Common/Sources
Normal file
@ -0,0 +1,17 @@
|
||||
TARGETNAME=Common
|
||||
TARGETTYPE=DRIVER_LIBRARY
|
||||
|
||||
INCLUDES = ..;../Crypto
|
||||
|
||||
SOURCES = \
|
||||
Cache.c \
|
||||
Crc.c \
|
||||
Crypto.c \
|
||||
EncryptionThreadPool.c \
|
||||
Endian.c \
|
||||
GfMul.c \
|
||||
Pkcs5.c \
|
||||
Volumes.c \
|
||||
Xts.c \
|
||||
Tests.c \
|
||||
Wipe.c
|
301
src/Common/Tcdefs.h
Normal file
301
src/Common/Tcdefs.h
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TCDEFS_H
|
||||
#define TCDEFS_H
|
||||
|
||||
#define TC_APP_NAME "TrueCrypt"
|
||||
|
||||
// Version displayed to user
|
||||
#define VERSION_STRING "7.1a"
|
||||
|
||||
// Version number to compare against driver
|
||||
#define VERSION_NUM 0x071a
|
||||
|
||||
// Release date
|
||||
#define TC_STR_RELEASE_DATE "February 7, 2012"
|
||||
#define TC_RELEASE_DATE_YEAR 2012
|
||||
#define TC_RELEASE_DATE_MONTH 2
|
||||
|
||||
#define BYTES_PER_KB 1024LL
|
||||
#define BYTES_PER_MB 1048576LL
|
||||
#define BYTES_PER_GB 1073741824LL
|
||||
#define BYTES_PER_TB 1099511627776LL
|
||||
#define BYTES_PER_PB 1125899906842624LL
|
||||
|
||||
/* GUI/driver errors */
|
||||
|
||||
#define WIDE(x) (LPWSTR)L##x
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
typedef __int8 int8;
|
||||
typedef __int16 int16;
|
||||
typedef __int32 int32;
|
||||
typedef unsigned __int8 byte;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef unsigned __int32 uint32;
|
||||
|
||||
#ifdef TC_NO_COMPILER_INT64
|
||||
typedef unsigned __int32 TC_LARGEST_COMPILER_UINT;
|
||||
#else
|
||||
typedef unsigned __int64 TC_LARGEST_COMPILER_UINT;
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#endif
|
||||
|
||||
#else // !_MSC_VER
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
#if UCHAR_MAX != 0xffU
|
||||
#error UCHAR_MAX != 0xff
|
||||
#endif
|
||||
#define __int8 char
|
||||
|
||||
#if USHRT_MAX != 0xffffU
|
||||
#error USHRT_MAX != 0xffff
|
||||
#endif
|
||||
#define __int16 short
|
||||
|
||||
#if UINT_MAX != 0xffffffffU
|
||||
#error UINT_MAX != 0xffffffff
|
||||
#endif
|
||||
#define __int32 int
|
||||
|
||||
typedef uint64 TC_LARGEST_COMPILER_UINT;
|
||||
|
||||
#define BOOL int
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#endif // !_MSC_VER
|
||||
|
||||
#define TC_INT_TYPES_DEFINED
|
||||
|
||||
// Integer types required by Cryptolib
|
||||
typedef unsigned __int8 uint_8t;
|
||||
typedef unsigned __int16 uint_16t;
|
||||
typedef unsigned __int32 uint_32t;
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
typedef uint64 uint_64t;
|
||||
#endif
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned __int32 LowPart;
|
||||
unsigned __int32 HighPart;
|
||||
};
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
uint64 Value;
|
||||
#endif
|
||||
|
||||
} UINT64_STRUCT;
|
||||
|
||||
#ifdef TC_WINDOWS_BOOT
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void ThrowFatalException (int line);
|
||||
|
||||
# define TC_THROW_FATAL_EXCEPTION ThrowFatalException (__LINE__)
|
||||
#elif defined (TC_WINDOWS_DRIVER)
|
||||
# define TC_THROW_FATAL_EXCEPTION KeBugCheckEx (SECURITY_SYSTEM, __LINE__, 0, 0, 'TC')
|
||||
#else
|
||||
# define TC_THROW_FATAL_EXCEPTION *(char *) 0 = 0
|
||||
#endif
|
||||
|
||||
#ifdef TC_WINDOWS_DRIVER
|
||||
|
||||
#include <ntifs.h>
|
||||
#include <ntddk.h> /* Standard header file for nt drivers */
|
||||
#include <ntdddisk.h> /* Standard I/O control codes */
|
||||
|
||||
#define TCalloc(size) ((void *) ExAllocatePoolWithTag( NonPagedPool, size, 'MMCT' ))
|
||||
#define TCfree(memblock) ExFreePoolWithTag( memblock, 'MMCT' )
|
||||
|
||||
#define DEVICE_DRIVER
|
||||
|
||||
#ifndef BOOL
|
||||
typedef int BOOL;
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE !TRUE
|
||||
#endif
|
||||
|
||||
#else /* !TC_WINDOWS_DRIVER */
|
||||
|
||||
#define TCalloc malloc
|
||||
#define TCfree free
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef TC_LOCAL_WIN32_WINNT_OVERRIDE
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0501 /* Does not apply to the driver */
|
||||
#endif
|
||||
|
||||
#include <windows.h> /* Windows header */
|
||||
#include <commctrl.h> /* The common controls */
|
||||
#include <process.h> /* Process control */
|
||||
#include <winioctl.h>
|
||||
#include <stdio.h> /* For sprintf */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* !TC_WINDOWS_DRIVER */
|
||||
|
||||
#ifndef TC_TO_STRING
|
||||
# define TC_TO_STRING2(n) #n
|
||||
# define TC_TO_STRING(n) TC_TO_STRING2(n)
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
# if defined (DEBUG) || 0
|
||||
# if 1 // DbgPrintEx is not available on Windows 2000
|
||||
# define Dump DbgPrint
|
||||
# else
|
||||
# define Dump(...) DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__)
|
||||
# endif
|
||||
# define DumpMem(...) DumpMemory (__VA_ARGS__)
|
||||
# else
|
||||
# define Dump(...)
|
||||
# define DumpMem(...)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (trace_msg) && !defined (TC_WINDOWS_BOOT)
|
||||
# ifdef DEBUG
|
||||
# ifdef DEVICE_DRIVER
|
||||
# define trace_msg Dump
|
||||
# elif defined (_WIN32)
|
||||
# define trace_msg(...) do { char msg[2048]; _snprintf (msg, sizeof (msg), __VA_ARGS__); OutputDebugString (msg); } while (0)
|
||||
# endif
|
||||
# define trace_point trace_msg (__FUNCTION__ ":" TC_TO_STRING(__LINE__) "\n")
|
||||
# else
|
||||
# define trace_msg(...)
|
||||
# define trace_point
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
# define TC_EVENT KEVENT
|
||||
# define TC_WAIT_EVENT(EVENT) KeWaitForSingleObject (&EVENT, Executive, KernelMode, FALSE, NULL)
|
||||
#elif defined (_WIN32)
|
||||
# define TC_EVENT HANDLE
|
||||
# define TC_WAIT_EVENT(EVENT) WaitForSingleObject (EVENT, INFINITE)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); int burnc = size; RtlSecureZeroMemory (mem, size); while (burnc--) *burnm++ = 0; } while (0)
|
||||
#else
|
||||
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); int burnc = size; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#endif
|
||||
|
||||
// The size of the memory area to wipe is in bytes amd it must be a multiple of 8.
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
# define FAST_ERASE64(mem,size) do { volatile uint64 *burnm = (volatile uint64 *)(mem); int burnc = size >> 3; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#else
|
||||
# define FAST_ERASE64(mem,size) do { volatile unsigned __int32 *burnm = (volatile unsigned __int32 *)(mem); int burnc = size >> 2; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef TC_WINDOWS_BOOT
|
||||
# ifndef max
|
||||
# define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void EraseMemory (void *memory, int size);
|
||||
|
||||
# undef burn
|
||||
# define burn EraseMemory
|
||||
#endif
|
||||
|
||||
#ifdef MAX_PATH
|
||||
#define TC_MAX_PATH MAX_PATH
|
||||
#else
|
||||
#define TC_MAX_PATH 260 /* Includes the null terminator */
|
||||
#endif
|
||||
|
||||
#define TC_STR_RELEASED_BY "Released by TrueCrypt Foundation on " TC_STR_RELEASE_DATE
|
||||
|
||||
#define MAX_URL_LENGTH 2084 /* Internet Explorer limit. Includes the terminating null character. */
|
||||
|
||||
#define TC_HOMEPAGE "http://www.truecrypt.org/"
|
||||
#define TC_APPLINK "http://www.truecrypt.org/applink?version=" VERSION_STRING
|
||||
#define TC_APPLINK_SECURE "https://www.truecrypt.org/applink?version=" VERSION_STRING
|
||||
|
||||
enum
|
||||
{
|
||||
/* WARNING: ADD ANY NEW CODES AT THE END (DO NOT INSERT THEM BETWEEN EXISTING). DO *NOT* DELETE ANY
|
||||
EXISTING CODES! Changing these values or their meanings may cause incompatibility with other versions
|
||||
(for example, if a new version of the TrueCrypt installer receives an error code from an installed
|
||||
driver whose version is lower, it will report and interpret the error incorrectly). */
|
||||
|
||||
ERR_SUCCESS = 0,
|
||||
ERR_OS_ERROR = 1,
|
||||
ERR_OUTOFMEMORY = 2,
|
||||
ERR_PASSWORD_WRONG = 3,
|
||||
ERR_VOL_FORMAT_BAD = 4,
|
||||
ERR_DRIVE_NOT_FOUND = 5,
|
||||
ERR_FILES_OPEN = 6,
|
||||
ERR_VOL_SIZE_WRONG = 7,
|
||||
ERR_COMPRESSION_NOT_SUPPORTED = 8,
|
||||
ERR_PASSWORD_CHANGE_VOL_TYPE = 9,
|
||||
ERR_PASSWORD_CHANGE_VOL_VERSION = 10,
|
||||
ERR_VOL_SEEKING = 11,
|
||||
ERR_VOL_WRITING = 12,
|
||||
ERR_FILES_OPEN_LOCK = 13,
|
||||
ERR_VOL_READING = 14,
|
||||
ERR_DRIVER_VERSION = 15,
|
||||
ERR_NEW_VERSION_REQUIRED = 16,
|
||||
ERR_CIPHER_INIT_FAILURE = 17,
|
||||
ERR_CIPHER_INIT_WEAK_KEY = 18,
|
||||
ERR_SELF_TESTS_FAILED = 19,
|
||||
ERR_SECTOR_SIZE_INCOMPATIBLE = 20,
|
||||
ERR_VOL_ALREADY_MOUNTED = 21,
|
||||
ERR_NO_FREE_DRIVES = 22,
|
||||
ERR_FILE_OPEN_FAILED = 23,
|
||||
ERR_VOL_MOUNT_FAILED = 24,
|
||||
DEPRECATED_ERR_INVALID_DEVICE = 25,
|
||||
ERR_ACCESS_DENIED = 26,
|
||||
ERR_MODE_INIT_FAILED = 27,
|
||||
ERR_DONT_REPORT = 28,
|
||||
ERR_ENCRYPTION_NOT_COMPLETED = 29,
|
||||
ERR_PARAMETER_INCORRECT = 30,
|
||||
ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG = 31,
|
||||
ERR_NONSYS_INPLACE_ENC_INCOMPLETE = 32,
|
||||
ERR_USER_ABORT = 33
|
||||
};
|
||||
|
||||
#endif // #ifndef TCDEFS_H
|
1722
src/Common/Tests.c
Normal file
1722
src/Common/Tests.c
Normal file
File diff suppressed because it is too large
Load Diff
30
src/Common/Tests.h
Normal file
30
src/Common/Tests.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern unsigned char ks_tmp[MAX_EXPANDED_KEY];
|
||||
|
||||
void CipherInit2(int cipher, void* key, void* ks, int key_len);
|
||||
BOOL test_hmac_sha512 (void);
|
||||
BOOL test_hmac_sha1 (void);
|
||||
BOOL test_hmac_ripemd160 (void);
|
||||
BOOL test_hmac_whirlpool (void);
|
||||
BOOL test_pkcs5 (void);
|
||||
BOOL TestSectorBufEncryption ();
|
||||
BOOL TestLegacySectorBufEncryption ();
|
||||
BOOL AutoTestAlgorithms (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
BIN
src/Common/Textual_logo_288dpi.bmp
Normal file
BIN
src/Common/Textual_logo_288dpi.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 162 KiB |
BIN
src/Common/Textual_logo_96dpi.bmp
Normal file
BIN
src/Common/Textual_logo_96dpi.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
src/Common/Textual_logo_background.bmp
Normal file
BIN
src/Common/Textual_logo_background.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 822 B |
BIN
src/Common/TrueCrypt.ico
Normal file
BIN
src/Common/TrueCrypt.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
src/Common/TrueCrypt_Volume.ico
Normal file
BIN
src/Common/TrueCrypt_Volume.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
src/Common/TrueCrypt_mounted.ico
Normal file
BIN
src/Common/TrueCrypt_mounted.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
1198
src/Common/Volumes.c
Normal file
1198
src/Common/Volumes.c
Normal file
File diff suppressed because it is too large
Load Diff
144
src/Common/Volumes.h
Normal file
144
src/Common/Volumes.h
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_Common_Volumes
|
||||
#define TC_HEADER_Common_Volumes
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Volume header version
|
||||
#define VOLUME_HEADER_VERSION 0x0005
|
||||
|
||||
// Version number written to volume header during format;
|
||||
// specifies the minimum program version required to mount the volume
|
||||
#define TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION 0x0700
|
||||
|
||||
// Version number written (encrypted) to the key data area of an encrypted system partition/drive;
|
||||
// specifies the minimum program version required to decrypt the system partition/drive
|
||||
#define TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION 0x0700
|
||||
|
||||
// Current volume format version (created by TrueCrypt 6.0+)
|
||||
#define TC_VOLUME_FORMAT_VERSION 2
|
||||
|
||||
// Version number of volume format created by TrueCrypt 1.0-5.1a
|
||||
#define TC_VOLUME_FORMAT_VERSION_PRE_6_0 1
|
||||
|
||||
// Volume header sizes
|
||||
#define TC_VOLUME_HEADER_SIZE (64 * 1024L)
|
||||
#define TC_VOLUME_HEADER_EFFECTIVE_SIZE 512
|
||||
#define TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE 512
|
||||
#define TC_VOLUME_HEADER_SIZE_LEGACY 512
|
||||
|
||||
#define TC_VOLUME_HEADER_GROUP_SIZE (2 * TC_VOLUME_HEADER_SIZE)
|
||||
#define TC_TOTAL_VOLUME_HEADERS_SIZE (4 * TC_VOLUME_HEADER_SIZE)
|
||||
|
||||
// Volume offsets
|
||||
#define TC_VOLUME_HEADER_OFFSET 0
|
||||
#define TC_HIDDEN_VOLUME_HEADER_OFFSET TC_VOLUME_HEADER_SIZE
|
||||
|
||||
// Sector sizes
|
||||
#define TC_MIN_VOLUME_SECTOR_SIZE 512
|
||||
#define TC_MAX_VOLUME_SECTOR_SIZE 4096
|
||||
#define TC_SECTOR_SIZE_FILE_HOSTED_VOLUME 512
|
||||
#define TC_SECTOR_SIZE_LEGACY 512
|
||||
|
||||
// Sector size which can be safely assumed to be supported by all BIOSes
|
||||
#define TC_SECTOR_SIZE_BIOS 512
|
||||
|
||||
#define TC_VOLUME_SMALL_SIZE_THRESHOLD (2 * BYTES_PER_MB) // Volume sizes below this threshold are considered small
|
||||
|
||||
#define TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE TC_MAX_VOLUME_SECTOR_SIZE // FAT file system fills the last sector with zeroes (marked as free; observed when quick format was performed using the OS format tool).
|
||||
#define TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH TC_VOLUME_HEADER_GROUP_SIZE // Reserved area size used for hidden volumes larger than TC_VOLUME_SMALL_SIZE_THRESHOLD
|
||||
|
||||
#define TC_VOLUME_DATA_OFFSET TC_VOLUME_HEADER_GROUP_SIZE
|
||||
|
||||
// The offset, in bytes, of the legacy hidden volume header position from the end of the file (a positive value).
|
||||
#define TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY (TC_VOLUME_HEADER_SIZE_LEGACY + TC_SECTOR_SIZE_LEGACY * 2)
|
||||
|
||||
#define TC_MAX_128BIT_BLOCK_VOLUME_SIZE BYTES_PER_PB // Security bound (128-bit block XTS mode)
|
||||
|
||||
// Filesystem size limits
|
||||
#define TC_MIN_FAT_FS_SIZE (9 * TC_MAX_VOLUME_SECTOR_SIZE)
|
||||
#define TC_MAX_FAT_SECTOR_COUNT 0x100000000ULL
|
||||
#define TC_MIN_NTFS_FS_SIZE (884 * TC_MAX_VOLUME_SECTOR_SIZE)
|
||||
#define TC_MAX_NTFS_FS_SIZE (128LL * BYTES_PER_TB) // NTFS volume can theoretically be up to 16 exabytes, but Windows XP and 2003 limit the size to that addressable with 32-bit clusters, i.e. max size is 128 TB (if 64-KB clusters are used).
|
||||
#define TC_MAX_FAT_CLUSTER_SIZE (256 * BYTES_PER_KB) // Windows XP/Vista may crash when writing to a filesystem using clusters larger than 256 KB
|
||||
|
||||
// Volume size limits
|
||||
#define TC_MIN_VOLUME_SIZE (TC_TOTAL_VOLUME_HEADERS_SIZE + TC_MIN_FAT_FS_SIZE)
|
||||
#define TC_MIN_VOLUME_SIZE_LEGACY (37 * TC_SECTOR_SIZE_LEGACY)
|
||||
#define TC_MAX_VOLUME_SIZE_GENERAL 0x7fffFFFFffffFFFFLL // Signed 64-bit integer file offset values
|
||||
#define TC_MAX_VOLUME_SIZE TC_MAX_128BIT_BLOCK_VOLUME_SIZE
|
||||
|
||||
#define TC_MIN_HIDDEN_VOLUME_SIZE (TC_MIN_FAT_FS_SIZE + TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE)
|
||||
|
||||
#define TC_MIN_HIDDEN_VOLUME_HOST_SIZE (TC_MIN_VOLUME_SIZE + TC_MIN_HIDDEN_VOLUME_SIZE + 2 * TC_MAX_VOLUME_SECTOR_SIZE)
|
||||
#define TC_MAX_HIDDEN_VOLUME_HOST_SIZE (TC_MAX_NTFS_FS_SIZE - TC_TOTAL_VOLUME_HEADERS_SIZE)
|
||||
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
# if TC_MAX_VOLUME_SIZE > TC_MAX_VOLUME_SIZE_GENERAL
|
||||
# error TC_MAX_VOLUME_SIZE > TC_MAX_VOLUME_SIZE_GENERAL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define HEADER_ENCRYPTED_DATA_SIZE (TC_VOLUME_HEADER_EFFECTIVE_SIZE - HEADER_ENCRYPTED_DATA_OFFSET)
|
||||
|
||||
// Volume header field offsets
|
||||
#define HEADER_SALT_OFFSET 0
|
||||
#define HEADER_ENCRYPTED_DATA_OFFSET PKCS5_SALT_SIZE
|
||||
#define HEADER_MASTER_KEYDATA_OFFSET 256
|
||||
|
||||
#define TC_HEADER_OFFSET_MAGIC 64
|
||||
#define TC_HEADER_OFFSET_VERSION 68
|
||||
#define TC_HEADER_OFFSET_REQUIRED_VERSION 70
|
||||
#define TC_HEADER_OFFSET_KEY_AREA_CRC 72
|
||||
#define TC_HEADER_OFFSET_VOLUME_CREATION_TIME 76
|
||||
#define TC_HEADER_OFFSET_MODIFICATION_TIME 84
|
||||
#define TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE 92
|
||||
#define TC_HEADER_OFFSET_VOLUME_SIZE 100
|
||||
#define TC_HEADER_OFFSET_ENCRYPTED_AREA_START 108
|
||||
#define TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH 116
|
||||
#define TC_HEADER_OFFSET_FLAGS 124
|
||||
#define TC_HEADER_OFFSET_SECTOR_SIZE 128
|
||||
#define TC_HEADER_OFFSET_HEADER_CRC 252
|
||||
|
||||
// Volume header flags
|
||||
#define TC_HEADER_FLAG_ENCRYPTED_SYSTEM 0x1
|
||||
#define TC_HEADER_FLAG_NONSYS_INPLACE_ENC 0x2 // The volume has been created using non-system in-place encryption
|
||||
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumeHeader
|
||||
|
||||
#include "Password.h"
|
||||
|
||||
extern BOOL ReadVolumeHeaderRecoveryMode;
|
||||
|
||||
uint16 GetHeaderField16 (byte *header, int offset);
|
||||
uint32 GetHeaderField32 (byte *header, int offset);
|
||||
UINT64_STRUCT GetHeaderField64 (byte *header, int offset);
|
||||
int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo);
|
||||
|
||||
#if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)
|
||||
int CreateVolumeHeaderInMemory (BOOL bBoot, char *encryptedHeader, int ea, int mode, Password *password, int pkcs5_prf, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode);
|
||||
BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead);
|
||||
BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header);
|
||||
int WriteRandomDataToReservedHeaderAreas (HANDLE dev, CRYPTO_INFO *cryptoInfo, uint64 dataAreaSize, BOOL bPrimaryOnly, BOOL bBackupOnly);
|
||||
#endif
|
||||
|
||||
#endif // !TC_HEADER_Volume_VolumeHeader
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_Common_Volumes
|
187
src/Common/Wipe.c
Normal file
187
src/Common/Wipe.c
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Wipe.h"
|
||||
|
||||
|
||||
static BOOL Wipe1PseudoRandom (int pass, byte *buffer, size_t size)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Fill buffer with wipe patterns defined in "National Industrial Security Program Operating Manual", US DoD 5220.22-M.
|
||||
// Return: FALSE = buffer must be filled with random data
|
||||
|
||||
static BOOL Wipe3Dod5220 (int pass, byte *buffer, size_t size)
|
||||
{
|
||||
byte wipeChar;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 1:
|
||||
wipeChar = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
wipeChar = 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (buffer, wipeChar, size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL Wipe7Dod5220 (int pass, byte randChars[TC_WIPE_RAND_CHAR_COUNT], byte *buffer, size_t size)
|
||||
{
|
||||
byte wipeChar;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 1:
|
||||
wipeChar = randChars[0];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
wipeChar = ~randChars[0];
|
||||
break;
|
||||
|
||||
case 4:
|
||||
wipeChar = randChars[1];
|
||||
break;
|
||||
|
||||
case 5:
|
||||
wipeChar = randChars[2];
|
||||
break;
|
||||
|
||||
case 6:
|
||||
wipeChar = ~randChars[2];
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (buffer, wipeChar, size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Fill the buffer with wipe patterns defined in the paper "Secure Deletion of Data from Magnetic and Solid-State Memory" by Peter Gutmann.
|
||||
// Return: FALSE = buffer must be filled with random data
|
||||
|
||||
static BOOL Wipe35Gutmann (int pass, byte *buffer, size_t size)
|
||||
{
|
||||
byte wipePat3[] = { 0x92, 0x49, 0x24 };
|
||||
int wipePat3Pos;
|
||||
size_t i;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 5:
|
||||
memset (buffer, 0x55, size);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
memset (buffer, 0xaa, size);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 26:
|
||||
case 29:
|
||||
wipePat3Pos = 0;
|
||||
goto wipe3;
|
||||
|
||||
case 8:
|
||||
case 27:
|
||||
case 30:
|
||||
wipePat3Pos = 1;
|
||||
goto wipe3;
|
||||
|
||||
case 9:
|
||||
case 28:
|
||||
case 31:
|
||||
wipePat3Pos = 2;
|
||||
goto wipe3;
|
||||
|
||||
wipe3:
|
||||
if (pass >= 29)
|
||||
{
|
||||
wipePat3[0] = ~wipePat3[0];
|
||||
wipePat3[1] = ~wipePat3[1];
|
||||
wipePat3[2] = ~wipePat3[2];
|
||||
}
|
||||
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
buffer[i] = wipePat3[wipePat3Pos++ % 3];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pass >= 10 && pass <= 25)
|
||||
memset (buffer, (pass - 10) * 0x11, size);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int GetWipePassCount (WipeAlgorithmId algorithm)
|
||||
{
|
||||
switch (algorithm)
|
||||
{
|
||||
case TC_WIPE_1_RAND:
|
||||
return 1;
|
||||
|
||||
case TC_WIPE_3_DOD_5220:
|
||||
return 3;
|
||||
|
||||
case TC_WIPE_7_DOD_5220:
|
||||
return 7;
|
||||
|
||||
case TC_WIPE_35_GUTMANN:
|
||||
return 35;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return 0; // Prevent compiler warnings
|
||||
}
|
||||
|
||||
|
||||
BOOL WipeBuffer (WipeAlgorithmId algorithm, byte randChars[TC_WIPE_RAND_CHAR_COUNT], int pass, byte *buffer, size_t size)
|
||||
{
|
||||
switch (algorithm)
|
||||
{
|
||||
case TC_WIPE_1_RAND:
|
||||
return Wipe1PseudoRandom (pass, buffer, size);
|
||||
|
||||
case TC_WIPE_3_DOD_5220:
|
||||
return Wipe3Dod5220 (pass, buffer, size);
|
||||
|
||||
case TC_WIPE_7_DOD_5220:
|
||||
return Wipe7Dod5220 (pass, randChars, buffer, size);
|
||||
|
||||
case TC_WIPE_35_GUTMANN:
|
||||
return Wipe35Gutmann (pass, buffer, size);
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return FALSE; // Prevent compiler warnings
|
||||
}
|
40
src/Common/Wipe.h
Normal file
40
src/Common/Wipe.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_Wipe
|
||||
#define TC_HEADER_Common_Wipe
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* WARNING: As these values are written to config files, if they or their meanings
|
||||
are changed, incompatiblity with other versions may arise (upgrade, downgrade, etc.).
|
||||
When adding a new constant, verify that the value is unique within this block. */
|
||||
TC_WIPE_NONE = 0,
|
||||
TC_WIPE_1_RAND = 100,
|
||||
TC_WIPE_3_DOD_5220 = 300,
|
||||
TC_WIPE_7_DOD_5220 = 700,
|
||||
TC_WIPE_35_GUTMANN = 3500
|
||||
|
||||
} WipeAlgorithmId;
|
||||
|
||||
#define TC_WIPE_RAND_CHAR_COUNT 3
|
||||
|
||||
int GetWipePassCount (WipeAlgorithmId algorithm);
|
||||
BOOL WipeBuffer (WipeAlgorithmId algorithm, byte randChars[TC_WIPE_RAND_CHAR_COUNT], int pass, byte *buffer, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_Common_Wipe
|
231
src/Common/Xml.c
Normal file
231
src/Common/Xml.c
Normal file
@ -0,0 +1,231 @@
|
||||
/*
|
||||
Copyright (c) 2005-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "Xml.h"
|
||||
|
||||
|
||||
static BOOL BeginsWith (char *string, char *subString)
|
||||
{
|
||||
while (*string++ == *subString++)
|
||||
{
|
||||
if (*subString == 0) return TRUE;
|
||||
if (*string == 0) return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
char *XmlNextNode (char *xmlNode)
|
||||
{
|
||||
char *t = xmlNode + 1;
|
||||
while ((t = strchr (t, '<')) != NULL)
|
||||
{
|
||||
if (t[1] != '/')
|
||||
return t;
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *XmlFindElement (char *xmlNode, char *nodeName)
|
||||
{
|
||||
char *t = xmlNode;
|
||||
size_t nameLen = strlen (nodeName);
|
||||
|
||||
do
|
||||
{
|
||||
if (BeginsWith (t + 1, nodeName)
|
||||
&& (t[nameLen + 1] == '>'
|
||||
|| t[nameLen + 1] == ' ')) return t;
|
||||
|
||||
} while (t = XmlNextNode (t));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *XmlFindElementByAttributeValue (char *xml, char *nodeName, char *attrName, char *attrValue)
|
||||
{
|
||||
char attr[2048];
|
||||
|
||||
while (xml = XmlFindElement (xml, nodeName))
|
||||
{
|
||||
XmlGetAttributeText (xml, attrName, attr, sizeof (attr));
|
||||
if (strcmp (attr, attrValue) == 0)
|
||||
return xml;
|
||||
|
||||
xml++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *XmlGetAttributeText (char *xmlNode, char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize)
|
||||
{
|
||||
char *t = xmlNode;
|
||||
char *e = xmlNode;
|
||||
int l = 0;
|
||||
|
||||
xmlAttrValue[0] = 0;
|
||||
if (t[0] != '<') return NULL;
|
||||
|
||||
e = strchr (e, '>');
|
||||
if (e == NULL) return NULL;
|
||||
|
||||
while ((t = strstr (t, xmlAttrName)) && t < e)
|
||||
{
|
||||
char *o = t + strlen (xmlAttrName);
|
||||
if (t[-1] == ' '
|
||||
&&
|
||||
(BeginsWith (o, "=\"")
|
||||
|| BeginsWith (o, "= \"")
|
||||
|| BeginsWith (o, " =\"")
|
||||
|| BeginsWith (o, " = \""))
|
||||
)
|
||||
break;
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
if (t == NULL || t > e) return NULL;
|
||||
|
||||
t = strchr (t, '"') + 1;
|
||||
e = strchr (t, '"');
|
||||
l = (int)(e - t);
|
||||
if (e == NULL || l > xmlAttrValueSize) return NULL;
|
||||
|
||||
memcpy (xmlAttrValue, t, l);
|
||||
xmlAttrValue[l] = 0;
|
||||
|
||||
return xmlAttrValue;
|
||||
}
|
||||
|
||||
|
||||
char *XmlGetNodeText (char *xmlNode, char *xmlText, int xmlTextSize)
|
||||
{
|
||||
char *t = xmlNode;
|
||||
char *e = xmlNode + 1;
|
||||
int l = 0, i = 0, j = 0;
|
||||
|
||||
xmlText[0] = 0;
|
||||
|
||||
if (t[0] != '<')
|
||||
return NULL;
|
||||
|
||||
t = strchr (t, '>') + 1;
|
||||
if (t == (char *)1) return NULL;
|
||||
|
||||
e = strchr (e, '<');
|
||||
if (e == NULL) return NULL;
|
||||
|
||||
l = (int)(e - t);
|
||||
if (e == NULL || l > xmlTextSize) return NULL;
|
||||
|
||||
while (i < l)
|
||||
{
|
||||
if (BeginsWith (&t[i], "<"))
|
||||
{
|
||||
xmlText[j++] = '<';
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (BeginsWith (&t[i], ">"))
|
||||
{
|
||||
xmlText[j++] = '>';
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (BeginsWith (&t[i], "&"))
|
||||
{
|
||||
xmlText[j++] = '&';
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
xmlText[j++] = t[i++];
|
||||
}
|
||||
xmlText[j] = 0;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
char *XmlQuoteText (const char *textSrc, char *textDst, int textDstMaxSize)
|
||||
{
|
||||
char *textDstLast = textDst + textDstMaxSize - 1;
|
||||
|
||||
if (textDstMaxSize == 0)
|
||||
return NULL;
|
||||
|
||||
while (*textSrc != 0 && textDst <= textDstLast)
|
||||
{
|
||||
char c = *textSrc++;
|
||||
switch (c)
|
||||
{
|
||||
case '&':
|
||||
if (textDst + 6 > textDstLast)
|
||||
return NULL;
|
||||
strcpy (textDst, "&");
|
||||
textDst += 5;
|
||||
continue;
|
||||
|
||||
case '>':
|
||||
if (textDst + 5 > textDstLast)
|
||||
return NULL;
|
||||
strcpy (textDst, ">");
|
||||
textDst += 4;
|
||||
continue;
|
||||
|
||||
case '<':
|
||||
if (textDst + 5 > textDstLast)
|
||||
return NULL;
|
||||
strcpy (textDst, "<");
|
||||
textDst += 4;
|
||||
continue;
|
||||
|
||||
default:
|
||||
*textDst++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (textDst > textDstLast)
|
||||
return NULL;
|
||||
|
||||
*textDst = 0;
|
||||
return textDst;
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteHeader (FILE *file)
|
||||
{
|
||||
return fputs ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TrueCrypt>", file);
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteHeaderW (FILE *file)
|
||||
{
|
||||
return fputws (L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TrueCrypt>", file);
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteFooter (FILE *file)
|
||||
{
|
||||
return fputs ("\n</TrueCrypt>", file);
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteFooterW (FILE *file)
|
||||
{
|
||||
return fputws (L"\n</TrueCrypt>", file);
|
||||
}
|
26
src/Common/Xml.h
Normal file
26
src/Common/Xml.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright (c) 2005-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *XmlNextNode (char *xmlNode);
|
||||
char *XmlFindElement (char *xmlNode, char *nodeName);
|
||||
char *XmlGetAttributeText (char *xmlNode, char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize);
|
||||
char *XmlGetNodeText (char *xmlNode, char *xmlText, int xmlTextSize);
|
||||
int XmlWriteHeader (FILE *file);
|
||||
int XmlWriteHeaderW (FILE *file);
|
||||
int XmlWriteFooter (FILE *file);
|
||||
int XmlWriteFooterW (FILE *file);
|
||||
char *XmlFindElementByAttributeValue (char *xml, char *nodeName, char *attrName, char *attrValue);
|
||||
char *XmlQuoteText (const char *textSrc, char *textDst, int textDstMaxSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
746
src/Common/Xts.c
Normal file
746
src/Common/Xts.c
Normal file
@ -0,0 +1,746 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
/* If native 64-bit data types are not available, define TC_NO_COMPILER_INT64.
|
||||
|
||||
For big-endian platforms define BYTE_ORDER as BIG_ENDIAN. */
|
||||
|
||||
|
||||
#ifdef TC_MINIMIZE_CODE_SIZE
|
||||
// Preboot/boot version
|
||||
# ifndef TC_NO_COMPILER_INT64
|
||||
# define TC_NO_COMPILER_INT64
|
||||
# endif
|
||||
# pragma optimize ("tl", on)
|
||||
#endif
|
||||
|
||||
#ifdef TC_NO_COMPILER_INT64
|
||||
# include <memory.h>
|
||||
#endif
|
||||
|
||||
#include "Xts.h"
|
||||
|
||||
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
|
||||
// length: number of bytes to encrypt; may be larger than one data unit and must be divisible by the cipher block size
|
||||
// ks: the primary key schedule
|
||||
// ks2: the secondary key schedule
|
||||
// startDataUnitNo: The sequential number of the data unit with which the buffer starts.
|
||||
// startCipherBlockNo: The sequential number of the first plaintext block to encrypt inside the data unit startDataUnitNo.
|
||||
// When encrypting the data unit from its first block, startCipherBlockNo is 0.
|
||||
// The startCipherBlockNo value applies only to the first data unit in the buffer; each successive
|
||||
// data unit is encrypted from its first block. The start of the buffer does not have to be
|
||||
// aligned with the start of a data unit. If it is aligned, startCipherBlockNo must be 0; if it
|
||||
// is not aligned, startCipherBlockNo must reflect the misalignment accordingly.
|
||||
void EncryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
if (CipherSupportsIntraDataUnitParallelization (cipher))
|
||||
EncryptBufferXTSParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
else
|
||||
EncryptBufferXTSNonParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms supporting intra-data-unit parallelization
|
||||
static void EncryptBufferXTSParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuesPtr64 = (unsigned __int64 *) whiteningValues;
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned __int64 *dataUnitBufPtr;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
unsigned __int64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
/* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the
|
||||
finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block
|
||||
number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented
|
||||
as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if
|
||||
the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is
|
||||
derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
|
||||
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
#else
|
||||
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
dataUnitBufPtr = bufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
// Encrypt all blocks in this data unit
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
// Pre-whitening
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
// Actual encryption
|
||||
EncipherBlocks (cipher, dataUnitBufPtr, ks, endBlock - startBlock);
|
||||
|
||||
bufPtr = dataUnitBufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
// Post-whitening
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
FAST_ERASE64 (whiteningValues, sizeof (whiteningValues));
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms not supporting intra-data-unit parallelization
|
||||
static void EncryptBufferXTSNonParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
/* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the
|
||||
finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block
|
||||
number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented
|
||||
as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if
|
||||
the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is
|
||||
derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate (and apply) subsequent whitening values for blocks in this data unit and
|
||||
// encrypt all relevant blocks in this data unit
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
// Pre-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr-- ^= *whiteningValuePtr64--;
|
||||
|
||||
// Actual encryption
|
||||
EncipherBlock (cipher, bufPtr, ks);
|
||||
|
||||
// Post-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr++ ^= *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
#else
|
||||
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
}
|
||||
|
||||
|
||||
// For descriptions of the input parameters, see EncryptBufferXTS().
|
||||
void DecryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
if (CipherSupportsIntraDataUnitParallelization (cipher))
|
||||
DecryptBufferXTSParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
else
|
||||
DecryptBufferXTSNonParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms supporting intra-data-unit parallelization
|
||||
static void DecryptBufferXTSParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuesPtr64 = (unsigned __int64 *) whiteningValues;
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned __int64 *dataUnitBufPtr;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
unsigned __int64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
|
||||
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
|
||||
#else
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
dataUnitBufPtr = bufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
// Decrypt blocks in this data unit
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
DecipherBlocks (cipher, dataUnitBufPtr, ks, endBlock - startBlock);
|
||||
|
||||
bufPtr = dataUnitBufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
FAST_ERASE64 (whiteningValues, sizeof (whiteningValues));
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms not supporting intra-data-unit parallelization
|
||||
static void DecryptBufferXTSNonParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate (and apply) subsequent whitening values for blocks in this data unit and
|
||||
// decrypt all relevant blocks in this data unit
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
// Post-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr-- ^= *whiteningValuePtr64--;
|
||||
|
||||
// Actual decryption
|
||||
DecipherBlock (cipher, bufPtr, ks);
|
||||
|
||||
// Pre-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr++ ^= *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
|
||||
#else
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
}
|
||||
|
||||
|
||||
#else // TC_NO_COMPILER_INT64
|
||||
|
||||
/* ---- The following code is to be used only when native 64-bit data types are not available. ---- */
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#error The TC_NO_COMPILER_INT64 version of the XTS code is not compatible with big-endian platforms
|
||||
#endif
|
||||
|
||||
|
||||
// Converts a 64-bit unsigned integer (passed as two 32-bit integers for compatibility with non-64-bit
|
||||
// environments/platforms) into a little-endian 16-byte array.
|
||||
static void Uint64ToLE16ByteArray (unsigned __int8 *byteBuf, unsigned __int32 highInt32, unsigned __int32 lowInt32)
|
||||
{
|
||||
unsigned __int32 *bufPtr32 = (unsigned __int32 *) byteBuf;
|
||||
|
||||
*bufPtr32++ = lowInt32;
|
||||
*bufPtr32++ = highInt32;
|
||||
|
||||
// We're converting a 64-bit number into a little-endian 16-byte array so we can zero the last 8 bytes
|
||||
*bufPtr32++ = 0;
|
||||
*bufPtr32 = 0;
|
||||
}
|
||||
|
||||
|
||||
// Encrypts or decrypts all blocks in the buffer in XTS mode. For descriptions of the input parameters,
|
||||
// see the 64-bit version of EncryptBufferXTS().
|
||||
static void EncryptDecryptBufferXTS32 (const unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startBlock,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher,
|
||||
BOOL decryption)
|
||||
{
|
||||
TC_LARGEST_COMPILER_UINT blockCount;
|
||||
UINT64_STRUCT dataUnitNo;
|
||||
unsigned int block;
|
||||
unsigned int endBlock;
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int32 *bufPtr32 = (unsigned __int32 *) buffer;
|
||||
unsigned __int32 *whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int32 *const finalDwordWhiteningValuePtr = whiteningValuePtr32 + sizeof (whiteningValue) / sizeof (*whiteningValuePtr32) - 1;
|
||||
|
||||
// Store the 64-bit data unit number in a way compatible with non-64-bit environments/platforms
|
||||
dataUnitNo.HighPart = startDataUnitNo->HighPart;
|
||||
dataUnitNo.LowPart = startDataUnitNo->LowPart;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// (Passed as two 32-bit integers for compatibility with non-64-bit environments/platforms.)
|
||||
Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart);
|
||||
|
||||
// Generate whitening values for all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
memcpy (whiteningValue, byteBufUnitNo, BYTES_PER_XTS_BLOCK);
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate (and apply) subsequent whitening values for blocks in this data unit and
|
||||
// encrypt/decrypt all relevant blocks in this data unit
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
|
||||
|
||||
// Whitening
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32 ^= *whiteningValuePtr32;
|
||||
|
||||
bufPtr32 -= BYTES_PER_XTS_BLOCK / sizeof (*bufPtr32) - 1;
|
||||
|
||||
// Actual encryption/decryption
|
||||
if (decryption)
|
||||
DecipherBlock (cipher, bufPtr32, ks);
|
||||
else
|
||||
EncipherBlock (cipher, bufPtr32, ks);
|
||||
|
||||
whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
|
||||
|
||||
// Whitening
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32;
|
||||
}
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
finalCarry = 0;
|
||||
|
||||
for (whiteningValuePtr32 = finalDwordWhiteningValuePtr;
|
||||
whiteningValuePtr32 >= (unsigned __int32 *) whiteningValue;
|
||||
whiteningValuePtr32--)
|
||||
{
|
||||
if (*whiteningValuePtr32 & 0x80000000) // If the following shift results in a carry
|
||||
{
|
||||
if (whiteningValuePtr32 != finalDwordWhiteningValuePtr) // If not processing the highest double word
|
||||
{
|
||||
// A regular carry
|
||||
*(whiteningValuePtr32 + 1) |= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The highest byte shift will result in a carry
|
||||
finalCarry = 135;
|
||||
}
|
||||
}
|
||||
|
||||
*whiteningValuePtr32 <<= 1;
|
||||
}
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
|
||||
// Increase the data unit number by one
|
||||
if (!++dataUnitNo.LowPart)
|
||||
{
|
||||
dataUnitNo.HighPart++;
|
||||
}
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
}
|
||||
|
||||
|
||||
// For descriptions of the input parameters, see the 64-bit version of EncryptBufferXTS() above.
|
||||
void EncryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
// Encrypt all plaintext blocks in the buffer
|
||||
EncryptDecryptBufferXTS32 (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher, FALSE);
|
||||
}
|
||||
|
||||
|
||||
// For descriptions of the input parameters, see the 64-bit version of EncryptBufferXTS().
|
||||
void DecryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
// Decrypt all ciphertext blocks in the buffer
|
||||
EncryptDecryptBufferXTS32 (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher, TRUE);
|
||||
}
|
||||
|
||||
#endif // TC_NO_COMPILER_INT64
|
80
src/Common/Xts.h
Normal file
80
src/Common/Xts.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef XTS_H
|
||||
#define XTS_H
|
||||
|
||||
// Header files (optional)
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Common/Endian.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Macros
|
||||
|
||||
#ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#ifndef BIG_ENDIAN
|
||||
# define BIG_ENDIAN 2
|
||||
#endif
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifndef LE64
|
||||
# if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define LE64(x) (x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Custom data types
|
||||
|
||||
#ifndef TC_LARGEST_COMPILER_UINT
|
||||
# ifdef TC_NO_COMPILER_INT64
|
||||
typedef unsigned __int32 TC_LARGEST_COMPILER_UINT;
|
||||
# else
|
||||
typedef unsigned __int64 TC_LARGEST_COMPILER_UINT;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef TCDEFS_H
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned __int32 LowPart;
|
||||
unsigned __int32 HighPart;
|
||||
};
|
||||
# ifndef TC_NO_COMPILER_INT64
|
||||
unsigned __int64 Value;
|
||||
# endif
|
||||
|
||||
} UINT64_STRUCT;
|
||||
#endif
|
||||
|
||||
// Public function prototypes
|
||||
|
||||
void EncryptBufferXTS (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void EncryptBufferXTSParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void EncryptBufferXTSNonParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
void DecryptBufferXTS (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void DecryptBufferXTSParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void DecryptBufferXTSNonParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #ifndef XTS_H
|
215
src/Crypto/Aes.h
Normal file
215
src/Crypto/Aes.h
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2007, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software is allowed (with or without
|
||||
changes) provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the definitions required to use AES in C. See aesopt.h
|
||||
for optimisation details.
|
||||
*/
|
||||
|
||||
/* Adapted for TrueCrypt */
|
||||
|
||||
#ifndef _AES_H
|
||||
#define _AES_H
|
||||
|
||||
#include "Common/Tcdefs.h"
|
||||
|
||||
#ifndef EXIT_SUCCESS
|
||||
#define EXIT_SUCCESS 0
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
#define INT_RETURN int
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// #define AES_128 /* define if AES with 128 bit keys is needed */
|
||||
// #define AES_192 /* define if AES with 192 bit keys is needed */
|
||||
#define AES_256 /* define if AES with 256 bit keys is needed */
|
||||
// #define AES_VAR /* define if a variable key size is needed */
|
||||
// #define AES_MODES /* define if support is needed for modes */
|
||||
|
||||
/* The following must also be set in assembler files if being used */
|
||||
|
||||
#define AES_ENCRYPT /* if support for encryption is needed */
|
||||
#define AES_DECRYPT /* if support for decryption is needed */
|
||||
#define AES_ERR_CHK /* for parameter checks & error return codes */
|
||||
#define AES_REV_DKS /* define to reverse decryption key schedule */
|
||||
|
||||
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
|
||||
#define N_COLS 4 /* the number of columns in the state */
|
||||
|
||||
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
|
||||
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
|
||||
/* or 44, 52 or 60 32-bit words. */
|
||||
|
||||
#if defined( AES_VAR ) || defined( AES_256 )
|
||||
#define KS_LENGTH 60
|
||||
#elif defined( AES_192 )
|
||||
#define KS_LENGTH 52
|
||||
#else
|
||||
#define KS_LENGTH 44
|
||||
#endif
|
||||
|
||||
#if defined( AES_ERR_CHK )
|
||||
#define AES_RETURN INT_RETURN
|
||||
#else
|
||||
#define AES_RETURN VOID_RETURN
|
||||
#endif
|
||||
|
||||
/* the character array 'inf' in the following structures is used */
|
||||
/* to hold AES context information. This AES code uses cx->inf.b[0] */
|
||||
/* to hold the number of rounds multiplied by 16. The other three */
|
||||
/* elements can be used by code that implements additional modes */
|
||||
|
||||
typedef union
|
||||
{ uint_32t l;
|
||||
uint_8t b[4];
|
||||
} aes_inf;
|
||||
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_encrypt_ctx;
|
||||
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_decrypt_ctx;
|
||||
|
||||
/* This routine must be called before first use if non-static */
|
||||
/* tables are being used */
|
||||
|
||||
AES_RETURN aes_init(void);
|
||||
|
||||
/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
|
||||
/* those in the range 128 <= key_len <= 256 are given in bits */
|
||||
|
||||
#if defined( AES_ENCRYPT )
|
||||
|
||||
#if defined(AES_128) || defined(AES_VAR)
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined(AES_VAR)
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined(AES_VAR)
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined(AES_VAR)
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DECRYPT )
|
||||
|
||||
#if defined(AES_128) || defined(AES_VAR)
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined(AES_VAR)
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined(AES_VAR)
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined(AES_VAR)
|
||||
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_MODES)
|
||||
|
||||
/* Multiple calls to the following subroutines for multiple block */
|
||||
/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
|
||||
/* long messages incremantally provided that the context AND the iv */
|
||||
/* are preserved between all such calls. For the ECB and CBC modes */
|
||||
/* each individual call within a series of incremental calls must */
|
||||
/* process only full blocks (i.e. len must be a multiple of 16) but */
|
||||
/* the CFB, OFB and CTR mode calls can handle multiple incremental */
|
||||
/* calls of any length. Each mode is reset when a new AES key is */
|
||||
/* set but ECB and CBC operations can be reset without setting a */
|
||||
/* new key by setting a new IV value. To reset CFB, OFB and CTR */
|
||||
/* without setting the key, aes_mode_reset() must be called and the */
|
||||
/* IV must be set. NOTE: All these calls update the IV on exit so */
|
||||
/* this has to be reset if a new operation with the same IV as the */
|
||||
/* previous one is required (or decryption follows encryption with */
|
||||
/* the same IV array). */
|
||||
|
||||
AES_RETURN aes_test_alignment_detection(unsigned int n);
|
||||
|
||||
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
#define aes_ofb_encrypt aes_ofb_crypt
|
||||
#define aes_ofb_decrypt aes_ofb_crypt
|
||||
|
||||
AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
typedef void cbuf_inc(unsigned char *cbuf);
|
||||
|
||||
#define aes_ctr_encrypt aes_ctr_crypt
|
||||
#define aes_ctr_decrypt aes_ctr_crypt
|
||||
|
||||
AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
953
src/Crypto/AesSmall.c
Normal file
953
src/Crypto/AesSmall.c
Normal file
@ -0,0 +1,953 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software is allowed (with or without
|
||||
changes) provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue 09/09/2006
|
||||
|
||||
This is an AES implementation that uses only 8-bit byte operations on the
|
||||
cipher state (there are options to use 32-bit types if available).
|
||||
|
||||
The combination of mix columns and byte substitution used here is based on
|
||||
that developed by Karl Malbrain. His contribution is acknowledged.
|
||||
*/
|
||||
|
||||
/* Adapted for TrueCrypt:
|
||||
- Macro-generated tables were replaced with static data to enable compiling
|
||||
with MSVC++ 1.5 which runs out of resources when expanding large macros.
|
||||
*/
|
||||
|
||||
#pragma optimize ("t", on)
|
||||
|
||||
/* define if you have a fast memcpy function on your system */
|
||||
#if 1
|
||||
# define HAVE_MEMCPY
|
||||
# include <string.h>
|
||||
# if defined( _MSC_VER )
|
||||
# ifndef DEBUG
|
||||
# pragma intrinsic( memcpy )
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* define if you have fast 32-bit types on your system */
|
||||
#if 1
|
||||
# define HAVE_UINT_32T
|
||||
#endif
|
||||
|
||||
/* alternative versions (test for performance on your system) */
|
||||
#if 0
|
||||
# define VERSION_1
|
||||
#endif
|
||||
|
||||
#include "AesSmall.h"
|
||||
|
||||
#define WPOLY 0x011b
|
||||
#define DPOLY 0x008d
|
||||
#define f1(x) (x)
|
||||
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
|
||||
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
|
||||
#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
|
||||
^ (((x>>5) & 4) * WPOLY))
|
||||
#define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
|
||||
|
||||
#define f3(x) (f2(x) ^ x)
|
||||
#define f9(x) (f8(x) ^ x)
|
||||
#define fb(x) (f8(x) ^ f2(x) ^ x)
|
||||
#define fd(x) (f8(x) ^ f4(x) ^ x)
|
||||
#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
|
||||
|
||||
static const uint_8t s_box[256] = {
|
||||
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,
|
||||
0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
|
||||
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,
|
||||
0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
|
||||
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,
|
||||
0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
|
||||
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,
|
||||
0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
|
||||
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,
|
||||
0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
|
||||
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,
|
||||
0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
|
||||
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,
|
||||
0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
|
||||
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,
|
||||
0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
|
||||
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,
|
||||
0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
|
||||
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,
|
||||
0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
|
||||
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,
|
||||
0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
|
||||
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,
|
||||
0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
|
||||
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,
|
||||
0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
|
||||
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,
|
||||
0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
|
||||
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,
|
||||
0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
|
||||
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,
|
||||
0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
|
||||
};
|
||||
|
||||
static const uint_8t inv_s_box[256] = {
|
||||
0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
|
||||
0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
|
||||
0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
|
||||
0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
|
||||
0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
|
||||
0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
|
||||
0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
|
||||
0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
|
||||
0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
|
||||
0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
|
||||
0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
|
||||
0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
|
||||
0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
|
||||
0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
|
||||
0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
|
||||
0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
|
||||
0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
|
||||
0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
|
||||
0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
|
||||
0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
|
||||
0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
|
||||
0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
|
||||
0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
|
||||
0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
|
||||
0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
|
||||
0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
|
||||
0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
|
||||
0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
|
||||
0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
|
||||
0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
|
||||
0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
|
||||
0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
|
||||
};
|
||||
|
||||
static const uint_8t gfm2_s_box[256] = {
|
||||
0xc6,0xf8,0xee,0xf6,0xff,0xd6,0xde,0x91,
|
||||
0x60,0x02,0xce,0x56,0xe7,0xb5,0x4d,0xec,
|
||||
0x8f,0x1f,0x89,0xfa,0xef,0xb2,0x8e,0xfb,
|
||||
0x41,0xb3,0x5f,0x45,0x23,0x53,0xe4,0x9b,
|
||||
0x75,0xe1,0x3d,0x4c,0x6c,0x7e,0xf5,0x83,
|
||||
0x68,0x51,0xd1,0xf9,0xe2,0xab,0x62,0x2a,
|
||||
0x08,0x95,0x46,0x9d,0x30,0x37,0x0a,0x2f,
|
||||
0x0e,0x24,0x1b,0xdf,0xcd,0x4e,0x7f,0xea,
|
||||
0x12,0x1d,0x58,0x34,0x36,0xdc,0xb4,0x5b,
|
||||
0xa4,0x76,0xb7,0x7d,0x52,0xdd,0x5e,0x13,
|
||||
0xa6,0xb9,0x00,0xc1,0x40,0xe3,0x79,0xb6,
|
||||
0xd4,0x8d,0x67,0x72,0x94,0x98,0xb0,0x85,
|
||||
0xbb,0xc5,0x4f,0xed,0x86,0x9a,0x66,0x11,
|
||||
0x8a,0xe9,0x04,0xfe,0xa0,0x78,0x25,0x4b,
|
||||
0xa2,0x5d,0x80,0x05,0x3f,0x21,0x70,0xf1,
|
||||
0x63,0x77,0xaf,0x42,0x20,0xe5,0xfd,0xbf,
|
||||
0x81,0x18,0x26,0xc3,0xbe,0x35,0x88,0x2e,
|
||||
0x93,0x55,0xfc,0x7a,0xc8,0xba,0x32,0xe6,
|
||||
0xc0,0x19,0x9e,0xa3,0x44,0x54,0x3b,0x0b,
|
||||
0x8c,0xc7,0x6b,0x28,0xa7,0xbc,0x16,0xad,
|
||||
0xdb,0x64,0x74,0x14,0x92,0x0c,0x48,0xb8,
|
||||
0x9f,0xbd,0x43,0xc4,0x39,0x31,0xd3,0xf2,
|
||||
0xd5,0x8b,0x6e,0xda,0x01,0xb1,0x9c,0x49,
|
||||
0xd8,0xac,0xf3,0xcf,0xca,0xf4,0x47,0x10,
|
||||
0x6f,0xf0,0x4a,0x5c,0x38,0x57,0x73,0x97,
|
||||
0xcb,0xa1,0xe8,0x3e,0x96,0x61,0x0d,0x0f,
|
||||
0xe0,0x7c,0x71,0xcc,0x90,0x06,0xf7,0x1c,
|
||||
0xc2,0x6a,0xae,0x69,0x17,0x99,0x3a,0x27,
|
||||
0xd9,0xeb,0x2b,0x22,0xd2,0xa9,0x07,0x33,
|
||||
0x2d,0x3c,0x15,0xc9,0x87,0xaa,0x50,0xa5,
|
||||
0x03,0x59,0x09,0x1a,0x65,0xd7,0x84,0xd0,
|
||||
0x82,0x29,0x5a,0x1e,0x7b,0xa8,0x6d,0x2c
|
||||
};
|
||||
|
||||
static const uint_8t gfm3_s_box[256] = {
|
||||
0xa5,0x84,0x99,0x8d,0x0d,0xbd,0xb1,0x54,
|
||||
0x50,0x03,0xa9,0x7d,0x19,0x62,0xe6,0x9a,
|
||||
0x45,0x9d,0x40,0x87,0x15,0xeb,0xc9,0x0b,
|
||||
0xec,0x67,0xfd,0xea,0xbf,0xf7,0x96,0x5b,
|
||||
0xc2,0x1c,0xae,0x6a,0x5a,0x41,0x02,0x4f,
|
||||
0x5c,0xf4,0x34,0x08,0x93,0x73,0x53,0x3f,
|
||||
0x0c,0x52,0x65,0x5e,0x28,0xa1,0x0f,0xb5,
|
||||
0x09,0x36,0x9b,0x3d,0x26,0x69,0xcd,0x9f,
|
||||
0x1b,0x9e,0x74,0x2e,0x2d,0xb2,0xee,0xfb,
|
||||
0xf6,0x4d,0x61,0xce,0x7b,0x3e,0x71,0x97,
|
||||
0xf5,0x68,0x00,0x2c,0x60,0x1f,0xc8,0xed,
|
||||
0xbe,0x46,0xd9,0x4b,0xde,0xd4,0xe8,0x4a,
|
||||
0x6b,0x2a,0xe5,0x16,0xc5,0xd7,0x55,0x94,
|
||||
0xcf,0x10,0x06,0x81,0xf0,0x44,0xba,0xe3,
|
||||
0xf3,0xfe,0xc0,0x8a,0xad,0xbc,0x48,0x04,
|
||||
0xdf,0xc1,0x75,0x63,0x30,0x1a,0x0e,0x6d,
|
||||
0x4c,0x14,0x35,0x2f,0xe1,0xa2,0xcc,0x39,
|
||||
0x57,0xf2,0x82,0x47,0xac,0xe7,0x2b,0x95,
|
||||
0xa0,0x98,0xd1,0x7f,0x66,0x7e,0xab,0x83,
|
||||
0xca,0x29,0xd3,0x3c,0x79,0xe2,0x1d,0x76,
|
||||
0x3b,0x56,0x4e,0x1e,0xdb,0x0a,0x6c,0xe4,
|
||||
0x5d,0x6e,0xef,0xa6,0xa8,0xa4,0x37,0x8b,
|
||||
0x32,0x43,0x59,0xb7,0x8c,0x64,0xd2,0xe0,
|
||||
0xb4,0xfa,0x07,0x25,0xaf,0x8e,0xe9,0x18,
|
||||
0xd5,0x88,0x6f,0x72,0x24,0xf1,0xc7,0x51,
|
||||
0x23,0x7c,0x9c,0x21,0xdd,0xdc,0x86,0x85,
|
||||
0x90,0x42,0xc4,0xaa,0xd8,0x05,0x01,0x12,
|
||||
0xa3,0x5f,0xf9,0xd0,0x91,0x58,0x27,0xb9,
|
||||
0x38,0x13,0xb3,0x33,0xbb,0x70,0x89,0xa7,
|
||||
0xb6,0x22,0x92,0x20,0x49,0xff,0x78,0x7a,
|
||||
0x8f,0xf8,0x80,0x17,0xda,0x31,0xc6,0xb8,
|
||||
0xc3,0xb0,0x77,0x11,0xcb,0xfc,0xd6,0x3a
|
||||
};
|
||||
|
||||
static const uint_8t gfmul_9[256] = {
|
||||
0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,
|
||||
0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77,
|
||||
0x90,0x99,0x82,0x8b,0xb4,0xbd,0xa6,0xaf,
|
||||
0xd8,0xd1,0xca,0xc3,0xfc,0xf5,0xee,0xe7,
|
||||
0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,
|
||||
0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c,
|
||||
0xab,0xa2,0xb9,0xb0,0x8f,0x86,0x9d,0x94,
|
||||
0xe3,0xea,0xf1,0xf8,0xc7,0xce,0xd5,0xdc,
|
||||
0x76,0x7f,0x64,0x6d,0x52,0x5b,0x40,0x49,
|
||||
0x3e,0x37,0x2c,0x25,0x1a,0x13,0x08,0x01,
|
||||
0xe6,0xef,0xf4,0xfd,0xc2,0xcb,0xd0,0xd9,
|
||||
0xae,0xa7,0xbc,0xb5,0x8a,0x83,0x98,0x91,
|
||||
0x4d,0x44,0x5f,0x56,0x69,0x60,0x7b,0x72,
|
||||
0x05,0x0c,0x17,0x1e,0x21,0x28,0x33,0x3a,
|
||||
0xdd,0xd4,0xcf,0xc6,0xf9,0xf0,0xeb,0xe2,
|
||||
0x95,0x9c,0x87,0x8e,0xb1,0xb8,0xa3,0xaa,
|
||||
0xec,0xe5,0xfe,0xf7,0xc8,0xc1,0xda,0xd3,
|
||||
0xa4,0xad,0xb6,0xbf,0x80,0x89,0x92,0x9b,
|
||||
0x7c,0x75,0x6e,0x67,0x58,0x51,0x4a,0x43,
|
||||
0x34,0x3d,0x26,0x2f,0x10,0x19,0x02,0x0b,
|
||||
0xd7,0xde,0xc5,0xcc,0xf3,0xfa,0xe1,0xe8,
|
||||
0x9f,0x96,0x8d,0x84,0xbb,0xb2,0xa9,0xa0,
|
||||
0x47,0x4e,0x55,0x5c,0x63,0x6a,0x71,0x78,
|
||||
0x0f,0x06,0x1d,0x14,0x2b,0x22,0x39,0x30,
|
||||
0x9a,0x93,0x88,0x81,0xbe,0xb7,0xac,0xa5,
|
||||
0xd2,0xdb,0xc0,0xc9,0xf6,0xff,0xe4,0xed,
|
||||
0x0a,0x03,0x18,0x11,0x2e,0x27,0x3c,0x35,
|
||||
0x42,0x4b,0x50,0x59,0x66,0x6f,0x74,0x7d,
|
||||
0xa1,0xa8,0xb3,0xba,0x85,0x8c,0x97,0x9e,
|
||||
0xe9,0xe0,0xfb,0xf2,0xcd,0xc4,0xdf,0xd6,
|
||||
0x31,0x38,0x23,0x2a,0x15,0x1c,0x07,0x0e,
|
||||
0x79,0x70,0x6b,0x62,0x5d,0x54,0x4f,0x46
|
||||
};
|
||||
|
||||
static const uint_8t gfmul_b[256] = {
|
||||
0x00,0x0b,0x16,0x1d,0x2c,0x27,0x3a,0x31,
|
||||
0x58,0x53,0x4e,0x45,0x74,0x7f,0x62,0x69,
|
||||
0xb0,0xbb,0xa6,0xad,0x9c,0x97,0x8a,0x81,
|
||||
0xe8,0xe3,0xfe,0xf5,0xc4,0xcf,0xd2,0xd9,
|
||||
0x7b,0x70,0x6d,0x66,0x57,0x5c,0x41,0x4a,
|
||||
0x23,0x28,0x35,0x3e,0x0f,0x04,0x19,0x12,
|
||||
0xcb,0xc0,0xdd,0xd6,0xe7,0xec,0xf1,0xfa,
|
||||
0x93,0x98,0x85,0x8e,0xbf,0xb4,0xa9,0xa2,
|
||||
0xf6,0xfd,0xe0,0xeb,0xda,0xd1,0xcc,0xc7,
|
||||
0xae,0xa5,0xb8,0xb3,0x82,0x89,0x94,0x9f,
|
||||
0x46,0x4d,0x50,0x5b,0x6a,0x61,0x7c,0x77,
|
||||
0x1e,0x15,0x08,0x03,0x32,0x39,0x24,0x2f,
|
||||
0x8d,0x86,0x9b,0x90,0xa1,0xaa,0xb7,0xbc,
|
||||
0xd5,0xde,0xc3,0xc8,0xf9,0xf2,0xef,0xe4,
|
||||
0x3d,0x36,0x2b,0x20,0x11,0x1a,0x07,0x0c,
|
||||
0x65,0x6e,0x73,0x78,0x49,0x42,0x5f,0x54,
|
||||
0xf7,0xfc,0xe1,0xea,0xdb,0xd0,0xcd,0xc6,
|
||||
0xaf,0xa4,0xb9,0xb2,0x83,0x88,0x95,0x9e,
|
||||
0x47,0x4c,0x51,0x5a,0x6b,0x60,0x7d,0x76,
|
||||
0x1f,0x14,0x09,0x02,0x33,0x38,0x25,0x2e,
|
||||
0x8c,0x87,0x9a,0x91,0xa0,0xab,0xb6,0xbd,
|
||||
0xd4,0xdf,0xc2,0xc9,0xf8,0xf3,0xee,0xe5,
|
||||
0x3c,0x37,0x2a,0x21,0x10,0x1b,0x06,0x0d,
|
||||
0x64,0x6f,0x72,0x79,0x48,0x43,0x5e,0x55,
|
||||
0x01,0x0a,0x17,0x1c,0x2d,0x26,0x3b,0x30,
|
||||
0x59,0x52,0x4f,0x44,0x75,0x7e,0x63,0x68,
|
||||
0xb1,0xba,0xa7,0xac,0x9d,0x96,0x8b,0x80,
|
||||
0xe9,0xe2,0xff,0xf4,0xc5,0xce,0xd3,0xd8,
|
||||
0x7a,0x71,0x6c,0x67,0x56,0x5d,0x40,0x4b,
|
||||
0x22,0x29,0x34,0x3f,0x0e,0x05,0x18,0x13,
|
||||
0xca,0xc1,0xdc,0xd7,0xe6,0xed,0xf0,0xfb,
|
||||
0x92,0x99,0x84,0x8f,0xbe,0xb5,0xa8,0xa3
|
||||
};
|
||||
|
||||
static const uint_8t gfmul_d[256] = {
|
||||
0x00,0x0d,0x1a,0x17,0x34,0x39,0x2e,0x23,
|
||||
0x68,0x65,0x72,0x7f,0x5c,0x51,0x46,0x4b,
|
||||
0xd0,0xdd,0xca,0xc7,0xe4,0xe9,0xfe,0xf3,
|
||||
0xb8,0xb5,0xa2,0xaf,0x8c,0x81,0x96,0x9b,
|
||||
0xbb,0xb6,0xa1,0xac,0x8f,0x82,0x95,0x98,
|
||||
0xd3,0xde,0xc9,0xc4,0xe7,0xea,0xfd,0xf0,
|
||||
0x6b,0x66,0x71,0x7c,0x5f,0x52,0x45,0x48,
|
||||
0x03,0x0e,0x19,0x14,0x37,0x3a,0x2d,0x20,
|
||||
0x6d,0x60,0x77,0x7a,0x59,0x54,0x43,0x4e,
|
||||
0x05,0x08,0x1f,0x12,0x31,0x3c,0x2b,0x26,
|
||||
0xbd,0xb0,0xa7,0xaa,0x89,0x84,0x93,0x9e,
|
||||
0xd5,0xd8,0xcf,0xc2,0xe1,0xec,0xfb,0xf6,
|
||||
0xd6,0xdb,0xcc,0xc1,0xe2,0xef,0xf8,0xf5,
|
||||
0xbe,0xb3,0xa4,0xa9,0x8a,0x87,0x90,0x9d,
|
||||
0x06,0x0b,0x1c,0x11,0x32,0x3f,0x28,0x25,
|
||||
0x6e,0x63,0x74,0x79,0x5a,0x57,0x40,0x4d,
|
||||
0xda,0xd7,0xc0,0xcd,0xee,0xe3,0xf4,0xf9,
|
||||
0xb2,0xbf,0xa8,0xa5,0x86,0x8b,0x9c,0x91,
|
||||
0x0a,0x07,0x10,0x1d,0x3e,0x33,0x24,0x29,
|
||||
0x62,0x6f,0x78,0x75,0x56,0x5b,0x4c,0x41,
|
||||
0x61,0x6c,0x7b,0x76,0x55,0x58,0x4f,0x42,
|
||||
0x09,0x04,0x13,0x1e,0x3d,0x30,0x27,0x2a,
|
||||
0xb1,0xbc,0xab,0xa6,0x85,0x88,0x9f,0x92,
|
||||
0xd9,0xd4,0xc3,0xce,0xed,0xe0,0xf7,0xfa,
|
||||
0xb7,0xba,0xad,0xa0,0x83,0x8e,0x99,0x94,
|
||||
0xdf,0xd2,0xc5,0xc8,0xeb,0xe6,0xf1,0xfc,
|
||||
0x67,0x6a,0x7d,0x70,0x53,0x5e,0x49,0x44,
|
||||
0x0f,0x02,0x15,0x18,0x3b,0x36,0x21,0x2c,
|
||||
0x0c,0x01,0x16,0x1b,0x38,0x35,0x22,0x2f,
|
||||
0x64,0x69,0x7e,0x73,0x50,0x5d,0x4a,0x47,
|
||||
0xdc,0xd1,0xc6,0xcb,0xe8,0xe5,0xf2,0xff,
|
||||
0xb4,0xb9,0xae,0xa3,0x80,0x8d,0x9a,0x97
|
||||
};
|
||||
|
||||
static const uint_8t gfmul_e[256] = {
|
||||
0x00,0x0e,0x1c,0x12,0x38,0x36,0x24,0x2a,
|
||||
0x70,0x7e,0x6c,0x62,0x48,0x46,0x54,0x5a,
|
||||
0xe0,0xee,0xfc,0xf2,0xd8,0xd6,0xc4,0xca,
|
||||
0x90,0x9e,0x8c,0x82,0xa8,0xa6,0xb4,0xba,
|
||||
0xdb,0xd5,0xc7,0xc9,0xe3,0xed,0xff,0xf1,
|
||||
0xab,0xa5,0xb7,0xb9,0x93,0x9d,0x8f,0x81,
|
||||
0x3b,0x35,0x27,0x29,0x03,0x0d,0x1f,0x11,
|
||||
0x4b,0x45,0x57,0x59,0x73,0x7d,0x6f,0x61,
|
||||
0xad,0xa3,0xb1,0xbf,0x95,0x9b,0x89,0x87,
|
||||
0xdd,0xd3,0xc1,0xcf,0xe5,0xeb,0xf9,0xf7,
|
||||
0x4d,0x43,0x51,0x5f,0x75,0x7b,0x69,0x67,
|
||||
0x3d,0x33,0x21,0x2f,0x05,0x0b,0x19,0x17,
|
||||
0x76,0x78,0x6a,0x64,0x4e,0x40,0x52,0x5c,
|
||||
0x06,0x08,0x1a,0x14,0x3e,0x30,0x22,0x2c,
|
||||
0x96,0x98,0x8a,0x84,0xae,0xa0,0xb2,0xbc,
|
||||
0xe6,0xe8,0xfa,0xf4,0xde,0xd0,0xc2,0xcc,
|
||||
0x41,0x4f,0x5d,0x53,0x79,0x77,0x65,0x6b,
|
||||
0x31,0x3f,0x2d,0x23,0x09,0x07,0x15,0x1b,
|
||||
0xa1,0xaf,0xbd,0xb3,0x99,0x97,0x85,0x8b,
|
||||
0xd1,0xdf,0xcd,0xc3,0xe9,0xe7,0xf5,0xfb,
|
||||
0x9a,0x94,0x86,0x88,0xa2,0xac,0xbe,0xb0,
|
||||
0xea,0xe4,0xf6,0xf8,0xd2,0xdc,0xce,0xc0,
|
||||
0x7a,0x74,0x66,0x68,0x42,0x4c,0x5e,0x50,
|
||||
0x0a,0x04,0x16,0x18,0x32,0x3c,0x2e,0x20,
|
||||
0xec,0xe2,0xf0,0xfe,0xd4,0xda,0xc8,0xc6,
|
||||
0x9c,0x92,0x80,0x8e,0xa4,0xaa,0xb8,0xb6,
|
||||
0x0c,0x02,0x10,0x1e,0x34,0x3a,0x28,0x26,
|
||||
0x7c,0x72,0x60,0x6e,0x44,0x4a,0x58,0x56,
|
||||
0x37,0x39,0x2b,0x25,0x0f,0x01,0x13,0x1d,
|
||||
0x47,0x49,0x5b,0x55,0x7f,0x71,0x63,0x6d,
|
||||
0xd7,0xd9,0xcb,0xc5,0xef,0xe1,0xf3,0xfd,
|
||||
0xa7,0xa9,0xbb,0xb5,0x9f,0x91,0x83,0x8d
|
||||
};
|
||||
|
||||
#if defined( HAVE_UINT_32T )
|
||||
typedef unsigned long uint_32t;
|
||||
#endif
|
||||
|
||||
#if defined( HAVE_MEMCPY )
|
||||
# define block_copy(d, s, l) memcpy(d, s, l)
|
||||
# define block16_copy(d, s) memcpy(d, s, N_BLOCK)
|
||||
#else
|
||||
# define block_copy(d, s, l) copy_block(d, s, l)
|
||||
# define block16_copy(d, s) copy_block16(d, s)
|
||||
#endif
|
||||
|
||||
/* block size 'nn' must be a multiple of four */
|
||||
|
||||
static void copy_block16( void *d, const void *s )
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0];
|
||||
((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1];
|
||||
((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2];
|
||||
((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3];
|
||||
#else
|
||||
((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0];
|
||||
((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1];
|
||||
((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2];
|
||||
((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3];
|
||||
((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4];
|
||||
((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5];
|
||||
((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6];
|
||||
((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7];
|
||||
((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8];
|
||||
((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9];
|
||||
((uint_8t*)d)[10] = ((uint_8t*)s)[10];
|
||||
((uint_8t*)d)[11] = ((uint_8t*)s)[11];
|
||||
((uint_8t*)d)[12] = ((uint_8t*)s)[12];
|
||||
((uint_8t*)d)[13] = ((uint_8t*)s)[13];
|
||||
((uint_8t*)d)[14] = ((uint_8t*)s)[14];
|
||||
((uint_8t*)d)[15] = ((uint_8t*)s)[15];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void copy_block( void * d, void *s, uint_8t nn )
|
||||
{
|
||||
while( nn-- )
|
||||
*((uint_8t*)d)++ = *((uint_8t*)s)++;
|
||||
}
|
||||
|
||||
static void xor_block( void *d, const void *s )
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
((uint_32t*)d)[ 0] ^= ((uint_32t*)s)[ 0];
|
||||
((uint_32t*)d)[ 1] ^= ((uint_32t*)s)[ 1];
|
||||
((uint_32t*)d)[ 2] ^= ((uint_32t*)s)[ 2];
|
||||
((uint_32t*)d)[ 3] ^= ((uint_32t*)s)[ 3];
|
||||
#else
|
||||
((uint_8t*)d)[ 0] ^= ((uint_8t*)s)[ 0];
|
||||
((uint_8t*)d)[ 1] ^= ((uint_8t*)s)[ 1];
|
||||
((uint_8t*)d)[ 2] ^= ((uint_8t*)s)[ 2];
|
||||
((uint_8t*)d)[ 3] ^= ((uint_8t*)s)[ 3];
|
||||
((uint_8t*)d)[ 4] ^= ((uint_8t*)s)[ 4];
|
||||
((uint_8t*)d)[ 5] ^= ((uint_8t*)s)[ 5];
|
||||
((uint_8t*)d)[ 6] ^= ((uint_8t*)s)[ 6];
|
||||
((uint_8t*)d)[ 7] ^= ((uint_8t*)s)[ 7];
|
||||
((uint_8t*)d)[ 8] ^= ((uint_8t*)s)[ 8];
|
||||
((uint_8t*)d)[ 9] ^= ((uint_8t*)s)[ 9];
|
||||
((uint_8t*)d)[10] ^= ((uint_8t*)s)[10];
|
||||
((uint_8t*)d)[11] ^= ((uint_8t*)s)[11];
|
||||
((uint_8t*)d)[12] ^= ((uint_8t*)s)[12];
|
||||
((uint_8t*)d)[13] ^= ((uint_8t*)s)[13];
|
||||
((uint_8t*)d)[14] ^= ((uint_8t*)s)[14];
|
||||
((uint_8t*)d)[15] ^= ((uint_8t*)s)[15];
|
||||
#endif
|
||||
}
|
||||
|
||||
static void copy_and_key( void *d, const void *s, const void *k )
|
||||
{
|
||||
#if defined( HAVE_UINT_32T )
|
||||
((uint_32t*)d)[ 0] = ((uint_32t*)s)[ 0] ^ ((uint_32t*)k)[ 0];
|
||||
((uint_32t*)d)[ 1] = ((uint_32t*)s)[ 1] ^ ((uint_32t*)k)[ 1];
|
||||
((uint_32t*)d)[ 2] = ((uint_32t*)s)[ 2] ^ ((uint_32t*)k)[ 2];
|
||||
((uint_32t*)d)[ 3] = ((uint_32t*)s)[ 3] ^ ((uint_32t*)k)[ 3];
|
||||
#elif 1
|
||||
((uint_8t*)d)[ 0] = ((uint_8t*)s)[ 0] ^ ((uint_8t*)k)[ 0];
|
||||
((uint_8t*)d)[ 1] = ((uint_8t*)s)[ 1] ^ ((uint_8t*)k)[ 1];
|
||||
((uint_8t*)d)[ 2] = ((uint_8t*)s)[ 2] ^ ((uint_8t*)k)[ 2];
|
||||
((uint_8t*)d)[ 3] = ((uint_8t*)s)[ 3] ^ ((uint_8t*)k)[ 3];
|
||||
((uint_8t*)d)[ 4] = ((uint_8t*)s)[ 4] ^ ((uint_8t*)k)[ 4];
|
||||
((uint_8t*)d)[ 5] = ((uint_8t*)s)[ 5] ^ ((uint_8t*)k)[ 5];
|
||||
((uint_8t*)d)[ 6] = ((uint_8t*)s)[ 6] ^ ((uint_8t*)k)[ 6];
|
||||
((uint_8t*)d)[ 7] = ((uint_8t*)s)[ 7] ^ ((uint_8t*)k)[ 7];
|
||||
((uint_8t*)d)[ 8] = ((uint_8t*)s)[ 8] ^ ((uint_8t*)k)[ 8];
|
||||
((uint_8t*)d)[ 9] = ((uint_8t*)s)[ 9] ^ ((uint_8t*)k)[ 9];
|
||||
((uint_8t*)d)[10] = ((uint_8t*)s)[10] ^ ((uint_8t*)k)[10];
|
||||
((uint_8t*)d)[11] = ((uint_8t*)s)[11] ^ ((uint_8t*)k)[11];
|
||||
((uint_8t*)d)[12] = ((uint_8t*)s)[12] ^ ((uint_8t*)k)[12];
|
||||
((uint_8t*)d)[13] = ((uint_8t*)s)[13] ^ ((uint_8t*)k)[13];
|
||||
((uint_8t*)d)[14] = ((uint_8t*)s)[14] ^ ((uint_8t*)k)[14];
|
||||
((uint_8t*)d)[15] = ((uint_8t*)s)[15] ^ ((uint_8t*)k)[15];
|
||||
#else
|
||||
block16_copy(d, s);
|
||||
xor_block(d, k);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void add_round_key( uint_8t d[N_BLOCK], const uint_8t k[N_BLOCK] )
|
||||
{
|
||||
xor_block(d, k);
|
||||
}
|
||||
|
||||
static void shift_sub_rows( uint_8t st[N_BLOCK] )
|
||||
{ uint_8t tt;
|
||||
|
||||
st[ 0] = s_box[st[ 0]]; st[ 4] = s_box[st[ 4]];
|
||||
st[ 8] = s_box[st[ 8]]; st[12] = s_box[st[12]];
|
||||
|
||||
tt = st[1]; st[ 1] = s_box[st[ 5]]; st[ 5] = s_box[st[ 9]];
|
||||
st[ 9] = s_box[st[13]]; st[13] = s_box[ tt ];
|
||||
|
||||
tt = st[2]; st[ 2] = s_box[st[10]]; st[10] = s_box[ tt ];
|
||||
tt = st[6]; st[ 6] = s_box[st[14]]; st[14] = s_box[ tt ];
|
||||
|
||||
tt = st[15]; st[15] = s_box[st[11]]; st[11] = s_box[st[ 7]];
|
||||
st[ 7] = s_box[st[ 3]]; st[ 3] = s_box[ tt ];
|
||||
}
|
||||
|
||||
static void inv_shift_sub_rows( uint_8t st[N_BLOCK] )
|
||||
{ uint_8t tt;
|
||||
|
||||
st[ 0] = inv_s_box[st[ 0]]; st[ 4] = inv_s_box[st[ 4]];
|
||||
st[ 8] = inv_s_box[st[ 8]]; st[12] = inv_s_box[st[12]];
|
||||
|
||||
tt = st[13]; st[13] = inv_s_box[st[9]]; st[ 9] = inv_s_box[st[5]];
|
||||
st[ 5] = inv_s_box[st[1]]; st[ 1] = inv_s_box[ tt ];
|
||||
|
||||
tt = st[2]; st[ 2] = inv_s_box[st[10]]; st[10] = inv_s_box[ tt ];
|
||||
tt = st[6]; st[ 6] = inv_s_box[st[14]]; st[14] = inv_s_box[ tt ];
|
||||
|
||||
tt = st[3]; st[ 3] = inv_s_box[st[ 7]]; st[ 7] = inv_s_box[st[11]];
|
||||
st[11] = inv_s_box[st[15]]; st[15] = inv_s_box[ tt ];
|
||||
}
|
||||
|
||||
#if defined( VERSION_1 )
|
||||
static void mix_sub_columns( uint_8t dt[N_BLOCK] )
|
||||
{ uint_8t st[N_BLOCK];
|
||||
block16_copy(st, dt);
|
||||
#else
|
||||
static void mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
|
||||
{
|
||||
#endif
|
||||
dt[ 0] = gfm2_s_box[st[0]] ^ gfm3_s_box[st[5]] ^ s_box[st[10]] ^ s_box[st[15]];
|
||||
dt[ 1] = s_box[st[0]] ^ gfm2_s_box[st[5]] ^ gfm3_s_box[st[10]] ^ s_box[st[15]];
|
||||
dt[ 2] = s_box[st[0]] ^ s_box[st[5]] ^ gfm2_s_box[st[10]] ^ gfm3_s_box[st[15]];
|
||||
dt[ 3] = gfm3_s_box[st[0]] ^ s_box[st[5]] ^ s_box[st[10]] ^ gfm2_s_box[st[15]];
|
||||
|
||||
dt[ 4] = gfm2_s_box[st[4]] ^ gfm3_s_box[st[9]] ^ s_box[st[14]] ^ s_box[st[3]];
|
||||
dt[ 5] = s_box[st[4]] ^ gfm2_s_box[st[9]] ^ gfm3_s_box[st[14]] ^ s_box[st[3]];
|
||||
dt[ 6] = s_box[st[4]] ^ s_box[st[9]] ^ gfm2_s_box[st[14]] ^ gfm3_s_box[st[3]];
|
||||
dt[ 7] = gfm3_s_box[st[4]] ^ s_box[st[9]] ^ s_box[st[14]] ^ gfm2_s_box[st[3]];
|
||||
|
||||
dt[ 8] = gfm2_s_box[st[8]] ^ gfm3_s_box[st[13]] ^ s_box[st[2]] ^ s_box[st[7]];
|
||||
dt[ 9] = s_box[st[8]] ^ gfm2_s_box[st[13]] ^ gfm3_s_box[st[2]] ^ s_box[st[7]];
|
||||
dt[10] = s_box[st[8]] ^ s_box[st[13]] ^ gfm2_s_box[st[2]] ^ gfm3_s_box[st[7]];
|
||||
dt[11] = gfm3_s_box[st[8]] ^ s_box[st[13]] ^ s_box[st[2]] ^ gfm2_s_box[st[7]];
|
||||
|
||||
dt[12] = gfm2_s_box[st[12]] ^ gfm3_s_box[st[1]] ^ s_box[st[6]] ^ s_box[st[11]];
|
||||
dt[13] = s_box[st[12]] ^ gfm2_s_box[st[1]] ^ gfm3_s_box[st[6]] ^ s_box[st[11]];
|
||||
dt[14] = s_box[st[12]] ^ s_box[st[1]] ^ gfm2_s_box[st[6]] ^ gfm3_s_box[st[11]];
|
||||
dt[15] = gfm3_s_box[st[12]] ^ s_box[st[1]] ^ s_box[st[6]] ^ gfm2_s_box[st[11]];
|
||||
}
|
||||
|
||||
#if defined( VERSION_1 )
|
||||
static void inv_mix_sub_columns( uint_8t dt[N_BLOCK] )
|
||||
{ uint_8t st[N_BLOCK];
|
||||
block16_copy(st, dt);
|
||||
#else
|
||||
static void inv_mix_sub_columns( uint_8t dt[N_BLOCK], uint_8t st[N_BLOCK] )
|
||||
{
|
||||
#endif
|
||||
dt[ 0] = inv_s_box[gfmul_e[st[ 0]] ^ gfmul_b[st[ 1]] ^ gfmul_d[st[ 2]] ^ gfmul_9[st[ 3]]];
|
||||
dt[ 5] = inv_s_box[gfmul_9[st[ 0]] ^ gfmul_e[st[ 1]] ^ gfmul_b[st[ 2]] ^ gfmul_d[st[ 3]]];
|
||||
dt[10] = inv_s_box[gfmul_d[st[ 0]] ^ gfmul_9[st[ 1]] ^ gfmul_e[st[ 2]] ^ gfmul_b[st[ 3]]];
|
||||
dt[15] = inv_s_box[gfmul_b[st[ 0]] ^ gfmul_d[st[ 1]] ^ gfmul_9[st[ 2]] ^ gfmul_e[st[ 3]]];
|
||||
|
||||
dt[ 4] = inv_s_box[gfmul_e[st[ 4]] ^ gfmul_b[st[ 5]] ^ gfmul_d[st[ 6]] ^ gfmul_9[st[ 7]]];
|
||||
dt[ 9] = inv_s_box[gfmul_9[st[ 4]] ^ gfmul_e[st[ 5]] ^ gfmul_b[st[ 6]] ^ gfmul_d[st[ 7]]];
|
||||
dt[14] = inv_s_box[gfmul_d[st[ 4]] ^ gfmul_9[st[ 5]] ^ gfmul_e[st[ 6]] ^ gfmul_b[st[ 7]]];
|
||||
dt[ 3] = inv_s_box[gfmul_b[st[ 4]] ^ gfmul_d[st[ 5]] ^ gfmul_9[st[ 6]] ^ gfmul_e[st[ 7]]];
|
||||
|
||||
dt[ 8] = inv_s_box[gfmul_e[st[ 8]] ^ gfmul_b[st[ 9]] ^ gfmul_d[st[10]] ^ gfmul_9[st[11]]];
|
||||
dt[13] = inv_s_box[gfmul_9[st[ 8]] ^ gfmul_e[st[ 9]] ^ gfmul_b[st[10]] ^ gfmul_d[st[11]]];
|
||||
dt[ 2] = inv_s_box[gfmul_d[st[ 8]] ^ gfmul_9[st[ 9]] ^ gfmul_e[st[10]] ^ gfmul_b[st[11]]];
|
||||
dt[ 7] = inv_s_box[gfmul_b[st[ 8]] ^ gfmul_d[st[ 9]] ^ gfmul_9[st[10]] ^ gfmul_e[st[11]]];
|
||||
|
||||
dt[12] = inv_s_box[gfmul_e[st[12]] ^ gfmul_b[st[13]] ^ gfmul_d[st[14]] ^ gfmul_9[st[15]]];
|
||||
dt[ 1] = inv_s_box[gfmul_9[st[12]] ^ gfmul_e[st[13]] ^ gfmul_b[st[14]] ^ gfmul_d[st[15]]];
|
||||
dt[ 6] = inv_s_box[gfmul_d[st[12]] ^ gfmul_9[st[13]] ^ gfmul_e[st[14]] ^ gfmul_b[st[15]]];
|
||||
dt[11] = inv_s_box[gfmul_b[st[12]] ^ gfmul_d[st[13]] ^ gfmul_9[st[14]] ^ gfmul_e[st[15]]];
|
||||
}
|
||||
|
||||
#if defined( AES_ENC_PREKEYED ) || defined( AES_DEC_PREKEYED )
|
||||
|
||||
/* Set the cipher key for the pre-keyed version */
|
||||
|
||||
return_type aes_set_key( const unsigned char key[], length_type keylen, aes_context ctx[1] )
|
||||
{
|
||||
uint_8t cc, rc, hi;
|
||||
|
||||
switch( keylen )
|
||||
{
|
||||
case 16:
|
||||
case 128:
|
||||
keylen = 16;
|
||||
break;
|
||||
case 24:
|
||||
case 192:
|
||||
keylen = 24;
|
||||
break;
|
||||
case 32:
|
||||
case 256:
|
||||
keylen = 32;
|
||||
break;
|
||||
default:
|
||||
ctx->rnd = 0;
|
||||
return (return_type) -1;
|
||||
}
|
||||
block_copy(ctx->ksch, key, keylen);
|
||||
hi = (keylen + 28) << 2;
|
||||
ctx->rnd = (hi >> 4) - 1;
|
||||
for( cc = keylen, rc = 1; cc < hi; cc += 4 )
|
||||
{ uint_8t tt, t0, t1, t2, t3;
|
||||
|
||||
t0 = ctx->ksch[cc - 4];
|
||||
t1 = ctx->ksch[cc - 3];
|
||||
t2 = ctx->ksch[cc - 2];
|
||||
t3 = ctx->ksch[cc - 1];
|
||||
if( cc % keylen == 0 )
|
||||
{
|
||||
tt = t0;
|
||||
t0 = s_box[t1] ^ rc;
|
||||
t1 = s_box[t2];
|
||||
t2 = s_box[t3];
|
||||
t3 = s_box[tt];
|
||||
rc = f2(rc);
|
||||
}
|
||||
else if( keylen > 24 && cc % keylen == 16 )
|
||||
{
|
||||
t0 = s_box[t0];
|
||||
t1 = s_box[t1];
|
||||
t2 = s_box[t2];
|
||||
t3 = s_box[t3];
|
||||
}
|
||||
tt = cc - keylen;
|
||||
ctx->ksch[cc + 0] = ctx->ksch[tt + 0] ^ t0;
|
||||
ctx->ksch[cc + 1] = ctx->ksch[tt + 1] ^ t1;
|
||||
ctx->ksch[cc + 2] = ctx->ksch[tt + 2] ^ t2;
|
||||
ctx->ksch[cc + 3] = ctx->ksch[tt + 3] ^ t3;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_PREKEYED )
|
||||
|
||||
/* Encrypt a single block of 16 bytes */
|
||||
|
||||
return_type aes_encrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const aes_context ctx[1] )
|
||||
{
|
||||
if( ctx->rnd )
|
||||
{
|
||||
uint_8t s1[N_BLOCK], r;
|
||||
copy_and_key( s1, in, ctx->ksch );
|
||||
|
||||
for( r = 1 ; r < ctx->rnd ; ++r )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
mix_sub_columns( s1 );
|
||||
add_round_key( s1, ctx->ksch + r * N_BLOCK);
|
||||
}
|
||||
#else
|
||||
{ uint_8t s2[N_BLOCK];
|
||||
mix_sub_columns( s2, s1 );
|
||||
copy_and_key( s1, s2, ctx->ksch + r * N_BLOCK);
|
||||
}
|
||||
#endif
|
||||
shift_sub_rows( s1 );
|
||||
copy_and_key( out, s1, ctx->ksch + r * N_BLOCK );
|
||||
}
|
||||
else
|
||||
return (return_type) -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_PREKEYED )
|
||||
|
||||
/* Decrypt a single block of 16 bytes */
|
||||
|
||||
return_type aes_decrypt( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK], const aes_context ctx[1] )
|
||||
{
|
||||
if( ctx->rnd )
|
||||
{
|
||||
uint_8t s1[N_BLOCK], r;
|
||||
copy_and_key( s1, in, ctx->ksch + ctx->rnd * N_BLOCK );
|
||||
inv_shift_sub_rows( s1 );
|
||||
|
||||
for( r = ctx->rnd ; --r ; )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
add_round_key( s1, ctx->ksch + r * N_BLOCK );
|
||||
inv_mix_sub_columns( s1 );
|
||||
}
|
||||
#else
|
||||
{ uint_8t s2[N_BLOCK];
|
||||
copy_and_key( s2, s1, ctx->ksch + r * N_BLOCK );
|
||||
inv_mix_sub_columns( s1, s2 );
|
||||
}
|
||||
#endif
|
||||
copy_and_key( out, s1, ctx->ksch );
|
||||
}
|
||||
else
|
||||
return (return_type) -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_128_OTFK )
|
||||
|
||||
/* The 'on the fly' encryption key update for for 128 bit keys */
|
||||
|
||||
static void update_encrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
|
||||
{ uint_8t cc;
|
||||
|
||||
k[0] ^= s_box[k[13]] ^ *rc;
|
||||
k[1] ^= s_box[k[14]];
|
||||
k[2] ^= s_box[k[15]];
|
||||
k[3] ^= s_box[k[12]];
|
||||
*rc = f2( *rc );
|
||||
|
||||
for(cc = 4; cc < 16; cc += 4 )
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/* Encrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
|
||||
|
||||
void aes_encrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
|
||||
const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
|
||||
{ uint_8t s1[N_BLOCK], r, rc = 1;
|
||||
|
||||
if(o_key != key)
|
||||
block16_copy( o_key, key );
|
||||
copy_and_key( s1, in, o_key );
|
||||
|
||||
for( r = 1 ; r < 10 ; ++r )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
mix_sub_columns( s1 );
|
||||
update_encrypt_key_128( o_key, &rc );
|
||||
add_round_key( s1, o_key );
|
||||
}
|
||||
#else
|
||||
{ uint_8t s2[N_BLOCK];
|
||||
mix_sub_columns( s2, s1 );
|
||||
update_encrypt_key_128( o_key, &rc );
|
||||
copy_and_key( s1, s2, o_key );
|
||||
}
|
||||
#endif
|
||||
|
||||
shift_sub_rows( s1 );
|
||||
update_encrypt_key_128( o_key, &rc );
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_128_OTFK )
|
||||
|
||||
/* The 'on the fly' decryption key update for for 128 bit keys */
|
||||
|
||||
static void update_decrypt_key_128( uint_8t k[N_BLOCK], uint_8t *rc )
|
||||
{ uint_8t cc;
|
||||
|
||||
for( cc = 12; cc > 0; cc -= 4 )
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
*rc = d2(*rc);
|
||||
k[0] ^= s_box[k[13]] ^ *rc;
|
||||
k[1] ^= s_box[k[14]];
|
||||
k[2] ^= s_box[k[15]];
|
||||
k[3] ^= s_box[k[12]];
|
||||
}
|
||||
|
||||
/* Decrypt a single block of 16 bytes with 'on the fly' 128 bit keying */
|
||||
|
||||
void aes_decrypt_128( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
|
||||
const unsigned char key[N_BLOCK], unsigned char o_key[N_BLOCK] )
|
||||
{
|
||||
uint_8t s1[N_BLOCK], r, rc = 0x6c;
|
||||
if(o_key != key)
|
||||
block16_copy( o_key, key );
|
||||
|
||||
copy_and_key( s1, in, o_key );
|
||||
inv_shift_sub_rows( s1 );
|
||||
|
||||
for( r = 10 ; --r ; )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
update_decrypt_key_128( o_key, &rc );
|
||||
add_round_key( s1, o_key );
|
||||
inv_mix_sub_columns( s1 );
|
||||
}
|
||||
#else
|
||||
{ uint_8t s2[N_BLOCK];
|
||||
update_decrypt_key_128( o_key, &rc );
|
||||
copy_and_key( s2, s1, o_key );
|
||||
inv_mix_sub_columns( s1, s2 );
|
||||
}
|
||||
#endif
|
||||
update_decrypt_key_128( o_key, &rc );
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_ENC_256_OTFK )
|
||||
|
||||
/* The 'on the fly' encryption key update for for 256 bit keys */
|
||||
|
||||
static void update_encrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
|
||||
{ uint_8t cc;
|
||||
|
||||
k[0] ^= s_box[k[29]] ^ *rc;
|
||||
k[1] ^= s_box[k[30]];
|
||||
k[2] ^= s_box[k[31]];
|
||||
k[3] ^= s_box[k[28]];
|
||||
*rc = f2( *rc );
|
||||
|
||||
for(cc = 4; cc < 16; cc += 4)
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
|
||||
k[16] ^= s_box[k[12]];
|
||||
k[17] ^= s_box[k[13]];
|
||||
k[18] ^= s_box[k[14]];
|
||||
k[19] ^= s_box[k[15]];
|
||||
|
||||
for( cc = 20; cc < 32; cc += 4 )
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
}
|
||||
|
||||
/* Encrypt a single block of 16 bytes with 'on the fly' 256 bit keying */
|
||||
|
||||
void aes_encrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
|
||||
const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
|
||||
{
|
||||
uint_8t s1[N_BLOCK], r, rc = 1;
|
||||
if(o_key != key)
|
||||
{
|
||||
block16_copy( o_key, key );
|
||||
block16_copy( o_key + 16, key + 16 );
|
||||
}
|
||||
copy_and_key( s1, in, o_key );
|
||||
|
||||
for( r = 1 ; r < 14 ; ++r )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
mix_sub_columns(s1);
|
||||
if( r & 1 )
|
||||
add_round_key( s1, o_key + 16 );
|
||||
else
|
||||
{
|
||||
update_encrypt_key_256( o_key, &rc );
|
||||
add_round_key( s1, o_key );
|
||||
}
|
||||
}
|
||||
#else
|
||||
{ uint_8t s2[N_BLOCK];
|
||||
mix_sub_columns( s2, s1 );
|
||||
if( r & 1 )
|
||||
copy_and_key( s1, s2, o_key + 16 );
|
||||
else
|
||||
{
|
||||
update_encrypt_key_256( o_key, &rc );
|
||||
copy_and_key( s1, s2, o_key );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
shift_sub_rows( s1 );
|
||||
update_encrypt_key_256( o_key, &rc );
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DEC_256_OTFK )
|
||||
|
||||
/* The 'on the fly' encryption key update for for 256 bit keys */
|
||||
|
||||
static void update_decrypt_key_256( uint_8t k[2 * N_BLOCK], uint_8t *rc )
|
||||
{ uint_8t cc;
|
||||
|
||||
for(cc = 28; cc > 16; cc -= 4)
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
|
||||
k[16] ^= s_box[k[12]];
|
||||
k[17] ^= s_box[k[13]];
|
||||
k[18] ^= s_box[k[14]];
|
||||
k[19] ^= s_box[k[15]];
|
||||
|
||||
for(cc = 12; cc > 0; cc -= 4)
|
||||
{
|
||||
k[cc + 0] ^= k[cc - 4];
|
||||
k[cc + 1] ^= k[cc - 3];
|
||||
k[cc + 2] ^= k[cc - 2];
|
||||
k[cc + 3] ^= k[cc - 1];
|
||||
}
|
||||
|
||||
*rc = d2(*rc);
|
||||
k[0] ^= s_box[k[29]] ^ *rc;
|
||||
k[1] ^= s_box[k[30]];
|
||||
k[2] ^= s_box[k[31]];
|
||||
k[3] ^= s_box[k[28]];
|
||||
}
|
||||
|
||||
/* Decrypt a single block of 16 bytes with 'on the fly'
|
||||
256 bit keying
|
||||
*/
|
||||
void aes_decrypt_256( const unsigned char in[N_BLOCK], unsigned char out[N_BLOCK],
|
||||
const unsigned char key[2 * N_BLOCK], unsigned char o_key[2 * N_BLOCK] )
|
||||
{
|
||||
uint_8t s1[N_BLOCK], r, rc = 0x80;
|
||||
|
||||
if(o_key != key)
|
||||
{
|
||||
block16_copy( o_key, key );
|
||||
block16_copy( o_key + 16, key + 16 );
|
||||
}
|
||||
|
||||
copy_and_key( s1, in, o_key );
|
||||
inv_shift_sub_rows( s1 );
|
||||
|
||||
for( r = 14 ; --r ; )
|
||||
#if defined( VERSION_1 )
|
||||
{
|
||||
if( ( r & 1 ) )
|
||||
{
|
||||
update_decrypt_key_256( o_key, &rc );
|
||||
add_round_key( s1, o_key + 16 );
|
||||
}
|
||||
else
|
||||
add_round_key( s1, o_key );
|
||||
inv_mix_sub_columns( s1 );
|
||||
}
|
||||
#else
|
||||
{ uint_8t s2[N_BLOCK];
|
||||
if( ( r & 1 ) )
|
||||
{
|
||||
update_decrypt_key_256( o_key, &rc );
|
||||
copy_and_key( s2, s1, o_key + 16 );
|
||||
}
|
||||
else
|
||||
copy_and_key( s2, s1, o_key );
|
||||
inv_mix_sub_columns( s1, s2 );
|
||||
}
|
||||
#endif
|
||||
copy_and_key( out, s1, o_key );
|
||||
}
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user