Add original TrueCrypt 7.1a sources

This commit is contained in:
Mounir IDRASSI 2013-06-22 16:16:13 +02:00
commit c606f0866c
252 changed files with 96755 additions and 0 deletions

28
src/Boot/Windows/Bios.h Normal file
View 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

View 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&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH RESCUE_DISK=1"
ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue &gt;NUL:&#x0D;&#x0A;md Rescue 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_AES &gt;NUL:&#x0D;&#x0A;md Rescue_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Serpent &gt;NUL:&#x0D;&#x0A;md Rescue_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT RESCUE_DISK=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Rescue_Twofish &gt;NUL:&#x0D;&#x0A;md Rescue_Twofish 2&gt;NUL:&#x0D;&#x0A;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 &gt;NUL:"
Output="Release\BootLoader.com"
PreprocessorDefinitions="WIN32;NDEBUG"
IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
ForcedIncludes=""
AssemblySearchPath=""
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
</Configuration>
<Configuration
Name="Release Loader|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="0"
>
<Tool
Name="VCNMakeTool"
BuildCommandLine="md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
ReBuildCommandLine="del /q /s Release &gt;NUL:&#x0D;&#x0A;md Release 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_AES &gt;NUL:&#x0D;&#x0A;md Release_AES 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=AES&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Serpent &gt;NUL:&#x0D;&#x0A;md Release_Serpent 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=SERPENT&#x0D;&#x0A;&#x0D;&#x0A;del /q /s Release_Twofish &gt;NUL:&#x0D;&#x0A;md Release_Twofish 2&gt;NUL:&#x0D;&#x0A;nmake.exe /nologo RELEASE=1 SINGLE_CIPHER=TWOFISH"
CleanCommandLine="del /q /s Release Release_AES Release_Serpent Release_Twofish &gt;NUL:"
Output="Release\BootLoader.com"
PreprocessorDefinitions="WIN32;NDEBUG"
IncludeSearchPath="&quot;$(SolutionDir)&quot;;&quot;$(SolutionDir)\Common&quot;;&quot;$(SolutionDir)\Crypto&quot;;&quot;$(MSVC16_ROOT)\Include&quot;"
ForcedIncludes=""
AssemblySearchPath=""
ForcedUsingAssemblies=""
CompileAsManaged=""
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\BootConfig.cpp"
>
</File>
<File
RelativePath=".\BootConsoleIo.cpp"
>
</File>
<File
RelativePath=".\BootCrt.asm"
>
</File>
<File
RelativePath=".\BootDebug.cpp"
>
</File>
<File
RelativePath=".\BootDiskIo.cpp"
>
</File>
<File
RelativePath=".\BootEncryptedIo.cpp"
>
</File>
<File
RelativePath=".\BootMain.cpp"
>
</File>
<File
RelativePath=".\BootMemory.cpp"
>
</File>
<File
RelativePath=".\BootSector.asm"
>
</File>
<File
RelativePath=".\Decompressor.c"
>
</File>
<File
RelativePath=".\IntFilter.cpp"
>
</File>
<File
RelativePath=".\Platform.cpp"
>
</File>
<Filter
Name="Common"
>
<File
RelativePath="..\..\Common\Crc.c"
>
</File>
<File
RelativePath="..\..\Common\Crypto.c"
>
</File>
<File
RelativePath="..\..\Common\Endian.c"
>
</File>
<File
RelativePath="..\..\Common\Pkcs5.c"
>
</File>
<File
RelativePath="..\..\Common\Volumes.c"
>
</File>
<File
RelativePath="..\..\Common\Xts.c"
>
</File>
</Filter>
<Filter
Name="Crypto"
>
<File
RelativePath="..\..\Crypto\Aes_hw_cpu.asm"
>
</File>
<File
RelativePath="..\..\Crypto\AesSmall.c"
>
</File>
<File
RelativePath="..\..\Crypto\AesSmall_x86.asm"
>
</File>
<File
RelativePath="..\..\Crypto\Rmd160.c"
>
</File>
<File
RelativePath="..\..\Crypto\Serpent.c"
>
</File>
<File
RelativePath="..\..\Crypto\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>

View 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

View 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

View 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

View 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;
}

View 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

View 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

View 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

View 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
View 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

