mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-12 11:28:26 -06:00
Add original TrueCrypt 7.1a sources
This commit is contained in:
317
src/Common/Apidrvr.h
Normal file
317
src/Common/Apidrvr.h
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Boot/Windows/BootDefs.h"
|
||||
#include "Common.h"
|
||||
#include "Crypto.h"
|
||||
#include "Volumes.h"
|
||||
#include "Wipe.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* WARNING: Modifying the following values or their meanings can introduce incompatibility with previous versions. */
|
||||
|
||||
#define TC_IOCTL(CODE) (CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800 + (CODE), METHOD_BUFFERED, FILE_ANY_ACCESS))
|
||||
|
||||
#define TC_IOCTL_GET_DRIVER_VERSION TC_IOCTL (1)
|
||||
#define TC_IOCTL_GET_BOOT_LOADER_VERSION TC_IOCTL (2)
|
||||
#define TC_IOCTL_MOUNT_VOLUME TC_IOCTL (3)
|
||||
#define TC_IOCTL_DISMOUNT_VOLUME TC_IOCTL (4)
|
||||
#define TC_IOCTL_DISMOUNT_ALL_VOLUMES TC_IOCTL (5)
|
||||
#define TC_IOCTL_GET_MOUNTED_VOLUMES TC_IOCTL (6)
|
||||
#define TC_IOCTL_GET_VOLUME_PROPERTIES TC_IOCTL (7)
|
||||
#define TC_IOCTL_GET_DEVICE_REFCOUNT TC_IOCTL (8)
|
||||
#define TC_IOCTL_IS_DRIVER_UNLOAD_DISABLED TC_IOCTL (9)
|
||||
#define TC_IOCTL_IS_ANY_VOLUME_MOUNTED TC_IOCTL (10)
|
||||
#define TC_IOCTL_GET_PASSWORD_CACHE_STATUS TC_IOCTL (11)
|
||||
#define TC_IOCTL_WIPE_PASSWORD_CACHE TC_IOCTL (12)
|
||||
#define TC_IOCTL_OPEN_TEST TC_IOCTL (13)
|
||||
#define TC_IOCTL_GET_DRIVE_PARTITION_INFO TC_IOCTL (14)
|
||||
#define TC_IOCTL_GET_DRIVE_GEOMETRY TC_IOCTL (15)
|
||||
#define TC_IOCTL_PROBE_REAL_DRIVE_SIZE TC_IOCTL (16)
|
||||
#define TC_IOCTL_GET_RESOLVED_SYMLINK TC_IOCTL (17)
|
||||
#define TC_IOCTL_GET_BOOT_ENCRYPTION_STATUS TC_IOCTL (18)
|
||||
#define TC_IOCTL_BOOT_ENCRYPTION_SETUP TC_IOCTL (19)
|
||||
#define TC_IOCTL_ABORT_BOOT_ENCRYPTION_SETUP TC_IOCTL (20)
|
||||
#define TC_IOCTL_GET_BOOT_ENCRYPTION_SETUP_RESULT TC_IOCTL (21)
|
||||
#define TC_IOCTL_GET_BOOT_DRIVE_VOLUME_PROPERTIES TC_IOCTL (22)
|
||||
#define TC_IOCTL_REOPEN_BOOT_VOLUME_HEADER TC_IOCTL (23)
|
||||
#define TC_IOCTL_GET_BOOT_ENCRYPTION_ALGORITHM_NAME TC_IOCTL (24)
|
||||
#define TC_IOCTL_GET_PORTABLE_MODE_STATUS TC_IOCTL (25)
|
||||
#define TC_IOCTL_SET_PORTABLE_MODE_STATUS TC_IOCTL (26)
|
||||
#define TC_IOCTL_IS_HIDDEN_SYSTEM_RUNNING TC_IOCTL (27)
|
||||
#define TC_IOCTL_GET_SYSTEM_DRIVE_CONFIG TC_IOCTL (28)
|
||||
#define TC_IOCTL_DISK_IS_WRITABLE TC_IOCTL (29)
|
||||
#define TC_IOCTL_START_DECOY_SYSTEM_WIPE TC_IOCTL (30)
|
||||
#define TC_IOCTL_ABORT_DECOY_SYSTEM_WIPE TC_IOCTL (31)
|
||||
#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_STATUS TC_IOCTL (32)
|
||||
#define TC_IOCTL_GET_DECOY_SYSTEM_WIPE_RESULT TC_IOCTL (33)
|
||||
#define TC_IOCTL_WRITE_BOOT_DRIVE_SECTOR TC_IOCTL (34)
|
||||
#define TC_IOCTL_GET_WARNING_FLAGS TC_IOCTL (35)
|
||||
#define TC_IOCTL_SET_SYSTEM_FAVORITE_VOLUME_DIRTY TC_IOCTL (36)
|
||||
#define TC_IOCTL_REREAD_DRIVER_CONFIG TC_IOCTL (37)
|
||||
#define TC_IOCTL_GET_SYSTEM_DRIVE_DUMP_CONFIG TC_IOCTL (38)
|
||||
|
||||
// Legacy IOCTLs used before version 5.0
|
||||
#define TC_IOCTL_LEGACY_GET_DRIVER_VERSION 466968
|
||||
#define TC_IOCTL_LEGACY_GET_MOUNTED_VOLUMES 466948
|
||||
|
||||
|
||||
/* Start of driver interface structures, the size of these structures may
|
||||
change between versions; so make sure you first send DRIVER_VERSION to
|
||||
check that it's the correct device driver */
|
||||
|
||||
#pragma pack (push)
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nReturnCode; /* Return code back from driver */
|
||||
BOOL FilesystemDirty;
|
||||
BOOL VolumeMountedReadOnlyAfterAccessDenied;
|
||||
BOOL VolumeMountedReadOnlyAfterDeviceWriteProtected;
|
||||
|
||||
wchar_t wszVolume[TC_MAX_PATH]; /* Volume to be mounted */
|
||||
Password VolumePassword; /* User password */
|
||||
BOOL bCache; /* Cache passwords in driver */
|
||||
int nDosDriveNo; /* Drive number to mount */
|
||||
uint32 BytesPerSector;
|
||||
BOOL bMountReadOnly; /* Mount volume in read-only mode */
|
||||
BOOL bMountRemovable; /* Mount volume as removable media */
|
||||
BOOL bExclusiveAccess; /* Open host file/device in exclusive access mode */
|
||||
BOOL bMountManager; /* Announce volume to mount manager */
|
||||
BOOL bPreserveTimestamp; /* Preserve file container timestamp */
|
||||
BOOL bPartitionInInactiveSysEncScope; /* If TRUE, we are to attempt to mount a partition located on an encrypted system drive without pre-boot authentication. */
|
||||
int nPartitionInInactiveSysEncScopeDriveNo; /* If bPartitionInInactiveSysEncScope is TRUE, this contains the drive number of the system drive on which the partition is located. */
|
||||
BOOL SystemFavorite;
|
||||
// Hidden volume protection
|
||||
BOOL bProtectHiddenVolume; /* TRUE if the user wants the hidden volume within this volume to be protected against being overwritten (damaged) */
|
||||
Password ProtectedHidVolPassword; /* Password to the hidden volume to be protected against overwriting */
|
||||
BOOL UseBackupHeader;
|
||||
BOOL RecoveryMode;
|
||||
} MOUNT_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nDosDriveNo; /* Drive letter to unmount */
|
||||
BOOL ignoreOpenFiles;
|
||||
BOOL HiddenVolumeProtectionTriggered;
|
||||
int nReturnCode; /* Return code back from driver */
|
||||
} UNMOUNT_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned __int32 ulMountedDrives; /* Bitfield of all mounted drive letters */
|
||||
wchar_t wszVolume[26][TC_MAX_PATH]; /* Volume names of mounted volumes */
|
||||
unsigned __int64 diskLength[26];
|
||||
int ea[26];
|
||||
int volumeType[26]; /* Volume type (e.g. PROP_VOL_TYPE_OUTER, PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, etc.) */
|
||||
} MOUNT_LIST_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int driveNo;
|
||||
int uniqueId;
|
||||
wchar_t wszVolume[TC_MAX_PATH];
|
||||
unsigned __int64 diskLength;
|
||||
int ea;
|
||||
int mode;
|
||||
int pkcs5;
|
||||
int pkcs5Iterations;
|
||||
BOOL hiddenVolume;
|
||||
BOOL readOnly;
|
||||
BOOL removable;
|
||||
BOOL partitionInInactiveSysEncScope;
|
||||
#if 0
|
||||
unsigned __int64 volumeCreationTime; // Deprecated in v6.0
|
||||
unsigned __int64 headerCreationTime; // Deprecated in v6.0
|
||||
#endif
|
||||
uint32 volumeHeaderFlags;
|
||||
unsigned __int64 totalBytesRead;
|
||||
unsigned __int64 totalBytesWritten;
|
||||
int hiddenVolProtection; /* Hidden volume protection status (e.g. HIDVOL_PROT_STATUS_NONE, HIDVOL_PROT_STATUS_ACTIVE, etc.) */
|
||||
int volFormatVersion;
|
||||
} VOLUME_PROPERTIES_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR symLinkName[TC_MAX_PATH];
|
||||
WCHAR targetName[TC_MAX_PATH];
|
||||
} RESOLVE_SYMLINK_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR deviceName[TC_MAX_PATH];
|
||||
PARTITION_INFORMATION partInfo;
|
||||
BOOL IsGPT;
|
||||
BOOL IsDynamic;
|
||||
}
|
||||
DISK_PARTITION_INFO_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR deviceName[TC_MAX_PATH];
|
||||
DISK_GEOMETRY diskGeometry;
|
||||
}
|
||||
DISK_GEOMETRY_STRUCT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR DeviceName[TC_MAX_PATH];
|
||||
LARGE_INTEGER RealDriveSize;
|
||||
BOOL TimeOut;
|
||||
} ProbeRealDriveSizeRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wchar_t wszFileName[TC_MAX_PATH]; // Volume to be "open tested"
|
||||
BOOL bDetectTCBootLoader; // Whether the driver is to determine if the first sector contains a portion of the TrueCrypt Boot Loader
|
||||
BOOL TCBootLoaderDetected;
|
||||
BOOL DetectFilesystem;
|
||||
BOOL FilesystemDetected;
|
||||
} OPEN_TEST_STRUCT;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SetupNone = 0,
|
||||
SetupEncryption,
|
||||
SetupDecryption
|
||||
} BootEncryptionSetupMode;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// New fields must be added at the end of the structure to maintain compatibility with previous versions
|
||||
BOOL DeviceFilterActive;
|
||||
|
||||
uint16 BootLoaderVersion;
|
||||
|
||||
BOOL DriveMounted;
|
||||
BOOL VolumeHeaderPresent;
|
||||
BOOL DriveEncrypted;
|
||||
|
||||
LARGE_INTEGER BootDriveLength;
|
||||
|
||||
int64 ConfiguredEncryptedAreaStart;
|
||||
int64 ConfiguredEncryptedAreaEnd;
|
||||
int64 EncryptedAreaStart;
|
||||
int64 EncryptedAreaEnd;
|
||||
|
||||
uint32 VolumeHeaderSaltCrc32;
|
||||
|
||||
BOOL SetupInProgress;
|
||||
BootEncryptionSetupMode SetupMode;
|
||||
BOOL TransformWaitingForIdle;
|
||||
|
||||
uint32 HibernationPreventionCount;
|
||||
|
||||
BOOL HiddenSystem;
|
||||
int64 HiddenSystemPartitionStart;
|
||||
|
||||
// Number of times the filter driver answered that an unencrypted volume
|
||||
// is read-only (or mounted an outer/normal TrueCrypt volume as read only)
|
||||
uint32 HiddenSysLeakProtectionCount;
|
||||
|
||||
} BootEncryptionStatus;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BootEncryptionSetupMode SetupMode;
|
||||
WipeAlgorithmId WipeAlgorithm;
|
||||
BOOL ZeroUnreadableSectors;
|
||||
BOOL DiscardUnreadableEncryptedSectors;
|
||||
} BootEncryptionSetupRequest;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Password VolumePassword;
|
||||
} ReopenBootVolumeHeaderRequest;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char BootEncryptionAlgorithmName[256];
|
||||
} GetBootEncryptionAlgorithmNameRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wchar_t DevicePath[TC_MAX_PATH];
|
||||
byte Configuration;
|
||||
BOOL DriveIsDynamic;
|
||||
uint16 BootLoaderVersion;
|
||||
byte UserConfiguration;
|
||||
char CustomUserMessage[TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH + 1];
|
||||
} GetSystemDriveConfigurationRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WipeAlgorithmId WipeAlgorithm;
|
||||
byte WipeKey[MASTER_KEYDATA_SIZE];
|
||||
} WipeDecoySystemRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL WipeInProgress;
|
||||
WipeAlgorithmId WipeAlgorithm;
|
||||
int64 WipedAreaEnd;
|
||||
} DecoySystemWipeStatus;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LARGE_INTEGER Offset;
|
||||
byte Data[TC_SECTOR_SIZE_BIOS];
|
||||
} WriteBootDriveSectorRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL PagingFileCreationPrevented;
|
||||
BOOL SystemFavoriteVolumeDirty;
|
||||
} GetWarningFlagsRequest;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct _DriveFilterExtension *BootDriveFilterExtension;
|
||||
BOOL HwEncryptionEnabled;
|
||||
} GetSystemDriveDumpConfigRequest;
|
||||
|
||||
#pragma pack (pop)
|
||||
|
||||
#ifdef TC_WINDOWS_DRIVER
|
||||
#define DRIVER_STR WIDE
|
||||
#else
|
||||
#define DRIVER_STR
|
||||
#endif
|
||||
|
||||
#define TC_UNIQUE_ID_PREFIX "TrueCryptVolume"
|
||||
#define TC_MOUNT_PREFIX L"\\Device\\TrueCryptVolume"
|
||||
|
||||
#define NT_MOUNT_PREFIX DRIVER_STR("\\Device\\TrueCryptVolume")
|
||||
#define NT_ROOT_PREFIX DRIVER_STR("\\Device\\TrueCrypt")
|
||||
#define DOS_MOUNT_PREFIX DRIVER_STR("\\DosDevices\\")
|
||||
#define DOS_ROOT_PREFIX DRIVER_STR("\\DosDevices\\TrueCrypt")
|
||||
#define WIN32_ROOT_PREFIX DRIVER_STR("\\\\.\\TrueCrypt")
|
||||
|
||||
#define TC_DRIVER_CONFIG_REG_VALUE_NAME DRIVER_STR("TrueCryptConfig")
|
||||
#define TC_ENCRYPTION_FREE_CPU_COUNT_REG_VALUE_NAME DRIVER_STR("TrueCryptEncryptionFreeCpuCount")
|
||||
|
||||
// WARNING: Modifying the following values can introduce incompatibility with previous versions.
|
||||
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD 0x1
|
||||
#define TC_DRIVER_CONFIG_CACHE_BOOT_PASSWORD_FOR_SYS_FAVORITES 0x2
|
||||
#define TC_DRIVER_CONFIG_DISABLE_NONADMIN_SYS_FAVORITES_ACCESS 0x4
|
||||
#define TC_DRIVER_CONFIG_DISABLE_HARDWARE_ENCRYPTION 0x8
|
||||
|
||||
#endif /* _WIN32 */
|
||||
231
src/Common/BaseCom.cpp
Normal file
231
src/Common/BaseCom.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <atlcomcli.h>
|
||||
#include <atlconv.h>
|
||||
#include <comutil.h>
|
||||
#include <windows.h>
|
||||
#include "BaseCom.h"
|
||||
#include "BootEncryption.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Registry.h"
|
||||
|
||||
using namespace TrueCrypt;
|
||||
|
||||
HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv)
|
||||
{
|
||||
WCHAR monikerName[1024];
|
||||
WCHAR clsid[1024];
|
||||
BIND_OPTS3 bo;
|
||||
|
||||
StringFromGUID2 (guid, clsid, sizeof (clsid) / 2);
|
||||
swprintf_s (monikerName, sizeof (monikerName) / 2, L"Elevation:Administrator!new:%s", clsid);
|
||||
|
||||
memset (&bo, 0, sizeof (bo));
|
||||
bo.cbStruct = sizeof (bo);
|
||||
bo.hwnd = hwnd;
|
||||
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
|
||||
|
||||
// Prevent the GUI from being half-rendered when the UAC prompt "freezes" it
|
||||
ProcessPaintMessages (hwnd, 5000);
|
||||
|
||||
return CoGetObject (monikerName, &bo, iid, ppv);
|
||||
}
|
||||
|
||||
|
||||
BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer)
|
||||
{
|
||||
BOOL r;
|
||||
|
||||
if (IsUacSupported ())
|
||||
r = CreateElevatedComObject (hWnd, clsid, iid, tcServer) == S_OK;
|
||||
else
|
||||
r = CoCreateInstance (clsid, NULL, CLSCTX_LOCAL_SERVER, iid, tcServer) == S_OK;
|
||||
|
||||
if (!r)
|
||||
Error ("UAC_INIT_ERROR");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::CallDriver (DWORD ioctl, BSTR input, BSTR *output)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.CallDriver (ioctl,
|
||||
(BYTE *) input, !(BYTE *) input ? 0 : ((DWORD *) ((BYTE *) input))[-1],
|
||||
(BYTE *) *output, !(BYTE *) *output ? 0 : ((DWORD *) ((BYTE *) *output))[-1]);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::CopyFile (BSTR sourceFile, BSTR destinationFile)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
if (!::CopyFile (CW2A (sourceFile), CW2A (destinationFile), FALSE))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::DeleteFile (BSTR file)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
if (!::DeleteFile (CW2A (file)))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
BOOL BaseCom::IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly)
|
||||
{
|
||||
return ::IsPagingFileActive (checkNonWindowsPartitionsOnly);
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
|
||||
try
|
||||
{
|
||||
auto_ptr <File> file (device ? new Device (string (CW2A (filePath)), !write) : new File (string (CW2A (filePath)), !write));
|
||||
file->SeekAt (offset);
|
||||
|
||||
if (write)
|
||||
{
|
||||
file->Write ((BYTE *) *bufferBstr, size);
|
||||
*sizeDone = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
*sizeDone = file->Read ((BYTE *) *bufferBstr, size);
|
||||
}
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::RegisterFilterDriver (BOOL registerDriver, int filterType)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.RegisterFilterDriver (registerDriver ? true : false, (BootEncryption::FilterType) filterType);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::RegisterSystemFavoritesService (BOOL registerService)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.RegisterSystemFavoritesService (registerService);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::SetDriverServiceStartType (DWORD startType)
|
||||
{
|
||||
try
|
||||
{
|
||||
BootEncryption bootEnc (NULL);
|
||||
bootEnc.SetDriverServiceStartType (startType);
|
||||
}
|
||||
catch (SystemException &)
|
||||
{
|
||||
return GetLastError();
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return ERROR_EXCEPTION_IN_SERVICE;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DWORD BaseCom::WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value)
|
||||
{
|
||||
USES_CONVERSION;
|
||||
if (!::WriteLocalMachineRegistryDword (CW2A (keyPath), CW2A (valueName), value))
|
||||
return GetLastError();
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
115
src/Common/BaseCom.h
Normal file
115
src/Common/BaseCom.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
Copyright (c) 2007-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_BASE_COM
|
||||
#define TC_HEADER_BASE_COM
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
template <class TClass>
|
||||
class TrueCryptFactory : public IClassFactory
|
||||
{
|
||||
|
||||
public:
|
||||
TrueCryptFactory (DWORD messageThreadId) :
|
||||
RefCount (1), ServerLockCount (0), MessageThreadId (messageThreadId) { }
|
||||
|
||||
~TrueCryptFactory () { }
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef ()
|
||||
{
|
||||
return InterlockedIncrement (&RefCount) - 1;
|
||||
}
|
||||
|
||||
virtual ULONG STDMETHODCALLTYPE Release ()
|
||||
{
|
||||
ULONG r = InterlockedDecrement (&RefCount) + 1;
|
||||
|
||||
if (r == 0)
|
||||
delete this;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void **ppvObject)
|
||||
{
|
||||
if (riid == IID_IUnknown || riid == IID_IClassFactory)
|
||||
*ppvObject = this;
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
AddRef ();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateInstance (IUnknown *pUnkOuter, REFIID riid, void **ppvObject)
|
||||
{
|
||||
if (pUnkOuter != NULL)
|
||||
return CLASS_E_NOAGGREGATION;
|
||||
|
||||
TClass *tc = new TClass (MessageThreadId);
|
||||
if (tc == NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
HRESULT hr = tc->QueryInterface (riid, ppvObject);
|
||||
|
||||
if (hr)
|
||||
delete tc;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE LockServer (BOOL fLock)
|
||||
{
|
||||
if (fLock)
|
||||
{
|
||||
InterlockedIncrement (&ServerLockCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!InterlockedDecrement (&ServerLockCount))
|
||||
PostThreadMessage (MessageThreadId, WM_APP, 0, 0);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
virtual bool IsServerLocked ()
|
||||
{
|
||||
return ServerLockCount > 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
DWORD MessageThreadId;
|
||||
LONG RefCount;
|
||||
LONG ServerLockCount;
|
||||
};
|
||||
|
||||
|
||||
class BaseCom
|
||||
{
|
||||
public:
|
||||
static DWORD CallDriver (DWORD ioctl, BSTR input, BSTR *output);
|
||||
static DWORD CopyFile (BSTR sourceFile, BSTR destinationFile);
|
||||
static DWORD DeleteFile (BSTR file);
|
||||
static BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
|
||||
static DWORD ReadWriteFile (BOOL write, BOOL device, BSTR filePath, BSTR *bufferBstr, unsigned __int64 offset, unsigned __int32 size, DWORD *sizeDone);
|
||||
static DWORD RegisterFilterDriver (BOOL registerDriver, int filterType);
|
||||
static DWORD RegisterSystemFavoritesService (BOOL registerService);
|
||||
static DWORD SetDriverServiceStartType (DWORD startType);
|
||||
static DWORD WriteLocalMachineRegistryDwordValue (BSTR keyPath, BSTR valueName, DWORD value);
|
||||
};
|
||||
|
||||
|
||||
BOOL ComGetInstanceBase (HWND hWnd, REFCLSID clsid, REFIID iid, void **tcServer);
|
||||
HRESULT CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv);
|
||||
|
||||
#endif // TC_HEADER_BASE_COM
|
||||
2457
src/Common/BootEncryption.cpp
Normal file
2457
src/Common/BootEncryption.cpp
Normal file
File diff suppressed because it is too large
Load Diff
241
src/Common/BootEncryption.h
Normal file
241
src/Common/BootEncryption.h
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_BootEncryption
|
||||
#define TC_HEADER_Common_BootEncryption
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Exception.h"
|
||||
#include "Platform/PlatformBase.h"
|
||||
#include "Volumes.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
class File
|
||||
{
|
||||
public:
|
||||
File () : FileOpen (false) { }
|
||||
File (string path, bool readOnly = false, bool create = false);
|
||||
~File () { Close(); }
|
||||
|
||||
void Close ();
|
||||
DWORD Read (byte *buffer, DWORD size);
|
||||
void Write (byte *buffer, DWORD size);
|
||||
void SeekAt (int64 position);
|
||||
|
||||
protected:
|
||||
bool Elevated;
|
||||
bool FileOpen;
|
||||
uint64 FilePointerPosition;
|
||||
HANDLE Handle;
|
||||
bool IsDevice;
|
||||
string Path;
|
||||
};
|
||||
|
||||
|
||||
class Device : public File
|
||||
{
|
||||
public:
|
||||
Device (string path, bool readOnly = false);
|
||||
};
|
||||
|
||||
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
Buffer (size_t size) : DataSize (size)
|
||||
{
|
||||
DataPtr = new byte[size];
|
||||
if (!DataPtr)
|
||||
throw bad_alloc();
|
||||
}
|
||||
|
||||
~Buffer () { delete[] DataPtr; }
|
||||
byte *Ptr () const { return DataPtr; }
|
||||
size_t Size () const { return DataSize; }
|
||||
|
||||
protected:
|
||||
byte *DataPtr;
|
||||
size_t DataSize;
|
||||
};
|
||||
|
||||
|
||||
struct Partition
|
||||
{
|
||||
string DevicePath;
|
||||
PARTITION_INFORMATION Info;
|
||||
string MountPoint;
|
||||
size_t Number;
|
||||
BOOL IsGPT;
|
||||
wstring VolumeNameId;
|
||||
};
|
||||
|
||||
typedef list <Partition> PartitionList;
|
||||
|
||||
#pragma pack (push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct PartitionEntryMBR
|
||||
{
|
||||
byte BootIndicator;
|
||||
|
||||
byte StartHead;
|
||||
byte StartCylSector;
|
||||
byte StartCylinder;
|
||||
|
||||
byte Type;
|
||||
|
||||
byte EndHead;
|
||||
byte EndSector;
|
||||
byte EndCylinder;
|
||||
|
||||
uint32 StartLBA;
|
||||
uint32 SectorCountLBA;
|
||||
};
|
||||
|
||||
struct MBR
|
||||
{
|
||||
byte Code[446];
|
||||
PartitionEntryMBR Partitions[4];
|
||||
uint16 Signature;
|
||||
};
|
||||
|
||||
#pragma pack (pop)
|
||||
|
||||
struct SystemDriveConfiguration
|
||||
{
|
||||
string DeviceKernelPath;
|
||||
string DevicePath;
|
||||
int DriveNumber;
|
||||
Partition DrivePartition;
|
||||
bool ExtraBootPartitionPresent;
|
||||
int64 InitialUnallocatedSpace;
|
||||
PartitionList Partitions;
|
||||
Partition SystemPartition;
|
||||
int64 TotalUnallocatedSpace;
|
||||
bool SystemLoaderPresent;
|
||||
};
|
||||
|
||||
class BootEncryption
|
||||
{
|
||||
public:
|
||||
BootEncryption (HWND parent);
|
||||
~BootEncryption ();
|
||||
|
||||
enum FilterType
|
||||
{
|
||||
DriveFilter,
|
||||
VolumeFilter,
|
||||
DumpFilter
|
||||
};
|
||||
|
||||
void AbortDecoyOSWipe ();
|
||||
void AbortSetup ();
|
||||
void AbortSetupWait ();
|
||||
void CallDriver (DWORD ioctl, void *input = nullptr, DWORD inputSize = 0, void *output = nullptr, DWORD outputSize = 0);
|
||||
int ChangePassword (Password *oldPassword, Password *newPassword, int pkcs5);
|
||||
void CheckDecoyOSWipeResult ();
|
||||
void CheckEncryptionSetupResult ();
|
||||
void CheckRequirements ();
|
||||
void CheckRequirementsHiddenOS ();
|
||||
void CopyFileAdmin (const string &sourceFile, const string &destinationFile);
|
||||
void CreateRescueIsoImage (bool initialSetup, const string &isoImagePath);
|
||||
void Deinstall (bool displayWaitDialog = false);
|
||||
void DeleteFileAdmin (const string &file);
|
||||
DecoySystemWipeStatus GetDecoyOSWipeStatus ();
|
||||
DWORD GetDriverServiceStartType ();
|
||||
unsigned int GetHiddenOSCreationPhase ();
|
||||
uint16 GetInstalledBootLoaderVersion ();
|
||||
Partition GetPartitionForHiddenOS ();
|
||||
bool IsBootLoaderOnDrive (char *devicePath);
|
||||
BootEncryptionStatus GetStatus ();
|
||||
string GetTempPath ();
|
||||
void GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties);
|
||||
SystemDriveConfiguration GetSystemDriveConfiguration ();
|
||||
void Install (bool hiddenSystem);
|
||||
void InstallBootLoader (bool preserveUserConfig = false, bool hiddenOSCreation = false);
|
||||
void InvalidateCachedSysDriveProperties ();
|
||||
bool IsCDDrivePresent ();
|
||||
bool IsHiddenSystemRunning ();
|
||||
bool IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
|
||||
void PrepareHiddenOSCreation (int ea, int mode, int pkcs5);
|
||||
void PrepareInstallation (bool systemPartitionOnly, Password &password, int ea, int mode, int pkcs5, const string &rescueIsoImagePath);
|
||||
void ProbeRealSystemDriveSize ();
|
||||
void ReadBootSectorConfig (byte *config, size_t bufLength, byte *userConfig = nullptr, string *customUserMessage = nullptr, uint16 *bootLoaderVersion = nullptr);
|
||||
uint32 ReadDriverConfigurationFlags ();
|
||||
void RegisterBootDriver (bool hiddenSystem);
|
||||
void RegisterFilterDriver (bool registerDriver, FilterType filterType);
|
||||
void RegisterSystemFavoritesService (BOOL registerService);
|
||||
void RenameDeprecatedSystemLoaderBackup ();
|
||||
bool RestartComputer (void);
|
||||
void InitialSecurityChecksForHiddenOS ();
|
||||
void RestrictPagingFilesToSystemPartition ();
|
||||
void SetDriverConfigurationFlag (uint32 flag, bool state);
|
||||
void SetDriverServiceStartType (DWORD startType);
|
||||
void SetHiddenOSCreationPhase (unsigned int newPhase);
|
||||
void StartDecryption (BOOL discardUnreadableEncryptedSectors);
|
||||
void StartDecoyOSWipe (WipeAlgorithmId wipeAlgorithm);
|
||||
void StartEncryption (WipeAlgorithmId wipeAlgorithm, bool zeroUnreadableSectors);
|
||||
bool SystemDriveContainsPartitionType (byte type);
|
||||
bool SystemDriveContainsExtendedPartition ();
|
||||
bool SystemDriveContainsNonStandardPartitions ();
|
||||
bool SystemPartitionCoversWholeDrive ();
|
||||
bool SystemDriveIsDynamic ();
|
||||
bool VerifyRescueDisk ();
|
||||
void WipeHiddenOSCreationConfig ();
|
||||
void WriteBootDriveSector (uint64 offset, byte *data);
|
||||
void WriteBootSectorConfig (const byte newConfig[]);
|
||||
void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage);
|
||||
void WriteLocalMachineRegistryDwordValue (char *keyPath, char *valueName, DWORD value);
|
||||
|
||||
protected:
|
||||
static const uint32 RescueIsoImageSize = 1835008; // Size of ISO9660 image with bootable emulated 1.44MB floppy disk image
|
||||
|
||||
void BackupSystemLoader ();
|
||||
void CreateBootLoaderInMemory (byte *buffer, size_t bufferSize, bool rescueDisk, bool hiddenOSCreation = false);
|
||||
void CreateVolumeHeader (uint64 volumeSize, uint64 encryptedAreaStart, Password *password, int ea, int mode, int pkcs5);
|
||||
string GetSystemLoaderBackupPath ();
|
||||
uint32 GetChecksum (byte *data, size_t size);
|
||||
DISK_GEOMETRY GetDriveGeometry (int driveNumber);
|
||||
PartitionList GetDrivePartitions (int driveNumber);
|
||||
wstring GetRemarksOnHiddenOS ();
|
||||
string GetWindowsDirectory ();
|
||||
void RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid = nullptr);
|
||||
void RestoreSystemLoader ();
|
||||
void InstallVolumeHeader ();
|
||||
|
||||
HWND ParentWindow;
|
||||
SystemDriveConfiguration DriveConfig;
|
||||
int SelectedEncryptionAlgorithmId;
|
||||
Partition HiddenOSCandidatePartition;
|
||||
byte *RescueIsoImage;
|
||||
byte RescueVolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
|
||||
byte VolumeHeader[TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE];
|
||||
bool DriveConfigValid;
|
||||
bool RealSystemDriveSizeValid;
|
||||
bool RescueVolumeHeaderValid;
|
||||
bool VolumeHeaderValid;
|
||||
};
|
||||
}
|
||||
|
||||
#define TC_ABORT_TRANSFORM_WAIT_INTERVAL 10
|
||||
|
||||
#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_NTFS 2.1
|
||||
#define MIN_HIDDENOS_DECOY_PARTITION_SIZE_RATIO_FAT 1.05
|
||||
|
||||
#define TC_SYS_BOOT_LOADER_BACKUP_NAME "Original System Loader"
|
||||
#define TC_SYS_BOOT_LOADER_BACKUP_NAME_LEGACY "Original System Loader.bak" // Deprecated to prevent removal by some "cleaners"
|
||||
|
||||
#define TC_SYSTEM_FAVORITES_SERVICE_NAME TC_APP_NAME "SystemFavorites"
|
||||
#define TC_SYSTEM_FAVORITES_SERVICE_LOAD_ORDER_GROUP "Event Log"
|
||||
#define TC_SYSTEM_FAVORITES_SERVICE_CMDLINE_OPTION "/systemFavoritesService"
|
||||
|
||||
#endif // TC_HEADER_Common_BootEncryption
|
||||
94
src/Common/Cache.c
Normal file
94
src/Common/Cache.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crypto.h"
|
||||
#include "Fat.h"
|
||||
#include "Volumes.h"
|
||||
#include "Apidrvr.h"
|
||||
#include "Common.h"
|
||||
#include "Cache.h"
|
||||
|
||||
Password CachedPasswords[CACHE_SIZE];
|
||||
int cacheEmpty = 1;
|
||||
static int nPasswordIdx = 0;
|
||||
|
||||
int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, PCRYPTO_INFO *retInfo)
|
||||
{
|
||||
int nReturnCode = ERR_PASSWORD_WRONG;
|
||||
int i;
|
||||
|
||||
/* Attempt to recognize volume using mount password */
|
||||
if (password->Length > 0)
|
||||
{
|
||||
nReturnCode = ReadVolumeHeader (bBoot, header, password, retInfo, NULL);
|
||||
|
||||
/* Save mount passwords back into cache if asked to do so */
|
||||
if (bCache && (nReturnCode == 0 || nReturnCode == ERR_CIPHER_INIT_WEAK_KEY))
|
||||
{
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == CACHE_SIZE)
|
||||
{
|
||||
/* Store the password */
|
||||
CachedPasswords[nPasswordIdx] = *password;
|
||||
|
||||
/* Try another slot */
|
||||
nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE;
|
||||
|
||||
cacheEmpty = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!cacheEmpty)
|
||||
{
|
||||
/* Attempt to recognize volume using cached passwords */
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
if (CachedPasswords[i].Length > 0)
|
||||
{
|
||||
nReturnCode = ReadVolumeHeader (bBoot, header, &CachedPasswords[i], retInfo, NULL);
|
||||
|
||||
if (nReturnCode != ERR_PASSWORD_WRONG)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nReturnCode;
|
||||
}
|
||||
|
||||
|
||||
void AddPasswordToCache (Password *password)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < CACHE_SIZE; i++)
|
||||
{
|
||||
if (memcmp (&CachedPasswords[i], password, sizeof (Password)) == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
CachedPasswords[nPasswordIdx] = *password;
|
||||
nPasswordIdx = (nPasswordIdx + 1) % CACHE_SIZE;
|
||||
cacheEmpty = 0;
|
||||
}
|
||||
|
||||
|
||||
void WipeCache ()
|
||||
{
|
||||
burn (CachedPasswords, sizeof (CachedPasswords));
|
||||
nPasswordIdx = 0;
|
||||
cacheEmpty = 1;
|
||||
}
|
||||
23
src/Common/Cache.h
Normal file
23
src/Common/Cache.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#ifndef CACHE_SIZE
|
||||
/* WARNING: Changing this value might not be safe (some items may be hard coded for 4)! Inspection necessary. */
|
||||
#define CACHE_SIZE 4
|
||||
#endif
|
||||
|
||||
extern int cacheEmpty;
|
||||
|
||||
void AddPasswordToCache (Password *password);
|
||||
int ReadVolumeHeaderWCache (BOOL bBoot, BOOL bCache, char *header, Password *password, PCRYPTO_INFO *retInfo);
|
||||
void WipeCache (void);
|
||||
240
src/Common/Cmdline.c
Normal file
240
src/Common/Cmdline.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <ctype.h>
|
||||
#include "Cmdline.h"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Crypto.h"
|
||||
#include "Apidrvr.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Language.h"
|
||||
|
||||
/* Except in response to the WM_INITDIALOG message, the dialog box procedure
|
||||
should return nonzero if it processes the message, and zero if it does
|
||||
not. - see DialogProc */
|
||||
BOOL CALLBACK CommandHelpDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (lParam); /* remove warning */
|
||||
if (wParam); /* remove warning */
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
char * tmp = err_malloc(8192);
|
||||
char tmp2[MAX_PATH * 2];
|
||||
argumentspec *as;
|
||||
int i;
|
||||
|
||||
LocalizeDialog (hwndDlg, "IDD_COMMANDHELP_DLG");
|
||||
|
||||
as = (argumentspec*) lParam;
|
||||
|
||||
*tmp = 0;
|
||||
|
||||
strcpy (tmp, "Command line options:\n\n");
|
||||
for (i = 0; i < as->arg_cnt; i ++)
|
||||
{
|
||||
if (!as->args[i].Internal)
|
||||
{
|
||||
sprintf(tmp2, "%s\t%s\n", as->args[i].short_name, as->args[i].long_name);
|
||||
strcat(tmp,tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
SetWindowText (GetDlgItem (hwndDlg, IDC_COMMANDHELP_TEXT), (char*) tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
return 1;
|
||||
case WM_CLOSE:
|
||||
EndDialog (hwndDlg, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Win32CommandLine (char *lpszCommandLine, char ***lpszArgs)
|
||||
{
|
||||
int argumentCount;
|
||||
int i;
|
||||
|
||||
LPWSTR *arguments = CommandLineToArgvW (GetCommandLineW(), &argumentCount);
|
||||
if (!arguments)
|
||||
{
|
||||
handleWin32Error (NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--argumentCount;
|
||||
if (argumentCount < 1)
|
||||
{
|
||||
LocalFree (arguments);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*lpszArgs = malloc (sizeof (char *) * argumentCount);
|
||||
if (!*lpszArgs)
|
||||
AbortProcess ("OUTOFMEMORY");
|
||||
|
||||
for (i = 0; i < argumentCount; ++i)
|
||||
{
|
||||
size_t argLen = wcslen (arguments[i + 1]);
|
||||
|
||||
char *arg = malloc (argLen + 1);
|
||||
if (!arg)
|
||||
AbortProcess ("OUTOFMEMORY");
|
||||
|
||||
if (argLen > 0)
|
||||
{
|
||||
int len = WideCharToMultiByte (CP_ACP, 0, arguments[i + 1], -1, arg, argLen + 1, NULL, NULL);
|
||||
if (len == 0)
|
||||
{
|
||||
handleWin32Error (NULL);
|
||||
AbortProcessSilent();
|
||||
}
|
||||
}
|
||||
else
|
||||
arg[0] = 0;
|
||||
|
||||
(*lpszArgs)[i] = arg;
|
||||
}
|
||||
|
||||
LocalFree (arguments);
|
||||
return argumentCount;
|
||||
}
|
||||
|
||||
int GetArgSepPosOffset (char *lpszArgument)
|
||||
{
|
||||
if (lpszArgument[0] == '/')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetArgumentID (argumentspec *as, char *lpszArgument, int *nArgPos)
|
||||
{
|
||||
char szTmp[MAX_PATH * 2];
|
||||
int i;
|
||||
|
||||
i = strlen (lpszArgument);
|
||||
szTmp[i] = 0;
|
||||
while (--i >= 0)
|
||||
{
|
||||
szTmp[i] = (char) tolower (lpszArgument[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < as->arg_cnt; i++)
|
||||
{
|
||||
size_t k;
|
||||
|
||||
k = strlen (as->args[i].long_name);
|
||||
if (memcmp (as->args[i].long_name, szTmp, k * sizeof (char)) == 0)
|
||||
{
|
||||
int x;
|
||||
for (x = i + 1; x < as->arg_cnt; x++)
|
||||
{
|
||||
size_t m;
|
||||
|
||||
m = strlen (as->args[x].long_name);
|
||||
if (memcmp (as->args[x].long_name, szTmp, m * sizeof (char)) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x == as->arg_cnt)
|
||||
{
|
||||
if (strlen (lpszArgument) != k)
|
||||
*nArgPos = k;
|
||||
else
|
||||
*nArgPos = 0;
|
||||
return as->args[i].Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < as->arg_cnt; i++)
|
||||
{
|
||||
size_t k;
|
||||
|
||||
if (as->args[i].short_name[0] == 0)
|
||||
continue;
|
||||
|
||||
k = strlen (as->args[i].short_name);
|
||||
if (memcmp (as->args[i].short_name, szTmp, k * sizeof (char)) == 0)
|
||||
{
|
||||
int x;
|
||||
for (x = i + 1; x < as->arg_cnt; x++)
|
||||
{
|
||||
size_t m;
|
||||
|
||||
if (as->args[x].short_name[0] == 0)
|
||||
continue;
|
||||
|
||||
m = strlen (as->args[x].short_name);
|
||||
if (memcmp (as->args[x].short_name, szTmp, m * sizeof (char)) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (x == as->arg_cnt)
|
||||
{
|
||||
if (strlen (lpszArgument) != k)
|
||||
*nArgPos = k;
|
||||
else
|
||||
*nArgPos = 0;
|
||||
return as->args[i].Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GetArgumentValue (char **lpszCommandLineArgs, int nArgPos, int *nArgIdx,
|
||||
int nNoCommandLineArgs, char *lpszValue, int nValueSize)
|
||||
{
|
||||
*lpszValue = 0;
|
||||
|
||||
if (nArgPos)
|
||||
{
|
||||
/* Handles the case of no space between parameter code and
|
||||
value */
|
||||
strncpy (lpszValue, &lpszCommandLineArgs[*nArgIdx][nArgPos], nValueSize);
|
||||
lpszValue[nValueSize - 1] = 0;
|
||||
return HAS_ARGUMENT;
|
||||
}
|
||||
else if (*nArgIdx + 1 < nNoCommandLineArgs)
|
||||
{
|
||||
int x = GetArgSepPosOffset (lpszCommandLineArgs[*nArgIdx + 1]);
|
||||
if (x == 0)
|
||||
{
|
||||
/* Handles the case of space between parameter code
|
||||
and value */
|
||||
strncpy (lpszValue, &lpszCommandLineArgs[*nArgIdx + 1][x], nValueSize);
|
||||
lpszValue[nValueSize - 1] = 0;
|
||||
(*nArgIdx)++;
|
||||
return HAS_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
return HAS_NO_ARGUMENT;
|
||||
}
|
||||
41
src/Common/Cmdline.h
Normal file
41
src/Common/Cmdline.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HAS_ARGUMENT 1
|
||||
#define HAS_NO_ARGUMENT !HAS_ARGUMENT
|
||||
|
||||
typedef struct argument_t
|
||||
{
|
||||
int Id;
|
||||
char long_name[32];
|
||||
char short_name[8];
|
||||
BOOL Internal;
|
||||
} argument;
|
||||
|
||||
typedef struct argumentspec_t
|
||||
{
|
||||
argument *args;
|
||||
int arg_cnt;
|
||||
} argumentspec;
|
||||
|
||||
BOOL CALLBACK CommandHelpDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam );
|
||||
int Win32CommandLine ( char *lpszCommandLine , char ***lpszArgs );
|
||||
int GetArgSepPosOffset ( char *lpszArgument );
|
||||
int GetArgumentID ( argumentspec *as , char *lpszArgument , int *nArgPos );
|
||||
int GetArgumentValue ( char **lpszCommandLineArgs , int nArgPos , int *nArgIdx , int nNoCommandLineArgs , char *lpszValue , int nValueSize );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
212
src/Common/Combo.c
Normal file
212
src/Common/Combo.c
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Combo.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Xml.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#define SIZEOF_MRU_LIST 20
|
||||
|
||||
void AddComboItem (HWND hComboBox, char *lpszFileName, BOOL saveHistory)
|
||||
{
|
||||
LPARAM nIndex;
|
||||
|
||||
if (!saveHistory)
|
||||
{
|
||||
SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
|
||||
SetWindowText (hComboBox, lpszFileName);
|
||||
return;
|
||||
}
|
||||
|
||||
nIndex = SendMessage (hComboBox, CB_FINDSTRINGEXACT, (WPARAM) - 1, (LPARAM) & lpszFileName[0]);
|
||||
|
||||
if (nIndex == CB_ERR && *lpszFileName)
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) & lpszFileName[0]);
|
||||
if (nIndex != CB_ERR)
|
||||
SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) lTime);
|
||||
}
|
||||
|
||||
if (nIndex != CB_ERR && *lpszFileName)
|
||||
nIndex = SendMessage (hComboBox, CB_SETCURSEL, nIndex, 0);
|
||||
|
||||
if (*lpszFileName == 0)
|
||||
{
|
||||
SendMessage (hComboBox, CB_SETCURSEL, (WPARAM) - 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LPARAM MoveEditToCombo (HWND hComboBox, BOOL saveHistory)
|
||||
{
|
||||
char szTmp[TC_MAX_PATH] = {0};
|
||||
|
||||
if (!saveHistory)
|
||||
{
|
||||
GetWindowText (hComboBox, szTmp, sizeof (szTmp));
|
||||
SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
|
||||
SetWindowText (hComboBox, szTmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
GetWindowText (hComboBox, szTmp, sizeof (szTmp));
|
||||
|
||||
if (strlen (szTmp) > 0)
|
||||
{
|
||||
LPARAM nIndex = SendMessage (hComboBox, CB_FINDSTRINGEXACT, (WPARAM) - 1,
|
||||
(LPARAM) & szTmp[0]);
|
||||
if (nIndex == CB_ERR)
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) & szTmp[0]);
|
||||
if (nIndex != CB_ERR)
|
||||
SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (DWORD) lTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (DWORD) lTime);
|
||||
}
|
||||
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
return SendMessage (hComboBox, CB_GETCURSEL, 0, 0);
|
||||
}
|
||||
|
||||
int GetOrderComboIdx (HWND hComboBox, int *nIdxList, int nElems)
|
||||
{
|
||||
int x = (int) SendMessage (hComboBox, CB_GETCOUNT, 0, 0);
|
||||
if (x != CB_ERR)
|
||||
{
|
||||
int i, nHighIdx = CB_ERR;
|
||||
time_t lHighTime = -1;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
time_t lTime = SendMessage (hComboBox, CB_GETITEMDATA, (WPARAM) i, 0);
|
||||
if (lTime > lHighTime)
|
||||
{
|
||||
int n;
|
||||
for (n = 0; n < nElems; n++)
|
||||
if (nIdxList[n] == i)
|
||||
break;
|
||||
if (n == nElems)
|
||||
{
|
||||
lHighTime = lTime;
|
||||
nHighIdx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nHighIdx;
|
||||
}
|
||||
|
||||
return CB_ERR;
|
||||
}
|
||||
|
||||
LPARAM UpdateComboOrder (HWND hComboBox)
|
||||
{
|
||||
LPARAM nIndex;
|
||||
|
||||
nIndex = SendMessage (hComboBox, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (nIndex != CB_ERR)
|
||||
{
|
||||
time_t lTime = time (NULL);
|
||||
nIndex = SendMessage (hComboBox, CB_SETITEMDATA, (WPARAM) nIndex,
|
||||
(LPARAM) lTime);
|
||||
}
|
||||
|
||||
return nIndex;
|
||||
}
|
||||
|
||||
void LoadCombo (HWND hComboBox)
|
||||
{
|
||||
DWORD size;
|
||||
char *history = LoadFile (GetConfigPath (TC_APPD_FILENAME_HISTORY), &size);
|
||||
char *xml = history;
|
||||
char volume[MAX_PATH];
|
||||
|
||||
if (xml == NULL) return;
|
||||
|
||||
while (xml = XmlFindElement (xml, "volume"))
|
||||
{
|
||||
XmlGetNodeText (xml, volume, sizeof (volume));
|
||||
AddComboItem (hComboBox, volume, TRUE);
|
||||
xml++;
|
||||
}
|
||||
|
||||
SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
|
||||
|
||||
free (history);
|
||||
}
|
||||
|
||||
void DumpCombo (HWND hComboBox, int bClear)
|
||||
{
|
||||
FILE *f;
|
||||
int i, nComboIdx[SIZEOF_MRU_LIST];
|
||||
|
||||
if (bClear)
|
||||
{
|
||||
DeleteFile (GetConfigPath (TC_APPD_FILENAME_HISTORY));
|
||||
return;
|
||||
}
|
||||
|
||||
f = fopen (GetConfigPath (TC_APPD_FILENAME_HISTORY), "w");
|
||||
if (f == NULL) return;
|
||||
|
||||
XmlWriteHeader (f);
|
||||
fputs ("\n\t<history>", f);
|
||||
|
||||
/* combo list part:- get mru items */
|
||||
for (i = 0; i < SIZEOF_MRU_LIST; i++)
|
||||
nComboIdx[i] = GetOrderComboIdx (hComboBox, &nComboIdx[0], i);
|
||||
|
||||
/* combo list part:- write out mru items */
|
||||
for (i = 0; i < SIZEOF_MRU_LIST; i++)
|
||||
{
|
||||
char szTmp[MAX_PATH] = { 0 };
|
||||
|
||||
if (SendMessage (hComboBox, CB_GETLBTEXTLEN, nComboIdx[i], 0) < sizeof (szTmp))
|
||||
SendMessage (hComboBox, CB_GETLBTEXT, nComboIdx[i], (LPARAM) & szTmp[0]);
|
||||
|
||||
if (szTmp[0] != 0)
|
||||
{
|
||||
char q[MAX_PATH * 2] = { 0 };
|
||||
XmlQuoteText (szTmp, q, sizeof (q));
|
||||
|
||||
fprintf (f, "\n\t\t<volume>%s</volume>", q);
|
||||
}
|
||||
}
|
||||
|
||||
fputs ("\n\t</history>", f);
|
||||
XmlWriteFooter (f);
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
void ClearCombo (HWND hComboBox)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SIZEOF_MRU_LIST; i++)
|
||||
{
|
||||
SendMessage (hComboBox, CB_DELETESTRING, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int IsComboEmpty (HWND hComboBox)
|
||||
{
|
||||
return SendMessage (hComboBox, CB_GETCOUNT, 0, 0) < 1;
|
||||
}
|
||||
27
src/Common/Combo.h
Normal file
27
src/Common/Combo.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void AddComboItem (HWND hComboBox, char *lpszFileName, BOOL saveHistory);
|
||||
LPARAM MoveEditToCombo (HWND hComboBox, BOOL saveHistory);
|
||||
int GetOrderComboIdx ( HWND hComboBox , int *nIdxList , int nElems );
|
||||
LPARAM UpdateComboOrder ( HWND hComboBox );
|
||||
void LoadCombo ( HWND hComboBox );
|
||||
void DumpCombo ( HWND hComboBox , int bClear );
|
||||
void ClearCombo (HWND hComboBox);
|
||||
int IsComboEmpty (HWND hComboBox);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
81
src/Common/Common.h
Normal file
81
src/Common/Common.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include "Crypto.h"
|
||||
|
||||
#define MIN_MOUNTED_VOLUME_DRIVE_NUMBER ('A' - 'A')
|
||||
#define MAX_MOUNTED_VOLUME_DRIVE_NUMBER ('Z' - 'A')
|
||||
|
||||
#define MAX_HOST_DRIVE_NUMBER 64
|
||||
#define MAX_HOST_PARTITION_NUMBER 32
|
||||
|
||||
typedef enum
|
||||
{
|
||||
// IMPORTANT: If you add a new item here, update IsOSVersionAtLeast().
|
||||
|
||||
WIN_UNKNOWN = 0,
|
||||
WIN_31,
|
||||
WIN_95,
|
||||
WIN_98,
|
||||
WIN_ME,
|
||||
WIN_NT3,
|
||||
WIN_NT4,
|
||||
WIN_2000,
|
||||
WIN_XP,
|
||||
WIN_XP64,
|
||||
WIN_SERVER_2003,
|
||||
WIN_VISTA,
|
||||
WIN_SERVER_2008,
|
||||
WIN_7,
|
||||
WIN_SERVER_2008_R2,
|
||||
} OSVersionEnum;
|
||||
|
||||
/* Volume types */
|
||||
enum
|
||||
{
|
||||
TC_VOLUME_TYPE_NORMAL = 0,
|
||||
TC_VOLUME_TYPE_HIDDEN,
|
||||
TC_VOLUME_TYPE_HIDDEN_LEGACY,
|
||||
TC_VOLUME_TYPE_COUNT
|
||||
};
|
||||
|
||||
/* Prop volume types */
|
||||
enum
|
||||
{
|
||||
PROP_VOL_TYPE_NORMAL = 0,
|
||||
PROP_VOL_TYPE_HIDDEN,
|
||||
PROP_VOL_TYPE_OUTER, /* Outer/normal (hidden volume protected) */
|
||||
PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, /* Outer/normal (hidden volume protected AND write already prevented) */
|
||||
PROP_VOL_TYPE_SYSTEM,
|
||||
PROP_NBR_VOLUME_TYPES
|
||||
};
|
||||
|
||||
/* Hidden volume protection status */
|
||||
enum
|
||||
{
|
||||
HIDVOL_PROT_STATUS_NONE = 0,
|
||||
HIDVOL_PROT_STATUS_ACTIVE,
|
||||
HIDVOL_PROT_STATUS_ACTION_TAKEN /* Active + action taken (write operation has already been denied) */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL ReadOnly;
|
||||
BOOL Removable;
|
||||
BOOL ProtectHiddenVolume;
|
||||
BOOL PreserveTimestamp;
|
||||
BOOL PartitionInInactiveSysEncScope; /* If TRUE, we are to attempt to mount a partition located on an encrypted system drive without pre-boot authentication. */
|
||||
Password ProtectedHidVolPassword; /* Password of hidden volume to protect against overwriting */
|
||||
BOOL UseBackupHeader;
|
||||
BOOL RecoveryMode;
|
||||
} MountOptions;
|
||||
|
||||
#endif
|
||||
541
src/Common/Common.rc
Normal file
541
src/Common/Common.rc
Normal file
@@ -0,0 +1,541 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_ABOUT_DLG DIALOGEX 31, 51, 292, 199
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About TrueCrypt"
|
||||
CLASS "SplashDlg"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
EDITTEXT IDC_ABOUT_CREDITS,7,111,277,45,ES_MULTILINE | WS_VSCROLL | NOT WS_TABSTOP
|
||||
DEFPUSHBUTTON "OK",IDOK,230,178,52,14
|
||||
LTEXT "",IDC_HOMEPAGE,18,87,117,9,SS_NOTIFY
|
||||
LTEXT "",IDT_ABOUT_RELEASE,18,71,235,8
|
||||
CONTROL 517,IDC_ABOUT_BKG,"Static",SS_BITMAP,0,0,12,11,WS_EX_STATICEDGE
|
||||
LTEXT "",IDT_ABOUT_VERSION,18,61,161,8
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,167,291,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,169,291,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,107,291,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_ABOUT_LOGO_AREA,"Static",SS_GRAYRECT | NOT WS_VISIBLE,0,0,293,50,WS_EX_TRANSPARENT | WS_EX_STATICEDGE
|
||||
CONTROL 518,IDC_TEXTUAL_LOGO_IMG,"Static",SS_BITMAP,12,26,157,16
|
||||
END
|
||||
|
||||
IDD_COMMANDHELP_DLG DIALOGEX 0, 0, 249, 213
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Command Line Help"
|
||||
CLASS "CustomDlg"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,93,191,59,14
|
||||
LTEXT "",IDC_COMMANDHELP_TEXT,20,11,208,174
|
||||
END
|
||||
|
||||
IDD_RAWDEVICES_DLG DIALOGEX 0, 0, 305, 209
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Select a Partition or Device"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x0
|
||||
BEGIN
|
||||
CONTROL "",IDC_DEVICELIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,291,178
|
||||
DEFPUSHBUTTON "OK",IDOK,192,190,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,248,190,50,14
|
||||
END
|
||||
|
||||
IDD_MOUNT_OPTIONS DIALOGEX 0, 0, 277, 172
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Mount Options"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "Mount volume as read-&only",IDC_MOUNT_READONLY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,11,194,10
|
||||
CONTROL "Mount volume as removable &medium",IDC_MOUNT_REMOVABLE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,25,195,10
|
||||
CONTROL "Mount partition &using system encryption without pre-boot authentication",IDC_MOUNT_SYSENC_PART_WITHOUT_PBA,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,53,259,11
|
||||
CONTROL "&Protect hidden volume against damage caused by writing to outer volume",IDC_PROTECT_HIDDEN_VOL,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,86,252,10
|
||||
EDITTEXT IDC_PASSWORD_PROT_HIDVOL,112,104,151,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
CONTROL "&Display password",IDC_SHOW_PASSWORD_MO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,123,90,10
|
||||
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE_HIDVOL_PROT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,112,136,90,10
|
||||
PUSHBUTTON "&Keyfiles...",IDC_KEYFILES_HIDVOL_PROT,203,125,60,14
|
||||
LTEXT "What is hidden volume protection?",IDC_LINK_HIDVOL_PROTECTION_INFO,16,151,247,10,SS_NOTIFY
|
||||
DEFPUSHBUTTON "OK",IDOK,211,7,60,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,211,24,60,14
|
||||
RTEXT "P&assword to hidden volume:\n(if empty, cache is used)",IDT_HIDDEN_PROT_PASSWD,15,103,91,17,0,WS_EX_RIGHT
|
||||
GROUPBOX "Hidden Volume Protection",IDT_HIDDEN_VOL_PROTECTION,6,72,265,95
|
||||
CONTROL "Use backup header embedded in &volume if available",IDC_USE_EMBEDDED_HEADER_BAK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,39,257,11
|
||||
END
|
||||
|
||||
IDD_KEYFILES DIALOGEX 0, 0, 345, 237
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Keyfiles"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_KEYLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,8,263,118
|
||||
PUSHBUTTON "Add &Files...",IDC_KEYADD,7,132,61,14
|
||||
PUSHBUTTON "Add &Path...",IDC_ADD_KEYFILE_PATH,73,132,61,14
|
||||
PUSHBUTTON "Add &Token Files...",IDC_TOKEN_FILES_ADD,139,132,65,14
|
||||
PUSHBUTTON "&Remove",IDC_KEYREMOVE,209,132,61,14
|
||||
PUSHBUTTON "Remove &All",IDC_KEYREMOVEALL,275,132,61,14
|
||||
CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,219,83,11
|
||||
PUSHBUTTON "&Generate Random Keyfile...",IDC_GENERATE_KEYFILE,213,217,123,14
|
||||
DEFPUSHBUTTON "OK",IDOK,279,8,59,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,279,25,59,14
|
||||
LTEXT "",IDT_KEYFILES_NOTE,10,161,324,41,0,WS_EX_TRANSPARENT
|
||||
LTEXT "WARNING: If you lose a keyfile or if any bit of its first 1024 kilobytes changes, it will be impossible to mount volumes that use the keyfile!",IDT_KEYFILE_WARNING,279,44,58,85,0,WS_EX_TRANSPARENT
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,154,343,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,209,343,1,WS_EX_STATICEDGE
|
||||
LTEXT "More information on keyfiles",IDC_LINK_KEYFILES_INFO,96,220,108,10,SS_NOTIFY
|
||||
END
|
||||
|
||||
IDD_LANGUAGE DIALOGEX 0, 0, 209, 183
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Language"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LISTBOX IDC_LANGLIST,6,7,197,67,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_LANGPACK_CREDITS,6,108,197,28,ES_MULTILINE | ES_READONLY | WS_VSCROLL | NOT WS_TABSTOP
|
||||
CTEXT "Download language pack",IDC_GET_LANG_PACKS,2,146,205,10,SS_NOTIFY
|
||||
DEFPUSHBUTTON "OK",IDOK,97,165,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,153,165,50,14
|
||||
LTEXT "Translated by:",IDT_LANGPACK_AUTHORS,6,99,101,9,SS_NOTIFY,WS_EX_TRANSPARENT
|
||||
RTEXT "",IDC_LANGPACK_VERSION,79,86,118,11
|
||||
GROUPBOX "Active language pack",IDT_ACTIVE_LANG_PACK,0,77,209,65
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,158,208,1,WS_EX_STATICEDGE
|
||||
END
|
||||
|
||||
IDD_BENCHMARK_DLG DIALOGEX 0, 0, 330, 223
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Encryption Algorithm Benchmark"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
COMBOBOX IDC_BENCHMARK_BUFFER_SIZE,55,7,77,129,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
|
||||
COMBOBOX IDC_BENCHMARK_SORT_METHOD,207,7,116,74,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "",IDC_RESULTS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,37,249,160
|
||||
DEFPUSHBUTTON "Benchmark",IDC_PERFORM_BENCHMARK,265,37,58,14
|
||||
PUSHBUTTON "Close",IDCLOSE,265,55,58,14
|
||||
LTEXT "Hardware-accelerated AES:",IDC_HW_AES_LABEL_LINK,148,210,108,9,SS_NOTIFY,WS_EX_RIGHT
|
||||
CONTROL "",IDC_HW_AES,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,262,209,57,11,WS_EX_STATICEDGE
|
||||
LTEXT "Parallelization:",IDC_PARALLELIZATION_LABEL_LINK,4,210,67,9,SS_NOTIFY,WS_EX_RIGHT
|
||||
CONTROL "",IDC_PARALLELIZATION,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,77,209,57,11,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,29,328,1,WS_EX_STATICEDGE
|
||||
LTEXT "Buffer Size:",IDT_BUFFER_SIZE,0,9,53,8,0,WS_EX_RIGHT
|
||||
LTEXT "Sort Method:",IDT_SORT_METHOD,135,9,70,8,0,WS_EX_RIGHT
|
||||
LTEXT "Speed is affected by CPU load and storage device characteristics.\n\nThese tests take place in RAM.",IDT_BOX_BENCHMARK_INFO,266,81,57,116
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,205,328,1,WS_EX_STATICEDGE
|
||||
END
|
||||
|
||||
IDD_CIPHER_TEST_DLG DIALOGEX 0, 0, 326, 249
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Test Vectors"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
COMBOBOX IDC_CIPHER,109,10,104,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_KEY,8,36,309,14,ES_AUTOHSCROLL
|
||||
COMBOBOX IDC_KEY_SIZE,67,55,42,68,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_SECONDARY_KEY,8,93,309,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_TEST_DATA_UNIT_NUMBER,8,118,84,14,ES_AUTOHSCROLL
|
||||
CONTROL "XTS mode",IDC_XTS_MODE_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,221,12,95,10
|
||||
EDITTEXT IDC_PLAINTEXT,8,151,159,14,ES_AUTOHSCROLL
|
||||
COMBOBOX IDC_PLAINTEXT_SIZE,258,151,36,30,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_CIPHERTEXT,8,185,159,14,ES_AUTOHSCROLL
|
||||
DEFPUSHBUTTON "&Encrypt",IDC_ENCRYPT,8,229,52,14
|
||||
PUSHBUTTON "&Decrypt",IDC_DECRYPT,65,229,52,14
|
||||
PUSHBUTTON "&Auto-Test All",IDC_AUTO,129,229,67,14,BS_MULTILINE
|
||||
PUSHBUTTON "&Reset",IDC_RESET,208,229,52,14
|
||||
PUSHBUTTON "Close",IDCLOSE,266,229,52,14
|
||||
GROUPBOX "Key (hexadecimal)",IDT_TEST_KEY,1,26,323,49
|
||||
GROUPBOX "Plaintext (hexadecimal)",IDT_TEST_PLAINTEXT,1,140,323,33
|
||||
GROUPBOX "Ciphertext (hexadecimal)",IDT_TEST_CIPHERTEXT,1,174,323,33
|
||||
RTEXT "",IDC_TESTS_MESSAGE,50,213,178,10
|
||||
CONTROL "",IDC_REDTICK,"REDTICK",0x0,234,214,10,8
|
||||
RTEXT "Key size:",IDT_KEY,8,57,56,8
|
||||
RTEXT "Plaintext size:",IDT_PLAINTEXT,190,153,63,8
|
||||
LTEXT "bits",IDT_KEY_UNIT,114,57,45,8
|
||||
RTEXT "Cipher:",IDT_CIPHER,38,13,68,8
|
||||
LTEXT "bits",IDT_PLAINTEXT_SIZE_UNIT,298,153,22,8
|
||||
GROUPBOX "XTS mode",IDT_XTS_MODE,1,75,323,65
|
||||
LTEXT "Secondary key (hexadecimal)",IDT_SECONDARY_KEY,8,84,187,8
|
||||
LTEXT "Data unit number (64-bit hexadecimal, data unit size is 512 bytes)",IDT_TEST_DATA_UNIT_NUMBER,8,109,308,8
|
||||
RTEXT "Block number:",IDT_TEST_BLOCK_NUMBER,134,122,119,8
|
||||
COMBOBOX IDC_TEST_BLOCK_NUMBER,258,119,36,126,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
IDD_TEXT_INFO_DIALOG_BOX_DLG DIALOGEX 0, 0, 372, 220
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,305,200,58,14
|
||||
PUSHBUTTON "&Print",IDC_PRINT,156,200,58,14
|
||||
CONTROL "",IDC_INFO_BOX_TEXT,"RichEdit20A",ES_MULTILINE | ES_READONLY | ES_NUMBER | WS_BORDER | WS_VSCROLL | WS_TABSTOP,5,6,361,188
|
||||
END
|
||||
|
||||
IDD_KEYFILE_GENERATOR DIALOGEX 0, 0, 308, 270
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Keyfile Generator"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Close",IDCLOSE,237,10,59,14
|
||||
COMBOBOX IDC_PRF_ID,79,49,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
|
||||
PUSHBUTTON "Generate and Save Keyfile...",IDC_GENERATE_AND_SAVE_KEYFILE,89,248,131,14
|
||||
LTEXT "IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases the cryptographic strength of the keyfile.",IDT_KEYFILE_GENERATOR_NOTE,11,5,213,33
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,40,307,1,WS_EX_STATICEDGE
|
||||
RTEXT "Mixing PRF:",IDT_PRF,6,51,67,10,SS_CENTERIMAGE
|
||||
GROUPBOX "Current Pool Content",IDT_POOL_CONTENTS,6,70,296,170
|
||||
CONTROL "",IDC_POOL_CONTENTS,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,16,83,282,148,WS_EX_TRANSPARENT
|
||||
CONTROL "Display pool content",IDC_DISPLAY_POOL_CONTENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,191,51,111,10
|
||||
END
|
||||
|
||||
IDD_MULTI_CHOICE_DLG DIALOGEX 0, 0, 167, 322
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
PUSHBUTTON "",IDC_CHOICE10,7,292,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE9,7,268,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE8,7,244,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE7,7,220,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE6,7,196,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE5,7,172,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE4,7,148,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE3,7,124,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE2,7,100,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
PUSHBUTTON "",IDC_CHOICE1,7,76,153,24,BS_CENTER | BS_MULTILINE,WS_EX_STATICEDGE
|
||||
LTEXT "",IDC_MULTI_CHOICE_MSG,7,7,153,56,0,WS_EX_TRANSPARENT
|
||||
CONTROL "",IDC_MC_DLG_HR2,"Static",SS_ETCHEDHORZ,0,69,168,1,WS_EX_STATICEDGE
|
||||
CONTROL "",IDC_MC_DLG_HR1,"Static",SS_ETCHEDHORZ,0,1,168,1,WS_EX_STATICEDGE
|
||||
END
|
||||
|
||||
IDD_AUXILIARY_DLG DIALOGEX 0, 0, 426, 296
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | DS_NOFAILCREATE | WS_POPUP
|
||||
EXSTYLE WS_EX_TRANSPARENT
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "",IDC_ASPECT_RATIO_CALIBRATION_BOX,3,2,282,282,WS_DISABLED
|
||||
END
|
||||
|
||||
IDD_TOKEN_PASSWORD DIALOGEX 0, 0, 281, 47
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Security token password/PIN required"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
EDITTEXT IDC_TOKEN_PASSWORD,8,20,199,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
DEFPUSHBUTTON "OK",IDOK,215,7,59,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,215,25,59,14
|
||||
LTEXT "",IDT_TOKEN_PASSWORD_INFO,9,8,196,8
|
||||
END
|
||||
|
||||
IDD_TOKEN_KEYFILES DIALOGEX 0, 0, 337, 185
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Security Token Keyfiles"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_TOKEN_FILE_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_EDITLABELS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,256,152
|
||||
PUSHBUTTON "&Export...",IDC_EXPORT,7,164,55,14
|
||||
PUSHBUTTON "&Delete",IDC_DELETE,66,164,55,14
|
||||
PUSHBUTTON "&Import Keyfile to Token...",IDC_IMPORT_KEYFILE,126,164,137,14
|
||||
DEFPUSHBUTTON "OK",IDOK,271,7,59,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,271,25,59,14
|
||||
END
|
||||
|
||||
IDD_NEW_TOKEN_KEYFILE DIALOGEX 0, 0, 239, 82
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "New Security Token Keyfile Properties"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,128,61,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,183,61,50,14
|
||||
COMBOBOX IDC_SELECTED_TOKEN,77,13,140,43,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Security token:",IDT_SECURITY_TOKEN,11,15,62,8,0,WS_EX_RIGHT
|
||||
LTEXT "Keyfile name:",IDT_TOKEN_KEYFILE_NAME,12,34,61,8,0,WS_EX_RIGHT
|
||||
EDITTEXT IDC_TOKEN_KEYFILE_NAME,77,32,140,13,ES_AUTOHSCROLL
|
||||
GROUPBOX "",IDC_STATIC,5,2,228,51
|
||||
END
|
||||
|
||||
IDD_RANDOM_POOL_ENRICHMENT DIALOGEX 0, 0, 308, 270
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "TrueCrypt - Random Pool Enrichment"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "&Continue",IDC_CONTINUE,119,248,71,14
|
||||
COMBOBOX IDC_PRF_ID,79,49,91,90,CBS_DROPDOWNLIST | WS_TABSTOP
|
||||
LTEXT "IMPORTANT: Move your mouse as randomly as possible within this window. The longer you move it, the better. This significantly increases security. When done, click 'Continue'.",IDT_RANDOM_POOL_ENRICHMENT_NOTE,11,6,282,25
|
||||
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,1,37,307,1,WS_EX_STATICEDGE
|
||||
RTEXT "Mixing PRF:",IDT_PRF,6,51,67,10,SS_CENTERIMAGE
|
||||
GROUPBOX "Current Pool Content",IDT_POOL_CONTENTS,6,70,296,170
|
||||
CONTROL "",IDC_POOL_CONTENTS,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,16,83,282,148,WS_EX_TRANSPARENT
|
||||
CONTROL "Display pool content",IDC_DISPLAY_POOL_CONTENTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,191,51,111,10
|
||||
END
|
||||
|
||||
IDD_STATIC_MODELESS_WAIT_DLG DIALOGEX 0, 0, 292, 42
|
||||
STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
|
||||
EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
|
||||
CAPTION "TrueCrypt"
|
||||
FONT 8, "MS Shell Dlg", 0, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Please wait. This process may take a long time...",IDT_STATIC_MODELESS_WAIT_DLG_INFO,9,8,274,9
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_COMMANDHELP_DLG, DIALOG
|
||||
BEGIN
|
||||
BOTTOMMARGIN, 205
|
||||
END
|
||||
|
||||
IDD_RAWDEVICES_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 298
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 205
|
||||
END
|
||||
|
||||
IDD_MOUNT_OPTIONS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 166
|
||||
END
|
||||
|
||||
IDD_KEYFILES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 330
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 230
|
||||
END
|
||||
|
||||
IDD_LANGUAGE, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 6
|
||||
RIGHTMARGIN, 202
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 176
|
||||
END
|
||||
|
||||
IDD_BENCHMARK_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 323
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 216
|
||||
END
|
||||
|
||||
IDD_CIPHER_TEST_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 319
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 242
|
||||
END
|
||||
|
||||
IDD_TEXT_INFO_DIALOG_BOX_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 365
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 213
|
||||
END
|
||||
|
||||
IDD_KEYFILE_GENERATOR, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 299
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 266
|
||||
END
|
||||
|
||||
IDD_MULTI_CHOICE_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 160
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 316
|
||||
END
|
||||
|
||||
IDD_AUXILIARY_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 419
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 289
|
||||
END
|
||||
|
||||
IDD_TOKEN_PASSWORD, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 274
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 40
|
||||
END
|
||||
|
||||
IDD_TOKEN_KEYFILES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 330
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 178
|
||||
END
|
||||
|
||||
IDD_NEW_TOKEN_KEYFILE, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 232
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 75
|
||||
END
|
||||
|
||||
IDD_RANDOM_POOL_ENRICHMENT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 301
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 267
|
||||
END
|
||||
|
||||
IDD_STATIC_MODELESS_WAIT_DLG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 285
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 35
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BIN
|
||||
//
|
||||
|
||||
IDR_BOOT_SECTOR BIN "..\\Boot\\Windows\\Release\\BootSector.bin"
|
||||
IDR_BOOT_SECTOR_AES BIN "..\\Boot\\Windows\\Release_AES\\BootSector.bin"
|
||||
IDR_BOOT_SECTOR_SERPENT BIN "..\\Boot\\Windows\\Release_Serpent\\BootSector.bin"
|
||||
IDR_BOOT_SECTOR_TWOFISH BIN "..\\Boot\\Windows\\Release_Twofish\\BootSector.bin"
|
||||
IDR_BOOT_LOADER_DECOMPRESSOR BIN "..\\Boot\\Windows\\Release\\Decompressor.com"
|
||||
IDR_BOOT_LOADER BIN "..\\Boot\\Windows\\Release\\BootLoader.com.gz"
|
||||
IDR_BOOT_LOADER_AES BIN "..\\Boot\\Windows\\Release_AES\\BootLoader.com.gz"
|
||||
IDR_BOOT_LOADER_SERPENT BIN "..\\Boot\\Windows\\Release_Serpent\\BootLoader.com.gz"
|
||||
IDR_BOOT_LOADER_TWOFISH BIN "..\\Boot\\Windows\\Release_Twofish\\BootLoader.com.gz"
|
||||
IDR_RESCUE_BOOT_SECTOR BIN "..\\Boot\\Windows\\Rescue\\BootSector.bin"
|
||||
IDR_RESCUE_BOOT_SECTOR_AES BIN "..\\Boot\\Windows\\Rescue_AES\\BootSector.bin"
|
||||
IDR_RESCUE_BOOT_SECTOR_SERPENT BIN "..\\Boot\\Windows\\Rescue_Serpent\\BootSector.bin"
|
||||
IDR_RESCUE_BOOT_SECTOR_TWOFISH BIN "..\\Boot\\Windows\\Rescue_Twofish\\BootSector.bin"
|
||||
IDR_RESCUE_LOADER BIN "..\\Boot\\Windows\\Rescue\\BootLoader.com.gz"
|
||||
IDR_RESCUE_LOADER_AES BIN "..\\Boot\\Windows\\Rescue_AES\\BootLoader.com.gz"
|
||||
IDR_RESCUE_LOADER_SERPENT BIN "..\\Boot\\Windows\\Rescue_Serpent\\BootLoader.com.gz"
|
||||
IDR_RESCUE_LOADER_TWOFISH BIN "..\\Boot\\Windows\\Rescue_Twofish\\BootLoader.com.gz"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// XML
|
||||
//
|
||||
|
||||
IDR_LANGUAGE XML "..\\Common\\Language.xml"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// HEADER
|
||||
//
|
||||
|
||||
IDR_COMMON_RSRC_HEADER HEADER "..\\Common\\Resource.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXT
|
||||
//
|
||||
|
||||
IDR_LICENSE TEXT "..\\Resources\\Texts\\License.rtf"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_TRUECRYPT_ICON ICON "..\\Common\\TrueCrypt.ico"
|
||||
IDI_TRUECRYPT_VOL_ICON ICON "..\\Common\\TrueCrypt_volume.ico"
|
||||
IDI_TRUECRYPT_MOUNTED_ICON ICON "..\\Common\\TrueCrypt_mounted.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
IDB_TEXTUAL_LOGO_BKG BITMAP "..\\Common\\Textual_logo_background.bmp"
|
||||
IDB_TEXTUAL_LOGO_96DPI BITMAP "..\\Common\\Textual_logo_96dpi.bmp"
|
||||
IDB_TEXTUAL_LOGO_288DPI BITMAP "..\\Common\\Textual_logo_288dpi.bmp"
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
133
src/Common/Crc.c
Normal file
133
src/Common/Crc.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crc.h"
|
||||
#include "Common/Endian.h"
|
||||
|
||||
#ifndef TC_MINIMIZE_CODE_SIZE
|
||||
|
||||
/* CRC polynomial 0x04c11db7 */
|
||||
unsigned __int32 crc_32_tab[]=
|
||||
{
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
unsigned __int32 GetCrc32 (unsigned char *data, int length)
|
||||
{
|
||||
unsigned __int32 CRC = 0xffffffff;
|
||||
|
||||
while (length--)
|
||||
{
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *data++) & 0xFF ];
|
||||
}
|
||||
|
||||
return CRC ^ 0xffffffff;
|
||||
}
|
||||
|
||||
unsigned __int32 crc32int (unsigned __int32 *data)
|
||||
{
|
||||
unsigned char *d = (unsigned char *) data;
|
||||
unsigned __int32 CRC = 0xffffffff;
|
||||
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
|
||||
CRC = (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d++) & 0xFF ];
|
||||
return (CRC >> 8) ^ crc_32_tab[ (CRC ^ *d) & 0xFF ] ^ 0xffffffff;
|
||||
}
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define CRC_SELFTEST 0x6fcf9e13
|
||||
#else
|
||||
# define CRC_SELFTEST 0xca87914d
|
||||
#endif
|
||||
|
||||
BOOL crc32_selftests (void)
|
||||
{
|
||||
int i;
|
||||
unsigned __int32 crc = 0xffffffff;
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
for (i = 0; i < (int)sizeof(crc_32_tab); i++)
|
||||
crc = UPDC32 (((unsigned char *) crc_32_tab)[i], crc);
|
||||
|
||||
bSuccess = CRC_SELFTEST == (crc ^ 0xffffffff);
|
||||
|
||||
bSuccess &= GetCrc32 ((unsigned char *)crc_32_tab, sizeof crc_32_tab) == CRC_SELFTEST;
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
#else // TC_MINIMIZE_CODE_SIZE
|
||||
|
||||
unsigned __int32 GetCrc32 (unsigned char *data, int length)
|
||||
{
|
||||
unsigned __int32 r = 0xFFFFFFFFUL;
|
||||
int i, b;
|
||||
|
||||
for (i = 0; i < length; ++i)
|
||||
{
|
||||
r ^= data[i];
|
||||
for (b = 0; b < 8; ++b)
|
||||
{
|
||||
if ((unsigned __int8) r & 1)
|
||||
r = (r >> 1) ^ 0xEDB88320UL;
|
||||
else
|
||||
r >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return r ^ 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
BOOL crc32_selftests ()
|
||||
{
|
||||
unsigned __int8 testData[32];
|
||||
unsigned __int8 i;
|
||||
|
||||
for (i = 0; i < sizeof (testData); ++i)
|
||||
testData[i] = i;
|
||||
|
||||
return GetCrc32 (testData, sizeof (testData)) == 0x91267E8AUL;
|
||||
}
|
||||
|
||||
#endif // TC_MINIMIZE_CODE_SIZE
|
||||
35
src/Common/Crc.h
Normal file
35
src/Common/Crc.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_CRC
|
||||
#define TC_HEADER_CRC
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define UPDC32(octet, crc)\
|
||||
(unsigned __int32)((crc_32_tab[(((unsigned __int32)(crc)) ^ ((unsigned char)(octet))) & 0xff] ^ (((unsigned __int32)(crc)) >> 8)))
|
||||
|
||||
unsigned __int32 GetCrc32 (unsigned char *data, int length);
|
||||
unsigned __int32 crc32int (unsigned __int32 *data);
|
||||
BOOL crc32_selftests (void);
|
||||
|
||||
extern unsigned __int32 crc_32_tab[];
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_CRC
|
||||
1871
src/Common/Crypto.c
Normal file
1871
src/Common/Crypto.c
Normal file
File diff suppressed because it is too large
Load Diff
332
src/Common/Crypto.h
Normal file
332
src/Common/Crypto.h
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
/* Update the following when adding a new cipher or EA:
|
||||
|
||||
Crypto.h:
|
||||
ID #define
|
||||
MAX_EXPANDED_KEY #define
|
||||
|
||||
Crypto.c:
|
||||
Ciphers[]
|
||||
EncryptionAlgorithms[]
|
||||
CipherInit()
|
||||
EncipherBlock()
|
||||
DecipherBlock()
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Encryption data unit size, which may differ from the sector size and must always be 512
|
||||
#define ENCRYPTION_DATA_UNIT_SIZE 512
|
||||
|
||||
// Size of the salt (in bytes)
|
||||
#define PKCS5_SALT_SIZE 64
|
||||
|
||||
// Size of the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode)
|
||||
#define MASTER_KEYDATA_SIZE 256
|
||||
|
||||
// Size of the deprecated volume header item containing either an IV seed (CBC mode) or tweak key (LRW mode)
|
||||
#define LEGACY_VOL_IV_SIZE 32
|
||||
|
||||
// The first PRF to try when mounting
|
||||
#define FIRST_PRF_ID 1
|
||||
|
||||
// Hash algorithms (pseudorandom functions).
|
||||
enum
|
||||
{
|
||||
RIPEMD160 = FIRST_PRF_ID,
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
SHA512,
|
||||
WHIRLPOOL,
|
||||
SHA1, // Deprecated/legacy
|
||||
#endif
|
||||
HASH_ENUM_END_ID
|
||||
};
|
||||
|
||||
// The last PRF to try when mounting and also the number of implemented PRFs
|
||||
#define LAST_PRF_ID (HASH_ENUM_END_ID - 1)
|
||||
|
||||
#define RIPEMD160_BLOCKSIZE 64
|
||||
#define RIPEMD160_DIGESTSIZE 20
|
||||
|
||||
#define SHA1_BLOCKSIZE 64
|
||||
#define SHA1_DIGESTSIZE 20
|
||||
|
||||
#define SHA512_BLOCKSIZE 128
|
||||
#define SHA512_DIGESTSIZE 64
|
||||
|
||||
#define WHIRLPOOL_BLOCKSIZE 64
|
||||
#define WHIRLPOOL_DIGESTSIZE 64
|
||||
|
||||
#define MAX_DIGESTSIZE WHIRLPOOL_DIGESTSIZE
|
||||
|
||||
#define DEFAULT_HASH_ALGORITHM FIRST_PRF_ID
|
||||
#define DEFAULT_HASH_ALGORITHM_BOOT RIPEMD160
|
||||
|
||||
// The mode of operation used for newly created volumes and first to try when mounting
|
||||
#define FIRST_MODE_OF_OPERATION_ID 1
|
||||
|
||||
// Modes of operation
|
||||
enum
|
||||
{
|
||||
/* If you add/remove a mode, update the following: GetMaxPkcs5OutSize(), EAInitMode() */
|
||||
|
||||
XTS = FIRST_MODE_OF_OPERATION_ID,
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
LRW, // Deprecated/legacy
|
||||
CBC, // Deprecated/legacy
|
||||
OUTER_CBC, // Deprecated/legacy
|
||||
INNER_CBC, // Deprecated/legacy
|
||||
#endif
|
||||
MODE_ENUM_END_ID
|
||||
};
|
||||
|
||||
|
||||
// The last mode of operation to try when mounting and also the number of implemented modes
|
||||
#define LAST_MODE_OF_OPERATION (MODE_ENUM_END_ID - 1)
|
||||
|
||||
// Ciphertext/plaintext block size for XTS mode (in bytes)
|
||||
#define BYTES_PER_XTS_BLOCK 16
|
||||
|
||||
// Number of ciphertext/plaintext blocks per XTS data unit
|
||||
#define BLOCKS_PER_XTS_DATA_UNIT (ENCRYPTION_DATA_UNIT_SIZE / BYTES_PER_XTS_BLOCK)
|
||||
|
||||
|
||||
// Cipher IDs
|
||||
enum
|
||||
{
|
||||
NONE = 0,
|
||||
AES,
|
||||
SERPENT,
|
||||
TWOFISH,
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
BLOWFISH, // Deprecated/legacy
|
||||
CAST, // Deprecated/legacy
|
||||
TRIPLEDES // Deprecated/legacy
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Id; // Cipher ID
|
||||
char *Name; // Name
|
||||
int BlockSize; // Block size (bytes)
|
||||
int KeySize; // Key size (bytes)
|
||||
int KeyScheduleSize; // Scheduled key size (bytes)
|
||||
} Cipher;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Ciphers[4]; // Null terminated array of ciphers used by encryption algorithm
|
||||
int Modes[LAST_MODE_OF_OPERATION + 1]; // Null terminated array of modes of operation
|
||||
int FormatEnabled;
|
||||
} EncryptionAlgorithm;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Id; // Hash ID
|
||||
char *Name; // Name
|
||||
BOOL Deprecated;
|
||||
BOOL SystemEncryption; // Available for system encryption
|
||||
} Hash;
|
||||
|
||||
// Maxium length of scheduled key
|
||||
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_AES)
|
||||
# define AES_KS (sizeof(aes_encrypt_ctx) + sizeof(aes_decrypt_ctx))
|
||||
#else
|
||||
# define AES_KS (sizeof(aes_context))
|
||||
#endif
|
||||
#define SERPENT_KS (140 * 4)
|
||||
|
||||
#ifdef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
|
||||
|
||||
# ifdef TC_WINDOWS_BOOT_AES
|
||||
# define MAX_EXPANDED_KEY AES_KS
|
||||
# elif defined (TC_WINDOWS_BOOT_SERPENT)
|
||||
# define MAX_EXPANDED_KEY SERPENT_KS
|
||||
# elif defined (TC_WINDOWS_BOOT_TWOFISH)
|
||||
# define MAX_EXPANDED_KEY TWOFISH_KS
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
#define MAX_EXPANDED_KEY (AES_KS + SERPENT_KS + TWOFISH_KS)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define PRAND_DISK_WIPE_PASSES 3
|
||||
#else
|
||||
# define PRAND_DISK_WIPE_PASSES 256
|
||||
#endif
|
||||
|
||||
#if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_AES)
|
||||
# include "Aes.h"
|
||||
#else
|
||||
# include "AesSmall.h"
|
||||
#endif
|
||||
|
||||
#include "Aes_hw_cpu.h"
|
||||
#include "Blowfish.h"
|
||||
#include "Cast.h"
|
||||
#include "Des.h"
|
||||
#include "Serpent.h"
|
||||
#include "Twofish.h"
|
||||
|
||||
#include "Rmd160.h"
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
# include "Sha1.h"
|
||||
# include "Sha2.h"
|
||||
# include "Whirlpool.h"
|
||||
#endif
|
||||
|
||||
#include "GfMul.h"
|
||||
#include "Password.h"
|
||||
|
||||
typedef struct keyInfo_t
|
||||
{
|
||||
int noIterations; /* Number of times to iterate (PKCS-5) */
|
||||
int keyLength; /* Length of the key */
|
||||
__int8 userKey[MAX_PASSWORD]; /* Password (to which keyfiles may have been applied). WITHOUT +1 for the null terminator. */
|
||||
__int8 salt[PKCS5_SALT_SIZE]; /* PKCS-5 salt */
|
||||
__int8 master_keydata[MASTER_KEYDATA_SIZE]; /* Concatenated master primary and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
|
||||
} KEY_INFO, *PKEY_INFO;
|
||||
|
||||
typedef struct CRYPTO_INFO_t
|
||||
{
|
||||
int ea; /* Encryption algorithm ID */
|
||||
int mode; /* Mode of operation (e.g., XTS) */
|
||||
unsigned __int8 ks[MAX_EXPANDED_KEY]; /* Primary key schedule (if it is a cascade, it conatins multiple concatenated keys) */
|
||||
unsigned __int8 ks2[MAX_EXPANDED_KEY]; /* Secondary key schedule (if cascade, multiple concatenated) for XTS mode. */
|
||||
|
||||
BOOL hiddenVolume; // Indicates whether the volume is mounted/mountable as hidden volume
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
uint16 HeaderVersion;
|
||||
|
||||
GfCtx gf_ctx;
|
||||
|
||||
unsigned __int8 master_keydata[MASTER_KEYDATA_SIZE]; /* This holds the volume header area containing concatenated master key(s) and secondary key(s) (XTS mode). For LRW (deprecated/legacy), it contains the tweak key before the master key(s). For CBC (deprecated/legacy), it contains the IV seed before the master key(s). */
|
||||
unsigned __int8 k2[MASTER_KEYDATA_SIZE]; /* For XTS, this contains the secondary key (if cascade, multiple concatenated). For LRW (deprecated/legacy), it contains the tweak key. For CBC (deprecated/legacy), it contains the IV seed. */
|
||||
unsigned __int8 salt[PKCS5_SALT_SIZE];
|
||||
int noIterations;
|
||||
int pkcs5;
|
||||
|
||||
uint64 volume_creation_time; // Legacy
|
||||
uint64 header_creation_time; // Legacy
|
||||
|
||||
BOOL bProtectHiddenVolume; // Indicates whether the volume contains a hidden volume to be protected against overwriting
|
||||
BOOL bHiddenVolProtectionAction; // TRUE if a write operation has been denied by the driver in order to prevent the hidden volume from being overwritten (set to FALSE upon volume mount).
|
||||
|
||||
uint64 volDataAreaOffset; // Absolute position, in bytes, of the first data sector of the volume.
|
||||
|
||||
uint64 hiddenVolumeSize; // Size of the hidden volume excluding the header (in bytes). Set to 0 for standard volumes.
|
||||
uint64 hiddenVolumeOffset; // Absolute position, in bytes, of the first hidden volume data sector within the host volume (provided that there is a hidden volume within). This must be set for all hidden volumes; in case of a normal volume, this variable is only used when protecting a hidden volume within it.
|
||||
uint64 hiddenVolumeProtectedSize;
|
||||
|
||||
BOOL bPartitionInInactiveSysEncScope; // If TRUE, the volume is a partition located on an encrypted system drive and mounted without pre-boot authentication.
|
||||
|
||||
UINT64_STRUCT FirstDataUnitNo; // First data unit number of the volume. This is 0 for file-hosted and non-system partition-hosted volumes. For partitions within key scope of system encryption this reflects real physical offset within the device (this is used e.g. when such a partition is mounted as a regular volume without pre-boot authentication).
|
||||
|
||||
uint16 RequiredProgramVersion;
|
||||
BOOL LegacyVolume;
|
||||
|
||||
uint32 SectorSize;
|
||||
|
||||
#endif // !TC_WINDOWS_BOOT
|
||||
|
||||
UINT64_STRUCT VolumeSize;
|
||||
|
||||
UINT64_STRUCT EncryptedAreaStart;
|
||||
UINT64_STRUCT EncryptedAreaLength;
|
||||
|
||||
uint32 HeaderFlags;
|
||||
|
||||
} CRYPTO_INFO, *PCRYPTO_INFO;
|
||||
|
||||
PCRYPTO_INFO crypto_open (void);
|
||||
void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen);
|
||||
void crypto_close (PCRYPTO_INFO cryptoInfo);
|
||||
|
||||
int CipherGetBlockSize (int cipher);
|
||||
int CipherGetKeySize (int cipher);
|
||||
int CipherGetKeyScheduleSize (int cipher);
|
||||
BOOL CipherSupportsIntraDataUnitParallelization (int cipher);
|
||||
char * CipherGetName (int cipher);
|
||||
|
||||
int CipherInit (int cipher, unsigned char *key, unsigned char *ks);
|
||||
int EAInit (int ea, unsigned char *key, unsigned char *ks);
|
||||
BOOL EAInitMode (PCRYPTO_INFO ci);
|
||||
void EncipherBlock(int cipher, void *data, void *ks);
|
||||
void DecipherBlock(int cipher, void *data, void *ks);
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount);
|
||||
void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount);
|
||||
#endif
|
||||
|
||||
int EAGetFirst ();
|
||||
int EAGetCount (void);
|
||||
int EAGetNext (int previousEA);
|
||||
char * EAGetName (char *buf, int ea);
|
||||
int EAGetByName (char *name);
|
||||
int EAGetKeySize (int ea);
|
||||
int EAGetFirstMode (int ea);
|
||||
int EAGetNextMode (int ea, int previousModeId);
|
||||
char * EAGetModeName (int ea, int mode, BOOL capitalLetters);
|
||||
int EAGetKeyScheduleSize (int ea);
|
||||
int EAGetLargestKey ();
|
||||
int EAGetLargestKeyForMode (int mode);
|
||||
|
||||
int EAGetCipherCount (int ea);
|
||||
int EAGetFirstCipher (int ea);
|
||||
int EAGetLastCipher (int ea);
|
||||
int EAGetNextCipher (int ea, int previousCipherId);
|
||||
int EAGetPreviousCipher (int ea, int previousCipherId);
|
||||
int EAIsFormatEnabled (int ea);
|
||||
BOOL EAIsModeSupported (int ea, int testedMode);
|
||||
|
||||
char *HashGetName (int hash_algo_id);
|
||||
BOOL HashIsDeprecated (int hashId);
|
||||
|
||||
int GetMaxPkcs5OutSize (void);
|
||||
|
||||
void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci);
|
||||
void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
|
||||
void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci);
|
||||
void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci);
|
||||
void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo);
|
||||
void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo);
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
void EncryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
void DecryptBufferLRW128 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
void EncryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
void DecryptBufferLRW64 (byte *buffer, uint64 length, uint64 blockIndex, PCRYPTO_INFO cryptoInfo);
|
||||
uint64 DataUnit2LRWIndex (uint64 dataUnit, int blockSize, PCRYPTO_INFO ci);
|
||||
#endif // #ifndef TC_NO_COMPILER_INT64
|
||||
|
||||
BOOL IsAesHwCpuSupported ();
|
||||
void EnableHwEncryption (BOOL enable);
|
||||
BOOL IsHwEncryptionEnabled ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYPTO_H */
|
||||
80
src/Common/Dictionary.c
Normal file
80
src/Common/Dictionary.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "../Common/Dictionary.h"
|
||||
#include <windows.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static map <string, void *> StringKeyMap;
|
||||
static map <int, void *> IntKeyMap;
|
||||
|
||||
static void *DataPool = NULL;
|
||||
static size_t DataPoolSize = 0;
|
||||
|
||||
|
||||
void AddDictionaryEntry (char *key, int intKey, void *value)
|
||||
{
|
||||
if (key)
|
||||
StringKeyMap[key] = value;
|
||||
|
||||
if (intKey != 0)
|
||||
IntKeyMap[intKey] = value;
|
||||
}
|
||||
|
||||
|
||||
void *GetDictionaryValue (const char *key)
|
||||
{
|
||||
map <string, void *>::const_iterator i = StringKeyMap.find (key);
|
||||
|
||||
if (i == StringKeyMap.end())
|
||||
return NULL;
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
void *GetDictionaryValueByInt (int intKey)
|
||||
{
|
||||
map <int, void *>::const_iterator i = IntKeyMap.find (intKey);
|
||||
|
||||
if (i == IntKeyMap.end())
|
||||
return NULL;
|
||||
|
||||
return i->second;
|
||||
}
|
||||
|
||||
|
||||
void *AddPoolData (void *data, size_t dataSize)
|
||||
{
|
||||
if (DataPoolSize + dataSize > DATA_POOL_CAPACITY) return NULL;
|
||||
|
||||
if (DataPool == NULL)
|
||||
{
|
||||
DataPool = malloc (DATA_POOL_CAPACITY);
|
||||
if (DataPool == NULL) return NULL;
|
||||
}
|
||||
|
||||
memcpy ((BYTE *)DataPool + DataPoolSize, data, dataSize);
|
||||
|
||||
// Ensure 32-bit alignment for next entries
|
||||
dataSize = (dataSize + 3) & (~(size_t)3);
|
||||
|
||||
DataPoolSize += dataSize;
|
||||
return (BYTE *)DataPool + DataPoolSize - dataSize;
|
||||
}
|
||||
|
||||
|
||||
void ClearDictionaryPool ()
|
||||
{
|
||||
DataPoolSize = 0;
|
||||
StringKeyMap.clear();
|
||||
IntKeyMap.clear();
|
||||
}
|
||||
30
src/Common/Dictionary.h
Normal file
30
src/Common/Dictionary.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef DICTIONARY_H
|
||||
#define DICTIONARY_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DATA_POOL_CAPACITY 1000000
|
||||
|
||||
void AddDictionaryEntry (char *key, int intKey, void *value);
|
||||
void *GetDictionaryValue (const char *key);
|
||||
void *GetDictionaryValueByInt (int intKey);
|
||||
void *AddPoolData (void *data, size_t dataSize);
|
||||
void ClearDictionaryPool ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
9848
src/Common/Dlgcode.c
Normal file
9848
src/Common/Dlgcode.c
Normal file
File diff suppressed because it is too large
Load Diff
532
src/Common/Dlgcode.h
Normal file
532
src/Common/Dlgcode.h
Normal file
@@ -0,0 +1,532 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_DLGCODE
|
||||
#define TC_HEADER_DLGCODE
|
||||
|
||||
#include "Common.h"
|
||||
#include "Apidrvr.h"
|
||||
#include "Keyfiles.h"
|
||||
#include "Wipe.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* IDs for dynamically generated GUI elements */
|
||||
enum dynamic_gui_element_ids
|
||||
{
|
||||
IDPM_CHECK_FILESYS = 500001,
|
||||
IDPM_REPAIR_FILESYS,
|
||||
IDPM_OPEN_VOLUME,
|
||||
IDPM_SELECT_FILE_AND_MOUNT,
|
||||
IDPM_SELECT_DEVICE_AND_MOUNT,
|
||||
IDPM_ADD_TO_FAVORITES,
|
||||
IDPM_ADD_TO_SYSTEM_FAVORITES,
|
||||
IDM_SHOW_HIDE,
|
||||
IDM_HOMEPAGE_SYSTRAY
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TC_TBXID_LEGAL_NOTICES,
|
||||
TC_TBXID_SYS_ENCRYPTION_PRETEST,
|
||||
TC_TBXID_SYS_ENC_RESCUE_DISK,
|
||||
TC_TBXID_DECOY_OS_INSTRUCTIONS,
|
||||
TC_TBXID_EXTRA_BOOT_PARTITION_REMOVAL_INSTRUCTIONS
|
||||
};
|
||||
|
||||
#define TC_APPLICATION_ID L"TrueCryptFoundation.TrueCrypt"
|
||||
|
||||
#define TC_MUTEX_NAME_SYSENC "Global\\TrueCrypt System Encryption Wizard"
|
||||
#define TC_MUTEX_NAME_NONSYS_INPLACE_ENC "Global\\TrueCrypt In-Place Encryption Wizard"
|
||||
#define TC_MUTEX_NAME_APP_SETUP "Global\\TrueCrypt Setup"
|
||||
#define TC_MUTEX_NAME_DRIVER_SETUP "Global\\TrueCrypt Driver Setup"
|
||||
|
||||
#define IDC_ABOUT 0x7fff /* ID for AboutBox on system menu in wm_user range */
|
||||
|
||||
#define EXCL_ACCESS_MAX_AUTO_RETRIES 500
|
||||
#define EXCL_ACCESS_AUTO_RETRY_DELAY 10
|
||||
|
||||
#define UNMOUNT_MAX_AUTO_RETRIES 30
|
||||
#define UNMOUNT_AUTO_RETRY_DELAY 50
|
||||
|
||||
// After the user receives the "Incorrect password" error this number of times in a row, we should automatically
|
||||
// try using the embedded header backup (if any). This ensures that the "Incorrect password" message is reported faster
|
||||
// initially (most such errors are really caused by supplying an incorrect password, not by header corruption).
|
||||
#define TC_TRY_HEADER_BAK_AFTER_NBR_WRONG_PWD_TRIES 2
|
||||
|
||||
#define MAX_MULTI_CHOICES 10 /* Maximum number of options for mutliple-choice dialog */
|
||||
|
||||
#define TC_APPD_FILENAME_CONFIGURATION "Configuration.xml"
|
||||
#define TC_APPD_FILENAME_SYSTEM_ENCRYPTION "System Encryption.xml"
|
||||
#define TC_APPD_FILENAME_DEFAULT_KEYFILES "Default Keyfiles.xml"
|
||||
#define TC_APPD_FILENAME_HISTORY "History.xml"
|
||||
#define TC_APPD_FILENAME_FAVORITE_VOLUMES "Favorite Volumes.xml"
|
||||
#define TC_APPD_FILENAME_SYSTEM_FAVORITE_VOLUMES TC_APP_NAME " System Favorite Volumes.xml"
|
||||
#define TC_APPD_FILENAME_NONSYS_INPLACE_ENC "In-Place Encryption"
|
||||
#define TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE "In-Place Encryption Wipe Algo"
|
||||
#define TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL "Post-Install Task - Tutorial"
|
||||
#define TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES "Post-Install Task - Release Notes"
|
||||
|
||||
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||
#define USER_DEFAULT_SCREEN_DPI 96
|
||||
#endif
|
||||
|
||||
#if (USER_DEFAULT_SCREEN_DPI != 96)
|
||||
# error Revision of GUI and graphics necessary, since everything assumes default screen DPI as 96 (note that 96 is the default on Windows 2000, XP, and Vista).
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
TC_POST_INSTALL_CFG_REMOVE_ALL = 0,
|
||||
TC_POST_INSTALL_CFG_TUTORIAL,
|
||||
TC_POST_INSTALL_CFG_RELEASE_NOTES
|
||||
};
|
||||
|
||||
extern char *LastDialogId;
|
||||
extern char *ConfigBuffer;
|
||||
extern char szHelpFile[TC_MAX_PATH];
|
||||
extern char szHelpFile2[TC_MAX_PATH];
|
||||
extern char SecurityTokenLibraryPath[TC_MAX_PATH];
|
||||
extern HFONT hFixedDigitFont;
|
||||
extern HFONT hBoldFont;
|
||||
extern HFONT hTitleFont;
|
||||
extern HFONT hFixedFont;
|
||||
extern HFONT hUserFont;
|
||||
extern HFONT hUserUnderlineFont;
|
||||
extern HFONT hUserBoldFont;
|
||||
extern HFONT WindowTitleBarFont;
|
||||
extern int ScreenDPI;
|
||||
extern double DlgAspectRatio;
|
||||
extern HWND MainDlg;
|
||||
extern BOOL Silent;
|
||||
extern BOOL bHistory;
|
||||
extern BOOL bPreserveTimestamp;
|
||||
extern BOOL bStartOnLogon;
|
||||
extern BOOL bMountDevicesOnLogon;
|
||||
extern BOOL bMountFavoritesOnLogon;
|
||||
extern int HiddenSectorDetectionStatus;
|
||||
extern wchar_t *lpszTitle;
|
||||
extern OSVersionEnum nCurrentOS;
|
||||
extern int CurrentOSMajor;
|
||||
extern int CurrentOSMinor;
|
||||
extern int CurrentOSServicePack;
|
||||
extern BOOL RemoteSession;
|
||||
extern HANDLE hDriver;
|
||||
extern HINSTANCE hInst;
|
||||
extern int SystemEncryptionStatus;
|
||||
extern WipeAlgorithmId nWipeMode;
|
||||
extern BOOL bSysPartitionSelected;
|
||||
extern BOOL bSysDriveSelected;
|
||||
|
||||
extern BOOL bHyperLinkBeingTracked;
|
||||
extern BOOL bInPlaceEncNonSysPending;
|
||||
|
||||
extern BOOL KeyFilesEnable;
|
||||
extern KeyFile *FirstKeyFile;
|
||||
extern KeyFilesDlgParam defaultKeyFilesParam;
|
||||
extern BOOL UacElevated;
|
||||
extern BOOL IgnoreWmDeviceChange;
|
||||
extern BOOL DeviceChangeBroadcastDisabled;
|
||||
extern BOOL LastMountedVolumeDirty;
|
||||
extern BOOL MountVolumesAsSystemFavorite;
|
||||
extern BOOL FavoriteMountOnArrivalInProgress;
|
||||
extern BOOL MultipleMountOperationInProgress;
|
||||
|
||||
|
||||
enum tc_app_msg_ids
|
||||
{
|
||||
/* WARNING: Changing these values or their meanings may cause incompatibility with other versions
|
||||
(for example, if a new version of the TrueCrypt installer needed to shut down this version of
|
||||
TrueCrypt during upgrade, it could fail or do something unwanted because the signal value would
|
||||
be incorrect). When adding a new constant, verify that the value is unique within this block and
|
||||
that it is less than WM_APP+16383. */
|
||||
|
||||
// Common (inter-app)
|
||||
TC_APPMSG_CLOSE_BKG_TASK = WM_APP + 4, // Changing this value will prevent smooth upgrades from pre-5.x versions
|
||||
TC_APPMSG_SYSENC_CONFIG_UPDATE = WM_APP + 101,
|
||||
TC_APPMSG_TASKBAR_ICON = WM_APP + 102,
|
||||
TC_APPMSG_LOAD_TEXT_BOX_CONTENT = WM_APP + 103,
|
||||
// Mount
|
||||
TC_APPMSG_MOUNT_ENABLE_DISABLE_CONTROLS = WM_APP + 201,
|
||||
TC_APPMSG_MOUNT_SHOW_WINDOW = WM_APP + 202,
|
||||
TC_APPMSG_PREBOOT_PASSWORD_MODE = WM_APP + 203,
|
||||
// Format
|
||||
TC_APPMSG_VOL_TRANSFORM_THREAD_ENDED = WM_APP + 301,
|
||||
TC_APPMSG_FORMAT_FINISHED = WM_APP + 302,
|
||||
TC_APPMSG_FORMAT_USER_QUIT = WM_APP + 303,
|
||||
TC_APPMSG_PERFORM_POST_WMINIT_TASKS = WM_APP + 304,
|
||||
TC_APPMSG_PERFORM_POST_SYSENC_WMINIT_TASKS = WM_APP + 305,
|
||||
TC_APPMSG_NONSYS_INPLACE_ENC_FINISHED = WM_APP + 306,
|
||||
// Setup
|
||||
TC_APPMSG_INSTALL_SUCCESS = WM_APP + 401,
|
||||
TC_APPMSG_UNINSTALL_SUCCESS = WM_APP + 402,
|
||||
TC_APPMSG_EXTRACTION_SUCCESS = WM_APP + 403,
|
||||
TC_APPMSG_INSTALL_FAILURE = WM_APP + 404,
|
||||
TC_APPMSG_UNINSTALL_FAILURE = WM_APP + 405,
|
||||
TC_APPMSG_EXTRACTION_FAILURE = WM_APP + 406
|
||||
};
|
||||
|
||||
enum system_encryption_status
|
||||
{
|
||||
/* WARNING: As these values are written to config files, if they or their meanings
|
||||
are changed, incompatiblity with other versions may arise (upgrade, downgrade, etc.).
|
||||
When adding a new constant, verify that the value is unique within this block. */
|
||||
SYSENC_STATUS_NONE = 0,
|
||||
SYSENC_STATUS_PRETEST = 200, // This may also mean that the OS is to be (or has been) copied to a hidden volume (to create a hidden OS).
|
||||
SYSENC_STATUS_ENCRYPTING = 400,
|
||||
SYSENC_STATUS_DECRYPTING = 600
|
||||
};
|
||||
|
||||
enum vol_creation_wizard_modes
|
||||
{
|
||||
WIZARD_MODE_FILE_CONTAINER = 0,
|
||||
WIZARD_MODE_NONSYS_DEVICE,
|
||||
WIZARD_MODE_SYS_DEVICE
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL VolumeIsOpen;
|
||||
|
||||
CRYPTO_INFO *CryptoInfo;
|
||||
BOOL IsDevice;
|
||||
HANDLE HostFileHandle;
|
||||
uint64 HostSize;
|
||||
|
||||
BOOL TimestampsValid;
|
||||
FILETIME CreationTime;
|
||||
FILETIME LastWriteTime;
|
||||
FILETIME LastAccessTime;
|
||||
|
||||
} OpenVolumeContext;
|
||||
|
||||
|
||||
#define DEFAULT_VOL_CREATION_WIZARD_MODE WIZARD_MODE_FILE_CONTAINER
|
||||
|
||||
#define ICON_HAND MB_ICONHAND
|
||||
#define YES_NO MB_YESNO
|
||||
|
||||
#define ISO_BURNER_TOOL "isoburn.exe"
|
||||
#define PRINT_TOOL "notepad"
|
||||
|
||||
void cleanup ( void );
|
||||
void LowerCaseCopy ( char *lpszDest , const char *lpszSource );
|
||||
void UpperCaseCopy ( char *lpszDest , const char *lpszSource );
|
||||
void CreateFullVolumePath ( char *lpszDiskFile , const char *lpszFileName , BOOL *bDevice );
|
||||
int FakeDosNameForDevice ( const char *lpszDiskFile , char *lpszDosDevice , char *lpszCFDevice , BOOL bNameOnly );
|
||||
int RemoveFakeDosName ( char *lpszDiskFile , char *lpszDosDevice );
|
||||
void AbortProcess ( char *stringId );
|
||||
void AbortProcessSilent ( void );
|
||||
void *err_malloc ( size_t size );
|
||||
char *err_strdup ( char *lpszText );
|
||||
DWORD handleWin32Error ( HWND hwndDlg );
|
||||
BOOL IsDiskReadError (DWORD error);
|
||||
BOOL IsDiskWriteError (DWORD error);
|
||||
BOOL IsDiskError (DWORD error);
|
||||
BOOL translateWin32Error ( wchar_t *lpszMsgBuf , int nWSizeOfBuf );
|
||||
BOOL CALLBACK AboutDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam );
|
||||
static BOOL CALLBACK StaticModelessWaitDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void DisplayStaticModelessWaitDlg (HWND parent);
|
||||
void CloseStaticModelessWaitDlg (void);
|
||||
BOOL IsButtonChecked ( HWND hButton );
|
||||
void CheckButton ( HWND hButton );
|
||||
void LeftPadString (char *szTmp, int len, int targetLen, char filler);
|
||||
void ToSBCS ( LPWSTR lpszText );
|
||||
void ToUNICODE ( char *lpszText );
|
||||
void InitDialog ( HWND hwndDlg );
|
||||
void ProcessPaintMessages (HWND hwnd, int maxMessagesToProcess);
|
||||
HDC CreateMemBitmap ( HINSTANCE hInstance , HWND hwnd , char *resource );
|
||||
HBITMAP RenderBitmap ( char *resource , HWND hwndDest , int x , int y , int nWidth , int nHeight , BOOL bDirectRender , BOOL bKeepAspectRatio);
|
||||
LRESULT CALLBACK RedTick ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
BOOL RegisterRedTick ( HINSTANCE hInstance );
|
||||
BOOL UnregisterRedTick ( HINSTANCE hInstance );
|
||||
LRESULT CALLBACK SplashDlgProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
void WaitCursor ( void );
|
||||
void NormalCursor ( void );
|
||||
void ArrowWaitCursor ( void );
|
||||
void HandCursor ();
|
||||
void AddComboPair (HWND hComboBox, const char *lpszItem, int value);
|
||||
void AddComboPairW (HWND hComboBox, const wchar_t *lpszItem, int value);
|
||||
void SelectAlgo ( HWND hComboBox , int *nCipher );
|
||||
void PopulateWipeModeCombo (HWND hComboBox, BOOL bNA, BOOL bInPlaceEncryption);
|
||||
wchar_t *GetWipeModeName (WipeAlgorithmId modeId);
|
||||
wchar_t *GetPathType (const char *path, BOOL bUpperCase, BOOL *bIsPartition);
|
||||
LRESULT CALLBACK CustomDlgProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
BOOL TCCreateMutex (volatile HANDLE *hMutex, char *name);
|
||||
void TCCloseMutex (volatile HANDLE *hMutex);
|
||||
BOOL MutexExistsOnSystem (char *name);
|
||||
BOOL CreateSysEncMutex (void);
|
||||
BOOL InstanceHasSysEncMutex (void);
|
||||
void CloseSysEncMutex (void);
|
||||
BOOL CreateNonSysInplaceEncMutex (void);
|
||||
BOOL InstanceHasNonSysInplaceEncMutex (void);
|
||||
void CloseNonSysInplaceEncMutex (void);
|
||||
BOOL NonSysInplaceEncInProgressElsewhere (void);
|
||||
BOOL CreateDriverSetupMutex (void);
|
||||
void CloseDriverSetupMutex (void);
|
||||
BOOL CreateAppSetupMutex (void);
|
||||
BOOL InstanceHasAppSetupMutex (void);
|
||||
void CloseAppSetupMutex (void);
|
||||
BOOL IsTrueCryptInstallerRunning (void);
|
||||
uint32 ReadDriverConfigurationFlags ();
|
||||
uint32 ReadEncryptionThreadPoolFreeCpuCountLimit ();
|
||||
BOOL LoadSysEncSettings (HWND hwndDlg);
|
||||
int LoadNonSysInPlaceEncSettings (WipeAlgorithmId *wipeAlgorithm);
|
||||
void RemoveNonSysInPlaceEncNotifications (void);
|
||||
void SavePostInstallTasksSettings (int command);
|
||||
void DoPostInstallTasks (void);
|
||||
void InitOSVersionInfo ();
|
||||
void InitApp ( HINSTANCE hInstance, char *lpszCommandLine );
|
||||
void InitHelpFileName (void);
|
||||
BOOL OpenDevice (const char *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem);
|
||||
void NotifyDriverOfPortableMode (void);
|
||||
int GetAvailableFixedDisks ( HWND hComboBox , char *lpszRootPath );
|
||||
int GetAvailableRemovables ( HWND hComboBox , char *lpszRootPath );
|
||||
int IsSystemDevicePath (char *path, HWND hwndDlg, BOOL bReliableRequired);
|
||||
BOOL CALLBACK RawDevicesDlgProc ( HWND hwndDlg , UINT msg , WPARAM wParam , LPARAM lParam );
|
||||
BOOL TextInfoDialogBox (int nID);
|
||||
BOOL CALLBACK TextInfoDialogBoxDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
char * GetLegalNotices ();
|
||||
BOOL CALLBACK BenchmarkDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void UserEnrichRandomPool (HWND hwndDlg);
|
||||
BOOL CALLBACK KeyfileGeneratorDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK MultiChoiceDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
int DriverAttach ( void );
|
||||
BOOL CALLBACK CipherTestDialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam );
|
||||
void ResetCipherTest ( HWND hwndDlg , int idTestCipher );
|
||||
void ResetCurrentDirectory ();
|
||||
BOOL BrowseFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter);
|
||||
BOOL BrowseDirectories (HWND hWnd, char *lpszTitle, char *dirName);
|
||||
void handleError ( HWND hwndDlg , int code );
|
||||
BOOL CheckFileStreamWriteErrors (FILE *file, const char *fileName);
|
||||
void LocalizeDialog ( HWND hwnd, char *stringId );
|
||||
void OpenVolumeExplorerWindow (int driveNo);
|
||||
static BOOL CALLBACK CloseVolumeExplorerWindowsEnum( HWND hwnd, LPARAM driveNo);
|
||||
BOOL CloseVolumeExplorerWindows (HWND hwnd, int driveNo);
|
||||
BOOL CheckCapsLock (HWND hwnd, BOOL quiet);
|
||||
BOOL CheckFileExtension (char *fileName);
|
||||
void IncreaseWrongPwdRetryCount (int count);
|
||||
void ResetWrongPwdRetryCount (void);
|
||||
BOOL WrongPwdRetryCountOverLimit (void);
|
||||
int GetFirstAvailableDrive ();
|
||||
int GetLastAvailableDrive ();
|
||||
BOOL IsDriveAvailable (int driveNo);
|
||||
BOOL IsDeviceMounted (char *deviceName);
|
||||
int DriverUnmountVolume (HWND hwndDlg, int nDosDriveNo, BOOL forced);
|
||||
void BroadcastDeviceChange (WPARAM message, int nDosDriveNo, DWORD driveMap);
|
||||
int MountVolume (HWND hwndDlg, int driveNo, char *volumePath, Password *password, BOOL cachePassword, BOOL sharedAccess, const MountOptions* const mountOptions, BOOL quiet, BOOL bReportWrongPassword);
|
||||
BOOL UnmountVolume (HWND hwndDlg , int nDosDriveNo, BOOL forceUnmount);
|
||||
BOOL IsPasswordCacheEmpty (void);
|
||||
BOOL IsMountedVolume (const char *volname);
|
||||
int GetMountedVolumeDriveNo (char *volname);
|
||||
BOOL IsAdmin (void);
|
||||
BOOL IsBuiltInAdmin ();
|
||||
BOOL IsUacSupported ();
|
||||
BOOL ResolveSymbolicLink (const wchar_t *symLinkName, PWSTR targetName);
|
||||
int GetDiskDeviceDriveLetter (PWSTR deviceName);
|
||||
int FileSystemAppearsEmpty (const char *devicePath);
|
||||
__int64 GetStatsFreeSpaceOnPartition (const char *devicePath, float *percent, __int64 *occupiedBytes, BOOL silent);
|
||||
__int64 GetDeviceSize (const char *devicePath);
|
||||
HANDLE DismountDrive (char *devName, char *devicePath);
|
||||
int64 FindString (const char *buf, const char *str, int64 bufLen, size_t strLen, int64 startOffset);
|
||||
BOOL FileExists (const char *filePathPtr);
|
||||
__int64 FindStringInFile (const char *filePath, const char *str, int strLen);
|
||||
BOOL TCCopyFile (char *sourceFileName, char *destinationFile);
|
||||
BOOL SaveBufferToFile (const char *inputBuffer, const char *destinationFile, DWORD inputLength, BOOL bAppend);
|
||||
BOOL TCFlushFile (FILE *f);
|
||||
BOOL PrintHardCopyTextUTF16 (wchar_t *text, char *title, int byteLen);
|
||||
void GetSpeedString (unsigned __int64 speed, wchar_t *str);
|
||||
BOOL IsNonInstallMode ();
|
||||
BOOL DriverUnload ();
|
||||
LRESULT SetCheckBox (HWND hwndDlg, int dlgItem, BOOL state);
|
||||
BOOL GetCheckBox (HWND hwndDlg, int dlgItem);
|
||||
void SetListScrollHPos (HWND hList, int topMostVisibleItem);
|
||||
void ManageStartupSeq (void);
|
||||
void ManageStartupSeqWiz (BOOL bRemove, const char *arg);
|
||||
void CleanLastVisitedMRU (void);
|
||||
void ClearHistory (HWND hwndDlgItem);
|
||||
LRESULT ListItemAdd (HWND list, int index, char *string);
|
||||
LRESULT ListItemAddW (HWND list, int index, wchar_t *string);
|
||||
LRESULT ListSubItemSet (HWND list, int index, int subIndex, char *string);
|
||||
LRESULT ListSubItemSetW (HWND list, int index, int subIndex, wchar_t *string);
|
||||
BOOL GetMountList (MOUNT_LIST_STRUCT *list);
|
||||
int GetDriverRefCount ();
|
||||
void GetSizeString (unsigned __int64 size, wchar_t *str);
|
||||
__int64 GetFileSize64 (const char *path);
|
||||
BOOL LoadInt16 (char *filePath, int *result, __int64 fileOffset);
|
||||
BOOL LoadInt32 (char *filePath, unsigned __int32 *result, __int64 fileOffset);
|
||||
char *LoadFile (const char *fileName, DWORD *size);
|
||||
char *LoadFileBlock (char *fileName, __int64 fileOffset, size_t count);
|
||||
char *GetModPath (char *path, int maxSize);
|
||||
char *GetConfigPath (char *fileName);
|
||||
char *GetProgramConfigPath (char *fileName);
|
||||
char GetSystemDriveLetter (void);
|
||||
void OpenPageHelp (HWND hwndDlg, int nPage);
|
||||
void TaskBarIconDisplayBalloonTooltip (HWND hwnd, wchar_t *headline, wchar_t *text, BOOL warning);
|
||||
void InfoBalloon (char *headingStringId, char *textStringId);
|
||||
void InfoBalloonDirect (wchar_t *headingString, wchar_t *textString);
|
||||
void WarningBalloon (char *headingStringId, char *textStringId);
|
||||
void WarningBalloonDirect (wchar_t *headingString, wchar_t *textString);
|
||||
int Info (char *stringId);
|
||||
int InfoTopMost (char *stringId);
|
||||
int InfoDirect (const wchar_t *msg);
|
||||
int Warning (char *stringId);
|
||||
int WarningTopMost (char *stringId);
|
||||
int WarningDirect (const wchar_t *warnMsg);
|
||||
int Error (char *stringId);
|
||||
int ErrorDirect (const wchar_t *errMsg);
|
||||
int ErrorTopMost (char *stringId);
|
||||
int AskYesNo (char *stringId);
|
||||
int AskYesNoString (const wchar_t *str);
|
||||
int AskYesNoTopmost (char *stringId);
|
||||
int AskNoYes (char *stringId);
|
||||
int AskOkCancel (char *stringId);
|
||||
int AskWarnYesNo (char *stringId);
|
||||
int AskWarnYesNoString (const wchar_t *string);
|
||||
int AskWarnYesNoTopmost (char *stringId);
|
||||
int AskWarnYesNoStringTopmost (const wchar_t *string);
|
||||
int AskWarnNoYes (char *stringId);
|
||||
int AskWarnNoYesString (const wchar_t *string);
|
||||
int AskWarnNoYesTopmost (char *stringId);
|
||||
int AskWarnOkCancel (char *stringId);
|
||||
int AskWarnCancelOk (char *stringId);
|
||||
int AskErrYesNo (char *stringId);
|
||||
int AskErrNoYes (char *stringId);
|
||||
int AskMultiChoice (void *strings[], BOOL bBold);
|
||||
BOOL ConfigWriteBegin ();
|
||||
BOOL ConfigWriteEnd ();
|
||||
BOOL ConfigWriteString (char *configKey, char *configValue);
|
||||
BOOL ConfigWriteInt (char *configKey, int configValue);
|
||||
int ConfigReadInt (char *configKey, int defaultValue);
|
||||
char *ConfigReadString (char *configKey, char *defaultValue, char *str, int maxLen);
|
||||
void RestoreDefaultKeyFilesParam (void);
|
||||
BOOL LoadDefaultKeyFilesParam (void);
|
||||
void Debug (char *format, ...);
|
||||
void DebugMsgBox (char *format, ...);
|
||||
BOOL IsOSAtLeast (OSVersionEnum reqMinOS);
|
||||
BOOL IsOSVersionAtLeast (OSVersionEnum reqMinOS, int reqMinServicePack);
|
||||
BOOL Is64BitOs ();
|
||||
BOOL IsServerOS ();
|
||||
BOOL IsHiddenOSRunning (void);
|
||||
BOOL EnableWow64FsRedirection (BOOL enable);
|
||||
BOOL RestartComputer (void);
|
||||
void Applink (char *dest, BOOL bSendOS, char *extraOutput);
|
||||
char *RelativePath2Absolute (char *szFileName);
|
||||
void HandleDriveNotReadyError ();
|
||||
BOOL CALLBACK CloseTCWindowsEnum( HWND hwnd, LPARAM lParam);
|
||||
BOOL CALLBACK FindTCWindowEnum (HWND hwnd, LPARAM lParam);
|
||||
BYTE *MapResource (char *resourceType, int resourceId, PDWORD size);
|
||||
void InconsistencyResolved (char *msg);
|
||||
void ReportUnexpectedState (char *techInfo);
|
||||
BOOL SelectMultipleFiles (HWND hwndDlg, char *stringId, char *lpszFileName, BOOL keepHistory);
|
||||
BOOL SelectMultipleFilesNext (char *lpszFileName);
|
||||
void OpenOnlineHelp ();
|
||||
BOOL GetPartitionInfo (const char *deviceName, PPARTITION_INFORMATION rpartInfo);
|
||||
BOOL GetDeviceInfo (const char *deviceName, DISK_PARTITION_INFO_STRUCT *info);
|
||||
BOOL GetDriveGeometry (const char *deviceName, PDISK_GEOMETRY diskGeometry);
|
||||
BOOL IsVolumeDeviceHosted (const char *lpszDiskFile);
|
||||
int CompensateXDPI (int val);
|
||||
int CompensateYDPI (int val);
|
||||
int CompensateDPIFont (int val);
|
||||
int GetTextGfxWidth (HWND hwndDlgItem, const wchar_t *text, HFONT hFont);
|
||||
int GetTextGfxHeight (HWND hwndDlgItem, const wchar_t *text, HFONT hFont);
|
||||
BOOL ToHyperlink (HWND hwndDlg, UINT ctrlId);
|
||||
BOOL ToCustHyperlink (HWND hwndDlg, UINT ctrlId, HFONT hFont);
|
||||
void ToBootPwdField (HWND hwndDlg, UINT ctrlId);
|
||||
void AccommodateTextField (HWND hwndDlg, UINT ctrlId, BOOL bFirstUpdate, HFONT hFont);
|
||||
BOOL GetDriveLabel (int driveNo, wchar_t *label, int labelSize);
|
||||
BOOL DoDriverInstall (HWND hwndDlg);
|
||||
int OpenVolume (OpenVolumeContext *context, const char *volumePath, Password *password, BOOL write, BOOL preserveTimestamps, BOOL useBackupHeader);
|
||||
void CloseVolume (OpenVolumeContext *context);
|
||||
int ReEncryptVolumeHeader (char *buffer, BOOL bBoot, CRYPTO_INFO *cryptoInfo, Password *password, BOOL wipeMode);
|
||||
BOOL IsPagingFileActive (BOOL checkNonWindowsPartitionsOnly);
|
||||
BOOL IsPagingFileWildcardActive ();
|
||||
BOOL DisablePagingFile ();
|
||||
BOOL CALLBACK SecurityTokenPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL InitSecurityTokenLibrary ();
|
||||
BOOL FileHasReadOnlyAttribute (const char *path);
|
||||
BOOL IsFileOnReadOnlyFilesystem (const char *path);
|
||||
void CheckFilesystem (int driveNo, BOOL fixErrors);
|
||||
BOOL BufferContainsString (const byte *buffer, size_t bufferSize, const char *str);
|
||||
int AskNonSysInPlaceEncryptionResume ();
|
||||
BOOL RemoveDeviceWriteProtection (HWND hwndDlg, char *devicePath);
|
||||
void EnableElevatedCursorChange (HWND parent);
|
||||
BOOL DisableFileCompression (HANDLE file);
|
||||
BOOL VolumePathExists (char *volumePath);
|
||||
BOOL IsWindowsIsoBurnerAvailable ();
|
||||
BOOL LaunchWindowsIsoBurner (HWND hwnd, const char *isoPath);
|
||||
BOOL IsApplicationInstalled (const char *appName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
struct HostDevice
|
||||
{
|
||||
HostDevice ()
|
||||
:
|
||||
Bootable (false),
|
||||
ContainsSystem (false),
|
||||
DynamicVolume (false),
|
||||
Floppy (false),
|
||||
IsPartition (false),
|
||||
IsVirtualPartition (false),
|
||||
HasUnencryptedFilesystem (false),
|
||||
Removable (false),
|
||||
Size (0)
|
||||
{
|
||||
}
|
||||
|
||||
~HostDevice () { }
|
||||
|
||||
bool Bootable;
|
||||
bool ContainsSystem;
|
||||
bool DynamicVolume;
|
||||
bool Floppy;
|
||||
bool IsPartition;
|
||||
bool IsVirtualPartition;
|
||||
bool HasUnencryptedFilesystem;
|
||||
std::string MountPoint;
|
||||
std::wstring Name;
|
||||
std::string Path;
|
||||
bool Removable;
|
||||
uint64 Size;
|
||||
uint32 SystemNumber;
|
||||
|
||||
std::vector <HostDevice> Partitions;
|
||||
};
|
||||
|
||||
BOOL BrowseFilesInDir (HWND hwndDlg, char *stringId, char *initialDir, char *lpszFileName, BOOL keepHistory, BOOL saveMode, wchar_t *browseFilter, const wchar_t *initialFileName = NULL, const wchar_t *defaultExtension = NULL);
|
||||
std::wstring SingleStringToWide (const std::string &singleString);
|
||||
std::wstring Utf8StringToWide (const std::string &utf8String);
|
||||
std::string WideToSingleString (const std::wstring &wideString);
|
||||
std::string WideToUtf8String (const std::wstring &wideString);
|
||||
std::string StringToUpperCase (const std::string &str);
|
||||
std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties = false, bool singleList = false, bool noFloppy = true, bool detectUnencryptedFilesystems = false);
|
||||
std::string ToUpperCase (const std::string &str);
|
||||
std::wstring GetWrongPasswordErrorMessage (HWND hwndDlg);
|
||||
std::string GetWindowsEdition ();
|
||||
std::string FitPathInGfxWidth (HWND hwnd, HFONT hFont, LONG width, const std::string &path);
|
||||
std::string GetServiceConfigPath (const char *fileName);
|
||||
std::string VolumeGuidPathToDevicePath (std::string volumeGuidPath);
|
||||
std::string HarddiskVolumePathToPartitionPath (const std::string &harddiskVolumePath);
|
||||
std::string FindLatestFileOrDirectory (const std::string &directory, const char *namePattern, bool findDirectory, bool findFile);
|
||||
std::string GetUserFriendlyVersionString (int version);
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // TC_HEADER_DLGCODE
|
||||
507
src/Common/EncryptionThreadPool.c
Normal file
507
src/Common/EncryptionThreadPool.c
Normal file
@@ -0,0 +1,507 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "EncryptionThreadPool.h"
|
||||
#include "Pkcs5.h"
|
||||
#ifdef DEVICE_DRIVER
|
||||
#include "Driver/Ntdriver.h"
|
||||
#endif
|
||||
|
||||
#define TC_ENC_THREAD_POOL_MAX_THREAD_COUNT 64
|
||||
#define TC_ENC_THREAD_POOL_QUEUE_SIZE (TC_ENC_THREAD_POOL_MAX_THREAD_COUNT * 2)
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
|
||||
#define TC_THREAD_HANDLE PKTHREAD
|
||||
#define TC_THREAD_PROC VOID
|
||||
|
||||
#define TC_SET_EVENT(EVENT) KeSetEvent (&EVENT, IO_DISK_INCREMENT, FALSE)
|
||||
#define TC_CLEAR_EVENT(EVENT) KeClearEvent (&EVENT)
|
||||
|
||||
#define TC_MUTEX FAST_MUTEX
|
||||
#define TC_ACQUIRE_MUTEX(MUTEX) ExAcquireFastMutex (MUTEX)
|
||||
#define TC_RELEASE_MUTEX(MUTEX) ExReleaseFastMutex (MUTEX)
|
||||
|
||||
#else // !DEVICE_DRIVER
|
||||
|
||||
#define TC_THREAD_HANDLE HANDLE
|
||||
#define TC_THREAD_PROC unsigned __stdcall
|
||||
|
||||
#define TC_SET_EVENT(EVENT) SetEvent (EVENT)
|
||||
#define TC_CLEAR_EVENT(EVENT) ResetEvent (EVENT)
|
||||
|
||||
#define TC_MUTEX HANDLE
|
||||
#define TC_ACQUIRE_MUTEX(MUTEX) WaitForSingleObject (*(MUTEX), INFINITE)
|
||||
#define TC_RELEASE_MUTEX(MUTEX) ReleaseMutex (*(MUTEX))
|
||||
|
||||
#endif // !DEVICE_DRIVER
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WorkItemFree,
|
||||
WorkItemReady,
|
||||
WorkItemBusy
|
||||
} WorkItemState;
|
||||
|
||||
|
||||
typedef struct EncryptionThreadPoolWorkItemStruct
|
||||
{
|
||||
WorkItemState State;
|
||||
EncryptionThreadPoolWorkType Type;
|
||||
|
||||
TC_EVENT ItemCompletedEvent;
|
||||
|
||||
struct EncryptionThreadPoolWorkItemStruct *FirstFragment;
|
||||
LONG OutstandingFragmentCount;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
PCRYPTO_INFO CryptoInfo;
|
||||
byte *Data;
|
||||
UINT64_STRUCT StartUnitNo;
|
||||
uint32 UnitCount;
|
||||
|
||||
} Encryption;
|
||||
|
||||
struct
|
||||
{
|
||||
TC_EVENT *CompletionEvent;
|
||||
LONG *CompletionFlag;
|
||||
char *DerivedKey;
|
||||
int IterationCount;
|
||||
TC_EVENT *NoOutstandingWorkItemEvent;
|
||||
LONG *OutstandingWorkItemCount;
|
||||
char *Password;
|
||||
int PasswordLength;
|
||||
int Pkcs5Prf;
|
||||
char *Salt;
|
||||
|
||||
} KeyDerivation;
|
||||
};
|
||||
|
||||
} EncryptionThreadPoolWorkItem;
|
||||
|
||||
|
||||
static volatile BOOL ThreadPoolRunning = FALSE;
|
||||
static volatile BOOL StopPending = FALSE;
|
||||
|
||||
static uint32 ThreadCount;
|
||||
static TC_THREAD_HANDLE ThreadHandles[TC_ENC_THREAD_POOL_MAX_THREAD_COUNT];
|
||||
|
||||
static EncryptionThreadPoolWorkItem WorkItemQueue[TC_ENC_THREAD_POOL_QUEUE_SIZE];
|
||||
|
||||
static volatile int EnqueuePosition;
|
||||
static volatile int DequeuePosition;
|
||||
|
||||
static TC_MUTEX EnqueueMutex;
|
||||
static TC_MUTEX DequeueMutex;
|
||||
|
||||
static TC_EVENT WorkItemReadyEvent;
|
||||
static TC_EVENT WorkItemCompletedEvent;
|
||||
|
||||
|
||||
static WorkItemState GetWorkItemState (EncryptionThreadPoolWorkItem *workItem)
|
||||
{
|
||||
return InterlockedExchangeAdd ((LONG *) &workItem->State, 0);
|
||||
}
|
||||
|
||||
|
||||
static void SetWorkItemState (EncryptionThreadPoolWorkItem *workItem, WorkItemState newState)
|
||||
{
|
||||
InterlockedExchange ((LONG *) &workItem->State, (LONG) newState);
|
||||
}
|
||||
|
||||
|
||||
static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
|
||||
{
|
||||
EncryptionThreadPoolWorkItem *workItem;
|
||||
|
||||
while (!StopPending)
|
||||
{
|
||||
TC_ACQUIRE_MUTEX (&DequeueMutex);
|
||||
|
||||
workItem = &WorkItemQueue[DequeuePosition++];
|
||||
|
||||
if (DequeuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
|
||||
DequeuePosition = 0;
|
||||
|
||||
while (!StopPending && GetWorkItemState (workItem) != WorkItemReady)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemReadyEvent);
|
||||
}
|
||||
|
||||
SetWorkItemState (workItem, WorkItemBusy);
|
||||
|
||||
TC_RELEASE_MUTEX (&DequeueMutex);
|
||||
|
||||
if (StopPending)
|
||||
break;
|
||||
|
||||
switch (workItem->Type)
|
||||
{
|
||||
case DecryptDataUnitsWork:
|
||||
DecryptDataUnitsCurrentThread (workItem->Encryption.Data, &workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.CryptoInfo);
|
||||
break;
|
||||
|
||||
case EncryptDataUnitsWork:
|
||||
EncryptDataUnitsCurrentThread (workItem->Encryption.Data, &workItem->Encryption.StartUnitNo, workItem->Encryption.UnitCount, workItem->Encryption.CryptoInfo);
|
||||
break;
|
||||
|
||||
case DeriveKeyWork:
|
||||
switch (workItem->KeyDerivation.Pkcs5Prf)
|
||||
{
|
||||
case RIPEMD160:
|
||||
derive_key_ripemd160 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
derive_key_sha512 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
derive_key_whirlpool (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
case SHA1:
|
||||
derive_key_sha1 (workItem->KeyDerivation.Password, workItem->KeyDerivation.PasswordLength, workItem->KeyDerivation.Salt, PKCS5_SALT_SIZE,
|
||||
workItem->KeyDerivation.IterationCount, workItem->KeyDerivation.DerivedKey, GetMaxPkcs5OutSize());
|
||||
break;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
InterlockedExchange (workItem->KeyDerivation.CompletionFlag, TRUE);
|
||||
TC_SET_EVENT (*workItem->KeyDerivation.CompletionEvent);
|
||||
|
||||
if (InterlockedDecrement (workItem->KeyDerivation.OutstandingWorkItemCount) == 0)
|
||||
TC_SET_EVENT (*workItem->KeyDerivation.NoOutstandingWorkItemEvent);
|
||||
|
||||
SetWorkItemState (workItem, WorkItemFree);
|
||||
TC_SET_EVENT (WorkItemCompletedEvent);
|
||||
continue;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (workItem != workItem->FirstFragment)
|
||||
{
|
||||
SetWorkItemState (workItem, WorkItemFree);
|
||||
TC_SET_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
if (InterlockedDecrement (&workItem->FirstFragment->OutstandingFragmentCount) == 0)
|
||||
TC_SET_EVENT (workItem->FirstFragment->ItemCompletedEvent);
|
||||
}
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
PsTerminateSystemThread (STATUS_SUCCESS);
|
||||
#else
|
||||
_endthreadex (0);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
|
||||
{
|
||||
size_t cpuCount, i;
|
||||
|
||||
if (ThreadPoolRunning)
|
||||
return TRUE;
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
cpuCount = GetCpuCount();
|
||||
#else
|
||||
{
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetSystemInfo (&sysInfo);
|
||||
cpuCount = sysInfo.dwNumberOfProcessors;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cpuCount > encryptionFreeCpuCount)
|
||||
cpuCount -= encryptionFreeCpuCount;
|
||||
|
||||
if (cpuCount < 2)
|
||||
return TRUE;
|
||||
|
||||
if (cpuCount > TC_ENC_THREAD_POOL_MAX_THREAD_COUNT)
|
||||
cpuCount = TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
|
||||
|
||||
StopPending = FALSE;
|
||||
DequeuePosition = 0;
|
||||
EnqueuePosition = 0;
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
KeInitializeEvent (&WorkItemReadyEvent, SynchronizationEvent, FALSE);
|
||||
KeInitializeEvent (&WorkItemCompletedEvent, SynchronizationEvent, FALSE);
|
||||
#else
|
||||
WorkItemReadyEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
if (!WorkItemReadyEvent)
|
||||
return FALSE;
|
||||
|
||||
WorkItemCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
if (!WorkItemCompletedEvent)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
ExInitializeFastMutex (&DequeueMutex);
|
||||
ExInitializeFastMutex (&EnqueueMutex);
|
||||
#else
|
||||
DequeueMutex = CreateMutex (NULL, FALSE, NULL);
|
||||
if (!DequeueMutex)
|
||||
return FALSE;
|
||||
|
||||
EnqueueMutex = CreateMutex (NULL, FALSE, NULL);
|
||||
if (!EnqueueMutex)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
memset (WorkItemQueue, 0, sizeof (WorkItemQueue));
|
||||
|
||||
for (i = 0; i < sizeof (WorkItemQueue) / sizeof (WorkItemQueue[0]); ++i)
|
||||
{
|
||||
WorkItemQueue[i].State = WorkItemFree;
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
KeInitializeEvent (&WorkItemQueue[i].ItemCompletedEvent, SynchronizationEvent, FALSE);
|
||||
#else
|
||||
WorkItemQueue[i].ItemCompletedEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
|
||||
if (!WorkItemQueue[i].ItemCompletedEvent)
|
||||
{
|
||||
EncryptionThreadPoolStop();
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount)
|
||||
{
|
||||
#ifdef DEVICE_DRIVER
|
||||
if (!NT_SUCCESS (TCStartThread (EncryptionThreadProc, NULL, &ThreadHandles[ThreadCount])))
|
||||
#else
|
||||
if (!(ThreadHandles[ThreadCount] = (HANDLE) _beginthreadex (NULL, 0, EncryptionThreadProc, NULL, 0, NULL)))
|
||||
#endif
|
||||
{
|
||||
EncryptionThreadPoolStop();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPoolRunning = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void EncryptionThreadPoolStop ()
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!ThreadPoolRunning)
|
||||
return;
|
||||
|
||||
StopPending = TRUE;
|
||||
TC_SET_EVENT (WorkItemReadyEvent);
|
||||
|
||||
for (i = 0; i < ThreadCount; ++i)
|
||||
{
|
||||
#ifdef DEVICE_DRIVER
|
||||
TCStopThread (ThreadHandles[i], &WorkItemReadyEvent);
|
||||
#else
|
||||
TC_WAIT_EVENT (ThreadHandles[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
ThreadCount = 0;
|
||||
|
||||
#ifndef DEVICE_DRIVER
|
||||
CloseHandle (DequeueMutex);
|
||||
CloseHandle (EnqueueMutex);
|
||||
|
||||
CloseHandle (WorkItemReadyEvent);
|
||||
CloseHandle (WorkItemCompletedEvent);
|
||||
|
||||
for (i = 0; i < sizeof (WorkItemQueue) / sizeof (WorkItemQueue[0]); ++i)
|
||||
{
|
||||
if (WorkItemQueue[i].ItemCompletedEvent)
|
||||
CloseHandle (WorkItemQueue[i].ItemCompletedEvent);
|
||||
}
|
||||
#endif
|
||||
|
||||
ThreadPoolRunning = FALSE;
|
||||
}
|
||||
|
||||
|
||||
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey)
|
||||
{
|
||||
EncryptionThreadPoolWorkItem *workItem;
|
||||
|
||||
if (!ThreadPoolRunning)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
TC_ACQUIRE_MUTEX (&EnqueueMutex);
|
||||
|
||||
workItem = &WorkItemQueue[EnqueuePosition++];
|
||||
if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
|
||||
EnqueuePosition = 0;
|
||||
|
||||
while (GetWorkItemState (workItem) != WorkItemFree)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
workItem->Type = DeriveKeyWork;
|
||||
workItem->KeyDerivation.CompletionEvent = completionEvent;
|
||||
workItem->KeyDerivation.CompletionFlag = completionFlag;
|
||||
workItem->KeyDerivation.DerivedKey = derivedKey;
|
||||
workItem->KeyDerivation.IterationCount = iterationCount;
|
||||
workItem->KeyDerivation.NoOutstandingWorkItemEvent = noOutstandingWorkItemEvent;
|
||||
workItem->KeyDerivation.OutstandingWorkItemCount = outstandingWorkItemCount;
|
||||
workItem->KeyDerivation.Password = password;
|
||||
workItem->KeyDerivation.PasswordLength = passwordLength;
|
||||
workItem->KeyDerivation.Pkcs5Prf = pkcs5Prf;
|
||||
workItem->KeyDerivation.Salt = salt;
|
||||
|
||||
InterlockedIncrement (outstandingWorkItemCount);
|
||||
TC_CLEAR_EVENT (*noOutstandingWorkItemEvent);
|
||||
|
||||
SetWorkItemState (workItem, WorkItemReady);
|
||||
TC_SET_EVENT (WorkItemReadyEvent);
|
||||
TC_RELEASE_MUTEX (&EnqueueMutex);
|
||||
}
|
||||
|
||||
|
||||
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo)
|
||||
{
|
||||
uint32 fragmentCount;
|
||||
uint32 unitsPerFragment;
|
||||
uint32 remainder;
|
||||
|
||||
byte *fragmentData;
|
||||
uint64 fragmentStartUnitNo;
|
||||
|
||||
EncryptionThreadPoolWorkItem *workItem;
|
||||
EncryptionThreadPoolWorkItem *firstFragmentWorkItem;
|
||||
|
||||
if (unitCount == 0)
|
||||
return;
|
||||
|
||||
if (!ThreadPoolRunning || unitCount == 1)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DecryptDataUnitsWork:
|
||||
DecryptDataUnitsCurrentThread (data, startUnitNo, unitCount, cryptoInfo);
|
||||
break;
|
||||
|
||||
case EncryptDataUnitsWork:
|
||||
EncryptDataUnitsCurrentThread (data, startUnitNo, unitCount, cryptoInfo);
|
||||
break;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (unitCount <= ThreadCount)
|
||||
{
|
||||
fragmentCount = unitCount;
|
||||
unitsPerFragment = 1;
|
||||
remainder = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Note that it is not efficient to divide the data into fragments smaller than a few hundred bytes.
|
||||
The reason is that the overhead associated with thread handling would in most cases make a multi-threaded
|
||||
process actually slower than a single-threaded process. */
|
||||
|
||||
fragmentCount = ThreadCount;
|
||||
unitsPerFragment = unitCount / ThreadCount;
|
||||
remainder = unitCount % ThreadCount;
|
||||
|
||||
if (remainder > 0)
|
||||
++unitsPerFragment;
|
||||
}
|
||||
|
||||
fragmentData = data;
|
||||
fragmentStartUnitNo = startUnitNo->Value;
|
||||
|
||||
TC_ACQUIRE_MUTEX (&EnqueueMutex);
|
||||
firstFragmentWorkItem = &WorkItemQueue[EnqueuePosition];
|
||||
|
||||
while (GetWorkItemState (firstFragmentWorkItem) != WorkItemFree)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
firstFragmentWorkItem->OutstandingFragmentCount = fragmentCount;
|
||||
|
||||
while (fragmentCount-- > 0)
|
||||
{
|
||||
workItem = &WorkItemQueue[EnqueuePosition++];
|
||||
if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE)
|
||||
EnqueuePosition = 0;
|
||||
|
||||
while (GetWorkItemState (workItem) != WorkItemFree)
|
||||
{
|
||||
TC_WAIT_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
workItem->Type = type;
|
||||
workItem->FirstFragment = firstFragmentWorkItem;
|
||||
|
||||
workItem->Encryption.CryptoInfo = cryptoInfo;
|
||||
workItem->Encryption.Data = fragmentData;
|
||||
workItem->Encryption.UnitCount = unitsPerFragment;
|
||||
workItem->Encryption.StartUnitNo.Value = fragmentStartUnitNo;
|
||||
|
||||
fragmentData += unitsPerFragment * ENCRYPTION_DATA_UNIT_SIZE;
|
||||
fragmentStartUnitNo += unitsPerFragment;
|
||||
|
||||
if (remainder > 0 && --remainder == 0)
|
||||
--unitsPerFragment;
|
||||
|
||||
SetWorkItemState (workItem, WorkItemReady);
|
||||
TC_SET_EVENT (WorkItemReadyEvent);
|
||||
}
|
||||
|
||||
TC_RELEASE_MUTEX (&EnqueueMutex);
|
||||
|
||||
TC_WAIT_EVENT (firstFragmentWorkItem->ItemCompletedEvent);
|
||||
SetWorkItemState (firstFragmentWorkItem, WorkItemFree);
|
||||
TC_SET_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
|
||||
size_t GetEncryptionThreadCount ()
|
||||
{
|
||||
return ThreadPoolRunning ? ThreadCount : 0;
|
||||
}
|
||||
|
||||
|
||||
size_t GetMaxEncryptionThreadCount ()
|
||||
{
|
||||
return TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
|
||||
}
|
||||
|
||||
|
||||
BOOL IsEncryptionThreadPoolRunning ()
|
||||
{
|
||||
return ThreadPoolRunning;
|
||||
}
|
||||
38
src/Common/EncryptionThreadPool.h
Normal file
38
src/Common/EncryptionThreadPool.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_ENCRYPTION_THREAD_POOL
|
||||
#define TC_HEADER_ENCRYPTION_THREAD_POOL
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EncryptDataUnitsWork,
|
||||
DecryptDataUnitsWork,
|
||||
DeriveKeyWork
|
||||
} EncryptionThreadPoolWorkType;
|
||||
|
||||
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey);
|
||||
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo);
|
||||
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount);
|
||||
void EncryptionThreadPoolStop ();
|
||||
size_t GetEncryptionThreadCount ();
|
||||
size_t GetMaxEncryptionThreadCount ();
|
||||
BOOL IsEncryptionThreadPoolRunning ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_ENCRYPTION_THREAD_POOL
|
||||
57
src/Common/Endian.c
Normal file
57
src/Common/Endian.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Common/Endian.h"
|
||||
|
||||
|
||||
unsigned __int16 MirrorBytes16 (unsigned __int16 x)
|
||||
{
|
||||
return (x << 8) | (x >> 8);
|
||||
}
|
||||
|
||||
|
||||
unsigned __int32 MirrorBytes32 (unsigned __int32 x)
|
||||
{
|
||||
unsigned __int32 n = (unsigned __int8) x;
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 8);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 16);
|
||||
return (n << 8) | (unsigned __int8) (x >> 24);
|
||||
}
|
||||
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
uint64 MirrorBytes64 (uint64 x)
|
||||
{
|
||||
uint64 n = (unsigned __int8) x;
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 8);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 16);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 24);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 32);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 40);
|
||||
n <<= 8; n |= (unsigned __int8) (x >> 48);
|
||||
return (n << 8) | (unsigned __int8) (x >> 56);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
LongReverse (unsigned __int32 *buffer, unsigned byteCount)
|
||||
{
|
||||
unsigned __int32 value;
|
||||
|
||||
byteCount /= sizeof (unsigned __int32);
|
||||
while (byteCount--)
|
||||
{
|
||||
value = *buffer;
|
||||
value = ((value & 0xFF00FF00L) >> 8) | \
|
||||
((value & 0x00FF00FFL) << 8);
|
||||
*buffer++ = (value << 16) | (value >> 16);
|
||||
}
|
||||
}
|
||||
147
src/Common/Endian.h
Normal file
147
src/Common/Endian.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_ENDIAN_H
|
||||
#define TC_ENDIAN_H
|
||||
|
||||
#include "Common/Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
# ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# endif
|
||||
# ifndef BYTE_ORDER
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
# endif
|
||||
|
||||
#elif !defined(BYTE_ORDER)
|
||||
|
||||
# ifdef TC_MACOSX
|
||||
# include <machine/endian.h>
|
||||
# elif defined (TC_BSD)
|
||||
# include <sys/endian.h>
|
||||
# elif defined (TC_SOLARIS)
|
||||
# include <sys/types.h>
|
||||
# define LITTLE_ENDIAN 1234
|
||||
# define BIG_ENDIAN 4321
|
||||
# ifdef _BIG_ENDIAN
|
||||
# define BYTE_ORDER BIG_ENDIAN
|
||||
# else
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
# endif
|
||||
# else
|
||||
# include <endian.h>
|
||||
# endif
|
||||
|
||||
# ifndef BYTE_ORDER
|
||||
# ifndef __BYTE_ORDER
|
||||
# error Byte order cannot be determined (BYTE_ORDER undefined)
|
||||
# endif
|
||||
|
||||
# define BYTE_ORDER __BYTE_ORDER
|
||||
# endif
|
||||
|
||||
# ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN __LITTLE_ENDIAN
|
||||
# endif
|
||||
|
||||
# ifndef BIG_ENDIAN
|
||||
# define BIG_ENDIAN __BIG_ENDIAN
|
||||
# endif
|
||||
|
||||
#endif // !BYTE_ORDER
|
||||
|
||||
/* Macros to read and write 16, 32, and 64-bit quantities in a portable manner.
|
||||
These functions are implemented as macros rather than true functions as
|
||||
the need to adjust the memory pointers makes them somewhat painful to call
|
||||
in user code */
|
||||
|
||||
#define mputInt64(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 56 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 48 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 40 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 32 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 24 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 16 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
|
||||
|
||||
#define mputLong(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 24 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 16 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
|
||||
|
||||
#define mputWord(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) ( ( ( data ) >> 8 ) & 0xFF ), \
|
||||
*memPtr++ = ( unsigned char ) ( ( data ) & 0xFF )
|
||||
|
||||
#define mputByte(memPtr,data) \
|
||||
*memPtr++ = ( unsigned char ) data
|
||||
|
||||
#define mputBytes(memPtr,data,len) \
|
||||
memcpy (memPtr,data,len); \
|
||||
memPtr += len;
|
||||
|
||||
#define mgetInt64(memPtr) \
|
||||
( memPtr += 8, ( ( unsigned __int64 ) memPtr[ -8 ] << 56 ) | ( ( unsigned __int64 ) memPtr[ -7 ] << 48 ) | \
|
||||
( ( unsigned __int64 ) memPtr[ -6 ] << 40 ) | ( ( unsigned __int64 ) memPtr[ -5 ] << 32 ) | \
|
||||
( ( unsigned __int64 ) memPtr[ -4 ] << 24 ) | ( ( unsigned __int64 ) memPtr[ -3 ] << 16 ) | \
|
||||
( ( unsigned __int64 ) memPtr[ -2 ] << 8 ) | ( unsigned __int64 ) memPtr[ -1 ] )
|
||||
|
||||
#define mgetLong(memPtr) \
|
||||
( memPtr += 4, ( ( unsigned __int32 ) memPtr[ -4 ] << 24 ) | ( ( unsigned __int32 ) memPtr[ -3 ] << 16 ) | \
|
||||
( ( unsigned __int32 ) memPtr[ -2 ] << 8 ) | ( unsigned __int32 ) memPtr[ -1 ] )
|
||||
|
||||
#define mgetWord(memPtr) \
|
||||
( memPtr += 2, ( unsigned short ) memPtr[ -2 ] << 8 ) | ( ( unsigned short ) memPtr[ -1 ] )
|
||||
|
||||
#define mgetByte(memPtr) \
|
||||
( ( unsigned char ) *memPtr++ )
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define LE16(x) MirrorBytes16(x)
|
||||
# define LE32(x) MirrorBytes32(x)
|
||||
# define LE64(x) MirrorBytes64(x)
|
||||
#else
|
||||
# define LE16(x) (x)
|
||||
# define LE32(x) (x)
|
||||
# define LE64(x) (x)
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define BE16(x) MirrorBytes16(x)
|
||||
# define BE32(x) MirrorBytes32(x)
|
||||
# define BE64(x) MirrorBytes64(x)
|
||||
#else
|
||||
# define BE16(x) (x)
|
||||
# define BE32(x) (x)
|
||||
# define BE64(x) (x)
|
||||
#endif
|
||||
|
||||
unsigned __int16 MirrorBytes16 (unsigned __int16 x);
|
||||
unsigned __int32 MirrorBytes32 (unsigned __int32 x);
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
uint64 MirrorBytes64 (uint64 x);
|
||||
#endif
|
||||
void LongReverse ( unsigned __int32 *buffer , unsigned byteCount );
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TC_ENDIAN_H */
|
||||
81
src/Common/Exception.h
Normal file
81
src/Common/Exception.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_Exception
|
||||
#define TC_HEADER_Common_Exception
|
||||
|
||||
#include "Platform/PlatformBase.h"
|
||||
#include "Dlgcode.h"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
struct Exception
|
||||
{
|
||||
virtual void Show (HWND parent) const = 0;
|
||||
};
|
||||
|
||||
struct SystemException : public Exception
|
||||
{
|
||||
SystemException () : ErrorCode (GetLastError()) { }
|
||||
|
||||
void Show (HWND parent) const
|
||||
{
|
||||
SetLastError (ErrorCode);
|
||||
handleWin32Error (parent);
|
||||
}
|
||||
|
||||
DWORD ErrorCode;
|
||||
};
|
||||
|
||||
struct ErrorException : public Exception
|
||||
{
|
||||
ErrorException (char *langId) : ErrLangId (langId) { }
|
||||
ErrorException (const wstring &errMsg) : ErrMsg (errMsg) { }
|
||||
|
||||
void Show (HWND parent) const
|
||||
{
|
||||
if (ErrMsg.empty())
|
||||
::Error (ErrLangId);
|
||||
else
|
||||
::ErrorDirect (ErrMsg.c_str());
|
||||
}
|
||||
|
||||
char *ErrLangId;
|
||||
wstring ErrMsg;
|
||||
};
|
||||
|
||||
struct ParameterIncorrect : public Exception
|
||||
{
|
||||
ParameterIncorrect (const char *srcPos) : SrcPos (srcPos) { }
|
||||
|
||||
void Show (HWND parent) const
|
||||
{
|
||||
string msgBody = "Parameter incorrect.\n\n\n(If you report a bug in connection with this, please include the following technical information in the bug report:\n" + string (SrcPos) + ")";
|
||||
MessageBox (parent, msgBody.c_str(), "TrueCrypt", MB_ICONERROR | MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
const char *SrcPos;
|
||||
};
|
||||
|
||||
struct TimeOut : public Exception
|
||||
{
|
||||
TimeOut (const char *srcPos) { }
|
||||
void Show (HWND parent) const { ErrorDirect (L"Timeout"); }
|
||||
};
|
||||
|
||||
struct UserAbort : public Exception
|
||||
{
|
||||
UserAbort (const char *srcPos) { }
|
||||
void Show (HWND parent) const { }
|
||||
};
|
||||
}
|
||||
|
||||
#define throw_sys_if(condition) do { if (condition) throw SystemException(); } while (false)
|
||||
|
||||
|
||||
#endif // TC_HEADER_Common_Exception
|
||||
445
src/Common/Fat.c
Normal file
445
src/Common/Fat.c
Normal file
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include "Crypto.h"
|
||||
#include "Common/Endian.h"
|
||||
#include "Format.h"
|
||||
#include "Fat.h"
|
||||
#include "Progress.h"
|
||||
#include "Random.h"
|
||||
#include "Volumes.h"
|
||||
|
||||
void
|
||||
GetFatParams (fatparams * ft)
|
||||
{
|
||||
uint64 volumeSize = (uint64) ft->num_sectors * ft->sector_size;
|
||||
unsigned int fatsecs;
|
||||
|
||||
if(ft->cluster_size == 0) // 'Default' cluster size
|
||||
{
|
||||
uint32 clusterSize;
|
||||
|
||||
// Determine optimal cluster size to minimize FAT size (mounting delay), maximize number of files, keep 4 KB alignment, etc.
|
||||
if (volumeSize >= 2 * BYTES_PER_TB)
|
||||
clusterSize = 256 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 512 * BYTES_PER_GB)
|
||||
clusterSize = 128 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 128 * BYTES_PER_GB)
|
||||
clusterSize = 64 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 64 * BYTES_PER_GB)
|
||||
clusterSize = 32 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 32 * BYTES_PER_GB)
|
||||
clusterSize = 16 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 16 * BYTES_PER_GB)
|
||||
clusterSize = 8 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 512 * BYTES_PER_MB)
|
||||
clusterSize = 4 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 256 * BYTES_PER_MB)
|
||||
clusterSize = 2 * BYTES_PER_KB;
|
||||
else if (volumeSize >= 1 * BYTES_PER_MB)
|
||||
clusterSize = 1 * BYTES_PER_KB;
|
||||
else
|
||||
clusterSize = 512;
|
||||
|
||||
ft->cluster_size = clusterSize / ft->sector_size;
|
||||
|
||||
if (ft->cluster_size == 0)
|
||||
ft->cluster_size = 1;
|
||||
|
||||
if (ft->cluster_size * ft->sector_size > TC_MAX_FAT_CLUSTER_SIZE)
|
||||
ft->cluster_size = TC_MAX_FAT_CLUSTER_SIZE / ft->sector_size;
|
||||
|
||||
if (ft->cluster_size > 128)
|
||||
ft->cluster_size = 128;
|
||||
}
|
||||
|
||||
if (volumeSize <= TC_MAX_FAT_CLUSTER_SIZE * 4)
|
||||
ft->cluster_size = 1;
|
||||
|
||||
// Geometry always set to SECTORS/1/1
|
||||
ft->secs_track = 1;
|
||||
ft->heads = 1;
|
||||
|
||||
ft->dir_entries = 512;
|
||||
ft->fats = 2;
|
||||
ft->media = 0xf8;
|
||||
ft->hidden = 0;
|
||||
|
||||
ft->size_root_dir = ft->dir_entries * 32;
|
||||
|
||||
// FAT12
|
||||
ft->size_fat = 12;
|
||||
ft->reserved = 2;
|
||||
fatsecs = ft->num_sectors - (ft->size_root_dir + ft->sector_size - 1) / ft->sector_size - ft->reserved;
|
||||
ft->cluster_count = (int) (((__int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size));
|
||||
ft->fat_length = (((ft->cluster_count * 3 + 1) >> 1) + ft->sector_size - 1) / ft->sector_size;
|
||||
|
||||
if (ft->cluster_count >= 4085) // FAT16
|
||||
{
|
||||
ft->size_fat = 16;
|
||||
ft->reserved = 2;
|
||||
fatsecs = ft->num_sectors - (ft->size_root_dir + ft->sector_size - 1) / ft->sector_size - ft->reserved;
|
||||
ft->cluster_count = (int) (((__int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size));
|
||||
ft->fat_length = (ft->cluster_count * 2 + ft->sector_size - 1) / ft->sector_size;
|
||||
}
|
||||
|
||||
if(ft->cluster_count >= 65525) // FAT32
|
||||
{
|
||||
ft->size_fat = 32;
|
||||
ft->reserved = 32 - 1;
|
||||
|
||||
do
|
||||
{
|
||||
ft->reserved++;
|
||||
|
||||
fatsecs = ft->num_sectors - ft->reserved;
|
||||
ft->size_root_dir = ft->cluster_size * ft->sector_size;
|
||||
ft->cluster_count = (int) (((__int64) fatsecs * ft->sector_size) / (ft->cluster_size * ft->sector_size));
|
||||
ft->fat_length = (ft->cluster_count * 4 + ft->sector_size - 1) / ft->sector_size;
|
||||
|
||||
// Align data area on TC_MAX_VOLUME_SECTOR_SIZE
|
||||
|
||||
} while (ft->sector_size == TC_SECTOR_SIZE_LEGACY
|
||||
&& (ft->reserved * ft->sector_size + ft->fat_length * ft->fats * ft->sector_size) % TC_MAX_VOLUME_SECTOR_SIZE != 0);
|
||||
}
|
||||
|
||||
ft->cluster_count -= ft->fat_length * ft->fats / ft->cluster_size;
|
||||
|
||||
if (ft->num_sectors >= 65536 || ft->size_fat == 32)
|
||||
{
|
||||
ft->sectors = 0;
|
||||
ft->total_sect = ft->num_sectors;
|
||||
}
|
||||
else
|
||||
{
|
||||
ft->sectors = (uint16) ft->num_sectors;
|
||||
ft->total_sect = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PutBoot (fatparams * ft, unsigned char *boot)
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
boot[cnt++] = 0xeb; /* boot jump */
|
||||
boot[cnt++] = 0x3c;
|
||||
boot[cnt++] = 0x90;
|
||||
memcpy (boot + cnt, "MSDOS5.0", 8); /* system id */
|
||||
cnt += 8;
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->sector_size); /* bytes per sector */
|
||||
cnt += 2;
|
||||
boot[cnt++] = (__int8) ft->cluster_size; /* sectors per cluster */
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->reserved); /* reserved sectors */
|
||||
cnt += 2;
|
||||
boot[cnt++] = (__int8) ft->fats; /* 2 fats */
|
||||
|
||||
if(ft->size_fat == 32)
|
||||
{
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->dir_entries); /* 512 root entries */
|
||||
cnt += 2;
|
||||
}
|
||||
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->sectors); /* # sectors */
|
||||
cnt += 2;
|
||||
boot[cnt++] = (__int8) ft->media; /* media byte */
|
||||
|
||||
if(ft->size_fat == 32)
|
||||
{
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(__int16 *)(boot + cnt) = LE16((uint16) ft->fat_length); /* fat size */
|
||||
cnt += 2;
|
||||
}
|
||||
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->secs_track); /* # sectors per track */
|
||||
cnt += 2;
|
||||
*(__int16 *)(boot + cnt) = LE16(ft->heads); /* # heads */
|
||||
cnt += 2;
|
||||
*(__int32 *)(boot + cnt) = LE32(ft->hidden); /* # hidden sectors */
|
||||
cnt += 4;
|
||||
*(__int32 *)(boot + cnt) = LE32(ft->total_sect); /* # huge sectors */
|
||||
cnt += 4;
|
||||
|
||||
if(ft->size_fat == 32)
|
||||
{
|
||||
*(__int32 *)(boot + cnt) = LE32(ft->fat_length); cnt += 4; /* fat size 32 */
|
||||
boot[cnt++] = 0x00; /* ExtFlags */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00; /* FSVer */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x02; /* RootClus */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x01; /* FSInfo */
|
||||
boot[cnt++] = 0x00;
|
||||
boot[cnt++] = 0x06; /* BkBootSec */
|
||||
boot[cnt++] = 0x00;
|
||||
memset(boot+cnt, 0, 12); cnt+=12; /* Reserved */
|
||||
}
|
||||
|
||||
boot[cnt++] = 0x00; /* drive number */ // FIXED 80 > 00
|
||||
boot[cnt++] = 0x00; /* reserved */
|
||||
boot[cnt++] = 0x29; /* boot sig */
|
||||
|
||||
memcpy (boot + cnt, ft->volume_id, 4); /* vol id */
|
||||
cnt += 4;
|
||||
|
||||
memcpy (boot + cnt, ft->volume_name, 11); /* vol title */
|
||||
cnt += 11;
|
||||
|
||||
switch(ft->size_fat) /* filesystem type */
|
||||
{
|
||||
case 12: memcpy (boot + cnt, "FAT12 ", 8); break;
|
||||
case 16: memcpy (boot + cnt, "FAT16 ", 8); break;
|
||||
case 32: memcpy (boot + cnt, "FAT32 ", 8); break;
|
||||
}
|
||||
cnt += 8;
|
||||
|
||||
memset (boot + cnt, 0, ft->size_fat==32 ? 420:448); /* boot code */
|
||||
cnt += ft->size_fat==32 ? 420:448;
|
||||
boot[cnt++] = 0x55;
|
||||
boot[cnt++] = 0xaa; /* boot sig */
|
||||
}
|
||||
|
||||
|
||||
/* FAT32 FSInfo */
|
||||
static void PutFSInfo (unsigned char *sector, fatparams *ft)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
sector[3]=0x41; /* LeadSig */
|
||||
sector[2]=0x61;
|
||||
sector[1]=0x52;
|
||||
sector[0]=0x52;
|
||||
sector[484+3]=0x61; /* StrucSig */
|
||||
sector[484+2]=0x41;
|
||||
sector[484+1]=0x72;
|
||||
sector[484+0]=0x72;
|
||||
|
||||
// Free cluster count
|
||||
*(uint32 *)(sector + 488) = LE32 (ft->cluster_count - ft->size_root_dir / ft->sector_size / ft->cluster_size);
|
||||
|
||||
// Next free cluster
|
||||
*(uint32 *)(sector + 492) = LE32 (2);
|
||||
|
||||
sector[508+3]=0xaa; /* TrailSig */
|
||||
sector[508+2]=0x55;
|
||||
sector[508+1]=0x00;
|
||||
sector[508+0]=0x00;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FormatFat (unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat)
|
||||
{
|
||||
int write_buf_cnt = 0;
|
||||
char sector[TC_MAX_VOLUME_SECTOR_SIZE], *write_buf;
|
||||
unsigned __int64 nSecNo = startSector;
|
||||
int x, n;
|
||||
int retVal;
|
||||
char temporaryKey[MASTER_KEYDATA_SIZE];
|
||||
|
||||
LARGE_INTEGER startOffset;
|
||||
LARGE_INTEGER newOffset;
|
||||
|
||||
// Seek to start sector
|
||||
startOffset.QuadPart = startSector * ft->sector_size;
|
||||
if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
|
||||
|| newOffset.QuadPart != startOffset.QuadPart)
|
||||
{
|
||||
return ERR_VOL_SEEKING;
|
||||
}
|
||||
|
||||
/* Write the data area */
|
||||
|
||||
write_buf = (char *)TCalloc (FormatWriteBufferSize);
|
||||
if (!write_buf)
|
||||
return ERR_OUTOFMEMORY;
|
||||
|
||||
memset (sector, 0, ft->sector_size);
|
||||
|
||||
RandgetBytes (ft->volume_id, sizeof (ft->volume_id), FALSE);
|
||||
|
||||
PutBoot (ft, (unsigned char *) sector);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
/* fat32 boot area */
|
||||
if (ft->size_fat == 32)
|
||||
{
|
||||
/* fsinfo */
|
||||
PutFSInfo((unsigned char *) sector, ft);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
/* reserved */
|
||||
while (nSecNo - startSector < 6)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
sector[508+3]=0xaa; /* TrailSig */
|
||||
sector[508+2]=0x55;
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* bootsector backup */
|
||||
memset (sector, 0, ft->sector_size);
|
||||
PutBoot (ft, (unsigned char *) sector);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
PutFSInfo((unsigned char *) sector, ft);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* reserved */
|
||||
while (nSecNo - startSector < (unsigned int)ft->reserved)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* write fat */
|
||||
for (x = 1; x <= ft->fats; x++)
|
||||
{
|
||||
for (n = 0; n < ft->fat_length; n++)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
unsigned char fat_sig[12];
|
||||
if (ft->size_fat == 32)
|
||||
{
|
||||
fat_sig[0] = (unsigned char) ft->media;
|
||||
fat_sig[1] = fat_sig[2] = 0xff;
|
||||
fat_sig[3] = 0x0f;
|
||||
fat_sig[4] = fat_sig[5] = fat_sig[6] = 0xff;
|
||||
fat_sig[7] = 0x0f;
|
||||
fat_sig[8] = fat_sig[9] = fat_sig[10] = 0xff;
|
||||
fat_sig[11] = 0x0f;
|
||||
memcpy (sector, fat_sig, 12);
|
||||
}
|
||||
else if (ft->size_fat == 16)
|
||||
{
|
||||
fat_sig[0] = (unsigned char) ft->media;
|
||||
fat_sig[1] = 0xff;
|
||||
fat_sig[2] = 0xff;
|
||||
fat_sig[3] = 0xff;
|
||||
memcpy (sector, fat_sig, 4);
|
||||
}
|
||||
else if (ft->size_fat == 12)
|
||||
{
|
||||
fat_sig[0] = (unsigned char) ft->media;
|
||||
fat_sig[1] = 0xff;
|
||||
fat_sig[2] = 0xff;
|
||||
fat_sig[3] = 0x00;
|
||||
memcpy (sector, fat_sig, 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* write rootdir */
|
||||
for (x = 0; x < ft->size_root_dir / ft->sector_size; x++)
|
||||
{
|
||||
memset (sector, 0, ft->sector_size);
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
|
||||
}
|
||||
|
||||
/* Fill the rest of the data area with random data */
|
||||
|
||||
if(!quickFormat)
|
||||
{
|
||||
if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
|
||||
goto fail;
|
||||
|
||||
/* Generate a random temporary key set to be used for "dummy" encryption that will fill
|
||||
the free disk space (data area) with random data. This is necessary for plausible
|
||||
deniability of hidden volumes (and also reduces the amount of predictable plaintext
|
||||
within the volume). */
|
||||
|
||||
// Temporary master key
|
||||
if (!RandgetBytes (temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE))
|
||||
goto fail;
|
||||
|
||||
// Temporary secondary key (XTS mode)
|
||||
if (!RandgetBytes (cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE))
|
||||
goto fail;
|
||||
|
||||
retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
|
||||
if (retVal != ERR_SUCCESS)
|
||||
{
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return retVal;
|
||||
}
|
||||
if (!EAInitMode (cryptoInfo))
|
||||
{
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return ERR_MODE_INIT_FAILED;
|
||||
}
|
||||
|
||||
x = ft->num_sectors - ft->reserved - ft->size_root_dir / ft->sector_size - ft->fat_length * 2;
|
||||
while (x--)
|
||||
{
|
||||
if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
|
||||
cryptoInfo) == FALSE)
|
||||
goto fail;
|
||||
}
|
||||
UpdateProgressBar (nSecNo * ft->sector_size);
|
||||
}
|
||||
else
|
||||
UpdateProgressBar ((uint64) ft->num_sectors * ft->sector_size);
|
||||
|
||||
if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
|
||||
goto fail;
|
||||
|
||||
TCfree (write_buf);
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
||||
TCfree (write_buf);
|
||||
burn (temporaryKey, sizeof(temporaryKey));
|
||||
return ERR_OS_ERROR;
|
||||
}
|
||||
67
src/Common/Fat.h
Normal file
67
src/Common/Fat.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
typedef struct fatparams_t
|
||||
{
|
||||
char volume_name[11];
|
||||
byte volume_id[4];
|
||||
unsigned int num_sectors; /* total number of sectors */
|
||||
int cluster_count; /* number of clusters */
|
||||
int size_root_dir; /* size of the root directory in bytes */
|
||||
int size_fat; /* size of FAT */
|
||||
int fats;
|
||||
int media;
|
||||
int cluster_size;
|
||||
int fat_length;
|
||||
uint16 dir_entries;
|
||||
uint16 sector_size;
|
||||
int hidden;
|
||||
__int16 reserved;
|
||||
uint16 sectors;
|
||||
unsigned int total_sect;
|
||||
|
||||
uint16 heads;
|
||||
uint16 secs_track;
|
||||
|
||||
} fatparams;
|
||||
|
||||
|
||||
struct msdos_boot_sector
|
||||
{
|
||||
unsigned char boot_jump[3]; /* Boot strap short or near jump */
|
||||
char system_id[8]; /* Name - can be used to special case
|
||||
partition manager volumes */
|
||||
unsigned char sector_size[2]; /* bytes per logical sector */
|
||||
unsigned char cluster_size; /* sectors/cluster */
|
||||
unsigned short reserved;/* reserved sectors */
|
||||
unsigned char fats; /* number of FATs */
|
||||
unsigned char dir_entries[2]; /* root directory entries */
|
||||
unsigned char sectors[2]; /* number of sectors */
|
||||
unsigned char media; /* media code */
|
||||
unsigned short fat_length; /* sectors/FAT */
|
||||
unsigned short secs_track; /* sectors per track */
|
||||
unsigned short heads; /* number of heads */
|
||||
unsigned __int32 hidden; /* hidden sectors */
|
||||
unsigned __int32 total_sect; /* number of sectors (if sectors == 0) */
|
||||
unsigned char drive_number; /* BIOS drive number */
|
||||
unsigned char RESERVED; /* Unused */
|
||||
unsigned char ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */
|
||||
unsigned char volume_id[4]; /* Volume ID number */
|
||||
char volume_label[11]; /* Volume label */
|
||||
char fs_type[8]; /* Typically FAT12, FAT16, or FAT32 */
|
||||
unsigned char boot_code[448]; /* Boot code (or message) */
|
||||
unsigned short boot_sign; /* 0xAA55 */
|
||||
};
|
||||
|
||||
|
||||
void GetFatParams ( fatparams *ft );
|
||||
void PutBoot ( fatparams *ft , unsigned char *boot );
|
||||
int FormatFat (unsigned __int64 startSector, fatparams * ft, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat);
|
||||
1010
src/Common/Format.c
Normal file
1010
src/Common/Format.c
Normal file
File diff suppressed because it is too large
Load Diff
68
src/Common/Format.h
Normal file
68
src/Common/Format.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_Format
|
||||
#define TC_HEADER_Format
|
||||
|
||||
#include "Password.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// FMIFS
|
||||
typedef BOOLEAN (__stdcall *PFMIFSCALLBACK)( int command, DWORD subCommand, PVOID parameter );
|
||||
typedef VOID (__stdcall *PFORMATEX)( PWCHAR DriveRoot, DWORD MediaFlag, PWCHAR Format, PWCHAR Label, BOOL QuickFormat, DWORD ClusterSize, PFMIFSCALLBACK Callback );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL bDevice;
|
||||
BOOL hiddenVol;
|
||||
char *volumePath;
|
||||
unsigned __int64 size;
|
||||
unsigned __int64 hiddenVolHostSize;
|
||||
int ea;
|
||||
int pkcs5;
|
||||
uint32 headerFlags;
|
||||
int fileSystem;
|
||||
int clusterSize;
|
||||
BOOL sparseFileSwitch;
|
||||
BOOL quickFormat;
|
||||
int sectorSize;
|
||||
int *realClusterSize;
|
||||
Password *password;
|
||||
HWND hwndDlg;
|
||||
}
|
||||
FORMAT_VOL_PARAMETERS;
|
||||
|
||||
#define FMIFS_DONE 0xB
|
||||
#define FMIFS_HARDDISK 0xC
|
||||
|
||||
extern int FormatWriteBufferSize;
|
||||
|
||||
int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams);
|
||||
BOOL FormatNtfs (int driveNo, int clusterSize);
|
||||
uint64 GetVolumeDataAreaSize (BOOL hiddenVolume, uint64 volumeSize);
|
||||
int FormatNoFs (unsigned __int64 startSector, __int64 num_sectors, void *dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat);
|
||||
BOOL WriteSector ( void *dev , char *sector , char *write_buf , int *write_buf_cnt , __int64 *nSecNo , PCRYPTO_INFO cryptoInfo );
|
||||
BOOL FlushFormatWriteBuffer (void *dev, char *write_buf, int *write_buf_cnt, __int64 *nSecNo, PCRYPTO_INFO cryptoInfo);
|
||||
static BOOL StartFormatWriteThread ();
|
||||
static void StopFormatWriteThread ();
|
||||
|
||||
#define FILESYS_NONE 0
|
||||
#define FILESYS_FAT 1
|
||||
#define FILESYS_NTFS 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_Format
|
||||
894
src/Common/GfMul.c
Normal file
894
src/Common/GfMul.c
Normal file
@@ -0,0 +1,894 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software is allowed (with or without
|
||||
changes) provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 31/01/2004
|
||||
|
||||
My thanks to John Viega and David McGrew for their support in developing
|
||||
this code and to David for testing it on a big-endain system.
|
||||
*/
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Portions Copyright (c) 2005 TrueCrypt Developers Association
|
||||
|
||||
Changes:
|
||||
|
||||
- Added multiplication in the finite field GF(2^128) optimized for
|
||||
cases involving a 64-bit operand.
|
||||
|
||||
- Added multiplication in the finite field GF(2^64).
|
||||
|
||||
- Added MSB-first mode.
|
||||
|
||||
- Added basic test algorithms.
|
||||
|
||||
- Removed GCM.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#include "GfMul.h"
|
||||
#include "Tcdefs.h"
|
||||
#include "Common/Endian.h"
|
||||
|
||||
/* BUFFER_ALIGN32 or BUFFER_ALIGN64 must be defined at this point to */
|
||||
/* enable faster operation by taking advantage of memory aligned values */
|
||||
/* NOTE: the BUFFER_ALIGN64 option has not been tested extensively */
|
||||
|
||||
#define BUFFER_ALIGN32
|
||||
#define UNROLL_LOOPS /* define to unroll some loops */
|
||||
#define IN_LINES /* define to use inline functions */
|
||||
/* in place of macros */
|
||||
|
||||
#define mode(x) GM_##x
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef unsigned __int32 mode(32t);
|
||||
typedef uint64 mode(64t);
|
||||
|
||||
#define BRG_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
#define BRG_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER BRG_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER BRG_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma intrinsic(memcpy)
|
||||
#define in_line __inline
|
||||
#else
|
||||
#define in_line
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
#define rotl32 _lrotl
|
||||
#define rotr32 _lrotr
|
||||
#else
|
||||
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
#endif
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
|
||||
#define SWAP_BYTES
|
||||
#else
|
||||
#undef SWAP_BYTES
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
|
||||
#if defined ( IN_LINES )
|
||||
|
||||
in_line void bsw_32(void * p, unsigned int n)
|
||||
{ unsigned int i = n;
|
||||
while(i--)
|
||||
((mode(32t)*)p)[i] = bswap_32(((mode(32t)*)p)[i]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((mode(32t)*)p)[_i] = bswap_32(((mode(32t)*)p)[_i]); }
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
|
||||
/* These values are used to detect long word alignment in order */
|
||||
/* to speed up some GCM buffer operations. This facility may */
|
||||
/* not work on some machines */
|
||||
|
||||
#define lp08(x) ((unsigned char*)(x))
|
||||
#define lp32(x) ((mode(32t)*)(x))
|
||||
#define lp64(x) ((mode(64t)*)(x))
|
||||
|
||||
#define A32_MASK 3
|
||||
#define A64_MASK 7
|
||||
#define aligned32(x) (!(((mode(32t))(x)) & A32_MASK))
|
||||
#define aligned64(x) (!(((mode(32t))(x)) & A64_MASK))
|
||||
|
||||
#if defined( BUFFER_ALIGN32 )
|
||||
|
||||
#define ADR_MASK A32_MASK
|
||||
#define aligned aligned32
|
||||
#define lp lp32
|
||||
#define lp_inc 4
|
||||
|
||||
#if defined( IN_LINES )
|
||||
|
||||
in_line void move_block_aligned( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1],
|
||||
lp32(p)[2] = lp32(q)[2], lp32(p)[3] = lp32(q)[3];
|
||||
}
|
||||
|
||||
in_line void move_block_aligned64( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1];
|
||||
}
|
||||
|
||||
in_line void xor_block_aligned( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1],
|
||||
lp32(p)[2] ^= lp32(q)[2], lp32(p)[3] ^= lp32(q)[3];
|
||||
}
|
||||
|
||||
in_line void xor_block_aligned64( void *p, const void *q)
|
||||
{
|
||||
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define move_block_aligned(p,q) \
|
||||
lp32(p)[0] = lp32(q)[0], lp32(p)[1] = lp32(q)[1], \
|
||||
lp32(p)[2] = lp32(q)[2], lp32(p)[3] = lp32(q)[3]
|
||||
|
||||
#define xor_block_aligned(p,q) \
|
||||
lp32(p)[0] ^= lp32(q)[0], lp32(p)[1] ^= lp32(q)[1], \
|
||||
lp32(p)[2] ^= lp32(q)[2], lp32(p)[3] ^= lp32(q)[3]
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined( BUFFER_ALIGN64 )
|
||||
|
||||
#define ADR_MASK A64_MASK
|
||||
#define aligned aligned64
|
||||
#define lp lp64
|
||||
#define lp_inc 8
|
||||
|
||||
#define move_block_aligned(p,q) \
|
||||
lp64(p)[0] = lp64(q)[0], lp64(p)[1] = lp64(q)[1]
|
||||
|
||||
#define xor_block_aligned(p,q) \
|
||||
lp64(p)[0] ^= lp64(q)[0], lp64(p)[1] ^= lp64(q)[1]
|
||||
|
||||
#else
|
||||
#define aligned(x) 0
|
||||
#endif
|
||||
|
||||
#define move_block(p,q) memcpy((p), (q), BLOCK_LEN)
|
||||
|
||||
#define xor_block(p,q) \
|
||||
lp08(p)[ 0] ^= lp08(q)[ 0], lp08(p)[ 1] ^= lp08(q)[ 1], \
|
||||
lp08(p)[ 2] ^= lp08(q)[ 2], lp08(p)[ 3] ^= lp08(q)[ 3], \
|
||||
lp08(p)[ 4] ^= lp08(q)[ 4], lp08(p)[ 5] ^= lp08(q)[ 5], \
|
||||
lp08(p)[ 6] ^= lp08(q)[ 6], lp08(p)[ 7] ^= lp08(q)[ 7], \
|
||||
lp08(p)[ 8] ^= lp08(q)[ 8], lp08(p)[ 9] ^= lp08(q)[ 9], \
|
||||
lp08(p)[10] ^= lp08(q)[10], lp08(p)[11] ^= lp08(q)[11], \
|
||||
lp08(p)[12] ^= lp08(q)[12], lp08(p)[13] ^= lp08(q)[13], \
|
||||
lp08(p)[14] ^= lp08(q)[14], lp08(p)[15] ^= lp08(q)[15]
|
||||
|
||||
|
||||
#define gf_dat(q) {\
|
||||
q(0x00), q(0x01), q(0x02), q(0x03), q(0x04), q(0x05), q(0x06), q(0x07),\
|
||||
q(0x08), q(0x09), q(0x0a), q(0x0b), q(0x0c), q(0x0d), q(0x0e), q(0x0f),\
|
||||
q(0x10), q(0x11), q(0x12), q(0x13), q(0x14), q(0x15), q(0x16), q(0x17),\
|
||||
q(0x18), q(0x19), q(0x1a), q(0x1b), q(0x1c), q(0x1d), q(0x1e), q(0x1f),\
|
||||
q(0x20), q(0x21), q(0x22), q(0x23), q(0x24), q(0x25), q(0x26), q(0x27),\
|
||||
q(0x28), q(0x29), q(0x2a), q(0x2b), q(0x2c), q(0x2d), q(0x2e), q(0x2f),\
|
||||
q(0x30), q(0x31), q(0x32), q(0x33), q(0x34), q(0x35), q(0x36), q(0x37),\
|
||||
q(0x38), q(0x39), q(0x3a), q(0x3b), q(0x3c), q(0x3d), q(0x3e), q(0x3f),\
|
||||
q(0x40), q(0x41), q(0x42), q(0x43), q(0x44), q(0x45), q(0x46), q(0x47),\
|
||||
q(0x48), q(0x49), q(0x4a), q(0x4b), q(0x4c), q(0x4d), q(0x4e), q(0x4f),\
|
||||
q(0x50), q(0x51), q(0x52), q(0x53), q(0x54), q(0x55), q(0x56), q(0x57),\
|
||||
q(0x58), q(0x59), q(0x5a), q(0x5b), q(0x5c), q(0x5d), q(0x5e), q(0x5f),\
|
||||
q(0x60), q(0x61), q(0x62), q(0x63), q(0x64), q(0x65), q(0x66), q(0x67),\
|
||||
q(0x68), q(0x69), q(0x6a), q(0x6b), q(0x6c), q(0x6d), q(0x6e), q(0x6f),\
|
||||
q(0x70), q(0x71), q(0x72), q(0x73), q(0x74), q(0x75), q(0x76), q(0x77),\
|
||||
q(0x78), q(0x79), q(0x7a), q(0x7b), q(0x7c), q(0x7d), q(0x7e), q(0x7f),\
|
||||
q(0x80), q(0x81), q(0x82), q(0x83), q(0x84), q(0x85), q(0x86), q(0x87),\
|
||||
q(0x88), q(0x89), q(0x8a), q(0x8b), q(0x8c), q(0x8d), q(0x8e), q(0x8f),\
|
||||
q(0x90), q(0x91), q(0x92), q(0x93), q(0x94), q(0x95), q(0x96), q(0x97),\
|
||||
q(0x98), q(0x99), q(0x9a), q(0x9b), q(0x9c), q(0x9d), q(0x9e), q(0x9f),\
|
||||
q(0xa0), q(0xa1), q(0xa2), q(0xa3), q(0xa4), q(0xa5), q(0xa6), q(0xa7),\
|
||||
q(0xa8), q(0xa9), q(0xaa), q(0xab), q(0xac), q(0xad), q(0xae), q(0xaf),\
|
||||
q(0xb0), q(0xb1), q(0xb2), q(0xb3), q(0xb4), q(0xb5), q(0xb6), q(0xb7),\
|
||||
q(0xb8), q(0xb9), q(0xba), q(0xbb), q(0xbc), q(0xbd), q(0xbe), q(0xbf),\
|
||||
q(0xc0), q(0xc1), q(0xc2), q(0xc3), q(0xc4), q(0xc5), q(0xc6), q(0xc7),\
|
||||
q(0xc8), q(0xc9), q(0xca), q(0xcb), q(0xcc), q(0xcd), q(0xce), q(0xcf),\
|
||||
q(0xd0), q(0xd1), q(0xd2), q(0xd3), q(0xd4), q(0xd5), q(0xd6), q(0xd7),\
|
||||
q(0xd8), q(0xd9), q(0xda), q(0xdb), q(0xdc), q(0xdd), q(0xde), q(0xdf),\
|
||||
q(0xe0), q(0xe1), q(0xe2), q(0xe3), q(0xe4), q(0xe5), q(0xe6), q(0xe7),\
|
||||
q(0xe8), q(0xe9), q(0xea), q(0xeb), q(0xec), q(0xed), q(0xee), q(0xef),\
|
||||
q(0xf0), q(0xf1), q(0xf2), q(0xf3), q(0xf4), q(0xf5), q(0xf6), q(0xf7),\
|
||||
q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) }
|
||||
|
||||
/* given the value i in 0..255 as the byte overflow when a a field */
|
||||
/* element in GHASH is multipled by x^8, this function will return */
|
||||
/* the values that are generated in the lo 16-bit word of the field */
|
||||
/* value by applying the modular polynomial. The values lo_byte and */
|
||||
/* hi_byte are returned via the macro xp_fun(lo_byte, hi_byte) so */
|
||||
/* that the values can be assembled into memory as required by a */
|
||||
/* suitable definition of this macro operating on the table above */
|
||||
|
||||
#define xp(i) xp_fun( \
|
||||
(i & 0x80 ? 0xe1 : 0) ^ (i & 0x40 ? 0x70 : 0) ^ \
|
||||
(i & 0x20 ? 0x38 : 0) ^ (i & 0x10 ? 0x1c : 0) ^ \
|
||||
(i & 0x08 ? 0x0e : 0) ^ (i & 0x04 ? 0x07 : 0) ^ \
|
||||
(i & 0x02 ? 0x03 : 0) ^ (i & 0x01 ? 0x01 : 0), \
|
||||
(i & 0x80 ? 0x00 : 0) ^ (i & 0x40 ? 0x80 : 0) ^ \
|
||||
(i & 0x20 ? 0x40 : 0) ^ (i & 0x10 ? 0x20 : 0) ^ \
|
||||
(i & 0x08 ? 0x10 : 0) ^ (i & 0x04 ? 0x08 : 0) ^ \
|
||||
(i & 0x02 ? 0x84 : 0) ^ (i & 0x01 ? 0xc2 : 0) )
|
||||
|
||||
#define xp64(i) xp_fun( \
|
||||
(i & 0x80 ? 0xd8 : 0) ^ (i & 0x40 ? 0x6c : 0) ^ \
|
||||
(i & 0x20 ? 0x36 : 0) ^ (i & 0x10 ? 0x1b : 0) ^ \
|
||||
(i & 0x08 ? 0x0d : 0) ^ (i & 0x04 ? 0x06 : 0) ^ \
|
||||
(i & 0x02 ? 0x03 : 0) ^ (i & 0x01 ? 0x01 : 0), \
|
||||
(i & 0x80 ? 0x00 : 0) ^ (i & 0x40 ? 0x00 : 0) ^ \
|
||||
(i & 0x20 ? 0x00 : 0) ^ (i & 0x10 ? 0x00 : 0) ^ \
|
||||
(i & 0x08 ? 0x80 : 0) ^ (i & 0x04 ? 0xc0 : 0) ^ \
|
||||
(i & 0x02 ? 0x60 : 0) ^ (i & 0x01 ? 0xb0 : 0) )
|
||||
|
||||
static mode(32t) gf_poly[2] = { 0, 0xe1000000 };
|
||||
static mode(32t) gf_poly64[2] = { 0, 0xd8000000 };
|
||||
|
||||
/* Multiply of a GF128 field element by x. The field element */
|
||||
/* is held in an array of bytes in which field bits 8n..8n + 7 */
|
||||
/* are held in byte[n], with lower indexed bits placed in the */
|
||||
/* more numerically significant bit positions in bytes. */
|
||||
|
||||
/* This function multiples a field element x, in the polynomial */
|
||||
/* field representation. It uses 32-bit word operations to gain */
|
||||
/* speed but compensates for machine endianess and hence works */
|
||||
/* correctly on both styles of machine */
|
||||
|
||||
in_line void mul_x(mode(32t) x[4])
|
||||
{ mode(32t) t;
|
||||
|
||||
bsw_32(x, 4);
|
||||
|
||||
/* at this point the filed element bits 0..127 are set out */
|
||||
/* as follows in 32-bit words (where the most significant */
|
||||
/* (ms) numeric bits are to the left) */
|
||||
/* */
|
||||
/* x[0] x[1] x[2] x[3] */
|
||||
/* ms ls ms ls ms ls ms ls */
|
||||
/* field: 0 ... 31 32 .. 63 64 .. 95 96 .. 127 */
|
||||
|
||||
t = gf_poly[x[3] & 1]; /* bit 127 of the element */
|
||||
x[3] = (x[3] >> 1) | (x[2] << 31); /* shift bits up by one */
|
||||
x[2] = (x[2] >> 1) | (x[1] << 31); /* position */
|
||||
x[1] = (x[1] >> 1) | (x[0] << 31); /* if bit 7 is 1 xor in */
|
||||
x[0] = (x[0] >> 1) ^ t; /* the field polynomial */
|
||||
bsw_32(x, 4);
|
||||
}
|
||||
|
||||
in_line void mul_x64(mode(32t) x[2])
|
||||
{ mode(32t) t;
|
||||
|
||||
bsw_32(x, 2);
|
||||
|
||||
/* at this point the filed element bits 0..127 are set out */
|
||||
/* as follows in 32-bit words (where the most significant */
|
||||
/* (ms) numeric bits are to the left) */
|
||||
/* */
|
||||
/* x[0] x[1] x[2] x[3] */
|
||||
/* ms ls ms ls ms ls ms ls */
|
||||
/* field: 0 ... 31 32 .. 63 64 .. 95 96 .. 127 */
|
||||
|
||||
t = gf_poly64[x[1] & 1]; /* bit 127 of the element */
|
||||
/* shift bits up by one */
|
||||
/* position */
|
||||
x[1] = (x[1] >> 1) | (x[0] << 31); /* if bit 7 is 1 xor in */
|
||||
x[0] = (x[0] >> 1) ^ t; /* the field polynomial */
|
||||
bsw_32(x, 2);
|
||||
}
|
||||
|
||||
/* Multiply of a GF128 field element by x^8 using 32-bit words */
|
||||
/* for speed - machine endianess matters here */
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
|
||||
|
||||
#define xp_fun(x,y) ((mode(32t))(x)) | (((mode(32t))(y)) << 8)
|
||||
static const unsigned __int16 gft_le[256] = gf_dat(xp);
|
||||
static const unsigned __int16 gft_le64[256] = gf_dat(xp64);
|
||||
|
||||
in_line void mul_lex8(mode(32t) x[4]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[3] >> 24); /* in little endian format */
|
||||
x[3] = (x[3] << 8) | (x[2] >> 24);
|
||||
x[2] = (x[2] << 8) | (x[1] >> 24);
|
||||
x[1] = (x[1] << 8) | (x[0] >> 24);
|
||||
x[0] = (x[0] << 8) ^ gft_le[t];
|
||||
}
|
||||
|
||||
in_line void mul_lex8_64(mode(32t) x[2]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[1] >> 24); /* in little endian format */
|
||||
x[1] = (x[1] << 8) | (x[0] >> 24);
|
||||
x[0] = (x[0] << 8) ^ gft_le64[t];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 1 || (PLATFORM_BYTE_ORDER == BRG_LITTLE_ENDIAN)
|
||||
|
||||
#undef xp_fun
|
||||
#define xp_fun(x,y) ((mode(32t))(y)) | (((mode(32t))(x)) << 8)
|
||||
static const unsigned __int16 gft_be[256] = gf_dat(xp);
|
||||
static const unsigned __int16 gft_be64[256] = gf_dat(xp64);
|
||||
|
||||
in_line void mul_bex8(mode(32t) x[4]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[3] & 0xff); /* in big endian format */
|
||||
x[3] = (x[3] >> 8) | (x[2] << 24);
|
||||
x[2] = (x[2] >> 8) | (x[1] << 24);
|
||||
x[1] = (x[1] >> 8) | (x[0] << 24);
|
||||
x[0] = (x[0] >> 8) ^ (((mode(32t))gft_be[t]) << 16);
|
||||
}
|
||||
|
||||
in_line void mul_bex8_64(mode(32t) x[2]) /* mutiply with long words */
|
||||
{ mode(32t) t = (x[1] & 0xff); /* in big endian format */
|
||||
x[1] = (x[1] >> 8) | (x[0] << 24);
|
||||
x[0] = (x[0] >> 8) ^ (((mode(32t))gft_be64[t]) << 16);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* hence choose the correct version for the machine endianess */
|
||||
|
||||
#if PLATFORM_BYTE_ORDER == BRG_BIG_ENDIAN
|
||||
#define mul_x8 mul_bex8
|
||||
#define mul_x8_64 mul_bex8_64
|
||||
#else
|
||||
#define mul_x8 mul_lex8
|
||||
#define mul_x8_64 mul_lex8_64
|
||||
#endif
|
||||
|
||||
/* different versions of the general gf_mul function are provided */
|
||||
/* here. Sadly none are very fast :-( */
|
||||
|
||||
void GfMul128 (void *a, const void* b)
|
||||
{ mode(32t) r[CBLK_LEN >> 2], p[8][CBLK_LEN >> 2];
|
||||
int i;
|
||||
|
||||
move_block_aligned(p[0], b);
|
||||
bsw_32(p[0], 4);
|
||||
for(i = 0; i < 7; ++i)
|
||||
{
|
||||
p[i + 1][3] = (p[i][3] >> 1) | (p[i][2] << 31);
|
||||
p[i + 1][2] = (p[i][2] >> 1) | (p[i][1] << 31);
|
||||
p[i + 1][1] = (p[i][1] >> 1) | (p[i][0] << 31);
|
||||
p[i + 1][0] = (p[i][0] >> 1) ^ gf_poly[p[i][3] & 1];
|
||||
}
|
||||
|
||||
memset(r, 0, CBLK_LEN);
|
||||
for(i = 0; i < 16; ++i)
|
||||
{
|
||||
if(i) mul_bex8(r); /* order is always big endian here */
|
||||
|
||||
if(((unsigned char*)a)[15 - i] & 0x80)
|
||||
xor_block_aligned(r, p[0]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x40)
|
||||
xor_block_aligned(r, p[1]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x20)
|
||||
xor_block_aligned(r, p[2]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x10)
|
||||
xor_block_aligned(r, p[3]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x08)
|
||||
xor_block_aligned(r, p[4]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x04)
|
||||
xor_block_aligned(r, p[5]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x02)
|
||||
xor_block_aligned(r, p[6]);
|
||||
if(((unsigned char*)a)[15 - i] & 0x01)
|
||||
xor_block_aligned(r, p[7]);
|
||||
}
|
||||
bsw_32(r, 4);
|
||||
move_block_aligned(a, r);
|
||||
}
|
||||
|
||||
#if defined( UNROLL_LOOPS )
|
||||
|
||||
#define xor_8k(i) \
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i][a[i] & 15]); \
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i + 1][a[i] >> 4])
|
||||
|
||||
|
||||
void GfMul128Tab (unsigned char a[CBLK_LEN], GfCtx8k *ctx)
|
||||
{ unsigned __int32 r[CBLK_LEN >> 2];
|
||||
|
||||
move_block_aligned(r, ctx->gf_t8k[0][a[0] & 15]);
|
||||
xor_block_aligned(r, ctx->gf_t8k[1][a[0] >> 4]);
|
||||
xor_8k( 1); xor_8k( 2); xor_8k( 3);
|
||||
xor_8k( 4); xor_8k( 5); xor_8k( 6); xor_8k( 7);
|
||||
xor_8k( 8); xor_8k( 9); xor_8k(10); xor_8k(11);
|
||||
xor_8k(12); xor_8k(13); xor_8k(14); xor_8k(15);
|
||||
move_block_aligned(a, r);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void GfMul128Tab (unsigned char a[CBLK_LEN], GfCtx8k *ctx)
|
||||
{ unsigned __int32 r[CBLK_LEN >> 2], *p;
|
||||
int i;
|
||||
|
||||
p = ctx->gf_t8k[0][a[0] & 15];
|
||||
memcpy(r, p, CBLK_LEN);
|
||||
p = ctx->gf_t8k[1][a[0] >> 4];
|
||||
xor_block_aligned(r, p);
|
||||
for(i = 1; i < CBLK_LEN; ++i)
|
||||
{
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i][a[i] & 15]);
|
||||
xor_block_aligned(r, ctx->gf_t8k[i + i + 1][a[i] >> 4]);
|
||||
}
|
||||
memcpy(a, r, CBLK_LEN);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void compile_8k_table(unsigned __int8 *a, GfCtx8k *ctx)
|
||||
{ int i, j, k;
|
||||
|
||||
memset(ctx->gf_t8k, 0, 32 * 16 * 16);
|
||||
for(i = 0; i < 2 * CBLK_LEN; ++i)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[1][8], a, CBLK_LEN);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[1][j], ctx->gf_t8k[1][j + j], CBLK_LEN);
|
||||
mul_x(ctx->gf_t8k[1][j]);
|
||||
}
|
||||
memcpy(ctx->gf_t8k[0][8], ctx->gf_t8k[1][1], CBLK_LEN);
|
||||
mul_x(ctx->gf_t8k[0][8]);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[0][j], ctx->gf_t8k[0][j + j], CBLK_LEN);
|
||||
mul_x(ctx->gf_t8k[0][j]);
|
||||
}
|
||||
}
|
||||
else if(i > 1)
|
||||
for(j = 8; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t8k[i][j], ctx->gf_t8k[i - 2][j], CBLK_LEN);
|
||||
mul_x8(ctx->gf_t8k[i][j]);
|
||||
}
|
||||
|
||||
for(j = 2; j < 16; j += j)
|
||||
{
|
||||
mode(32t) *pj = ctx->gf_t8k[i][j];
|
||||
mode(32t) *pk = ctx->gf_t8k[i][1];
|
||||
mode(32t) *pl = ctx->gf_t8k[i][j + 1];
|
||||
|
||||
for(k = 1; k < j; ++k)
|
||||
{
|
||||
*pl++ = pj[0] ^ *pk++;
|
||||
*pl++ = pj[1] ^ *pk++;
|
||||
*pl++ = pj[2] ^ *pk++;
|
||||
*pl++ = pj[3] ^ *pk++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void compile_4k_table64(unsigned __int8 *a, GfCtx4k64 *ctx)
|
||||
{ int i, j, k;
|
||||
|
||||
memset(ctx->gf_t4k, 0, sizeof(ctx->gf_t4k));
|
||||
for(i = 0; i < 2 * CBLK_LEN8; ++i)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[1][8], a, CBLK_LEN8);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[1][j], ctx->gf_t4k[1][j + j], CBLK_LEN8);
|
||||
mul_x64(ctx->gf_t4k[1][j]);
|
||||
}
|
||||
memcpy(ctx->gf_t4k[0][8], ctx->gf_t4k[1][1], CBLK_LEN8);
|
||||
mul_x64(ctx->gf_t4k[0][8]);
|
||||
for(j = 4; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[0][j], ctx->gf_t4k[0][j + j], CBLK_LEN8);
|
||||
mul_x64(ctx->gf_t4k[0][j]);
|
||||
}
|
||||
}
|
||||
else if(i > 1)
|
||||
for(j = 8; j > 0; j >>= 1)
|
||||
{
|
||||
memcpy(ctx->gf_t4k[i][j], ctx->gf_t4k[i - 2][j], CBLK_LEN8);
|
||||
mul_x8_64(ctx->gf_t4k[i][j]);
|
||||
}
|
||||
|
||||
for(j = 2; j < 16; j += j)
|
||||
{
|
||||
mode(32t) *pj = ctx->gf_t4k[i][j];
|
||||
mode(32t) *pk = ctx->gf_t4k[i][1];
|
||||
mode(32t) *pl = ctx->gf_t4k[i][j + 1];
|
||||
|
||||
for(k = 1; k < j; ++k)
|
||||
{
|
||||
*pl++ = pj[0] ^ *pk++;
|
||||
*pl++ = pj[1] ^ *pk++;
|
||||
*pl++ = pj[2] ^ *pk++;
|
||||
*pl++ = pj[3] ^ *pk++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int IsBitSet128 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
return a[(127 - bit) / 8] & (0x80 >> ((127 - bit) % 8));
|
||||
}
|
||||
|
||||
static int IsBitSet64 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
return a[(63 - bit) / 8] & (0x80 >> ((63 - bit) % 8));
|
||||
}
|
||||
|
||||
static void SetBit128 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
a[(127 - bit) / 8] |= 0x80 >> ((127 - bit) % 8);
|
||||
}
|
||||
|
||||
static void SetBit64 (unsigned int bit, unsigned __int8 *a)
|
||||
{
|
||||
a[(63 - bit) / 8] |= 0x80 >> ((63 - bit) % 8);
|
||||
}
|
||||
|
||||
void MirrorBits128 (unsigned __int8 *a)
|
||||
{
|
||||
unsigned __int8 t[128 / 8];
|
||||
int i;
|
||||
memset (t,0,16);
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
if (IsBitSet128(i, a))
|
||||
SetBit128 (127 - i, t);
|
||||
}
|
||||
memcpy (a, t, sizeof (t));
|
||||
burn (t,sizeof (t));
|
||||
}
|
||||
|
||||
void MirrorBits64 (unsigned __int8 *a)
|
||||
{
|
||||
unsigned __int8 t[64 / 8];
|
||||
int i;
|
||||
memset (t,0,8);
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
if (IsBitSet64(i, a))
|
||||
SetBit64 (63 - i, t);
|
||||
}
|
||||
memcpy (a, t, sizeof (t));
|
||||
burn (t,sizeof (t));
|
||||
}
|
||||
|
||||
/* Allocate and initialize speed optimization table
|
||||
for multiplication by 64-bit operand in MSB-first mode */
|
||||
int Gf128Tab64Init (unsigned __int8 *a, GfCtx *ctx)
|
||||
{
|
||||
GfCtx8k *ctx8k;
|
||||
unsigned __int8 am[16];
|
||||
int i, j;
|
||||
|
||||
ctx8k = (GfCtx8k *) TCalloc (sizeof (GfCtx8k));
|
||||
if (!ctx8k)
|
||||
return FALSE;
|
||||
|
||||
memcpy (am, a, 16);
|
||||
MirrorBits128 (am);
|
||||
compile_8k_table (am, ctx8k);
|
||||
|
||||
/* Convert 8k LSB-first table to 4k MSB-first */
|
||||
for (i = 16; i < 32; i++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
int jm = 0;
|
||||
jm |= (j & 0x1) << 3;
|
||||
jm |= (j & 0x2) << 1;
|
||||
jm |= (j & 0x4) >> 1;
|
||||
jm |= (j & 0x8) >> 3;
|
||||
|
||||
memcpy (&ctx->gf_t128[i-16][jm], (unsigned char *)&ctx8k->gf_t8k[31-i][j], 16);
|
||||
MirrorBits128 ((unsigned char *)&ctx->gf_t128[i-16][jm]);
|
||||
}
|
||||
}
|
||||
|
||||
burn (ctx8k ,sizeof (*ctx8k));
|
||||
burn (am, sizeof (am));
|
||||
TCfree (ctx8k);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int Gf64TabInit (unsigned __int8 *a, GfCtx *ctx)
|
||||
{
|
||||
/* Deprecated/legacy */
|
||||
|
||||
GfCtx4k64 *ctx4k;
|
||||
unsigned __int8 am[8];
|
||||
int i, j;
|
||||
|
||||
ctx4k = (GfCtx4k64 *) TCalloc (sizeof (GfCtx4k64));
|
||||
if (!ctx4k)
|
||||
return FALSE;
|
||||
|
||||
memcpy (am, a, 8);
|
||||
MirrorBits64 (am);
|
||||
compile_4k_table64 (am, ctx4k);
|
||||
|
||||
/* Convert LSB-first table to MSB-first */
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
int jm = 0;
|
||||
jm |= (j & 0x1) << 3;
|
||||
jm |= (j & 0x2) << 1;
|
||||
jm |= (j & 0x4) >> 1;
|
||||
jm |= (j & 0x8) >> 3;
|
||||
|
||||
memcpy (&ctx->gf_t64[i][jm], (unsigned char *)&ctx4k->gf_t4k[15-i][j], 8);
|
||||
MirrorBits64 ((unsigned char *)&ctx->gf_t64[i][jm]);
|
||||
}
|
||||
}
|
||||
|
||||
burn (ctx4k,sizeof (*ctx4k));
|
||||
burn (am, sizeof (am));
|
||||
TCfree (ctx4k);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define xor_8kt64(i) \
|
||||
xor_block_aligned(r, ctx->gf_t128[i + i][a[i] & 15]); \
|
||||
xor_block_aligned(r, ctx->gf_t128[i + i + 1][a[i] >> 4])
|
||||
|
||||
/* Multiply a 128-bit number by a 64-bit number in the finite field GF(2^128) */
|
||||
void Gf128MulBy64Tab (unsigned __int8 a[8], unsigned __int8 p[16], GfCtx *ctx)
|
||||
{
|
||||
unsigned __int32 r[CBLK_LEN >> 2];
|
||||
|
||||
move_block_aligned(r, ctx->gf_t128[7*2][a[7] & 15]);
|
||||
xor_block_aligned(r, ctx->gf_t128[7*2+1][a[7] >> 4]);
|
||||
|
||||
if (*(unsigned __int16 *)a)
|
||||
{
|
||||
xor_8kt64(0);
|
||||
xor_8kt64(1);
|
||||
}
|
||||
if (a[2])
|
||||
{
|
||||
xor_8kt64(2);
|
||||
}
|
||||
xor_8kt64(3);
|
||||
xor_8kt64(4);
|
||||
xor_8kt64(5);
|
||||
xor_8kt64(6);
|
||||
|
||||
move_block_aligned(p, r);
|
||||
}
|
||||
|
||||
#define xor_8k64(i) \
|
||||
xor_block_aligned64(r, ctx->gf_t64[i + i][a[i] & 15]); \
|
||||
xor_block_aligned64(r, ctx->gf_t64[i + i + 1][a[i] >> 4])
|
||||
|
||||
/* Multiply two 64-bit numbers in the finite field GF(2^64) */
|
||||
void Gf64MulTab (unsigned char a[8], unsigned char p[8], GfCtx *ctx)
|
||||
{
|
||||
/* Deprecated/legacy */
|
||||
|
||||
unsigned __int32 r[CBLK_LEN8 >> 2];
|
||||
|
||||
move_block_aligned64(r, ctx->gf_t64[7*2][a[7] & 15]);
|
||||
xor_block_aligned64(r, ctx->gf_t64[7*2+1][a[7] >> 4]);
|
||||
|
||||
if (*(unsigned __int16 *)a)
|
||||
{
|
||||
xor_8k64(0);
|
||||
xor_8k64(1);
|
||||
}
|
||||
if (a[2])
|
||||
{
|
||||
xor_8k64(2);
|
||||
}
|
||||
xor_8k64(3);
|
||||
xor_8k64(4);
|
||||
xor_8k64(5);
|
||||
xor_8k64(6);
|
||||
|
||||
move_block_aligned64(p, r);
|
||||
}
|
||||
|
||||
|
||||
/* Basic algorithms for testing of optimized algorithms */
|
||||
|
||||
static void xor128 (uint64 *a, uint64 *b)
|
||||
{
|
||||
*a++ ^= *b++;
|
||||
*a ^= *b;
|
||||
}
|
||||
|
||||
static void shl128 (unsigned __int8 *a)
|
||||
{
|
||||
int i, x = 0, xx;
|
||||
for (i = 15; i >= 0; i--)
|
||||
{
|
||||
xx = (a[i] & 0x80) >> 7;
|
||||
a[i] = (char) ((a[i] << 1) | x);
|
||||
x = xx;
|
||||
}
|
||||
}
|
||||
|
||||
static void GfMul128Basic (unsigned __int8 *a, unsigned __int8 *b, unsigned __int8 *p)
|
||||
{
|
||||
int i;
|
||||
unsigned __int8 la[16];
|
||||
memcpy (la, a, 16);
|
||||
memset (p, 0, 16);
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
if (IsBitSet128 (i, b))
|
||||
xor128 ((uint64 *)p, (uint64 *)la);
|
||||
|
||||
if (la[0] & 0x80)
|
||||
{
|
||||
shl128 (la);
|
||||
la[15] ^= 0x87;
|
||||
}
|
||||
else
|
||||
{
|
||||
shl128 (la);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void xor64 (uint64 *a, uint64 *b)
|
||||
{
|
||||
*a ^= *b;
|
||||
}
|
||||
|
||||
static void shl64 (unsigned __int8 *a)
|
||||
{
|
||||
int i, x = 0, xx;
|
||||
for (i = 7; i >= 0; i--)
|
||||
{
|
||||
xx = (a[i] & 0x80) >> 7;
|
||||
a[i] = (char) ((a[i] << 1) | x);
|
||||
x = xx;
|
||||
}
|
||||
}
|
||||
|
||||
static void GfMul64Basic (unsigned __int8 *a, unsigned __int8 *b, unsigned __int8* p)
|
||||
{
|
||||
/* Deprecated/legacy */
|
||||
|
||||
int i;
|
||||
unsigned __int8 la[8];
|
||||
memcpy (la, a, 8);
|
||||
memset (p, 0, 8);
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
if (IsBitSet64 (i, b))
|
||||
xor64 ((uint64 *)p, (uint64 *)la);
|
||||
|
||||
if (la[0] & 0x80)
|
||||
{
|
||||
shl64 (la);
|
||||
la[7] ^= 0x1b;
|
||||
}
|
||||
else
|
||||
{
|
||||
shl64 (la);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL GfMulSelfTest ()
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
unsigned __int8 a[16];
|
||||
unsigned __int8 b[16];
|
||||
unsigned __int8 p1[16];
|
||||
unsigned __int8 p2[16];
|
||||
GfCtx *gfCtx = (GfCtx *) TCalloc (sizeof (GfCtx));
|
||||
int i, j;
|
||||
|
||||
if (!gfCtx)
|
||||
return FALSE;
|
||||
|
||||
/* GF(2^64) - deprecated/legacy */
|
||||
for (i = 0; i < 0x100; i++)
|
||||
{
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
a[j] = (unsigned __int8) i;
|
||||
b[j] = a[j] ^ 0xff;
|
||||
}
|
||||
|
||||
GfMul64Basic (a, b, p1);
|
||||
|
||||
Gf64TabInit (a, gfCtx);
|
||||
Gf64MulTab (b, p2, gfCtx);
|
||||
|
||||
if (memcmp (p1, p2, 8) != 0)
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
/* GF(2^128) */
|
||||
for (i = 0; i < 0x100; i++)
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
a[j] = (unsigned __int8) i;
|
||||
b[j] = j < 8 ? 0 : a[j] ^ 0xff;
|
||||
}
|
||||
|
||||
GfMul128Basic (a, b, p1);
|
||||
|
||||
Gf128Tab64Init (a, gfCtx);
|
||||
Gf128MulBy64Tab (b + 8, p2, gfCtx);
|
||||
|
||||
if (memcmp (p1, p2, 16) != 0)
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
TCfree (gfCtx);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
76
src/Common/GfMul.h
Normal file
76
src/Common/GfMul.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 2003, Dr Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The free distribution and use of this software is allowed (with or without
|
||||
changes) provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 31/01/2004
|
||||
*/
|
||||
|
||||
/* Adapted for TrueCrypt */
|
||||
|
||||
#ifndef _GCM_H
|
||||
#define _GCM_H
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define CBLK_LEN 16 /* encryption block length */
|
||||
#define CBLK_LEN8 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned __int32 gf_t8k[CBLK_LEN * 2][16][CBLK_LEN / 4];
|
||||
} GfCtx8k;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned __int32 gf_t4k[CBLK_LEN8 * 2][16][CBLK_LEN / 4];
|
||||
} GfCtx4k64;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* union not used to support faster mounting */
|
||||
unsigned __int32 gf_t128[CBLK_LEN * 2 / 2][16][CBLK_LEN / 4];
|
||||
unsigned __int32 gf_t64[CBLK_LEN8 * 2][16][CBLK_LEN8 / 4];
|
||||
} GfCtx;
|
||||
|
||||
typedef int ret_type;
|
||||
|
||||
void GfMul128 (void *a, const void* b);
|
||||
void GfMul128Tab(unsigned char a[16], GfCtx8k *ctx);
|
||||
int Gf128Tab64Init (unsigned __int8 *a, GfCtx *ctx);
|
||||
void Gf128MulBy64Tab (unsigned __int8 a[8], unsigned __int8 p[16], GfCtx *ctx);
|
||||
int Gf64TabInit (unsigned __int8 *a, GfCtx *ctx);
|
||||
void Gf64MulTab (unsigned char a[8], unsigned char p[8], GfCtx *ctx);
|
||||
void MirrorBits128 (unsigned __int8 *a);
|
||||
void MirrorBits64 (unsigned __int8 *a);
|
||||
BOOL GfMulSelfTest ();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1308
src/Common/Inflate.c
Normal file
1308
src/Common/Inflate.c
Normal file
File diff suppressed because it is too large
Load Diff
51
src/Common/Inflate.h
Normal file
51
src/Common/Inflate.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define WSIZE 0x8000 // Window size
|
||||
#define ZCONST const
|
||||
#define OF(p) p
|
||||
|
||||
typedef unsigned long ulg;
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef void zvoid;
|
||||
|
||||
typedef struct huft
|
||||
{
|
||||
uch b, e;
|
||||
union
|
||||
{
|
||||
ush n;
|
||||
struct huft *t;
|
||||
}v;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uch *inptr, *outbufptr;
|
||||
int incnt;
|
||||
int outCounter;
|
||||
|
||||
struct huft *fixed_tl;
|
||||
struct huft *fixed_td;
|
||||
int fixed_bl, fixed_bd;
|
||||
|
||||
unsigned bk, wp;
|
||||
ulg bb;
|
||||
} G_struct;
|
||||
|
||||
#define __GPRO void
|
||||
#define __GPRO__
|
||||
#define __G
|
||||
#define __G__
|
||||
#define __GDEF
|
||||
|
||||
|
||||
#define FLUSH(cnt) { memcpy (G.outbufptr, redirSlide, cnt); G.outbufptr += cnt; G.outCounter += cnt; }
|
||||
#define NEXTBYTE (((G.incnt--) >= 0) ? (*G.inptr++) : EOF)
|
||||
|
||||
|
||||
int huft_free(struct huft *t);
|
||||
int huft_build(__GDEF ZCONST unsigned *b, unsigned n, unsigned s, ZCONST ush *d, ZCONST ush *e, struct huft **t, int *m);
|
||||
|
||||
int DecompressDeflatedData (char *out, char *in, int inLength);
|
||||
685
src/Common/Keyfiles.c
Normal file
685
src/Common/Keyfiles.c
Normal file
@@ -0,0 +1,685 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Keyfiles.h"
|
||||
#include "Crc.h"
|
||||
|
||||
#include <io.h>
|
||||
#include "Dlgcode.h"
|
||||
#include "Language.h"
|
||||
#include "SecurityToken.h"
|
||||
#include "Common/resource.h"
|
||||
#include "Platform/Finally.h"
|
||||
#include "Platform/ForEach.h"
|
||||
|
||||
using namespace TrueCrypt;
|
||||
|
||||
#define stat _stat
|
||||
#define S_IFDIR _S_IFDIR
|
||||
#define snprintf _snprintf
|
||||
|
||||
|
||||
BOOL HiddenFilesPresentInKeyfilePath = FALSE;
|
||||
|
||||
|
||||
KeyFile *KeyFileAdd (KeyFile *firstKeyFile, KeyFile *keyFile)
|
||||
{
|
||||
KeyFile *kf = firstKeyFile;
|
||||
|
||||
if (firstKeyFile != NULL)
|
||||
{
|
||||
while (kf->Next)
|
||||
kf = kf->Next;
|
||||
|
||||
kf->Next = keyFile;
|
||||
}
|
||||
else
|
||||
firstKeyFile = keyFile;
|
||||
|
||||
keyFile->Next = NULL;
|
||||
|
||||
return firstKeyFile;
|
||||
}
|
||||
|
||||
|
||||
// Returns first keyfile, NULL if last keyfile was removed
|
||||
static KeyFile *KeyFileRemove (KeyFile *firstKeyFile, KeyFile *keyFile)
|
||||
{
|
||||
KeyFile *prevkf = NULL, *kf = firstKeyFile;
|
||||
|
||||
if (firstKeyFile == NULL) return NULL;
|
||||
do
|
||||
{
|
||||
if (kf == keyFile)
|
||||
{
|
||||
if (prevkf == NULL)
|
||||
firstKeyFile = kf->Next;
|
||||
else
|
||||
prevkf->Next = kf->Next;
|
||||
|
||||
burn (keyFile, sizeof(*keyFile)); // wipe
|
||||
free (keyFile);
|
||||
break;
|
||||
}
|
||||
prevkf = kf;
|
||||
}
|
||||
while (kf = kf->Next);
|
||||
|
||||
return firstKeyFile;
|
||||
}
|
||||
|
||||
|
||||
void KeyFileRemoveAll (KeyFile **firstKeyFile)
|
||||
{
|
||||
KeyFile *kf = *firstKeyFile;
|
||||
while (kf != NULL)
|
||||
{
|
||||
KeyFile *d = kf;
|
||||
kf = kf->Next;
|
||||
burn (d, sizeof(*d)); // wipe
|
||||
free (d);
|
||||
}
|
||||
|
||||
*firstKeyFile = NULL;
|
||||
}
|
||||
|
||||
|
||||
KeyFile *KeyFileClone (KeyFile *keyFile)
|
||||
{
|
||||
KeyFile *clone;
|
||||
|
||||
if (keyFile == NULL) return NULL;
|
||||
|
||||
clone = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
strcpy (clone->FileName, keyFile->FileName);
|
||||
clone->Next = NULL;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
KeyFile *KeyFileCloneAll (KeyFile *firstKeyFile)
|
||||
{
|
||||
KeyFile *cloneFirstKeyFile = KeyFileClone (firstKeyFile);
|
||||
KeyFile *kf;
|
||||
|
||||
if (firstKeyFile == NULL) return NULL;
|
||||
kf = firstKeyFile->Next;
|
||||
while (kf != NULL)
|
||||
{
|
||||
KeyFileAdd (cloneFirstKeyFile, KeyFileClone (kf));
|
||||
kf = kf->Next;
|
||||
}
|
||||
|
||||
return cloneFirstKeyFile;
|
||||
}
|
||||
|
||||
|
||||
static BOOL KeyFileProcess (unsigned __int8 *keyPool, KeyFile *keyFile)
|
||||
{
|
||||
FILE *f;
|
||||
unsigned __int8 buffer[64 * 1024];
|
||||
unsigned __int32 crc = 0xffffffff;
|
||||
int writePos = 0;
|
||||
size_t bytesRead, totalRead = 0;
|
||||
int status = TRUE;
|
||||
|
||||
HANDLE src;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
|
||||
BOOL bTimeStampValid = FALSE;
|
||||
|
||||
/* Remember the last access time of the keyfile. It will be preserved in order to prevent
|
||||
an adversary from determining which file may have been used as keyfile. */
|
||||
src = CreateFile (keyFile->FileName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (src != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetFileTime ((HANDLE) src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime))
|
||||
bTimeStampValid = TRUE;
|
||||
}
|
||||
|
||||
finally_do_arg (HANDLE, src,
|
||||
{
|
||||
if (finally_arg != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (finally_arg);
|
||||
});
|
||||
|
||||
f = fopen (keyFile->FileName, "rb");
|
||||
if (f == NULL) return FALSE;
|
||||
|
||||
while ((bytesRead = fread (buffer, 1, sizeof (buffer), f)) > 0)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (ferror (f))
|
||||
{
|
||||
status = FALSE;
|
||||
goto close;
|
||||
}
|
||||
|
||||
for (i = 0; i < bytesRead; i++)
|
||||
{
|
||||
crc = UPDC32 (buffer[i], crc);
|
||||
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 24);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 16);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
|
||||
keyPool[writePos++] += (unsigned __int8) crc;
|
||||
|
||||
if (writePos >= KEYFILE_POOL_SIZE)
|
||||
writePos = 0;
|
||||
|
||||
if (++totalRead >= KEYFILE_MAX_READ_LEN)
|
||||
goto close;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror (f))
|
||||
{
|
||||
status = FALSE;
|
||||
}
|
||||
else if (totalRead == 0)
|
||||
{
|
||||
status = FALSE;
|
||||
SetLastError (ERROR_HANDLE_EOF);
|
||||
}
|
||||
|
||||
close:
|
||||
DWORD err = GetLastError();
|
||||
fclose (f);
|
||||
|
||||
if (bTimeStampValid && !IsFileOnReadOnlyFilesystem (keyFile->FileName))
|
||||
{
|
||||
// Restore the keyfile timestamp
|
||||
SetFileTime (src, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);
|
||||
}
|
||||
|
||||
SetLastError (err);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
BOOL KeyFilesApply (Password *password, KeyFile *firstKeyFile)
|
||||
{
|
||||
BOOL status = TRUE;
|
||||
KeyFile kfSubStruct;
|
||||
KeyFile *kf;
|
||||
KeyFile *kfSub = &kfSubStruct;
|
||||
static unsigned __int8 keyPool [KEYFILE_POOL_SIZE];
|
||||
size_t i;
|
||||
struct stat statStruct;
|
||||
char searchPath [TC_MAX_PATH*2];
|
||||
struct _finddata_t fBuf;
|
||||
intptr_t searchHandle;
|
||||
|
||||
HiddenFilesPresentInKeyfilePath = FALSE;
|
||||
|
||||
if (firstKeyFile == NULL) return TRUE;
|
||||
|
||||
VirtualLock (keyPool, sizeof (keyPool));
|
||||
memset (keyPool, 0, sizeof (keyPool));
|
||||
|
||||
for (kf = firstKeyFile; kf != NULL; kf = kf->Next)
|
||||
{
|
||||
// Determine whether it's a security token path
|
||||
try
|
||||
{
|
||||
if (SecurityToken::IsKeyfilePathValid (SingleStringToWide (kf->FileName)))
|
||||
{
|
||||
// Apply security token keyfile
|
||||
vector <byte> keyfileData;
|
||||
SecurityToken::GetKeyfileData (SecurityTokenKeyfile (SingleStringToWide (kf->FileName)), keyfileData);
|
||||
|
||||
if (keyfileData.empty())
|
||||
{
|
||||
SetLastError (ERROR_HANDLE_EOF);
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned __int32 crc = 0xffffffff;
|
||||
int writePos = 0;
|
||||
size_t totalRead = 0;
|
||||
|
||||
for (size_t i = 0; i < keyfileData.size(); i++)
|
||||
{
|
||||
crc = UPDC32 (keyfileData[i], crc);
|
||||
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 24);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 16);
|
||||
keyPool[writePos++] += (unsigned __int8) (crc >> 8);
|
||||
keyPool[writePos++] += (unsigned __int8) crc;
|
||||
|
||||
if (writePos >= KEYFILE_POOL_SIZE)
|
||||
writePos = 0;
|
||||
|
||||
if (++totalRead >= KEYFILE_MAX_READ_LEN)
|
||||
break;
|
||||
}
|
||||
|
||||
burn (&keyfileData.front(), keyfileData.size());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
e.Show (NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Determine whether it's a path or a file
|
||||
if (stat (kf->FileName, &statStruct) != 0)
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (statStruct.st_mode & S_IFDIR) // If it's a directory
|
||||
{
|
||||
/* Find and process all keyfiles in the directory */
|
||||
int keyfileCount = 0;
|
||||
|
||||
snprintf (searchPath, sizeof (searchPath), "%s\\*.*", kf->FileName);
|
||||
if ((searchHandle = _findfirst (searchPath, &fBuf)) == -1)
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE_PATH");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA fileAttributes;
|
||||
|
||||
snprintf (kfSub->FileName, sizeof(kfSub->FileName), "%s%c%s", kf->FileName,
|
||||
'\\',
|
||||
fBuf.name
|
||||
);
|
||||
|
||||
// Determine whether it's a path or a file
|
||||
if (stat (kfSub->FileName, &statStruct) != 0)
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
continue;
|
||||
}
|
||||
else if (statStruct.st_mode & S_IFDIR) // If it's a directory
|
||||
{
|
||||
// Prevent recursive folder scanning
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip hidden files
|
||||
if (GetFileAttributesEx (kfSub->FileName, GetFileExInfoStandard, &fileAttributes)
|
||||
&& (fileAttributes.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0)
|
||||
{
|
||||
HiddenFilesPresentInKeyfilePath = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
++keyfileCount;
|
||||
|
||||
// Apply keyfile to the pool
|
||||
if (!KeyFileProcess (keyPool, kfSub))
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
}
|
||||
|
||||
} while (_findnext (searchHandle, &fBuf) != -1);
|
||||
_findclose (searchHandle);
|
||||
|
||||
burn (&kfSubStruct, sizeof (kfSubStruct));
|
||||
|
||||
if (keyfileCount == 0)
|
||||
{
|
||||
ErrorDirect ((wstring (GetString ("ERR_KEYFILE_PATH_EMPTY")) + L"\n\n" + SingleStringToWide (kf->FileName)).c_str());
|
||||
status = FALSE;
|
||||
}
|
||||
}
|
||||
// Apply keyfile to the pool
|
||||
else if (!KeyFileProcess (keyPool, kf))
|
||||
{
|
||||
handleWin32Error (MainDlg);
|
||||
Error ("ERR_PROCESS_KEYFILE");
|
||||
status = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mix the keyfile pool contents into the password */
|
||||
|
||||
for (i = 0; i < sizeof (keyPool); i++)
|
||||
{
|
||||
if (i < password->Length)
|
||||
password->Text[i] += keyPool[i];
|
||||
else
|
||||
password->Text[i] = keyPool[i];
|
||||
}
|
||||
|
||||
if (password->Length < (int)sizeof (keyPool))
|
||||
password->Length = sizeof (keyPool);
|
||||
|
||||
burn (keyPool, sizeof (keyPool));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static void LoadKeyList (HWND hwndDlg, KeyFile *firstKeyFile)
|
||||
{
|
||||
KeyFile *kf;
|
||||
LVITEM LvItem;
|
||||
int line = 0;
|
||||
HWND hList = GetDlgItem (hwndDlg, IDC_KEYLIST);
|
||||
|
||||
ListView_DeleteAllItems (hList);
|
||||
EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVE), FALSE);
|
||||
EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVEALL), firstKeyFile != NULL);
|
||||
SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, firstKeyFile != NULL);
|
||||
|
||||
for (kf = firstKeyFile; kf != NULL; kf = kf->Next)
|
||||
{
|
||||
memset (&LvItem,0,sizeof(LvItem));
|
||||
LvItem.mask = LVIF_TEXT|LVIF_PARAM;
|
||||
LvItem.iItem = line++;
|
||||
LvItem.iSubItem = 0;
|
||||
LvItem.pszText = kf->FileName;
|
||||
LvItem.lParam = (LPARAM) kf;
|
||||
SendMessage (hList, LVM_INSERTITEM, 0, (LPARAM)&LvItem);
|
||||
}
|
||||
}
|
||||
|
||||
#if KEYFILE_POOL_SIZE % 4 != 0
|
||||
#error KEYFILE_POOL_SIZE must be a multiple of 4
|
||||
#endif
|
||||
|
||||
BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static KeyFilesDlgParam *param;
|
||||
static KeyFilesDlgParam origParam;
|
||||
|
||||
WORD lw = LOWORD (wParam);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
LVCOLUMNW LvCol;
|
||||
HWND hList = GetDlgItem (hwndDlg, IDC_KEYLIST);
|
||||
|
||||
param = (KeyFilesDlgParam *) lParam;
|
||||
origParam = *(KeyFilesDlgParam *) lParam;
|
||||
|
||||
param->FirstKeyFile = KeyFileCloneAll (param->FirstKeyFile);
|
||||
|
||||
LocalizeDialog (hwndDlg, "IDD_KEYFILES");
|
||||
DragAcceptFiles (hwndDlg, TRUE);
|
||||
|
||||
SendMessageW (hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,
|
||||
LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP
|
||||
);
|
||||
|
||||
memset (&LvCol,0,sizeof(LvCol));
|
||||
LvCol.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM|LVCF_FMT;
|
||||
LvCol.pszText = GetString ("KEYFILE");
|
||||
LvCol.cx = CompensateXDPI (374);
|
||||
LvCol.fmt = LVCFMT_LEFT;
|
||||
SendMessageW (hList, LVM_INSERTCOLUMNW, 0, (LPARAM)&LvCol);
|
||||
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, param->EnableKeyFiles);
|
||||
|
||||
SetWindowTextW(GetDlgItem(hwndDlg, IDT_KEYFILES_NOTE), GetString ("KEYFILES_NOTE"));
|
||||
|
||||
ToHyperlink (hwndDlg, IDC_LINK_KEYFILES_INFO);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case WM_COMMAND:
|
||||
|
||||
if (lw == IDC_KEYADD)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, bHistory))
|
||||
{
|
||||
do
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
|
||||
kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
} while (SelectMultipleFilesNext (kf->FileName));
|
||||
}
|
||||
|
||||
free (kf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_ADD_KEYFILE_PATH)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
|
||||
if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
free (kf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_TOKEN_FILES_ADD)
|
||||
{
|
||||
list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
|
||||
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
|
||||
{
|
||||
foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
strcpy_s (kf->FileName, sizeof (kf->FileName), WideToSingleString (keyPath).c_str());
|
||||
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_KEYREMOVE)
|
||||
{
|
||||
HWND list = GetDlgItem (hwndDlg, IDC_KEYLIST);
|
||||
LVITEM LvItem;
|
||||
memset (&LvItem, 0, sizeof(LvItem));
|
||||
LvItem.mask = LVIF_PARAM;
|
||||
LvItem.iItem = -1;
|
||||
|
||||
while (-1 != (LvItem.iItem = ListView_GetNextItem (list, LvItem.iItem, LVIS_SELECTED)))
|
||||
{
|
||||
ListView_GetItem (list, &LvItem);
|
||||
param->FirstKeyFile = KeyFileRemove (param->FirstKeyFile, (KeyFile *) LvItem.lParam);
|
||||
}
|
||||
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_KEYREMOVEALL)
|
||||
{
|
||||
KeyFileRemoveAll (¶m->FirstKeyFile);
|
||||
LoadKeyList (hwndDlg, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_GENERATE_KEYFILE)
|
||||
{
|
||||
DialogBoxParamW (hInst,
|
||||
MAKEINTRESOURCEW (IDD_KEYFILE_GENERATOR), hwndDlg,
|
||||
(DLGPROC) KeyfileGeneratorDlgProc, (LPARAM) 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_LINK_KEYFILES_INFO)
|
||||
{
|
||||
Applink ("keyfiles", TRUE, "");
|
||||
}
|
||||
|
||||
if (lw == IDOK)
|
||||
{
|
||||
param->EnableKeyFiles = IsButtonChecked (GetDlgItem (hwndDlg, IDC_KEYFILES_ENABLE));
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDCANCEL)
|
||||
{
|
||||
KeyFileRemoveAll (¶m->FirstKeyFile);
|
||||
*param = origParam;
|
||||
|
||||
EndDialog (hwndDlg, IDCLOSE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_DROPFILES:
|
||||
{
|
||||
HDROP hdrop = (HDROP) wParam;
|
||||
|
||||
int i = 0, count = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
|
||||
|
||||
while (count-- > 0)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
DragQueryFile (hdrop, i++, kf->FileName, sizeof (kf->FileName));
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
LoadKeyList (hwndDlg, param->FirstKeyFile);
|
||||
}
|
||||
|
||||
DragFinish (hdrop);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case WM_NOTIFY:
|
||||
if (((LPNMHDR) lParam)->code == LVN_ITEMCHANGED)
|
||||
{
|
||||
EnableWindow (GetDlgItem (hwndDlg, IDC_KEYREMOVE),
|
||||
ListView_GetNextItem (GetDlgItem (hwndDlg, IDC_KEYLIST), -1, LVIS_SELECTED) != -1);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
KeyFileRemoveAll (¶m->FirstKeyFile);
|
||||
*param = origParam;
|
||||
|
||||
EndDialog (hwndDlg, IDCLOSE);
|
||||
return 1;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define IDM_KEYFILES_POPUP_ADD_FILES 9001
|
||||
#define IDM_KEYFILES_POPUP_ADD_DIR 9002
|
||||
#define IDM_KEYFILES_POPUP_ADD_TOKEN_FILES 9003
|
||||
|
||||
BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *param)
|
||||
{
|
||||
HMENU popup = CreatePopupMenu ();
|
||||
int sel;
|
||||
BOOL status = FALSE;
|
||||
|
||||
AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_FILES, GetString ("IDC_KEYADD"));
|
||||
AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_DIR, GetString ("IDC_ADD_KEYFILE_PATH"));
|
||||
AppendMenuW (popup, MF_STRING, IDM_KEYFILES_POPUP_ADD_TOKEN_FILES, GetString ("IDC_TOKEN_FILES_ADD"));
|
||||
|
||||
sel = TrackPopupMenu (popup, TPM_RETURNCMD | TPM_LEFTBUTTON, popupPosition.x, popupPosition.y, 0, hwndDlg, NULL);
|
||||
|
||||
switch (sel)
|
||||
{
|
||||
case IDM_KEYFILES_POPUP_ADD_FILES:
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
if (SelectMultipleFiles (hwndDlg, "SELECT_KEYFILE", kf->FileName, bHistory))
|
||||
{
|
||||
do
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
} while (SelectMultipleFilesNext (kf->FileName));
|
||||
|
||||
param->EnableKeyFiles = TRUE;
|
||||
status = TRUE;
|
||||
}
|
||||
|
||||
free (kf);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_KEYFILES_POPUP_ADD_DIR:
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
|
||||
if (BrowseDirectories (hwndDlg,"SELECT_KEYFILE_PATH", kf->FileName))
|
||||
{
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
param->EnableKeyFiles = TRUE;
|
||||
status = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (kf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IDM_KEYFILES_POPUP_ADD_TOKEN_FILES:
|
||||
{
|
||||
list <SecurityTokenKeyfilePath> selectedTokenKeyfiles;
|
||||
if (DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_TOKEN_KEYFILES), hwndDlg, (DLGPROC) SecurityTokenKeyfileDlgProc, (LPARAM) &selectedTokenKeyfiles) == IDOK)
|
||||
{
|
||||
foreach (const SecurityTokenKeyfilePath &keyPath, selectedTokenKeyfiles)
|
||||
{
|
||||
KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
|
||||
strcpy_s (kf->FileName, sizeof (kf->FileName), WideToSingleString (keyPath).c_str());
|
||||
|
||||
param->FirstKeyFile = KeyFileAdd (param->FirstKeyFile, kf);
|
||||
param->EnableKeyFiles = TRUE;
|
||||
status = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DestroyMenu (popup);
|
||||
return status;
|
||||
}
|
||||
48
src/Common/Keyfiles.h
Normal file
48
src/Common/Keyfiles.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (c) 2005 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef KEYFILES_H
|
||||
#define KEYFILES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#define KEYFILE_POOL_SIZE 64
|
||||
#define KEYFILE_MAX_READ_LEN (1024*1024)
|
||||
|
||||
typedef struct KeyFileStruct
|
||||
{
|
||||
char FileName[MAX_PATH];
|
||||
struct KeyFileStruct *Next;
|
||||
} KeyFile;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL EnableKeyFiles;
|
||||
KeyFile *FirstKeyFile;
|
||||
} KeyFilesDlgParam;
|
||||
|
||||
KeyFile *KeyFileAdd (KeyFile *firstKeyFile, KeyFile *keyFile);
|
||||
void KeyFileRemoveAll (KeyFile **firstKeyFile);
|
||||
KeyFile *KeyFileClone (KeyFile *keyFile);
|
||||
KeyFile *KeyFileCloneAll (KeyFile *firstKeyFile);
|
||||
BOOL KeyFilesApply (Password *password, KeyFile *firstKeyFile);
|
||||
|
||||
BOOL CALLBACK KeyFilesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
BOOL KeyfilesPopupMenu (HWND hwndDlg, POINT popupPosition, KeyFilesDlgParam *dialogParam);
|
||||
|
||||
extern BOOL HiddenFilesPresentInKeyfilePath;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef KEYFILES_H */
|
||||
515
src/Common/Language.c
Normal file
515
src/Common/Language.c
Normal file
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
Copyright (c) 2005-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Language.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Dictionary.h"
|
||||
#include "Tcdefs.h"
|
||||
#include "Xml.h"
|
||||
|
||||
#include "../Common/Resource.h"
|
||||
|
||||
#ifdef TCMOUNT
|
||||
#include "../Mount/Resource.h"
|
||||
#endif
|
||||
|
||||
#ifdef VOLFORMAT
|
||||
#include "../Format/Resource.h"
|
||||
#endif
|
||||
|
||||
#ifdef SETUP
|
||||
#include "../Setup/Resource.h"
|
||||
#endif
|
||||
|
||||
BOOL LocalizationActive;
|
||||
int LocalizationSerialNo;
|
||||
|
||||
wchar_t UnknownString[1024];
|
||||
static char *LanguageFileBuffer;
|
||||
static HANDLE LanguageFileFindHandle = INVALID_HANDLE_VALUE;
|
||||
static char PreferredLangId[6];
|
||||
static char *LanguageResource;
|
||||
static char *HeaderResource[2];
|
||||
static char ActiveLangPackVersion[6];
|
||||
|
||||
static char *MapFirstLanguageFile ()
|
||||
{
|
||||
if (LanguageFileFindHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FindClose (LanguageFileFindHandle);
|
||||
LanguageFileFindHandle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (LanguageResource == NULL)
|
||||
{
|
||||
DWORD size;
|
||||
LanguageResource = MapResource ("Xml", IDR_LANGUAGE, &size);
|
||||
LanguageResource[size - 1] = 0;
|
||||
}
|
||||
|
||||
return LanguageResource;
|
||||
}
|
||||
|
||||
|
||||
static char *MapNextLanguageFile ()
|
||||
{
|
||||
wchar_t f[TC_MAX_PATH*2], *t;
|
||||
WIN32_FIND_DATAW find;
|
||||
HANDLE file;
|
||||
DWORD read;
|
||||
|
||||
if (LanguageFileFindHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
GetModuleFileNameW (NULL, f, sizeof (f) / sizeof (f[0]));
|
||||
t = wcsrchr (f, L'\\');
|
||||
if (t == NULL) return NULL;
|
||||
|
||||
wcscpy (t, L"\\Language*.xml");
|
||||
|
||||
LanguageFileFindHandle = FindFirstFileW (f, &find);
|
||||
}
|
||||
else if (!FindNextFileW (LanguageFileFindHandle, &find))
|
||||
{
|
||||
FindClose (LanguageFileFindHandle);
|
||||
LanguageFileFindHandle = INVALID_HANDLE_VALUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (find.nFileSizeHigh != 0) return NULL;
|
||||
|
||||
if (LanguageFileBuffer != NULL) free (LanguageFileBuffer);
|
||||
LanguageFileBuffer = malloc(find.nFileSizeLow);
|
||||
if (LanguageFileBuffer == NULL) return NULL;
|
||||
|
||||
GetModuleFileNameW (NULL, f, sizeof (f) / sizeof(f[0]));
|
||||
t = wcsrchr (f, L'\\');
|
||||
wcscpy (t + 1, find.cFileName);
|
||||
|
||||
file = CreateFileW (f, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (file == INVALID_HANDLE_VALUE) return NULL;
|
||||
|
||||
ReadFile (file, LanguageFileBuffer, find.nFileSizeLow, &read, NULL);
|
||||
CloseHandle (file);
|
||||
if (read != find.nFileSizeLow) return NULL;
|
||||
|
||||
return LanguageFileBuffer;
|
||||
}
|
||||
|
||||
|
||||
BOOL LoadLanguageFile ()
|
||||
{
|
||||
DWORD size;
|
||||
BYTE *res;
|
||||
char *xml, *header;
|
||||
char langId[6] = "en", attr[32768], key[128];
|
||||
BOOL defaultLangParsed = FALSE, langFound = FALSE;
|
||||
WCHAR wattr[32768];
|
||||
int i, intKey, len;
|
||||
|
||||
char *xmlElements[] = {"control", "string", 0};
|
||||
|
||||
#ifdef TCMOUNT
|
||||
int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_MOUNT_RSRC_HEADER, 0 };
|
||||
#endif
|
||||
|
||||
#ifdef VOLFORMAT
|
||||
int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_FORMAT_RSRC_HEADER, 0 };
|
||||
#endif
|
||||
|
||||
#ifdef SETUP
|
||||
int headers[] = { IDR_COMMON_RSRC_HEADER, IDR_SETUP_RSRC_HEADER, 0 };
|
||||
#endif
|
||||
|
||||
LocalizationActive = FALSE;
|
||||
ActiveLangPackVersion[0] = 0;
|
||||
ClearDictionaryPool ();
|
||||
|
||||
if (PreferredLangId[0] != 0)
|
||||
strcpy (langId, PreferredLangId);
|
||||
|
||||
// Parse all available language files until preferred language is found
|
||||
for (res = MapFirstLanguageFile (); res != NULL; res = MapNextLanguageFile ())
|
||||
{
|
||||
xml = (char *) res;
|
||||
xml = XmlFindElement (xml, "localization");
|
||||
if (!xml)
|
||||
continue;
|
||||
|
||||
// Required TrueCrypt version
|
||||
XmlGetAttributeText (xml, "prog-version", attr, sizeof (attr));
|
||||
|
||||
// Check version of external language file
|
||||
if (defaultLangParsed && strcmp (attr, VERSION_STRING) && strcmp (attr, "DEBUG"))
|
||||
{
|
||||
wchar_t m[2048];
|
||||
swprintf (m, L"The installed language pack is incompatible with this version of TrueCrypt (the language pack is for TrueCrypt %hs). A newer version may be available at www.truecrypt.org.\n\nTo prevent this message from being displayed, do any of the following:\n\n- Select 'Settings' > 'Language'; then select 'English' and click 'OK'.\n\n- Remove or replace the language pack with a compatible version (the language pack may reside e.g. in 'C:\\Program Files\\TrueCrypt' or '%%LOCALAPPDATA%%\\VirtualStore\\Program Files\\TrueCrypt', etc.)", attr);
|
||||
MessageBoxW (NULL, m, L"TrueCrypt", MB_ICONERROR);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Search language id in language file
|
||||
if (defaultLangParsed)
|
||||
{
|
||||
while (xml = XmlFindElement (xml, "language"))
|
||||
{
|
||||
XmlGetAttributeText (xml, "langid", attr, sizeof (attr));
|
||||
if (strcmp (attr, langId) == 0)
|
||||
{
|
||||
XmlGetAttributeText (xml++, "version", ActiveLangPackVersion, sizeof (ActiveLangPackVersion));
|
||||
langFound = TRUE;
|
||||
break;
|
||||
}
|
||||
xml++;
|
||||
}
|
||||
|
||||
if (!langFound) continue;
|
||||
}
|
||||
|
||||
// Create font dictionary
|
||||
xml = (char *) res;
|
||||
while (xml = XmlFindElement (xml, "font"))
|
||||
{
|
||||
XmlGetAttributeText (xml, "lang", attr, sizeof (attr));
|
||||
if (!defaultLangParsed
|
||||
|| strcmp (attr, langId) == 0)
|
||||
{
|
||||
Font font;
|
||||
memset (&font, 0, sizeof (font));
|
||||
|
||||
XmlGetAttributeText (xml, "face", attr, sizeof (attr));
|
||||
|
||||
len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
|
||||
font.FaceName = AddPoolData ((void *) wattr, len * 2);
|
||||
|
||||
XmlGetAttributeText (xml, "size", attr, sizeof (attr));
|
||||
sscanf (attr, "%d", &font.Size);
|
||||
|
||||
strcpy (attr, "font_");
|
||||
XmlGetAttributeText (xml, "class", attr + 5, sizeof (attr) - 5);
|
||||
AddDictionaryEntry (
|
||||
AddPoolData ((void *) attr, strlen (attr) + 1), 0,
|
||||
AddPoolData ((void *) &font, sizeof(font)));
|
||||
}
|
||||
|
||||
xml++;
|
||||
}
|
||||
|
||||
// Create string and control dictionaries
|
||||
for (i = 0; xmlElements[i] != 0; i++)
|
||||
{
|
||||
xml = (char *) res;
|
||||
while (xml = XmlFindElement (xml, xmlElements[i]))
|
||||
{
|
||||
void *key;
|
||||
void *text;
|
||||
|
||||
XmlGetAttributeText (xml, "lang", attr, sizeof (attr));
|
||||
if (!defaultLangParsed
|
||||
|| strcmp (attr, langId) == 0)
|
||||
{
|
||||
if (XmlGetAttributeText (xml, "key", attr, sizeof (attr)))
|
||||
{
|
||||
key = AddPoolData (attr, strlen (attr) + 1);
|
||||
if (key == NULL) return FALSE;
|
||||
|
||||
XmlGetNodeText (xml, attr, sizeof (attr));
|
||||
|
||||
// Parse \ escape sequences
|
||||
{
|
||||
char *in = attr, *out = attr;
|
||||
while (*in)
|
||||
{
|
||||
if (*in == '\\')
|
||||
{
|
||||
in++;
|
||||
switch (*in++)
|
||||
{
|
||||
case '\\': *out++ = '\\'; break;
|
||||
case 't': *out++ = '\t'; break;
|
||||
case 'n': *out++ = 13; *out++ = 10; break;
|
||||
default:
|
||||
MessageBox (0, key, "TrueCrypt: Unknown '\\' escape sequence in string", MB_ICONERROR);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
*out++ = *in++;
|
||||
}
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
// UTF8 => wide char
|
||||
len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
|
||||
if (len == 0 || len == ERROR_NO_UNICODE_TRANSLATION)
|
||||
{
|
||||
MessageBox (0, key, "TrueCrypt: Error while decoding UTF-8 string", MB_ICONERROR);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Add to dictionary
|
||||
text = AddPoolData ((void *) wattr, len * 2);
|
||||
if (text == NULL) return FALSE;
|
||||
|
||||
AddDictionaryEntry ((char *) key, 0, text);
|
||||
}
|
||||
}
|
||||
|
||||
xml++;
|
||||
}
|
||||
}
|
||||
|
||||
if (langFound)
|
||||
break;
|
||||
|
||||
if (!defaultLangParsed)
|
||||
{
|
||||
defaultLangParsed = TRUE;
|
||||
if (langId[0] == 0 || strcmp (langId, "en") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LocalizationActive = langFound && strcmp (langId, "en") != 0;
|
||||
LocalizationSerialNo++;
|
||||
|
||||
// Create control ID dictionary
|
||||
|
||||
// Default controls
|
||||
AddDictionaryEntry (NULL, 1, GetString ("IDOK"));
|
||||
AddDictionaryEntry (NULL, 2, GetString ("IDCANCEL"));
|
||||
AddDictionaryEntry (NULL, 8, GetString ("IDCLOSE"));
|
||||
AddDictionaryEntry (NULL, 9, GetString ("IDHELP"));
|
||||
|
||||
for (i = 0; headers[i] != 0; i++)
|
||||
{
|
||||
if (HeaderResource[i] == NULL)
|
||||
{
|
||||
HeaderResource[i] = MapResource ("Header", headers[i], &size);
|
||||
*(HeaderResource[i] + size - 1) = 0;
|
||||
}
|
||||
|
||||
header = HeaderResource[i];
|
||||
if (header == NULL) return FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
if (sscanf (header, "#define %s %d", key, &intKey) == 2)
|
||||
{
|
||||
WCHAR *str = GetString (key);
|
||||
|
||||
if (str != UnknownString)
|
||||
AddDictionaryEntry (NULL, intKey, str);
|
||||
}
|
||||
|
||||
} while ((header = strchr (header, '\n') + 1) != (char *) 1);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// lParam = 1: auto mode
|
||||
BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WORD lw = LOWORD (wParam);
|
||||
WORD hw = HIWORD (wParam);
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
char *xml;
|
||||
char attr[2048], lastLangId[10];
|
||||
WCHAR wattr[2048];
|
||||
int len;
|
||||
int langCount = 0;
|
||||
BOOL defaultLangFound = FALSE;
|
||||
|
||||
LocalizeDialog (hwndDlg, "IDD_LANGUAGE");
|
||||
ToHyperlink (hwndDlg, IDC_GET_LANG_PACKS);
|
||||
|
||||
for (xml = MapFirstLanguageFile (); xml != NULL; xml = MapNextLanguageFile ())
|
||||
{
|
||||
while (xml = XmlFindElement (xml, "language"))
|
||||
{
|
||||
XmlGetAttributeText (xml, "name", attr, sizeof (attr));
|
||||
len = MultiByteToWideChar (CP_UTF8, 0, attr, -1, wattr, sizeof (wattr) / sizeof(wattr[0]));
|
||||
|
||||
if (len != 0 && len != ERROR_NO_UNICODE_TRANSLATION
|
||||
&& (!defaultLangFound || wcscmp (wattr, L"English") != 0))
|
||||
{
|
||||
int i = SendDlgItemMessageW (hwndDlg, IDC_LANGLIST, LB_ADDSTRING, 0, (LPARAM)wattr);
|
||||
if (i >= 0)
|
||||
{
|
||||
int id;
|
||||
|
||||
// Encode language id in LPARAM
|
||||
XmlGetAttributeText (xml, "langid", attr, sizeof (attr));
|
||||
switch (strlen (attr))
|
||||
{
|
||||
case 2: id = attr[0] | attr[1] << 8; break;
|
||||
case 5: id = attr[0] | attr[1] << 8 | attr[3] << 16 | attr[4] << 24; break;
|
||||
default: continue;
|
||||
}
|
||||
|
||||
if (!defaultLangFound)
|
||||
defaultLangFound = TRUE;
|
||||
|
||||
SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETITEMDATA, i, (LPARAM) id);
|
||||
|
||||
if (strcmp (attr, PreferredLangId) == 0)
|
||||
{
|
||||
char credits [10000];
|
||||
WCHAR wcredits [10000];
|
||||
WCHAR wversion [20];
|
||||
wchar_t szVers [200];
|
||||
int nLen;
|
||||
|
||||
SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_SETCURSEL, i, 0);
|
||||
|
||||
// Language pack version
|
||||
if (!ActiveLangPackVersion[0] || memcmp (ActiveLangPackVersion, "0.0.0", 5) == 0)
|
||||
{
|
||||
swprintf (szVers, GetString("LANG_PACK_VERSION"), L"--");
|
||||
}
|
||||
else
|
||||
{
|
||||
nLen = MultiByteToWideChar (CP_UTF8, 0, ActiveLangPackVersion, -1, wversion, sizeof (wversion) / sizeof(wversion[0]));
|
||||
if (nLen != 0 && nLen != ERROR_NO_UNICODE_TRANSLATION)
|
||||
swprintf (szVers, GetString("LANG_PACK_VERSION"), wversion);
|
||||
}
|
||||
SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_VERSION), szVers);
|
||||
|
||||
// Translator credits
|
||||
XmlGetAttributeText (xml, "translators", credits, sizeof (credits));
|
||||
nLen = MultiByteToWideChar (CP_UTF8, 0, credits, -1, wcredits, sizeof (wcredits) / sizeof(wcredits[0]));
|
||||
if (nLen != 0 && nLen != ERROR_NO_UNICODE_TRANSLATION)
|
||||
{
|
||||
SetWindowTextW (GetDlgItem (hwndDlg, IDC_LANGPACK_CREDITS), wcredits);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy (lastLangId, attr);
|
||||
langCount++;
|
||||
}
|
||||
}
|
||||
|
||||
xml++;
|
||||
}
|
||||
}
|
||||
|
||||
if (lParam == 1)
|
||||
{
|
||||
// Auto mode
|
||||
if (langCount < 2)
|
||||
EndDialog (hwndDlg, IDCANCEL);
|
||||
|
||||
if (langCount == 2)
|
||||
strcpy (PreferredLangId, lastLangId);
|
||||
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
|
||||
if (lw == IDOK || hw == LBN_DBLCLK)
|
||||
{
|
||||
int i = SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCURSEL, 0, 0);
|
||||
|
||||
if (i >= 0)
|
||||
{
|
||||
int id = SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETITEMDATA, i, 0);
|
||||
|
||||
if (id != LB_ERR)
|
||||
{
|
||||
char l[6];
|
||||
|
||||
// Decode language id from LPARAM
|
||||
l[0] = (char) id;
|
||||
l[1] = (char) (id >> 8);
|
||||
l[2] = 0;
|
||||
|
||||
if ((id & 0xffff0000) != 0)
|
||||
{
|
||||
l[2] = '-';
|
||||
l[3] = (char) (id >> 16);
|
||||
l[4] = id >> 24;
|
||||
l[5] = 0;
|
||||
}
|
||||
|
||||
if (SendDlgItemMessage (hwndDlg, IDC_LANGLIST, LB_GETCOUNT, 0, 0) > 1)
|
||||
strcpy (PreferredLangId, l);
|
||||
}
|
||||
}
|
||||
|
||||
EndDialog (hwndDlg, IDOK);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDCANCEL)
|
||||
{
|
||||
EndDialog (hwndDlg, lw);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lw == IDC_GET_LANG_PACKS)
|
||||
{
|
||||
char tmpstr [256];
|
||||
|
||||
if (strlen (ActiveLangPackVersion) > 0 && strlen (GetPreferredLangId()) > 0)
|
||||
sprintf (tmpstr, "&langpackversion=%s&lang=%s", ActiveLangPackVersion, GetPreferredLangId());
|
||||
else
|
||||
tmpstr[0] = 0;
|
||||
|
||||
Applink ("localizations", TRUE, tmpstr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *GetPreferredLangId ()
|
||||
{
|
||||
return PreferredLangId;
|
||||
}
|
||||
|
||||
|
||||
void SetPreferredLangId (char *langId)
|
||||
{
|
||||
strncpy (PreferredLangId, langId, 5);
|
||||
}
|
||||
|
||||
|
||||
char *GetActiveLangPackVersion ()
|
||||
{
|
||||
return ActiveLangPackVersion;
|
||||
}
|
||||
|
||||
|
||||
wchar_t *GetString (const char *stringId)
|
||||
{
|
||||
WCHAR *str = (WCHAR *) GetDictionaryValue (stringId);
|
||||
if (str != NULL) return str;
|
||||
|
||||
wsprintfW (UnknownString, UNKNOWN_STRING_ID L"%hs" UNKNOWN_STRING_ID, stringId);
|
||||
return UnknownString;
|
||||
}
|
||||
|
||||
|
||||
Font *GetFont (char *fontType)
|
||||
{
|
||||
return (Font *) GetDictionaryValue (fontType);
|
||||
|
||||
}
|
||||
37
src/Common/Language.h
Normal file
37
src/Common/Language.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UNKNOWN_STRING_ID L"[?]"
|
||||
|
||||
extern BOOL LocalizationActive;
|
||||
extern int LocalizationSerialNo;
|
||||
extern wchar_t UnknownString[1024];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
wchar_t *FaceName;
|
||||
int Size;
|
||||
} Font;
|
||||
|
||||
BOOL CALLBACK LanguageDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
wchar_t *GetString (const char *stringId);
|
||||
Font *GetFont (char *fontType);
|
||||
BOOL LoadLanguageFile ();
|
||||
char *GetPreferredLangId ();
|
||||
void SetPreferredLangId (char *langId);
|
||||
char *GetActiveLangPackVersion ();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1341
src/Common/Language.xml
Normal file
1341
src/Common/Language.xml
Normal file
File diff suppressed because it is too large
Load Diff
1
src/Common/Makefile
Normal file
1
src/Common/Makefile
Normal file
@@ -0,0 +1 @@
|
||||
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||
422
src/Common/Password.c
Normal file
422
src/Common/Password.c
Normal file
@@ -0,0 +1,422 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include "Crypto.h"
|
||||
#include "Volumes.h"
|
||||
#include "Password.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Language.h"
|
||||
#include "Pkcs5.h"
|
||||
#include "Endian.h"
|
||||
#include "Random.h"
|
||||
|
||||
#include <io.h>
|
||||
|
||||
void VerifyPasswordAndUpdate (HWND hwndDlg, HWND hButton, HWND hPassword,
|
||||
HWND hVerify, unsigned char *szPassword,
|
||||
char *szVerify,
|
||||
BOOL keyFilesEnabled)
|
||||
{
|
||||
char szTmp1[MAX_PASSWORD + 1];
|
||||
char szTmp2[MAX_PASSWORD + 1];
|
||||
int k = GetWindowTextLength (hPassword);
|
||||
BOOL bEnable = FALSE;
|
||||
|
||||
if (hwndDlg); /* Remove warning */
|
||||
|
||||
GetWindowText (hPassword, szTmp1, sizeof (szTmp1));
|
||||
GetWindowText (hVerify, szTmp2, sizeof (szTmp2));
|
||||
|
||||
if (strcmp (szTmp1, szTmp2) != 0)
|
||||
bEnable = FALSE;
|
||||
else
|
||||
{
|
||||
if (k >= MIN_PASSWORD || keyFilesEnabled)
|
||||
bEnable = TRUE;
|
||||
else
|
||||
bEnable = FALSE;
|
||||
}
|
||||
|
||||
if (szPassword != NULL)
|
||||
memcpy (szPassword, szTmp1, sizeof (szTmp1));
|
||||
|
||||
if (szVerify != NULL)
|
||||
memcpy (szVerify, szTmp2, sizeof (szTmp2));
|
||||
|
||||
burn (szTmp1, sizeof (szTmp1));
|
||||
burn (szTmp2, sizeof (szTmp2));
|
||||
|
||||
EnableWindow (hButton, bEnable);
|
||||
}
|
||||
|
||||
|
||||
BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
if (hPassword == NULL)
|
||||
{
|
||||
unsigned char *pw;
|
||||
len = ptrPw->Length;
|
||||
pw = (unsigned char *) ptrPw->Text;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (pw[i] >= 0x7f || pw[i] < 0x20) // A non-ASCII or non-printable character?
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t s[MAX_PASSWORD + 1];
|
||||
len = GetWindowTextLength (hPassword);
|
||||
|
||||
if (len > MAX_PASSWORD)
|
||||
return FALSE;
|
||||
|
||||
GetWindowTextW (hPassword, s, sizeof (s) / sizeof (wchar_t));
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
if (s[i] >= 0x7f || s[i] < 0x20) // A non-ASCII or non-printable character?
|
||||
break;
|
||||
}
|
||||
|
||||
burn (s, sizeof(s));
|
||||
|
||||
if (i < len)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CheckPasswordLength (HWND hwndDlg, HWND hwndItem)
|
||||
{
|
||||
if (GetWindowTextLength (hwndItem) < PASSWORD_LEN_WARNING)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
if (MessageBoxW (hwndDlg, GetString ("PASSWORD_LENGTH_WARNING"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2) != IDYES)
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int ChangePwd (char *lpszVolume, Password *oldPassword, Password *newPassword, int pkcs5, HWND hwndDlg)
|
||||
{
|
||||
int nDosLinkCreated = 1, nStatus = ERR_OS_ERROR;
|
||||
char szDiskFile[TC_MAX_PATH], szCFDevice[TC_MAX_PATH];
|
||||
char szDosDevice[TC_MAX_PATH];
|
||||
char buffer[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
|
||||
PCRYPTO_INFO cryptoInfo = NULL, ci = NULL;
|
||||
void *dev = INVALID_HANDLE_VALUE;
|
||||
DWORD dwError;
|
||||
DWORD bytesRead;
|
||||
BOOL bDevice;
|
||||
unsigned __int64 hostSize = 0;
|
||||
int volumeType;
|
||||
int wipePass;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
BOOL bTimeStampValid = FALSE;
|
||||
LARGE_INTEGER headerOffset;
|
||||
BOOL backupHeader;
|
||||
DISK_GEOMETRY driveInfo;
|
||||
|
||||
if (oldPassword->Length == 0 || newPassword->Length == 0) return -1;
|
||||
|
||||
WaitCursor ();
|
||||
|
||||
CreateFullVolumePath (szDiskFile, lpszVolume, &bDevice);
|
||||
|
||||
if (bDevice == FALSE)
|
||||
{
|
||||
strcpy (szCFDevice, szDiskFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, szCFDevice, FALSE);
|
||||
|
||||
if (nDosLinkCreated != 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
dev = CreateFile (szCFDevice, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (dev == INVALID_HANDLE_VALUE)
|
||||
goto error;
|
||||
|
||||
if (bDevice)
|
||||
{
|
||||
/* This is necessary to determine the hidden volume header offset */
|
||||
|
||||
if (dev == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
PARTITION_INFORMATION diskInfo;
|
||||
DWORD dwResult;
|
||||
BOOL bResult;
|
||||
|
||||
bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
|
||||
&driveInfo, sizeof (driveInfo), &dwResult, NULL);
|
||||
|
||||
if (!bResult)
|
||||
goto error;
|
||||
|
||||
bResult = GetPartitionInfo (lpszVolume, &diskInfo);
|
||||
|
||||
if (bResult)
|
||||
{
|
||||
hostSize = diskInfo.PartitionLength.QuadPart;
|
||||
}
|
||||
else
|
||||
{
|
||||
hostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector *
|
||||
driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder;
|
||||
}
|
||||
|
||||
if (hostSize == 0)
|
||||
{
|
||||
nStatus = ERR_VOL_SIZE_WRONG;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx (dev, &fileSize))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
hostSize = fileSize.QuadPart;
|
||||
}
|
||||
|
||||
if (Randinit ())
|
||||
goto error;
|
||||
|
||||
if (!bDevice && bPreserveTimestamp)
|
||||
{
|
||||
if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
|
||||
bTimeStampValid = FALSE;
|
||||
else
|
||||
bTimeStampValid = TRUE;
|
||||
}
|
||||
|
||||
for (volumeType = TC_VOLUME_TYPE_NORMAL; volumeType < TC_VOLUME_TYPE_COUNT; volumeType++)
|
||||
{
|
||||
// Seek the volume header
|
||||
switch (volumeType)
|
||||
{
|
||||
case TC_VOLUME_TYPE_NORMAL:
|
||||
headerOffset.QuadPart = TC_VOLUME_HEADER_OFFSET;
|
||||
break;
|
||||
|
||||
case TC_VOLUME_TYPE_HIDDEN:
|
||||
if (TC_HIDDEN_VOLUME_HEADER_OFFSET + TC_VOLUME_HEADER_SIZE > hostSize)
|
||||
continue;
|
||||
|
||||
headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET;
|
||||
break;
|
||||
|
||||
case TC_VOLUME_TYPE_HIDDEN_LEGACY:
|
||||
if (bDevice && driveInfo.BytesPerSector != TC_SECTOR_SIZE_LEGACY)
|
||||
continue;
|
||||
|
||||
headerOffset.QuadPart = hostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Read in volume header */
|
||||
if (!ReadEffectiveVolumeHeader (bDevice, dev, buffer, &bytesRead))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bytesRead != sizeof (buffer))
|
||||
{
|
||||
// Windows may report EOF when reading sectors from the last cluster of a device formatted as NTFS
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
}
|
||||
|
||||
/* Try to decrypt the header */
|
||||
|
||||
nStatus = ReadVolumeHeader (FALSE, buffer, oldPassword, &cryptoInfo, NULL);
|
||||
if (nStatus == ERR_CIPHER_INIT_WEAK_KEY)
|
||||
nStatus = 0; // We can ignore this error here
|
||||
|
||||
if (nStatus == ERR_PASSWORD_WRONG)
|
||||
{
|
||||
continue; // Try next volume type
|
||||
}
|
||||
else if (nStatus != 0)
|
||||
{
|
||||
cryptoInfo = NULL;
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (nStatus != 0)
|
||||
{
|
||||
cryptoInfo = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM)
|
||||
{
|
||||
nStatus = ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Change the PKCS-5 PRF if requested by user
|
||||
if (pkcs5 != 0)
|
||||
cryptoInfo->pkcs5 = pkcs5;
|
||||
|
||||
RandSetHashFunction (cryptoInfo->pkcs5);
|
||||
|
||||
NormalCursor();
|
||||
UserEnrichRandomPool (hwndDlg);
|
||||
EnableElevatedCursorChange (hwndDlg);
|
||||
WaitCursor();
|
||||
|
||||
/* Re-encrypt the volume header */
|
||||
backupHeader = FALSE;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
/* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using
|
||||
techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
|
||||
to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
|
||||
times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
|
||||
impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
|
||||
valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
|
||||
recommends. During each pass we will write a valid working header. Each pass will use the same master
|
||||
key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
|
||||
item that will be different for each pass will be the salt. This is sufficient to cause each "version"
|
||||
of the header to differ substantially and in a random manner from the versions written during the
|
||||
other passes. */
|
||||
|
||||
for (wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
|
||||
{
|
||||
// Prepare new volume header
|
||||
nStatus = CreateVolumeHeaderInMemory (FALSE,
|
||||
buffer,
|
||||
cryptoInfo->ea,
|
||||
cryptoInfo->mode,
|
||||
newPassword,
|
||||
cryptoInfo->pkcs5,
|
||||
cryptoInfo->master_keydata,
|
||||
&ci,
|
||||
cryptoInfo->VolumeSize.Value,
|
||||
(volumeType == TC_VOLUME_TYPE_HIDDEN || volumeType == TC_VOLUME_TYPE_HIDDEN_LEGACY) ? cryptoInfo->hiddenVolumeSize : 0,
|
||||
cryptoInfo->EncryptedAreaStart.Value,
|
||||
cryptoInfo->EncryptedAreaLength.Value,
|
||||
cryptoInfo->RequiredProgramVersion,
|
||||
cryptoInfo->HeaderFlags,
|
||||
cryptoInfo->SectorSize,
|
||||
wipePass < PRAND_DISK_WIPE_PASSES - 1);
|
||||
|
||||
if (ci != NULL)
|
||||
crypto_close (ci);
|
||||
|
||||
if (nStatus != 0)
|
||||
goto error;
|
||||
|
||||
if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!WriteEffectiveVolumeHeader (bDevice, dev, buffer))
|
||||
{
|
||||
nStatus = ERR_OS_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (bDevice
|
||||
&& !cryptoInfo->LegacyVolume
|
||||
&& !cryptoInfo->hiddenVolume
|
||||
&& cryptoInfo->HeaderVersion == 4
|
||||
&& (cryptoInfo->HeaderFlags & TC_HEADER_FLAG_NONSYS_INPLACE_ENC) != 0
|
||||
&& (cryptoInfo->HeaderFlags & ~TC_HEADER_FLAG_NONSYS_INPLACE_ENC) == 0)
|
||||
{
|
||||
nStatus = WriteRandomDataToReservedHeaderAreas (dev, cryptoInfo, cryptoInfo->VolumeSize.Value, !backupHeader, backupHeader);
|
||||
if (nStatus != ERR_SUCCESS)
|
||||
goto error;
|
||||
}
|
||||
|
||||
FlushFileBuffers (dev);
|
||||
}
|
||||
|
||||
if (backupHeader || cryptoInfo->LegacyVolume)
|
||||
break;
|
||||
|
||||
backupHeader = TRUE;
|
||||
headerOffset.QuadPart += hostSize - TC_VOLUME_HEADER_GROUP_SIZE;
|
||||
}
|
||||
|
||||
/* Password successfully changed */
|
||||
nStatus = 0;
|
||||
|
||||
error:
|
||||
dwError = GetLastError ();
|
||||
|
||||
burn (buffer, sizeof (buffer));
|
||||
|
||||
if (cryptoInfo != NULL)
|
||||
crypto_close (cryptoInfo);
|
||||
|
||||
if (bTimeStampValid)
|
||||
SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);
|
||||
|
||||
if (dev != INVALID_HANDLE_VALUE)
|
||||
CloseHandle ((HANDLE) dev);
|
||||
|
||||
if (nDosLinkCreated == 0)
|
||||
RemoveFakeDosName (szDiskFile, szDosDevice);
|
||||
|
||||
RandStop (FALSE);
|
||||
NormalCursor ();
|
||||
|
||||
SetLastError (dwError);
|
||||
|
||||
if (nStatus == ERR_OS_ERROR && dwError == ERROR_ACCESS_DENIED
|
||||
&& bDevice
|
||||
&& !UacElevated
|
||||
&& IsUacSupported ())
|
||||
return nStatus;
|
||||
|
||||
if (nStatus != 0)
|
||||
handleError (hwndDlg, nStatus);
|
||||
|
||||
return nStatus;
|
||||
}
|
||||
|
||||
46
src/Common/Password.h
Normal file
46
src/Common/Password.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef PASSWORD_H
|
||||
#define PASSWORD_H
|
||||
|
||||
// User text input limits
|
||||
#define MIN_PASSWORD 1 // Minimum possible password length
|
||||
#define MAX_PASSWORD 64 // Maximum possible password length
|
||||
|
||||
#define PASSWORD_LEN_WARNING 20 // Display a warning when a password is shorter than this
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Modifying this structure can introduce incompatibility with previous versions
|
||||
unsigned __int32 Length;
|
||||
unsigned char Text[MAX_PASSWORD + 1];
|
||||
char Pad[3]; // keep 64-bit alignment
|
||||
} Password;
|
||||
|
||||
#if defined(_WIN32) && !defined(TC_WINDOWS_DRIVER)
|
||||
|
||||
void VerifyPasswordAndUpdate ( HWND hwndDlg , HWND hButton , HWND hPassword , HWND hVerify , unsigned char *szPassword , char *szVerify, BOOL keyFilesEnabled );
|
||||
BOOL CheckPasswordLength (HWND hwndDlg, HWND hwndItem);
|
||||
BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw);
|
||||
int ChangePwd (char *lpszVolume, Password *oldPassword, Password *newPassword, int pkcs5, HWND hwndDlg);
|
||||
|
||||
#endif // defined(_WIN32) && !defined(TC_WINDOWS_DRIVER)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PASSWORD_H
|
||||
642
src/Common/Pkcs5.c
Normal file
642
src/Common/Pkcs5.c
Normal file
@@ -0,0 +1,642 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#include <memory.h>
|
||||
#include "Rmd160.h"
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
#include "Sha1.h"
|
||||
#include "Sha2.h"
|
||||
#include "Whirlpool.h"
|
||||
#endif
|
||||
#include "Pkcs5.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
void hmac_truncate
|
||||
(
|
||||
char *d1, /* data to be truncated */
|
||||
char *d2, /* truncated data */
|
||||
int len /* length in bytes to keep */
|
||||
)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
d2[i] = d1[i];
|
||||
}
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
|
||||
void hmac_sha512
|
||||
(
|
||||
char *k, /* secret key */
|
||||
int lk, /* length of the key in bytes */
|
||||
char *d, /* data */
|
||||
int ld, /* length of data in bytes */
|
||||
char *out, /* output buffer, at least "t" bytes */
|
||||
int t
|
||||
)
|
||||
{
|
||||
sha512_ctx ictx, octx;
|
||||
char isha[SHA512_DIGESTSIZE], osha[SHA512_DIGESTSIZE];
|
||||
char key[SHA512_DIGESTSIZE];
|
||||
char buf[SHA512_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = sha512(key), as per HMAC specifications. */
|
||||
if (lk > SHA512_BLOCKSIZE)
|
||||
{
|
||||
sha512_ctx tctx;
|
||||
|
||||
sha512_begin (&tctx);
|
||||
sha512_hash ((unsigned char *) k, lk, &tctx);
|
||||
sha512_end ((unsigned char *) key, &tctx);
|
||||
|
||||
k = key;
|
||||
lk = SHA512_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/**** Inner Digest ****/
|
||||
|
||||
sha512_begin (&ictx);
|
||||
|
||||
/* Pad the key for inner digest */
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x36);
|
||||
for (i = lk; i < SHA512_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x36;
|
||||
|
||||
sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &ictx);
|
||||
sha512_hash ((unsigned char *) d, ld, &ictx);
|
||||
|
||||
sha512_end ((unsigned char *) isha, &ictx);
|
||||
|
||||
/**** Outer Digest ****/
|
||||
|
||||
sha512_begin (&octx);
|
||||
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x5C);
|
||||
for (i = lk; i < SHA512_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x5C;
|
||||
|
||||
sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &octx);
|
||||
sha512_hash ((unsigned char *) isha, SHA512_DIGESTSIZE, &octx);
|
||||
|
||||
sha512_end ((unsigned char *) osha, &octx);
|
||||
|
||||
/* truncate and print the results */
|
||||
t = t > SHA512_DIGESTSIZE ? SHA512_DIGESTSIZE : t;
|
||||
hmac_truncate (osha, out, t);
|
||||
|
||||
/* Prevent leaks */
|
||||
burn (&ictx, sizeof(ictx));
|
||||
burn (&octx, sizeof(octx));
|
||||
burn (isha, sizeof(isha));
|
||||
burn (osha, sizeof(osha));
|
||||
burn (buf, sizeof(buf));
|
||||
burn (key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[SHA512_DIGESTSIZE], k[SHA512_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_sha512 (pwd, pwd_len, init, salt_len + 4, j, SHA512_DIGESTSIZE);
|
||||
memcpy (u, j, SHA512_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_sha512 (pwd, pwd_len, j, SHA512_DIGESTSIZE, k, SHA512_DIGESTSIZE);
|
||||
for (i = 0; i < SHA512_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
|
||||
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[SHA512_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % SHA512_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / SHA512_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / SHA512_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * SHA512_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, SHA512_DIGESTSIZE);
|
||||
dk += SHA512_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
|
||||
/* Deprecated/legacy */
|
||||
void hmac_sha1
|
||||
(
|
||||
char *k, /* secret key */
|
||||
int lk, /* length of the key in bytes */
|
||||
char *d, /* data */
|
||||
int ld, /* length of data in bytes */
|
||||
char *out, /* output buffer, at least "t" bytes */
|
||||
int t
|
||||
)
|
||||
{
|
||||
sha1_ctx ictx, octx;
|
||||
char isha[SHA1_DIGESTSIZE], osha[SHA1_DIGESTSIZE];
|
||||
char key[SHA1_DIGESTSIZE];
|
||||
char buf[SHA1_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = sha1(key), as per HMAC specifications. */
|
||||
if (lk > SHA1_BLOCKSIZE)
|
||||
{
|
||||
sha1_ctx tctx;
|
||||
|
||||
sha1_begin (&tctx);
|
||||
sha1_hash ((unsigned char *) k, lk, &tctx);
|
||||
sha1_end ((unsigned char *) key, &tctx);
|
||||
|
||||
k = key;
|
||||
lk = SHA1_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/**** Inner Digest ****/
|
||||
|
||||
sha1_begin (&ictx);
|
||||
|
||||
/* Pad the key for inner digest */
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x36);
|
||||
for (i = lk; i < SHA1_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x36;
|
||||
|
||||
sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &ictx);
|
||||
sha1_hash ((unsigned char *) d, ld, &ictx);
|
||||
|
||||
sha1_end ((unsigned char *) isha, &ictx);
|
||||
|
||||
/**** Outer Digest ****/
|
||||
|
||||
sha1_begin (&octx);
|
||||
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x5C);
|
||||
for (i = lk; i < SHA1_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x5C;
|
||||
|
||||
sha1_hash ((unsigned char *) buf, SHA1_BLOCKSIZE, &octx);
|
||||
sha1_hash ((unsigned char *) isha, SHA1_DIGESTSIZE, &octx);
|
||||
|
||||
sha1_end ((unsigned char *) osha, &octx);
|
||||
|
||||
/* truncate and print the results */
|
||||
t = t > SHA1_DIGESTSIZE ? SHA1_DIGESTSIZE : t;
|
||||
hmac_truncate (osha, out, t);
|
||||
|
||||
/* Prevent leaks */
|
||||
burn (&ictx, sizeof(ictx));
|
||||
burn (&octx, sizeof(octx));
|
||||
burn (isha, sizeof(isha));
|
||||
burn (osha, sizeof(osha));
|
||||
burn (buf, sizeof(buf));
|
||||
burn (key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
/* Deprecated/legacy */
|
||||
void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[SHA1_DIGESTSIZE], k[SHA1_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_sha1 (pwd, pwd_len, init, salt_len + 4, j, SHA1_DIGESTSIZE);
|
||||
memcpy (u, j, SHA1_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_sha1 (pwd, pwd_len, j, SHA1_DIGESTSIZE, k, SHA1_DIGESTSIZE);
|
||||
for (i = 0; i < SHA1_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
|
||||
/* Deprecated/legacy */
|
||||
void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[SHA1_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % SHA1_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / SHA1_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / SHA1_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * SHA1_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, SHA1_DIGESTSIZE);
|
||||
dk += SHA1_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_sha1 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
#endif // TC_WINDOWS_BOOT
|
||||
|
||||
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest)
|
||||
{
|
||||
RMD160_CTX context;
|
||||
unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
|
||||
unsigned char k_opad[65]; /* outer padding - key XORd with opad */
|
||||
unsigned char tk[RIPEMD160_DIGESTSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = ripemd160(key), as per HMAC specifications. */
|
||||
if (keylen > RIPEMD160_BLOCKSIZE)
|
||||
{
|
||||
RMD160_CTX tctx;
|
||||
|
||||
RMD160Init(&tctx);
|
||||
RMD160Update(&tctx, (const unsigned char *) key, keylen);
|
||||
RMD160Final(tk, &tctx);
|
||||
|
||||
key = (char *) tk;
|
||||
keylen = RIPEMD160_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
RMD160(K XOR opad, RMD160(K XOR ipad, text))
|
||||
|
||||
where K is an n byte key
|
||||
ipad is the byte 0x36 repeated RIPEMD160_BLOCKSIZE times
|
||||
opad is the byte 0x5c repeated RIPEMD160_BLOCKSIZE times
|
||||
and text is the data being protected */
|
||||
|
||||
|
||||
/* start out by storing key in pads */
|
||||
memset(k_ipad, 0x36, sizeof(k_ipad));
|
||||
memset(k_opad, 0x5c, sizeof(k_opad));
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i=0; i<keylen; i++)
|
||||
{
|
||||
k_ipad[i] ^= key[i];
|
||||
k_opad[i] ^= key[i];
|
||||
}
|
||||
|
||||
/* perform inner RIPEMD-160 */
|
||||
|
||||
RMD160Init(&context); /* init context for 1st pass */
|
||||
RMD160Update(&context, k_ipad, RIPEMD160_BLOCKSIZE); /* start with inner pad */
|
||||
RMD160Update(&context, (const unsigned char *) input, len); /* then text of datagram */
|
||||
RMD160Final((unsigned char *) digest, &context); /* finish up 1st pass */
|
||||
|
||||
/* perform outer RIPEMD-160 */
|
||||
RMD160Init(&context); /* init context for 2nd pass */
|
||||
RMD160Update(&context, k_opad, RIPEMD160_BLOCKSIZE); /* start with outer pad */
|
||||
/* results of 1st hash */
|
||||
RMD160Update(&context, (const unsigned char *) digest, RIPEMD160_DIGESTSIZE);
|
||||
RMD160Final((unsigned char *) digest, &context); /* finish up 2nd pass */
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (k_ipad, sizeof(k_ipad));
|
||||
burn (k_opad, sizeof(k_opad));
|
||||
burn (tk, sizeof(tk));
|
||||
burn (&context, sizeof(context));
|
||||
}
|
||||
|
||||
void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[RIPEMD160_DIGESTSIZE], k[RIPEMD160_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_ripemd160 (pwd, pwd_len, init, salt_len + 4, j);
|
||||
memcpy (u, j, RIPEMD160_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_ripemd160 (pwd, pwd_len, j, RIPEMD160_DIGESTSIZE, k);
|
||||
for (i = 0; i < RIPEMD160_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[RIPEMD160_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % RIPEMD160_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / RIPEMD160_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / RIPEMD160_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * RIPEMD160_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, RIPEMD160_DIGESTSIZE);
|
||||
dk += RIPEMD160_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_ripemd160 (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
|
||||
void hmac_whirlpool
|
||||
(
|
||||
char *k, /* secret key */
|
||||
int lk, /* length of the key in bytes */
|
||||
char *d, /* data */
|
||||
int ld, /* length of data in bytes */
|
||||
char *out, /* output buffer, at least "t" bytes */
|
||||
int t
|
||||
)
|
||||
{
|
||||
WHIRLPOOL_CTX ictx, octx;
|
||||
char iwhi[WHIRLPOOL_DIGESTSIZE], owhi[WHIRLPOOL_DIGESTSIZE];
|
||||
char key[WHIRLPOOL_DIGESTSIZE];
|
||||
char buf[WHIRLPOOL_BLOCKSIZE];
|
||||
int i;
|
||||
|
||||
/* If the key is longer than the hash algorithm block size,
|
||||
let key = whirlpool(key), as per HMAC specifications. */
|
||||
if (lk > WHIRLPOOL_BLOCKSIZE)
|
||||
{
|
||||
WHIRLPOOL_CTX tctx;
|
||||
|
||||
WHIRLPOOL_init (&tctx);
|
||||
WHIRLPOOL_add ((unsigned char *) k, lk * 8, &tctx);
|
||||
WHIRLPOOL_finalize (&tctx, (unsigned char *) key);
|
||||
|
||||
k = key;
|
||||
lk = WHIRLPOOL_DIGESTSIZE;
|
||||
|
||||
burn (&tctx, sizeof(tctx)); // Prevent leaks
|
||||
}
|
||||
|
||||
/**** Inner Digest ****/
|
||||
|
||||
WHIRLPOOL_init (&ictx);
|
||||
|
||||
/* Pad the key for inner digest */
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x36);
|
||||
for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x36;
|
||||
|
||||
WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &ictx);
|
||||
WHIRLPOOL_add ((unsigned char *) d, ld * 8, &ictx);
|
||||
|
||||
WHIRLPOOL_finalize (&ictx, (unsigned char *) iwhi);
|
||||
|
||||
/**** Outer Digest ****/
|
||||
|
||||
WHIRLPOOL_init (&octx);
|
||||
|
||||
for (i = 0; i < lk; ++i)
|
||||
buf[i] = (char) (k[i] ^ 0x5C);
|
||||
for (i = lk; i < WHIRLPOOL_BLOCKSIZE; ++i)
|
||||
buf[i] = 0x5C;
|
||||
|
||||
WHIRLPOOL_add ((unsigned char *) buf, WHIRLPOOL_BLOCKSIZE * 8, &octx);
|
||||
WHIRLPOOL_add ((unsigned char *) iwhi, WHIRLPOOL_DIGESTSIZE * 8, &octx);
|
||||
|
||||
WHIRLPOOL_finalize (&octx, (unsigned char *) owhi);
|
||||
|
||||
/* truncate and print the results */
|
||||
t = t > WHIRLPOOL_DIGESTSIZE ? WHIRLPOOL_DIGESTSIZE : t;
|
||||
hmac_truncate (owhi, out, t);
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (&ictx, sizeof(ictx));
|
||||
burn (&octx, sizeof(octx));
|
||||
burn (owhi, sizeof(owhi));
|
||||
burn (iwhi, sizeof(iwhi));
|
||||
burn (buf, sizeof(buf));
|
||||
burn (key, sizeof(key));
|
||||
}
|
||||
|
||||
void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b)
|
||||
{
|
||||
char j[WHIRLPOOL_DIGESTSIZE], k[WHIRLPOOL_DIGESTSIZE];
|
||||
char init[128];
|
||||
char counter[4];
|
||||
int c, i;
|
||||
|
||||
/* iteration 1 */
|
||||
memset (counter, 0, 4);
|
||||
counter[3] = (char) b;
|
||||
memcpy (init, salt, salt_len); /* salt */
|
||||
memcpy (&init[salt_len], counter, 4); /* big-endian block number */
|
||||
hmac_whirlpool (pwd, pwd_len, init, salt_len + 4, j, WHIRLPOOL_DIGESTSIZE);
|
||||
memcpy (u, j, WHIRLPOOL_DIGESTSIZE);
|
||||
|
||||
/* remaining iterations */
|
||||
for (c = 1; c < iterations; c++)
|
||||
{
|
||||
hmac_whirlpool (pwd, pwd_len, j, WHIRLPOOL_DIGESTSIZE, k, WHIRLPOOL_DIGESTSIZE);
|
||||
for (i = 0; i < WHIRLPOOL_DIGESTSIZE; i++)
|
||||
{
|
||||
u[i] ^= k[i];
|
||||
j[i] = k[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (j, sizeof(j));
|
||||
burn (k, sizeof(k));
|
||||
}
|
||||
|
||||
void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen)
|
||||
{
|
||||
char u[WHIRLPOOL_DIGESTSIZE];
|
||||
int b, l, r;
|
||||
|
||||
if (dklen % WHIRLPOOL_DIGESTSIZE)
|
||||
{
|
||||
l = 1 + dklen / WHIRLPOOL_DIGESTSIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = dklen / WHIRLPOOL_DIGESTSIZE;
|
||||
}
|
||||
|
||||
r = dklen - (l - 1) * WHIRLPOOL_DIGESTSIZE;
|
||||
|
||||
/* first l - 1 blocks */
|
||||
for (b = 1; b < l; b++)
|
||||
{
|
||||
derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, WHIRLPOOL_DIGESTSIZE);
|
||||
dk += WHIRLPOOL_DIGESTSIZE;
|
||||
}
|
||||
|
||||
/* last block */
|
||||
derive_u_whirlpool (pwd, pwd_len, salt, salt_len, iterations, u, b);
|
||||
memcpy (dk, u, r);
|
||||
|
||||
|
||||
/* Prevent possible leaks. */
|
||||
burn (u, sizeof(u));
|
||||
}
|
||||
|
||||
|
||||
char *get_pkcs5_prf_name (int pkcs5_prf_id)
|
||||
{
|
||||
switch (pkcs5_prf_id)
|
||||
{
|
||||
case SHA512:
|
||||
return "HMAC-SHA-512";
|
||||
|
||||
case SHA1: // Deprecated/legacy
|
||||
return "HMAC-SHA-1";
|
||||
|
||||
case RIPEMD160:
|
||||
return "HMAC-RIPEMD-160";
|
||||
|
||||
case WHIRLPOOL:
|
||||
return "HMAC-Whirlpool";
|
||||
|
||||
default:
|
||||
return "(Unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
#endif //!TC_WINDOWS_BOOT
|
||||
|
||||
|
||||
int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot)
|
||||
{
|
||||
switch (pkcs5_prf_id)
|
||||
{
|
||||
case RIPEMD160:
|
||||
return (bBoot ? 1000 : 2000);
|
||||
|
||||
#ifndef TC_WINDOWS_BOOT
|
||||
|
||||
case SHA512:
|
||||
return 1000;
|
||||
|
||||
case SHA1: // Deprecated/legacy
|
||||
return 2000;
|
||||
|
||||
case WHIRLPOOL:
|
||||
return 1000;
|
||||
#endif
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION; // Unknown/wrong ID
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
41
src/Common/Pkcs5.h
Normal file
41
src/Common/Pkcs5.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_PKCS5
|
||||
#define TC_HEADER_PKCS5
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void hmac_sha512 (char *k, int lk, char *d, int ld, char *out, int t);
|
||||
void derive_u_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
void hmac_sha1 (char *k, int lk, char *d, int ld, char *out, int t);
|
||||
void derive_u_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_sha1 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
void hmac_ripemd160 (char *key, int keylen, char *input, int len, char *digest);
|
||||
void derive_u_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_ripemd160 (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
void hmac_whirlpool (char *k, int lk, char *d, int ld, char *out, int t);
|
||||
void derive_u_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *u, int b);
|
||||
void derive_key_whirlpool (char *pwd, int pwd_len, char *salt, int salt_len, int iterations, char *dk, int dklen);
|
||||
int get_pkcs5_iteration_count (int pkcs5_prf_id, BOOL bBoot);
|
||||
char *get_pkcs5_prf_name (int pkcs5_prf_id);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_PKCS5
|
||||
130
src/Common/Progress.c
Normal file
130
src/Common/Progress.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Language.h"
|
||||
#include "Dlgcode.h"
|
||||
#include "Progress.h"
|
||||
#include "../Format/Tcformat.h"
|
||||
#include "../Format/FormatCom.h"
|
||||
#include "../Format/resource.h"
|
||||
|
||||
static ULONG prevTime, startTime;
|
||||
static __int64 TotalSize;
|
||||
static __int64 resumedPointBytesDone;
|
||||
static BOOL bProgressBarReverse = FALSE;
|
||||
static BOOL bRWThroughput = FALSE;
|
||||
static BOOL bShowStatus = FALSE;
|
||||
static BOOL bPercentMode = FALSE;
|
||||
|
||||
static wchar_t *seconds, *minutes, *hours, *days;
|
||||
|
||||
|
||||
// If bIOThroughput is TRUE, the speed reflects the amount of data read AND written per second (rather than
|
||||
// the speed of the "transform cursor").
|
||||
void InitProgressBar (__int64 totalBytes, __int64 bytesDone, BOOL bReverse, BOOL bIOThroughput, BOOL bDisplayStatus, BOOL bShowPercent)
|
||||
{
|
||||
HWND hProgressBar = GetDlgItem (hCurPage, nPbar);
|
||||
SendMessage (hProgressBar, PBM_SETRANGE32, 0, 10000);
|
||||
SendMessage (hProgressBar, PBM_SETSTEP, 1, 0);
|
||||
|
||||
bProgressBarReverse = bReverse;
|
||||
bRWThroughput = bIOThroughput;
|
||||
bShowStatus = bDisplayStatus;
|
||||
bPercentMode = bShowPercent;
|
||||
|
||||
seconds = GetString ("SECONDS");
|
||||
minutes = GetString ("MINUTES");
|
||||
hours = GetString ("HOURS");
|
||||
days = GetString ("DAYS");
|
||||
|
||||
prevTime = startTime = GetTickCount ();
|
||||
TotalSize = totalBytes;
|
||||
resumedPointBytesDone = bytesDone;
|
||||
}
|
||||
|
||||
|
||||
BOOL UpdateProgressBar (__int64 byteOffset)
|
||||
{
|
||||
return UpdateProgressBarProc (byteOffset);
|
||||
}
|
||||
|
||||
|
||||
BOOL UpdateProgressBarProc (__int64 byteOffset)
|
||||
{
|
||||
wchar_t text[100];
|
||||
wchar_t speed[100];
|
||||
HWND hProgressBar = GetDlgItem (hCurPage, nPbar);
|
||||
int time = GetTickCount ();
|
||||
int elapsed = (time - startTime) / 1000;
|
||||
|
||||
uint64 bytesDone = (bProgressBarReverse ? (TotalSize - byteOffset) : byteOffset);
|
||||
uint64 bytesPerSec = (bProgressBarReverse ? (resumedPointBytesDone - byteOffset) : (bytesDone - resumedPointBytesDone)) / (elapsed + 1);
|
||||
|
||||
if (bPercentMode)
|
||||
{
|
||||
double perc = (double) (100.0 * (bProgressBarReverse ? ((double) (TotalSize - byteOffset)) : ((double) byteOffset)) / (TotalSize == 0 ? 0.0001 : ((double) TotalSize)));
|
||||
|
||||
if (perc > 99.999999999)
|
||||
wcscpy (text, GetString ("PROCESSED_PORTION_100_PERCENT"));
|
||||
else
|
||||
_snwprintf (text, sizeof text/2, GetString ("PROCESSED_PORTION_X_PERCENT"), perc);
|
||||
|
||||
wcscat (speed, L" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
GetSizeString (bytesDone, text);
|
||||
if (bytesDone < (unsigned __int64) BYTES_PER_MB * 1000000)
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_MB, GetString ("MB"));
|
||||
else if (bytesDone < (unsigned __int64) BYTES_PER_GB * 1000000)
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_GB, GetString ("GB"));
|
||||
else if (bytesDone < (unsigned __int64) BYTES_PER_TB * 1000000)
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_TB, GetString ("TB"));
|
||||
else
|
||||
swprintf(text, L"%I64d %s ", bytesDone / BYTES_PER_PB, GetString ("PB"));
|
||||
}
|
||||
|
||||
SetWindowTextW (GetDlgItem (hCurPage, IDC_BYTESWRITTEN), text);
|
||||
|
||||
if (!bShowStatus)
|
||||
{
|
||||
GetSpeedString (bRWThroughput ? bytesPerSec*2 : bytesPerSec, speed);
|
||||
wcscat (speed, L" ");
|
||||
SetWindowTextW (GetDlgItem (hCurPage, IDC_WRITESPEED), speed);
|
||||
}
|
||||
|
||||
if (byteOffset < TotalSize)
|
||||
{
|
||||
int64 sec = (int64) ((bProgressBarReverse ? byteOffset : (TotalSize - byteOffset)) / (bytesPerSec == 0 ? 0.001 : bytesPerSec));
|
||||
|
||||
if (bytesPerSec == 0 || sec > 60 * 60 * 24 * 999)
|
||||
swprintf (text, L"%s ", GetString ("NOT_APPLICABLE_OR_NOT_AVAILABLE"));
|
||||
else if (sec >= 60 * 60 * 24 * 2)
|
||||
swprintf (text, L"%I64d %s ", sec / (60 * 24 * 60), days);
|
||||
else if (sec >= 120 * 60)
|
||||
swprintf (text, L"%I64d %s ", sec / (60 * 60), hours);
|
||||
else if (sec >= 120)
|
||||
swprintf (text, L"%I64d %s ", sec / 60, minutes);
|
||||
else
|
||||
swprintf (text, L"%I64d %s ", sec, seconds);
|
||||
|
||||
SetWindowTextW (GetDlgItem (hCurPage, IDC_TIMEREMAIN), text);
|
||||
}
|
||||
|
||||
prevTime = time;
|
||||
|
||||
SendMessage (hProgressBar, PBM_SETPOS,
|
||||
(int) (10000.0 * (bProgressBarReverse ? (TotalSize - byteOffset) : byteOffset) / (TotalSize == 0 ? 1 : TotalSize)),
|
||||
0);
|
||||
|
||||
return bVolTransformThreadCancel;
|
||||
}
|
||||
22
src/Common/Progress.h
Normal file
22
src/Common/Progress.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void InitProgressBar (__int64 totalBytes, __int64 bytesDone, BOOL bReverse, BOOL bIOThroughput, BOOL bDisplayStatus, BOOL bShowPercent);
|
||||
BOOL UpdateProgressBar (__int64 byteOffset);
|
||||
BOOL UpdateProgressBarProc (__int64 byteOffset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
772
src/Common/Random.c
Normal file
772
src/Common/Random.c
Normal file
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Crc.h"
|
||||
#include "Random.h"
|
||||
|
||||
static unsigned __int8 buffer[RNG_POOL_SIZE];
|
||||
static unsigned char *pRandPool = NULL;
|
||||
static BOOL bRandDidInit = FALSE;
|
||||
static int nRandIndex = 0, randPoolReadIndex = 0;
|
||||
static int HashFunction = DEFAULT_HASH_ALGORITHM;
|
||||
static BOOL bDidSlowPoll = FALSE;
|
||||
BOOL volatile bFastPollEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */
|
||||
BOOL volatile bRandmixEnabled = TRUE; /* Used to reduce CPU load when performing benchmarks */
|
||||
static BOOL RandomPoolEnrichedByUser = FALSE;
|
||||
static HANDLE PeriodicFastPollThreadHandle = NULL;
|
||||
|
||||
/* Macro to add a single byte to the pool */
|
||||
#define RandaddByte(x) {\
|
||||
if (nRandIndex == RNG_POOL_SIZE) nRandIndex = 0;\
|
||||
pRandPool[nRandIndex] = (unsigned char) ((unsigned char)x + pRandPool[nRandIndex]); \
|
||||
if (nRandIndex % RANDMIX_BYTE_INTERVAL == 0) Randmix();\
|
||||
nRandIndex++; \
|
||||
}
|
||||
|
||||
/* Macro to add four bytes to the pool */
|
||||
#define RandaddInt32(x) RandAddInt((unsigned __int32)x);
|
||||
|
||||
void RandAddInt (unsigned __int32 x)
|
||||
{
|
||||
RandaddByte(x);
|
||||
RandaddByte((x >> 8));
|
||||
RandaddByte((x >> 16));
|
||||
RandaddByte((x >> 24));
|
||||
}
|
||||
|
||||
#include <tlhelp32.h>
|
||||
#include "Dlgcode.h"
|
||||
|
||||
HHOOK hMouse = NULL; /* Mouse hook for the random number generator */
|
||||
HHOOK hKeyboard = NULL; /* Keyboard hook for the random number generator */
|
||||
|
||||
/* Variables for thread control, the thread is used to gather up info about
|
||||
the system in in the background */
|
||||
CRITICAL_SECTION critRandProt; /* The critical section */
|
||||
BOOL volatile bThreadTerminate = FALSE; /* This variable is shared among thread's so its made volatile */
|
||||
|
||||
/* Network library handle for the SlowPoll function */
|
||||
HANDLE hNetAPI32 = NULL;
|
||||
|
||||
// CryptoAPI
|
||||
BOOL CryptoAPIAvailable = FALSE;
|
||||
HCRYPTPROV hCryptProv;
|
||||
|
||||
|
||||
/* Init the random number generator, setup the hooks, and start the thread */
|
||||
int Randinit ()
|
||||
{
|
||||
if (GetMaxPkcs5OutSize() > RNG_POOL_SIZE)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
if(bRandDidInit)
|
||||
return 0;
|
||||
|
||||
InitializeCriticalSection (&critRandProt);
|
||||
|
||||
bRandDidInit = TRUE;
|
||||
|
||||
if (pRandPool == NULL)
|
||||
{
|
||||
pRandPool = (unsigned char *) TCalloc (RANDOMPOOL_ALLOCSIZE);
|
||||
if (pRandPool == NULL)
|
||||
goto error;
|
||||
|
||||
bDidSlowPoll = FALSE;
|
||||
RandomPoolEnrichedByUser = FALSE;
|
||||
|
||||
memset (pRandPool, 0, RANDOMPOOL_ALLOCSIZE);
|
||||
VirtualLock (pRandPool, RANDOMPOOL_ALLOCSIZE);
|
||||
}
|
||||
|
||||
hKeyboard = SetWindowsHookEx (WH_KEYBOARD, (HOOKPROC)&KeyboardProc, NULL, GetCurrentThreadId ());
|
||||
if (hKeyboard == 0) handleWin32Error (0);
|
||||
|
||||
hMouse = SetWindowsHookEx (WH_MOUSE, (HOOKPROC)&MouseProc, NULL, GetCurrentThreadId ());
|
||||
if (hMouse == 0)
|
||||
{
|
||||
handleWin32Error (0);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0)
|
||||
&& !CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET))
|
||||
CryptoAPIAvailable = FALSE;
|
||||
else
|
||||
CryptoAPIAvailable = TRUE;
|
||||
|
||||
if (!(PeriodicFastPollThreadHandle = (HANDLE) _beginthreadex (NULL, 0, PeriodicFastPollThreadProc, NULL, 0, NULL)))
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
RandStop (TRUE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Close everything down, including the thread which is closed down by
|
||||
setting a flag which eventually causes the thread function to exit */
|
||||
void RandStop (BOOL freePool)
|
||||
{
|
||||
if (!bRandDidInit && freePool && pRandPool)
|
||||
goto freePool;
|
||||
|
||||
if (bRandDidInit == FALSE)
|
||||
return;
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
|
||||
if (hMouse != 0)
|
||||
UnhookWindowsHookEx (hMouse);
|
||||
if (hKeyboard != 0)
|
||||
UnhookWindowsHookEx (hKeyboard);
|
||||
|
||||
bThreadTerminate = TRUE;
|
||||
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
if (PeriodicFastPollThreadHandle)
|
||||
WaitForSingleObject (PeriodicFastPollThreadHandle, INFINITE);
|
||||
|
||||
if (hNetAPI32 != 0)
|
||||
{
|
||||
FreeLibrary (hNetAPI32);
|
||||
hNetAPI32 = NULL;
|
||||
}
|
||||
|
||||
if (CryptoAPIAvailable)
|
||||
{
|
||||
CryptReleaseContext (hCryptProv, 0);
|
||||
CryptoAPIAvailable = FALSE;
|
||||
}
|
||||
|
||||
hMouse = NULL;
|
||||
hKeyboard = NULL;
|
||||
bThreadTerminate = FALSE;
|
||||
DeleteCriticalSection (&critRandProt);
|
||||
|
||||
bRandDidInit = FALSE;
|
||||
|
||||
freePool:
|
||||
if (freePool)
|
||||
{
|
||||
bDidSlowPoll = FALSE;
|
||||
RandomPoolEnrichedByUser = FALSE;
|
||||
|
||||
if (pRandPool != NULL)
|
||||
{
|
||||
burn (pRandPool, RANDOMPOOL_ALLOCSIZE);
|
||||
TCfree (pRandPool);
|
||||
pRandPool = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL IsRandomNumberGeneratorStarted ()
|
||||
{
|
||||
return bRandDidInit;
|
||||
}
|
||||
|
||||
void RandSetHashFunction (int hash_algo_id)
|
||||
{
|
||||
if (HashIsDeprecated (hash_algo_id))
|
||||
hash_algo_id = DEFAULT_HASH_ALGORITHM;
|
||||
|
||||
HashFunction = hash_algo_id;
|
||||
}
|
||||
|
||||
int RandGetHashFunction (void)
|
||||
{
|
||||
return HashFunction;
|
||||
}
|
||||
|
||||
void SetRandomPoolEnrichedByUserStatus (BOOL enriched)
|
||||
{
|
||||
RandomPoolEnrichedByUser = enriched;
|
||||
}
|
||||
|
||||
BOOL IsRandomPoolEnrichedByUser ()
|
||||
{
|
||||
return RandomPoolEnrichedByUser;
|
||||
}
|
||||
|
||||
/* The random pool mixing function */
|
||||
BOOL Randmix ()
|
||||
{
|
||||
if (bRandmixEnabled)
|
||||
{
|
||||
unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
|
||||
WHIRLPOOL_CTX wctx;
|
||||
RMD160_CTX rctx;
|
||||
sha512_ctx sctx;
|
||||
int poolIndex, digestIndex, digestSize;
|
||||
|
||||
switch (HashFunction)
|
||||
{
|
||||
case RIPEMD160:
|
||||
digestSize = RIPEMD160_DIGESTSIZE;
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
digestSize = SHA512_DIGESTSIZE;
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
digestSize = WHIRLPOOL_DIGESTSIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (RNG_POOL_SIZE % digestSize)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
for (poolIndex = 0; poolIndex < RNG_POOL_SIZE; poolIndex += digestSize)
|
||||
{
|
||||
/* Compute the message digest of the entire pool using the selected hash function. */
|
||||
switch (HashFunction)
|
||||
{
|
||||
case RIPEMD160:
|
||||
RMD160Init(&rctx);
|
||||
RMD160Update(&rctx, pRandPool, RNG_POOL_SIZE);
|
||||
RMD160Final(hashOutputBuffer, &rctx);
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
sha512_begin (&sctx);
|
||||
sha512_hash (pRandPool, RNG_POOL_SIZE, &sctx);
|
||||
sha512_end (hashOutputBuffer, &sctx);
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
WHIRLPOOL_init (&wctx);
|
||||
WHIRLPOOL_add (pRandPool, RNG_POOL_SIZE * 8, &wctx);
|
||||
WHIRLPOOL_finalize (&wctx, hashOutputBuffer);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown/wrong ID
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
/* XOR the resultant message digest to the pool at the poolIndex position. */
|
||||
for (digestIndex = 0; digestIndex < digestSize; digestIndex++)
|
||||
{
|
||||
pRandPool [poolIndex + digestIndex] ^= hashOutputBuffer [digestIndex];
|
||||
}
|
||||
}
|
||||
|
||||
/* Prevent leaks */
|
||||
burn (hashOutputBuffer, MAX_DIGESTSIZE);
|
||||
switch (HashFunction)
|
||||
{
|
||||
case RIPEMD160:
|
||||
burn (&rctx, sizeof(rctx));
|
||||
break;
|
||||
|
||||
case SHA512:
|
||||
burn (&sctx, sizeof(sctx));
|
||||
break;
|
||||
|
||||
case WHIRLPOOL:
|
||||
burn (&wctx, sizeof(wctx));
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unknown/wrong ID
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Add a buffer to the pool */
|
||||
void RandaddBuf (void *buf, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
RandaddByte (((unsigned char *) buf)[i]);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL RandpeekBytes (unsigned char *buf, int len)
|
||||
{
|
||||
if (!bRandDidInit)
|
||||
return FALSE;
|
||||
|
||||
if (len > RNG_POOL_SIZE)
|
||||
{
|
||||
Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
|
||||
len = RNG_POOL_SIZE;
|
||||
}
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
memcpy (buf, pRandPool, len);
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Get len random bytes from the pool (max. RNG_POOL_SIZE bytes per a single call) */
|
||||
BOOL RandgetBytes (unsigned char *buf, int len, BOOL forceSlowPoll)
|
||||
{
|
||||
int i;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (!bRandDidInit || HashFunction == 0)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
|
||||
if (bDidSlowPoll == FALSE || forceSlowPoll)
|
||||
{
|
||||
if (!SlowPoll ())
|
||||
ret = FALSE;
|
||||
else
|
||||
bDidSlowPoll = TRUE;
|
||||
}
|
||||
|
||||
if (!FastPoll ())
|
||||
ret = FALSE;
|
||||
|
||||
/* There's never more than RNG_POOL_SIZE worth of randomess */
|
||||
if (len > RNG_POOL_SIZE)
|
||||
{
|
||||
Error ("ERR_NOT_ENOUGH_RANDOM_DATA");
|
||||
len = RNG_POOL_SIZE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Requested number of bytes is copied from pool to output buffer,
|
||||
// pool is rehashed, and output buffer is XORed with new data from pool
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
buf[i] = pRandPool[randPoolReadIndex++];
|
||||
if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
|
||||
}
|
||||
|
||||
/* Invert the pool */
|
||||
for (i = 0; i < RNG_POOL_SIZE / 4; i++)
|
||||
{
|
||||
((unsigned __int32 *) pRandPool)[i] = ~((unsigned __int32 *) pRandPool)[i];
|
||||
}
|
||||
|
||||
// Mix the pool
|
||||
if (!FastPoll ())
|
||||
ret = FALSE;
|
||||
|
||||
// XOR the current pool content into the output buffer to prevent pool state leaks
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
buf[i] ^= pRandPool[randPoolReadIndex++];
|
||||
if (randPoolReadIndex == RNG_POOL_SIZE) randPoolReadIndex = 0;
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
if (!ret)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Capture the mouse, and as long as the event is not the same as the last
|
||||
two events, add the crc of the event, and the crc of the time difference
|
||||
between this event and the last + the current time to the pool.
|
||||
The role of CRC-32 is merely to perform diffusion. Note that the output
|
||||
of CRC-32 is subsequently processed using a cryptographically secure hash
|
||||
algorithm. */
|
||||
LRESULT CALLBACK MouseProc (int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static DWORD dwLastTimer;
|
||||
static unsigned __int32 lastCrc, lastCrc2;
|
||||
MOUSEHOOKSTRUCT *lpMouse = (MOUSEHOOKSTRUCT *) lParam;
|
||||
|
||||
if (nCode < 0)
|
||||
return CallNextHookEx (hMouse, nCode, wParam, lParam);
|
||||
else
|
||||
{
|
||||
DWORD dwTimer = GetTickCount ();
|
||||
DWORD j = dwLastTimer - dwTimer;
|
||||
unsigned __int32 crc = 0L;
|
||||
int i;
|
||||
|
||||
dwLastTimer = dwTimer;
|
||||
|
||||
for (i = 0; i < sizeof (MOUSEHOOKSTRUCT); i++)
|
||||
{
|
||||
crc = UPDC32 (((unsigned char *) lpMouse)[i], crc);
|
||||
}
|
||||
|
||||
if (crc != lastCrc && crc != lastCrc2)
|
||||
{
|
||||
unsigned __int32 timeCrc = 0L;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
|
||||
}
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
RandaddInt32 ((unsigned __int32) (crc + timeCrc));
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
}
|
||||
lastCrc2 = lastCrc;
|
||||
lastCrc = crc;
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Capture the keyboard, as long as the event is not the same as the last two
|
||||
events, add the crc of the event to the pool along with the crc of the time
|
||||
difference between this event and the last. The role of CRC-32 is merely to
|
||||
perform diffusion. Note that the output of CRC-32 is subsequently processed
|
||||
using a cryptographically secure hash algorithm. */
|
||||
LRESULT CALLBACK KeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static int lLastKey, lLastKey2;
|
||||
static DWORD dwLastTimer;
|
||||
int nKey = (lParam & 0x00ff0000) >> 16;
|
||||
int nCapture = 0;
|
||||
|
||||
if (nCode < 0)
|
||||
return CallNextHookEx (hMouse, nCode, wParam, lParam);
|
||||
|
||||
if ((lParam & 0x0000ffff) == 1 && !(lParam & 0x20000000) &&
|
||||
(lParam & 0x80000000))
|
||||
{
|
||||
if (nKey != lLastKey)
|
||||
nCapture = 1; /* Capture this key */
|
||||
else if (nKey != lLastKey2)
|
||||
nCapture = 1; /* Allow for one repeat */
|
||||
}
|
||||
if (nCapture)
|
||||
{
|
||||
DWORD dwTimer = GetTickCount ();
|
||||
DWORD j = dwLastTimer - dwTimer;
|
||||
unsigned __int32 timeCrc = 0L;
|
||||
int i;
|
||||
|
||||
dwLastTimer = dwTimer;
|
||||
lLastKey2 = lLastKey;
|
||||
lLastKey = nKey;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &j)[i], timeCrc);
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
timeCrc = UPDC32 (((unsigned char *) &dwTimer)[i], timeCrc);
|
||||
}
|
||||
|
||||
EnterCriticalSection (&critRandProt);
|
||||
RandaddInt32 ((unsigned __int32) (crc32int(&lParam) + timeCrc));
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
}
|
||||
|
||||
return CallNextHookEx (hMouse, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
/* This is the thread function which will poll the system for randomness */
|
||||
static unsigned __stdcall PeriodicFastPollThreadProc (void *dummy)
|
||||
{
|
||||
if (dummy); /* Remove unused parameter warning */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
EnterCriticalSection (&critRandProt);
|
||||
|
||||
if (bThreadTerminate)
|
||||
{
|
||||
bThreadTerminate = FALSE;
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
_endthreadex (0);
|
||||
}
|
||||
else if (bFastPollEnabled)
|
||||
{
|
||||
FastPoll ();
|
||||
}
|
||||
|
||||
LeaveCriticalSection (&critRandProt);
|
||||
|
||||
Sleep (FASTPOLL_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Type definitions for function pointers to call NetAPI32 functions */
|
||||
|
||||
typedef
|
||||
DWORD (WINAPI * NETSTATISTICSGET) (LPWSTR szServer, LPWSTR szService,
|
||||
DWORD dwLevel, DWORD dwOptions,
|
||||
LPBYTE * lpBuffer);
|
||||
typedef
|
||||
DWORD (WINAPI * NETAPIBUFFERSIZE) (LPVOID lpBuffer, LPDWORD cbBuffer);
|
||||
typedef
|
||||
DWORD (WINAPI * NETAPIBUFFERFREE) (LPVOID lpBuffer);
|
||||
|
||||
NETSTATISTICSGET pNetStatisticsGet = NULL;
|
||||
NETAPIBUFFERSIZE pNetApiBufferSize = NULL;
|
||||
NETAPIBUFFERFREE pNetApiBufferFree = NULL;
|
||||
|
||||
|
||||
/* This is the slowpoll function which gathers up network/hard drive
|
||||
performance data for the random pool */
|
||||
BOOL SlowPoll (void)
|
||||
{
|
||||
static int isWorkstation = -1;
|
||||
static int cbPerfData = 0x10000;
|
||||
HANDLE hDevice;
|
||||
LPBYTE lpBuffer;
|
||||
DWORD dwSize, status;
|
||||
LPWSTR lpszLanW, lpszLanS;
|
||||
int nDrive;
|
||||
|
||||
/* Find out whether this is an NT server or workstation if necessary */
|
||||
if (isWorkstation == -1)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
|
||||
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
|
||||
0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
unsigned char szValue[32];
|
||||
dwSize = sizeof (szValue);
|
||||
|
||||
isWorkstation = TRUE;
|
||||
status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
|
||||
szValue, &dwSize);
|
||||
|
||||
if (status == ERROR_SUCCESS && _stricmp ((char *) szValue, "WinNT"))
|
||||
/* Note: There are (at least) three cases for
|
||||
ProductType: WinNT = NT Workstation,
|
||||
ServerNT = NT Server, LanmanNT = NT Server
|
||||
acting as a Domain Controller */
|
||||
isWorkstation = FALSE;
|
||||
|
||||
RegCloseKey (hKey);
|
||||
}
|
||||
}
|
||||
/* Initialize the NetAPI32 function pointers if necessary */
|
||||
if (hNetAPI32 == NULL)
|
||||
{
|
||||
/* Obtain a handle to the module containing the Lan Manager
|
||||
functions */
|
||||
hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
|
||||
if (hNetAPI32 != NULL)
|
||||
{
|
||||
/* Now get pointers to the functions */
|
||||
pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
|
||||
"NetStatisticsGet");
|
||||
pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
|
||||
"NetApiBufferSize");
|
||||
pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
|
||||
"NetApiBufferFree");
|
||||
|
||||
/* Make sure we got valid pointers for every NetAPI32
|
||||
function */
|
||||
if (pNetStatisticsGet == NULL ||
|
||||
pNetApiBufferSize == NULL ||
|
||||
pNetApiBufferFree == NULL)
|
||||
{
|
||||
/* Free the library reference and reset the
|
||||
static handle */
|
||||
FreeLibrary (hNetAPI32);
|
||||
hNetAPI32 = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get network statistics. Note: Both NT Workstation and NT Server
|
||||
by default will be running both the workstation and server
|
||||
services. The heuristic below is probably useful though on the
|
||||
assumption that the majority of the network traffic will be via
|
||||
the appropriate service */
|
||||
lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
|
||||
lpszLanS = (LPWSTR) WIDE ("LanmanServer");
|
||||
if (hNetAPI32 &&
|
||||
pNetStatisticsGet (NULL,
|
||||
isWorkstation ? lpszLanW : lpszLanS,
|
||||
0, 0, &lpBuffer) == 0)
|
||||
{
|
||||
pNetApiBufferSize (lpBuffer, &dwSize);
|
||||
RandaddBuf ((unsigned char *) lpBuffer, dwSize);
|
||||
pNetApiBufferFree (lpBuffer);
|
||||
}
|
||||
|
||||
/* Get disk I/O statistics for all the hard drives */
|
||||
for (nDrive = 0;; nDrive++)
|
||||
{
|
||||
DISK_PERFORMANCE diskPerformance;
|
||||
char szDevice[24];
|
||||
|
||||
/* Check whether we can access this device */
|
||||
sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
|
||||
hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hDevice == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
|
||||
/* Note: This only works if you have turned on the disk
|
||||
performance counters with 'diskperf -y'. These counters
|
||||
are off by default */
|
||||
if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
|
||||
&diskPerformance, sizeof (DISK_PERFORMANCE),
|
||||
&dwSize, NULL))
|
||||
{
|
||||
RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
|
||||
}
|
||||
CloseHandle (hDevice);
|
||||
}
|
||||
|
||||
// CryptoAPI
|
||||
if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
||||
RandaddBuf (buffer, sizeof (buffer));
|
||||
|
||||
burn(buffer, sizeof (buffer));
|
||||
Randmix();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* This is the fastpoll function which gathers up info by calling various api's */
|
||||
BOOL FastPoll (void)
|
||||
{
|
||||
int nOriginalRandIndex = nRandIndex;
|
||||
static BOOL addedFixedItems = FALSE;
|
||||
FILETIME creationTime, exitTime, kernelTime, userTime;
|
||||
DWORD minimumWorkingSetSize, maximumWorkingSetSize;
|
||||
LARGE_INTEGER performanceCount;
|
||||
MEMORYSTATUS memoryStatus;
|
||||
HANDLE handle;
|
||||
POINT point;
|
||||
|
||||
/* Get various basic pieces of system information */
|
||||
RandaddInt32 (GetActiveWindow ()); /* Handle of active window */
|
||||
RandaddInt32 (GetCapture ()); /* Handle of window with mouse
|
||||
capture */
|
||||
RandaddInt32 (GetClipboardOwner ()); /* Handle of clipboard owner */
|
||||
RandaddInt32 (GetClipboardViewer ()); /* Handle of start of
|
||||
clpbd.viewer list */
|
||||
RandaddInt32 (GetCurrentProcess ()); /* Pseudohandle of current
|
||||
process */
|
||||
RandaddInt32 (GetCurrentProcessId ()); /* Current process ID */
|
||||
RandaddInt32 (GetCurrentThread ()); /* Pseudohandle of current
|
||||
thread */
|
||||
RandaddInt32 (GetCurrentThreadId ()); /* Current thread ID */
|
||||
RandaddInt32 (GetCurrentTime ()); /* Milliseconds since Windows
|
||||
started */
|
||||
RandaddInt32 (GetDesktopWindow ()); /* Handle of desktop window */
|
||||
RandaddInt32 (GetFocus ()); /* Handle of window with kb.focus */
|
||||
RandaddInt32 (GetInputState ()); /* Whether sys.queue has any events */
|
||||
RandaddInt32 (GetMessagePos ()); /* Cursor pos.for last message */
|
||||
RandaddInt32 (GetMessageTime ()); /* 1 ms time for last message */
|
||||
RandaddInt32 (GetOpenClipboardWindow ()); /* Handle of window with
|
||||
clpbd.open */
|
||||
RandaddInt32 (GetProcessHeap ()); /* Handle of process heap */
|
||||
RandaddInt32 (GetProcessWindowStation ()); /* Handle of procs
|
||||
window station */
|
||||
RandaddInt32 (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in
|
||||
input queue */
|
||||
|
||||
/* Get multiword system information */
|
||||
GetCaretPos (&point); /* Current caret position */
|
||||
RandaddBuf ((unsigned char *) &point, sizeof (POINT));
|
||||
GetCursorPos (&point); /* Current mouse cursor position */
|
||||
RandaddBuf ((unsigned char *) &point, sizeof (POINT));
|
||||
|
||||
/* Get percent of memory in use, bytes of physical memory, bytes of
|
||||
free physical memory, bytes in paging file, free bytes in paging
|
||||
file, user bytes of address space, and free user bytes */
|
||||
memoryStatus.dwLength = sizeof (MEMORYSTATUS);
|
||||
GlobalMemoryStatus (&memoryStatus);
|
||||
RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));
|
||||
|
||||
/* Get thread and process creation time, exit time, time in kernel
|
||||
mode, and time in user mode in 100ns intervals */
|
||||
handle = GetCurrentThread ();
|
||||
GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
|
||||
RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
|
||||
handle = GetCurrentProcess ();
|
||||
GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
|
||||
RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
|
||||
RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
|
||||
|
||||
/* Get the minimum and maximum working set size for the current
|
||||
process */
|
||||
GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
|
||||
&maximumWorkingSetSize);
|
||||
RandaddInt32 (minimumWorkingSetSize);
|
||||
RandaddInt32 (maximumWorkingSetSize);
|
||||
|
||||
/* The following are fixed for the lifetime of the process so we only
|
||||
add them once */
|
||||
if (addedFixedItems == 0)
|
||||
{
|
||||
STARTUPINFO startupInfo;
|
||||
|
||||
/* Get name of desktop, console window title, new window
|
||||
position and size, window flags, and handles for stdin,
|
||||
stdout, and stderr */
|
||||
startupInfo.cb = sizeof (STARTUPINFO);
|
||||
GetStartupInfo (&startupInfo);
|
||||
RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
|
||||
addedFixedItems = TRUE;
|
||||
}
|
||||
/* The docs say QPC can fail if appropriate hardware is not
|
||||
available. It works on 486 & Pentium boxes, but hasn't been tested
|
||||
for 386 or RISC boxes */
|
||||
if (QueryPerformanceCounter (&performanceCount))
|
||||
RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
|
||||
else
|
||||
{
|
||||
/* Millisecond accuracy at best... */
|
||||
DWORD dwTicks = GetTickCount ();
|
||||
RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
|
||||
}
|
||||
|
||||
// CryptoAPI
|
||||
if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer))
|
||||
RandaddBuf (buffer, sizeof (buffer));
|
||||
|
||||
/* Apply the pool mixing function */
|
||||
Randmix();
|
||||
|
||||
/* Restore the original pool cursor position. If this wasn't done, mouse coordinates
|
||||
could be written to a limited area of the pool, especially when moving the mouse
|
||||
uninterruptedly. The severity of the problem would depend on the length of data
|
||||
written by FastPoll (if it was equal to the size of the pool, mouse coordinates
|
||||
would be written only to a particular 4-byte area, whenever moving the mouse
|
||||
uninterruptedly). */
|
||||
nRandIndex = nOriginalRandIndex;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
62
src/Common/Random.h
Normal file
62
src/Common/Random.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
|
||||
#include "Crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* RNG defines & pool pointers */
|
||||
#define RNG_POOL_SIZE 320 // Must be divisible by the size of the output of each of the implemented hash functions. (in bytes)
|
||||
|
||||
#if RNG_POOL_SIZE % SHA512_DIGESTSIZE || RNG_POOL_SIZE % WHIRLPOOL_DIGESTSIZE || RNG_POOL_SIZE % RIPEMD160_DIGESTSIZE
|
||||
#error RNG_POOL_SIZE must be divisible by the size of the output of each of the implemented hash functions.
|
||||
#endif
|
||||
|
||||
#define RANDOMPOOL_ALLOCSIZE RNG_POOL_SIZE
|
||||
|
||||
// After every RANDMIX_BYTE_INTERVAL-th byte written to the pool, the pool mixing function is applied to the entire pool
|
||||
#define RANDMIX_BYTE_INTERVAL 16
|
||||
|
||||
// FastPoll interval (in milliseconds)
|
||||
#define FASTPOLL_INTERVAL 500
|
||||
|
||||
void RandAddInt ( unsigned __int32 x );
|
||||
int Randinit ( void );
|
||||
void RandStop (BOOL freePool);
|
||||
BOOL IsRandomNumberGeneratorStarted ();
|
||||
void RandSetHashFunction ( int hash_algo_id );
|
||||
int RandGetHashFunction (void);
|
||||
void SetRandomPoolEnrichedByUserStatus (BOOL enriched);
|
||||
BOOL IsRandomPoolEnrichedByUser ();
|
||||
BOOL Randmix ( void );
|
||||
void RandaddBuf ( void *buf , int len );
|
||||
BOOL FastPoll ( void );
|
||||
BOOL SlowPoll ( void );
|
||||
BOOL RandpeekBytes ( unsigned char *buf , int len );
|
||||
BOOL RandgetBytes ( unsigned char *buf , int len, BOOL forceSlowPoll );
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
extern BOOL volatile bFastPollEnabled;
|
||||
extern BOOL volatile bRandmixEnabled;
|
||||
|
||||
LRESULT CALLBACK MouseProc ( int nCode , WPARAM wParam , LPARAM lParam );
|
||||
LRESULT CALLBACK KeyboardProc ( int nCode , WPARAM wParam , LPARAM lParam );
|
||||
static unsigned __stdcall PeriodicFastPollThreadProc (void *dummy);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
286
src/Common/Registry.c
Normal file
286
src/Common/Registry.c
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
Copyright (c) 2004-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Registry.h"
|
||||
|
||||
BOOL ReadLocalMachineRegistryDword (char *subKey, char *name, DWORD *value)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD size = sizeof (*value);
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) value, &size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_DWORD;
|
||||
}
|
||||
|
||||
BOOL ReadLocalMachineRegistryMultiString (char *subKey, char *name, char *value, DWORD *size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) value, size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_MULTI_SZ;
|
||||
}
|
||||
|
||||
BOOL ReadLocalMachineRegistryString (const char *subKey, char *name, char *str, DWORD *size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) str, size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_SZ;
|
||||
}
|
||||
|
||||
BOOL ReadLocalMachineRegistryStringNonReflected (const char *subKey, char *name, char *str, DWORD *size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD type;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ | KEY_WOW64_64KEY, &hkey) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, NULL, &type, (BYTE *) str, size) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return type == REG_SZ;
|
||||
}
|
||||
|
||||
int ReadRegistryInt (char *subKey, char *name, int defaultValue)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD value, size = sizeof (DWORD);
|
||||
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return defaultValue;
|
||||
|
||||
if (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) &value, &size) != ERROR_SUCCESS)
|
||||
value = defaultValue;
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return value;
|
||||
}
|
||||
|
||||
char *ReadRegistryString (char *subKey, char *name, char *defaultValue, char *str, int maxLen)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
char value[MAX_PATH*4];
|
||||
DWORD size = sizeof (value);
|
||||
|
||||
strncpy (str, defaultValue, maxLen-1);
|
||||
|
||||
ZeroMemory (value, sizeof value);
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, KEY_READ, &hkey) == ERROR_SUCCESS)
|
||||
if (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) &value, &size) == ERROR_SUCCESS)
|
||||
strncpy (str, value, maxLen-1);
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return str;
|
||||
}
|
||||
|
||||
DWORD ReadRegistryBytes (char *path, char *name, char *value, int maxLen)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD size = maxLen;
|
||||
BOOL success = FALSE;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, path, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
success = (RegQueryValueEx (hkey, name, 0, 0, (LPBYTE) value, &size) == ERROR_SUCCESS);
|
||||
RegCloseKey (hkey);
|
||||
|
||||
return success ? size : 0;
|
||||
}
|
||||
|
||||
void WriteRegistryInt (char *subKey, char *name, int value)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
|
||||
if (RegCreateKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
RegSetValueEx (hkey, name, 0, REG_DWORD, (BYTE *) &value, sizeof value);
|
||||
RegCloseKey (hkey);
|
||||
}
|
||||
|
||||
BOOL WriteLocalMachineRegistryDword (char *subKey, char *name, DWORD value)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
LONG status;
|
||||
|
||||
if ((status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegSetValueEx (hkey, name, 0, REG_DWORD, (BYTE *) &value, sizeof value)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WriteLocalMachineRegistryMultiString (char *subKey, char *name, char *multiString, DWORD size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
LONG status;
|
||||
|
||||
if ((status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegSetValueEx (hkey, name, 0, REG_MULTI_SZ, (BYTE *) multiString, size)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WriteLocalMachineRegistryString (char *subKey, char *name, char *str, BOOL expandable)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
LONG status;
|
||||
|
||||
if ((status = RegCreateKeyEx (HKEY_LOCAL_MACHINE, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegSetValueEx (hkey, name, 0, expandable ? REG_EXPAND_SZ : REG_SZ, (BYTE *) str, strlen (str) + 1)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void WriteRegistryString (char *subKey, char *name, char *str)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
|
||||
if (RegCreateKeyEx (HKEY_CURRENT_USER, subKey,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
RegSetValueEx (hkey, name, 0, REG_SZ, (BYTE *) str, strlen (str) + 1);
|
||||
RegCloseKey (hkey);
|
||||
}
|
||||
|
||||
BOOL WriteRegistryBytes (char *path, char *name, char *str, DWORD size)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
DWORD disp;
|
||||
BOOL res;
|
||||
|
||||
if (RegCreateKeyEx (HKEY_CURRENT_USER, path,
|
||||
0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkey, &disp) != ERROR_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
res = RegSetValueEx (hkey, name, 0, REG_BINARY, (BYTE *) str, size);
|
||||
RegCloseKey (hkey);
|
||||
return res == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL DeleteLocalMachineRegistryKey (char *parentKey, char *subKeyToDelete)
|
||||
{
|
||||
LONG status;
|
||||
HKEY hkey = 0;
|
||||
|
||||
if ((status = RegOpenKeyEx (HKEY_LOCAL_MACHINE, parentKey, 0, KEY_WRITE, &hkey)) != ERROR_SUCCESS)
|
||||
{
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((status = RegDeleteKey (hkey, subKeyToDelete)) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey (hkey);
|
||||
SetLastError (status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RegCloseKey (hkey);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void DeleteRegistryValue (char *subKey, char *name)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
|
||||
if (RegOpenKeyEx (HKEY_CURRENT_USER, subKey, 0, KEY_WRITE, &hkey) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
||||
RegDeleteValue (hkey, name);
|
||||
RegCloseKey (hkey);
|
||||
}
|
||||
|
||||
|
||||
void GetStartupRegKeyName (char *regk)
|
||||
{
|
||||
// The string is split in order to prevent some antivirus packages from falsely reporting
|
||||
// TrueCrypt.exe to contain a possible Trojan horse because of this string (heuristic scan).
|
||||
sprintf (regk, "%s%s", "Software\\Microsoft\\Windows\\Curren", "tVersion\\Run");
|
||||
}
|
||||
32
src/Common/Registry.h
Normal file
32
src/Common/Registry.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright (c) 2004-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
BOOL ReadLocalMachineRegistryDword (char *subKey, char *name, DWORD *value);
|
||||
BOOL ReadLocalMachineRegistryMultiString (char *subKey, char *name, char *value, DWORD *size);
|
||||
BOOL ReadLocalMachineRegistryString (const char *subKey, char *name, char *value, DWORD *size);
|
||||
BOOL ReadLocalMachineRegistryStringNonReflected (const char *subKey, char *name, char *str, DWORD *size);
|
||||
int ReadRegistryInt (char *subKey, char *name, int defaultValue);
|
||||
char *ReadRegistryString (char *subKey, char *name, char *defaultValue, char *str, int maxLen);
|
||||
DWORD ReadRegistryBytes (char *path, char *name, char *value, int maxLen);
|
||||
void WriteRegistryInt (char *subKey, char *name, int value);
|
||||
BOOL WriteLocalMachineRegistryDword (char *subKey, char *name, DWORD value);
|
||||
BOOL WriteLocalMachineRegistryMultiString (char *subKey, char *name, char *multiString, DWORD size);
|
||||
BOOL WriteLocalMachineRegistryString (char *subKey, char *name, char *str, BOOL expandable);
|
||||
void WriteRegistryString (char *subKey, char *name, char *str);
|
||||
BOOL WriteRegistryBytes (char *path, char *name, char *str, DWORD size);
|
||||
BOOL DeleteLocalMachineRegistryKey (char *parentKey, char *subKeyToDelete);
|
||||
void DeleteRegistryValue (char *subKey, char *name);
|
||||
void GetStartupRegKeyName (char *regk);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
174
src/Common/Resource.h
Normal file
174
src/Common/Resource.h
Normal file
@@ -0,0 +1,174 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by Common.rc
|
||||
//
|
||||
#define IDI_TRUECRYPT_ICON 501
|
||||
#define IDI_TRUECRYPT_VOL_ICON 502
|
||||
#define IDD_BENCHMARK_DLG 503
|
||||
#define IDD_MOUNT_OPTIONS 504
|
||||
#define IDD_KEYFILES 505
|
||||
#define IDR_LANGUAGE 506
|
||||
#define IDI_TRUECRYPT 507
|
||||
#define IDD_ABOUT_DLG 508
|
||||
#define IDD_COMMANDHELP_DLG 509
|
||||
#define IDD_RAWDEVICES_DLG 510
|
||||
#define IDC_HOMEPAGE 511
|
||||
#define IDR_COMMON_RSRC_HEADER 512
|
||||
#define IDD_LANGUAGE 513
|
||||
#define IDD_CIPHER_TEST_DLG 514
|
||||
#define IDR_LICENSE 515
|
||||
#define IDD_AUXILIARY_DLG 516
|
||||
#define IDB_TEXTUAL_LOGO_BKG 517
|
||||
#define IDB_TEXTUAL_LOGO_96DPI 518
|
||||
#define IDB_TEXTUAL_LOGO_288DPI 519
|
||||
#define IDR_BOOT_SECTOR 520
|
||||
#define IDR_BOOT_SECTOR_AES 521
|
||||
#define IDR_BOOT_SECTOR_SERPENT 522
|
||||
#define IDR_BOOT_SECTOR_TWOFISH 523
|
||||
#define IDR_BOOT_LOADER_DECOMPRESSOR 524
|
||||
#define IDR_BOOT_LOADER 525
|
||||
#define IDR_BOOT_LOADER_AES 526
|
||||
#define IDR_BOOT_LOADER_SERPENT 527
|
||||
#define IDR_BOOT_LOADER_TWOFISH 528
|
||||
#define IDR_RESCUE_BOOT_SECTOR 529
|
||||
#define IDR_RESCUE_BOOT_SECTOR_AES 530
|
||||
#define IDR_RESCUE_BOOT_SECTOR_SERPENT 531
|
||||
#define IDR_RESCUE_BOOT_SECTOR_TWOFISH 532
|
||||
#define IDR_RESCUE_LOADER 533
|
||||
#define IDR_RESCUE_LOADER_AES 534
|
||||
#define IDR_RESCUE_LOADER_SERPENT 535
|
||||
#define IDR_RESCUE_LOADER_TWOFISH 536
|
||||
#define IDD_TOKEN_PASSWORD 537
|
||||
#define IDD_TOKEN_KEYFILES 538
|
||||
#define IDD_NEW_TOKEN_KEYFILE 539
|
||||
#define IDD_RANDOM_POOL_ENRICHMENT 540
|
||||
#define IDI_TRUECRYPT_MOUNTED_ICON 541
|
||||
#define IDC_HW_AES_LABEL_LINK 5000
|
||||
#define IDC_HW_AES 5001
|
||||
#define IDC_PARALLELIZATION_LABEL_LINK 5002
|
||||
#define IDC_PARALLELIZATION 5003
|
||||
#define IDT_TOKEN_PASSWORD 5004
|
||||
#define IDC_PRINT 5005
|
||||
#define IDC_KEY 5006
|
||||
#define IDC_PLAINTEXT 5007
|
||||
#define IDC_CIPHERTEXT 5008
|
||||
#define IDC_INFO_BOX_TEXT 5009
|
||||
#define IDC_SECONDARY_KEY 5010
|
||||
#define IDD_TEXT_INFO_DIALOG_BOX_DLG 5011
|
||||
#define IDC_TEST_DATA_UNIT_NUMBER 5012
|
||||
#define IDD_KEYFILE_GENERATOR 5013
|
||||
#define IDC_CIPHER 5014
|
||||
#define IDD_MULTI_CHOICE_DLG 5015
|
||||
#define IDC_TEST_BLOCK_NUMBER 5016
|
||||
#define IDD_STATIC_MODELESS_WAIT_DLG 5017
|
||||
#define IDC_POOL_CONTENTS 5018
|
||||
#define IDC_PRF_ID 5019
|
||||
#define IDC_KEY_SIZE 5020
|
||||
#define IDC_PLAINTEXT_SIZE 5021
|
||||
#define IDC_REDTICK 5022
|
||||
#define IDC_TESTS_MESSAGE 5023
|
||||
#define IDC_RESET 5024
|
||||
#define IDC_AUTO 5025
|
||||
#define IDC_DECRYPT 5026
|
||||
#define IDT_TEST_KEY 5027
|
||||
#define IDT_TEST_PLAINTEXT 5028
|
||||
#define IDT_PRF 5029
|
||||
#define IDT_XTS_MODE 5030
|
||||
#define IDT_TEST_CIPHERTEXT 5031
|
||||
#define IDT_KEY 5032
|
||||
#define IDT_PLAINTEXT 5033
|
||||
#define IDC_ENCRYPT 5034
|
||||
#define IDT_KEY_UNIT 5035
|
||||
#define IDT_CIPHER 5036
|
||||
#define IDT_PLAINTEXT_SIZE_UNIT 5037
|
||||
#define IDC_DEVICELIST 5038
|
||||
#define IDT_TEST_BLOCK_NUMBER 5039
|
||||
#define IDT_SECONDARY_KEY 5040
|
||||
#define IDC_PERFORM_BENCHMARK 5041
|
||||
#define IDT_TEST_DATA_UNIT_NUMBER 5042
|
||||
#define IDC_KEYFILES_HIDVOL_PROT 5043
|
||||
#define IDC_KEYLIST 5044
|
||||
#define IDC_ABOUT_BKG 5045
|
||||
#define IDT_ABOUT_VERSION 5046
|
||||
#define IDT_BOX_BENCHMARK_INFO 5047
|
||||
#define IDC_ABOUT_CREDITS 5048
|
||||
#define IDT_SORT_METHOD 5049
|
||||
#define IDC_MOUNT_READONLY 5050
|
||||
#define IDC_MOUNT_REMOVABLE 5051
|
||||
#define IDC_PROTECT_HIDDEN_VOL 5052
|
||||
#define IDC_COMMANDHELP_TEXT 5053
|
||||
#define IDC_USE_EMBEDDED_HEADER_BAK 5054
|
||||
#define IDC_MOUNT_SYSENC_PART_WITHOUT_PBA 5055
|
||||
#define IDT_HIDDEN_PROT_PASSWD 5056
|
||||
#define IDC_RESULTS 5057
|
||||
#define IDC_KEYADD 5058
|
||||
#define IDC_KEYREMOVE 5059
|
||||
#define IDC_KEYREMOVEALL 5060
|
||||
#define IDC_KEYFILES_ENABLE 5061
|
||||
#define IDT_HIDDEN_VOL_PROTECTION 5062
|
||||
#define IDC_ADD_KEYFILE_PATH 5063
|
||||
#define IDC_BENCHMARK_BUFFER_SIZE 5064
|
||||
#define IDC_SHOW_PASSWORD_MO 5065
|
||||
#define IDC_GENERATE_KEYFILE 5066
|
||||
#define IDC_BENCHMARK_SORT_METHOD 5067
|
||||
#define IDC_PASSWORD_PROT_HIDVOL 5068
|
||||
#define IDT_BUFFER_SIZE 5069
|
||||
#define IDC_LANGLIST 5070
|
||||
#define IDC_KEYFILES_ENABLE_HIDVOL_PROT 5071
|
||||
#define IDT_KEYFILES_NOTE 5072
|
||||
#define IDT_KEYFILE_WARNING 5073
|
||||
#define IDT_KEYFILE_GENERATOR_NOTE 5074
|
||||
#define IDC_GENERATE_AND_SAVE_KEYFILE 5075
|
||||
#define IDT_POOL_CONTENTS 5076
|
||||
#define IDC_GET_LANG_PACKS 5077
|
||||
#define IDT_LANGPACK_AUTHORS 5078
|
||||
#define IDC_LANGPACK_CREDITS 5079
|
||||
#define IDC_LANGPACK_VERSION 5080
|
||||
#define IDT_ACTIVE_LANG_PACK 5081
|
||||
#define IDC_DISPLAY_POOL_CONTENTS 5082
|
||||
#define IDC_XTS_MODE_ENABLED 5083
|
||||
#define IDC_MULTI_CHOICE_MSG 5084
|
||||
#define IDC_CHOICE1 5085
|
||||
#define IDC_CHOICE5 5086
|
||||
#define IDC_CHOICE2 5087
|
||||
#define IDC_CHOICE3 5088
|
||||
#define IDC_CHOICE4 5089
|
||||
#define IDC_CHOICE6 5090
|
||||
#define IDC_CHOICE7 5091
|
||||
#define IDC_CHOICE8 5092
|
||||
#define IDC_CHOICE9 5093
|
||||
#define IDC_CHOICE10 5094
|
||||
#define IDC_MC_DLG_HR1 5095
|
||||
#define IDC_MC_DLG_HR2 5096
|
||||
#define IDC_LINK_HIDVOL_PROTECTION_INFO 5097
|
||||
#define IDC_LINK_KEYFILES_INFO 5098
|
||||
#define IDC_TEXTUAL_LOGO_IMG 5099
|
||||
#define IDC_ASPECT_RATIO_CALIBRATION_BOX 5100
|
||||
#define IDC_ABOUT_LOGO_AREA 5101
|
||||
#define IDC_TOKEN_PASSWORD 5102
|
||||
#define IDC_TOKEN_FILE_LIST 5103
|
||||
#define IDC_TOKEN_FILES_ADD 5104
|
||||
#define IDC_EXPORT 5105
|
||||
#define IDC_DELETE 5106
|
||||
#define IDC_IMPORT_KEYFILE 5107
|
||||
#define IDC_SELECTED_TOKEN 5108
|
||||
#define IDT_SECURITY_TOKEN 5109
|
||||
#define IDT_TOKEN_KEYFILE_NAME 5110
|
||||
#define IDC_TOKEN_KEYFILE_NAME 5111
|
||||
#define IDT_TOKEN_PASSWORD_INFO 5112
|
||||
#define IDT_RANDOM_POOL_ENRICHMENT_NOTE 5113
|
||||
#define IDC_CONTINUE 5114
|
||||
#define IDT_ABOUT_RELEASE 5115
|
||||
#define IDT_STATIC_MODELESS_WAIT_DLG_INFO 5116
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 542
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 5117
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
761
src/Common/SecurityToken.cpp
Normal file
761
src/Common/SecurityToken.cpp
Normal file
@@ -0,0 +1,761 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Platform/Finally.h"
|
||||
#include "Platform/ForEach.h"
|
||||
|
||||
#if !defined (TC_WINDOWS) || defined (TC_PROTOTYPE)
|
||||
# include "Platform/SerializerFactory.h"
|
||||
# include "Platform/StringConverter.h"
|
||||
# include "Platform/SystemException.h"
|
||||
#else
|
||||
# include "Dictionary.h"
|
||||
# include "Language.h"
|
||||
#endif
|
||||
|
||||
#ifdef TC_UNIX
|
||||
# include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "SecurityToken.h"
|
||||
|
||||
#ifndef burn
|
||||
# define burn Memory::Erase
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path)
|
||||
{
|
||||
wstring pathStr = path;
|
||||
unsigned long slotId;
|
||||
|
||||
if (swscanf (pathStr.c_str(), TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1)
|
||||
throw InvalidSecurityTokenKeyfilePath();
|
||||
|
||||
SlotId = slotId;
|
||||
|
||||
size_t keyIdPos = pathStr.find (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/");
|
||||
if (keyIdPos == string::npos)
|
||||
throw InvalidSecurityTokenKeyfilePath();
|
||||
|
||||
Id = pathStr.substr (keyIdPos + wstring (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size());
|
||||
|
||||
vector <SecurityTokenKeyfile> keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id);
|
||||
|
||||
if (keyfiles.empty())
|
||||
throw SecurityTokenKeyfileNotFound();
|
||||
|
||||
*this = keyfiles.front();
|
||||
}
|
||||
|
||||
SecurityTokenKeyfile::operator SecurityTokenKeyfilePath () const
|
||||
{
|
||||
wstringstream path;
|
||||
path << TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/" << SlotId << L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/" << Id;
|
||||
return path.str();
|
||||
}
|
||||
|
||||
void SecurityToken::CheckLibraryStatus ()
|
||||
{
|
||||
if (!Initialized)
|
||||
throw SecurityTokenLibraryNotInitialized();
|
||||
}
|
||||
|
||||
void SecurityToken::CloseLibrary ()
|
||||
{
|
||||
if (Initialized)
|
||||
{
|
||||
CloseAllSessions();
|
||||
Pkcs11Functions->C_Finalize (NULL_PTR);
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
FreeLibrary (Pkcs11LibraryHandle);
|
||||
#else
|
||||
dlclose (Pkcs11LibraryHandle);
|
||||
#endif
|
||||
Initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::CloseAllSessions () throw ()
|
||||
{
|
||||
if (!Initialized)
|
||||
return;
|
||||
|
||||
typedef pair <CK_SLOT_ID, Pkcs11Session> SessionMapPair;
|
||||
|
||||
foreach (SessionMapPair p, Sessions)
|
||||
{
|
||||
try
|
||||
{
|
||||
CloseSession (p.first);
|
||||
}
|
||||
catch (...) { }
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::CloseSession (CK_SLOT_ID slotId)
|
||||
{
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
Pkcs11Functions->C_CloseSession (Sessions[slotId].Handle);
|
||||
Sessions.erase (Sessions.find (slotId));
|
||||
}
|
||||
|
||||
void SecurityToken::CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name)
|
||||
{
|
||||
if (name.empty())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
LoginUserIfRequired (slotId);
|
||||
|
||||
foreach (const SecurityTokenKeyfile &keyfile, GetAvailableKeyfiles (&slotId))
|
||||
{
|
||||
if (keyfile.IdUtf8 == name)
|
||||
throw SecurityTokenKeyfileAlreadyExists();
|
||||
}
|
||||
|
||||
CK_OBJECT_CLASS dataClass = CKO_DATA;
|
||||
CK_BBOOL trueVal = CK_TRUE;
|
||||
|
||||
CK_ATTRIBUTE keyfileTemplate[] =
|
||||
{
|
||||
{ CKA_CLASS, &dataClass, sizeof (dataClass) },
|
||||
{ CKA_TOKEN, &trueVal, sizeof (trueVal) },
|
||||
{ CKA_PRIVATE, &trueVal, sizeof (trueVal) },
|
||||
{ CKA_LABEL, (CK_UTF8CHAR *) name.c_str(), name.size() },
|
||||
{ CKA_VALUE, &keyfileData.front(), keyfileData.size() }
|
||||
};
|
||||
|
||||
CK_OBJECT_HANDLE keyfileHandle;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_CreateObject (Sessions[slotId].Handle, keyfileTemplate, array_capacity (keyfileTemplate), &keyfileHandle);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case CKR_DATA_LEN_RANGE:
|
||||
status = CKR_DEVICE_MEMORY;
|
||||
break;
|
||||
|
||||
case CKR_SESSION_READ_ONLY:
|
||||
status = CKR_TOKEN_WRITE_PROTECTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
// Some tokens report success even if the new object was truncated to fit in the available memory
|
||||
vector <byte> objectData;
|
||||
|
||||
GetObjectAttribute (slotId, keyfileHandle, CKA_VALUE, objectData);
|
||||
finally_do_arg (vector <byte> *, &objectData, { if (!finally_arg->empty()) burn (&finally_arg->front(), finally_arg->size()); });
|
||||
|
||||
if (objectData.size() != keyfileData.size())
|
||||
{
|
||||
Pkcs11Functions->C_DestroyObject (Sessions[slotId].Handle, keyfileHandle);
|
||||
throw Pkcs11Exception (CKR_DEVICE_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::DeleteKeyfile (const SecurityTokenKeyfile &keyfile)
|
||||
{
|
||||
LoginUserIfRequired (keyfile.SlotId);
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_DestroyObject (Sessions[keyfile.SlotId].Handle, keyfile.Handle);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
}
|
||||
|
||||
vector <SecurityTokenKeyfile> SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter)
|
||||
{
|
||||
bool unrecognizedTokenPresent = false;
|
||||
vector <SecurityTokenKeyfile> keyfiles;
|
||||
|
||||
foreach (const CK_SLOT_ID &slotId, GetTokenSlots())
|
||||
{
|
||||
SecurityTokenInfo token;
|
||||
|
||||
if (slotIdFilter && *slotIdFilter != slotId)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
LoginUserIfRequired (slotId);
|
||||
token = GetTokenInfo (slotId);
|
||||
}
|
||||
catch (UserAbort &)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
catch (Pkcs11Exception &e)
|
||||
{
|
||||
if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED)
|
||||
{
|
||||
unrecognizedTokenPresent = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
foreach (const CK_OBJECT_HANDLE &dataHandle, GetObjects (slotId, CKO_DATA))
|
||||
{
|
||||
SecurityTokenKeyfile keyfile;
|
||||
keyfile.Handle = dataHandle;
|
||||
keyfile.SlotId = slotId;
|
||||
keyfile.Token = token;
|
||||
|
||||
vector <byte> privateAttrib;
|
||||
GetObjectAttribute (slotId, dataHandle, CKA_PRIVATE, privateAttrib);
|
||||
|
||||
if (privateAttrib.size() == sizeof (CK_BBOOL) && *(CK_BBOOL *) &privateAttrib.front() != CK_TRUE)
|
||||
continue;
|
||||
|
||||
vector <byte> label;
|
||||
GetObjectAttribute (slotId, dataHandle, CKA_LABEL, label);
|
||||
label.push_back (0);
|
||||
|
||||
keyfile.IdUtf8 = (char *) &label.front();
|
||||
|
||||
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
|
||||
keyfile.Id = Utf8StringToWide ((const char *) &label.front());
|
||||
#else
|
||||
keyfile.Id = StringConverter::ToWide ((const char *) &label.front());
|
||||
#endif
|
||||
if (keyfile.Id.empty() || (!keyfileIdFilter.empty() && keyfileIdFilter != keyfile.Id))
|
||||
continue;
|
||||
|
||||
keyfiles.push_back (keyfile);
|
||||
|
||||
if (!keyfileIdFilter.empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyfiles.empty() && unrecognizedTokenPresent)
|
||||
throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED);
|
||||
|
||||
return keyfiles;
|
||||
}
|
||||
|
||||
list <SecurityTokenInfo> SecurityToken::GetAvailableTokens ()
|
||||
{
|
||||
bool unrecognizedTokenPresent = false;
|
||||
list <SecurityTokenInfo> tokens;
|
||||
|
||||
foreach (const CK_SLOT_ID &slotId, GetTokenSlots())
|
||||
{
|
||||
try
|
||||
{
|
||||
tokens.push_back (GetTokenInfo (slotId));
|
||||
}
|
||||
catch (Pkcs11Exception &e)
|
||||
{
|
||||
if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED)
|
||||
{
|
||||
unrecognizedTokenPresent = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (tokens.empty() && unrecognizedTokenPresent)
|
||||
throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED);
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
SecurityTokenInfo SecurityToken::GetTokenInfo (CK_SLOT_ID slotId)
|
||||
{
|
||||
CK_TOKEN_INFO info;
|
||||
CK_RV status = Pkcs11Functions->C_GetTokenInfo (slotId, &info);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
SecurityTokenInfo token;
|
||||
token.SlotId = slotId;
|
||||
token.Flags = info.flags;
|
||||
|
||||
char label[sizeof (info.label) + 1];
|
||||
memset (label, 0, sizeof (label));
|
||||
memcpy (label, info.label, sizeof (info.label));
|
||||
|
||||
token.LabelUtf8 = label;
|
||||
|
||||
size_t lastSpace = token.LabelUtf8.find_last_not_of (' ');
|
||||
if (lastSpace == string::npos)
|
||||
token.LabelUtf8.clear();
|
||||
else
|
||||
token.LabelUtf8 = token.LabelUtf8.substr (0, lastSpace + 1);
|
||||
|
||||
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
|
||||
token.Label = Utf8StringToWide (token.LabelUtf8);
|
||||
#else
|
||||
token.Label = StringConverter::ToWide (token.LabelUtf8);
|
||||
#endif
|
||||
return token;
|
||||
}
|
||||
|
||||
void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData)
|
||||
{
|
||||
LoginUserIfRequired (keyfile.SlotId);
|
||||
GetObjectAttribute (keyfile.SlotId, keyfile.Handle, CKA_VALUE, keyfileData);
|
||||
}
|
||||
|
||||
vector <CK_OBJECT_HANDLE> SecurityToken::GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass)
|
||||
{
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
CK_ATTRIBUTE findTemplate;
|
||||
findTemplate.type = CKA_CLASS;
|
||||
findTemplate.pValue = &objectClass;
|
||||
findTemplate.ulValueLen = sizeof (objectClass);
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_FindObjectsInit (Sessions[slotId].Handle, &findTemplate, 1);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
finally_do_arg (CK_SLOT_ID, slotId, { Pkcs11Functions->C_FindObjectsFinal (Sessions[finally_arg].Handle); });
|
||||
|
||||
CK_ULONG objectCount;
|
||||
vector <CK_OBJECT_HANDLE> objects;
|
||||
|
||||
while (true)
|
||||
{
|
||||
CK_OBJECT_HANDLE object;
|
||||
CK_RV status = Pkcs11Functions->C_FindObjects (Sessions[slotId].Handle, &object, 1, &objectCount);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
if (objectCount != 1)
|
||||
break;
|
||||
|
||||
objects.push_back (object);
|
||||
}
|
||||
|
||||
return objects;
|
||||
}
|
||||
|
||||
void SecurityToken::GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue)
|
||||
{
|
||||
attributeValue.clear();
|
||||
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
CK_ATTRIBUTE attribute;
|
||||
attribute.type = attributeType;
|
||||
attribute.pValue = NULL_PTR;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
if (attribute.ulValueLen == 0)
|
||||
return;
|
||||
|
||||
attributeValue = vector <byte> (attribute.ulValueLen);
|
||||
attribute.pValue = &attributeValue.front();
|
||||
|
||||
status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
}
|
||||
|
||||
list <CK_SLOT_ID> SecurityToken::GetTokenSlots ()
|
||||
{
|
||||
CheckLibraryStatus();
|
||||
|
||||
list <CK_SLOT_ID> slots;
|
||||
CK_ULONG slotCount;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_GetSlotList (TRUE, NULL_PTR, &slotCount);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
if (slotCount > 0)
|
||||
{
|
||||
vector <CK_SLOT_ID> slotArray (slotCount);
|
||||
status = Pkcs11Functions->C_GetSlotList (TRUE, &slotArray.front(), &slotCount);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
for (size_t i = 0; i < slotCount; i++)
|
||||
{
|
||||
CK_SLOT_INFO slotInfo;
|
||||
status = Pkcs11Functions->C_GetSlotInfo (slotArray[i], &slotInfo);
|
||||
|
||||
if (status != CKR_OK || !(slotInfo.flags & CKF_TOKEN_PRESENT))
|
||||
continue;
|
||||
|
||||
slots.push_back (slotArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
bool SecurityToken::IsKeyfilePathValid (const wstring &securityTokenKeyfilePath)
|
||||
{
|
||||
return securityTokenKeyfilePath.find (TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0;
|
||||
}
|
||||
|
||||
void SecurityToken::Login (CK_SLOT_ID slotId, const string &pin)
|
||||
{
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
OpenSession (slotId);
|
||||
else if (Sessions[slotId].UserLoggedIn)
|
||||
return;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, (CK_CHAR_PTR) pin.c_str(), pin.size());
|
||||
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
Sessions[slotId].UserLoggedIn = true;
|
||||
}
|
||||
|
||||
void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId)
|
||||
{
|
||||
CheckLibraryStatus();
|
||||
CK_RV status;
|
||||
|
||||
if (Sessions.find (slotId) == Sessions.end())
|
||||
{
|
||||
OpenSession (slotId);
|
||||
}
|
||||
else
|
||||
{
|
||||
CK_SESSION_INFO sessionInfo;
|
||||
status = Pkcs11Functions->C_GetSessionInfo (Sessions[slotId].Handle, &sessionInfo);
|
||||
|
||||
if (status == CKR_OK)
|
||||
{
|
||||
Sessions[slotId].UserLoggedIn = (sessionInfo.state == CKS_RO_USER_FUNCTIONS || sessionInfo.state == CKS_RW_USER_FUNCTIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
CloseSession (slotId);
|
||||
}
|
||||
catch (...) { }
|
||||
OpenSession (slotId);
|
||||
}
|
||||
}
|
||||
|
||||
SecurityTokenInfo tokenInfo = GetTokenInfo (slotId);
|
||||
|
||||
while (!Sessions[slotId].UserLoggedIn && (tokenInfo.Flags & CKF_LOGIN_REQUIRED))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||
{
|
||||
status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, NULL_PTR, 0);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
}
|
||||
else
|
||||
{
|
||||
string pin = tokenInfo.LabelUtf8;
|
||||
if (tokenInfo.Label.empty())
|
||||
{
|
||||
stringstream s;
|
||||
s << "#" << slotId;
|
||||
pin = s.str();
|
||||
}
|
||||
|
||||
finally_do_arg (string*, &pin, { burn ((void *) finally_arg->c_str(), finally_arg->size()); });
|
||||
|
||||
(*PinCallback) (pin);
|
||||
Login (slotId, pin);
|
||||
}
|
||||
|
||||
Sessions[slotId].UserLoggedIn = true;
|
||||
}
|
||||
catch (Pkcs11Exception &e)
|
||||
{
|
||||
CK_RV error = e.GetErrorCode();
|
||||
|
||||
if (error == CKR_USER_ALREADY_LOGGED_IN)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (error == CKR_PIN_INCORRECT && !(tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH))
|
||||
{
|
||||
(*WarningCallback) (Pkcs11Exception (CKR_PIN_INCORRECT));
|
||||
continue;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SecurityToken::InitLibrary (const string &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback)
|
||||
{
|
||||
if (Initialized)
|
||||
CloseLibrary();
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
Pkcs11LibraryHandle = LoadLibraryA (pkcs11LibraryPath.c_str());
|
||||
#else
|
||||
Pkcs11LibraryHandle = dlopen (pkcs11LibraryPath.c_str(), RTLD_NOW | RTLD_LOCAL);
|
||||
#endif
|
||||
throw_sys_if (!Pkcs11LibraryHandle);
|
||||
|
||||
typedef CK_RV (*C_GetFunctionList_t) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
|
||||
#ifdef TC_WINDOWS
|
||||
C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) GetProcAddress (Pkcs11LibraryHandle, "C_GetFunctionList");
|
||||
#else
|
||||
C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) dlsym (Pkcs11LibraryHandle, "C_GetFunctionList");
|
||||
#endif
|
||||
|
||||
if (!C_GetFunctionList)
|
||||
throw SecurityTokenLibraryNotInitialized();
|
||||
|
||||
CK_RV status = C_GetFunctionList (&Pkcs11Functions);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
status = Pkcs11Functions->C_Initialize (NULL_PTR);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
PinCallback = pinCallback;
|
||||
WarningCallback = warningCallback;
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
void SecurityToken::OpenSession (CK_SLOT_ID slotId)
|
||||
{
|
||||
if (Sessions.find (slotId) != Sessions.end())
|
||||
return;
|
||||
|
||||
CK_SESSION_HANDLE session;
|
||||
|
||||
CK_FLAGS flags = CKF_SERIAL_SESSION;
|
||||
|
||||
if (!(GetTokenInfo (slotId).Flags & CKF_WRITE_PROTECTED))
|
||||
flags |= CKF_RW_SESSION;
|
||||
|
||||
CK_RV status = Pkcs11Functions->C_OpenSession (slotId, flags, NULL_PTR, NULL_PTR, &session);
|
||||
if (status != CKR_OK)
|
||||
throw Pkcs11Exception (status);
|
||||
|
||||
Sessions[slotId].Handle = session;
|
||||
}
|
||||
|
||||
Pkcs11Exception::operator string () const
|
||||
{
|
||||
if (ErrorCode == CKR_OK)
|
||||
return string();
|
||||
|
||||
static const struct
|
||||
{
|
||||
CK_RV ErrorCode;
|
||||
const char *ErrorString;
|
||||
} ErrorStrings[] =
|
||||
{
|
||||
# define TC_TOKEN_ERR(CODE) { CODE, #CODE },
|
||||
|
||||
TC_TOKEN_ERR (CKR_CANCEL)
|
||||
TC_TOKEN_ERR (CKR_HOST_MEMORY)
|
||||
TC_TOKEN_ERR (CKR_SLOT_ID_INVALID)
|
||||
TC_TOKEN_ERR (CKR_GENERAL_ERROR)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_FAILED)
|
||||
TC_TOKEN_ERR (CKR_ARGUMENTS_BAD)
|
||||
TC_TOKEN_ERR (CKR_NO_EVENT)
|
||||
TC_TOKEN_ERR (CKR_NEED_TO_CREATE_THREADS)
|
||||
TC_TOKEN_ERR (CKR_CANT_LOCK)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_READ_ONLY)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_SENSITIVE)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_TYPE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_ATTRIBUTE_VALUE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_DATA_INVALID)
|
||||
TC_TOKEN_ERR (CKR_DATA_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_DEVICE_ERROR)
|
||||
TC_TOKEN_ERR (CKR_DEVICE_MEMORY)
|
||||
TC_TOKEN_ERR (CKR_DEVICE_REMOVED)
|
||||
TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_INVALID)
|
||||
TC_TOKEN_ERR (CKR_ENCRYPTED_DATA_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_CANCELED)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_NOT_PARALLEL)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_NOT_SUPPORTED)
|
||||
TC_TOKEN_ERR (CKR_KEY_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_KEY_SIZE_RANGE)
|
||||
TC_TOKEN_ERR (CKR_KEY_TYPE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_KEY_NOT_NEEDED)
|
||||
TC_TOKEN_ERR (CKR_KEY_CHANGED)
|
||||
TC_TOKEN_ERR (CKR_KEY_NEEDED)
|
||||
TC_TOKEN_ERR (CKR_KEY_INDIGESTIBLE)
|
||||
TC_TOKEN_ERR (CKR_KEY_FUNCTION_NOT_PERMITTED)
|
||||
TC_TOKEN_ERR (CKR_KEY_NOT_WRAPPABLE)
|
||||
TC_TOKEN_ERR (CKR_KEY_UNEXTRACTABLE)
|
||||
TC_TOKEN_ERR (CKR_MECHANISM_INVALID)
|
||||
TC_TOKEN_ERR (CKR_MECHANISM_PARAM_INVALID)
|
||||
TC_TOKEN_ERR (CKR_OBJECT_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_OPERATION_ACTIVE)
|
||||
TC_TOKEN_ERR (CKR_OPERATION_NOT_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_PIN_INCORRECT)
|
||||
TC_TOKEN_ERR (CKR_PIN_INVALID)
|
||||
TC_TOKEN_ERR (CKR_PIN_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_PIN_EXPIRED)
|
||||
TC_TOKEN_ERR (CKR_PIN_LOCKED)
|
||||
TC_TOKEN_ERR (CKR_SESSION_CLOSED)
|
||||
TC_TOKEN_ERR (CKR_SESSION_COUNT)
|
||||
TC_TOKEN_ERR (CKR_SESSION_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_SESSION_PARALLEL_NOT_SUPPORTED)
|
||||
TC_TOKEN_ERR (CKR_SESSION_READ_ONLY)
|
||||
TC_TOKEN_ERR (CKR_SESSION_EXISTS)
|
||||
TC_TOKEN_ERR (CKR_SESSION_READ_ONLY_EXISTS)
|
||||
TC_TOKEN_ERR (CKR_SESSION_READ_WRITE_SO_EXISTS)
|
||||
TC_TOKEN_ERR (CKR_SIGNATURE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_SIGNATURE_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_TEMPLATE_INCOMPLETE)
|
||||
TC_TOKEN_ERR (CKR_TEMPLATE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_TOKEN_NOT_PRESENT)
|
||||
TC_TOKEN_ERR (CKR_TOKEN_NOT_RECOGNIZED)
|
||||
TC_TOKEN_ERR (CKR_TOKEN_WRITE_PROTECTED)
|
||||
TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_SIZE_RANGE)
|
||||
TC_TOKEN_ERR (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_USER_ALREADY_LOGGED_IN)
|
||||
TC_TOKEN_ERR (CKR_USER_NOT_LOGGED_IN)
|
||||
TC_TOKEN_ERR (CKR_USER_PIN_NOT_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_USER_TYPE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
|
||||
TC_TOKEN_ERR (CKR_USER_TOO_MANY_TYPES)
|
||||
TC_TOKEN_ERR (CKR_WRAPPED_KEY_INVALID)
|
||||
TC_TOKEN_ERR (CKR_WRAPPED_KEY_LEN_RANGE)
|
||||
TC_TOKEN_ERR (CKR_WRAPPING_KEY_HANDLE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_WRAPPING_KEY_SIZE_RANGE)
|
||||
TC_TOKEN_ERR (CKR_WRAPPING_KEY_TYPE_INCONSISTENT)
|
||||
TC_TOKEN_ERR (CKR_RANDOM_SEED_NOT_SUPPORTED)
|
||||
TC_TOKEN_ERR (CKR_RANDOM_NO_RNG)
|
||||
TC_TOKEN_ERR (CKR_DOMAIN_PARAMS_INVALID)
|
||||
TC_TOKEN_ERR (CKR_BUFFER_TOO_SMALL)
|
||||
TC_TOKEN_ERR (CKR_SAVED_STATE_INVALID)
|
||||
TC_TOKEN_ERR (CKR_INFORMATION_SENSITIVE)
|
||||
TC_TOKEN_ERR (CKR_STATE_UNSAVEABLE)
|
||||
TC_TOKEN_ERR (CKR_CRYPTOKI_NOT_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_CRYPTOKI_ALREADY_INITIALIZED)
|
||||
TC_TOKEN_ERR (CKR_MUTEX_BAD)
|
||||
TC_TOKEN_ERR (CKR_MUTEX_NOT_LOCKED)
|
||||
TC_TOKEN_ERR (CKR_NEW_PIN_MODE)
|
||||
TC_TOKEN_ERR (CKR_NEXT_OTP)
|
||||
TC_TOKEN_ERR (CKR_FUNCTION_REJECTED)
|
||||
|
||||
#undef TC_TOKEN_ERR
|
||||
};
|
||||
|
||||
|
||||
for (size_t i = 0; i < array_capacity (ErrorStrings); ++i)
|
||||
{
|
||||
if (ErrorStrings[i].ErrorCode == ErrorCode)
|
||||
return ErrorStrings[i].ErrorString;
|
||||
}
|
||||
|
||||
stringstream s;
|
||||
s << "0x" << hex << ErrorCode;
|
||||
return s.str();
|
||||
|
||||
}
|
||||
|
||||
#ifdef TC_HEADER_Common_Exception
|
||||
void Pkcs11Exception::Show (HWND parent) const
|
||||
{
|
||||
string errorString = string (*this);
|
||||
|
||||
if (!errorString.empty())
|
||||
{
|
||||
wstringstream subjectErrorCode;
|
||||
if (SubjectErrorCodeValid)
|
||||
subjectErrorCode << L": " << SubjectErrorCode;
|
||||
|
||||
if (!GetDictionaryValue (errorString.c_str()))
|
||||
{
|
||||
if (errorString.find ("CKR_") == 0)
|
||||
{
|
||||
errorString = errorString.substr (4);
|
||||
for (size_t i = 0; i < errorString.size(); ++i)
|
||||
{
|
||||
if (errorString[i] == '_')
|
||||
errorString[i] = ' ';
|
||||
}
|
||||
}
|
||||
wchar_t err[8192];
|
||||
wsprintfW (err, L"%s:\n\n%hs%s", GetString ("SECURITY_TOKEN_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str());
|
||||
ErrorDirect (err);
|
||||
}
|
||||
else
|
||||
{
|
||||
wstring err = GetString (errorString.c_str());
|
||||
|
||||
if (SubjectErrorCodeValid)
|
||||
err += L"\n\nError code" + subjectErrorCode.str();
|
||||
|
||||
ErrorDirect (err.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // TC_HEADER_Common_Exception
|
||||
|
||||
auto_ptr <GetPinFunctor> SecurityToken::PinCallback;
|
||||
auto_ptr <SendExceptionFunctor> SecurityToken::WarningCallback;
|
||||
|
||||
bool SecurityToken::Initialized;
|
||||
CK_FUNCTION_LIST_PTR SecurityToken::Pkcs11Functions;
|
||||
map <CK_SLOT_ID, Pkcs11Session> SecurityToken::Sessions;
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
HMODULE SecurityToken::Pkcs11LibraryHandle;
|
||||
#else
|
||||
void *SecurityToken::Pkcs11LibraryHandle;
|
||||
#endif
|
||||
|
||||
#ifdef TC_HEADER_Platform_Exception
|
||||
|
||||
void Pkcs11Exception::Deserialize (shared_ptr <Stream> stream)
|
||||
{
|
||||
Exception::Deserialize (stream);
|
||||
Serializer sr (stream);
|
||||
uint64 code;
|
||||
sr.Deserialize ("ErrorCode", code);
|
||||
sr.Deserialize ("SubjectErrorCodeValid", SubjectErrorCodeValid);
|
||||
sr.Deserialize ("SubjectErrorCode", SubjectErrorCode);
|
||||
ErrorCode = (CK_RV) code;
|
||||
}
|
||||
|
||||
void Pkcs11Exception::Serialize (shared_ptr <Stream> stream) const
|
||||
{
|
||||
Exception::Serialize (stream);
|
||||
Serializer sr (stream);
|
||||
sr.Serialize ("ErrorCode", (uint64) ErrorCode);
|
||||
sr.Serialize ("SubjectErrorCodeValid", SubjectErrorCodeValid);
|
||||
sr.Serialize ("SubjectErrorCode", SubjectErrorCode);
|
||||
}
|
||||
|
||||
# define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
# undef TC_EXCEPTION_NODECL
|
||||
# define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE)
|
||||
|
||||
TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SecurityTokenException);
|
||||
|
||||
#endif
|
||||
}
|
||||
216
src/Common/SecurityToken.h
Normal file
216
src/Common/SecurityToken.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_SecurityToken
|
||||
#define TC_HEADER_Common_SecurityToken
|
||||
|
||||
#include "Platform/PlatformBase.h"
|
||||
#if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE)
|
||||
# include "Exception.h"
|
||||
#else
|
||||
# include "Platform/Exception.h"
|
||||
#endif
|
||||
|
||||
#ifndef NULL_PTR
|
||||
# define NULL_PTR 0
|
||||
#endif
|
||||
#define CK_PTR *
|
||||
#define CK_CALLBACK_FUNCTION(RET_TYPE, NAME) RET_TYPE (* NAME)
|
||||
|
||||
#ifdef TC_WINDOWS
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# define CK_DEFINE_FUNCTION(RET_TYPE, NAME) RET_TYPE __declspec(dllexport) NAME
|
||||
# define CK_DECLARE_FUNCTION(RET_TYPE, NAME) RET_TYPE __declspec(dllimport) NAME
|
||||
# define CK_DECLARE_FUNCTION_POINTER(RET_TYPE, NAME) RET_TYPE __declspec(dllimport) (* NAME)
|
||||
|
||||
# pragma pack(push, cryptoki, 1)
|
||||
# include <pkcs11.h>
|
||||
# pragma pack(pop, cryptoki)
|
||||
|
||||
#else // !TC_WINDOWS
|
||||
|
||||
# define CK_DEFINE_FUNCTION(RET_TYPE, NAME) RET_TYPE NAME
|
||||
# define CK_DECLARE_FUNCTION(RET_TYPE, NAME) RET_TYPE NAME
|
||||
# define CK_DECLARE_FUNCTION_POINTER(RET_TYPE, NAME) RET_TYPE (* NAME)
|
||||
|
||||
# include <pkcs11.h>
|
||||
|
||||
#endif // !TC_WINDOWS
|
||||
|
||||
|
||||
#define TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX L"token://"
|
||||
#define TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"slot"
|
||||
#define TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"file"
|
||||
|
||||
namespace TrueCrypt
|
||||
{
|
||||
struct SecurityTokenInfo
|
||||
{
|
||||
CK_SLOT_ID SlotId;
|
||||
CK_FLAGS Flags;
|
||||
wstring Label;
|
||||
string LabelUtf8;
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfilePath
|
||||
{
|
||||
SecurityTokenKeyfilePath () { }
|
||||
SecurityTokenKeyfilePath (const wstring &path) : Path (path) { }
|
||||
operator wstring () const { return Path; }
|
||||
wstring Path;
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfile
|
||||
{
|
||||
SecurityTokenKeyfile () { }
|
||||
SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path);
|
||||
|
||||
operator SecurityTokenKeyfilePath () const;
|
||||
|
||||
CK_OBJECT_HANDLE Handle;
|
||||
wstring Id;
|
||||
string IdUtf8;
|
||||
CK_SLOT_ID SlotId;
|
||||
SecurityTokenInfo Token;
|
||||
};
|
||||
|
||||
struct Pkcs11Exception : public Exception
|
||||
{
|
||||
Pkcs11Exception (CK_RV errorCode = (CK_RV) -1)
|
||||
: ErrorCode (errorCode),
|
||||
SubjectErrorCodeValid (false)
|
||||
{
|
||||
}
|
||||
|
||||
Pkcs11Exception (CK_RV errorCode, uint64 subjectErrorCode)
|
||||
: ErrorCode (errorCode),
|
||||
SubjectErrorCodeValid (true),
|
||||
SubjectErrorCode (subjectErrorCode)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TC_HEADER_Platform_Exception
|
||||
virtual ~Pkcs11Exception () throw () { }
|
||||
TC_SERIALIZABLE_EXCEPTION (Pkcs11Exception);
|
||||
#else
|
||||
void Show (HWND parent) const;
|
||||
#endif
|
||||
operator string () const;
|
||||
CK_RV GetErrorCode () const { return ErrorCode; }
|
||||
|
||||
protected:
|
||||
CK_RV ErrorCode;
|
||||
bool SubjectErrorCodeValid;
|
||||
uint64 SubjectErrorCode;
|
||||
};
|
||||
|
||||
|
||||
#ifdef TC_HEADER_Platform_Exception
|
||||
|
||||
#define TC_EXCEPTION(NAME) TC_EXCEPTION_DECL(NAME,Exception)
|
||||
|
||||
#undef TC_EXCEPTION_SET
|
||||
#define TC_EXCEPTION_SET \
|
||||
TC_EXCEPTION_NODECL (Pkcs11Exception); \
|
||||
TC_EXCEPTION (InvalidSecurityTokenKeyfilePath); \
|
||||
TC_EXCEPTION (SecurityTokenLibraryNotInitialized); \
|
||||
TC_EXCEPTION (SecurityTokenKeyfileAlreadyExists); \
|
||||
TC_EXCEPTION (SecurityTokenKeyfileNotFound);
|
||||
|
||||
TC_EXCEPTION_SET;
|
||||
|
||||
#undef TC_EXCEPTION
|
||||
|
||||
#else // !TC_HEADER_Platform_Exception
|
||||
|
||||
struct SecurityTokenLibraryNotInitialized : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error (SecurityTokenLibraryPath[0] == 0 ? "NO_PKCS11_MODULE_SPECIFIED" : "PKCS11_MODULE_INIT_FAILED"); }
|
||||
};
|
||||
|
||||
struct InvalidSecurityTokenKeyfilePath : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error ("INVALID_TOKEN_KEYFILE_PATH"); }
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfileAlreadyExists : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error ("TOKEN_KEYFILE_ALREADY_EXISTS"); }
|
||||
};
|
||||
|
||||
struct SecurityTokenKeyfileNotFound : public Exception
|
||||
{
|
||||
void Show (HWND parent) const { Error ("TOKEN_KEYFILE_NOT_FOUND"); }
|
||||
};
|
||||
|
||||
#endif // !TC_HEADER_Platform_Exception
|
||||
|
||||
|
||||
struct Pkcs11Session
|
||||
{
|
||||
Pkcs11Session () : UserLoggedIn (false) { }
|
||||
|
||||
CK_SESSION_HANDLE Handle;
|
||||
bool UserLoggedIn;
|
||||
};
|
||||
|
||||
struct GetPinFunctor
|
||||
{
|
||||
virtual ~GetPinFunctor () { }
|
||||
virtual void operator() (string &str) = 0;
|
||||
};
|
||||
|
||||
struct SendExceptionFunctor
|
||||
{
|
||||
virtual ~SendExceptionFunctor () { }
|
||||
virtual void operator() (const Exception &e) = 0;
|
||||
};
|
||||
|
||||
class SecurityToken
|
||||
{
|
||||
public:
|
||||
static void CloseAllSessions () throw ();
|
||||
static void CloseLibrary ();
|
||||
static void CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name);
|
||||
static void DeleteKeyfile (const SecurityTokenKeyfile &keyfile);
|
||||
static vector <SecurityTokenKeyfile> GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter = nullptr, const wstring keyfileIdFilter = wstring());
|
||||
static void GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData);
|
||||
static list <SecurityTokenInfo> GetAvailableTokens ();
|
||||
static SecurityTokenInfo GetTokenInfo (CK_SLOT_ID slotId);
|
||||
static void InitLibrary (const string &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback);
|
||||
static bool IsInitialized () { return Initialized; }
|
||||
static bool IsKeyfilePathValid (const wstring &securityTokenKeyfilePath);
|
||||
|
||||
static const size_t MaxPasswordLength = 128;
|
||||
|
||||
protected:
|
||||
static void CloseSession (CK_SLOT_ID slotId);
|
||||
static vector <CK_OBJECT_HANDLE> GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass);
|
||||
static void GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue);
|
||||
static list <CK_SLOT_ID> GetTokenSlots ();
|
||||
static void Login (CK_SLOT_ID slotId, const string &pin);
|
||||
static void LoginUserIfRequired (CK_SLOT_ID slotId);
|
||||
static void OpenSession (CK_SLOT_ID slotId);
|
||||
static void CheckLibraryStatus ();
|
||||
|
||||
static bool Initialized;
|
||||
static auto_ptr <GetPinFunctor> PinCallback;
|
||||
static CK_FUNCTION_LIST_PTR Pkcs11Functions;
|
||||
#ifdef TC_WINDOWS
|
||||
static HMODULE Pkcs11LibraryHandle;
|
||||
#else
|
||||
static void *Pkcs11LibraryHandle;
|
||||
#endif
|
||||
static map <CK_SLOT_ID, Pkcs11Session> Sessions;
|
||||
static auto_ptr <SendExceptionFunctor> WarningCallback;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TC_HEADER_Common_SecurityToken
|
||||
17
src/Common/Sources
Normal file
17
src/Common/Sources
Normal file
@@ -0,0 +1,17 @@
|
||||
TARGETNAME=Common
|
||||
TARGETTYPE=DRIVER_LIBRARY
|
||||
|
||||
INCLUDES = ..;../Crypto
|
||||
|
||||
SOURCES = \
|
||||
Cache.c \
|
||||
Crc.c \
|
||||
Crypto.c \
|
||||
EncryptionThreadPool.c \
|
||||
Endian.c \
|
||||
GfMul.c \
|
||||
Pkcs5.c \
|
||||
Volumes.c \
|
||||
Xts.c \
|
||||
Tests.c \
|
||||
Wipe.c
|
||||
301
src/Common/Tcdefs.h
Normal file
301
src/Common/Tcdefs.h
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TCDEFS_H
|
||||
#define TCDEFS_H
|
||||
|
||||
#define TC_APP_NAME "TrueCrypt"
|
||||
|
||||
// Version displayed to user
|
||||
#define VERSION_STRING "7.1a"
|
||||
|
||||
// Version number to compare against driver
|
||||
#define VERSION_NUM 0x071a
|
||||
|
||||
// Release date
|
||||
#define TC_STR_RELEASE_DATE "February 7, 2012"
|
||||
#define TC_RELEASE_DATE_YEAR 2012
|
||||
#define TC_RELEASE_DATE_MONTH 2
|
||||
|
||||
#define BYTES_PER_KB 1024LL
|
||||
#define BYTES_PER_MB 1048576LL
|
||||
#define BYTES_PER_GB 1073741824LL
|
||||
#define BYTES_PER_TB 1099511627776LL
|
||||
#define BYTES_PER_PB 1125899906842624LL
|
||||
|
||||
/* GUI/driver errors */
|
||||
|
||||
#define WIDE(x) (LPWSTR)L##x
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
typedef __int8 int8;
|
||||
typedef __int16 int16;
|
||||
typedef __int32 int32;
|
||||
typedef unsigned __int8 byte;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef unsigned __int32 uint32;
|
||||
|
||||
#ifdef TC_NO_COMPILER_INT64
|
||||
typedef unsigned __int32 TC_LARGEST_COMPILER_UINT;
|
||||
#else
|
||||
typedef unsigned __int64 TC_LARGEST_COMPILER_UINT;
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#endif
|
||||
|
||||
#else // !_MSC_VER
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
typedef uint8_t byte;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
#if UCHAR_MAX != 0xffU
|
||||
#error UCHAR_MAX != 0xff
|
||||
#endif
|
||||
#define __int8 char
|
||||
|
||||
#if USHRT_MAX != 0xffffU
|
||||
#error USHRT_MAX != 0xffff
|
||||
#endif
|
||||
#define __int16 short
|
||||
|
||||
#if UINT_MAX != 0xffffffffU
|
||||
#error UINT_MAX != 0xffffffff
|
||||
#endif
|
||||
#define __int32 int
|
||||
|
||||
typedef uint64 TC_LARGEST_COMPILER_UINT;
|
||||
|
||||
#define BOOL int
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#endif // !_MSC_VER
|
||||
|
||||
#define TC_INT_TYPES_DEFINED
|
||||
|
||||
// Integer types required by Cryptolib
|
||||
typedef unsigned __int8 uint_8t;
|
||||
typedef unsigned __int16 uint_16t;
|
||||
typedef unsigned __int32 uint_32t;
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
typedef uint64 uint_64t;
|
||||
#endif
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned __int32 LowPart;
|
||||
unsigned __int32 HighPart;
|
||||
};
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
uint64 Value;
|
||||
#endif
|
||||
|
||||
} UINT64_STRUCT;
|
||||
|
||||
#ifdef TC_WINDOWS_BOOT
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void ThrowFatalException (int line);
|
||||
|
||||
# define TC_THROW_FATAL_EXCEPTION ThrowFatalException (__LINE__)
|
||||
#elif defined (TC_WINDOWS_DRIVER)
|
||||
# define TC_THROW_FATAL_EXCEPTION KeBugCheckEx (SECURITY_SYSTEM, __LINE__, 0, 0, 'TC')
|
||||
#else
|
||||
# define TC_THROW_FATAL_EXCEPTION *(char *) 0 = 0
|
||||
#endif
|
||||
|
||||
#ifdef TC_WINDOWS_DRIVER
|
||||
|
||||
#include <ntifs.h>
|
||||
#include <ntddk.h> /* Standard header file for nt drivers */
|
||||
#include <ntdddisk.h> /* Standard I/O control codes */
|
||||
|
||||
#define TCalloc(size) ((void *) ExAllocatePoolWithTag( NonPagedPool, size, 'MMCT' ))
|
||||
#define TCfree(memblock) ExFreePoolWithTag( memblock, 'MMCT' )
|
||||
|
||||
#define DEVICE_DRIVER
|
||||
|
||||
#ifndef BOOL
|
||||
typedef int BOOL;
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE !TRUE
|
||||
#endif
|
||||
|
||||
#else /* !TC_WINDOWS_DRIVER */
|
||||
|
||||
#define TCalloc malloc
|
||||
#define TCfree free
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef TC_LOCAL_WIN32_WINNT_OVERRIDE
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0501 /* Does not apply to the driver */
|
||||
#endif
|
||||
|
||||
#include <windows.h> /* Windows header */
|
||||
#include <commctrl.h> /* The common controls */
|
||||
#include <process.h> /* Process control */
|
||||
#include <winioctl.h>
|
||||
#include <stdio.h> /* For sprintf */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* !TC_WINDOWS_DRIVER */
|
||||
|
||||
#ifndef TC_TO_STRING
|
||||
# define TC_TO_STRING2(n) #n
|
||||
# define TC_TO_STRING(n) TC_TO_STRING2(n)
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
# if defined (DEBUG) || 0
|
||||
# if 1 // DbgPrintEx is not available on Windows 2000
|
||||
# define Dump DbgPrint
|
||||
# else
|
||||
# define Dump(...) DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, __VA_ARGS__)
|
||||
# endif
|
||||
# define DumpMem(...) DumpMemory (__VA_ARGS__)
|
||||
# else
|
||||
# define Dump(...)
|
||||
# define DumpMem(...)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (trace_msg) && !defined (TC_WINDOWS_BOOT)
|
||||
# ifdef DEBUG
|
||||
# ifdef DEVICE_DRIVER
|
||||
# define trace_msg Dump
|
||||
# elif defined (_WIN32)
|
||||
# define trace_msg(...) do { char msg[2048]; _snprintf (msg, sizeof (msg), __VA_ARGS__); OutputDebugString (msg); } while (0)
|
||||
# endif
|
||||
# define trace_point trace_msg (__FUNCTION__ ":" TC_TO_STRING(__LINE__) "\n")
|
||||
# else
|
||||
# define trace_msg(...)
|
||||
# define trace_point
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
# define TC_EVENT KEVENT
|
||||
# define TC_WAIT_EVENT(EVENT) KeWaitForSingleObject (&EVENT, Executive, KernelMode, FALSE, NULL)
|
||||
#elif defined (_WIN32)
|
||||
# define TC_EVENT HANDLE
|
||||
# define TC_WAIT_EVENT(EVENT) WaitForSingleObject (EVENT, INFINITE)
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); int burnc = size; RtlSecureZeroMemory (mem, size); while (burnc--) *burnm++ = 0; } while (0)
|
||||
#else
|
||||
#define burn(mem,size) do { volatile char *burnm = (volatile char *)(mem); int burnc = size; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#endif
|
||||
|
||||
// The size of the memory area to wipe is in bytes amd it must be a multiple of 8.
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
# define FAST_ERASE64(mem,size) do { volatile uint64 *burnm = (volatile uint64 *)(mem); int burnc = size >> 3; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#else
|
||||
# define FAST_ERASE64(mem,size) do { volatile unsigned __int32 *burnm = (volatile unsigned __int32 *)(mem); int burnc = size >> 2; while (burnc--) *burnm++ = 0; } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef TC_WINDOWS_BOOT
|
||||
# ifndef max
|
||||
# define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void EraseMemory (void *memory, int size);
|
||||
|
||||
# undef burn
|
||||
# define burn EraseMemory
|
||||
#endif
|
||||
|
||||
#ifdef MAX_PATH
|
||||
#define TC_MAX_PATH MAX_PATH
|
||||
#else
|
||||
#define TC_MAX_PATH 260 /* Includes the null terminator */
|
||||
#endif
|
||||
|
||||
#define TC_STR_RELEASED_BY "Released by TrueCrypt Foundation on " TC_STR_RELEASE_DATE
|
||||
|
||||
#define MAX_URL_LENGTH 2084 /* Internet Explorer limit. Includes the terminating null character. */
|
||||
|
||||
#define TC_HOMEPAGE "http://www.truecrypt.org/"
|
||||
#define TC_APPLINK "http://www.truecrypt.org/applink?version=" VERSION_STRING
|
||||
#define TC_APPLINK_SECURE "https://www.truecrypt.org/applink?version=" VERSION_STRING
|
||||
|
||||
enum
|
||||
{
|
||||
/* WARNING: ADD ANY NEW CODES AT THE END (DO NOT INSERT THEM BETWEEN EXISTING). DO *NOT* DELETE ANY
|
||||
EXISTING CODES! Changing these values or their meanings may cause incompatibility with other versions
|
||||
(for example, if a new version of the TrueCrypt installer receives an error code from an installed
|
||||
driver whose version is lower, it will report and interpret the error incorrectly). */
|
||||
|
||||
ERR_SUCCESS = 0,
|
||||
ERR_OS_ERROR = 1,
|
||||
ERR_OUTOFMEMORY = 2,
|
||||
ERR_PASSWORD_WRONG = 3,
|
||||
ERR_VOL_FORMAT_BAD = 4,
|
||||
ERR_DRIVE_NOT_FOUND = 5,
|
||||
ERR_FILES_OPEN = 6,
|
||||
ERR_VOL_SIZE_WRONG = 7,
|
||||
ERR_COMPRESSION_NOT_SUPPORTED = 8,
|
||||
ERR_PASSWORD_CHANGE_VOL_TYPE = 9,
|
||||
ERR_PASSWORD_CHANGE_VOL_VERSION = 10,
|
||||
ERR_VOL_SEEKING = 11,
|
||||
ERR_VOL_WRITING = 12,
|
||||
ERR_FILES_OPEN_LOCK = 13,
|
||||
ERR_VOL_READING = 14,
|
||||
ERR_DRIVER_VERSION = 15,
|
||||
ERR_NEW_VERSION_REQUIRED = 16,
|
||||
ERR_CIPHER_INIT_FAILURE = 17,
|
||||
ERR_CIPHER_INIT_WEAK_KEY = 18,
|
||||
ERR_SELF_TESTS_FAILED = 19,
|
||||
ERR_SECTOR_SIZE_INCOMPATIBLE = 20,
|
||||
ERR_VOL_ALREADY_MOUNTED = 21,
|
||||
ERR_NO_FREE_DRIVES = 22,
|
||||
ERR_FILE_OPEN_FAILED = 23,
|
||||
ERR_VOL_MOUNT_FAILED = 24,
|
||||
DEPRECATED_ERR_INVALID_DEVICE = 25,
|
||||
ERR_ACCESS_DENIED = 26,
|
||||
ERR_MODE_INIT_FAILED = 27,
|
||||
ERR_DONT_REPORT = 28,
|
||||
ERR_ENCRYPTION_NOT_COMPLETED = 29,
|
||||
ERR_PARAMETER_INCORRECT = 30,
|
||||
ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG = 31,
|
||||
ERR_NONSYS_INPLACE_ENC_INCOMPLETE = 32,
|
||||
ERR_USER_ABORT = 33
|
||||
};
|
||||
|
||||
#endif // #ifndef TCDEFS_H
|
||||
1722
src/Common/Tests.c
Normal file
1722
src/Common/Tests.c
Normal file
File diff suppressed because it is too large
Load Diff
30
src/Common/Tests.h
Normal file
30
src/Common/Tests.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2008 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern unsigned char ks_tmp[MAX_EXPANDED_KEY];
|
||||
|
||||
void CipherInit2(int cipher, void* key, void* ks, int key_len);
|
||||
BOOL test_hmac_sha512 (void);
|
||||
BOOL test_hmac_sha1 (void);
|
||||
BOOL test_hmac_ripemd160 (void);
|
||||
BOOL test_hmac_whirlpool (void);
|
||||
BOOL test_pkcs5 (void);
|
||||
BOOL TestSectorBufEncryption ();
|
||||
BOOL TestLegacySectorBufEncryption ();
|
||||
BOOL AutoTestAlgorithms (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
BIN
src/Common/Textual_logo_288dpi.bmp
Normal file
BIN
src/Common/Textual_logo_288dpi.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 162 KiB |
BIN
src/Common/Textual_logo_96dpi.bmp
Normal file
BIN
src/Common/Textual_logo_96dpi.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
src/Common/Textual_logo_background.bmp
Normal file
BIN
src/Common/Textual_logo_background.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
BIN
src/Common/TrueCrypt.ico
Normal file
BIN
src/Common/TrueCrypt.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
src/Common/TrueCrypt_Volume.ico
Normal file
BIN
src/Common/TrueCrypt_Volume.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
src/Common/TrueCrypt_mounted.ico
Normal file
BIN
src/Common/TrueCrypt_mounted.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
1198
src/Common/Volumes.c
Normal file
1198
src/Common/Volumes.c
Normal file
File diff suppressed because it is too large
Load Diff
144
src/Common/Volumes.h
Normal file
144
src/Common/Volumes.h
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
Legal Notice: Some portions of the source code contained in this file were
|
||||
derived from the source code of Encryption for the Masses 2.02a, which is
|
||||
Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
|
||||
Agreement for Encryption for the Masses'. Modifications and additions to
|
||||
the original source code (contained in this file) and all other portions
|
||||
of this file are Copyright (c) 2003-2010 TrueCrypt Developers Association
|
||||
and are governed by the TrueCrypt License 3.0 the full text of which is
|
||||
contained in the file License.txt included in TrueCrypt binary and source
|
||||
code distribution packages. */
|
||||
|
||||
#ifndef TC_HEADER_Common_Volumes
|
||||
#define TC_HEADER_Common_Volumes
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Volume header version
|
||||
#define VOLUME_HEADER_VERSION 0x0005
|
||||
|
||||
// Version number written to volume header during format;
|
||||
// specifies the minimum program version required to mount the volume
|
||||
#define TC_VOLUME_MIN_REQUIRED_PROGRAM_VERSION 0x0700
|
||||
|
||||
// Version number written (encrypted) to the key data area of an encrypted system partition/drive;
|
||||
// specifies the minimum program version required to decrypt the system partition/drive
|
||||
#define TC_SYSENC_KEYSCOPE_MIN_REQ_PROG_VERSION 0x0700
|
||||
|
||||
// Current volume format version (created by TrueCrypt 6.0+)
|
||||
#define TC_VOLUME_FORMAT_VERSION 2
|
||||
|
||||
// Version number of volume format created by TrueCrypt 1.0-5.1a
|
||||
#define TC_VOLUME_FORMAT_VERSION_PRE_6_0 1
|
||||
|
||||
// Volume header sizes
|
||||
#define TC_VOLUME_HEADER_SIZE (64 * 1024L)
|
||||
#define TC_VOLUME_HEADER_EFFECTIVE_SIZE 512
|
||||
#define TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE 512
|
||||
#define TC_VOLUME_HEADER_SIZE_LEGACY 512
|
||||
|
||||
#define TC_VOLUME_HEADER_GROUP_SIZE (2 * TC_VOLUME_HEADER_SIZE)
|
||||
#define TC_TOTAL_VOLUME_HEADERS_SIZE (4 * TC_VOLUME_HEADER_SIZE)
|
||||
|
||||
// Volume offsets
|
||||
#define TC_VOLUME_HEADER_OFFSET 0
|
||||
#define TC_HIDDEN_VOLUME_HEADER_OFFSET TC_VOLUME_HEADER_SIZE
|
||||
|
||||
// Sector sizes
|
||||
#define TC_MIN_VOLUME_SECTOR_SIZE 512
|
||||
#define TC_MAX_VOLUME_SECTOR_SIZE 4096
|
||||
#define TC_SECTOR_SIZE_FILE_HOSTED_VOLUME 512
|
||||
#define TC_SECTOR_SIZE_LEGACY 512
|
||||
|
||||
// Sector size which can be safely assumed to be supported by all BIOSes
|
||||
#define TC_SECTOR_SIZE_BIOS 512
|
||||
|
||||
#define TC_VOLUME_SMALL_SIZE_THRESHOLD (2 * BYTES_PER_MB) // Volume sizes below this threshold are considered small
|
||||
|
||||
#define TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE TC_MAX_VOLUME_SECTOR_SIZE // FAT file system fills the last sector with zeroes (marked as free; observed when quick format was performed using the OS format tool).
|
||||
#define TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE_HIGH TC_VOLUME_HEADER_GROUP_SIZE // Reserved area size used for hidden volumes larger than TC_VOLUME_SMALL_SIZE_THRESHOLD
|
||||
|
||||
#define TC_VOLUME_DATA_OFFSET TC_VOLUME_HEADER_GROUP_SIZE
|
||||
|
||||
// The offset, in bytes, of the legacy hidden volume header position from the end of the file (a positive value).
|
||||
#define TC_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY (TC_VOLUME_HEADER_SIZE_LEGACY + TC_SECTOR_SIZE_LEGACY * 2)
|
||||
|
||||
#define TC_MAX_128BIT_BLOCK_VOLUME_SIZE BYTES_PER_PB // Security bound (128-bit block XTS mode)
|
||||
|
||||
// Filesystem size limits
|
||||
#define TC_MIN_FAT_FS_SIZE (9 * TC_MAX_VOLUME_SECTOR_SIZE)
|
||||
#define TC_MAX_FAT_SECTOR_COUNT 0x100000000ULL
|
||||
#define TC_MIN_NTFS_FS_SIZE (884 * TC_MAX_VOLUME_SECTOR_SIZE)
|
||||
#define TC_MAX_NTFS_FS_SIZE (128LL * BYTES_PER_TB) // NTFS volume can theoretically be up to 16 exabytes, but Windows XP and 2003 limit the size to that addressable with 32-bit clusters, i.e. max size is 128 TB (if 64-KB clusters are used).
|
||||
#define TC_MAX_FAT_CLUSTER_SIZE (256 * BYTES_PER_KB) // Windows XP/Vista may crash when writing to a filesystem using clusters larger than 256 KB
|
||||
|
||||
// Volume size limits
|
||||
#define TC_MIN_VOLUME_SIZE (TC_TOTAL_VOLUME_HEADERS_SIZE + TC_MIN_FAT_FS_SIZE)
|
||||
#define TC_MIN_VOLUME_SIZE_LEGACY (37 * TC_SECTOR_SIZE_LEGACY)
|
||||
#define TC_MAX_VOLUME_SIZE_GENERAL 0x7fffFFFFffffFFFFLL // Signed 64-bit integer file offset values
|
||||
#define TC_MAX_VOLUME_SIZE TC_MAX_128BIT_BLOCK_VOLUME_SIZE
|
||||
|
||||
#define TC_MIN_HIDDEN_VOLUME_SIZE (TC_MIN_FAT_FS_SIZE + TC_HIDDEN_VOLUME_HOST_FS_RESERVED_END_AREA_SIZE)
|
||||
|
||||
#define TC_MIN_HIDDEN_VOLUME_HOST_SIZE (TC_MIN_VOLUME_SIZE + TC_MIN_HIDDEN_VOLUME_SIZE + 2 * TC_MAX_VOLUME_SECTOR_SIZE)
|
||||
#define TC_MAX_HIDDEN_VOLUME_HOST_SIZE (TC_MAX_NTFS_FS_SIZE - TC_TOTAL_VOLUME_HEADERS_SIZE)
|
||||
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
# if TC_MAX_VOLUME_SIZE > TC_MAX_VOLUME_SIZE_GENERAL
|
||||
# error TC_MAX_VOLUME_SIZE > TC_MAX_VOLUME_SIZE_GENERAL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define HEADER_ENCRYPTED_DATA_SIZE (TC_VOLUME_HEADER_EFFECTIVE_SIZE - HEADER_ENCRYPTED_DATA_OFFSET)
|
||||
|
||||
// Volume header field offsets
|
||||
#define HEADER_SALT_OFFSET 0
|
||||
#define HEADER_ENCRYPTED_DATA_OFFSET PKCS5_SALT_SIZE
|
||||
#define HEADER_MASTER_KEYDATA_OFFSET 256
|
||||
|
||||
#define TC_HEADER_OFFSET_MAGIC 64
|
||||
#define TC_HEADER_OFFSET_VERSION 68
|
||||
#define TC_HEADER_OFFSET_REQUIRED_VERSION 70
|
||||
#define TC_HEADER_OFFSET_KEY_AREA_CRC 72
|
||||
#define TC_HEADER_OFFSET_VOLUME_CREATION_TIME 76
|
||||
#define TC_HEADER_OFFSET_MODIFICATION_TIME 84
|
||||
#define TC_HEADER_OFFSET_HIDDEN_VOLUME_SIZE 92
|
||||
#define TC_HEADER_OFFSET_VOLUME_SIZE 100
|
||||
#define TC_HEADER_OFFSET_ENCRYPTED_AREA_START 108
|
||||
#define TC_HEADER_OFFSET_ENCRYPTED_AREA_LENGTH 116
|
||||
#define TC_HEADER_OFFSET_FLAGS 124
|
||||
#define TC_HEADER_OFFSET_SECTOR_SIZE 128
|
||||
#define TC_HEADER_OFFSET_HEADER_CRC 252
|
||||
|
||||
// Volume header flags
|
||||
#define TC_HEADER_FLAG_ENCRYPTED_SYSTEM 0x1
|
||||
#define TC_HEADER_FLAG_NONSYS_INPLACE_ENC 0x2 // The volume has been created using non-system in-place encryption
|
||||
|
||||
|
||||
#ifndef TC_HEADER_Volume_VolumeHeader
|
||||
|
||||
#include "Password.h"
|
||||
|
||||
extern BOOL ReadVolumeHeaderRecoveryMode;
|
||||
|
||||
uint16 GetHeaderField16 (byte *header, int offset);
|
||||
uint32 GetHeaderField32 (byte *header, int offset);
|
||||
UINT64_STRUCT GetHeaderField64 (byte *header, int offset);
|
||||
int ReadVolumeHeader (BOOL bBoot, char *encryptedHeader, Password *password, PCRYPTO_INFO *retInfo, CRYPTO_INFO *retHeaderCryptoInfo);
|
||||
|
||||
#if !defined (DEVICE_DRIVER) && !defined (TC_WINDOWS_BOOT)
|
||||
int CreateVolumeHeaderInMemory (BOOL bBoot, char *encryptedHeader, int ea, int mode, Password *password, int pkcs5_prf, char *masterKeydata, PCRYPTO_INFO *retInfo, unsigned __int64 volumeSize, unsigned __int64 hiddenVolumeSize, unsigned __int64 encryptedAreaStart, unsigned __int64 encryptedAreaLength, uint16 requiredProgramVersion, uint32 headerFlags, uint32 sectorSize, BOOL bWipeMode);
|
||||
BOOL ReadEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header, DWORD *bytesRead);
|
||||
BOOL WriteEffectiveVolumeHeader (BOOL device, HANDLE fileHandle, byte *header);
|
||||
int WriteRandomDataToReservedHeaderAreas (HANDLE dev, CRYPTO_INFO *cryptoInfo, uint64 dataAreaSize, BOOL bPrimaryOnly, BOOL bBackupOnly);
|
||||
#endif
|
||||
|
||||
#endif // !TC_HEADER_Volume_VolumeHeader
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_Common_Volumes
|
||||
187
src/Common/Wipe.c
Normal file
187
src/Common/Wipe.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Wipe.h"
|
||||
|
||||
|
||||
static BOOL Wipe1PseudoRandom (int pass, byte *buffer, size_t size)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// Fill buffer with wipe patterns defined in "National Industrial Security Program Operating Manual", US DoD 5220.22-M.
|
||||
// Return: FALSE = buffer must be filled with random data
|
||||
|
||||
static BOOL Wipe3Dod5220 (int pass, byte *buffer, size_t size)
|
||||
{
|
||||
byte wipeChar;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 1:
|
||||
wipeChar = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
wipeChar = 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (buffer, wipeChar, size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL Wipe7Dod5220 (int pass, byte randChars[TC_WIPE_RAND_CHAR_COUNT], byte *buffer, size_t size)
|
||||
{
|
||||
byte wipeChar;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 1:
|
||||
wipeChar = randChars[0];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
wipeChar = ~randChars[0];
|
||||
break;
|
||||
|
||||
case 4:
|
||||
wipeChar = randChars[1];
|
||||
break;
|
||||
|
||||
case 5:
|
||||
wipeChar = randChars[2];
|
||||
break;
|
||||
|
||||
case 6:
|
||||
wipeChar = ~randChars[2];
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (buffer, wipeChar, size);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Fill the buffer with wipe patterns defined in the paper "Secure Deletion of Data from Magnetic and Solid-State Memory" by Peter Gutmann.
|
||||
// Return: FALSE = buffer must be filled with random data
|
||||
|
||||
static BOOL Wipe35Gutmann (int pass, byte *buffer, size_t size)
|
||||
{
|
||||
byte wipePat3[] = { 0x92, 0x49, 0x24 };
|
||||
int wipePat3Pos;
|
||||
size_t i;
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case 5:
|
||||
memset (buffer, 0x55, size);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
memset (buffer, 0xaa, size);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 26:
|
||||
case 29:
|
||||
wipePat3Pos = 0;
|
||||
goto wipe3;
|
||||
|
||||
case 8:
|
||||
case 27:
|
||||
case 30:
|
||||
wipePat3Pos = 1;
|
||||
goto wipe3;
|
||||
|
||||
case 9:
|
||||
case 28:
|
||||
case 31:
|
||||
wipePat3Pos = 2;
|
||||
goto wipe3;
|
||||
|
||||
wipe3:
|
||||
if (pass >= 29)
|
||||
{
|
||||
wipePat3[0] = ~wipePat3[0];
|
||||
wipePat3[1] = ~wipePat3[1];
|
||||
wipePat3[2] = ~wipePat3[2];
|
||||
}
|
||||
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
buffer[i] = wipePat3[wipePat3Pos++ % 3];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pass >= 10 && pass <= 25)
|
||||
memset (buffer, (pass - 10) * 0x11, size);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int GetWipePassCount (WipeAlgorithmId algorithm)
|
||||
{
|
||||
switch (algorithm)
|
||||
{
|
||||
case TC_WIPE_1_RAND:
|
||||
return 1;
|
||||
|
||||
case TC_WIPE_3_DOD_5220:
|
||||
return 3;
|
||||
|
||||
case TC_WIPE_7_DOD_5220:
|
||||
return 7;
|
||||
|
||||
case TC_WIPE_35_GUTMANN:
|
||||
return 35;
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return 0; // Prevent compiler warnings
|
||||
}
|
||||
|
||||
|
||||
BOOL WipeBuffer (WipeAlgorithmId algorithm, byte randChars[TC_WIPE_RAND_CHAR_COUNT], int pass, byte *buffer, size_t size)
|
||||
{
|
||||
switch (algorithm)
|
||||
{
|
||||
case TC_WIPE_1_RAND:
|
||||
return Wipe1PseudoRandom (pass, buffer, size);
|
||||
|
||||
case TC_WIPE_3_DOD_5220:
|
||||
return Wipe3Dod5220 (pass, buffer, size);
|
||||
|
||||
case TC_WIPE_7_DOD_5220:
|
||||
return Wipe7Dod5220 (pass, randChars, buffer, size);
|
||||
|
||||
case TC_WIPE_35_GUTMANN:
|
||||
return Wipe35Gutmann (pass, buffer, size);
|
||||
|
||||
default:
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
return FALSE; // Prevent compiler warnings
|
||||
}
|
||||
40
src/Common/Wipe.h
Normal file
40
src/Common/Wipe.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef TC_HEADER_Common_Wipe
|
||||
#define TC_HEADER_Common_Wipe
|
||||
|
||||
#include "Tcdefs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* WARNING: As these values are written to config files, if they or their meanings
|
||||
are changed, incompatiblity with other versions may arise (upgrade, downgrade, etc.).
|
||||
When adding a new constant, verify that the value is unique within this block. */
|
||||
TC_WIPE_NONE = 0,
|
||||
TC_WIPE_1_RAND = 100,
|
||||
TC_WIPE_3_DOD_5220 = 300,
|
||||
TC_WIPE_7_DOD_5220 = 700,
|
||||
TC_WIPE_35_GUTMANN = 3500
|
||||
|
||||
} WipeAlgorithmId;
|
||||
|
||||
#define TC_WIPE_RAND_CHAR_COUNT 3
|
||||
|
||||
int GetWipePassCount (WipeAlgorithmId algorithm);
|
||||
BOOL WipeBuffer (WipeAlgorithmId algorithm, byte randChars[TC_WIPE_RAND_CHAR_COUNT], int pass, byte *buffer, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TC_HEADER_Common_Wipe
|
||||
231
src/Common/Xml.c
Normal file
231
src/Common/Xml.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
Copyright (c) 2005-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "Xml.h"
|
||||
|
||||
|
||||
static BOOL BeginsWith (char *string, char *subString)
|
||||
{
|
||||
while (*string++ == *subString++)
|
||||
{
|
||||
if (*subString == 0) return TRUE;
|
||||
if (*string == 0) return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
char *XmlNextNode (char *xmlNode)
|
||||
{
|
||||
char *t = xmlNode + 1;
|
||||
while ((t = strchr (t, '<')) != NULL)
|
||||
{
|
||||
if (t[1] != '/')
|
||||
return t;
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *XmlFindElement (char *xmlNode, char *nodeName)
|
||||
{
|
||||
char *t = xmlNode;
|
||||
size_t nameLen = strlen (nodeName);
|
||||
|
||||
do
|
||||
{
|
||||
if (BeginsWith (t + 1, nodeName)
|
||||
&& (t[nameLen + 1] == '>'
|
||||
|| t[nameLen + 1] == ' ')) return t;
|
||||
|
||||
} while (t = XmlNextNode (t));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *XmlFindElementByAttributeValue (char *xml, char *nodeName, char *attrName, char *attrValue)
|
||||
{
|
||||
char attr[2048];
|
||||
|
||||
while (xml = XmlFindElement (xml, nodeName))
|
||||
{
|
||||
XmlGetAttributeText (xml, attrName, attr, sizeof (attr));
|
||||
if (strcmp (attr, attrValue) == 0)
|
||||
return xml;
|
||||
|
||||
xml++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *XmlGetAttributeText (char *xmlNode, char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize)
|
||||
{
|
||||
char *t = xmlNode;
|
||||
char *e = xmlNode;
|
||||
int l = 0;
|
||||
|
||||
xmlAttrValue[0] = 0;
|
||||
if (t[0] != '<') return NULL;
|
||||
|
||||
e = strchr (e, '>');
|
||||
if (e == NULL) return NULL;
|
||||
|
||||
while ((t = strstr (t, xmlAttrName)) && t < e)
|
||||
{
|
||||
char *o = t + strlen (xmlAttrName);
|
||||
if (t[-1] == ' '
|
||||
&&
|
||||
(BeginsWith (o, "=\"")
|
||||
|| BeginsWith (o, "= \"")
|
||||
|| BeginsWith (o, " =\"")
|
||||
|| BeginsWith (o, " = \""))
|
||||
)
|
||||
break;
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
if (t == NULL || t > e) return NULL;
|
||||
|
||||
t = strchr (t, '"') + 1;
|
||||
e = strchr (t, '"');
|
||||
l = (int)(e - t);
|
||||
if (e == NULL || l > xmlAttrValueSize) return NULL;
|
||||
|
||||
memcpy (xmlAttrValue, t, l);
|
||||
xmlAttrValue[l] = 0;
|
||||
|
||||
return xmlAttrValue;
|
||||
}
|
||||
|
||||
|
||||
char *XmlGetNodeText (char *xmlNode, char *xmlText, int xmlTextSize)
|
||||
{
|
||||
char *t = xmlNode;
|
||||
char *e = xmlNode + 1;
|
||||
int l = 0, i = 0, j = 0;
|
||||
|
||||
xmlText[0] = 0;
|
||||
|
||||
if (t[0] != '<')
|
||||
return NULL;
|
||||
|
||||
t = strchr (t, '>') + 1;
|
||||
if (t == (char *)1) return NULL;
|
||||
|
||||
e = strchr (e, '<');
|
||||
if (e == NULL) return NULL;
|
||||
|
||||
l = (int)(e - t);
|
||||
if (e == NULL || l > xmlTextSize) return NULL;
|
||||
|
||||
while (i < l)
|
||||
{
|
||||
if (BeginsWith (&t[i], "<"))
|
||||
{
|
||||
xmlText[j++] = '<';
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (BeginsWith (&t[i], ">"))
|
||||
{
|
||||
xmlText[j++] = '>';
|
||||
i += 4;
|
||||
continue;
|
||||
}
|
||||
if (BeginsWith (&t[i], "&"))
|
||||
{
|
||||
xmlText[j++] = '&';
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
xmlText[j++] = t[i++];
|
||||
}
|
||||
xmlText[j] = 0;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
char *XmlQuoteText (const char *textSrc, char *textDst, int textDstMaxSize)
|
||||
{
|
||||
char *textDstLast = textDst + textDstMaxSize - 1;
|
||||
|
||||
if (textDstMaxSize == 0)
|
||||
return NULL;
|
||||
|
||||
while (*textSrc != 0 && textDst <= textDstLast)
|
||||
{
|
||||
char c = *textSrc++;
|
||||
switch (c)
|
||||
{
|
||||
case '&':
|
||||
if (textDst + 6 > textDstLast)
|
||||
return NULL;
|
||||
strcpy (textDst, "&");
|
||||
textDst += 5;
|
||||
continue;
|
||||
|
||||
case '>':
|
||||
if (textDst + 5 > textDstLast)
|
||||
return NULL;
|
||||
strcpy (textDst, ">");
|
||||
textDst += 4;
|
||||
continue;
|
||||
|
||||
case '<':
|
||||
if (textDst + 5 > textDstLast)
|
||||
return NULL;
|
||||
strcpy (textDst, "<");
|
||||
textDst += 4;
|
||||
continue;
|
||||
|
||||
default:
|
||||
*textDst++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (textDst > textDstLast)
|
||||
return NULL;
|
||||
|
||||
*textDst = 0;
|
||||
return textDst;
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteHeader (FILE *file)
|
||||
{
|
||||
return fputs ("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TrueCrypt>", file);
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteHeaderW (FILE *file)
|
||||
{
|
||||
return fputws (L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TrueCrypt>", file);
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteFooter (FILE *file)
|
||||
{
|
||||
return fputs ("\n</TrueCrypt>", file);
|
||||
}
|
||||
|
||||
|
||||
int XmlWriteFooterW (FILE *file)
|
||||
{
|
||||
return fputws (L"\n</TrueCrypt>", file);
|
||||
}
|
||||
26
src/Common/Xml.h
Normal file
26
src/Common/Xml.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright (c) 2005-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *XmlNextNode (char *xmlNode);
|
||||
char *XmlFindElement (char *xmlNode, char *nodeName);
|
||||
char *XmlGetAttributeText (char *xmlNode, char *xmlAttrName, char *xmlAttrValue, int xmlAttrValueSize);
|
||||
char *XmlGetNodeText (char *xmlNode, char *xmlText, int xmlTextSize);
|
||||
int XmlWriteHeader (FILE *file);
|
||||
int XmlWriteHeaderW (FILE *file);
|
||||
int XmlWriteFooter (FILE *file);
|
||||
int XmlWriteFooterW (FILE *file);
|
||||
char *XmlFindElementByAttributeValue (char *xml, char *nodeName, char *attrName, char *attrValue);
|
||||
char *XmlQuoteText (const char *textSrc, char *textDst, int textDstMaxSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
746
src/Common/Xts.c
Normal file
746
src/Common/Xts.c
Normal file
@@ -0,0 +1,746 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
/* If native 64-bit data types are not available, define TC_NO_COMPILER_INT64.
|
||||
|
||||
For big-endian platforms define BYTE_ORDER as BIG_ENDIAN. */
|
||||
|
||||
|
||||
#ifdef TC_MINIMIZE_CODE_SIZE
|
||||
// Preboot/boot version
|
||||
# ifndef TC_NO_COMPILER_INT64
|
||||
# define TC_NO_COMPILER_INT64
|
||||
# endif
|
||||
# pragma optimize ("tl", on)
|
||||
#endif
|
||||
|
||||
#ifdef TC_NO_COMPILER_INT64
|
||||
# include <memory.h>
|
||||
#endif
|
||||
|
||||
#include "Xts.h"
|
||||
|
||||
|
||||
#ifndef TC_NO_COMPILER_INT64
|
||||
|
||||
// length: number of bytes to encrypt; may be larger than one data unit and must be divisible by the cipher block size
|
||||
// ks: the primary key schedule
|
||||
// ks2: the secondary key schedule
|
||||
// startDataUnitNo: The sequential number of the data unit with which the buffer starts.
|
||||
// startCipherBlockNo: The sequential number of the first plaintext block to encrypt inside the data unit startDataUnitNo.
|
||||
// When encrypting the data unit from its first block, startCipherBlockNo is 0.
|
||||
// The startCipherBlockNo value applies only to the first data unit in the buffer; each successive
|
||||
// data unit is encrypted from its first block. The start of the buffer does not have to be
|
||||
// aligned with the start of a data unit. If it is aligned, startCipherBlockNo must be 0; if it
|
||||
// is not aligned, startCipherBlockNo must reflect the misalignment accordingly.
|
||||
void EncryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
if (CipherSupportsIntraDataUnitParallelization (cipher))
|
||||
EncryptBufferXTSParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
else
|
||||
EncryptBufferXTSNonParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms supporting intra-data-unit parallelization
|
||||
static void EncryptBufferXTSParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuesPtr64 = (unsigned __int64 *) whiteningValues;
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned __int64 *dataUnitBufPtr;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
unsigned __int64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
/* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the
|
||||
finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block
|
||||
number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented
|
||||
as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if
|
||||
the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is
|
||||
derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
|
||||
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
#else
|
||||
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
dataUnitBufPtr = bufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
// Encrypt all blocks in this data unit
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
// Pre-whitening
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
// Actual encryption
|
||||
EncipherBlocks (cipher, dataUnitBufPtr, ks, endBlock - startBlock);
|
||||
|
||||
bufPtr = dataUnitBufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
// Post-whitening
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
FAST_ERASE64 (whiteningValues, sizeof (whiteningValues));
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms not supporting intra-data-unit parallelization
|
||||
static void EncryptBufferXTSNonParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
/* The encrypted data unit number (i.e. the resultant ciphertext block) is to be multiplied in the
|
||||
finite field GF(2^128) by j-th power of n, where j is the sequential plaintext/ciphertext block
|
||||
number and n is 2, a primitive element of GF(2^128). This can be (and is) simplified and implemented
|
||||
as a left shift of the preceding whitening value by one bit (with carry propagating). In addition, if
|
||||
the shift of the highest byte results in a carry, 135 is XORed into the lowest byte. The value 135 is
|
||||
derived from the modulus of the Galois Field (x^128+x^7+x^2+x+1). */
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate (and apply) subsequent whitening values for blocks in this data unit and
|
||||
// encrypt all relevant blocks in this data unit
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
// Pre-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr-- ^= *whiteningValuePtr64--;
|
||||
|
||||
// Actual encryption
|
||||
EncipherBlock (cipher, bufPtr, ks);
|
||||
|
||||
// Post-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr++ ^= *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
#else
|
||||
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
}
|
||||
|
||||
|
||||
// For descriptions of the input parameters, see EncryptBufferXTS().
|
||||
void DecryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
if (CipherSupportsIntraDataUnitParallelization (cipher))
|
||||
DecryptBufferXTSParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
else
|
||||
DecryptBufferXTSNonParallel (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher);
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms supporting intra-data-unit parallelization
|
||||
static void DecryptBufferXTSParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValues [ENCRYPTION_DATA_UNIT_SIZE];
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuesPtr64 = (unsigned __int64 *) whiteningValues;
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned __int64 *dataUnitBufPtr;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
unsigned __int64 *const finalInt64WhiteningValuesPtr = whiteningValuesPtr64 + sizeof (whiteningValues) / sizeof (*whiteningValuesPtr64) - 1;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate subsequent whitening values for blocks in this data unit. Note that all generated 128-bit
|
||||
// whitening values are stored in memory as a sequence of 64-bit integers in reverse order.
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64++;
|
||||
*whiteningValuesPtr64-- = *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
|
||||
#else
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
dataUnitBufPtr = bufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
// Decrypt blocks in this data unit
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
DecipherBlocks (cipher, dataUnitBufPtr, ks, endBlock - startBlock);
|
||||
|
||||
bufPtr = dataUnitBufPtr;
|
||||
whiteningValuesPtr64 = finalInt64WhiteningValuesPtr;
|
||||
|
||||
for (block = startBlock; block < endBlock; block++)
|
||||
{
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
*bufPtr++ ^= *whiteningValuesPtr64--;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
FAST_ERASE64 (whiteningValues, sizeof (whiteningValues));
|
||||
}
|
||||
|
||||
|
||||
// Optimized for encryption algorithms not supporting intra-data-unit parallelization
|
||||
static void DecryptBufferXTSNonParallel (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int64 *whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
unsigned __int64 *bufPtr = (unsigned __int64 *) buffer;
|
||||
unsigned int startBlock = startCipherBlockNo, endBlock, block;
|
||||
TC_LARGEST_COMPILER_UINT blockCount, dataUnitNo;
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// Note that as we are converting a 64-bit number into a 16-byte array we can always zero the last 8 bytes.
|
||||
dataUnitNo = startDataUnitNo->Value;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
*((unsigned __int64 *) byteBufUnitNo + 1) = 0;
|
||||
|
||||
if (length % BYTES_PER_XTS_BLOCK)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Process all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
whiteningValuePtr64 = (unsigned __int64 *) whiteningValue;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
*whiteningValuePtr64 = *((unsigned __int64 *) byteBufUnitNo);
|
||||
*(whiteningValuePtr64 + 1) = 0;
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate (and apply) subsequent whitening values for blocks in this data unit and
|
||||
// decrypt all relevant blocks in this data unit
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
// Post-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr-- ^= *whiteningValuePtr64--;
|
||||
|
||||
// Actual decryption
|
||||
DecipherBlock (cipher, bufPtr, ks);
|
||||
|
||||
// Pre-whitening
|
||||
*bufPtr++ ^= *whiteningValuePtr64++;
|
||||
*bufPtr++ ^= *whiteningValuePtr64;
|
||||
}
|
||||
else
|
||||
whiteningValuePtr64++;
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
// Little-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x8000000000000000) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64-- <<= 1;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x8000000000000000)
|
||||
*(whiteningValuePtr64 + 1) |= 1;
|
||||
|
||||
*whiteningValuePtr64 <<= 1;
|
||||
|
||||
#else
|
||||
// Big-endian platforms
|
||||
|
||||
finalCarry =
|
||||
(*whiteningValuePtr64 & 0x80) ?
|
||||
135 : 0;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
|
||||
whiteningValuePtr64--;
|
||||
|
||||
if (*whiteningValuePtr64 & 0x80)
|
||||
*(whiteningValuePtr64 + 1) |= 0x0100000000000000;
|
||||
|
||||
*whiteningValuePtr64 = LE64 (LE64 (*whiteningValuePtr64) << 1);
|
||||
#endif
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
dataUnitNo++;
|
||||
*((unsigned __int64 *) byteBufUnitNo) = LE64 (dataUnitNo);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
}
|
||||
|
||||
|
||||
#else // TC_NO_COMPILER_INT64
|
||||
|
||||
/* ---- The following code is to be used only when native 64-bit data types are not available. ---- */
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#error The TC_NO_COMPILER_INT64 version of the XTS code is not compatible with big-endian platforms
|
||||
#endif
|
||||
|
||||
|
||||
// Converts a 64-bit unsigned integer (passed as two 32-bit integers for compatibility with non-64-bit
|
||||
// environments/platforms) into a little-endian 16-byte array.
|
||||
static void Uint64ToLE16ByteArray (unsigned __int8 *byteBuf, unsigned __int32 highInt32, unsigned __int32 lowInt32)
|
||||
{
|
||||
unsigned __int32 *bufPtr32 = (unsigned __int32 *) byteBuf;
|
||||
|
||||
*bufPtr32++ = lowInt32;
|
||||
*bufPtr32++ = highInt32;
|
||||
|
||||
// We're converting a 64-bit number into a little-endian 16-byte array so we can zero the last 8 bytes
|
||||
*bufPtr32++ = 0;
|
||||
*bufPtr32 = 0;
|
||||
}
|
||||
|
||||
|
||||
// Encrypts or decrypts all blocks in the buffer in XTS mode. For descriptions of the input parameters,
|
||||
// see the 64-bit version of EncryptBufferXTS().
|
||||
static void EncryptDecryptBufferXTS32 (const unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startBlock,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher,
|
||||
BOOL decryption)
|
||||
{
|
||||
TC_LARGEST_COMPILER_UINT blockCount;
|
||||
UINT64_STRUCT dataUnitNo;
|
||||
unsigned int block;
|
||||
unsigned int endBlock;
|
||||
unsigned __int8 byteBufUnitNo [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int8 whiteningValue [BYTES_PER_XTS_BLOCK];
|
||||
unsigned __int32 *bufPtr32 = (unsigned __int32 *) buffer;
|
||||
unsigned __int32 *whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
|
||||
unsigned __int8 finalCarry;
|
||||
unsigned __int32 *const finalDwordWhiteningValuePtr = whiteningValuePtr32 + sizeof (whiteningValue) / sizeof (*whiteningValuePtr32) - 1;
|
||||
|
||||
// Store the 64-bit data unit number in a way compatible with non-64-bit environments/platforms
|
||||
dataUnitNo.HighPart = startDataUnitNo->HighPart;
|
||||
dataUnitNo.LowPart = startDataUnitNo->LowPart;
|
||||
|
||||
blockCount = length / BYTES_PER_XTS_BLOCK;
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
// (Passed as two 32-bit integers for compatibility with non-64-bit environments/platforms.)
|
||||
Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart);
|
||||
|
||||
// Generate whitening values for all blocks in the buffer
|
||||
while (blockCount > 0)
|
||||
{
|
||||
if (blockCount < BLOCKS_PER_XTS_DATA_UNIT)
|
||||
endBlock = startBlock + (unsigned int) blockCount;
|
||||
else
|
||||
endBlock = BLOCKS_PER_XTS_DATA_UNIT;
|
||||
|
||||
// Encrypt the data unit number using the secondary key (in order to generate the first
|
||||
// whitening value for this data unit)
|
||||
memcpy (whiteningValue, byteBufUnitNo, BYTES_PER_XTS_BLOCK);
|
||||
EncipherBlock (cipher, whiteningValue, ks2);
|
||||
|
||||
// Generate (and apply) subsequent whitening values for blocks in this data unit and
|
||||
// encrypt/decrypt all relevant blocks in this data unit
|
||||
for (block = 0; block < endBlock; block++)
|
||||
{
|
||||
if (block >= startBlock)
|
||||
{
|
||||
whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
|
||||
|
||||
// Whitening
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32 ^= *whiteningValuePtr32;
|
||||
|
||||
bufPtr32 -= BYTES_PER_XTS_BLOCK / sizeof (*bufPtr32) - 1;
|
||||
|
||||
// Actual encryption/decryption
|
||||
if (decryption)
|
||||
DecipherBlock (cipher, bufPtr32, ks);
|
||||
else
|
||||
EncipherBlock (cipher, bufPtr32, ks);
|
||||
|
||||
whiteningValuePtr32 = (unsigned __int32 *) whiteningValue;
|
||||
|
||||
// Whitening
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32++;
|
||||
*bufPtr32++ ^= *whiteningValuePtr32;
|
||||
}
|
||||
|
||||
// Derive the next whitening value
|
||||
|
||||
finalCarry = 0;
|
||||
|
||||
for (whiteningValuePtr32 = finalDwordWhiteningValuePtr;
|
||||
whiteningValuePtr32 >= (unsigned __int32 *) whiteningValue;
|
||||
whiteningValuePtr32--)
|
||||
{
|
||||
if (*whiteningValuePtr32 & 0x80000000) // If the following shift results in a carry
|
||||
{
|
||||
if (whiteningValuePtr32 != finalDwordWhiteningValuePtr) // If not processing the highest double word
|
||||
{
|
||||
// A regular carry
|
||||
*(whiteningValuePtr32 + 1) |= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The highest byte shift will result in a carry
|
||||
finalCarry = 135;
|
||||
}
|
||||
}
|
||||
|
||||
*whiteningValuePtr32 <<= 1;
|
||||
}
|
||||
|
||||
whiteningValue[0] ^= finalCarry;
|
||||
}
|
||||
|
||||
blockCount -= endBlock - startBlock;
|
||||
startBlock = 0;
|
||||
|
||||
// Increase the data unit number by one
|
||||
if (!++dataUnitNo.LowPart)
|
||||
{
|
||||
dataUnitNo.HighPart++;
|
||||
}
|
||||
|
||||
// Convert the 64-bit data unit number into a little-endian 16-byte array.
|
||||
Uint64ToLE16ByteArray (byteBufUnitNo, dataUnitNo.HighPart, dataUnitNo.LowPart);
|
||||
}
|
||||
|
||||
FAST_ERASE64 (whiteningValue, sizeof (whiteningValue));
|
||||
}
|
||||
|
||||
|
||||
// For descriptions of the input parameters, see the 64-bit version of EncryptBufferXTS() above.
|
||||
void EncryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
// Encrypt all plaintext blocks in the buffer
|
||||
EncryptDecryptBufferXTS32 (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher, FALSE);
|
||||
}
|
||||
|
||||
|
||||
// For descriptions of the input parameters, see the 64-bit version of EncryptBufferXTS().
|
||||
void DecryptBufferXTS (unsigned __int8 *buffer,
|
||||
TC_LARGEST_COMPILER_UINT length,
|
||||
const UINT64_STRUCT *startDataUnitNo,
|
||||
unsigned int startCipherBlockNo,
|
||||
unsigned __int8 *ks,
|
||||
unsigned __int8 *ks2,
|
||||
int cipher)
|
||||
{
|
||||
// Decrypt all ciphertext blocks in the buffer
|
||||
EncryptDecryptBufferXTS32 (buffer, length, startDataUnitNo, startCipherBlockNo, ks, ks2, cipher, TRUE);
|
||||
}
|
||||
|
||||
#endif // TC_NO_COMPILER_INT64
|
||||
80
src/Common/Xts.h
Normal file
80
src/Common/Xts.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (c) 2008-2010 TrueCrypt Developers Association. All rights reserved.
|
||||
|
||||
Governed by the TrueCrypt License 3.0 the full text of which is contained in
|
||||
the file License.txt included in TrueCrypt binary and source code distribution
|
||||
packages.
|
||||
*/
|
||||
|
||||
#ifndef XTS_H
|
||||
#define XTS_H
|
||||
|
||||
// Header files (optional)
|
||||
|
||||
#include "Tcdefs.h"
|
||||
#include "Common/Endian.h"
|
||||
#include "Crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Macros
|
||||
|
||||
#ifndef LITTLE_ENDIAN
|
||||
# define LITTLE_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#ifndef BIG_ENDIAN
|
||||
# define BIG_ENDIAN 2
|
||||
#endif
|
||||
|
||||
#ifndef BYTE_ORDER
|
||||
# define BYTE_ORDER LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifndef LE64
|
||||
# if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define LE64(x) (x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Custom data types
|
||||
|
||||
#ifndef TC_LARGEST_COMPILER_UINT
|
||||
# ifdef TC_NO_COMPILER_INT64
|
||||
typedef unsigned __int32 TC_LARGEST_COMPILER_UINT;
|
||||
# else
|
||||
typedef unsigned __int64 TC_LARGEST_COMPILER_UINT;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef TCDEFS_H
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned __int32 LowPart;
|
||||
unsigned __int32 HighPart;
|
||||
};
|
||||
# ifndef TC_NO_COMPILER_INT64
|
||||
unsigned __int64 Value;
|
||||
# endif
|
||||
|
||||
} UINT64_STRUCT;
|
||||
#endif
|
||||
|
||||
// Public function prototypes
|
||||
|
||||
void EncryptBufferXTS (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void EncryptBufferXTSParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void EncryptBufferXTSNonParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
void DecryptBufferXTS (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void DecryptBufferXTSParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
static void DecryptBufferXTSNonParallel (unsigned __int8 *buffer, TC_LARGEST_COMPILER_UINT length, const UINT64_STRUCT *startDataUnitNo, unsigned int startCipherBlockNo, unsigned __int8 *ks, unsigned __int8 *ks2, int cipher);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #ifndef XTS_H
|
||||
Reference in New Issue
Block a user