View 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 &sectorCount)
{
Print (sectorCount >> (TC_LB_SIZE_BIT_SHIFT_DIVISOR + 2)); Print (" MB ");
}
BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
{
CheckStack();
byte cylinderLow = (byte) chs.Cylinder;
byte sector = chs.Sector;
sector |= byte (chs.Cylinder >> 2) & 0xc0;
byte function = write ? 0x03 : 0x02;
BiosResult result;
byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
do
{
result = BiosResultSuccess;
__asm
{
push es
mov ax, bufferSegment
mov es, ax
mov bx, bufferOffset
mov dl, drive
mov ch, cylinderLow
mov si, chs
mov dh, [si].Head
mov cl, sector
mov al, sectorCount
mov ah, function
int 0x13
jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
mov result, ah
ok:
pop es
}
if (result == BiosResultEccCorrected)
result = BiosResultSuccess;
// Some BIOSes report I/O errors prematurely in some cases
} while (result != BiosResultSuccess && --tryCount != 0);
if (!silent && result != BiosResultSuccess)
PrintDiskError (result, write, drive, nullptr, &chs);
return result;
}
BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
{
uint16 codeSeg;
__asm mov codeSeg, cs
return ReadWriteSectors (write, codeSeg, (uint16) buffer, drive, chs, sectorCount, silent);
}
BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
{
return ReadWriteSectors (false, buffer, drive, chs, sectorCount, silent);
}
BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent)
{
return ReadWriteSectors (true, buffer, drive, chs, sectorCount, silent);
}
static BiosResult ReadWriteSectors (bool write, BiosLbaPacket &dapPacket, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
{
CheckStack();
if (!IsLbaSupported (drive))
{
DriveGeometry geometry;
BiosResult result = GetDriveGeometry (drive, geometry, silent);
if (result != BiosResultSuccess)
return result;
ChsAddress chs;
LbaToChs (geometry, sector, chs);
return ReadWriteSectors (write, (uint16) (dapPacket.Buffer >> 16), (uint16) dapPacket.Buffer, drive, chs, sectorCount, silent);
}
dapPacket.Size = sizeof (dapPacket);
dapPacket.Reserved = 0;
dapPacket.SectorCount = sectorCount;
dapPacket.Sector = sector;
byte function = write ? 0x43 : 0x42;
BiosResult result;
byte tryCount = TC_MAX_BIOS_DISK_IO_RETRIES;
do
{
result = BiosResultSuccess;
__asm
{
mov bx, 0x55aa
mov dl, drive
mov si, [dapPacket]
mov ah, function
xor al, al
int 0x13
jnc ok // If CF=0, ignore AH to prevent issues caused by potential bugs in BIOSes
mov result, ah
ok:
}
if (result == BiosResultEccCorrected)
result = BiosResultSuccess;
// Some BIOSes report I/O errors prematurely in some cases
} while (result != BiosResultSuccess && --tryCount != 0);
if (!silent && result != BiosResultSuccess)
PrintDiskError (result, write, drive, &sector);
return result;
}
static BiosResult ReadWriteSectors (bool write, byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
{
BiosLbaPacket dapPacket;
dapPacket.Buffer = (uint32) buffer;
return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
}
BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
{
BiosLbaPacket dapPacket;
dapPacket.Buffer = ((uint32) bufferSegment << 16) | bufferOffset;
return ReadWriteSectors (write, dapPacket, drive, sector, sectorCount, silent);
}
BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
{
return ReadWriteSectors (false, bufferSegment, bufferOffset, drive, sector, sectorCount, silent);
}
BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
{
BiosResult result;
uint16 codeSeg;
__asm mov codeSeg, cs
result = ReadSectors (BootStarted ? codeSeg : TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, drive, sector, sectorCount, silent);
// Alternative segment is used to prevent memory corruption caused by buggy BIOSes
if (!BootStarted)
CopyMemory (TC_BOOT_LOADER_ALT_SEGMENT, (uint16) buffer, buffer, sectorCount * TC_LB_SIZE);
return result;
}
BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent)
{
return ReadWriteSectors (true, buffer, drive, sector, sectorCount, silent);
}
BiosResult GetDriveGeometry (byte drive, DriveGeometry &geometry, bool silent)
{
CheckStack();
byte maxCylinderLow, maxHead, maxSector;
BiosResult result;
__asm
{
push es
mov dl, drive
mov ah, 0x08
int 0x13
mov result, ah
mov maxCylinderLow, ch
mov maxSector, cl
mov maxHead, dh
pop es
}
if (result == BiosResultSuccess)
{
geometry.Cylinders = (maxCylinderLow | (uint16 (maxSector & 0xc0) << 2)) + 1;
geometry.Heads = maxHead + 1;
geometry.Sectors = maxSector & ~0xc0;
}
else if (!silent)
{
Print ("Drive ");
Print (drive ^ 0x80);
Print (" not found: ");
PrintErrorNoEndl ("");
Print (result);
PrintEndl();
}
return result;
}
void ChsToLba (const DriveGeometry &geometry, const ChsAddress &chs, uint64 &lba)
{
lba.HighPart = 0;
lba.LowPart = (uint32 (chs.Cylinder) * geometry.Heads + chs.Head) * geometry.Sectors + chs.Sector - 1;
}
void LbaToChs (const DriveGeometry &geometry, const uint64 &lba, ChsAddress &chs)
{
chs.Sector = (byte) ((lba.LowPart % geometry.Sectors) + 1);
uint32 ch = lba.LowPart / geometry.Sectors;
chs.Head = (byte) (ch % geometry.Heads);
chs.Cylinder = (uint16) (ch / geometry.Heads);
}
void PartitionEntryMBRToPartition (const PartitionEntryMBR &partEntry, Partition &partition)
{
partition.Active = partEntry.BootIndicator == 0x80;
partition.EndSector.HighPart = 0;
partition.EndSector.LowPart = partEntry.StartLBA + partEntry.SectorCountLBA - 1;
partition.SectorCount.HighPart = 0;
partition.SectorCount.LowPart = partEntry.SectorCountLBA;
partition.StartSector.HighPart = 0;
partition.StartSector.LowPart = partEntry.StartLBA;
partition.Type = partEntry.Type;
}
BiosResult ReadWriteMBR (bool write, byte drive, bool silent)
{
uint64 mbrSector;
mbrSector.HighPart = 0;
mbrSector.LowPart = 0;
if (write)
return WriteSectors (SectorBuffer, drive, mbrSector, 1, silent);
return ReadSectors (SectorBuffer, drive, mbrSector, 1, silent); // Uses alternative segment
}
BiosResult GetDrivePartitions (byte drive, Partition *partitionArray, size_t partitionArrayCapacity, size_t &partitionCount, bool activeOnly, Partition *findPartitionFollowingThis, bool silent)
{
Partition *followingPartition;
Partition tmpPartition;
if (findPartitionFollowingThis)
{
assert (partitionArrayCapacity == 1);
partitionArrayCapacity = 0xff;
followingPartition = partitionArray;
partitionArray = &tmpPartition;
followingPartition->Drive = TC_INVALID_BIOS_DRIVE;
followingPartition->StartSector.LowPart = 0xFFFFffffUL;
}
AcquireSectorBuffer();
BiosResult result = ReadWriteMBR (false, drive, silent);
ReleaseSectorBuffer();
partitionCount = 0;
MBR *mbr = (MBR *) SectorBuffer;
if (result != BiosResultSuccess || mbr->Signature != 0xaa55)
return result;
PartitionEntryMBR mbrPartitions[4];
memcpy (mbrPartitions, mbr->Partitions, sizeof (mbrPartitions));
size_t partitionArrayPos = 0, partitionNumber;
for (partitionNumber = 0;
partitionNumber < array_capacity (mbrPartitions) && partitionArrayPos < partitionArrayCapacity;
++partitionNumber)
{
const PartitionEntryMBR &partEntry = mbrPartitions[partitionNumber];
if (partEntry.SectorCountLBA > 0)
{
Partition &partition = partitionArray[partitionArrayPos];
PartitionEntryMBRToPartition (partEntry, partition);
if (activeOnly && !partition.Active)
continue;
partition.Drive = drive;
partition.Number = partitionArrayPos;
if (partEntry.Type == 0x5 || partEntry.Type == 0xf) // Extended partition
{
if (IsLbaSupported (drive))
{
// Find all extended partitions
uint64 firstExtStartLBA = partition.StartSector;
uint64 extStartLBA = partition.StartSector;
MBR *extMbr = (MBR *) SectorBuffer;
while (partitionArrayPos < partitionArrayCapacity &&
(result = ReadSectors ((byte *) extMbr, drive, extStartLBA, 1, silent)) == BiosResultSuccess
&& extMbr->Signature == 0xaa55)
{
if (extMbr->Partitions[0].SectorCountLBA > 0)
{
Partition &logPart = partitionArray[partitionArrayPos];
PartitionEntryMBRToPartition (extMbr->Partitions[0], logPart);
logPart.Drive = drive;
logPart.Number = partitionArrayPos;
logPart.Primary = false;
logPart.StartSector.LowPart += extStartLBA.LowPart;
logPart.EndSector.LowPart += extStartLBA.LowPart;
if (findPartitionFollowingThis)
{
if (logPart.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
&& logPart.StartSector.LowPart < followingPartition->StartSector.LowPart)
{
*followingPartition = logPart;
}
}
else
++partitionArrayPos;
}
// Secondary extended
if (extMbr->Partitions[1].Type != 0x5 && extMbr->Partitions[1].Type == 0xf
|| extMbr->Partitions[1].SectorCountLBA == 0)
break;
extStartLBA.LowPart = extMbr->Partitions[1].StartLBA + firstExtStartLBA.LowPart;
}
}
}
else
{
partition.Primary = true;
if (findPartitionFollowingThis)
{
if (partition.StartSector.LowPart > findPartitionFollowingThis->EndSector.LowPart
&& partition.StartSector.LowPart < followingPartition->StartSector.LowPart)
{
*followingPartition = partition;
}
}
else
++partitionArrayPos;
}
}
}
partitionCount = partitionArrayPos;
return result;
}
bool GetActivePartition (byte drive)
{
size_t partCount;
if (GetDrivePartitions (drive, &ActivePartition, 1, partCount, true) != BiosResultSuccess || partCount < 1)
{
ActivePartition.Drive = TC_INVALID_BIOS_DRIVE;
PrintError (TC_BOOT_STR_NO_BOOT_PARTITION);
return false;
}
return true;
}

View 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 &sectorCount);
BiosResult ReadWriteMBR (bool write, byte drive, bool silent = false);
BiosResult ReadSectors (uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
BiosResult ReadSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
BiosResult ReadSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
BiosResult ReadWriteSectors (bool write, uint16 bufferSegment, uint16 bufferOffset, byte drive, const uint64 &sector, uint16 sectorCount, bool silent);
BiosResult WriteSectors (byte *buffer, byte drive, const uint64 &sector, uint16 sectorCount, bool silent = false);
BiosResult WriteSectors (byte *buffer, byte drive, const ChsAddress &chs, byte sectorCount, bool silent = false);
extern byte SectorBuffer[TC_LB_SIZE];
#endif // TC_HEADER_Boot_BootDiskIo

View 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, &sector, 1, BootCryptoInfo);
CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE);
ReleaseSectorBuffer();
}
++sector;
destOffset += TC_LB_SIZE;
}
}
return result;
}
BiosResult WriteEncryptedSectors (uint16 sourceSegment, uint16 sourceOffset, byte drive, uint64 sector, uint16 sectorCount)
{
BiosResult result;
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 &sector, uint16 sectorCount)
{
uint64 readWriteEnd = sector + --sectorCount;
return ((sector < EncryptedVirtualPartition.StartSector && readWriteEnd >= EncryptedVirtualPartition.StartSector)
|| (sector >= EncryptedVirtualPartition.StartSector && readWriteEnd > EncryptedVirtualPartition.EndSector));
}

View 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 &sector, uint16 sectorCount);
#endif // TC_HEADER_Boot_BootEncryptionIo

File diff suppressed because it is too large Load Diff

View 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

View 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);
}

View 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);

View 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

View 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

View 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;
}

View 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 (&regs, &IntRegisters, sizeof (regs));
__asm sti
static int ReEntryCount = -1;
++ReEntryCount;
byte function = (byte) (regs.AX >> 8);
#ifdef TC_TRACE_INT13
DisableScreenOutput();
PrintHex (function);
Print (" EN:"); Print (ReEntryCount);
Print (" SS:"); PrintHex (regs.SS);
uint16 spdbg;
__asm mov spdbg, sp
PrintChar (' ');
PrintHex (spdbg);
PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
#endif
bool passOriginalRequest = true;
switch (function)
{
case 0x2: // Read sectors
case 0x3: // Write sectors
{
byte drive = (byte) regs.DX;
ChsAddress chs;
chs.Cylinder = ((regs.CX << 2) & 0x300) | (regs.CX >> 8);
chs.Head = regs.DX >> 8;
chs.Sector = regs.CX & 0x3f;
byte sectorCount = (byte) regs.AX;
#ifdef TC_TRACE_INT13
PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
Print (" Chs: "); Print (chs);
#endif
uint64 sector;
if (drive == BootDrive)
{
if (!BootDriveGeometryValid)
TC_THROW_FATAL_EXCEPTION;
ChsToLba (BootDriveGeometry, chs, sector);
#ifdef TC_TRACE_INT13
PrintVal (" Sec", sector.LowPart, false);
#endif
}
#ifdef TC_TRACE_INT13
PrintVal (" Count", sectorCount, false);
Print (" Buf: "); PrintHex (regs.ES); PrintChar (':'); PrintHex (regs.BX);
PrintEndl();
#endif
if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
{
BiosResult result;
if (function == 0x3)
result = WriteEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
else
result = ReadEncryptedSectors (regs.ES, regs.BX, drive, sector, sectorCount);
__asm cli
memcpy (&IntRegisters, &regs, sizeof (regs));
IntRegisters.AX = (uint16) result << 8;
if (result == BiosResultSuccess)
{
IntRegisters.AX |= sectorCount;
IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
}
else
IntRegisters.Flags |= TC_X86_CARRY_FLAG;
passOriginalRequest = false;
}
}
break;
case 0x42: // Read sectors LBA
case 0x43: // Write sectors LBA
{
byte drive = (byte) regs.DX;
BiosLbaPacket lba;
CopyMemory (regs.DS, regs.SI, (byte *) &lba, sizeof (lba));
#ifdef TC_TRACE_INT13
PrintVal (": Drive", drive - TC_FIRST_BIOS_DRIVE, false);
PrintVal (" Sec", lba.Sector.LowPart, false);
PrintVal (" Count", lba.SectorCount, false);
PrintVal (" Buf", lba.Buffer, false, true);
PrintEndl();
#endif
if (ReEntryCount == 0 && drive == EncryptedVirtualPartition.Drive)
{
BiosResult result;
uint16 segment = (uint16) (lba.Buffer >> 16);
uint16 offset = (uint16) lba.Buffer;
if (function == 0x43)
result = WriteEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
else
result = ReadEncryptedSectors (segment, offset, drive, lba.Sector, lba.SectorCount);
__asm cli
memcpy (&IntRegisters, &regs, sizeof (regs));
IntRegisters.AX = (IntRegisters.AX & 0xff) | ((uint16) result << 8);
if (result == BiosResultSuccess)
IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
else
IntRegisters.Flags |= TC_X86_CARRY_FLAG;
passOriginalRequest = false;
}
}
break;
default:
#ifdef TC_TRACE_INT13
PrintEndl();
#endif
break;
}
#ifdef TC_TRACE_INT13
EnableScreenOutput();
#endif
--ReEntryCount;
return passOriginalRequest;
}
#define TC_MAX_MEMORY_MAP_SIZE 80
BiosMemoryMapEntry BiosMemoryMap[TC_MAX_MEMORY_MAP_SIZE];
static size_t BiosMemoryMapSize;
static void CreateBootLoaderMemoryMapEntry (BiosMemoryMapEntry *newMapEntry, uint32 bootLoaderStart)
{
newMapEntry->Type = 0x2;
newMapEntry->BaseAddress.HighPart = 0;
newMapEntry->BaseAddress.LowPart = bootLoaderStart;
newMapEntry->Length.HighPart = 0;
newMapEntry->Length.LowPart = TC_BOOT_MEMORY_REQUIRED * 1024UL;
}
static bool CreateNewBiosMemoryMap ()
{
// Create a new BIOS memory map presenting the memory area of the loader as reserved
BiosMemoryMapSize = 0;
BiosMemoryMapEntry entry;
BiosMemoryMapEntry *newMapEntry = BiosMemoryMap;
const BiosMemoryMapEntry *mapEnd = BiosMemoryMap + TC_MAX_MEMORY_MAP_SIZE;
uint64 bootLoaderStart;
bootLoaderStart.HighPart = 0;
uint16 codeSeg;
__asm mov codeSeg, cs
bootLoaderStart.LowPart = GetLinearAddress (codeSeg, 0);
uint64 bootLoaderEnd;
bootLoaderEnd.HighPart = 0;
bootLoaderEnd.LowPart = bootLoaderStart.LowPart + TC_BOOT_MEMORY_REQUIRED * 1024UL;
bool loaderEntryInserted = false;
if (GetFirstBiosMemoryMapEntry (entry))
{
do
{
uint64 entryEnd = entry.BaseAddress + entry.Length;
if (entry.Type == 0x1 && RegionsIntersect (bootLoaderStart, TC_BOOT_MEMORY_REQUIRED * 1024UL, entry.BaseAddress, entryEnd - 1))
{
// Free map entry covers the boot loader area
if (entry.BaseAddress < bootLoaderStart)
{
// Create free entry below the boot loader area
if (newMapEntry >= mapEnd)
goto mapOverflow;
*newMapEntry = entry;
newMapEntry->Length = bootLoaderStart - entry.BaseAddress;
++newMapEntry;
}
if (!loaderEntryInserted)
{
// Create reserved entry for the boot loader if it has not been done yet
if (newMapEntry >= mapEnd)
goto mapOverflow;
CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
++newMapEntry;
loaderEntryInserted = true;
}
if (bootLoaderEnd < entryEnd)
{
// Create free entry above the boot loader area
if (newMapEntry >= mapEnd)
goto mapOverflow;
newMapEntry->Type = 0x1;
newMapEntry->BaseAddress = bootLoaderEnd;
newMapEntry->Length = entryEnd - bootLoaderEnd;
++newMapEntry;
}
}
else
{
if (newMapEntry >= mapEnd)
goto mapOverflow;
if (!loaderEntryInserted && entry.BaseAddress > bootLoaderStart)
{
// Create reserved entry for the boot loader if it has not been done yet
CreateBootLoaderMemoryMapEntry (newMapEntry, bootLoaderStart.LowPart);
++newMapEntry;
loaderEntryInserted = true;
}
// Copy map entry
*newMapEntry++ = entry;
}
} while (GetNextBiosMemoryMapEntry (entry));
}
BiosMemoryMapSize = newMapEntry - BiosMemoryMap;
return true;
mapOverflow:
size_t overSize = 0;
while (GetNextBiosMemoryMapEntry (entry))
{
++overSize;
}
PrintErrorNoEndl ("MMP:");
Print (overSize);
PrintEndl();
return false;
}
bool Int15Filter ()
{
CheckStack();
#ifdef TC_TRACE_INT15
DisableScreenOutput();
Print ("15-");
PrintHex (IntRegisters.AX);
Print (" SS:"); PrintHex (IntRegisters.SS);
uint16 spdbg;
__asm mov spdbg, sp
PrintChar (' ');
PrintHex (spdbg);
PrintChar ('<'); PrintHex (TC_BOOT_LOADER_STACK_TOP);
Print (" EAX:"); PrintHex (IntRegisters.EAX);
Print (" EBX:"); PrintHex (IntRegisters.EBX);
Print (" ECX:"); PrintHex (IntRegisters.ECX);
Print (" EDX:"); PrintHex (IntRegisters.EDX);
Print (" DI:"); PrintHex (IntRegisters.DI);
PrintEndl();
#endif
if (IntRegisters.EBX >= BiosMemoryMapSize)
{
IntRegisters.Flags |= TC_X86_CARRY_FLAG;
IntRegisters.EBX = 0;
IntRegisters.AX = -1;
}
else
{
CopyMemory ((byte *) &BiosMemoryMap[IntRegisters.EBX], IntRegisters.ES, IntRegisters.DI, sizeof (BiosMemoryMap[0]));
IntRegisters.Flags &= ~TC_X86_CARRY_FLAG;
IntRegisters.EAX = 0x534D4150UL;
++IntRegisters.EBX;
if (IntRegisters.EBX >= BiosMemoryMapSize)
IntRegisters.EBX = 0;
IntRegisters.ECX = sizeof (BiosMemoryMap[0]);
}
if (IntRegisters.EBX == 0 && !(BootSectorFlags & TC_BOOT_CFG_FLAG_WINDOWS_VISTA_OR_LATER))
{
// Uninstall filter when the modified map has been issued three times to prevent
// problems with hardware drivers on some notebooks running Windows XP.
static int CompleteMapIssueCount = 0;
if (++CompleteMapIssueCount >= 3)
{
__asm
{
cli
push es
lea si, OriginalInt15Handler
xor ax, ax
mov es, ax
mov di, 0x15 * 4
mov ax, [si]
mov es:[di], ax
mov ax, [si + 2]
mov es:[di + 2], ax
pop es
sti
}
}
}
#ifdef TC_TRACE_INT15
BiosMemoryMapEntry entry;
CopyMemory (IntRegisters.ES, IntRegisters.DI, (byte *) &entry, sizeof (entry));
PrintHex (entry.Type); PrintChar (' ');
PrintHex (entry.BaseAddress); PrintChar (' ');
PrintHex (entry.Length); PrintChar (' ');
PrintHex (entry.BaseAddress + entry.Length); PrintEndl();
Print ("EAX:"); PrintHex (IntRegisters.EAX);
Print (" EBX:"); PrintHex (IntRegisters.EBX);
Print (" ECX:"); PrintHex (IntRegisters.ECX);
Print (" EDX:"); PrintHex (IntRegisters.EDX);
Print (" DI:"); PrintHex (IntRegisters.DI);
Print (" FL:"); PrintHex (IntRegisters.Flags);
PrintEndl (2);
#endif
#ifdef TC_TRACE_INT15
EnableScreenOutput();
#endif
return false;
}
void IntFilterEntry ()
{
// No automatic variables should be used in this scope as SS may change
static uint16 OrigStackPointer;
static uint16 OrigStackSegment;
__asm
{
pushf
pushad
cli
mov cs:IntRegisters.DI, di
lea di, cs:IntRegisters.EAX
TC_ASM_EMIT4 (66,2E,89,05) // mov [cs:di], eax
lea di, cs:IntRegisters.EBX
TC_ASM_EMIT4 (66,2E,89,1D) // mov [cs:di], ebx
lea di, cs:IntRegisters.ECX
TC_ASM_EMIT4 (66,2E,89,0D) // mov [cs:di], ecx
lea di, cs:IntRegisters.EDX
TC_ASM_EMIT4 (66,2E,89,15) // mov [cs:di], edx
mov ax, [bp + 8]
mov cs:IntRegisters.Flags, ax
mov cs:IntRegisters.SI, si
mov si, [bp + 2] // Int number
mov cs:IntRegisters.DS, ds
mov cs:IntRegisters.ES, es
mov cs:IntRegisters.SS, ss
// Compiler assumes SS == DS - use our stack if this condition is not met
mov ax, ss
mov bx, cs
cmp ax, bx
jz stack_ok
mov cs:OrigStackPointer, sp
mov cs:OrigStackSegment, ss
mov ax, cs
mov ss, ax
mov sp, TC_BOOT_LOADER_STACK_TOP
stack_ok:
// DS = CS
push ds
push es
mov ax, cs
mov ds, ax
mov es, ax
push si // Int number
// Filter request
cmp si, 0x15
je filter15
cmp si, 0x13
jne $
call Int13Filter
jmp s0
filter15:
call Int15Filter
s0:
pop si // Int number
pop es
pop ds
// Restore original SS:SP if our stack is empty
cli
mov bx, TC_BOOT_LOADER_STACK_TOP
cmp bx, sp
jnz stack_in_use
mov ss, cs:OrigStackSegment
mov sp, cs:OrigStackPointer
stack_in_use:
test ax, ax // passOriginalRequest
jnz pass_request
// Return results of filtered request
popad
popf
mov ax, cs:IntRegisters.Flags
mov [bp + 8], ax
leave
lea di, cs:IntRegisters.EAX
TC_ASM_EMIT4 (66,2E,8B,05) // mov eax, [cs:di]
lea di, cs:IntRegisters.EBX
TC_ASM_EMIT4 (66,2E,8B,1D) // mov ebx, [cs:di]
lea di, cs:IntRegisters.ECX
TC_ASM_EMIT4 (66,2E,8B,0D) // mov ecx, [cs:di]
lea di, cs:IntRegisters.EDX
TC_ASM_EMIT4 (66,2E,8B,15) // mov edx, [cs:di]
mov di, cs:IntRegisters.DI
mov si, cs:IntRegisters.SI
mov es, cs:IntRegisters.ES
mov ds, cs:IntRegisters.DS
sti
add sp, 2
iret
// Pass original request
pass_request:
sti
cmp si, 0x15
je pass15
cmp si, 0x13
jne $
popad
popf
leave
add sp, 2
jmp cs:OriginalInt13Handler
pass15:
popad
popf
leave
add sp, 2
jmp cs:OriginalInt15Handler
}
}
void Int13FilterEntry ()
{
__asm
{
leave
push 0x13
jmp IntFilterEntry
}
}
static void Int15FilterEntry ()
{
__asm
{
pushf
cmp ax, 0xe820 // Get system memory map
je filter
popf
leave
jmp cs:OriginalInt15Handler
filter:
leave
push 0x15
jmp IntFilterEntry
}
}
bool InstallInterruptFilters ()
{
#ifndef TC_WINDOWS_BOOT_RESCUE_DISK_MODE
// If the filters have already been installed, it usually indicates stack corruption
// and a consequent reentry of this routine without a system reset.
uint32 currentInt13Handler;
CopyMemory (0, 0x13 * 4, &currentInt13Handler, sizeof (currentInt13Handler));
if (currentInt13Handler == (uint32) Int13FilterEntry)
{
PrintError ("Memory corrupted");
Print (TC_BOOT_STR_UPGRADE_BIOS);
GetKeyboardChar();
return true;
}
#endif
if (!CreateNewBiosMemoryMap())
return false;
__asm
{
cli
push es
// Save original INT 13 handler
xor ax, ax
mov es, ax
mov si, 0x13 * 4
lea di, OriginalInt13Handler
mov ax, es:[si]
mov [di], ax
mov ax, es:[si + 2]
mov [di + 2], ax
// Install INT 13 filter
lea ax, Int13FilterEntry
mov es:[si], ax
mov es:[si + 2], cs
// Save original INT 15 handler
mov si, 0x15 * 4
lea di, OriginalInt15Handler
mov ax, es:[si]
mov [di], ax
mov ax, es:[si + 2]
mov [di + 2], ax
// Install INT 15 filter
lea ax, Int15FilterEntry
mov es:[si], ax
mov es:[si + 2], cs
// If the BIOS does not support system memory map (INT15 0xe820),
// set amount of available memory to CS:0000 - 0:0000
cmp BiosMemoryMapSize, 1
jg mem_map_ok
mov ax, cs
shr ax, 10 - 4 // CS * 16 / 1024
mov es:[0x413], ax // = KBytes available
mem_map_ok:
pop es
sti
}
return true;
}

View 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
View 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 ..

View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

241
src/Common/BootEncryption.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

332
src/Common/Crypto.h Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

532
src/Common/Dlgcode.h Normal file
View 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

View 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;
}

View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

68
src/Common/Format.h Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

51
src/Common/Inflate.h Normal file
View 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
View 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 (&param->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 (&param->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 (&param->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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

1
src/Common/Makefile Normal file
View File

@ -0,0 +1 @@
!INCLUDE $(NTMAKEENV)\makefile.def

422
src/Common/Password.c Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

30
src/Common/Tests.h Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

BIN
src/Common/TrueCrypt.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

1198
src/Common/Volumes.c Normal file

File diff suppressed because it is too large Load Diff

144
src/Common/Volumes.h Normal file
View 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
View 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
View 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
View 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], "&lt;"))
{
xmlText[j++] = '<';
i += 4;
continue;
}
if (BeginsWith (&t[i], "&gt;"))
{
xmlText[j++] = '>';
i += 4;
continue;
}
if (BeginsWith (&t[i], "&amp;"))
{
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, "&amp;");
textDst += 5;
continue;
case '>':
if (textDst + 5 > textDstLast)
return NULL;
strcpy (textDst, "&gt;");
textDst += 4;
continue;
case '<':
if (textDst + 5 > textDstLast)
return NULL;
strcpy (textDst, "&lt;");
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
View 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
View 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
View 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
View 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
View 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